Merge branch 'v1.2.stable' of ssh://git.freeswitch.org:222/freeswitch into v1.2.stable

This commit is contained in:
Michael S Collins 2012-11-30 13:27:42 -08:00
commit 77a44bd2ad
706 changed files with 142742 additions and 34037 deletions

71
.gitignore vendored
View File

@ -29,6 +29,7 @@
*.ilk
*.bsc
*.pch
*.opensdf
*.tar
*.gz
*.tgz
@ -50,6 +51,7 @@ TAGS
*.unsuccessfulbuild
*.cache
*.lastbuildstate
*.sdf
/w32/Library/lastversion
/w32/Library/tmpVersion.Bat
@ -81,9 +83,9 @@ TAGS
/tone2wav
/All/
/Debug/
Debug/
/bin/
/Release/
Release/
/ipch/
/*.log
@ -165,63 +167,18 @@ TAGS
/src/mod/say/mod_say_zh/Makefile
BuildLog.htm
/w32/Console/Debug/
/w32/Console/Release/
/w32/Library/Debug/
/w32/Library/Release/
Freeswitch.2010.sdf
Win32/
win32/
!/libs/win32/
*.suo
*.sdf
x64/
ipch/
/Win32/
/x64/
src/mod/codecs/mod_celt/*/*/mod_celt.log
src/mod/endpoints/mod_skinny/*/*/mod_skinny_2010.log
src/mod/formats/mod_shout/*/*/mod_shout.log
/libs/xmlrpc-c/tools/xml-rpc-api2txt
/w32/Setup/obj
/src/mod/asr_tts/mod_pocketsphinx/x64/Debug/mod_pocketsphinx_manifest.rc
/src/mod/endpoints/mod_h323/x64/Debug/mod_h323_manifest.rc
/src/mod/endpoints/mod_rtmp/Win32/Debug/mod_rtmp_2010.log
/src/mod/endpoints/mod_rtmp/Win32/Release/mod_rtmp_2010.log
/src/mod/endpoints/mod_rtmp/x64/Debug/mod_rtmp_2010.log
/src/mod/endpoints/mod_rtmp/x64/Debug/mod_rtmp_manifest.rc
/src/mod/endpoints/mod_rtmp/x64/Release/mod_rtmp_2010.log
/src/mod/endpoints/mod_skinny/x64/Debug/mod_skinny_manifest.rc
/src/mod/languages/mod_managed/x64/Debug_CLR/FREESWITCH.MANAGED.DLL.metagen
/src/mod/languages/mod_managed/x64/Debug_CLR/RSAENH.DLL.bi
/src/mod/languages/mod_managed/x64/Debug_CLR/TZRES.DLL.bi
/w32/Library/x64/Debug/FreeSwitch_manifest.rc
/src/mod/endpoints/mod_h323/Win32/Debug/mod_h323_manifest.rc
/src/mod/endpoints/mod_rtmp/Win32/Debug/mod_rtmp_manifest.rc
/src/mod/endpoints/mod_skinny/Win32/Debug/mod_skinny_manifest.rc
/src/mod/languages/mod_managed/Win32/Debug_CLR/FREESWITCH.MANAGED.DLL.metagen
/src/mod/languages/mod_managed/Win32/Debug_CLR/RSAENH.DLL.bi
/src/mod/languages/mod_managed/Win32/Debug_CLR/TZRES.DLL.bi
/w32/Library/Win32/Debug/FreeSwitch_manifest.rc
/src/mod/languages/mod_managed/Win32/Release_CLR/FREESWITCH.MANAGED.DLL.metagen
/src/mod/languages/mod_managed/Win32/Release_CLR/RSAENH.DLL.bi
/src/mod/languages/mod_managed/Win32/Release_CLR/TZRES.DLL.bi
/src/mod/languages/mod_managed/x64/Release_CLR/FREESWITCH.MANAGED.DLL.metagen
/src/mod/languages/mod_managed/x64/Release_CLR/RSAENH.DLL.bi
/src/mod/languages/mod_managed/x64/Release_CLR/TZRES.DLL.bi
libs/apr-util/a.out.dSYM/Contents/Info.plist
libs/apr-util/a.out.dSYM/Contents/Resources/DWARF/a.out
libs/apr/a.out.dSYM/Contents/Info.plist
libs/apr/a.out.dSYM/Contents/Resources/DWARF/a.out
libs/iksemel/a.out.dSYM/Contents/Info.plist
libs/iksemel/a.out.dSYM/Contents/Resources/DWARF/a.out
libs/ilbc/a.out.dSYM/Contents/Info.plist
libs/ilbc/a.out.dSYM/Contents/Resources/DWARF/a.out
libs/libedit/a.out.dSYM/Contents/Info.plist
libs/libedit/a.out.dSYM/Contents/Resources/DWARF/a.out
libs/pcre/a.out.dSYM/Contents/Info.plist
libs/pcre/a.out.dSYM/Contents/Resources/DWARF/a.out
libs/sqlite/lemon.dSYM/Contents/Info.plist
libs/sqlite/lemon.dSYM/Contents/Resources/DWARF/lemon
libs/sqlite/mkkeywordhash.dSYM/Contents/Info.plist
libs/sqlite/mkkeywordhash.dSYM/Contents/Resources/DWARF/mkkeywordhash
libs/sqlite/sqlite3.dSYM/Contents/Info.plist
libs/sqlite/sqlite3.dSYM/Contents/Resources/DWARF/sqlite3
libs/srtp/a.out.dSYM/Contents/Info.plist
libs/srtp/a.out.dSYM/Contents/Resources/DWARF/a.out
*dSYM*
/libs/xmlrpc-c/lib/expat/xmltok/nametab.h

View File

@ -114,12 +114,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_console", "src\mod\logg
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_xml_rpc", "src\mod\xml_int\mod_xml_rpc\mod_xml_rpc.2008.vcproj", "{CBEC7225-0C21-4DA8-978E-1F158F8AD950}"
ProjectSection(ProjectDependencies) = postProject
{0D108721-EAE8-4BAF-8102-D8960EC93647} = {0D108721-EAE8-4BAF-8102-D8960EC93647}
{B535402E-38D2-4D54-8360-423ACBD17192} = {B535402E-38D2-4D54-8360-423ACBD17192}
{202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B} = {2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B}
{A4D67895-E709-40C7-82B6-DE1D12DDDE04} = {A4D67895-E709-40C7-82B6-DE1D12DDDE04}
{87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588}
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA} = {CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9} = {D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}
{510BDAA8-C04D-47DB-8482-E6AF380D3E07} = {510BDAA8-C04D-47DB-8482-E6AF380D3E07}
{E5A9BCDA-B82D-4B08-B23E-9A782E367888} = {E5A9BCDA-B82D-4B08-B23E-9A782E367888}
{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268} = {3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_rss", "src\mod\applications\mod_rss\mod_rss.2008.vcproj", "{B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}"
@ -380,13 +381,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_lua", "src\mod\language
{D0B36172-CD76-454A-9B89-990025266C2A} = {D0B36172-CD76-454A-9B89-990025266C2A}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "abyss", "libs\xmlrpc-c\Windows\abyss.2008.vcproj", "{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "abyss", "libs\win32\xmlrpc-c\abyss.2008.vcproj", "{A4D67895-E709-40C7-82B6-DE1D12DDDE04}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc", "libs\xmlrpc-c\Windows\xmlrpc.2008.vcproj", "{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc", "libs\win32\xmlrpc-c\xmlrpc.2008.vcproj", "{510BDAA8-C04D-47DB-8482-E6AF380D3E07}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlparse", "libs\xmlrpc-c\Windows\xmlparse.2008.vcproj", "{0D108721-EAE8-4BAF-8102-D8960EC93647}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlparse", "libs\win32\xmlrpc-c\xmlparse.2008.vcproj", "{E5A9BCDA-B82D-4B08-B23E-9A782E367888}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmltok", "libs\xmlrpc-c\Windows\xmltok.2008.vcproj", "{B535402E-38D2-4D54-8360-423ACBD17192}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmltok", "libs\win32\xmlrpc-c\xmltok.2008.vcproj", "{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}"
ProjectSection(ProjectDependencies) = postProject
{2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B} = {2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download sphinxbase", "libs\win32\Download sphinxbase.2008.vcproj", "{4F92B672-DADB-4047-8D6A-4BB3796733FD}"
EndProject
@ -675,6 +679,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "libs\win32\libjp
{21A7DA70-555E-49FA-942B-D84A38B61243} = {21A7DA70-555E-49FA-942B-D84A38B61243}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gennmtab", "libs\win32\xmlrpc-c\gennmtab.2008.vcproj", "{2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
All|Win32 = All|Win32
@ -1447,50 +1453,50 @@ Global
{7B077E7F-1BE7-4291-AB86-55E527B25CAC}.Release|Win32.Build.0 = Release|Win32
{7B077E7F-1BE7-4291-AB86-55E527B25CAC}.Release|x64.ActiveCfg = Release|x64
{7B077E7F-1BE7-4291-AB86-55E527B25CAC}.Release|x64.Build.0 = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|Win32.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|x64.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|x64.Build.0 = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|Win32.ActiveCfg = Debug|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|Win32.Build.0 = Debug|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|x64.ActiveCfg = Debug|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|x64.Build.0 = Debug|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|Win32.ActiveCfg = Release|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|Win32.Build.0 = Release|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|x64.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|x64.Build.0 = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|Win32.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|x64.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|x64.Build.0 = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|Win32.ActiveCfg = Debug|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|Win32.Build.0 = Debug|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|x64.ActiveCfg = Debug|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|x64.Build.0 = Debug|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|Win32.ActiveCfg = Release|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|Win32.Build.0 = Release|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|x64.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|x64.Build.0 = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|Win32.ActiveCfg = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|x64.ActiveCfg = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|x64.Build.0 = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|Win32.ActiveCfg = Debug|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|Win32.Build.0 = Debug|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|x64.ActiveCfg = Debug|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|x64.Build.0 = Debug|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|Win32.ActiveCfg = Release|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|Win32.Build.0 = Release|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|x64.ActiveCfg = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|x64.Build.0 = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|Win32.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|x64.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|x64.Build.0 = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|Win32.ActiveCfg = Debug|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|Win32.Build.0 = Debug|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|x64.ActiveCfg = Debug|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|x64.Build.0 = Debug|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|Win32.ActiveCfg = Release|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|Win32.Build.0 = Release|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|x64.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|x64.Build.0 = Release|x64
{A4D67895-E709-40C7-82B6-DE1D12DDDE04}.All|Win32.ActiveCfg = Release|x64
{A4D67895-E709-40C7-82B6-DE1D12DDDE04}.All|x64.ActiveCfg = Release|x64
{A4D67895-E709-40C7-82B6-DE1D12DDDE04}.All|x64.Build.0 = Release|x64
{A4D67895-E709-40C7-82B6-DE1D12DDDE04}.Debug|Win32.ActiveCfg = Debug|Win32
{A4D67895-E709-40C7-82B6-DE1D12DDDE04}.Debug|Win32.Build.0 = Debug|Win32
{A4D67895-E709-40C7-82B6-DE1D12DDDE04}.Debug|x64.ActiveCfg = Debug|Win32
{A4D67895-E709-40C7-82B6-DE1D12DDDE04}.Debug|x64.Build.0 = Debug|Win32
{A4D67895-E709-40C7-82B6-DE1D12DDDE04}.Release|Win32.ActiveCfg = Release|Win32
{A4D67895-E709-40C7-82B6-DE1D12DDDE04}.Release|Win32.Build.0 = Release|Win32
{A4D67895-E709-40C7-82B6-DE1D12DDDE04}.Release|x64.ActiveCfg = Release|x64
{A4D67895-E709-40C7-82B6-DE1D12DDDE04}.Release|x64.Build.0 = Release|x64
{510BDAA8-C04D-47DB-8482-E6AF380D3E07}.All|Win32.ActiveCfg = Release|x64
{510BDAA8-C04D-47DB-8482-E6AF380D3E07}.All|x64.ActiveCfg = Release|x64
{510BDAA8-C04D-47DB-8482-E6AF380D3E07}.All|x64.Build.0 = Release|x64
{510BDAA8-C04D-47DB-8482-E6AF380D3E07}.Debug|Win32.ActiveCfg = Debug|Win32
{510BDAA8-C04D-47DB-8482-E6AF380D3E07}.Debug|Win32.Build.0 = Debug|Win32
{510BDAA8-C04D-47DB-8482-E6AF380D3E07}.Debug|x64.ActiveCfg = Debug|Win32
{510BDAA8-C04D-47DB-8482-E6AF380D3E07}.Debug|x64.Build.0 = Debug|Win32
{510BDAA8-C04D-47DB-8482-E6AF380D3E07}.Release|Win32.ActiveCfg = Release|Win32
{510BDAA8-C04D-47DB-8482-E6AF380D3E07}.Release|Win32.Build.0 = Release|Win32
{510BDAA8-C04D-47DB-8482-E6AF380D3E07}.Release|x64.ActiveCfg = Release|x64
{510BDAA8-C04D-47DB-8482-E6AF380D3E07}.Release|x64.Build.0 = Release|x64
{E5A9BCDA-B82D-4B08-B23E-9A782E367888}.All|Win32.ActiveCfg = Debug|x64
{E5A9BCDA-B82D-4B08-B23E-9A782E367888}.All|x64.ActiveCfg = Debug|x64
{E5A9BCDA-B82D-4B08-B23E-9A782E367888}.All|x64.Build.0 = Debug|x64
{E5A9BCDA-B82D-4B08-B23E-9A782E367888}.Debug|Win32.ActiveCfg = Debug|Win32
{E5A9BCDA-B82D-4B08-B23E-9A782E367888}.Debug|Win32.Build.0 = Debug|Win32
{E5A9BCDA-B82D-4B08-B23E-9A782E367888}.Debug|x64.ActiveCfg = Debug|Win32
{E5A9BCDA-B82D-4B08-B23E-9A782E367888}.Debug|x64.Build.0 = Debug|Win32
{E5A9BCDA-B82D-4B08-B23E-9A782E367888}.Release|Win32.ActiveCfg = Release|Win32
{E5A9BCDA-B82D-4B08-B23E-9A782E367888}.Release|Win32.Build.0 = Release|Win32
{E5A9BCDA-B82D-4B08-B23E-9A782E367888}.Release|x64.ActiveCfg = Release|x64
{E5A9BCDA-B82D-4B08-B23E-9A782E367888}.Release|x64.Build.0 = Release|x64
{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}.All|Win32.ActiveCfg = Release|x64
{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}.All|x64.ActiveCfg = Release|x64
{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}.All|x64.Build.0 = Release|x64
{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}.Debug|Win32.ActiveCfg = Debug|Win32
{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}.Debug|Win32.Build.0 = Debug|Win32
{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}.Debug|x64.ActiveCfg = Debug|Win32
{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}.Debug|x64.Build.0 = Debug|Win32
{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}.Release|Win32.ActiveCfg = Release|Win32
{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}.Release|Win32.Build.0 = Release|Win32
{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}.Release|x64.ActiveCfg = Release|x64
{3CF7C0E0-07C2-473A-A1E4-2274AEEC1268}.Release|x64.Build.0 = Release|x64
{4F92B672-DADB-4047-8D6A-4BB3796733FD}.All|Win32.ActiveCfg = Release|Win32
{4F92B672-DADB-4047-8D6A-4BB3796733FD}.All|Win32.Build.0 = Release|Win32
{4F92B672-DADB-4047-8D6A-4BB3796733FD}.All|x64.ActiveCfg = Release|Win32
@ -2164,6 +2170,15 @@ Global
{FE02CD06-DD97-489C-8F61-B5E7F89BCC0A}.Release|Win32.ActiveCfg = Release|Win32
{FE02CD06-DD97-489C-8F61-B5E7F89BCC0A}.Release|Win32.Build.0 = Release|Win32
{FE02CD06-DD97-489C-8F61-B5E7F89BCC0A}.Release|x64.ActiveCfg = Release|Win32
{2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B}.All|Win32.ActiveCfg = Release|Win32
{2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B}.All|Win32.Build.0 = Release|Win32
{2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B}.All|x64.ActiveCfg = Release|Win32
{2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B}.Debug|Win32.ActiveCfg = Debug|Win32
{2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B}.Debug|Win32.Build.0 = Debug|Win32
{2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B}.Debug|x64.ActiveCfg = Debug|Win32
{2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B}.Release|Win32.ActiveCfg = Release|Win32
{2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B}.Release|Win32.Build.0 = Release|Win32
{2390F054-A7F1-4CB9-ACB0-F46EC6E77B5B}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

File diff suppressed because it is too large Load Diff

View File

@ -142,13 +142,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_spidermonkey_curl", "sr
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_lua", "src\mod\languages\mod_lua\mod_lua.2010.vcxproj", "{7B077E7F-1BE7-4291-AB86-55E527B25CAC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "abyss", "libs\xmlrpc-c\Windows\abyss.2010.vcxproj", "{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "abyss", "libs\win32\xmlrpc-c\abyss.2010.vcxproj", "{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc", "libs\xmlrpc-c\Windows\xmlrpc.2010.vcxproj", "{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc", "libs\win32\xmlrpc-c\xmlrpc.2010.vcxproj", "{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlparse", "libs\xmlrpc-c\Windows\xmlparse.2010.vcxproj", "{0D108721-EAE8-4BAF-8102-D8960EC93647}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlparse", "libs\win32\xmlrpc-c\xmlparse.2010.vcxproj", "{0D108721-EAE8-4BAF-8102-D8960EC93647}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmltok", "libs\xmlrpc-c\Windows\xmltok.2010.vcxproj", "{B535402E-38D2-4D54-8360-423ACBD17192}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmltok", "libs\win32\xmlrpc-c\xmltok.2010.vcxproj", "{B535402E-38D2-4D54-8360-423ACBD17192}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download sphinxbase", "libs\win32\Download sphinxbase.2010.vcxproj", "{4F92B672-DADB-4047-8D6A-4BB3796733FD}"
EndProject
@ -334,6 +334,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "libs\win32\libjp
{652AD5F7-8488-489F-AAD0-7FBE064703B6} = {652AD5F7-8488-489F-AAD0-7FBE064703B6}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gennmtab", "libs\win32\xmlrpc-c\gennmtab.2010.vcxproj", "{BED7539C-0099-4A14-AD5D-30828F15A171}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
All|Win32 = All|Win32
@ -2043,6 +2045,15 @@ Global
{019DBD2A-273D-4BA4-BF86-B5EFE2ED76B1}.Release|Win32.ActiveCfg = Release|Win32
{019DBD2A-273D-4BA4-BF86-B5EFE2ED76B1}.Release|Win32.Build.0 = Release|Win32
{019DBD2A-273D-4BA4-BF86-B5EFE2ED76B1}.Release|x64.ActiveCfg = Release|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.All|Win32.ActiveCfg = Release|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.All|Win32.Build.0 = Release|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.All|x64.ActiveCfg = Release|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Debug|Win32.ActiveCfg = Debug|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Debug|Win32.Build.0 = Debug|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Debug|x64.ActiveCfg = Debug|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Release|Win32.ActiveCfg = Release|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Release|Win32.Build.0 = Release|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -207,6 +207,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_console", "src\mod\loggers\mod_console\mod_console.2010.vcxproj", "{1C453396-D912-4213-89FD-9B489162B7B5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_xml_rpc", "src\mod\xml_int\mod_xml_rpc\mod_xml_rpc.2010.vcxproj", "{CBEC7225-0C21-4DA8-978E-1F158F8AD950}"
ProjectSection(ProjectDependencies) = postProject
{BED7539C-0099-4A14-AD5D-30828F15A171} = {BED7539C-0099-4A14-AD5D-30828F15A171}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_rss", "src\mod\applications\mod_rss\mod_rss.2010.vcxproj", "{B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}"
EndProject
@ -315,14 +318,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_spidermonkey_curl", "sr
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_lua", "src\mod\languages\mod_lua\mod_lua.2010.vcxproj", "{7B077E7F-1BE7-4291-AB86-55E527B25CAC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "abyss", "libs\xmlrpc-c\Windows\abyss.2010.vcxproj", "{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc", "libs\xmlrpc-c\Windows\xmlrpc.2010.vcxproj", "{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlparse", "libs\xmlrpc-c\Windows\xmlparse.2010.vcxproj", "{0D108721-EAE8-4BAF-8102-D8960EC93647}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmltok", "libs\xmlrpc-c\Windows\xmltok.2010.vcxproj", "{B535402E-38D2-4D54-8360-423ACBD17192}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download sphinxbase", "libs\win32\Download sphinxbase.2010.vcxproj", "{4F92B672-DADB-4047-8D6A-4BB3796733FD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download sphinxmodel", "libs\win32\Download sphinxmodel.2010.vcxproj", "{2DEE4895-1134-439C-B688-52203E57D878}"
@ -529,6 +524,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_abstraction", "src\mod\
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_sms", "src\mod\applications\mod_sms\mod_sms.2010.vcxproj", "{2469B306-B027-4FF2-8815-C9C1EA2CAE79}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "xmlrpc-c", "xmlrpc-c", "{9DE35039-A8F6-4FBF-B1B6-EB527F802411}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsmlib", "src\mod\endpoints\mod_gsmopen\gsmlib\gsmlib-1.10-patched-13ubuntu\win32\gsmlib.2010.vcxproj", "{26C82FCE-E0CF-4D10-A00C-D8E582FFEB53}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_gsmopen", "src\mod\endpoints\mod_gsmopen\mod_gsmopen.2010.vcxproj", "{74B120FF-6935-4DFE-A142-CDB6BEA99C90}"
@ -544,6 +541,31 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "libs\win32\libjp
{652AD5F7-8488-489F-AAD0-7FBE064703B6} = {652AD5F7-8488-489F-AAD0-7FBE064703B6}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "abyss", "libs\win32\xmlrpc-c\abyss.2010.vcxproj", "{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}"
ProjectSection(ProjectDependencies) = postProject
{0D108721-EAE8-4BAF-8102-D8960EC93647} = {0D108721-EAE8-4BAF-8102-D8960EC93647}
{B535402E-38D2-4D54-8360-423ACBD17192} = {B535402E-38D2-4D54-8360-423ACBD17192}
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA} = {CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gennmtab", "libs\win32\xmlrpc-c\gennmtab.2010.vcxproj", "{BED7539C-0099-4A14-AD5D-30828F15A171}"
ProjectSection(ProjectDependencies) = postProject
{0D108721-EAE8-4BAF-8102-D8960EC93647} = {0D108721-EAE8-4BAF-8102-D8960EC93647}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlparse", "libs\win32\xmlrpc-c\xmlparse.2010.vcxproj", "{0D108721-EAE8-4BAF-8102-D8960EC93647}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc", "libs\win32\xmlrpc-c\xmlrpc.2010.vcxproj", "{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}"
ProjectSection(ProjectDependencies) = postProject
{0D108721-EAE8-4BAF-8102-D8960EC93647} = {0D108721-EAE8-4BAF-8102-D8960EC93647}
{B535402E-38D2-4D54-8360-423ACBD17192} = {B535402E-38D2-4D54-8360-423ACBD17192}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmltok", "libs\win32\xmlrpc-c\xmltok.2010.vcxproj", "{B535402E-38D2-4D54-8360-423ACBD17192}"
ProjectSection(ProjectDependencies) = postProject
{BED7539C-0099-4A14-AD5D-30828F15A171} = {BED7539C-0099-4A14-AD5D-30828F15A171}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
All|Win32 = All|Win32
@ -1826,78 +1848,6 @@ Global
{7B077E7F-1BE7-4291-AB86-55E527B25CAC}.Release|x64.Build.0 = Release|x64
{7B077E7F-1BE7-4291-AB86-55E527B25CAC}.Release|x64 Setup.ActiveCfg = Release|x64
{7B077E7F-1BE7-4291-AB86-55E527B25CAC}.Release|x86 Setup.ActiveCfg = Release|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|Win32.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|x64.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|x64.Build.0 = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|x64 Setup.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|x64 Setup.Build.0 = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|x86 Setup.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|Win32.ActiveCfg = Debug|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|Win32.Build.0 = Debug|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|x64.ActiveCfg = Debug|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|x64.Build.0 = Debug|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|x64 Setup.ActiveCfg = Debug|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|x86 Setup.ActiveCfg = Debug|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|Win32.ActiveCfg = Release|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|Win32.Build.0 = Release|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|x64.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|x64.Build.0 = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|x64 Setup.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|x86 Setup.ActiveCfg = Release|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|Win32.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|x64.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|x64.Build.0 = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|x64 Setup.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|x64 Setup.Build.0 = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|x86 Setup.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|Win32.ActiveCfg = Debug|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|Win32.Build.0 = Debug|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|x64.ActiveCfg = Debug|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|x64.Build.0 = Debug|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|x64 Setup.ActiveCfg = Debug|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|x86 Setup.ActiveCfg = Debug|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|Win32.ActiveCfg = Release|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|Win32.Build.0 = Release|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|x64.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|x64.Build.0 = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|x64 Setup.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|x86 Setup.ActiveCfg = Release|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|Win32.ActiveCfg = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|x64.ActiveCfg = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|x64.Build.0 = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|x64 Setup.ActiveCfg = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|x64 Setup.Build.0 = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|x86 Setup.ActiveCfg = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|Win32.ActiveCfg = Debug|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|Win32.Build.0 = Debug|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|x64.ActiveCfg = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|x64.Build.0 = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|x64 Setup.ActiveCfg = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|x86 Setup.ActiveCfg = Debug|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|Win32.ActiveCfg = Release|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|Win32.Build.0 = Release|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|x64.ActiveCfg = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|x64.Build.0 = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|x64 Setup.ActiveCfg = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|x86 Setup.ActiveCfg = Release|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.All|Win32.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|x64.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|x64.Build.0 = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|x64 Setup.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|x64 Setup.Build.0 = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|x86 Setup.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|Win32.ActiveCfg = Debug|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|Win32.Build.0 = Debug|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|x64.ActiveCfg = Debug|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|x64.Build.0 = Debug|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|x64 Setup.ActiveCfg = Debug|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|x86 Setup.ActiveCfg = Debug|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|Win32.ActiveCfg = Release|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|Win32.Build.0 = Release|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|x64.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|x64.Build.0 = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|x64 Setup.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|x86 Setup.ActiveCfg = Release|Win32
{4F92B672-DADB-4047-8D6A-4BB3796733FD}.All|Win32.ActiveCfg = Release|Win32
{4F92B672-DADB-4047-8D6A-4BB3796733FD}.All|Win32.Build.0 = Release|Win32
{4F92B672-DADB-4047-8D6A-4BB3796733FD}.All|x64.ActiveCfg = Release|Win32
@ -3718,6 +3668,91 @@ Global
{019DBD2A-273D-4BA4-BF86-B5EFE2ED76B1}.Release|x64.Build.0 = Release|x64
{019DBD2A-273D-4BA4-BF86-B5EFE2ED76B1}.Release|x64 Setup.ActiveCfg = Release|Win32
{019DBD2A-273D-4BA4-BF86-B5EFE2ED76B1}.Release|x86 Setup.ActiveCfg = Release|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|Win32.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|x64.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|x64.Build.0 = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|x64 Setup.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.All|x86 Setup.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|Win32.ActiveCfg = Debug|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|Win32.Build.0 = Debug|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|x64.ActiveCfg = Debug|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|x64.Build.0 = Debug|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|x64 Setup.ActiveCfg = Debug|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Debug|x86 Setup.ActiveCfg = Debug|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|Win32.ActiveCfg = Release|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|Win32.Build.0 = Release|Win32
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|x64.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|x64.Build.0 = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|x64 Setup.ActiveCfg = Release|x64
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}.Release|x86 Setup.ActiveCfg = Release|x64
{BED7539C-0099-4A14-AD5D-30828F15A171}.All|Win32.ActiveCfg = Release|x64
{BED7539C-0099-4A14-AD5D-30828F15A171}.All|x64.ActiveCfg = Release|x64
{BED7539C-0099-4A14-AD5D-30828F15A171}.All|x64.Build.0 = Release|x64
{BED7539C-0099-4A14-AD5D-30828F15A171}.All|x64 Setup.ActiveCfg = Release|x64
{BED7539C-0099-4A14-AD5D-30828F15A171}.All|x86 Setup.ActiveCfg = Release|x64
{BED7539C-0099-4A14-AD5D-30828F15A171}.Debug|Win32.ActiveCfg = Debug|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Debug|Win32.Build.0 = Debug|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Debug|x64.ActiveCfg = Debug|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Debug|x64.Build.0 = Debug|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Debug|x64 Setup.ActiveCfg = Debug|x64
{BED7539C-0099-4A14-AD5D-30828F15A171}.Debug|x86 Setup.ActiveCfg = Debug|x64
{BED7539C-0099-4A14-AD5D-30828F15A171}.Release|Win32.ActiveCfg = Release|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Release|Win32.Build.0 = Release|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Release|x64.ActiveCfg = Release|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Release|x64.Build.0 = Release|Win32
{BED7539C-0099-4A14-AD5D-30828F15A171}.Release|x64 Setup.ActiveCfg = Release|x64
{BED7539C-0099-4A14-AD5D-30828F15A171}.Release|x86 Setup.ActiveCfg = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|Win32.ActiveCfg = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|x64.ActiveCfg = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|x64.Build.0 = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|x64 Setup.ActiveCfg = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.All|x86 Setup.ActiveCfg = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|Win32.ActiveCfg = Debug|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|Win32.Build.0 = Debug|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|x64.ActiveCfg = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|x64.Build.0 = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|x64 Setup.ActiveCfg = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Debug|x86 Setup.ActiveCfg = Debug|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|Win32.ActiveCfg = Release|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|Win32.Build.0 = Release|Win32
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|x64.ActiveCfg = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|x64.Build.0 = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|x64 Setup.ActiveCfg = Release|x64
{0D108721-EAE8-4BAF-8102-D8960EC93647}.Release|x86 Setup.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|Win32.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|x64.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|x64.Build.0 = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|x64 Setup.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.All|x86 Setup.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|Win32.ActiveCfg = Debug|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|Win32.Build.0 = Debug|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|x64.ActiveCfg = Debug|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|x64.Build.0 = Debug|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|x64 Setup.ActiveCfg = Debug|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Debug|x86 Setup.ActiveCfg = Debug|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|Win32.ActiveCfg = Release|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|Win32.Build.0 = Release|Win32
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|x64.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|x64.Build.0 = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|x64 Setup.ActiveCfg = Release|x64
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}.Release|x86 Setup.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|Win32.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|x64.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|x64.Build.0 = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|x64 Setup.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.All|x86 Setup.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|Win32.ActiveCfg = Debug|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|Win32.Build.0 = Debug|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|x64.ActiveCfg = Debug|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|x64.Build.0 = Debug|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|x64 Setup.ActiveCfg = Debug|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Debug|x86 Setup.ActiveCfg = Debug|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|Win32.ActiveCfg = Release|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|Win32.Build.0 = Release|Win32
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|x64.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|x64.Build.0 = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|x64 Setup.ActiveCfg = Release|x64
{B535402E-38D2-4D54-8360-423ACBD17192}.Release|x86 Setup.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -3769,8 +3804,8 @@ Global
{B889A18E-70A7-44B5-B2C9-47798D4F43B3} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{5C2B4D88-3BEA-4FE0-90DF-FA9836099D5F} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{A61D7CB4-75A5-4A55-8CA1-BE5AF615D921} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{50AAC2CE-BFC9-4912-87CC-C6381850D735} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{A61D7CB4-75A5-4A55-8CA1-BE5AF615D921} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{4748FF56-CA85-4809-97D6-A94C0FAC1D77} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{60C542EE-6882-4EA2-8C21-5AB6DB1BA73F} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{2469B306-B027-4FF2-8815-C9C1EA2CAE79} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
@ -3804,10 +3839,6 @@ Global
{DF018947-0FFF-4EB3-BDEE-441DC81DA7A4} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{4043FC6A-9A30-4577-8AD5-9B233C9575D8} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{0A18A071-125E-442F-AFF7-A3F68ABECF99} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{0D108721-EAE8-4BAF-8102-D8960EC93647} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{B535402E-38D2-4D54-8360-423ACBD17192} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{2F025EAD-99BD-40F5-B2CC-F0A28CAD7F2D} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{94001A0E-A837-445C-8004-F918F10D0226} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{0AD1177E-1FD8-4643-9391-431467A11084} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
@ -3832,6 +3863,7 @@ Global
{E4D29906-8B73-4F8A-B5F4-CA8BFA648F5A} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{70A49BC2-7500-41D0-B75D-EDCC5BE987A0} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{23B4D303-79FC-49E0-89E2-2280E7E28940} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{9DE35039-A8F6-4FBF-B1B6-EB527F802411} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{C13CC324-0032-4492-9A30-310A6BD64FF5} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{019DBD2A-273D-4BA4-BF86-B5EFE2ED76B1} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
@ -3917,5 +3949,10 @@ Global
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE} = {E4D29906-8B73-4F8A-B5F4-CA8BFA648F5A}
{B4B62169-5AD4-4559-8707-3D933AC5DB39} = {E4D29906-8B73-4F8A-B5F4-CA8BFA648F5A}
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79} = {E4D29906-8B73-4F8A-B5F4-CA8BFA648F5A}
{D2396DD7-7D38-473A-ABB7-6F96D65AE1B9} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411}
{BED7539C-0099-4A14-AD5D-30828F15A171} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411}
{0D108721-EAE8-4BAF-8102-D8960EC93647} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411}
{CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411}
{B535402E-38D2-4D54-8360-423ACBD17192} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411}
EndGlobalSection
EndGlobal

View File

@ -202,12 +202,14 @@ library_include_HEADERS = \
src/include/switch_xml_config.h \
src/include/switch_cpp.h \
src/include/switch_json.h \
libs/stfu/stfu.h \
libs/libteletone/src/libteletone_detect.h \
libs/libteletone/src/libteletone_generate.h \
libs/libteletone/src/libteletone.h \
libs/libtpl-1.5/src/tpl.h \
src/include/switch_limit.h \
src/include/switch_odbc.h
src/include/switch_odbc.h \
src/include/switch_pgsql.h
nodist_libfreeswitch_la_SOURCES = \
src/include/switch_frame.h \
@ -262,6 +264,7 @@ libfreeswitch_la_SOURCES = \
src/switch_config.c \
src/switch_time.c \
src/switch_odbc.c \
src/switch_pgsql.c \
src/switch_limit.c \
src/g711.c \
src/switch_pcm.c \
@ -448,27 +451,37 @@ libs/curl/lib/libcurl.la: libs/curl libs/curl/Makefile
@cd libs/curl && $(MAKE)
@$(TOUCH_TARGET)
libs/apr/libapr-1.la: libs/apr libs/apr/.update
libs/apr/Makefile: libs/apr/Makefile.in libs/apr/config.status libs/apr libs/apr/.update
@cd libs/apr && ./config.status
@$(TOUCH_TARGET)
libs/apr/libapr-1.la: libs/apr/Makefile libs/apr/.update
touch src/include/switch.h
@cd libs/apr && $(MAKE)
@$(TOUCH_TARGET)
libs/apr-util/libaprutil-1.la: libs/apr-util libs/apr-util/.update libs/apr/libapr-1.la
touch src/include/switch.h
@cd libs/apr-util && $(MAKE)
@$(TOUCH_TARGET)
libs/speex/libspeex/libspeexdsp.la: libs/speex/.update
touch src/include/switch.h
@cd libs/speex && $(MAKE)
@$(TOUCH_TARGET)
libs/sqlite/libsqlite3.la: libs/sqlite libs/sqlite/.update
touch src/include/switch.h
@cd libs/sqlite && $(MAKE) CFLAGS="$(SWITCH_AM_CFLAGS)"
@$(TOUCH_TARGET)
libs/pcre/libpcre.la: libs/pcre libs/pcre/.update
touch src/include/switch.h
@cd libs/pcre && $(MAKE)
@$(TOUCH_TARGET)
libs/srtp/libsrtp.la: libs/srtp libs/srtp/.update
touch src/include/switch.h
@cd libs/srtp && $(MAKE)
@$(TOUCH_TARGET)
@ -593,6 +606,10 @@ version:
reinstall: modwipe uninstall install
pristine:
git clean -fdx
git reset --hard
update-clean: clean libs/openzap/Makefile python-reconf
cd libs/sofia-sip && $(MAKE) clean
cd libs/openzap && $(MAKE) clean
@ -605,13 +622,6 @@ swigall:
@echo reswigging all
sh $(switch_srcdir)/build/swigall.sh
sure: current
speedy-sure: update-clean
$(MAKE) -j core
cd libs/sofia-sip && $(MAKE) -j
$(MAKE) -j modules
speex-reconf:
cd libs/speex && autoreconf
cd libs/speex && ./config.status --recheck
@ -667,6 +677,14 @@ cluecon:
@echo
@echo http://www.cluecon.com
@sleep 5
sure: is-scm pristine update
git pull
sh bootstrap.sh
sh configure $(CONFIGURE_ARGS)
make $(MAKE_ARGS)
make reinstall
current: cluecon update-clean is-scm
$(MAKE) update
$(MAKE) all

10
build/cc.sh Normal file
View File

@ -0,0 +1,10 @@
#!/bin/sh
s=(`stty size`)
c=${s[1]}
if [ $c -gt 99 ] ; then
cat ../cluecon2.tmpl
else
cat ../cluecon2_small.tmpl
fi

View File

@ -1 +1 @@
1.2-rc3
1.2.5

View File

@ -69,15 +69,15 @@ static int print_human_version(void) {
if ((sys1(xdate,sizeof(xdate),"git log -n1 --format='%ct' HEAD"))) return 1;
xdate_t=(time_t)atoi(xdate);
if (!(xdate_tm=gmtime(&xdate_t))) return 1;
strftime(xfdate,sizeof(xfdate),"%a, %d %b %Y %H:%M:%S Z",xdate_tm);
if ((sys1(xcommit,sizeof(xcommit),"git rev-list -n1 --abbrev=10 --abbrev-commit HEAD")))
strftime(xfdate,sizeof(xfdate),"%Y-%m-%d %H:%M:%SZ",xdate_tm);
if ((sys1(xcommit,sizeof(xcommit),"git rev-list -n1 --abbrev=7 --abbrev-commit HEAD")))
return 1;
snprintf(xver,sizeof(xver),"; git at commit %s on %s",xcommit,xfdate);
snprintf(xver,sizeof(xver),"git %s %s",xcommit,xfdate);
if (show_unclean && (sys(NULL,0,"git diff-index --quiet HEAD"))) {
char buf[256], now[256]; time_t now_t=time(NULL); struct tm *now_tm;
if (!(now_tm=gmtime(&now_t))) return 1;
strftime(now,sizeof(now),"%a, %d %b %Y %H:%M:%S Z",now_tm);
snprintf(buf,sizeof(buf),"%s; unclean git build on %s",xver,now);
strftime(now,sizeof(now),"%Y-%m-%d %H:%M:%SZ",now_tm);
snprintf(buf,sizeof(buf),"%s unclean %s",xver,now);
strncpy(xver,buf,sizeof(xver));
}
printf("%s\n",xver);

View File

@ -8,9 +8,10 @@ sdir="."
check_pwd
check_input_ver_build $@
in_ver="$1"
in_hrev="$2"
if [ "$in_ver" = "auto" ]; then
in_ver="$(cat build/next-release.txt)"
fi
eval $(parse_version "$in_ver")
set_fs_ver "$gver" "$gmajor" "$gminor" "$gmicro" "$grev"
set_fs_ver "$gver" "$gmajor" "$gminor" "$gmicro" "$grev" "$in_hrev"

View File

@ -1,3 +1,3 @@
en-us-callie 1.0.18
en-us-callie 1.0.22
ru-RU-elena 1.0.13

2
cc.sh
View File

@ -1,8 +1,10 @@
cc=`cat cluecon.tmpl | sed 's/\\\\/\\\\\\\\/g' | awk '{printf "%s\\\\n", $0}' `
cc_s=`cat cluecon_small.tmpl | sed 's/\\\\/\\\\\\\\/g' | awk '{printf "%s\\\\n", $0}' `
cat <<EOF > src/include/cc.h
const char *cc = "$cc";
const char *cc_s = "$cc_s";
EOF

10
cluecon2_small.tmpl Normal file
View File

@ -0,0 +1,10 @@

.===============================================================.
| _ |
| ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |
| / __| | | | |/ _ \/ __/ _ \| '_ \ / __/ _ \| '_ ` _ \ |
| | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |
| \___|_|\__,_|\___|\___\___/|_| |_| (_) \___\___/|_| |_| |_| |
| |
.===============================================================.


8
cluecon_small.tmpl Normal file
View File

@ -0,0 +1,8 @@
.===============================================================.
| _ |
| ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |
| / __| | | | |/ _ \/ __/ _ \| '_ \ / __/ _ \| '_ ` _ \ |
| | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |
| \___|_|\__,_|\___|\___\___/|_| |_| (_) \___\___/|_| |_| |_| |
| |
.===============================================================.

View File

@ -1,13 +1,8 @@
<configuration name="java.conf" description="Java Plug-Ins">
<!-- Path to the Java 1.6 virtual machine to use -->
<javavm path="/usr/java/jdk1.6.0/jre/lib/i386/client/libjvm.so"/>
<!-- Options to pass to Java -->
<javavm path="/opt/jdk1.6.0_04/jre/lib/amd64/server/libjvm.so"/>
<options>
<!-- Your class path (make sure freeswitch.jar is on it) -->
<option value="-Djava.class.path=$${base_dir}/scripts/freeswitch.jar"/>
<!-- Enable remote debugging -->
<option value="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=127.0.0.1:8000"/>
<option value="-Djava.class.path=$${base_dir}/scripts/freeswitch.jar:$${base_dir}/scripts/example.jar"/>
<option value="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:8000"/>
</options>
<startup class="net/cog/fs/system/Control" method="startup" arg="start up arg"/>
<shutdown class="net/cog/fs/system/Control" method="shutdown" arg="shutdown arg"/>
<startup class="org/freeswitch/example/ApplicationLauncher" method="startup"/>
</configuration>

View File

@ -144,6 +144,7 @@
<param name="rtp-enable-zrtp" value="true"/>
<!-- <param name="core-db-dsn" value="pgsql://hostaddr=127.0.0.1 dbname=freeswitch user=freeswitch password='' options='-c client_min_messages=NOTICE' application_name='freeswitch'" /> -->
<!-- <param name="core-db-dsn" value="dsn:username:password" /> -->
<!--
Allow to specify the sqlite db at a different location (In this example, move it to ramdrive for

View File

@ -141,6 +141,18 @@
<!-- <action application="export" data="sip_secure_media=true"/> -->
</condition>
<!--
Since we have inbound-late-negotation on by default now the
above behavior isn't the same so you have to do one extra step.
-->
<condition field="${endpoint_disposition}" expression="^(DELAYED NEGOTIATION)"/>
<condition field="${switch_r_sdp}" expression="(AES_CM_128_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_80)" break="never">
<action application="set" data="sip_secure_media=true"/>
<!-- Offer SRTP on outbound legs if we have it on inbound. -->
<!-- <action application="export" data="sip_secure_media=true"/> -->
</condition>
<condition>
<action application="hash" data="insert/${domain_name}-spymap/${caller_id_number}/${uuid}"/>
<action application="hash" data="insert/${domain_name}-last_dial/${caller_id_number}/${destination_number}"/>

View File

@ -21,7 +21,7 @@
<!--the domain or ip (the right hand side of the @ in the addr-->
<domain name="$${domain}">
<params>
<param name="dial-string" value="{sip_invite_domain=${dialed_domain},presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}"/>
<param name="dial-string" value="{^^:sip_invite_domain=${dialed_domain}:presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(*/${dialed_user}@${dialed_domain})}"/>
</params>
<variables>

View File

@ -213,6 +213,9 @@
<!--If you have ODBC support and a working dsn you can use it instead of SQLite-->
<!--<param name="odbc-dsn" value="dsn:user:pass"/>-->
<!-- Or, if you have PGSQL support, you can use that -->
<!--<param name="odbc-dsn" value="pgsql://hostaddr=127.0.0.1 dbname=freeswitch user=freeswitch password='' options='-c client_min_messages=NOTICE' application_name='freeswitch'" />-->
<!--Uncomment to set all inbound calls to no media mode-->
<!--<param name="inbound-bypass-media" value="true"/>-->

View File

@ -212,6 +212,7 @@
<X-PRE-PROCESS cmd="set" data="dk-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="dz-ring=%(1500,3500,425)"/>
<X-PRE-PROCESS cmd="set" data="eg-ring=%(2000,1000,475,375)"/>
<X-PRE-PROCESS cmd="set" data="es-ring=%(1500,3000,425)"/>
<X-PRE-PROCESS cmd="set" data="fi-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="fr-ring=%(1500,3500,440)"/>
<X-PRE-PROCESS cmd="set" data="hk-ring=%(400,200,440,480);%(400,3000,440,480)"/>

View File

@ -3,10 +3,10 @@
# Must change all of the below together
# For a release, set revision for that tagged release as well and uncomment
AC_INIT([freeswitch], [1.2.3], BUG-REPORT-ADDRESS)
AC_INIT([freeswitch], [1.2.5.2], BUG-REPORT-ADDRESS)
AC_SUBST(SWITCH_VERSION_MAJOR, [1])
AC_SUBST(SWITCH_VERSION_MINOR, [2])
AC_SUBST(SWITCH_VERSION_MICRO, [3])
AC_SUBST(SWITCH_VERSION_MICRO, [5.2])
AC_SUBST(SWITCH_VERSION_REVISION, [])
AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, [])
@ -155,8 +155,8 @@ fi
AX_PATH_LIBGNUTLS()
# set defaults for use on all platforms
SWITCH_AM_CFLAGS="-I${switch_srcdir}/src/include -I${switch_builddir}/src/include -I${switch_srcdir}/libs/libteletone/src"
SWITCH_AM_CXXFLAGS="-I${switch_srcdir}/src/include -I${switch_builddir}/src/include -I${switch_srcdir}/libs/libteletone/src"
SWITCH_AM_CFLAGS="-I${switch_srcdir}/src/include -I${switch_builddir}/src/include -I${switch_srcdir}/libs/libteletone/src -I${switch_srcdir}/libs/stfu"
SWITCH_AM_CXXFLAGS="-I${switch_srcdir}/src/include -I${switch_builddir}/src/include -I${switch_srcdir}/libs/libteletone/src -I${switch_srcdir}/libs/stfu"
SWITCH_AM_LDFLAGS="-lm"
#set SOLINK variable based on compiler and host
@ -164,7 +164,7 @@ if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then
SOLINK="-Bdynamic -dy -G"
elif test "x${ax_cv_c_compiler_vendor}" = "xgnu" ; then
case "$host" in
*darwin10.*)
*darwin12.*|*darwin11.*|*darwin10.*)
SOLINK="-dynamic -force-flat-namespace"
;;
*darwin*)
@ -248,7 +248,7 @@ elif test "x${ax_cv_c_compiler_vendor}" = "xgnu" ; then
APR_ADDTO(SWITCH_AM_CFLAGS, -Werror)
if test "${enable_64}" = "yes"; then
case "$host" in
*darwin10.*|*darwin9.*|*darwin8.*)
*darwin12.*|*darwin11.*|*darwin10.*|*darwin9.*|*darwin8.*)
APR_ADDTO(CFLAGS, -arch x86_64)
APR_ADDTO(LDFLAGS, -arch x86_64)
APR_ADDTO(CXXFLAGS, -arch x86_64)
@ -395,7 +395,42 @@ if test "x$enable_core_odbc_support" != "xno"; then
AC_CHECK_LIB([odbc], [SQLDisconnect],, AC_MSG_ERROR([no usable libodbc; please install unixodbc devel package or equivalent]))
fi
AC_ARG_ENABLE(core-pgsql-support,
[AS_HELP_STRING([--enable-core-pgsql-support], [Compile with PGSQL Support])],,[enable_core_pgsql_support="no"])
if test x"$enable_core_pgsql_support" = x"yes" ; then
AC_PATH_PROG([PG_CONFIG], [pg_config], [no])
if test "$PG_CONFIG" != "no"; then
AC_MSG_CHECKING([for PostgreSQL libraries])
POSTGRESQL_CXXFLAGS="`$PG_CONFIG --cppflags` -I`$PG_CONFIG --includedir`"
POSTGRESQL_LDFLAGS="`$PG_CONFIG --ldflags` -L`$PG_CONFIG --libdir` -lpq"
POSTGRESQL_VERSION=`$PG_CONFIG --version | sed -e 's#PostgreSQL ##'`
POSTGRESQL_MAJOR_VERSION=`$PG_CONFIG --version | sed -re 's#PostgreSQL ([0-9]+).[0-9]+.[0-9]+#\1#'`
POSTGRESQL_MINOR_VERSION=`$PG_CONFIG --version | sed -re 's#PostgreSQL [0-9]+.([0-9]+).[0-9]+#\1#'`
POSTGRESQL_PATCH_VERSION=`$PG_CONFIG --version | sed -re 's#PostgreSQL [0-9]+.[0-9]+.([0-9]+)#\1#'`
AC_DEFINE([SWITCH_HAVE_PGSQL], [1], [Define to 1 if PostgreSQL libraries are available])
AC_DEFINE_UNQUOTED([POSTGRESQL_VERSION], "${POSTGRESQL_VERSION}", [Specifies the version of PostgreSQL we are linking against])
AC_DEFINE_UNQUOTED([POSTGRESQL_MAJOR_VERSION], ${POSTGRESQL_MAJOR_VERSION}, [Specifies the version of PostgreSQL we are linking against])
AC_DEFINE_UNQUOTED([POSTGRESQL_MINOR_VERSION], ${POSTGRESQL_MINOR_VERSION}, [Specifies the version of PostgreSQL we are linking against])
AC_DEFINE_UNQUOTED([POSTGRESQL_PATCH_VERSION], ${POSTGRESQL_PATCH_VERSION}, [Specifies the version of PostgreSQL we are linking against])
AC_CHECK_LIB([pq], [PQgetvalue],, AC_MSG_ERROR([no usable libpq; please install PostgreSQL devel package or equivalent]))
AC_MSG_RESULT([yes])
SWITCH_AM_CXXFLAGS="$POSTGRESQL_CXXFLAGS $SWITCH_AM_CXXFLAGS"
SWITCH_AM_LDFLAGS="$POSTGRESQL_LDFLAGS $SWITCH_AM_LDFLAGS"
else
AC_MSG_RESULT([no])
AC_MSG_FAILURE([Unabled to find pg_config in PATH. Is PostgreSQL installed?])
fi
fi
AC_ARG_ENABLE(deprecated-core-db-events,
[AS_HELP_STRING([--enable-deprecated-core-db-events], [Keep deprecated core db events])],,[enable_deprecated_core_db_events="no"])
if test x"$enable_deprecated_core_db_events" = x"yes" ; then
AC_DEFINE([SWITCH_DEPRECATED_CORE_DB], [1], [Define to 1 to enable deprecated core db events])
fi
AC_ARG_ENABLE(timerfd-wrapper,
[AC_HELP_STRING([--enable-timerfd-wrapper],[timerfd is in the kernel but not in your libc])],[enable_timer_fd_wrapper="$enableval"],[enable_timer_fd_wrapper="no"])
@ -419,6 +454,17 @@ PLATFORM_CORE_LDFLAGS=
PLATFORM_CORE_LIBS=
# tweak platform specific flags
case "$host" in
*darwin12.*|*darwin11.*)
APR_ADDTO(SWITCH_AM_CFLAGS, -DMACOSX)
APR_ADDTO(CFLAGS, -pipe -no-cpp-precomp -Wno-deprecated-declarations)
APR_ADDTO(LDFLAGS, -pipe -bind_at_load)
APR_ADDTO(CXXFLAGS, -pipe)
APR_REMOVEFROM(SWITCH_AM_CFLAGS, -fPIC)
if test "x$enable_core_odbc_support" != "xno"; then
APR_ADDTO([PLATFORM_CORE_LDFLAGS], [--framework CoreFoundation])
fi
APR_ADDTO([PLATFORM_CORE_LIBS], [-ldl])
;;
*darwin10.*)
APR_ADDTO(SWITCH_AM_CFLAGS, -DMACOSX)
APR_ADDTO(CFLAGS, -pipe -no-cpp-precomp)
@ -469,9 +515,8 @@ AC_SUBST(LIBTOOL_LIB_EXTEN)
# Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS([sys/types.h sys/resource.h sched.h wchar.h sys/filio.h sys/ioctl.h netdb.h execinfo.h])
AC_CHECK_HEADERS([sys/types.h sys/resource.h sched.h wchar.h sys/filio.h sys/ioctl.h sys/select.h netdb.h execinfo.h])
# for xmlrpc-c config.h
if test x"$ac_cv_header_wchar_h" = xyes; then
HAVE_WCHAR_H_DEFINE=1
else
@ -479,6 +524,31 @@ else
fi
AC_SUBST(HAVE_WCHAR_H_DEFINE)
# Needed by Abyss on Solaris:
if test x"$ac_cv_header_sys_filio_h" = xyes; then
HAVE_SYS_FILIO_H_DEFINE=1
else
HAVE_SYS_FILIO_H_DEFINE=0
fi
AC_SUBST(HAVE_SYS_FILIO_H_DEFINE)
# Needed by Abyss on Solaris:
if test x"$ac_cv_header_sys_ioctl_h" = xyes; then
HAVE_SYS_IOCTL_H_DEFINE=1
else
HAVE_SYS_IOCTL_H_DEFINE=0
fi
AC_SUBST(HAVE_SYS_IOCTL_H_DEFINE)
if test x"$ac_cv_header_sys_select_h" = xyes; then
HAVE_SYS_SELECT_H_DEFINE=1
else
HAVE_SYS_SELECT_H_DEFINE=0
fi
AC_SUBST(HAVE_SYS_SELECT_H_DEFINE)
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
@ -507,6 +577,8 @@ AX_HAVE_CPU_SET
AC_CHECK_LIB(rt, clock_gettime, [AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if you have clock_gettime()])])
AC_CHECK_LIB(rt, clock_getres, [AC_DEFINE(HAVE_CLOCK_GETRES, 1, [Define if you have clock_getres()])])
AC_CHECK_LIB(rt, clock_nanosleep, [AC_DEFINE(HAVE_CLOCK_NANOSLEEP, 1, [Define if you have clock_nanosleep()])])
AC_CHECK_LIB(pthread, pthread_setschedparam, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPARAM, 1, [Define if you have pthread_setschedparam()])])
AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket))
AC_CHECK_FILE(/dev/ptmx, [AC_DEFINE(HAVE_DEV_PTMX, 1, [Define if you have /dev/ptmx])])
@ -532,6 +604,12 @@ AC_CHECK_DECL([SCHED_RR],
#include <sched.h>
#endif])
AC_CHECK_DECL([SCHED_FIFO],
[AC_DEFINE([HAVE_SCHED_FIFO],[1],[SCHED_FIFO constant for sched_setscheduler])],,
[#ifdef HAVE_SCHED_H
#include <sched.h>
#endif])
#
# use mlockall only on linux (for now; if available)
#
@ -572,11 +650,11 @@ if test "x${ac_cv_func_sched_setscheduler}" = "xyes" -a \
then
AC_DEFINE([USE_SCHED_SETSCHEDULER],[1],[Enable round-robin scheduler using sched_setscheduler])
fi
#
# xmlrpc-c checks
#
AC_CHECK_FUNCS(setenv strtoll strtoull strtoq strtouq __strtoll __strtoull)
HAVE_LIBWWW_SSL_DEFINE=0
AC_SUBST(HAVE_LIBWWW_SSL_DEFINE)
@ -1023,8 +1101,10 @@ AC_CONFIG_FILES([Makefile
build/getg729.sh
build/freeswitch.pc
build/modmake.rules
libs/xmlrpc-c/include/xmlrpc-c/config.h
libs/xmlrpc-c/xmlrpc_config.h
libs/xmlrpc-c/config.mk
libs/xmlrpc-c/srcdir.mk
libs/xmlrpc-c/stamp-h
scripts/gentls_cert])
AM_CONDITIONAL(ISLINUX, [test `uname -s` = Linux])

View File

@ -1,5 +1,5 @@
FreeSWITCH for Debian
--------------
---------------------
This debian packaging breaks out every module of freeswitch into a
separate package, so be sure to verify that you are actually
@ -23,4 +23,4 @@ recommend doing the following:
/etc/init.d/freeswitch start
fs_cli
-- Travis Cross <tc@traviscross.com>, Sat, 5 May 2012 23:41:29 +0000
-- Travis Cross <tc@traviscross.com>, Wed, 3 Oct 2012 02:15:32 +0000

View File

@ -1,5 +1,5 @@
FreeSWITCH for Debian
--------------
---------------------
You may be reading this because you're wondering where all the files
are in debian/, such as control. You may also be here looking for the
@ -94,4 +94,4 @@ freeswitch-music-*:
git clone https://github.com/traviscross/freeswitch-sounds.git
cd freeswitch-sounds && cat debian/README.source
-- Travis Cross <tc@traviscross.com>, Tue, 4 Sep 2012 14:56:52 +0000
-- Travis Cross <tc@traviscross.com>, Wed, 3 Oct 2012 02:15:24 +0000

211
debian/bootstrap.sh vendored
View File

@ -8,16 +8,13 @@ fs_description="FreeSWITCH is a scalable open source cross-platform telephony pl
mod_build_depends="."
supported_distros="squeeze wheezy sid"
avoid_mods=(
applications/mod_fax
applications/mod_limit
applications/mod_mongo
applications/mod_mp4
applications/mod_osp
applications/mod_rad_auth
applications/mod_skel
applications/mod_soundtouch
asr_tts/mod_cepstral
asr_tts/mod_flite
codecs/mod_com_g729
codecs/mod_ilbc
codecs/mod_sangoma_codec
@ -35,6 +32,7 @@ avoid_mods=(
languages/mod_spidermonkey
sdk/autotools
xml_int/mod_xml_ldap
xml_int/mod_xml_radius
)
avoid_mods_sid=(
endpoints/mod_portaudio
@ -177,7 +175,7 @@ Build-Depends:
wget, pkg-config,
# configure options
libssl-dev, unixodbc-dev,
libncurses5-dev, libjpeg62-dev,
libncurses5-dev, libjpeg62-dev | libjpeg8-dev,
python-dev, erlang-dev,
# documentation
doxygen,
@ -322,6 +320,207 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch
This is a metapackage which depends on the packages needed for
running the FreeSWITCH vanilla example configuration.
Package: freeswitch-meta-sorbet
Architecture: any
Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
Recommends:
freeswitch-init (= \${binary:Version}),
freeswitch-meta-codecs (= \${binary:Version}),
freeswitch-music (= \${binary:Version}),
freeswitch-sounds (= \${binary:Version}),
freeswitch-mod-abstraction (= \${binary:Version}),
freeswitch-mod-avmd (= \${binary:Version}),
freeswitch-mod-blacklist (= \${binary:Version}),
freeswitch-mod-callcenter (= \${binary:Version}),
freeswitch-mod-cidlookup (= \${binary:Version}),
freeswitch-mod-commands (= \${binary:Version}),
freeswitch-mod-conference (= \${binary:Version}),
freeswitch-mod-curl (= \${binary:Version}),
freeswitch-mod-db (= \${binary:Version}),
freeswitch-mod-directory (= \${binary:Version}),
freeswitch-mod-distributor (= \${binary:Version}),
freeswitch-mod-dptools (= \${binary:Version}),
freeswitch-mod-easyroute (= \${binary:Version}),
freeswitch-mod-enum (= \${binary:Version}),
freeswitch-mod-esf (= \${binary:Version}),
freeswitch-mod-esl (= \${binary:Version}),
freeswitch-mod-expr (= \${binary:Version}),
freeswitch-mod-fifo (= \${binary:Version}),
freeswitch-mod-fsk (= \${binary:Version}),
freeswitch-mod-fsv (= \${binary:Version}),
freeswitch-mod-hash (= \${binary:Version}),
freeswitch-mod-httapi (= \${binary:Version}),
freeswitch-mod-http-cache (= \${binary:Version}),
freeswitch-mod-lcr (= \${binary:Version}),
freeswitch-mod-nibblebill (= \${binary:Version}),
freeswitch-mod-oreka (= \${binary:Version}),
freeswitch-mod-random (= \${binary:Version}),
freeswitch-mod-redis (= \${binary:Version}),
freeswitch-mod-rss (= \${binary:Version}),
freeswitch-mod-sms (= \${binary:Version}),
freeswitch-mod-snapshot (= \${binary:Version}),
freeswitch-mod-snom (= \${binary:Version}),
freeswitch-mod-sonar (= \${binary:Version}),
freeswitch-mod-soundtouch (= \${binary:Version}),
freeswitch-mod-spandsp (= \${binary:Version}),
freeswitch-mod-spy (= \${binary:Version}),
freeswitch-mod-stress (= \${binary:Version}),
freeswitch-mod-valet-parking (= \${binary:Version}),
freeswitch-mod-vmd (= \${binary:Version}),
freeswitch-mod-voicemail (= \${binary:Version}),
freeswitch-mod-voicemail-ivr (= \${binary:Version}),
freeswitch-mod-pocketsphinx (= \${binary:Version}),
freeswitch-mod-tts-commandline (= \${binary:Version}),
freeswitch-mod-dialplan-xml (= \${binary:Version}),
freeswitch-mod-html5 (= \${binary:Version}),
freeswitch-mod-loopback (= \${binary:Version}),
freeswitch-mod-rtmp (= \${binary:Version}),
freeswitch-mod-skinny (= \${binary:Version}),
freeswitch-mod-sofia (= \${binary:Version}),
freeswitch-mod-cdr-csv (= \${binary:Version}),
freeswitch-mod-cdr-sqlite (= \${binary:Version}),
freeswitch-mod-event-socket (= \${binary:Version}),
freeswitch-mod-json-cdr (= \${binary:Version}),
freeswitch-mod-local-stream (= \${binary:Version}),
freeswitch-mod-native-file (= \${binary:Version}),
freeswitch-mod-shell-stream (= \${binary:Version}),
freeswitch-mod-sndfile (= \${binary:Version}),
freeswitch-mod-tone-stream (= \${binary:Version}),
freeswitch-mod-lua (= \${binary:Version}),
freeswitch-mod-console (= \${binary:Version}),
freeswitch-mod-logfile (= \${binary:Version}),
freeswitch-mod-syslog (= \${binary:Version}),
freeswitch-mod-say-en (= \${binary:Version}),
freeswitch-mod-posix-timer (= \${binary:Version}),
freeswitch-mod-timerfd (= \${binary:Version}),
freeswitch-mod-xml-cdr (= \${binary:Version}),
freeswitch-mod-xml-curl (= \${binary:Version}),
Description: Cross-Platform Scalable Multi-Protocol Soft Switch
$(debian_wrap "${fs_description}")
.
This is a metapackage which recommends most packaged FreeSWITCH
modules except a few which aren't recommended.
Package: freeswitch-meta-all
Architecture: any
Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
Recommends:
freeswitch-init (= \${binary:Version}),
freeswitch-meta-codecs (= \${binary:Version}),
freeswitch-music (= \${binary:Version}),
freeswitch-sounds (= \${binary:Version}),
freeswitch-mod-abstraction (= \${binary:Version}),
freeswitch-mod-avmd (= \${binary:Version}),
freeswitch-mod-blacklist (= \${binary:Version}),
freeswitch-mod-callcenter (= \${binary:Version}),
freeswitch-mod-cidlookup (= \${binary:Version}),
freeswitch-mod-cluechoo (= \${binary:Version}),
freeswitch-mod-commands (= \${binary:Version}),
freeswitch-mod-conference (= \${binary:Version}),
freeswitch-mod-curl (= \${binary:Version}),
freeswitch-mod-db (= \${binary:Version}),
freeswitch-mod-directory (= \${binary:Version}),
freeswitch-mod-distributor (= \${binary:Version}),
freeswitch-mod-dptools (= \${binary:Version}),
freeswitch-mod-easyroute (= \${binary:Version}),
freeswitch-mod-enum (= \${binary:Version}),
freeswitch-mod-esf (= \${binary:Version}),
freeswitch-mod-esl (= \${binary:Version}),
freeswitch-mod-expr (= \${binary:Version}),
freeswitch-mod-fifo (= \${binary:Version}),
freeswitch-mod-fsk (= \${binary:Version}),
freeswitch-mod-fsv (= \${binary:Version}),
freeswitch-mod-hash (= \${binary:Version}),
freeswitch-mod-httapi (= \${binary:Version}),
freeswitch-mod-http-cache (= \${binary:Version}),
freeswitch-mod-ladspa (= \${binary:Version}),
freeswitch-mod-lcr (= \${binary:Version}),
freeswitch-mod-memcache (= \${binary:Version}),
freeswitch-mod-nibblebill (= \${binary:Version}),
freeswitch-mod-oreka (= \${binary:Version}),
freeswitch-mod-random (= \${binary:Version}),
freeswitch-mod-redis (= \${binary:Version}),
freeswitch-mod-rss (= \${binary:Version}),
freeswitch-mod-sms (= \${binary:Version}),
freeswitch-mod-snapshot (= \${binary:Version}),
freeswitch-mod-snipe-hunt (= \${binary:Version}),
freeswitch-mod-snom (= \${binary:Version}),
freeswitch-mod-sonar (= \${binary:Version}),
freeswitch-mod-soundtouch (= \${binary:Version}),
freeswitch-mod-spandsp (= \${binary:Version}),
freeswitch-mod-spy (= \${binary:Version}),
freeswitch-mod-stress (= \${binary:Version}),
freeswitch-mod-valet-parking (= \${binary:Version}),
freeswitch-mod-vmd (= \${binary:Version}),
freeswitch-mod-voicemail (= \${binary:Version}),
freeswitch-mod-voicemail-ivr (= \${binary:Version}),
freeswitch-mod-pocketsphinx (= \${binary:Version}),
freeswitch-mod-tts-commandline (= \${binary:Version}),
freeswitch-mod-dialplan-asterisk (= \${binary:Version}),
freeswitch-mod-dialplan-directory (= \${binary:Version}),
freeswitch-mod-dialplan-xml (= \${binary:Version}),
freeswitch-mod-ldap (= \${binary:Version}),
freeswitch-mod-alsa (= \${binary:Version}),
freeswitch-mod-dingaling (= \${binary:Version}),
freeswitch-mod-html5 (= \${binary:Version}),
freeswitch-mod-loopback (= \${binary:Version}),
freeswitch-mod-rtmp (= \${binary:Version}),
freeswitch-mod-skinny (= \${binary:Version}),
freeswitch-mod-sofia (= \${binary:Version}),
freeswitch-mod-cdr-csv (= \${binary:Version}),
freeswitch-mod-cdr-mongodb (= \${binary:Version}),
freeswitch-mod-cdr-pg-csv (= \${binary:Version}),
freeswitch-mod-cdr-sqlite (= \${binary:Version}),
freeswitch-mod-erlang-event (= \${binary:Version}),
freeswitch-mod-event-multicast (= \${binary:Version}),
freeswitch-mod-event-socket (= \${binary:Version}),
freeswitch-mod-event-test (= \${binary:Version}),
freeswitch-mod-event-zmq (= \${binary:Version}),
freeswitch-mod-json-cdr (= \${binary:Version}),
freeswitch-mod-radius-cdr (= \${binary:Version}),
freeswitch-mod-snmp (= \${binary:Version}),
freeswitch-mod-local-stream (= \${binary:Version}),
freeswitch-mod-native-file (= \${binary:Version}),
freeswitch-mod-shell-stream (= \${binary:Version}),
freeswitch-mod-sndfile (= \${binary:Version}),
freeswitch-mod-tone-stream (= \${binary:Version}),
freeswitch-mod-java (= \${binary:Version}),
freeswitch-mod-lua (= \${binary:Version}),
freeswitch-mod-perl (= \${binary:Version}),
freeswitch-mod-python (= \${binary:Version}),
freeswitch-mod-yaml (= \${binary:Version}),
freeswitch-mod-console (= \${binary:Version}),
freeswitch-mod-logfile (= \${binary:Version}),
freeswitch-mod-syslog (= \${binary:Version}),
freeswitch-mod-say-en (= \${binary:Version}),
freeswitch-mod-posix-timer (= \${binary:Version}),
freeswitch-mod-timerfd (= \${binary:Version}),
freeswitch-mod-xml-cdr (= \${binary:Version}),
freeswitch-mod-xml-curl (= \${binary:Version}),
freeswitch-mod-xml-rpc (= \${binary:Version}),
freeswitch-mod-xml-scgi (= \${binary:Version}),
Suggests:
freeswitch-mod-vlc (= \${binary:Version}),
freeswitch-mod-say-de (= \${binary:Version}),
freeswitch-mod-say-es (= \${binary:Version}),
freeswitch-mod-say-fa (= \${binary:Version}),
freeswitch-mod-say-fr (= \${binary:Version}),
freeswitch-mod-say-he (= \${binary:Version}),
freeswitch-mod-say-hr (= \${binary:Version}),
freeswitch-mod-say-hu (= \${binary:Version}),
freeswitch-mod-say-it (= \${binary:Version}),
freeswitch-mod-say-ja (= \${binary:Version}),
freeswitch-mod-say-nl (= \${binary:Version}),
freeswitch-mod-say-pt (= \${binary:Version}),
freeswitch-mod-say-ru (= \${binary:Version}),
freeswitch-mod-say-th (= \${binary:Version}),
freeswitch-mod-say-zh (= \${binary:Version}),
Description: Cross-Platform Scalable Multi-Protocol Soft Switch
$(debian_wrap "${fs_description}")
.
This is a metapackage which recommends or suggests all packaged
FreeSWITCH modules.
Package: freeswitch-meta-codecs
Architecture: any
Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
@ -333,12 +532,14 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
freeswitch-mod-g723-1 (= \${binary:Version}),
freeswitch-mod-g729 (= \${binary:Version}),
freeswitch-mod-h26x (= \${binary:Version}),
freeswitch-mod-isac (= \${binary:Version}),
freeswitch-mod-mp4v (= \${binary:Version}),
freeswitch-mod-opus (= \${binary:Version}),
freeswitch-mod-silk (= \${binary:Version}),
freeswitch-mod-spandsp (= \${binary:Version}),
freeswitch-mod-speex (= \${binary:Version}),
freeswitch-mod-theora (= \${binary:Version})
freeswitch-mod-theora (= \${binary:Version}),
freeswitch-mod-vp8 (= \${binary:Version})
Suggests:
freeswitch-mod-ilbc (= \${binary:Version}),
freeswitch-mod-siren (= \${binary:Version})

View File

@ -79,10 +79,6 @@ Module: applications/mod_expr
Description: Expr
This module adds expr support for expression evaluation.
Module: applications/mod_fax
Description: Fax
This module adds fax support provided by Steve Underwood's SpanDSP.
Module: applications/mod_fifo
Description: FIFO
This module adds a first-in first-out queue system.
@ -147,6 +143,11 @@ Description: Nibblebill
This module allows for real-time accounting of a cash balance and
using that information for call routing.
Module: applications/mod_oreka
Description: Media recording with Oreka
This module provides media recording with the Oreka cross-platfor
audio stream recording and retrieval system.
Module: applications/mod_osp
Description: Open Settlement Protocol
This module adds support for the Open Settlement Protocol (OSP).
@ -192,6 +193,11 @@ Module: applications/mod_snom
Description: SNOM specific features
This module implements features specific to SNOM phones.
Module: applications/mod_sonar
Description: Sonar ping timer
This module measures the latency on an audio link by sending audible
audio sonar pings.
Module: applications/mod_soundtouch
Description: Soundtouch
This module implements example media bugs.
@ -335,6 +341,10 @@ Module: codecs/mod_voipcodecs
Description: mod_voipcodecs
Adds mod_voipcodecs.
Module: codecs/mod_vp8
Description: VP8 video codec
This module adds the VP8 video codec, also known as WebM.
## mod/dialplans
Module: dialplans/mod_dialplan_asterisk
@ -374,7 +384,11 @@ Build-Depends: libx11-dev
Module: endpoints/mod_h323
Description: mod_h323
Adds mod_h323.
Build-Depends: libopenh323-dev, libpt-dev
Build-Depends: libopenh323-dev | libh323plus-dev, libpt-dev
Module: endpoints/mod_html5
Description: HTML5 endpoint module
This module adds support for HTML5 technologies such as WebRTC.
Module: endpoints/mod_khomp
Description: mod_khomp
@ -497,6 +511,7 @@ Build-Depends: libogg-dev, libvorbis-dev
Module: formats/mod_sndfile
Description: mod_sndfile
Adds mod_sndfile.
Build-Depends: libflac-dev, libogg-dev, libvorbis-dev
Module: formats/mod_tone_stream
Description: mod_tone_stream
@ -651,6 +666,10 @@ Description: mod_xml_ldap
Adds mod_xml_ldap.
Build-Depends: libsasl2-dev
Module: xml_int/mod_xml_radius
Description: mod_xml_radius
Adds mod_xml_radius
Module: xml_int/mod_xml_rpc
Description: mod_xml_rpc
Adds mod_xml_rpc.

2
debian/rules vendored
View File

@ -6,7 +6,7 @@
FS_CC?=gcc
FS_CXX?=g++
FS_CFLAGS?=-ggdb3 -O2
FS_CFLAGS?=-ggdb3 -O2 -fPIC
FS_CPPFLAGS?=
FS_CXXFLAGS?=$(FS_CFLAGS)
export PATH?=/usr/lib/ccache:/usr/sbin:/usr/bin:/sbin:/bin

16
debian/util.sh vendored
View File

@ -140,14 +140,18 @@ get_last_release_ver () {
get_nightly_version () {
local commit="$(git rev-list -n1 --abbrev=10 --abbrev-commit HEAD)"
echo "$(get_last_release_ver)+git~$(date +%Y%m%dT%H%M%SZ)~$commit"
echo "$(get_last_release_ver)+git~$(date -u '+%Y%m%dT%H%M%SZ')~$commit"
}
get_nightly_revision_human () {
echo "git $(git rev-list -n1 --abbrev=7 --abbrev-commit HEAD) $(date -u '+%Y-%m-%d %H:%M:%SZ')"
}
create_orig () {
{
set -e
local OPTIND OPTARG
local uver="" bundle_deps=false zl=9e
local uver="" hrev="" bundle_deps=false zl=9e
while getopts 'bnv:z:' o "$@"; do
case "$o" in
b) bundle_deps=true;;
@ -157,8 +161,10 @@ create_orig () {
esac
done
shift $(($OPTIND-1))
[ -z "$uver" ] || [ "$uver" = "nightly" ] \
&& uver="$(get_nightly_version)"
if [ -z "$uver" ] || [ "$uver" = "nightly" ]; then
uver="$(get_nightly_version)"
hrev="$(get_nightly_revision_human)"
fi
local treeish="$1" dver="$(mk_dver "$uver")"
local orig="../freeswitch_$dver.orig.tar.xz"
[ -n "$treeish" ] || treeish="HEAD"
@ -175,7 +181,7 @@ create_orig () {
(cd libs && getlibs)
git add -f libs
fi
./build/set-fs-version.sh "$uver" && git add configure.in
./build/set-fs-version.sh "$uver" "$hrev" && git add configure.in
echo "$uver" > .version && git add -f .version
git commit --allow-empty -m "nightly v$uver"
git archive -v \

View File

@ -1,3 +1,46 @@
freeswitch (1.2.5)
mod_lua: Enable mod_lua to use native pgsql dbh support (r:2cea7f0f)
mod_sofia: Add att_xfer_destination_number variable to indicate the original destination number of the attended transfer leg on REFER for semi-attended transfer scenarios. (r:893cd7be)
sounds: Bump Callie sounds ver to 1.0.22 (r:41e00c78)
freeswitch (1.2.4)
core: Add Postgres core db support (r:0c1180d5)
mod_cdr_mongodb: update MongoDB driver to v0.6 (r:10093b44)
mod_dingaling: do lookup in dingaling when an address is specified as host:foo.bar.com like sofia does (r:fbfe830a)
freeswitch (1.2.3)
core: add hold_events variable with start and stop times for each hold (r:9a193a9c)
core: update json lib in core and ESL and re-apply old patches (r:5a956890)
core: add skip_cdr_causes variable to list call hangup causes that should not trigger cdr processing (r:3cf238fc)
formats: add mod_mp4v2 for mp4 recording, most things are hardcodec, but it should work with 8000hz audio and H264 video (r:7e01bd10)
freetdm: M2UA Signaling gateway support (SIGTRAN)
freetdm: New TDM endpoint for raw IO access to boards (controllable channel)
freetdm: New dialplan paramters and SIP X headers to set ISUP message information elements
freetdm: Misc ISUP bug fixes
libsofia: Fix DoS vulnerability in processing Route Header (r:016550f2/FS-4627)
libtpl: add tpl to tree (r:4985a41f)
mod_sofia: add transfer_to variable for call processing (r:1b2b4565)
freeswitch (1.2.2)
configuration: Add language config files for es-ES,es-MX,pt-BR,pt-PT (Thanks Francois Delawarde) (r:9cde99b4/FS-3003)
core: move recovery engine up into the core (r:66677c94)
core: add ignore_early_media=consume to ivr_originate (r:13dab11c)
core: add timestamps for on and off hold times to put in xml cdrs (r:b0e49d3e)
libtiff: update to 4.0.2 (r:a2b5af56)
mod_commands: add uuid_answer and uuid_pre_answer (r:ce88d572)
mod_commands: add uuid_early_ok (r:35f0e2ff)
mod_commands: add uuid_media_reneg api command to tell a channel to send a re-invite with optional list of new codecs (r:bfc46567)
mod_dptools: mutex app (r:212953bc)
mod_httapi: add cache param (r:a8b89bcc)
mod_sofia: change mod_sofia to use new core based recovery engine (r:2a8841ab)
mod_sofia: fire-message-events profile param (r:9c06cb34)
mod_sofia: add send-display-update profile param to disable the update method (r:8f0c726b)
mod_spidermonkey: add email function to js (r:37b36aea)
freeswitch (1.2.1)
libapr: Updating in tree apr for 1.4.6 (r:4029614e)
libwebsockets: Initial commit (r:6fa2fd36)
mod_sofia: add rtp endpoint contributed by sangoma (r:ef5c1256)
mod_spidermonkey: add javascript chatplan app (r:61839229)
freeswitch (1.2.0)
build: Automated builds for CI testing/Jenkins (r:2aff535a)
build: add debian source package building script (r:c164aae9)

View File

@ -511,7 +511,7 @@
<prompt phrase="There is..." filename="ivr-there_is.wav"/>
<prompt phrase="That number is on the Do Not Call list." filename="ivr-do_not_call_list.wav"/>
<prompt phrase="The call attempt has been aborted." filename="ivr-call_attempt_aborted.wav"/>
<prompt phrase="To wait for the next available representative, please stay on the line." filename="ivr_to_wait_stay_on_the_line.wav"/>
<prompt phrase="To wait for the next available representative, please stay on the line." filename="ivr-to_wait_stay_on_the_line.wav"/>
<prompt phrase="If you would like us to call you back, press..." filename="ivr-if_you_would_like_us_to_call_back.wav"/>
<prompt phrase="It appears that your phone number is..." filename="ivr-it_appears_that_your_phone_number_is.wav"/>
<prompt phrase="Would you like to receive a call at this number?" filename="ivr-would_you_like_to_receive_a_call_at_this_number.wav"/>

View File

@ -1118,6 +1118,22 @@ Requires: %{name} = %{version}-%{release}
%description lang-he
Hebrew language phrases module and directory structure for say module and voicemail
%package lang-es
Summary: Provides Spanish language dependend modules and speech config for the FreeSWITCH Open Source telephone platform.
Group: System/Libraries
Requires: %{name} = %{version}-%{release}
%description lang-es
Spanish language phrases module and directory structure for say module and voicemail
%package lang-pt
Summary: Provides Portugese language dependend modules and speech config for the FreeSWITCH Open Source telephone platform.
Group: System/Libraries
Requires: %{name} = %{version}-%{release}
%description lang-pt
Hebrew language phrases module and directory structure for say module and voicemail
######################################################################################################################
# FreeSWITCH Timer Modules
######################################################################################################################
@ -1733,6 +1749,7 @@ fi
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/mongo.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/nibblebill.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/opal.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/oreka.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/osp.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/pocketsphinx.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/portaudio.conf.xml
@ -2296,6 +2313,30 @@ fi
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/he/dir/*.xml
%{MODINSTDIR}/mod_say_he.so*
%files lang-es
%defattr(-, freeswitch, daemon)
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/es
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/es/demo
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/es/vm
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/es/dir
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/demo/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/vm/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/dir/*.xml
%{MODINSTDIR}/mod_say_en.so*
%files lang-pt
%defattr(-, freeswitch, daemon)
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/pt
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/pt/demo
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/pt/vm
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/pt/dir
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/demo/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/vm/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/dir/*.xml
%{MODINSTDIR}/mod_say_en.so*
######################################################################################################################
#
# Timer Modules
@ -2332,6 +2373,8 @@ fi
#
######################################################################################################################
%changelog
* Thu Sep 19 2012 - krice@freeswitch.org
- Add support for Spanish and Portugese say language modules
* Thu Jan 26 2012 - krice@freeswitch.org
- complete rework of spec file
* Tue Jun 14 2011 - michal.bielicki@seventhsignal.de

50
libs/.gitignore vendored
View File

@ -341,6 +341,19 @@ opal
/libsndfile/tests/test_wrapper.sh
/libsndfile/Win32/Makefile
/libsndfile/Win32/Makefile.in
/libwebsockets/Makefile
/libwebsockets/Makefile.in
/libwebsockets/config.h
/libwebsockets/lib/Makefile
/libwebsockets/lib/Makefile.in
/libwebsockets/m4/libtool.m4
/libwebsockets/m4/ltoptions.m4
/libwebsockets/m4/ltsugar.m4
/libwebsockets/m4/ltversion.m4
/libwebsockets/m4/lt~obsolete.m4
/libwebsockets/stamp-h1
/libwebsockets/test-server/Makefile
/libwebsockets/test-server/Makefile.in
/mongo-cxx-driver-v*/
/mpg123/
/openldap-*/
@ -678,6 +691,9 @@ opal
/srtp/Makefile.in
/srtp/test/Makefile
/srtp/test/Makefile.in
/tiff-*/build/Makefile
/tiff-*/build/Makefile.in
/tiff-*/tools/tiffcrop
/tiff-*/contrib/acorn/Makefile
/tiff-*/contrib/acorn/Makefile.in
/tiff-*/contrib/addtiffo/addtiffo
@ -868,11 +884,40 @@ opal
/win32/libshout/*/*/libshout.log
/win32/pcre/pcre_chartables.c
/win32/tmp*.bat
/xmlrpc-c/include/xmlrpc-c/config.h
!/xmlrpc-c/include/xmlrpc-c/config.h.in
/xmlrpc-c/stamp-h2
/xmlrpc-c/xmlrpc_amconfig.h
/xmlrpc-c/examples/config.h
/xmlrpc-c/include/xmlrpc-c/config.h
/xmlrpc-c/transport_config.h
/xmlrpc-c/version.h
/xmlrpc-c/xmlrpc_config.h
/xmlrpc-c/xmlrpc_amconfig.h
/xmlrpc-c/config.mk
/xmlrpc-c/lib/expat/gennmtab/depend.mk
/xmlrpc-c/lib/expat/gennmtab/gennmtab
/xmlrpc-c/lib/expat/xmlparse/depend.mk
/xmlrpc-c/lib/expat/xmlparse/srcdir
/xmlrpc-c/lib/expat/xmltok/blddir
/xmlrpc-c/lib/expat/xmltok/depend.mk
/xmlrpc-c/lib/expat/xmltok/srcdir
/xmlrpc-c/lib/libutil/blddir
/xmlrpc-c/lib/libutil/depend.mk
/xmlrpc-c/lib/libutil/srcdir
/xmlrpc-c/lib/util/blddir
/xmlrpc-c/lib/util/depend.mk
/xmlrpc-c/lib/util/srcdir
/xmlrpc-c/src/blddir
/xmlrpc-c/src/depend.mk
/xmlrpc-c/src/srcdir
/xmlrpc-c/src/test/blddir
/xmlrpc-c/src/test/depend.mk
/xmlrpc-c/src/test/srcdir
/xmlrpc-c/srcdir.mk
/xmlrpc-c/stamp-h
/xmlrpc-c/tools/lib/blddir
/xmlrpc-c/tools/lib/depend.mk
/xmlrpc-c/tools/lib/srcdir
/yaml/
/yaml/config.h
/yaml/stamp-h1
@ -928,4 +973,3 @@ opal
!/yaml/config/ltmain.sh
!/yaml/config/missing
!/yaml/configure

View File

@ -1 +1 @@
Mon Sep 27 13:15:54 CDT 2010
Wed Nov 7 10:37:54 CST 2012

View File

@ -66,6 +66,18 @@ apr-config.out: $(APR_CONFIG)
build/apr_rules.out: build/apr_rules.mk
sed 's,^\(apr_build.*=\).*$$,\1$(installbuilddir),' < build/apr_rules.mk > $@
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_blddir)/config.status
cd $(srcdir) && ./config.status
$(top_blddir)/config.status: $(top_srcdir)/configure
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: $(top_srcdir)/configure.in
cd $(srcdir) && autoconf
cd $(srcdir) && autoheader
install: $(TARGET_LIB) apr-config.out build/apr_rules.out
$(APR_MKDIR) $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) $(DESTDIR)$(installbuilddir) \
$(DESTDIR)$(libdir)/pkgconfig $(DESTDIR)$(includedir)

View File

@ -550,6 +550,7 @@ AC_CHECK_LIB(truerand, main)
AC_SEARCH_LIBS(modf, m)
AC_CHECK_LIB(dl, dlopen)
dnl ----------------------------- Checking for Threads
echo "${nl}Checking for Threads..."
@ -1619,6 +1620,8 @@ APR_CHECK_DEFINE_FILES(POLLIN, poll.h sys/poll.h)
if test "$threads" = "1"; then
APR_CHECK_DEFINE(PTHREAD_PROCESS_SHARED, pthread.h)
AC_CHECK_FUNCS(pthread_mutexattr_setpshared)
AC_CHECK_LIB(pthread, pthread_setschedparam, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPARAM, 1, [Define if you have pthread_setschedparam()])])
# Some systems have setpshared and define PROCESS_SHARED, but don't
# really support PROCESS_SHARED locks. So, we must validate that we
# can go through the steps without receiving some sort of system error.

View File

@ -60,6 +60,7 @@ struct apr_thread_t {
struct apr_threadattr_t {
apr_pool_t *pool;
pthread_attr_t attr;
int priority;
};
struct apr_threadkey_t {

View File

@ -146,6 +146,7 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new,
{
apr_status_t stat;
pthread_attr_t *temp;
pthread_t tt;
(*new) = (apr_thread_t *)apr_pcalloc(pool, sizeof(apr_thread_t));
@ -173,7 +174,21 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new,
return stat;
}
if ((stat = pthread_create((*new)->td, temp, dummy_worker, (*new))) == 0) {
if ((stat = pthread_create(&tt, temp, dummy_worker, (*new))) == 0) {
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
if (attr && attr->priority) {
int policy;
struct sched_param param = { 0 };
pthread_getschedparam(tt, &policy, &param);
param.sched_priority = attr->priority;
pthread_setschedparam(tt, policy, &param);
}
#endif
*(*new)->td = tt;
return APR_SUCCESS;
}
else {

View File

@ -39,6 +39,7 @@
#define KEY_RIGHT 7
#define KEY_INSERT 8
#define PROMPT_OP 9
#define KEY_DELETE 10
static int console_bufferInput (char *buf, int len, char *cmd, int key);
static unsigned char esl_console_complete(const char *buffer, const char *cursor, const char *lastchar);
#endif
@ -116,6 +117,31 @@ static void clear_cli(void) {
fflush(stdout);
}
static void screen_size(int *x, int *y)
{
#ifdef WIN32
CONSOLE_SCREEN_BUFFER_INFO csbi;
int ret;
if ((ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ), &csbi))) {
if (x) *x = csbi.dwSize.X;
if (y) *y = csbi.dwSize.Y;
}
#elif defined(TIOCGWINSZ)
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
if (x) *x = w.ws_col;
if (y) *y = w.ws_row;
#else
if (x) *x = 80;
if (y) *y = 24;
#endif
}
/* If a fnkey is configured then process the command */
static unsigned char console_fnkey_pressed(int i)
{
@ -293,6 +319,22 @@ static int console_bufferInput (char *addchars, int len, char *cmd, int key)
if (key == KEY_INSERT) {
insertMode = !insertMode;
}
if (key == KEY_DELETE) {
if (iCmdCursor < iCmdBuffer) {
int pos;
for (pos = iCmdCursor; pos < iCmdBuffer; pos++) {
cmd[pos] = cmd[pos + 1];
}
cmd[pos] = 0;
iCmdBuffer--;
for (pos = iCmdCursor; pos < iCmdBuffer; pos++) {
printf("%c", cmd[pos]);
}
printf(" ");
SetConsoleCursorPosition(hOut, position);
}
}
for (iBuf = 0; iBuf < len; iBuf++) {
switch (addchars[iBuf]) {
case '\r':
@ -485,6 +527,9 @@ static BOOL console_readConsole(HANDLE conIn, char *buf, int len, int *pRed, int
if (keyEvent.wVirtualKeyCode == 45 && keyEvent.wVirtualScanCode == 82) {
*key = KEY_INSERT;
}
if (keyEvent.wVirtualKeyCode == 46 && keyEvent.wVirtualScanCode == 83) {
*key = KEY_DELETE;
}
while (keyEvent.wRepeatCount && keyEvent.uChar.AsciiChar) {
buf[bufferIndex] = keyEvent.uChar.AsciiChar;
if (buf[bufferIndex] == '\r') {
@ -923,13 +968,19 @@ static const char *inf = "Type /help <enter> to see a list of commands\n\n\n";
static void print_banner(FILE *stream)
{
int x;
const char *use = NULL;
#include <cc.h>
screen_size(&x, NULL);
use = (x > 100) ? cc : cc_s;
#ifdef WIN32
/* Print banner in yellow with blue background */
SetConsoleTextAttribute(hStdout, ESL_SEQ_FYELLOW | BACKGROUND_BLUE);
WriteFile(hStdout, banner, (DWORD) strlen(banner), NULL, NULL);
WriteFile(hStdout, cc, (DWORD) strlen(cc), NULL, NULL);
WriteFile(hStdout, use, (DWORD) strlen(use), NULL, NULL);
SetConsoleTextAttribute(hStdout, wOldColorAttrs);
/* Print the rest info in default colors */
@ -940,10 +991,14 @@ static void print_banner(FILE *stream)
ESL_SEQ_DEFAULT_COLOR,
ESL_SEQ_FYELLOW, ESL_SEQ_BBLUE,
banner,
cc, ESL_SEQ_DEFAULT_COLOR, inf);
use, ESL_SEQ_DEFAULT_COLOR, inf);
fprintf(stream, "%s", output_text_color);
#endif
if (x < 160) {
fprintf(stream, "\n[This app Best viewed at 160x60 or more..]\n");
}
}
static void set_fn_keys(cli_profile_t *profile)
@ -1465,6 +1520,9 @@ int main(int argc, char *argv[])
el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete);
el_set(el, EL_BIND, "^I", "ed-complete", NULL);
/* "Delete" key. */
el_set(el, EL_BIND, "\033[3~", "ed-delete-next-char", NULL);
if (!(myhistory = history_init())) {
esl_log(ESL_LOG_ERROR, "history could not be initialized\n");
goto done;

View File

@ -916,6 +916,9 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *
int rval = 0;
const char *hval;
struct addrinfo hints = { 0 }, *result;
struct sockaddr_in *sockaddr_in;
struct sockaddr_in6 *sockaddr_in6;
socklen_t socklen;
#ifndef WIN32
int fd_flags = 0;
#else
@ -936,27 +939,38 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *
if (!handle->packet_buf) {
esl_buffer_create(&handle->packet_buf, BUF_CHUNK, BUF_START, 0);
}
handle->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (handle->sock == ESL_SOCK_INVALID) {
snprintf(handle->err, sizeof(handle->err), "Socket Error");
return ESL_FAIL;
}
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(host, NULL, &hints, &result)) {
strncpy(handle->err, "Cannot resolve host", sizeof(handle->err));
goto fail;
}
memcpy(&handle->sockaddr, result->ai_addr, sizeof(handle->sockaddr));
handle->sockaddr.sin_family = AF_INET;
handle->sockaddr.sin_port = htons(port);
switch(handle->sockaddr.ss_family) {
case AF_INET:
sockaddr_in = (struct sockaddr_in*)&(handle->sockaddr);
sockaddr_in->sin_port = htons(port);
socklen = sizeof(struct sockaddr_in);
break;
case AF_INET6:
sockaddr_in6 = (struct sockaddr_in6*)&(handle->sockaddr);
sockaddr_in6->sin6_port = htons(port);
socklen = sizeof(struct sockaddr_in6);
break;
default:
strncpy(handle->err, "Host resolves to unsupported address family", sizeof(handle->err));
goto fail;
}
freeaddrinfo(result);
handle->sock = socket(handle->sockaddr.ss_family, SOCK_STREAM, IPPROTO_TCP);
if (handle->sock == ESL_SOCK_INVALID) {
snprintf(handle->err, sizeof(handle->err), "Socket Error");
return ESL_FAIL;
}
if (timeout) {
#ifdef WIN32
@ -974,7 +988,7 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *
#endif
}
rval = connect(handle->sock, (struct sockaddr*)&handle->sockaddr, sizeof(handle->sockaddr));
rval = connect(handle->sock, (struct sockaddr*)&handle->sockaddr, socklen);
if (timeout) {
int r;

View File

@ -552,7 +552,12 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st
esl_assert(hv);
header->value = hv;
esl_snprintf(header->value, len, "ARRAY::");
if (header->idx > 1) {
esl_snprintf(header->value, len, "ARRAY::");
} else {
*header->value = '\0';
}
for(j = 0; j < header->idx; j++) {
esl_snprintf(header->value + strlen(header->value), len - strlen(header->value), "%s%s", j == 0 ? "" : "|:", header->array[j]);
}

View File

@ -35,7 +35,7 @@
static const char *ep;
ESL_DECLARE(const char *)cJSON_GetErrorPtr() {return ep;}
ESL_DECLARE(const char *)cJSON_GetErrorPtr(void) {return ep;}
static int cJSON_strcasecmp(const char *s1,const char *s2)
{
@ -82,7 +82,7 @@ ESL_DECLARE(void)cJSON_InitHooks(cJSON_Hooks* hooks)
}
/* Internal constructor. */
static cJSON *cJSON_New_Item()
static cJSON *cJSON_New_Item(void)
{
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
if (node) memset(node,0,sizeof(cJSON));
@ -513,14 +513,14 @@ ESL_DECLARE(void) cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newite
ESL_DECLARE(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
/* Create basic types: */
ESL_DECLARE(cJSON *)cJSON_CreateNull() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
ESL_DECLARE(cJSON *)cJSON_CreateTrue() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
ESL_DECLARE(cJSON *)cJSON_CreateFalse() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
ESL_DECLARE(cJSON *)cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
ESL_DECLARE(cJSON *)cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
ESL_DECLARE(cJSON *)cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
ESL_DECLARE(cJSON *)cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
ESL_DECLARE(cJSON *)cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
ESL_DECLARE(cJSON *)cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
ESL_DECLARE(cJSON *)cJSON_CreateArray() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
ESL_DECLARE(cJSON *)cJSON_CreateObject() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
ESL_DECLARE(cJSON *)cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
ESL_DECLARE(cJSON *)cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
/* Create Arrays: */
ESL_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}

View File

@ -1,2 +1,4 @@
const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n";
const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n";
const char *cc_s = ".===============================================================.\n| _ |\n| ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.===============================================================.\n";

View File

@ -221,6 +221,7 @@ typedef enum {
#include <winsock2.h>
#include <windows.h>
typedef SOCKET esl_socket_t;
#if !defined(_STDINT) && !defined(uint32_t)
typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
@ -229,6 +230,7 @@ typedef __int64 int64_t;
typedef __int32 int32_t;
typedef __int16 int16_t;
typedef __int8 int8_t;
#endif
typedef intptr_t esl_ssize_t;
typedef int esl_filehandle_t;
#define ESL_SOCK_INVALID INVALID_SOCKET
@ -286,7 +288,7 @@ typedef enum {
/*! \brief A handle that will hold the socket information and
different events received. */
typedef struct {
struct sockaddr_in sockaddr;
struct sockaddr_storage sockaddr;
struct hostent hostent;
char hostbuf[256];
esl_socket_t sock;

View File

@ -79,17 +79,17 @@ ESL_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item);
ESL_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
ESL_DECLARE(const char *)cJSON_GetErrorPtr();
ESL_DECLARE(const char *)cJSON_GetErrorPtr(void);
/* These calls create a cJSON item of the appropriate type. */
ESL_DECLARE(cJSON *)cJSON_CreateNull();
ESL_DECLARE(cJSON *)cJSON_CreateTrue();
ESL_DECLARE(cJSON *)cJSON_CreateFalse();
ESL_DECLARE(cJSON *)cJSON_CreateNull(void);
ESL_DECLARE(cJSON *)cJSON_CreateTrue(void);
ESL_DECLARE(cJSON *)cJSON_CreateFalse(void);
ESL_DECLARE(cJSON *)cJSON_CreateBool(int b);
ESL_DECLARE(cJSON *)cJSON_CreateNumber(double num);
ESL_DECLARE(cJSON *)cJSON_CreateString(const char *string);
ESL_DECLARE(cJSON *)cJSON_CreateArray();
ESL_DECLARE(cJSON *)cJSON_CreateObject();
ESL_DECLARE(cJSON *)cJSON_CreateArray(void);
ESL_DECLARE(cJSON *)cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
ESL_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count);

View File

@ -1318,6 +1318,9 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
if (!zstr(outbound_profile->caller_id_number)) {
callerid_num = switch_sanitize_number(switch_core_strdup(outbound_profile->pool, outbound_profile->caller_id_number));
if ( callerid_num && *callerid_num == '+' ) {
callerid_num++;
}
}
if (!zstr(callerid_num) && !strcmp(callerid_num, SWITCH_DEFAULT_CLID_NUMBER)) {
@ -1394,6 +1397,9 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CallerNumber");
if (sipvar) {
if ( *sipvar == '+' ) {
sipvar++;
}
ftdm_set_string(caller_data.cid_num.digits, sipvar);
}
@ -1653,7 +1659,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
caller_data.rdnis.plan = outbound_profile->rdnis_numplan;
ftdm_set_string(caller_data.cid_name, outbound_profile->caller_id_name);
ftdm_set_string(caller_data.cid_num.digits, switch_str_nil(outbound_profile->caller_id_number));
ftdm_set_string(caller_data.cid_num.digits, switch_str_nil(callerid_num));
memset(&hunting, 0, sizeof(hunting));

View File

@ -4735,7 +4735,7 @@ static void print_core_usage(ftdm_stream_handle_t *stream)
static unsigned long long ftdm_str2val(const char *str, val_str_t *val_str_table, ftdm_size_t array_size, unsigned long long default_val)
{
int i;
ftdm_size_t i;
for (i = 0; i < array_size; i++) {
if (!strcasecmp(val_str_table[i].str, str)) {
return val_str_table[i].val;
@ -4746,7 +4746,7 @@ static unsigned long long ftdm_str2val(const char *str, val_str_t *val_str_table
static const char *ftdm_val2str(unsigned long long val, val_str_t *val_str_table, ftdm_size_t array_size, const char *default_str)
{
int i;
ftdm_size_t i;
for (i = 0; i < array_size; i++) {
if (val_str_table[i].val == val) {
return val_str_table[i].str;
@ -6093,7 +6093,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
case FTDM_SIGEVENT_START:
{
ftdm_assert(!ftdm_test_flag(fchan, FTDM_CHANNEL_CALL_STARTED), "Started call twice!");
ftdm_assert(!ftdm_test_flag(fchan, FTDM_CHANNEL_CALL_STARTED), "Started call twice!\n");
if (ftdm_test_flag(fchan, FTDM_CHANNEL_OUTBOUND)) {
ftdm_log_chan_msg(fchan, FTDM_LOG_WARNING, "Inbound call taking over outbound channel\n");

View File

@ -779,6 +779,9 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
case FTDM_CHANNEL_STATE_GET_CALLERID:
{
memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Initializing cid data!\n");
ftdm_set_string(ftdmchan->caller_data.ani.digits, "unknown");
ftdm_set_string(ftdmchan->caller_data.cid_name, ftdmchan->caller_data.ani.digits);
ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_CALLERID_DETECT, NULL);
continue;
}

View File

@ -942,7 +942,7 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
ftdm_channel_t *chtmp = chan;
if (call) {
pri_destroycall(isdn_data->spri.pri, call);
/* pri call destroy is done by libpri itself (on release_ack) */
chan_priv->call = NULL;
}
@ -953,6 +953,9 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
lpwrap_stop_timer(&isdn_data->spri, &chan_priv->t316);
chan_priv->t316_timeout_cnt = 0;
/* Unset remote hangup */
chan_priv->peerhangup = 0;
if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n",
ftdm_channel_get_span_id(chan),
@ -974,7 +977,13 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
}
} else if (call) {
pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0);
/*
* Even if we have no media, sending progress without PI is forbidden
* by Q.931 3.1.8, so a protocol error will be issued from libpri
* and from remote equipment.
* So just pretend we have PI.
*/
pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1);
} else {
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
}
@ -1200,12 +1209,21 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
{
if (call) {
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
pri_hangup(isdn_data->spri.pri, call, caller_data->hangup_cause);
// pri_destroycall(isdn_data->spri.pri, call);
// chan_priv->call = NULL;
if (chan_priv->peerhangup) {
/* Call is inbound and hangup has been initiated by peer */
if (!ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
} else if (caller_data->hangup_cause == PRI_CAUSE_NO_USER_RESPONSE) {
/* Can happen when we have a DL link expire or some timer expired */
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
} else if (caller_data->hangup_cause == PRI_CAUSE_DESTINATION_OUT_OF_ORDER) {
/* Can happen when we have a DL link expire or some timer expired */
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
}
}
}
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
}
break;
@ -1362,6 +1380,7 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
{
ftdm_span_t *span = spri->span;
ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->hangup.channel);
ftdm_libpri_b_chan_t *chan_priv = chan->call_data;
if (!chan) {
ftdm_log(FTDM_LOG_CRIT, "-- Hangup on channel %d:%d but it's not in use?\n", ftdm_span_get_id(spri->span), pevent->hangup.channel);
@ -1380,8 +1399,6 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup REQ on channel %d:%d\n",
ftdm_span_get_id(spri->span), pevent->hangup.channel);
pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause);
chan->caller_data.hangup_cause = pevent->hangup.cause;
switch (ftdm_channel_get_state(chan)) {
@ -1394,19 +1411,27 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
}
break;
case LPWRAP_PRI_EVENT_HANGUP_ACK: /* */
case LPWRAP_PRI_EVENT_HANGUP_ACK: /* RELEASE_COMPLETE */
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup ACK on channel %d:%d\n",
ftdm_span_get_id(spri->span), pevent->hangup.channel);
pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause);
ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
switch (ftdm_channel_get_state(chan)) {
case FTDM_CHANNEL_STATE_RESTART:
/* ACK caused by DL FAILURE in DISC REQ */
ftdm_set_state(chan, FTDM_CHANNEL_STATE_DOWN);
break;
default:
ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
break;
}
break;
case LPWRAP_PRI_EVENT_HANGUP: /* "RELEASE/RELEASE_COMPLETE/other" */
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n",
ftdm_span_get_id(spri->span), pevent->hangup.channel);
chan_priv->peerhangup = 1;
switch (ftdm_channel_get_state(chan)) {
case FTDM_CHANNEL_STATE_DIALING:
case FTDM_CHANNEL_STATE_RINGING:
@ -1418,9 +1443,19 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING);
break;
case FTDM_CHANNEL_STATE_HANGUP:
/* this will send "RELEASE_COMPLETE", eventually */
pri_hangup(spri->pri, pevent->hangup.call, chan->caller_data.hangup_cause);
chan->caller_data.hangup_cause = pevent->hangup.cause;
ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
break;
case FTDM_CHANNEL_STATE_RESTART:
/*
* We got an hungup doing a restart, normally beacause link has been lost during
* a call and the T309 timer has expired. So destroy it :) (DL_RELEASE_IND)
*/
pri_destroycall(spri->pri, pevent->hangup.call);
ftdm_set_state(chan, FTDM_CHANNEL_STATE_DOWN);
break;
// case FTDM_CHANNEL_STATE_TERMINATING:
// ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP);
// break;
@ -2249,6 +2284,7 @@ static int handle_facility_aoc_e(const struct pri_subcmd_aoc_e *aoc_e)
ftdm_log(FTDM_LOG_INFO, "AOC-E:\n%s", tmp);
return 0;
}
#endif
/**
* \brief Handler for libpri facility events
@ -2275,6 +2311,7 @@ static int on_facility(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev
int res = -1;
switch (sub->cmd) {
#ifdef HAVE_LIBPRI_AOC
case PRI_SUBCMD_AOC_S: /* AOC-S: Start of call */
res = handle_facility_aoc_s(&sub->u.aoc_s);
break;
@ -2293,6 +2330,7 @@ static int on_facility(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev
sub->u.aoc_request_response.charging_request,
sub->u.aoc_request_response.charging_response);
break;
#endif
default:
ftdm_log(FTDM_LOG_DEBUG, "FACILITY subcommand %d is not implemented, ignoring\n", sub->cmd);
}
@ -2303,7 +2341,6 @@ static int on_facility(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev
ftdm_log(FTDM_LOG_DEBUG, "Caught Event on span %d %u (%s)\n", ftdm_span_get_id(spri->span), event_type, lpwrap_pri_event_str(event_type));
return 0;
}
#endif
/**
* \brief Handler for libpri dchan up event

View File

@ -131,6 +131,7 @@ struct ftdm_libpri_b_chan {
q931_call *call; /*!< libpri opaque call handle */
uint32_t flags; /*!< channel flags */
uint32_t t316_timeout_cnt; /*!< T316 timeout counter */
int peerhangup; /*!< hangup requested from libpri (RELEASE/RELEASE_ACK/DL_RELEASE/TIMERS EXPIRY) */
};
typedef struct ftdm_libpri_b_chan ftdm_libpri_b_chan_t;

View File

@ -169,6 +169,10 @@ int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *
if (spri->pri) {
pri_set_debug(spri->pri, debug);
#ifdef HAVE_LIBPRI_BRI
/* "follow Q.931 Section 5.3.2 call hangup better" */
pri_hangup_fix_enable(spri->pri, 1);
#endif
#ifdef HAVE_LIBPRI_AOC
pri_aoc_events_enable(spri->pri, 1);
#endif
@ -182,7 +186,7 @@ int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *
#define timeval_to_ms(x) \
(((ftdm_time_t)(x)->tv_sec * 1000) + (ftdm_time_t)((x)->tv_usec / 1000))
(ftdm_time_t)(((x)->tv_sec * 1000) + ((x)->tv_usec / 1000))
int lpwrap_start_timer(struct lpwrap_pri *spri, struct lpwrap_timer *timer, const uint32_t timeout_ms, timeout_handler callback)
{

View File

@ -38,8 +38,11 @@
#define PRI_SPAN(p) (((p) >> 8) & 0xff)
#define PRI_CHANNEL(p) ((p) & 0xff)
#define PRITAP_NETWORK_ANSWER 0x1
typedef enum {
PRITAP_RUNNING = (1 << 0),
PRITAP_MASTER = (1 << 1),
} pritap_flags_t;
typedef struct {
@ -49,10 +52,16 @@ typedef struct {
ftdm_number_t callednum;
ftdm_channel_t *fchan;
char callingname[80];
int proceeding:1;
int inuse:1;
uint8_t proceeding;
uint8_t inuse;
} passive_call_t;
typedef enum pritap_iface {
PRITAP_IFACE_UNKNOWN = 0,
PRITAP_IFACE_CPE = 1,
PRITAP_IFACE_NET = 2,
} pritap_iface_t;
typedef struct pritap {
int32_t flags;
struct pri *pri;
@ -63,6 +72,7 @@ typedef struct pritap {
ftdm_span_t *peerspan;
ftdm_mutex_t *pcalls_lock;
passive_call_t pcalls[FTDM_MAX_CHANNELS_PHYSICAL_SPAN];
pritap_iface_t iface;
} pritap_t;
static FIO_IO_UNLOAD_FUNCTION(ftdm_pritap_unload)
@ -266,11 +276,14 @@ static ftdm_state_map_t pritap_state_map = {
}
};
#define PRITAP_GET_INTERFACE(iface) iface == PRITAP_IFACE_CPE ? "CPE" : \
iface == PRITAP_IFACE_NET ? "NET" : "UNKNOWN"
static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
{
ftdm_status_t status;
ftdm_sigmsg_t sig;
ftdm_channel_t *peerchan = ftdmchan->call_data;
pritap_t *pritap = ftdmchan->span->signal_data;
pritap_t *peer_pritap = pritap->peerspan->signal_data;
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "processing state %s\n", ftdm_channel_state2str(ftdmchan->state));
@ -279,28 +292,56 @@ static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
sig.span_id = ftdmchan->span_id;
sig.channel = ftdmchan;
ftdm_channel_complete_state(ftdmchan);
ftdm_channel_complete_state(ftdmchan);
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_DOWN:
{
ftdmchan->call_data = NULL;
ftdm_channel_close(&ftdmchan);
ftdm_channel_t *fchan = ftdmchan;
peerchan->call_data = NULL;
ftdm_channel_close(&peerchan);
/* Destroy the peer data first */
if (fchan->call_data) {
ftdm_channel_t *peerchan = fchan->call_data;
ftdm_channel_t *pchan = peerchan;
ftdm_channel_lock(peerchan);
pchan->call_data = NULL;
pchan->pflags = 0;
ftdm_channel_close(&pchan);
ftdm_channel_unlock(peerchan);
} else {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "No call data?\n");
}
ftdmchan->call_data = NULL;
ftdmchan->pflags = 0;
ftdm_channel_close(&fchan);
}
break;
case FTDM_CHANNEL_STATE_PROGRESS:
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
case FTDM_CHANNEL_STATE_UP:
case FTDM_CHANNEL_STATE_HANGUP:
break;
case FTDM_CHANNEL_STATE_UP:
{
if (ftdm_test_pflag(ftdmchan, PRITAP_NETWORK_ANSWER)) {
ftdm_clear_pflag(ftdmchan, PRITAP_NETWORK_ANSWER);
sig.event_id = FTDM_SIGEVENT_UP;
ftdm_span_send_signal(ftdmchan->span, &sig);
}
}
break;
case FTDM_CHANNEL_STATE_RING:
{
sig.event_id = FTDM_SIGEVENT_START;
/* The ring interface (where the setup was received) is the peer, since we RING the channel
* where PROCEED/PROGRESS is received */
ftdm_sigmsg_add_var(&sig, "pritap_ring_interface", PRITAP_GET_INTERFACE(peer_pritap->iface));
if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
}
@ -333,9 +374,9 @@ static __inline__ void pritap_check_state(ftdm_span_t *span)
uint32_t j;
ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE);
for(j = 1; j <= span->chan_count; j++) {
ftdm_mutex_lock(span->channels[j]->mutex);
ftdm_channel_lock(span->channels[j]);
ftdm_channel_advance_states(span->channels[j]);
ftdm_mutex_unlock(span->channels[j]->mutex);
ftdm_channel_unlock(span->channels[j]);
}
}
}
@ -397,23 +438,47 @@ static passive_call_t *tap_pri_get_pcall_bycrv(pritap_t *pritap, int crv)
for (i = 0; i < ftdm_array_len(pritap->pcalls); i++) {
tstcrv = pritap->pcalls[i].callref ? tap_pri_get_crv(pritap->pri, pritap->pcalls[i].callref) : 0;
if (pritap->pcalls[i].callref && tstcrv == crv) {
if (!pritap->pcalls[i].inuse) {
ftdm_log(FTDM_LOG_ERROR, "Found crv %d in slot %d of span %s with call %p but is no longer in use!\n",
crv, i, pritap->span->name, pritap->pcalls[i].callref);
continue;
if (pritap->pcalls[i].inuse) {
ftdm_mutex_unlock(pritap->pcalls_lock);
return &pritap->pcalls[i];
}
ftdm_mutex_unlock(pritap->pcalls_lock);
return &pritap->pcalls[i];
/* This just means the crv is being re-used in another call before this one was destroyed */
ftdm_log(FTDM_LOG_DEBUG, "Found crv %d in slot %d of span %s with call %p but is no longer in use\n",
crv, i, pritap->span->name, pritap->pcalls[i].callref);
}
}
ftdm_log(FTDM_LOG_DEBUG, "crv %d was not found active in span %s\n", crv, pritap->span->name);
ftdm_mutex_unlock(pritap->pcalls_lock);
return NULL;
}
/*
* This is a tricky function with some side effects, some explanation needed ...
*
* The libpri stack process HDLC frames, then finds Q921 frames and Q931 events, each time
* it finds a new Q931 event, checks if the crv of that event matches a known call in the internal
* list found in the PRI control block (for us, one control block per span), if it does not find
* the call, allocates a new one and then sends the event up to the user (us, ftmod_pritap in this case)
*
* The user is then expected to destroy the call when done with it (on hangup), but things get tricky here
* because in ftmod_pritap we do not destroy the call right away to be sure we only destroy it when no one
* else needs that pointer, therefore we decide to delay the destruction of the call pointer until later
* when a new call comes which triggers the garbage collecting code in this function
*
* Now, what happens if a new call arrives right away with the same crv than the last call? the pri stack
* does *not* allocate a new call pointer because is still a known call and we must therefore re-use the
* same call pointer
*
* This function accepts a pointer to a callref, even a NULL one. When callref is NULL we search for an
* available slot so the caller of this function can use it to store a new callref pointer. In the process
* we also scan for slots that still have a callref pointer but are no longer in use (inuse=0) and we
* destroy that callref and clear the slot (memset). The trick is, we only do this if the callref to
* be garbage collected is NOT the one provided by the parameter callref, of course! otherwise we may
* be freeing a pointer to a callref for a new call that used an old (recycled) callref!
*/
static passive_call_t *tap_pri_get_pcall(pritap_t *pritap, void *callref)
{
int i;
@ -422,7 +487,11 @@ static passive_call_t *tap_pri_get_pcall(pritap_t *pritap, void *callref)
ftdm_mutex_lock(pritap->pcalls_lock);
for (i = 0; i < ftdm_array_len(pritap->pcalls); i++) {
if (pritap->pcalls[i].callref && !pritap->pcalls[i].inuse) {
/* If this slot has a call reference
* and it is different than the *callref provided to us
* and is no longer in use,
* then it is time to garbage collect it ... */
if (pritap->pcalls[i].callref && callref != pritap->pcalls[i].callref && !pritap->pcalls[i].inuse) {
crv = tap_pri_get_crv(pritap->pri, pritap->pcalls[i].callref);
/* garbage collection */
ftdm_log(FTDM_LOG_DEBUG, "Garbage collecting callref %d/%p from span %s in slot %d\n",
@ -431,7 +500,17 @@ static passive_call_t *tap_pri_get_pcall(pritap_t *pritap, void *callref)
memset(&pritap->pcalls[i], 0, sizeof(pritap->pcalls[0]));
}
if (callref == pritap->pcalls[i].callref) {
pritap->pcalls[i].inuse = 1;
if (callref == NULL) {
pritap->pcalls[i].inuse = 1;
ftdm_log(FTDM_LOG_DEBUG, "Enabling callref slot %d in span %s\n", i, pritap->span->name);
} else if (!pritap->pcalls[i].inuse) {
crv = tap_pri_get_crv(pritap->pri, callref);
ftdm_log(FTDM_LOG_DEBUG, "Recyclying callref slot %d in span %s for callref %d/%p\n",
i, pritap->span->name, crv, callref);
memset(&pritap->pcalls[i], 0, sizeof(pritap->pcalls[0]));
pritap->pcalls[i].callref = callref;
pritap->pcalls[i].inuse = 1;
}
ftdm_mutex_unlock(pritap->pcalls_lock);
@ -464,13 +543,11 @@ static void tap_pri_put_pcall(pritap_t *pritap, void *callref)
}
tstcrv = tap_pri_get_crv(pritap->pri, pritap->pcalls[i].callref);
if (tstcrv == crv) {
ftdm_log(FTDM_LOG_DEBUG, "releasing slot %d in span %s used by callref %d/%p\n", i,
pritap->span->name, crv, pritap->pcalls[i].callref);
if (!pritap->pcalls[i].inuse) {
ftdm_log(FTDM_LOG_ERROR, "slot %d in span %s used by callref %d/%p was released already?\n",
i, pritap->span->name, crv, pritap->pcalls[i].callref);
if (pritap->pcalls[i].inuse) {
ftdm_log(FTDM_LOG_DEBUG, "releasing slot %d in span %s used by callref %d/%p\n", i,
pritap->span->name, crv, pritap->pcalls[i].callref);
pritap->pcalls[i].inuse = 0;
}
pritap->pcalls[i].inuse = 0;
}
}
@ -480,6 +557,7 @@ static void tap_pri_put_pcall(pritap_t *pritap, void *callref)
static __inline__ ftdm_channel_t *tap_pri_get_fchan(pritap_t *pritap, passive_call_t *pcall, int channel)
{
ftdm_channel_t *fchan = NULL;
int err = 0;
int chanpos = PRI_CHANNEL(channel);
if (!chanpos || chanpos > pritap->span->chan_count) {
ftdm_log(FTDM_LOG_CRIT, "Invalid pri tap channel %d requested in span %s\n", channel, pritap->span->name);
@ -487,14 +565,19 @@ static __inline__ ftdm_channel_t *tap_pri_get_fchan(pritap_t *pritap, passive_ca
}
fchan = pritap->span->channels[PRI_CHANNEL(channel)];
ftdm_channel_lock(fchan);
if (ftdm_test_flag(fchan, FTDM_CHANNEL_INUSE)) {
ftdm_log(FTDM_LOG_ERROR, "Channel %d requested in span %s is already in use!\n", channel, pritap->span->name);
return NULL;
err = 1;
goto done;
}
if (ftdm_channel_open_chan(fchan) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Could not open tap channel %d requested in span %s\n", channel, pritap->span->name);
return NULL;
err = 1;
goto done;
}
memset(&fchan->caller_data, 0, sizeof(fchan->caller_data));
@ -508,6 +591,15 @@ static __inline__ ftdm_channel_t *tap_pri_get_fchan(pritap_t *pritap, passive_ca
ftdm_set_string(fchan->caller_data.ani.digits, pcall->callingani.digits);
ftdm_set_string(fchan->caller_data.dnis.digits, pcall->callednum.digits);
done:
if (fchan) {
ftdm_channel_unlock(fchan);
}
if (err) {
return NULL;
}
return fchan;
}
@ -534,10 +626,17 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e)
ftdm_log(FTDM_LOG_WARNING, "There is a call with callref %d already, ignoring duplicated ring event\n", crv);
break;
}
pcall = tap_pri_get_pcall(pritap, NULL);
/* Try to get a recycled call (ie, e->ring.call is a call that the PRI stack allocated previously and then
* re-used for the next RING event because we did not destroy it fast enough) */
pcall = tap_pri_get_pcall(pritap, e->ring.call);
if (!pcall) {
ftdm_log(FTDM_LOG_ERROR, "Failed to get a free passive PRI call slot for callref %d, this is a bug!\n", crv);
break;
/* ok so the call is really not known to us, let's get a new one */
pcall = tap_pri_get_pcall(pritap, NULL);
if (!pcall) {
ftdm_log(FTDM_LOG_ERROR, "Failed to get a free passive PRI call slot for callref %d, this is a bug!\n", crv);
break;
}
}
pcall->callref = e->ring.call;
ftdm_set_string(pcall->callingnum.digits, e->ring.callingnum);
@ -562,7 +661,7 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e)
/* check that we already know about this call in the peer PRI (which was the one receiving the PRI_EVENT_RING event) */
if (!(pcall = tap_pri_get_pcall_bycrv(peertap, crv))) {
ftdm_log(FTDM_LOG_DEBUG,
"ignoring proceeding in channel %s:%d:%d for callref %d since we don't know about it",
"ignoring proceeding in channel %s:%d:%d for callref %d since we don't know about it\n",
pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
break;
}
@ -570,13 +669,27 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e)
ftdm_log(FTDM_LOG_DEBUG, "Ignoring duplicated proceeding with callref %d\n", crv);
break;
}
peerpcall = tap_pri_get_pcall(pritap, NULL);
if (!peerpcall) {
ftdm_log(FTDM_LOG_ERROR, "Failed to get a free peer PRI passive call slot for callref %d in span %s, this is a bug!\n",
crv, pritap->span->name);
pcall->proceeding = 1;
/* This call should not be known to this PRI yet ... */
if ((peerpcall = tap_pri_get_pcall_bycrv(pritap, crv))) {
ftdm_log(FTDM_LOG_ERROR,
"ignoring proceeding in channel %s:%d:%d for callref %d, dup???\n",
pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
break;
}
peerpcall->callref = e->proceeding.call;
/* Check if the call pointer is being recycled */
peerpcall = tap_pri_get_pcall(pritap, e->proceeding.call);
if (!peerpcall) {
peerpcall = tap_pri_get_pcall(pritap, NULL);
if (!peerpcall) {
ftdm_log(FTDM_LOG_ERROR, "Failed to get a free peer PRI passive call slot for callref %d in span %s, this is a bug!\n",
crv, pritap->span->name);
break;
}
peerpcall->callref = e->proceeding.call;
}
/* check that the layer 1 and trans capability are supported */
layer1 = pri_get_layer1(peertap->pri, pcall->callref);
@ -598,7 +711,6 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e)
pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
break;
}
pcall->fchan = fchan;
peerfchan = tap_pri_get_fchan(peertap, pcall, e->proceeding.channel);
if (!peerfchan) {
@ -606,12 +718,20 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e)
peertap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
break;
}
pcall->fchan = fchan;
peerpcall->fchan = fchan;
fchan->call_data = peerfchan;
peerfchan->call_data = fchan;
ftdm_log_chan(fchan, FTDM_LOG_NOTICE, "Starting new tapped call with callref %d\n", crv);
ftdm_channel_lock(fchan);
fchan->call_data = peerfchan;
ftdm_set_state(fchan, FTDM_CHANNEL_STATE_RING);
ftdm_channel_unlock(fchan);
ftdm_channel_lock(peerfchan);
peerfchan->call_data = fchan;
ftdm_channel_unlock(peerfchan);
ftdm_set_state_locked(fchan, FTDM_CHANNEL_STATE_RING);
break;
case PRI_EVENT_ANSWER:
@ -620,33 +740,54 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e)
pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv);
if (!(pcall = tap_pri_get_pcall_bycrv(pritap, crv))) {
ftdm_log(FTDM_LOG_DEBUG,
"ignoring answer in channel %s:%d:%d for callref %d since we don't know about it",
pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
"ignoring answer in channel %s:%d:%d for callref %d since we don't know about it\n",
pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->proceeding.channel), crv);
break;
}
if (!pcall->fchan) {
ftdm_log(FTDM_LOG_ERROR,
"Received answer in channel %s:%d:%d for callref %d but we never got a channel\n",
pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv);
break;
}
ftdm_channel_lock(pcall->fchan);
ftdm_log_chan(pcall->fchan, FTDM_LOG_NOTICE, "Tapped call was answered in state %s\n", ftdm_channel_state2str(pcall->fchan->state));
ftdm_set_pflag(pcall->fchan, PRITAP_NETWORK_ANSWER);
ftdm_set_state(pcall->fchan, FTDM_CHANNEL_STATE_UP);
ftdm_channel_unlock(pcall->fchan);
break;
case PRI_EVENT_HANGUP_REQ:
crv = tap_pri_get_crv(pritap->pri, e->hangup.call);
ftdm_log(FTDM_LOG_DEBUG, "Hangup on channel %s:%d:%d with callref %d\n",
pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv);
ftdm_log(FTDM_LOG_DEBUG, "Hangup on channel %s:%d:%d with callref %d\n",
pritap->span->name, PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), crv);
if (!(pcall = tap_pri_get_pcall_bycrv(pritap, crv))) {
ftdm_log(FTDM_LOG_DEBUG,
"ignoring hangup in channel %s:%d:%d for callref %d since we don't know about it",
pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
pritap->span->name, PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), crv);
break;
}
fchan = pcall->fchan;
ftdm_set_state_locked(fchan, FTDM_CHANNEL_STATE_TERMINATING);
if (pcall->fchan) {
fchan = pcall->fchan;
ftdm_channel_lock(fchan);
if (fchan->state < FTDM_CHANNEL_STATE_TERMINATING) {
ftdm_set_state(fchan, FTDM_CHANNEL_STATE_TERMINATING);
}
pcall->fchan = NULL; /* after this event we're not supposed to need to do anything with the channel anymore */
ftdm_channel_unlock(fchan);
}
tap_pri_put_pcall(pritap, e->hangup.call);
tap_pri_put_pcall(peertap, e->hangup.call);
break;
case PRI_EVENT_HANGUP_ACK:
crv = tap_pri_get_crv(pritap->pri, e->hangup.call);
ftdm_log(FTDM_LOG_DEBUG, "Hangup ack on channel %s:%d:%d with callref %d\n",
pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv);
pritap->span->name, PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), crv);
tap_pri_put_pcall(pritap, e->hangup.call);
tap_pri_put_pcall(peertap, e->hangup.call);
break;
@ -661,12 +802,14 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e)
static void *ftdm_pritap_run(ftdm_thread_t *me, void *obj)
{
ftdm_span_t *span = (ftdm_span_t *) obj;
ftdm_span_t *peer = NULL;
pritap_t *pritap = span->signal_data;
pritap_t *p_pritap = NULL;
pri_event *event = NULL;
struct pollfd dpoll = { 0, 0, 0 };
struct pollfd dpoll[2];
int rc = 0;
ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread started on span %d\n", span->span_id);
ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread started on span %s\n", span->name);
pritap->span = span;
@ -684,48 +827,80 @@ static void *ftdm_pritap_run(ftdm_thread_t *me, void *obj)
goto done;
}
dpoll.fd = pritap->dchan->sockfd;
/* The last span starting runs the show ...
* This simplifies locking and avoid races by having multiple threads for a single tapped link
* Since both threads really handle a single tapped link there is no benefit on multi-threading, just complications ... */
peer = pritap->peerspan;
p_pritap = peer->signal_data;
if (!ftdm_test_flag(pritap, PRITAP_MASTER)) {
ftdm_log(FTDM_LOG_DEBUG, "Running dummy thread on span %s\n", span->name);
while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) {
poll(NULL, 0, 100);
}
} else {
memset(&dpoll, 0, sizeof(dpoll));
dpoll[0].fd = pritap->dchan->sockfd;
dpoll[1].fd = p_pritap->dchan->sockfd;
while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) {
ftdm_log(FTDM_LOG_DEBUG, "Master tapping thread on span %s (fd1=%d, fd2=%d)\n", span->name,
pritap->dchan->sockfd, p_pritap->dchan->sockfd);
while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) {
pritap_check_state(span);
pritap_check_state(span);
pritap_check_state(peer);
dpoll.revents = 0;
dpoll.events = POLLIN;
dpoll[0].revents = 0;
dpoll[0].events = POLLIN;
rc = poll(&dpoll, 1, 10);
dpoll[1].revents = 0;
dpoll[1].events = POLLIN;
if (rc < 0) {
if (errno == EINTR) {
ftdm_log(FTDM_LOG_DEBUG, "D-channel waiting interrupted, continuing ...\n");
rc = poll(&dpoll[0], 2, 10);
if (rc < 0) {
if (errno == EINTR) {
ftdm_log(FTDM_LOG_DEBUG, "D-channel waiting interrupted, continuing ...\n");
continue;
}
ftdm_log(FTDM_LOG_ERROR, "poll failed: %s\n", strerror(errno));
continue;
}
ftdm_log(FTDM_LOG_ERROR, "poll failed: %s\n", strerror(errno));
continue;
}
pri_schedule_run(pritap->pri);
pri_schedule_run(pritap->pri);
pri_schedule_run(p_pritap->pri);
if (rc) {
if (dpoll.revents & POLLIN) {
event = pri_read_event(pritap->pri);
if (event) {
handle_pri_passive_event(pritap, event);
pritap_check_state(span);
pritap_check_state(peer);
if (rc) {
if (dpoll[0].revents & POLLIN) {
event = pri_read_event(pritap->pri);
if (event) {
handle_pri_passive_event(pritap, event);
pritap_check_state(span);
}
}
} else {
ftdm_log(FTDM_LOG_WARNING, "nothing to read?\n");
}
}
pritap_check_state(span);
if (dpoll[1].revents & POLLIN) {
event = pri_read_event(p_pritap->pri);
if (event) {
handle_pri_passive_event(p_pritap, event);
pritap_check_state(peer);
}
}
}
}
}
done:
ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread ended on span %d\n", span->span_id);
ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread ended on span %s\n", span->name);
ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD);
ftdm_clear_flag(pritap, PRITAP_RUNNING);
ftdm_clear_flag(pritap, PRITAP_MASTER);
return NULL;
}
@ -811,6 +986,7 @@ static ftdm_status_t ftdm_pritap_start(ftdm_span_t *span)
{
ftdm_status_t ret;
pritap_t *pritap = span->signal_data;
pritap_t *p_pritap = pritap->peerspan->signal_data;
if (ftdm_test_flag(pritap, PRITAP_RUNNING)) {
return FTDM_FAIL;
@ -822,6 +998,10 @@ static ftdm_status_t ftdm_pritap_start(ftdm_span_t *span)
ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD);
ftdm_set_flag(pritap, PRITAP_RUNNING);
if (p_pritap && ftdm_test_flag(p_pritap, PRITAP_RUNNING)) {
/* our peer already started, we're the master */
ftdm_set_flag(pritap, PRITAP_MASTER);
}
ret = ftdm_thread_create_detached(ftdm_pritap_run, span);
if (ret != FTDM_SUCCESS) {
@ -840,6 +1020,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span)
ftdm_channel_t *dchan = NULL;
pritap_t *pritap = NULL;
ftdm_span_t *peerspan = NULL;
pritap_iface_t iface = PRITAP_IFACE_UNKNOWN;
unsigned paramindex = 0;
if (span->trunk_type >= FTDM_TRUNK_NONE) {
@ -867,6 +1048,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span)
debug = val;
} else if (!strcasecmp(var, "mixaudio")) {
mixaudio = ftdm_true(val);
} else if (!strcasecmp(var, "interface")) {
if (!strcasecmp(val, "cpe")) {
iface = PRITAP_IFACE_CPE;
} else if (!strcasecmp(val, "net")) {
iface = PRITAP_IFACE_NET;
} else {
ftdm_log(FTDM_LOG_WARNING, "Ignoring invalid tapping interface type %s\n", val);
}
} else if (!strcasecmp(var, "peerspan")) {
if (ftdm_span_find_by_name(val, &peerspan) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Invalid tapping peer span %s\n", val);
@ -891,6 +1080,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span)
pritap->dchan = dchan;
pritap->peerspan = peerspan;
pritap->mixaudio = mixaudio;
pritap->iface = iface;
span->start = ftdm_pritap_start;
span->stop = ftdm_pritap_stop;

View File

@ -273,7 +273,7 @@ static ftdm_status_t parse_trunkgroup(const char *_trunkgroup)
{
int i;
char *p, *name, *dchan_span, *backup_span, *trunkgroup;
uint8_t num_spans;
uint8_t num_spans = 0;
ftdm_status_t ret = FTDM_SUCCESS;
trunkgroup = ftdm_strdup(_trunkgroup);

View File

@ -475,8 +475,16 @@ void sngisdn_snd_restart(ftdm_channel_t *ftdmchan)
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
{
sng_l1_frame_t l1_frame;
ftdm_alarm_flag_t alarmbits = 0;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
ftdm_channel_get_alarms(dchan, &alarmbits);
if (alarmbits) {
ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Dropping incoming data due to L1 alarm\n");
return;
}
if (len > sizeof(l1_frame.data)) {
ftdm_log_chan(dchan, FTDM_LOG_ERROR, "Received frame of %"FTDM_SIZE_FMT" bytes, exceeding max size of %"FTDM_SIZE_FMT" bytes\n",
len, sizeof(l1_frame.data));
@ -548,9 +556,11 @@ void sngisdn_snd_event(sngisdn_span_data_t *signal_data, ftdm_oob_event_t event)
case FTDM_OOB_ALARM_CLEAR:
l1_event.type = SNG_L1EVENT_ALARM_OFF;
sng_isdn_event_ind(signal_data->link_id, &l1_event);
ftdm_sched_timer(signal_data->sched, "delayed_dl_req", 8000, sngisdn_delayed_dl_req, (void*) signal_data, NULL);
signal_data->dl_request_pending = 1;
if (!signal_data->dl_request_pending) {
signal_data->dl_request_pending = 1;
ftdm_sched_timer(signal_data->sched, "delayed_dl_req", 8000, sngisdn_delayed_dl_req, (void*) signal_data, NULL);
}
break;
case FTDM_OOB_ALARM_TRAP:
l1_event.type = SNG_L1EVENT_ALARM_ON;

View File

@ -1091,7 +1091,7 @@ void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...)
switch (level) {
case SNG_LOGLEVEL_DEBUG:
ftdm_log(FTDM_LOG_DEBUG, "sng_isdn->%s\n", data);
ftdm_log(FTDM_LOG_DEBUG, "sng_isdn->%s", data);
break;
case SNG_LOGLEVEL_WARN:
if ( strncmp(data, "Invalid Q.921/Q.931 frame", 25) ) {

View File

@ -1214,14 +1214,23 @@ void sngisdn_t3_timeout(void *p_sngisdn_info)
void sngisdn_delayed_dl_req(void *p_signal_data)
{
ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t *)p_signal_data;
ftdm_span_t *span = signal_data->ftdm_span;
if (!signal_data->dl_request_pending) {
return;
}
signal_data->dl_request_pending = 0;
ftdm_span_get_sig_status(span, &sigstatus);
if (sigstatus == FTDM_SIG_STATE_UP) {
signal_data->dl_request_pending = 0;
return;
}
sngisdn_snd_dl_req(span->channels[1]);
ftdm_sched_timer(signal_data->sched, "delayed_dl_req", 4000, sngisdn_delayed_dl_req, (void*) signal_data, NULL);
return;
}

View File

@ -102,6 +102,7 @@ struct ioctl_codes {
ioctlcmd SETTXBITS;
ioctlcmd GETRXBITS;
ioctlcmd SETPOLARITY;
ioctlcmd TONEDETECT;
};
/**
@ -139,7 +140,8 @@ static struct ioctl_codes zt_ioctl_codes = {
.GETCONFMUTE = ZT_GETCONFMUTE,
.ECHOTRAIN = ZT_ECHOTRAIN,
.SETTXBITS = ZT_SETTXBITS,
.GETRXBITS = ZT_GETRXBITS
.GETRXBITS = ZT_GETRXBITS,
.TONEDETECT = ZT_TONEDETECT,
};
/**
@ -178,7 +180,8 @@ static struct ioctl_codes dahdi_ioctl_codes = {
.ECHOTRAIN = DAHDI_ECHOTRAIN,
.SETTXBITS = DAHDI_SETTXBITS,
.GETRXBITS = DAHDI_GETRXBITS,
.SETPOLARITY = DAHDI_SETPOLARITY
.SETPOLARITY = DAHDI_SETPOLARITY,
.TONEDETECT = DAHDI_TONEDETECT,
};
#define ZT_INVALID_SOCKET -1
@ -271,6 +274,7 @@ static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, f
{
unsigned configured = 0, x;
zt_params_t ztp;
zt_tone_mode_t mode = 0;
memset(&ztp, 0, sizeof(ztp));
@ -361,7 +365,7 @@ static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, f
cc.sigtype = ZT_SIG_CAS;
cc.idlebits = cas_bits;
if (ioctl(CONTROL_FD, codes.CHANCONFIG, &cc)) {
ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s as FreeTDM device %d:%d fd:%d err:%s", chanpath, ftdmchan->span_id, ftdmchan->chan_id, sockfd, strerror(errno));
ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s as FreeTDM device %d:%d fd:%d err:%s\n", chanpath, ftdmchan->span_id, ftdmchan->chan_id, sockfd, strerror(errno));
close(sockfd);
continue;
}
@ -436,12 +440,23 @@ static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, f
continue;
}
mode = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
if (ioctl(sockfd, codes.TONEDETECT, &mode)) {
ftdm_log(FTDM_LOG_DEBUG, "HW DTMF not available on FreeTDM device %d:%d fd:%d\n", ftdmchan->span_id, ftdmchan->chan_id, sockfd);
} else {
ftdm_log(FTDM_LOG_DEBUG, "HW DTMF available on FreeTDM device %d:%d fd:%d\n", ftdmchan->span_id, ftdmchan->chan_id, sockfd);
ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT);
mode = 0;
ioctl(sockfd, codes.TONEDETECT, &mode);
}
if (!ftdm_strlen_zero(name)) {
ftdm_copy_string(ftdmchan->chan_name, name, sizeof(ftdmchan->chan_name));
}
if (!ftdm_strlen_zero(number)) {
ftdm_copy_string(ftdmchan->chan_number, number, sizeof(ftdmchan->chan_number));
}
configured++;
} else {
ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s\n", chanpath);
@ -666,7 +681,6 @@ static FIO_OPEN_FUNCTION(zt_open)
}
}
}
}
return FTDM_SUCCESS;
}
@ -858,6 +872,24 @@ static FIO_COMMAND_FUNCTION(zt_command)
err = ioctl(ftdmchan->sockfd, codes.FLUSH, &flushmode);
}
break;
case FTDM_COMMAND_SET_RX_QUEUE_SIZE:
case FTDM_COMMAND_SET_TX_QUEUE_SIZE:
/* little white lie ... eventually we can implement this, in the meantime, not worth the effort
and this is only used by some sig modules such as ftmod_r2 to behave bettter under load */
err = 0;
break;
case FTDM_COMMAND_ENABLE_DTMF_DETECT:
{
zt_tone_mode_t mode = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
err = ioctl(ftdmchan->sockfd, codes.TONEDETECT, &mode);
}
break;
case FTDM_COMMAND_DISABLE_DTMF_DETECT:
{
zt_tone_mode_t mode = 0;
err = ioctl(ftdmchan->sockfd, codes.TONEDETECT, &mode);
}
break;
default:
err = FTDM_NOTIMPL;
break;
@ -949,7 +981,7 @@ pollagain:
pfds[0].fd = ftdmchan->sockfd;
pfds[0].events = inflags;
result = poll(pfds, 1, to);
*flags = 0;
*flags = FTDM_NO_FLAGS;
if (result < 0 && errno == EINTR) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "DAHDI wait got interrupted, trying again\n");
@ -965,8 +997,6 @@ pollagain:
inflags = pfds[0].revents;
}
*flags = FTDM_NO_FLAGS;
if (result < 0){
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Poll failed");
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to poll DAHDI device: %s\n", strerror(errno));
@ -1042,6 +1072,23 @@ FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event)
return k ? FTDM_SUCCESS : FTDM_FAIL;
}
static __inline__ int handle_dtmf_event(ftdm_channel_t *fchan, zt_event_t zt_event_id)
{
if ((zt_event_id & ZT_EVENT_DTMFUP)) {
int digit = (zt_event_id & (~ZT_EVENT_DTMFUP));
char tmp_dtmf[2] = { digit, 0 };
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "DTMF UP [%d]\n", digit);
ftdm_channel_queue_dtmf(fchan, tmp_dtmf);
return 0;
} else if ((zt_event_id & ZT_EVENT_DTMFDOWN)) {
int digit = (zt_event_id & (~ZT_EVENT_DTMFDOWN));
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "DTMF DOWN [%d]\n", digit);
return 0;
} else {
return -1;
}
}
/**
* \brief Process an event from a ftdmchan and set the proper OOB event_id. The channel must be locked.
* \param fchan Channel to retrieve event from
@ -1151,8 +1198,12 @@ static __inline__ ftdm_status_t zt_channel_process_event(ftdm_channel_t *fchan,
break;
default:
{
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Unhandled event %d\n", zt_event_id);
*event_id = FTDM_OOB_INVALID;
if (handle_dtmf_event(fchan, zt_event_id)) {
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Unhandled event %d\n", zt_event_id);
*event_id = FTDM_OOB_INVALID;
} else {
*event_id = FTDM_OOB_NOOP;
}
}
break;
}
@ -1308,8 +1359,12 @@ tryagain:
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed retrieving event after ELAST on write: %s\n", strerror(errno));
return FTDM_FAIL;
}
/* we should enqueue this event somewhere so it can be retrieved by the user, for now, dropping it to see what it is! */
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dropping event %d to be able to write data\n", zt_event_id);
if (handle_dtmf_event(ftdmchan, zt_event_id)) {
/* we should enqueue this event somewhere so it can be retrieved by the user, for now, dropping it to see what it is! */
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dropping event %d to be able to write data\n", zt_event_id);
}
goto tryagain;
}
@ -1325,7 +1380,6 @@ static FIO_CHANNEL_DESTROY_FUNCTION(zt_channel_destroy)
{
close(ftdmchan->sockfd);
ftdmchan->sockfd = ZT_INVALID_SOCKET;
return FTDM_SUCCESS;
}

View File

@ -195,7 +195,9 @@ typedef enum {
ZT_EVENT_TIMER_EXPIRED = 15,
ZT_EVENT_TIMER_PING = 16,
ZT_EVENT_POLARITY = 17,
ZT_EVENT_RINGBEGIN = 18
ZT_EVENT_RINGBEGIN = 18,
ZT_EVENT_DTMFDOWN = (1 << 17),
ZT_EVENT_DTMFUP = (1 << 18),
} zt_event_t;
typedef enum {
@ -258,6 +260,12 @@ ZT_BBIT = 4,
ZT_ABIT = 8
} zt_cas_bit_t;
typedef enum {
/* Tone Detection */
ZT_TONEDETECT_ON = (1 << 0), /* Detect tones */
ZT_TONEDETECT_MUTE = (1 << 1) /* Mute audio in received channel */
} zt_tone_mode_t;
/* Defines */
#define ZT_MAX_BLOCKSIZE 8192
@ -312,6 +320,11 @@ ZT_ABIT = 8
#define ZT_SETTXBITS _IOW (ZT_CODE, 43, int)
#define ZT_GETRXBITS _IOR (ZT_CODE, 45, int)
/*
* Enable tone detection -- implemented by low level driver
*/
#define ZT_TONEDETECT _IOW(ZT_CODE, 91, int)
#define DAHDI_GET_BLOCKSIZE _IOR (DAHDI_CODE, 1, int) /* Get Transfer Block Size. */
#define DAHDI_SET_BLOCKSIZE _IOW (DAHDI_CODE, 1, int) /* Set Transfer Block Size. */
#define DAHDI_FLUSH _IOW (DAHDI_CODE, 3, int) /* Flush Buffer(s) and stop I/O */
@ -361,6 +374,11 @@ ZT_ABIT = 8
#define DAHDI_SETPOLARITY _IOW (DAHDI_CODE, 92, int) /* Polarity setting for FXO lines */
/*
* Enable tone detection -- implemented by low level driver
*/
#define DAHDI_TONEDETECT _IOW(DAHDI_CODE, 91, int)
#endif
/* For Emacs:

View File

@ -64,10 +64,10 @@ typedef uint64_t ftdm_time_t;
#endif
/*! \brief strncpy replacement */
#define ftdm_copy_string(x,y,z) strncpy(x, y, z - 1)
#define ftdm_copy_string(x,y,z) strncpy(x, y, z - 1)
/*! \brief strncpy into a fixed-length buffer */
#define ftdm_set_string(x,y) strncpy(x, y, sizeof(x)-1)
#define ftdm_set_string(x,y) strncpy(x, y, sizeof(x)-1)
/*! \brief check for null or zero length string buffer */
#define ftdm_strlen_zero(s) (!s || *s == '\0')
@ -87,6 +87,10 @@ typedef uint64_t ftdm_time_t;
/*! \brief Get value that is in range [vmin,vmax] */
#define ftdm_clamp(val,vmin,vmax) ftdm_max(vmin,ftdm_min(val,vmax))
/*!< \brief Safer version of ftdm_clamp(), that swaps vmin/vmax parameters if vmin > vmax */
#define ftdm_clamp_safe(val,vmin,vmax) \
ftdm_clamp(val, ftdm_min(vmin,vmax), ftdm_max(vmin,vmax))
/*!
* \brief Get offset of member in structure
* \param[in] type Type of struct

View File

@ -425,7 +425,7 @@ if test "$target" != "$host"; then
LDFLAGS=$_SAVE_LDFLAGS
case "$build:$target" in
powerpc-apple-darwin8*:i?86-apple-darwin*)
powerpc-apple-darwin8*:*86-apple-darwin*)
dnl The Darwin cross compiler doesn't necessarily point itself at a
dnl root that has libraries for the proper architecture, it defaults
dnl to the system root. The libraries in the system root on current
@ -446,7 +446,7 @@ if test "$target" != "$host"; then
AC_PROG_CXX
case "$build:$target" in
powerpc-apple-darwin8*:i?86-apple-darwin*)
powerpc-apple-darwin8*:*86-apple-darwin*)
dnl Revert the changes made above. From this point on, the target
dnl compiler will never be used without applying the SDK to CFLAGS
dnl (see --with-macos-sdk below).
@ -496,7 +496,7 @@ fi
rm -f a.out
case "$build:$target" in
i?86-apple-darwin*:powerpc-apple-darwin*)
*86-apple-darwin*:powerpc-apple-darwin*)
dnl cross_compiling will have erroneously been set to "no" in this
dnl case, because the x86 build host is able to run ppc code in a
dnl translated environment, making a cross compiler appear native.
@ -975,7 +975,7 @@ case "$target" in
AC_DEFINE(HAVE_BSD_FLOCK)
CFLAGS="$CFLAGS -Wmost -fno-common"
case "${target_cpu}" in
i*86*)
*86*)
AC_DEFINE(i386)
CPU_ARCH=i386
PR_MD_ASFILES=os_Darwin_x86.s
@ -1014,7 +1014,7 @@ case "$target" in
dnl Architecture minimum 10.1
export MACOSX_DEPLOYMENT_TARGET=10.1
;;
i*86*)
*86*)
dnl Architecture minimum 10.4
export MACOSX_DEPLOYMENT_TARGET=10.4
;;

View File

@ -42,7 +42,7 @@ extern "C" {
#ifdef _MSC_VER
#ifndef uint32_t
#if !defined(_STDINT) && !defined(uint32_t)
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;

View File

@ -623,7 +623,7 @@ static ldl_status parse_jingle_code(ldl_handle_t *handle, iks *xml, char *to, ch
}
if (!(id && action)) {
if (!(id && action && from)) {
globals.logger(DL_LOG_CRIT, "missing required params\n");
return LDL_STATUS_FALSE;
}
@ -820,6 +820,9 @@ static ldl_status parse_jingle_code(ldl_handle_t *handle, iks *xml, char *to, ch
break;
}
}
} else {
globals.logger(DL_LOG_WARNING, "No preference specified");
continue;
}
if (index < 0) {

View File

@ -45,7 +45,7 @@ __RCSID("$NetBSD: unvis.c,v 1.28 2005/09/13 01:44:09 christos Exp $");
#include <stdio.h>
#include <vis.h>
#if defined(__weak_reference) && !defined(__FreeBSD__)
#if defined(__weak_reference) && !defined(__FreeBSD__) && !defined(__NetBSD__)
__weak_alias(strunvis,_strunvis)
#endif

View File

@ -915,14 +915,14 @@ vi_comment_out(EditLine *el, int c)
* NB: posix implies that we should enter insert mode, however
* this is against historical precedent...
*/
#if defined(__weak_reference) && !defined(__FreeBSD__)
#if defined(__weak_reference) && !defined(__FreeBSD__) && !defined(__NetBSD__)
extern char *get_alias_text(const char *) __weak_reference(get_alias_text);
#endif
protected el_action_t
/*ARGSUSED*/
vi_alias(EditLine *el, int c)
{
#if defined(__weak_reference) && !defined(__FreeBSD__)
#if defined(__weak_reference) && !defined(__FreeBSD__) && !defined(__NetBSD__)
char alias_name[3];
char *alias_text;

View File

@ -88,7 +88,7 @@ __RCSID("$NetBSD: vis.c,v 1.35 2006/08/28 20:42:12 christos Exp $");
#include <vis.h>
#include <stdlib.h>
#if defined(__weak_reference) && !defined(__FreeBSD__)
#if defined(__weak_reference) && !defined(__FreeBSD__) && !defined(__NetBSD__)
__weak_alias(strsvis,_strsvis)
__weak_alias(strsvisx,_strsvisx)
__weak_alias(strvis,_strvis)

View File

@ -200,7 +200,7 @@ AC_CHECK_HEADERS([audiofile.h])
AC_LANG([C])
if test "${build}" == "${host}"
if test "${build}" = "${host}"
then
case "${host}" in
x86_64-*)

26
libs/libks/Makefile Normal file
View File

@ -0,0 +1,26 @@
PWD=$(shell pwd)
INCS=-I$(PWD)/src/include
DEBUG=-g -ggdb
BASE_FLAGS=$(INCS) $(DEBUG) -I$(LIBEDIT_DIR)/src/ -fPIC
PICKY=-O2
CFLAGS=$(BASE_FLAGS) $(PICKY)
CXXFLAGS=$(BASE_FLAGS)
MYLIB=libks.a
LIBS=-lncurses -lks -lpthread -lm
LDFLAGS=-L.
OBJS=src/ks.o src/ks_threadmutex.o src/ks_config.o src/ks_json.o src/ks_buffer.o src/mpool.o src/table.o src/table_util.o src/simclist.o
SRC=src/ks.c src/ks_json.c src/ks_threadmutex.c src/ks_config.c src/ks_json.c src/ks_buffer.c src/mpool.c src/table.c src/table_util.c src/simclist.c
HEADERS=src/include/ks_config.h src/include/ks.h src/include/ks_threadmutex.h src/include/ks_json.h src/include/ks_buffer.h src/include/mpool.h src/include/mpool_loc.h src/include/table.h src/include/table_loc.h src/include/simclist.h
SOLINK=-shared -Xlinker -x
all: $(MYLIB)
$(MYLIB): $(OBJS) $(HEADERS) $(SRC)
ar rcs $(MYLIB) $(OBJS)
ranlib $(MYLIB)
%.o: %.c $(HEADERS)
$(CC) $(CC_CFLAGS) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o src/*.o libks.a *~ src/*~ src/include/*~

View File

@ -0,0 +1,2 @@
const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n";

371
libs/libks/src/include/ks.h Normal file
View File

@ -0,0 +1,371 @@
/*
* Copyright (c) 2007-2012, Anthony Minessale II
* 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 original author; nor the names of any 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.
*/
#ifndef _KS_H_
#define _KS_H_
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
#define ks_copy_string(_x, _y, _z) strncpy(_x, _y, _z - 1)
#define ks_set_string(_x, _y) ks_copy_string(_x, _y, sizeof(_x))
#define KS_VA_NONE "%s", ""
typedef enum {
KS_POLL_READ = (1 << 0),
KS_POLL_WRITE = (1 << 1),
KS_POLL_ERROR = (1 << 2)
} ks_poll_t;
#ifdef WIN32
#define KS_SEQ_FWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
#define KS_SEQ_BWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
#define KS_SEQ_FRED FOREGROUND_RED | FOREGROUND_INTENSITY
#define KS_SEQ_BRED FOREGROUND_RED
#define KS_SEQ_FMAGEN FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY
#define KS_SEQ_BMAGEN FOREGROUND_BLUE | FOREGROUND_RED
#define KS_SEQ_FCYAN FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
#define KS_SEQ_BCYAN FOREGROUND_GREEN | FOREGROUND_BLUE
#define KS_SEQ_FGREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY
#define KS_SEQ_BGREEN FOREGROUND_GREEN
#define KS_SEQ_FYELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY
#define KS_SEQ_BYELLOW FOREGROUND_RED | FOREGROUND_GREEN
#define KS_SEQ_DEFAULT_COLOR KS_SEQ_FWHITE
#define KS_SEQ_FBLUE FOREGROUND_BLUE | FOREGROUND_INTENSITY
#define KS_SEQ_BBLUE FOREGROUND_BLUE
#define KS_SEQ_FBLACK 0 | FOREGROUND_INTENSITY
#define KS_SEQ_BBLACK 0
#else
#define KS_SEQ_ESC "\033["
/* Ansi Control character suffixes */
#define KS_SEQ_HOME_CHAR 'H'
#define KS_SEQ_HOME_CHAR_STR "H"
#define KS_SEQ_CLEARLINE_CHAR '1'
#define KS_SEQ_CLEARLINE_CHAR_STR "1"
#define KS_SEQ_CLEARLINEEND_CHAR "K"
#define KS_SEQ_CLEARSCR_CHAR0 '2'
#define KS_SEQ_CLEARSCR_CHAR1 'J'
#define KS_SEQ_CLEARSCR_CHAR "2J"
#define KS_SEQ_DEFAULT_COLOR KS_SEQ_ESC KS_SEQ_END_COLOR /* Reset to Default fg/bg color */
#define KS_SEQ_AND_COLOR ";" /* To add multiple color definitions */
#define KS_SEQ_END_COLOR "m" /* To end color definitions */
/* Foreground colors values */
#define KS_SEQ_F_BLACK "30"
#define KS_SEQ_F_RED "31"
#define KS_SEQ_F_GREEN "32"
#define KS_SEQ_F_YELLOW "33"
#define KS_SEQ_F_BLUE "34"
#define KS_SEQ_F_MAGEN "35"
#define KS_SEQ_F_CYAN "36"
#define KS_SEQ_F_WHITE "37"
/* Background colors values */
#define KS_SEQ_B_BLACK "40"
#define KS_SEQ_B_RED "41"
#define KS_SEQ_B_GREEN "42"
#define KS_SEQ_B_YELLOW "43"
#define KS_SEQ_B_BLUE "44"
#define KS_SEQ_B_MAGEN "45"
#define KS_SEQ_B_CYAN "46"
#define KS_SEQ_B_WHITE "47"
/* Preset escape sequences - Change foreground colors only */
#define KS_SEQ_FBLACK KS_SEQ_ESC KS_SEQ_F_BLACK KS_SEQ_END_COLOR
#define KS_SEQ_FRED KS_SEQ_ESC KS_SEQ_F_RED KS_SEQ_END_COLOR
#define KS_SEQ_FGREEN KS_SEQ_ESC KS_SEQ_F_GREEN KS_SEQ_END_COLOR
#define KS_SEQ_FYELLOW KS_SEQ_ESC KS_SEQ_F_YELLOW KS_SEQ_END_COLOR
#define KS_SEQ_FBLUE KS_SEQ_ESC KS_SEQ_F_BLUE KS_SEQ_END_COLOR
#define KS_SEQ_FMAGEN KS_SEQ_ESC KS_SEQ_F_MAGEN KS_SEQ_END_COLOR
#define KS_SEQ_FCYAN KS_SEQ_ESC KS_SEQ_F_CYAN KS_SEQ_END_COLOR
#define KS_SEQ_FWHITE KS_SEQ_ESC KS_SEQ_F_WHITE KS_SEQ_END_COLOR
#define KS_SEQ_BBLACK KS_SEQ_ESC KS_SEQ_B_BLACK KS_SEQ_END_COLOR
#define KS_SEQ_BRED KS_SEQ_ESC KS_SEQ_B_RED KS_SEQ_END_COLOR
#define KS_SEQ_BGREEN KS_SEQ_ESC KS_SEQ_B_GREEN KS_SEQ_END_COLOR
#define KS_SEQ_BYELLOW KS_SEQ_ESC KS_SEQ_B_YELLOW KS_SEQ_END_COLOR
#define KS_SEQ_BBLUE KS_SEQ_ESC KS_SEQ_B_BLUE KS_SEQ_END_COLOR
#define KS_SEQ_BMAGEN KS_SEQ_ESC KS_SEQ_B_MAGEN KS_SEQ_END_COLOR
#define KS_SEQ_BCYAN KS_SEQ_ESC KS_SEQ_B_CYAN KS_SEQ_END_COLOR
#define KS_SEQ_BWHITE KS_SEQ_ESC KS_SEQ_B_WHITE KS_SEQ_END_COLOR
/* Preset escape sequences */
#define KS_SEQ_HOME KS_SEQ_ESC KS_SEQ_HOME_CHAR_STR
#define KS_SEQ_CLEARLINE KS_SEQ_ESC KS_SEQ_CLEARLINE_CHAR_STR
#define KS_SEQ_CLEARLINEEND KS_SEQ_ESC KS_SEQ_CLEARLINEEND_CHAR
#define KS_SEQ_CLEARSCR KS_SEQ_ESC KS_SEQ_CLEARSCR_CHAR KS_SEQ_HOME
#endif
#if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
#define _XOPEN_SOURCE 600
#endif
#ifndef HAVE_STRINGS_H
#define HAVE_STRINGS_H 1
#endif
#ifndef HAVE_SYS_SOCKET_H
#define HAVE_SYS_SOCKET_H 1
#endif
#ifndef __WINDOWS__
#if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)
#define __WINDOWS__
#endif
#endif
#ifdef _MSC_VER
#ifndef __inline__
#define __inline__ __inline
#endif
#if (_MSC_VER >= 1400) /* VC8+ */
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
#ifndef _CRT_NONSTDC_NO_DEPRECATE
#define _CRT_NONSTDC_NO_DEPRECATE
#endif
#endif
#ifndef strcasecmp
#define strcasecmp(s1, s2) _stricmp(s1, s2)
#endif
#ifndef strncasecmp
#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
#endif
#ifndef snprintf
#define snprintf _snprintf
#endif
#ifndef S_IRUSR
#define S_IRUSR _S_IREAD
#endif
#ifndef S_IWUSR
#define S_IWUSR _S_IWRITE
#endif
#undef HAVE_STRINGS_H
#undef HAVE_SYS_SOCKET_H
#endif
#include <time.h>
#ifndef WIN32
#include <sys/time.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <sys/types.h>
#include <sys/select.h>
#include <netinet/tcp.h>
#include <sys/signal.h>
#include <unistd.h>
#include <ctype.h>
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#include <assert.h>
#if (_MSC_VER >= 1400) // VC8+
#define ks_assert(expr) assert(expr);__analysis_assume( expr )
#endif
#ifndef ks_assert
#define ks_assert(_x) assert(_x)
#endif
#define ks_safe_free(_x) if (_x) free(_x); _x = NULL
#define ks_strlen_zero(s) (!s || *(s) == '\0')
#define ks_strlen_zero_buf(s) (*(s) == '\0')
#define end_of(_s) *(*_s == '\0' ? _s : _s + strlen(_s) - 1)
#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
typedef SOCKET ks_socket_t;
typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int8 uint8_t;
typedef __int64 int64_t;
typedef __int32 int32_t;
typedef __int16 int16_t;
typedef __int8 int8_t;
typedef intptr_t ks_ssize_t;
typedef int ks_filehandle_t;
#define KS_SOCK_INVALID INVALID_SOCKET
#define strerror_r(num, buf, size) strerror_s(buf, size, num)
#if defined(KS_DECLARE_STATIC)
#define KS_DECLARE(type) type __stdcall
#define KS_DECLARE_NONSTD(type) type __cdecl
#define KS_DECLARE_DATA
#elif defined(KS_EXPORTS)
#define KS_DECLARE(type) __declspec(dllexport) type __stdcall
#define KS_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl
#define KS_DECLARE_DATA __declspec(dllexport)
#else
#define KS_DECLARE(type) __declspec(dllimport) type __stdcall
#define KS_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl
#define KS_DECLARE_DATA __declspec(dllimport)
#endif
#else
#define KS_DECLARE(type) type
#define KS_DECLARE_NONSTD(type) type
#define KS_DECLARE_DATA
#include <stdint.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define KS_SOCK_INVALID -1
typedef int ks_socket_t;
typedef ssize_t ks_ssize_t;
typedef int ks_filehandle_t;
#endif
#include "math.h"
#include "ks_json.h"
typedef int16_t ks_port_t;
typedef size_t ks_size_t;
typedef enum {
KS_SUCCESS,
KS_FAIL,
KS_BREAK,
KS_DISCONNECTED,
KS_GENERR
} ks_status_t;
#define BUF_CHUNK 65536 * 50
#define BUF_START 65536 * 100
#include <ks_threadmutex.h>
#include <ks_buffer.h>
#define ks_test_flag(obj, flag) ((obj)->flags & flag)
#define ks_set_flag(obj, flag) (obj)->flags |= (flag)
#define ks_clear_flag(obj, flag) (obj)->flags &= ~(flag)
/*! \brief Used internally for truth test */
typedef enum {
KS_TRUE = 1,
KS_FALSE = 0
} ks_bool_t;
#ifndef __FUNCTION__
#define __FUNCTION__ (const char *)__func__
#endif
#define KS_PRE __FILE__, __FUNCTION__, __LINE__
#define KS_LOG_LEVEL_DEBUG 7
#define KS_LOG_LEVEL_INFO 6
#define KS_LOG_LEVEL_NOTICE 5
#define KS_LOG_LEVEL_WARNING 4
#define KS_LOG_LEVEL_ERROR 3
#define KS_LOG_LEVEL_CRIT 2
#define KS_LOG_LEVEL_ALERT 1
#define KS_LOG_LEVEL_EMERG 0
#define KS_LOG_DEBUG KS_PRE, KS_LOG_LEVEL_DEBUG
#define KS_LOG_INFO KS_PRE, KS_LOG_LEVEL_INFO
#define KS_LOG_NOTICE KS_PRE, KS_LOG_LEVEL_NOTICE
#define KS_LOG_WARNING KS_PRE, KS_LOG_LEVEL_WARNING
#define KS_LOG_ERROR KS_PRE, KS_LOG_LEVEL_ERROR
#define KS_LOG_CRIT KS_PRE, KS_LOG_LEVEL_CRIT
#define KS_LOG_ALERT KS_PRE, KS_LOG_LEVEL_ALERT
#define KS_LOG_EMERG KS_PRE, KS_LOG_LEVEL_EMERG
typedef void (*ks_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...);
typedef void (*ks_listen_callback_t)(ks_socket_t server_sock, ks_socket_t client_sock, struct sockaddr_in *addr);
KS_DECLARE(int) ks_vasprintf(char **ret, const char *fmt, va_list ap);
KS_DECLARE_DATA extern ks_logger_t ks_log;
/*! Sets the logger for libks. Default is the null_logger */
KS_DECLARE(void) ks_global_set_logger(ks_logger_t logger);
/*! Sets the default log level for libks */
KS_DECLARE(void) ks_global_set_default_logger(int level);
#include "ks_threadmutex.h"
#include "ks_config.h"
#include "ks_buffer.h"
#include "mpool.h"
#include "simclist.h"
#include "table.h"
KS_DECLARE(size_t) ks_url_encode(const char *url, char *buf, size_t len);
KS_DECLARE(char *)ks_url_decode(char *s);
KS_DECLARE(const char *)ks_stristr(const char *instr, const char *str);
KS_DECLARE(int) ks_toupper(int c);
KS_DECLARE(int) ks_tolower(int c);
KS_DECLARE(int) ks_snprintf(char *buffer, size_t count, const char *fmt, ...);
KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags);
KS_DECLARE(unsigned int) ks_separate_string_string(char *buf, const char *delim, char **array, unsigned int arraylen);
#define ks_recv(_h) ks_recv_event(_h, 0, NULL)
#define ks_recv_timed(_h, _ms) ks_recv_event_timed(_h, _ms, 0, NULL)
static __inline__ int ks_safe_strcasecmp(const char *s1, const char *s2)
{
if (!(s1 && s2)) {
return 1;
}
return strcasecmp(s1, s2);
}
#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */
#endif /* defined(_KS_H_) */
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/

View File

@ -0,0 +1,146 @@
/*
* Copyright (c) 2010-2012, Anthony Minessale II
* 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 original author; nor the names of any 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.
*/
#include "ks.h"
#ifndef KS_BUFFER_H
#define KS_BUFFER_H
/**
* @defgroup ks_buffer Buffer Routines
* @ingroup buffer
* The purpose of this module is to make a plain buffering interface that can be used for read/write buffers
* throughout the application.
* @{
*/
struct ks_buffer;
typedef struct ks_buffer ks_buffer_t;
/*! \brief Allocate a new dynamic ks_buffer
* \param buffer returned pointer to the new buffer
* \param blocksize length to realloc by as data is added
* \param start_len ammount of memory to reserve initially
* \param max_len length the buffer is allowed to grow to
* \return status
*/
KS_DECLARE(ks_status_t) ks_buffer_create(ks_buffer_t **buffer, ks_size_t blocksize, ks_size_t start_len, ks_size_t max_len);
/*! \brief Get the length of a ks_buffer_t
* \param buffer any buffer of type ks_buffer_t
* \return int size of the buffer.
*/
KS_DECLARE(ks_size_t) ks_buffer_len(ks_buffer_t *buffer);
/*! \brief Get the freespace of a ks_buffer_t
* \param buffer any buffer of type ks_buffer_t
* \return int freespace in the buffer.
*/
KS_DECLARE(ks_size_t) ks_buffer_freespace(ks_buffer_t *buffer);
/*! \brief Get the in use amount of a ks_buffer_t
* \param buffer any buffer of type ks_buffer_t
* \return int ammount of buffer curently in use
*/
KS_DECLARE(ks_size_t) ks_buffer_inuse(ks_buffer_t *buffer);
/*! \brief Read data from a ks_buffer_t up to the ammount of datalen if it is available. Remove read data from buffer.
* \param buffer any buffer of type ks_buffer_t
* \param data pointer to the read data to be returned
* \param datalen amount of data to be returned
* \return int ammount of data actually read
*/
KS_DECLARE(ks_size_t) ks_buffer_read(ks_buffer_t *buffer, void *data, ks_size_t datalen);
KS_DECLARE(ks_size_t) ks_buffer_read_packet(ks_buffer_t *buffer, void *data, ks_size_t maxlen);
KS_DECLARE(ks_size_t) ks_buffer_packet_count(ks_buffer_t *buffer);
/*! \brief Read data endlessly from a ks_buffer_t
* \param buffer any buffer of type ks_buffer_t
* \param data pointer to the read data to be returned
* \param datalen amount of data to be returned
* \return int ammount of data actually read
* \note Once you have read all the data from the buffer it will loop around.
*/
KS_DECLARE(ks_size_t) ks_buffer_read_loop(ks_buffer_t *buffer, void *data, ks_size_t datalen);
/*! \brief Assign a number of loops to read
* \param buffer any buffer of type ks_buffer_t
* \param loops the number of loops (-1 for infinite)
*/
KS_DECLARE(void) ks_buffer_set_loops(ks_buffer_t *buffer, int32_t loops);
/*! \brief Write data into a ks_buffer_t up to the length of datalen
* \param buffer any buffer of type ks_buffer_t
* \param data pointer to the data to be written
* \param datalen amount of data to be written
* \return int amount of buffer used after the write, or 0 if no space available
*/
KS_DECLARE(ks_size_t) ks_buffer_write(ks_buffer_t *buffer, const void *data, ks_size_t datalen);
/*! \brief Remove data from the buffer
* \param buffer any buffer of type ks_buffer_t
* \param datalen amount of data to be removed
* \return int size of buffer, or 0 if unable to toss that much data
*/
KS_DECLARE(ks_size_t) ks_buffer_toss(ks_buffer_t *buffer, ks_size_t datalen);
/*! \brief Remove all data from the buffer
* \param buffer any buffer of type ks_buffer_t
*/
KS_DECLARE(void) ks_buffer_zero(ks_buffer_t *buffer);
/*! \brief Destroy the buffer
* \param buffer buffer to destroy
* \note only neccessary on dynamic buffers (noop on pooled ones)
*/
KS_DECLARE(void) ks_buffer_destroy(ks_buffer_t **buffer);
/*! \brief Seek to offset from the beginning of the buffer
* \param buffer buffer to seek
* \param datalen offset in bytes
* \return new position
*/
KS_DECLARE(ks_size_t) ks_buffer_seek(ks_buffer_t *buffer, ks_size_t datalen);
/** @} */
KS_DECLARE(ks_size_t) ks_buffer_zwrite(ks_buffer_t *buffer, const void *data, ks_size_t datalen);
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/

View File

@ -0,0 +1,178 @@
/*
* Copyright (c) 2007-2012, Anthony Minessale II
* 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 original author; nor the names of any 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.
*/
/**
* @defgroup config Config File Parser
* @ingroup config
* This module implements a basic interface and file format parser
*
* <pre>
*
* EXAMPLE
*
* [category1]
* var1 => val1
* var2 => val2
* \# lines that begin with \# are comments
* \#var3 => val3
* </pre>
* @{
*/
#ifndef KS_CONFIG_H
#define KS_CONFIG_H
#include "ks.h"
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
#define KS_URL_SEPARATOR "://"
#ifdef WIN32
#define KS_PATH_SEPARATOR "\\"
#ifndef KS_CONFIG_DIR
#define KS_CONFIG_DIR "c:\\openks"
#endif
#define ks_is_file_path(file) (*(file +1) == ':' || *file == '/' || strstr(file, SWITCH_URL_SEPARATOR))
#else
#define KS_PATH_SEPARATOR "/"
#ifndef KS_CONFIG_DIR
#define KS_CONFIG_DIR "/etc/openks"
#endif
#define ks_is_file_path(file) ((*file == '/') || strstr(file, SWITCH_URL_SEPARATOR))
#endif
/*!
\brief Evaluate the truthfullness of a string expression
\param expr a string expression
\return true or false
*/
#define ks_true(expr)\
(expr && ( !strcasecmp(expr, "yes") ||\
!strcasecmp(expr, "on") ||\
!strcasecmp(expr, "true") ||\
!strcasecmp(expr, "enabled") ||\
!strcasecmp(expr, "active") ||\
!strcasecmp(expr, "allow") ||\
atoi(expr))) ? 1 : 0
/*!
\brief Evaluate the falsefullness of a string expression
\param expr a string expression
\return true or false
*/
#define ks_false(expr)\
(expr && ( !strcasecmp(expr, "no") ||\
!strcasecmp(expr, "off") ||\
!strcasecmp(expr, "false") ||\
!strcasecmp(expr, "disabled") ||\
!strcasecmp(expr, "inactive") ||\
!strcasecmp(expr, "disallow") ||\
!atoi(expr))) ? 1 : 0
typedef struct ks_config ks_config_t;
/*! \brief A simple file handle representing an open configuration file **/
struct ks_config {
/*! FILE stream buffer to the opened file */
FILE *file;
/*! path to the file */
char path[512];
/*! current category */
char category[256];
/*! current section */
char section[256];
/*! buffer of current line being read */
char buf[1024];
/*! current line number in file */
int lineno;
/*! current category number in file */
int catno;
/*! current section number in file */
int sectno;
int lockto;
};
/*!
\brief Open a configuration file
\param cfg (ks_config_t *) config handle to use
\param file_path path to the file
\return 1 (true) on success 0 (false) on failure
*/
KS_DECLARE(int) ks_config_open_file(ks_config_t * cfg, const char *file_path);
/*!
\brief Close a previously opened configuration file
\param cfg (ks_config_t *) config handle to use
*/
KS_DECLARE(void) ks_config_close_file(ks_config_t * cfg);
/*!
\brief Retrieve next name/value pair from configuration file
\param cfg (ks_config_t *) config handle to use
\param var pointer to aim at the new variable name
\param val pointer to aim at the new value
*/
KS_DECLARE(int) ks_config_next_pair(ks_config_t * cfg, char **var, char **val);
/*!
\brief Retrieve the CAS bits from a configuration string value
\param strvalue pointer to the configuration string value (expected to be in format whatever:xxxx)
\param outbits pointer to aim at the CAS bits
*/
KS_DECLARE(int) ks_config_get_cas_bits(char *strvalue, unsigned char *outbits);
/** @} */
#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */
#endif /* defined(KS_CONFIG_H) */
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/

127
libs/libks/src/include/ks_json.h Executable file
View File

@ -0,0 +1,127 @@
/*
Copyright (c) 2009 Dave Gamble
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 "ks.h"
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
#define cJSON_IsReference 256
/* The cJSON structure: */
typedef struct cJSON {
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;
typedef struct cJSON_Hooks {
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks;
/* Supply malloc, realloc and free functions to cJSON */
KS_DECLARE(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
KS_DECLARE(cJSON *)cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
KS_DECLARE(char *)cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
KS_DECLARE(char *)cJSON_PrintUnformatted(cJSON *item);
/* Delete a cJSON entity and all subentities. */
KS_DECLARE(void) cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
KS_DECLARE(int) cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
KS_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item);
/* Get item "string" from object. Case insensitive. */
KS_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
KS_DECLARE(const char *)cJSON_GetErrorPtr();
/* These calls create a cJSON item of the appropriate type. */
KS_DECLARE(cJSON *)cJSON_CreateNull();
KS_DECLARE(cJSON *)cJSON_CreateTrue();
KS_DECLARE(cJSON *)cJSON_CreateFalse();
KS_DECLARE(cJSON *)cJSON_CreateBool(int b);
KS_DECLARE(cJSON *)cJSON_CreateNumber(double num);
KS_DECLARE(cJSON *)cJSON_CreateString(const char *string);
KS_DECLARE(cJSON *)cJSON_CreateArray();
KS_DECLARE(cJSON *)cJSON_CreateObject();
/* These utilities create an Array of count items. */
KS_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count);
KS_DECLARE(cJSON *)cJSON_CreateFloatArray(float *numbers,int count);
KS_DECLARE(cJSON *)cJSON_CreateDoubleArray(double *numbers,int count);
KS_DECLARE(cJSON *)cJSON_CreateStringArray(const char **strings,int count);
/* Append item to the specified array/object. */
KS_DECLARE(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
KS_DECLARE(void) cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
KS_DECLARE(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
KS_DECLARE(void) cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
KS_DECLARE(cJSON *)cJSON_DetachItemFromArray(cJSON *array,int which);
KS_DECLARE(void) cJSON_DeleteItemFromArray(cJSON *array,int which);
KS_DECLARE(cJSON *)cJSON_DetachItemFromObject(cJSON *object,const char *string);
KS_DECLARE(void) cJSON_DeleteItemFromObject(cJSON *object,const char *string);
/* Update array items. */
KS_DECLARE(void) cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
KS_DECLARE(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,58 @@
/*
* Cross Platform Thread/Mutex abstraction
* Copyright(C) 2007 Michael Jerris
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so.
*
* This work is provided under this license on an "as is" basis, without warranty of any kind,
* either expressed or implied, including, without limitation, warranties that the covered code
* is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire
* risk as to the quality and performance of the covered code is with you. Should any covered
* code prove defective in any respect, you (not the initial developer or any other contributor)
* assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty
* constitutes an essential part of this license. No use of any covered code is authorized hereunder
* except under this disclaimer.
*
*/
#ifndef _KS_THREADMUTEX_H
#define _KS_THREADMUTEX_H
#include "ks.h"
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
typedef struct ks_mutex ks_mutex_t;
typedef struct ks_thread ks_thread_t;
typedef void *(*ks_thread_function_t) (ks_thread_t *, void *);
KS_DECLARE(ks_status_t) ks_thread_create_detached(ks_thread_function_t func, void *data);
ks_status_t ks_thread_create_detached_ex(ks_thread_function_t func, void *data, size_t stack_size);
void ks_thread_override_default_stacksize(size_t size);
KS_DECLARE(ks_status_t) ks_mutex_create(ks_mutex_t **mutex);
KS_DECLARE(ks_status_t) ks_mutex_destroy(ks_mutex_t **mutex);
KS_DECLARE(ks_status_t) ks_mutex_lock(ks_mutex_t *mutex);
KS_DECLARE(ks_status_t) ks_mutex_trylock(ks_mutex_t *mutex);
KS_DECLARE(ks_status_t) ks_mutex_unlock(ks_mutex_t *mutex);
#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */
#endif /* defined(_KS_THREADMUTEX_H) */
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/

View File

@ -0,0 +1,463 @@
/*
* Memory pool defines.
*
* Copyright 1996 by Gray Watson.
*
* This file is part of the mpool package.
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies, and that the name of Gray Watson not be used in advertising
* or publicity pertaining to distribution of the document or software
* without specific, written prior permission.
*
* Gray Watson makes no representations about the suitability of the
* software described herein for any purpose. It is provided "as is"
* without express or implied warranty.
*
* The author may be reached via http://256.com/gray/
*
* $Id: mpool.h,v 1.4 2006/05/31 20:26:11 gray Exp $
*/
#ifndef __MPOOL_H__
#define __MPOOL_H__
#include <sys/types.h>
/*
* mpool flags to mpool_alloc or mpool_set_attr
*/
/*
* Choose a best fit algorithm not first fit. This takes more CPU
* time but will result in a tighter heap.
*/
#define MPOOL_FLAG_BEST_FIT (1<<0)
/*
* By default the library adds 2 bytes onto all allocations to insert
* a magic number that it can look for to determine how large a freed
* memory chunk is. This flag indicates that few if any frees are
* going to be performed on the pool and to not waste memory on these
* bytes.
*/
#define MPOOL_FLAG_NO_FREE (1<<1)
/*
* This enables very heavy packing at the possible expense of CPU.
* This affects a number of parts of the library.
*
* By default the 1st page of memory is reserved for the main mpool
* structure. This flag will cause the rest of the 1st block to be
* available for use as user memory.
*
* By default the library looks through the memory when freed looking
* for a magic value. There is an internal max size that it will look
* and then it will give up. This flag forces it to look until it
* finds it.
*/
#define MPOOL_FLAG_HEAVY_PACKING (1<<2)
/*
* Use sbrk not mmap to allocate pages. This is not recommended for
* normal use.
*/
#define MPOOL_FLAG_USE_SBRK (1<<3)
/*
* Mpool error codes
*/
#define MPOOL_ERROR_NONE 1 /* no error */
#define MPOOL_ERROR_ARG_NULL 2 /* function argument is null */
#define MPOOL_ERROR_ARG_INVALID 3 /* function argument is invalid */
#define MPOOL_ERROR_PNT 4 /* invalid mpool pointer */
#define MPOOL_ERROR_POOL_OVER 5 /* mpool structure was overwritten */
#define MPOOL_ERROR_PAGE_SIZE 6 /* could not get system page-size */
#define MPOOL_ERROR_OPEN_ZERO 7 /* could not open /dev/zero */
#define MPOOL_ERROR_NO_MEM 8 /* no memory available */
#define MPOOL_ERROR_MMAP 9 /* problems with mmap */
#define MPOOL_ERROR_SIZE 10 /* error processing requested size */
#define MPOOL_ERROR_TOO_BIG 11 /* allocation exceeded max size */
#define MPOOL_ERROR_MEM 12 /* invalid memory address */
#define MPOOL_ERROR_MEM_OVER 13 /* memory lower bounds overwritten */
#define MPOOL_ERROR_NOT_FOUND 14 /* memory block not found in pool */
#define MPOOL_ERROR_IS_FREE 15 /* memory block already free */
#define MPOOL_ERROR_BLOCK_STAT 16 /* invalid internal block status */
#define MPOOL_ERROR_FREE_ADDR 17 /* invalid internal free address */
#define MPOOL_ERROR_SBRK_CONTIG 18 /* sbrk did not return contiguous mem*/
#define MPOOL_ERROR_NO_PAGES 19 /* ran out of pages in pool */
#define MPOOL_ERROR_ALLOC 20 /* calloc,malloc,free,realloc failed */
#define MPOOL_ERROR_PNT_OVER 21 /* pointer structure was overwritten */
/*
* Mpool function IDs for the mpool_log_func callback function.
*/
#define MPOOL_FUNC_CLOSE 1 /* mpool_close function called */
#define MPOOL_FUNC_CLEAR 2 /* mpool_clear function called */
#define MPOOL_FUNC_ALLOC 3 /* mpool_alloc function called */
#define MPOOL_FUNC_CALLOC 4 /* mpool_calloc function called */
#define MPOOL_FUNC_FREE 5 /* mpool_free function called */
#define MPOOL_FUNC_RESIZE 6 /* mpool_resize function called */
/*
* void mpool_log_func_t
*
* DESCRIPTION:
*
* Mpool transaction log function.
*
* RETURNS:
*
* None.
*
* ARGUMENT:
*
* mp_p -> Associated mpool address.
*
* func_id -> Integer function ID which identifies which mpool
* function is being called.
*
* byte_size -> Optionally specified byte size.
*
* ele_n -> Optionally specified element number. For mpool_calloc
* only.
*
* new_addr -> Optionally specified new address. For mpool_alloc,
* mpool_calloc, and mpool_resize only.
*
* old_addr -> Optionally specified old address. For mpool_resize and
* mpool_free only.
*
* old_byte_size -> Optionally specified old byte size. For
* mpool_resize only.
*/
typedef void (*mpool_log_func_t)(const void *mp_p,
const int func_id,
const unsigned long byte_size,
const unsigned long ele_n,
const void *old_addr, const void *new_addr,
const unsigned long old_byte_size);
#ifdef MPOOL_MAIN
#include "mpool_loc.h"
#else
/* generic mpool type */
typedef void mpool_t;
#endif
/*<<<<<<<<<< The below prototypes are auto-generated by fillproto */
/*
* mpool_t *mpool_open
*
* DESCRIPTION:
*
* Open/allocate a new memory pool.
*
* RETURNS:
*
* Success - Pool pointer which must be passed to mpool_close to
* deallocate.
*
* Failure - NULL
*
* ARGUMENTS:
*
* flags -> Flags to set attributes of the memory pool. See the top
* of mpool.h.
*
* page_size -> Set the internal memory page-size. This must be a
* multiple of the getpagesize() value. Set to 0 for the default.
*
* start_addr -> Starting address to try and allocate memory pools.
* This is ignored if the MPOOL_FLAG_USE_SBRK is enabled.
*
* error_p <- Pointer to integer which, if not NULL, will be set with
* a mpool error code.
*/
extern
mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size,
void *start_addr, int *error_p);
/*
* int mpool_close
*
* DESCRIPTION:
*
* Close/free a memory allocation pool previously opened with
* mpool_open.
*
* RETURNS:
*
* Success - MPOOL_ERROR_NONE
*
* Failure - Mpool error code
*
* ARGUMENTS:
*
* mp_p <-> Pointer to our memory pool.
*/
extern
int mpool_close(mpool_t *mp_p);
/*
* int mpool_clear
*
* DESCRIPTION:
*
* Wipe an opened memory pool clean so we can start again.
*
* RETURNS:
*
* Success - MPOOL_ERROR_NONE
*
* Failure - Mpool error code
*
* ARGUMENTS:
*
* mp_p <-> Pointer to our memory pool.
*/
extern
int mpool_clear(mpool_t *mp_p);
/*
* void *mpool_alloc
*
* DESCRIPTION:
*
* Allocate space for bytes inside of an already open memory pool.
*
* RETURNS:
*
* Success - Pointer to the address to use.
*
* Failure - NULL
*
* ARGUMENTS:
*
* mp_p <-> Pointer to the memory pool. If NULL then it will do a
* normal malloc.
*
* byte_size -> Number of bytes to allocate in the pool. Must be >0.
*
* error_p <- Pointer to integer which, if not NULL, will be set with
* a mpool error code.
*/
extern
void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size,
int *error_p);
/*
* void *mpool_calloc
*
* DESCRIPTION:
*
* Allocate space for elements of bytes in the memory pool and zero
* the space afterwards.
*
* RETURNS:
*
* Success - Pointer to the address to use.
*
* Failure - NULL
*
* ARGUMENTS:
*
* mp_p <-> Pointer to the memory pool. If NULL then it will do a
* normal calloc.
*
* ele_n -> Number of elements to allocate.
*
* ele_size -> Number of bytes per element being allocated.
*
* error_p <- Pointer to integer which, if not NULL, will be set with
* a mpool error code.
*/
extern
void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n,
const unsigned long ele_size, int *error_p);
/*
* int mpool_free
*
* DESCRIPTION:
*
* Free an address from a memory pool.
*
* RETURNS:
*
* Success - MPOOL_ERROR_NONE
*
* Failure - Mpool error code
*
* ARGUMENTS:
*
* mp_p <-> Pointer to the memory pool. If NULL then it will do a
* normal free.
*
* addr <-> Address to free.
*
* size -> Size of the address being freed.
*/
extern
int mpool_free(mpool_t *mp_p, void *addr, const unsigned long size);
/*
* void *mpool_resize
*
* DESCRIPTION:
*
* Reallocate an address in a mmeory pool to a new size. This is
* different from realloc in that it needs the old address' size. If
* you don't have it then you need to allocate new space, copy the
* data, and free the old pointer yourself.
*
* RETURNS:
*
* Success - Pointer to the address to use.
*
* Failure - NULL
*
* ARGUMENTS:
*
* mp_p <-> Pointer to the memory pool. If NULL then it will do a
* normal realloc.
*
* old_addr -> Previously allocated address.
*
* old_byte_size -> Size of the old address. Must be known, cannot be
* 0.
*
* new_byte_size -> New size of the allocation.
*
* error_p <- Pointer to integer which, if not NULL, will be set with
* a mpool error code.
*/
extern
void *mpool_resize(mpool_t *mp_p, void *old_addr,
const unsigned long old_byte_size,
const unsigned long new_byte_size,
int *error_p);
/*
* int mpool_stats
*
* DESCRIPTION:
*
* Return stats from the memory pool.
*
* RETURNS:
*
* Success - MPOOL_ERROR_NONE
*
* Failure - Mpool error code
*
* ARGUMENTS:
*
* mp_p -> Pointer to the memory pool.
*
* page_size_p <- Pointer to an unsigned integer which, if not NULL,
* will be set to the page-size of the pool.
*
* num_alloced_p <- Pointer to an unsigned long which, if not NULL,
* will be set to the number of pointers currently allocated in pool.
*
* user_alloced_p <- Pointer to an unsigned long which, if not NULL,
* will be set to the number of user bytes allocated in this pool.
*
* max_alloced_p <- Pointer to an unsigned long which, if not NULL,
* will be set to the maximum number of user bytes that have been
* allocated in this pool.
*
* tot_alloced_p <- Pointer to an unsigned long which, if not NULL,
* will be set to the total amount of space (including administrative
* overhead) used by the pool.
*/
extern
int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p,
unsigned long *num_alloced_p,
unsigned long *user_alloced_p,
unsigned long *max_alloced_p,
unsigned long *tot_alloced_p);
/*
* int mpool_set_log_func
*
* DESCRIPTION:
*
* Set a logging callback function to be called whenever there was a
* memory transaction. See mpool_log_func_t.
*
* RETURNS:
*
* Success - MPOOL_ERROR_NONE
*
* Failure - Mpool error code
*
* ARGUMENTS:
*
* mp_p <-> Pointer to the memory pool.
*
* log_func -> Log function (defined in mpool.h) which will be called
* with each mpool transaction.
*/
extern
int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func);
/*
* int mpool_set_max_pages
*
* DESCRIPTION:
*
* Set the maximum number of pages that the library will use. Once it
* hits the limit it will return MPOOL_ERROR_NO_PAGES.
*
* NOTE: if the MPOOL_FLAG_HEAVY_PACKING is set then this max-pages
* value will include the page with the mpool header structure in it.
* If the flag is _not_ set then the max-pages will not include this
* first page.
*
* RETURNS:
*
* Success - MPOOL_ERROR_NONE
*
* Failure - Mpool error code
*
* ARGUMENTS:
*
* mp_p <-> Pointer to the memory pool.
*
* max_pages -> Maximum number of pages used by the library.
*/
extern
int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages);
/*
* const char *mpool_strerror
*
* DESCRIPTION:
*
* Return the corresponding string for the error number.
*
* RETURNS:
*
* Success - String equivalient of the error.
*
* Failure - String "invalid error code"
*
* ARGUMENTS:
*
* error -> Error number that we are converting.
*/
extern
const char *mpool_strerror(const int error);
/*<<<<<<<<<< This is end of the auto-generated output from fillproto. */
#endif /* ! __MPOOL_H__ */

View File

@ -0,0 +1,116 @@
/*
* Memory pool local defines.
*
* Copyright 1996 by Gray Watson.
*
* This file is part of the mpool package.
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies, and that the name of Gray Watson not be used in advertising
* or publicity pertaining to distribution of the document or software
* without specific, written prior permission.
*
* Gray Watson makes no representations about the suitability of the
* software described herein for any purpose. It is provided "as is"
* without express or implied warranty.
*
* The author may be reached via http://256.com/gray/
*
* $Id: mpool_loc.h,v 1.2 2005/05/20 20:08:54 gray Exp $
*/
#ifndef __MPOOL_LOC_H__
#define __MPOOL_LOC_H__
#define MPOOL_MAGIC 0xABACABA /* magic for struct */
#define BLOCK_MAGIC 0xB1B1007 /* magic for blocks */
#define FENCE_MAGIC0 (unsigned char)(0xFAU) /* 1st magic mem byte */
#define FENCE_MAGIC1 (unsigned char)(0xD3U) /* 2nd magic mem byte */
#define FENCE_SIZE 2 /* fence space */
#define MIN_ALLOCATION (sizeof(mpool_free_t)) /* min alloc */
#define MAX_FREE_SEARCH 10240 /* max size to search */
#define MAX_FREE_LIST_SEARCH 100 /* max looking for free mem */
/*
* bitflag tools for Variable and a Flag
*/
#define BIT_FLAG(x) (1 << (x))
#define BIT_SET(v,f) (v) |= (f)
#define BIT_CLEAR(v,f) (v) &= ~(f)
#define BIT_IS_SET(v,f) ((v) & (f))
#define BIT_TOGGLE(v,f) (v) ^= (f)
#define SET_POINTER(pnt, val) \
do { \
if ((pnt) != NULL) { \
(*(pnt)) = (val); \
} \
} while(0)
#define BLOCK_FLAG_USED BIT_FLAG(0) /* block is used */
#define BLOCK_FLAG_FREE BIT_FLAG(1) /* block is free */
#define DEFAULT_PAGE_MULT 16 /* pagesize = this * getpagesize*/
/* How many pages SIZE bytes resides in. We add in the block header. */
#define PAGES_IN_SIZE(mp_p, size) (((size) + sizeof(mpool_block_t) + \
(mp_p)->mp_page_size - 1) / \
(mp_p)->mp_page_size)
#define SIZE_OF_PAGES(mp_p, page_n) ((page_n) * (mp_p)->mp_page_size)
#define MAX_BITS 30 /* we only can allocate 1gb chunks */
#define MAX_BLOCK_USER_MEMORY(mp_p) ((mp_p)->mp_page_size - \
sizeof(mpool_block_t))
#define FIRST_ADDR_IN_BLOCK(block_p) (void *)((char *)(block_p) + \
sizeof(mpool_block_t))
#define MEMORY_IN_BLOCK(block_p) ((char *)(block_p)->mb_bounds_p - \
((char *)(block_p) + \
sizeof(mpool_block_t)))
typedef struct {
unsigned int mp_magic; /* magic number for struct */
unsigned int mp_flags; /* flags for the struct */
unsigned long mp_alloc_c; /* number of allocations */
unsigned long mp_user_alloc; /* user bytes allocated */
unsigned long mp_max_alloc; /* maximum user bytes allocated */
unsigned int mp_page_c; /* number of pages allocated */
unsigned int mp_max_pages; /* maximum number of pages to use */
unsigned int mp_page_size; /* page-size of our system */
int mp_fd; /* fd for /dev/zero if mmap-ing */
off_t mp_top; /* top of our allocations in fd */
mpool_log_func_t mp_log_func; /* log callback function */
void *mp_addr; /* current address for mmaping */
void *mp_min_p; /* min address in pool for checks */
void *mp_bounds_p; /* max address in pool for checks */
struct mpool_block_st *mp_first_p; /* first memory block we are using */
struct mpool_block_st *mp_last_p; /* last memory block we are using */
struct mpool_block_st *mp_free[MAX_BITS + 1]; /* free lists based on size */
unsigned int mp_magic2; /* upper magic for overwrite sanity */
} mpool_t;
/* for debuggers to be able to interrogate the generic type in the .h file */
typedef mpool_t mpool_ext_t;
/*
* Block header structure. This structure *MUST* be long-word
* aligned.
*/
typedef struct mpool_block_st {
unsigned int mb_magic; /* magic number for block header */
void *mb_bounds_p; /* block boundary location */
struct mpool_block_st *mb_next_p; /* linked list next pointer */
unsigned int mb_magic2; /* upper magic for overwrite sanity */
} mpool_block_t;
/*
* Free list structure.
*/
typedef struct {
void *mf_next_p; /* pointer to the next free address */
unsigned long mf_size; /* size of the free block */
} mpool_free_t;
#endif /* ! __MPOOL_LOC_H__ */

980
libs/libks/src/include/simclist.h Executable file
View File

@ -0,0 +1,980 @@
/*
* Copyright (c) 2007,2008 Mij <mij@bitchx.it>
*
* 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.
*/
/*
* SimCList library. See http://mij.oltrelinux.com/devel/simclist
*/
#ifndef SIMCLIST_H
#define SIMCLIST_H
#ifdef __cplusplus
extern "C" {
#endif
#include <inttypes.h>
#include <errno.h>
#include <sys/types.h>
#ifndef SIMCLIST_NO_DUMPRESTORE
# ifndef _WIN32
# include <sys/time.h> /* list_dump_info_t's struct timeval */
# else
# include <time.h>
# endif
#endif
/* Be friend of both C90 and C99 compilers */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
/* "inline" and "restrict" are keywords */
#else
# define inline /* inline */
# define restrict /* restrict */
#endif
/**
* Type representing list hashes.
*
* This is a signed integer value.
*/
typedef int32_t list_hash_t;
#ifndef SIMCLIST_NO_DUMPRESTORE
typedef struct {
uint16_t version; /* dump version */
struct timeval timestamp; /* when the list has been dumped, seconds since UNIX epoch */
uint32_t list_size;
uint32_t list_numels;
list_hash_t list_hash; /* hash of the list when dumped, or 0 if invalid */
uint32_t dumpsize;
int consistent; /* 1 if the dump is verified complete/consistent; 0 otherwise */
} list_dump_info_t;
#endif
/**
* a comparator of elements.
*
* A comparator of elements is a function that:
* -# receives two references to elements a and b
* -# returns {<0, 0, >0} if (a > b), (a == b), (a < b) respectively
*
* It is responsability of the function to handle possible NULL values.
*/
typedef int (*element_comparator)(const void *a, const void *b);
/**
* a seeker of elements.
*
* An element seeker is a function that:
* -# receives a reference to an element el
* -# receives a reference to some indicator data
* -# returns non-0 if the element matches the indicator, 0 otherwise
*
* It is responsability of the function to handle possible NULL values in any
* argument.
*/
typedef int (*element_seeker)(const void *el, const void *indicator);
/**
* an element lenght meter.
*
* An element meter is a function that:
* -# receives the reference to an element el
* -# returns its size in bytes
*
* It is responsability of the function to handle possible NULL values.
*/
typedef size_t (*element_meter)(const void *el);
/**
* a function computing the hash of elements.
*
* An hash computing function is a function that:
* -# receives the reference to an element el
* -# returns a hash value for el
*
* It is responsability of the function to handle possible NULL values.
*/
typedef list_hash_t (*element_hash_computer)(const void *el);
/**
* a function for serializing an element.
*
* A serializer function is one that gets a reference to an element,
* and returns a reference to a buffer that contains its serialization
* along with the length of this buffer.
* It is responsability of the function to handle possible NULL values,
* returning a NULL buffer and a 0 buffer length.
*
* These functions have 3 goals:
* -# "freeze" and "flatten" the memory representation of the element
* -# provide a portable (wrt byte order, or type size) representation of the element, if the dump can be used on different sw/hw combinations
* -# possibly extract a compressed representation of the element
*
* @param el reference to the element data
* @param serialize_buffer reference to fill with the length of the buffer
* @return reference to the buffer with the serialized data
*/
typedef void *(*element_serializer)(const void *restrict el, uint32_t *restrict serializ_len);
/**
* a function for un-serializing an element.
*
* An unserializer function accomplishes the inverse operation of the
* serializer function. An unserializer function is one that gets a
* serialized representation of an element and turns it backe to the original
* element. The serialized representation is passed as a reference to a buffer
* with its data, and the function allocates and returns the buffer containing
* the original element, and it sets the length of this buffer into the
* integer passed by reference.
*
* @param data reference to the buffer with the serialized representation of the element
* @param data_len reference to the location where to store the length of the data in the buffer returned
* @return reference to a buffer with the original, unserialized representation of the element
*/
typedef void *(*element_unserializer)(const void *restrict data, uint32_t *restrict data_len);
/* [private-use] list entry -- olds actual user datum */
struct list_entry_s {
void *data;
/* doubly-linked list service references */
struct list_entry_s *next;
struct list_entry_s *prev;
};
/* [private-use] list attributes */
struct list_attributes_s {
/* user-set routine for comparing list elements */
element_comparator comparator;
/* user-set routing for seeking elements */
element_seeker seeker;
/* user-set routine for determining the length of an element */
element_meter meter;
int copy_data;
/* user-set routine for computing the hash of an element */
element_hash_computer hasher;
/* user-set routine for serializing an element */
element_serializer serializer;
/* user-set routine for unserializing an element */
element_unserializer unserializer;
};
/** list object */
typedef struct {
struct list_entry_s *head_sentinel;
struct list_entry_s *tail_sentinel;
struct list_entry_s *mid;
unsigned int numels;
/* array of spare elements */
struct list_entry_s **spareels;
unsigned int spareelsnum;
#ifdef SIMCLIST_WITH_THREADS
/* how many threads are currently running */
unsigned int threadcount;
#endif
/* service variables for list iteration */
int iter_active;
unsigned int iter_pos;
struct list_entry_s *iter_curentry;
/* list attributes */
struct list_attributes_s attrs;
} list_t;
/**
* initialize a list object for use.
*
* @param l must point to a user-provided memory location
* @return 0 for success. -1 for failure
*/
int list_init(list_t *restrict l);
/**
* completely remove the list from memory.
*
* This function is the inverse of list_init(). It is meant to be called when
* the list is no longer going to be used. Elements and possible memory taken
* for internal use are freed.
*
* @param l list to destroy
*/
void list_destroy(list_t *restrict l);
/**
* set the comparator function for list elements.
*
* Comparator functions are used for searching and sorting. If NULL is passed
* as reference to the function, the comparator is disabled.
*
* @param l list to operate
* @param comparator_fun pointer to the actual comparator function
* @return 0 if the attribute was successfully set; -1 otherwise
*
* @see element_comparator()
*/
int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun);
/**
* set a seeker function for list elements.
*
* Seeker functions are used for finding elements. If NULL is passed as reference
* to the function, the seeker is disabled.
*
* @param l list to operate
* @param seeker_fun pointer to the actual seeker function
* @return 0 if the attribute was successfully set; -1 otherwise
*
* @see element_seeker()
*/
int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun);
/**
* require to free element data when list entry is removed (default: don't free).
*
* [ advanced preference ]
*
* By default, when an element is removed from the list, it disappears from
* the list by its actual data is not free()d. With this option, every
* deletion causes element data to be freed.
*
* It is responsability of this function to correctly handle NULL values, if
* NULL elements are inserted into the list.
*
* @param l list to operate
* @param metric_fun pointer to the actual metric function
* @param copy_data 0: do not free element data (default); non-0: do free
* @return 0 if the attribute was successfully set; -1 otherwise
*
* @see element_meter()
* @see list_meter_int8_t()
* @see list_meter_int16_t()
* @see list_meter_int32_t()
* @see list_meter_int64_t()
* @see list_meter_uint8_t()
* @see list_meter_uint16_t()
* @see list_meter_uint32_t()
* @see list_meter_uint64_t()
* @see list_meter_float()
* @see list_meter_double()
* @see list_meter_string()
*/
int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data);
/**
* set the element hash computing function for the list elements.
*
* [ advanced preference ]
*
* An hash can be requested depicting the list status at a given time. An hash
* only depends on the elements and their order. By default, the hash of an
* element is only computed on its reference. With this function, the user can
* set a custom function computing the hash of an element. If such function is
* provided, the list_hash() function automatically computes the list hash using
* the custom function instead of simply referring to element references.
*
* @param l list to operate
* @param hash_computer_fun pointer to the actual hash computing function
* @return 0 if the attribute was successfully set; -1 otherwise
*
* @see element_hash_computer()
*/
int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun);
/**
* set the element serializer function for the list elements.
*
* [ advanced preference ]
*
* Serialize functions are used for dumping the list to some persistent
* storage. The serializer function is called for each element; it is passed
* a reference to the element and a reference to a size_t object. It will
* provide (and return) the buffer with the serialization of the element and
* fill the size_t object with the length of this serialization data.
*
* @param l list to operate
* @param serializer_fun pointer to the actual serializer function
* @return 0 if the attribute was successfully set; -1 otherwise
*
* @see element_serializer()
* @see list_dump_filedescriptor()
* @see list_restore_filedescriptor()
*/
int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun);
/**
* set the element unserializer function for the list elements.
*
* [ advanced preference ]
*
* Unserialize functions are used for restoring the list from some persistent
* storage. The unserializer function is called for each element segment read
* from the storage; it is passed the segment and a reference to an integer.
* It shall allocate and return a buffer compiled with the resumed memory
* representation of the element, and set the integer value to the length of
* this buffer.
*
* @param l list to operate
* @param unserializer_fun pointer to the actual unserializer function
* @return 0 if the attribute was successfully set; -1 otherwise
*
* @see element_unserializer()
* @see list_dump_filedescriptor()
* @see list_restore_filedescriptor()
*/
int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun);
/**
* append data at the end of the list.
*
* This function is useful for adding elements with a FIFO/queue policy.
*
* @param l list to operate
* @param data pointer to user data to append
*
* @return 1 for success. < 0 for failure
*/
int list_append(list_t *restrict l, const void *data);
/**
* insert data in the head of the list.
*
* This function is useful for adding elements with a LIFO/Stack policy.
*
* @param l list to operate
* @param data pointer to user data to append
*
* @return 1 for success. < 0 for failure
*/
int list_prepend(list_t *restrict l, const void *restrict data);
/**
* extract the element in the top of the list.
*
* This function is for using a list with a FIFO/queue policy.
*
* @param l list to operate
* @return reference to user datum, or NULL on errors
*/
void *list_fetch(list_t *restrict l);
/**
* retrieve an element at a given position.
*
* @param l list to operate
* @param pos [0,size-1] position index of the element wanted
* @return reference to user datum, or NULL on errors
*/
void *list_get_at(const list_t *restrict l, unsigned int pos);
/**
* return the maximum element of the list.
*
* @warning Requires a comparator function to be set for the list.
*
* Returns the maximum element with respect to the comparator function output.
*
* @see list_attributes_comparator()
*
* @param l list to operate
* @return the reference to the element, or NULL
*/
void *list_get_max(const list_t *restrict l);
/**
* return the minimum element of the list.
*
* @warning Requires a comparator function to be set for the list.
*
* Returns the minimum element with respect to the comparator function output.
*
* @see list_attributes_comparator()
*
* @param l list to operate
* @return the reference to the element, or NULL
*/
void *list_get_min(const list_t *restrict l);
/**
* retrieve and remove from list an element at a given position.
*
* @param l list to operate
* @param pos [0,size-1] position index of the element wanted
* @return reference to user datum, or NULL on errors
*/
void *list_extract_at(list_t *restrict l, unsigned int pos);
/**
* insert an element at a given position.
*
* @param l list to operate
* @param data reference to data to be inserted
* @param pos [0,size-1] position index to insert the element at
* @return positive value on success. Negative on failure
*/
int list_insert_at(list_t *restrict l, const void *data, unsigned int pos);
/**
* expunge the first found given element from the list.
*
* Inspects the given list looking for the given element; if the element
* is found, it is removed. Only the first occurence is removed.
* If a comparator function was not set, elements are compared by reference.
* Otherwise, the comparator is used to match the element.
*
* @param l list to operate
* @param data reference of the element to search for
* @return 0 on success. Negative value on failure
*
* @see list_attributes_comparator()
* @see list_delete_at()
*/
int list_delete(list_t *restrict l, const void *data);
/**
* expunge an element at a given position from the list.
*
* @param l list to operate
* @param pos [0,size-1] position index of the element to be deleted
* @return 0 on success. Negative value on failure
*/
int list_delete_at(list_t *restrict l, unsigned int pos);
/**
* expunge an array of elements from the list, given their position range.
*
* @param l list to operate
* @param posstart [0,size-1] position index of the first element to be deleted
* @param posend [posstart,size-1] position of the last element to be deleted
* @return the number of elements successfully removed on success, <0 on error
*/
int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend);
/**
* clear all the elements off of the list.
*
* The element datums will not be freed.
*
* @see list_delete_range()
* @see list_size()
*
* @param l list to operate
* @return the number of elements removed on success, <0 on error
*/
int list_clear(list_t *restrict l);
/**
* inspect the number of elements in the list.
*
* @param l list to operate
* @return number of elements currently held by the list
*/
unsigned int list_size(const list_t *restrict l);
/**
* inspect whether the list is empty.
*
* @param l list to operate
* @return 0 iff the list is not empty
*
* @see list_size()
*/
int list_empty(const list_t *restrict l);
/**
* find the position of an element in a list.
*
* @warning Requires a comparator function to be set for the list.
*
* Inspects the given list looking for the given element; if the element
* is found, its position into the list is returned.
* Elements are inspected comparing references if a comparator has not been
* set. Otherwise, the comparator is used to find the element.
*
* @param l list to operate
* @param data reference of the element to search for
* @return position of element in the list, or <0 if not found
*
* @see list_attributes_comparator()
* @see list_get_at()
*/
int list_locate(const list_t *restrict l, const void *data);
/**
* returns an element given an indicator.
*
* @warning Requires a seeker function to be set for the list.
*
* Inspect the given list looking with the seeker if an element matches
* an indicator. If such element is found, the reference to the element
* is returned.
*
* @param l list to operate
* @param indicator indicator data to pass to the seeker along with elements
* @return reference to the element accepted by the seeker, or NULL if none found
*/
void *list_seek(list_t *restrict l, const void *indicator);
/**
* inspect whether some data is member of the list.
*
* @warning Requires a comparator function to be set for the list.
*
* By default, a per-reference comparison is accomplished. That is,
* the data is in list if any element of the list points to the same
* location of data.
* A "semantic" comparison is accomplished, otherwise, if a comparator
* function has been set previously, with list_attributes_comparator();
* in which case, the given data reference is believed to be in list iff
* comparator_fun(elementdata, userdata) == 0 for any element in the list.
*
* @param l list to operate
* @param data reference to the data to search
* @return 0 iff the list does not contain data as an element
*
* @see list_attributes_comparator()
*/
int list_contains(const list_t *restrict l, const void *data);
/**
* concatenate two lists
*
* Concatenates one list with another, and stores the result into a
* user-provided list object, which must be different from both the
* lists to concatenate. Attributes from the original lists are not
* cloned.
* The destination list referred is threated as virgin room: if it
* is an existing list containing elements, memory leaks will happen.
* It is OK to specify the same list twice as source, for "doubling"
* it in the destination.
*
* @param l1 base list
* @param l2 list to append to the base
* @param dest reference to the destination list
* @return 0 for success, -1 for errors
*/
int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest);
/**
* sort list elements.
*
* @warning Requires a comparator function to be set for the list.
*
* Sorts the list in ascending or descending order as specified by the versus
* flag. The algorithm chooses autonomously what algorithm is best suited for
* sorting the list wrt its current status.
*
* @param l list to operate
* @param versus positive: order small to big; negative: order big to small
* @return 0 iff sorting was successful
*
* @see list_attributes_comparator()
*/
int list_sort(list_t *restrict l, int versus);
/**
* start an iteration session.
*
* This function prepares the list to be iterated.
*
* @param l list to operate
* @return 0 if the list cannot be currently iterated. >0 otherwise
*
* @see list_iterator_stop()
*/
int list_iterator_start(list_t *restrict l);
/**
* return the next element in the iteration session.
*
* @param l list to operate
* @return element datum, or NULL on errors
*/
void *list_iterator_next(list_t *restrict l);
/**
* inspect whether more elements are available in the iteration session.
*
* @param l list to operate
* @return 0 iff no more elements are available.
*/
int list_iterator_hasnext(const list_t *restrict l);
/**
* end an iteration session.
*
* @param l list to operate
* @return 0 iff the iteration session cannot be stopped
*/
int list_iterator_stop(list_t *restrict l);
/**
* return the hash of the current status of the list.
*
* @param l list to operate
* @param hash where the resulting hash is put
*
* @return 0 for success; <0 for failure
*/
int list_hash(const list_t *restrict l, list_hash_t *restrict hash);
#ifndef SIMCLIST_NO_DUMPRESTORE
/**
* get meta informations on a list dump on filedescriptor.
*
* [ advanced function ]
*
* Extracts the meta information from a SimCList dump located in a file
* descriptor. The file descriptor must be open and positioned at the
* beginning of the SimCList dump block.
*
* @param fd file descriptor to get metadata from
* @param info reference to a dump metainformation structure to fill
* @return 0 for success; <0 for failure
*
* @see list_dump_filedescriptor()
*/
int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info);
/**
* get meta informations on a list dump on file.
*
* [ advanced function ]
*
* Extracts the meta information from a SimCList dump located in a file.
*
* @param filename filename of the file to fetch from
* @param info reference to a dump metainformation structure to fill
* @return 0 for success; <0 for failure
*
* @see list_dump_filedescriptor()
*/
int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info);
/**
* dump the list into an open, writable file descriptor.
*
* This function "dumps" the list to a persistent storage so it can be
* preserved across process terminations.
* When called, the file descriptor must be open for writing and positioned
* where the serialized data must begin. It writes its serialization of the
* list in a form which is portable across different architectures. Dump can
* be safely performed on stream-only (non seekable) descriptors. The file
* descriptor is not closed at the end of the operations.
*
* To use dump functions, either of these conditions must be satisfied:
* -# a metric function has been specified with list_attributes_copy()
* -# a serializer function has been specified with list_attributes_serializer()
*
* If a metric function has been specified, each element of the list is dumped
* as-is from memory, copying it from its pointer for its length down to the
* file descriptor. This might have impacts on portability of the dump to
* different architectures.
*
* If a serializer function has been specified, its result for each element is
* dumped to the file descriptor.
*
*
* @param l list to operate
* @param fd file descriptor to write to
* @param len location to store the resulting length of the dump (bytes), or NULL
*
* @return 0 if successful; -1 otherwise
*
* @see element_serializer()
* @see list_attributes_copy()
* @see list_attributes_serializer()
*/
int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len);
/**
* dump the list to a file name.
*
* This function creates a filename and dumps the current content of the list
* to it. If the file exists it is overwritten. The number of bytes written to
* the file can be returned in a specified argument.
*
* @param l list to operate
* @param filename filename to write to
* @param len location to store the resulting length of the dump (bytes), or NULL
*
* @return 0 if successful; -1 otherwise
*
* @see list_attributes_copy()
* @see element_serializer()
* @see list_attributes_serializer()
* @see list_dump_filedescriptor()
* @see list_restore_file()
*
* This function stores a representation of the list
*/
int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len);
/**
* restore the list from an open, readable file descriptor to memory.
*
* This function is the "inverse" of list_dump_filedescriptor(). It restores
* the list content from a (open, read-ready) file descriptor to memory. An
* unserializer might be needed to restore elements from the persistent
* representation back into memory-consistent format. List attributes can not
* be restored and must be set manually.
*
* @see list_dump_filedescriptor()
* @see list_attributes_serializer()
* @see list_attributes_unserializer()
*
* @param l list to restore to
* @param fd file descriptor to read from.
* @param len location to store the length of the dump read (bytes), or NULL
* @return 0 if successful; -1 otherwise
*/
int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len);
/**
* restore the list from a file name.
*
* This function restores the content of a list from a file into memory. It is
* the inverse of list_dump_file().
*
* @see element_unserializer()
* @see list_attributes_unserializer()
* @see list_dump_file()
* @see list_restore_filedescriptor()
*
* @param l list to restore to
* @param filename filename to read data from
* @param len location to store the length of the dump read (bytes), or NULL
* @return 0 if successful; -1 otherwise
*/
int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len);
#endif
/* ready-made comparators, meters and hash computers */
/* comparator functions */
/**
* ready-made comparator for int8_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_int8_t(const void *a, const void *b);
/**
* ready-made comparator for int16_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_int16_t(const void *a, const void *b);
/**
* ready-made comparator for int32_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_int32_t(const void *a, const void *b);
/**
* ready-made comparator for int64_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_int64_t(const void *a, const void *b);
/**
* ready-made comparator for uint8_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_uint8_t(const void *a, const void *b);
/**
* ready-made comparator for uint16_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_uint16_t(const void *a, const void *b);
/**
* ready-made comparator for uint32_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_uint32_t(const void *a, const void *b);
/**
* ready-made comparator for uint64_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_uint64_t(const void *a, const void *b);
/**
* ready-made comparator for float elements.
* @see list_attributes_comparator()
*/
int list_comparator_float(const void *a, const void *b);
/**
* ready-made comparator for double elements.
* @see list_attributes_comparator()
*/
int list_comparator_double(const void *a, const void *b);
/**
* ready-made comparator for string elements.
* @see list_attributes_comparator()
*/
int list_comparator_string(const void *a, const void *b);
/* metric functions */
/**
* ready-made metric function for int8_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_int8_t(const void *el);
/**
* ready-made metric function for int16_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_int16_t(const void *el);
/**
* ready-made metric function for int32_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_int32_t(const void *el);
/**
* ready-made metric function for int64_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_int64_t(const void *el);
/**
* ready-made metric function for uint8_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_uint8_t(const void *el);
/**
* ready-made metric function for uint16_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_uint16_t(const void *el);
/**
* ready-made metric function for uint32_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_uint32_t(const void *el);
/**
* ready-made metric function for uint64_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_uint64_t(const void *el);
/**
* ready-made metric function for float elements.
* @see list_attributes_copy()
*/
size_t list_meter_float(const void *el);
/**
* ready-made metric function for double elements.
* @see list_attributes_copy()
*/
size_t list_meter_double(const void *el);
/**
* ready-made metric function for string elements.
* @see list_attributes_copy()
*/
size_t list_meter_string(const void *el);
/* hash functions */
/**
* ready-made hash function for int8_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_int8_t(const void *el);
/**
* ready-made hash function for int16_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_int16_t(const void *el);
/**
* ready-made hash function for int32_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_int32_t(const void *el);
/**
* ready-made hash function for int64_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_int64_t(const void *el);
/**
* ready-made hash function for uint8_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_uint8_t(const void *el);
/**
* ready-made hash function for uint16_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_uint16_t(const void *el);
/**
* ready-made hash function for uint32_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_uint32_t(const void *el);
/**
* ready-made hash function for uint64_t elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_uint64_t(const void *el);
/**
* ready-made hash function for float elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_float(const void *el);
/**
* ready-made hash function for double elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_double(const void *el);
/**
* ready-made hash function for string elements.
* @see list_attributes_hash_computer()
*/
list_hash_t list_hashcomputer_string(const void *el);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,229 @@
/*
* local defines for the table module
*
* Copyright 2000 by Gray Watson.
*
* This file is part of the table package.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose and without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies,
* and that the name of Gray Watson not be used in advertising or
* publicity pertaining to distribution of the document or software
* without specific, written prior permission.
*
* Gray Watson makes no representations about the suitability of the
* software described herein for any purpose. It is provided "as is"
* without express or implied warranty.
*
* The author may be reached via http://256.com/gray/
*
* $Id: table_loc.h,v 1.11 2000/03/09 03:30:42 gray Exp $
*/
#ifndef __TABLE_LOC_H__
#define __TABLE_LOC_H__
#ifndef unix
#define NO_MMAP
#endif
#ifndef BITSPERBYTE
#define BITSPERBYTE 8
#endif
#ifndef BITS
#define BITS(type) (BITSPERBYTE * (int)sizeof(type))
#endif
#define TABLE_MAGIC 0xBADF00D /* very magic magicness */
#define LINEAR_MAGIC 0xAD00D00 /* magic value for linear struct */
#define DEFAULT_SIZE 1024 /* default table size */
#define MAX_ALIGNMENT 128 /* max alignment value */
/*
* Maximum number of splits. This should mean that these routines can
* handle at least 2^128 different values (that's _quite_ a few). And
* then you can always increase the value.
*/
#define MAX_QSORT_SPLITS 128
/*
* Maximum number of entries that must be in list for it to be
* partitioned. If there are fewer elements then just do our
* insertion sort.
*/
#define MAX_QSORT_MANY 8
/*
* Macros.
*/
/* returns 1 when we should grow or shrink the table */
#define SHOULD_TABLE_GROW(tab) ((tab)->ta_entry_n > (tab)->ta_bucket_n * 2)
#define SHOULD_TABLE_SHRINK(tab) ((tab)->ta_entry_n < (tab)->ta_bucket_n / 2)
/*
* void HASH_MIX
*
* DESCRIPTION:
*
* Mix 3 32-bit values reversibly. For every delta with one or two
* bits set, and the deltas of all three high bits or all three low
* bits, whether the original value of a,b,c is almost all zero or is
* uniformly distributed.
*
* If HASH_MIX() is run forward or backward, at least 32 bits in a,b,c
* have at least 1/4 probability of changing. If mix() is run
* forward, every bit of c will change between 1/3 and 2/3 of the
* time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
*
* HASH_MIX() takes 36 machine instructions, but only 18 cycles on a
* superscalar machine (like a Pentium or a Sparc). No faster mixer
* seems to work, that's the result of my brute-force search. There
* were about 2^68 hashes to choose from. I only tested about a
* billion of those.
*/
#define HASH_MIX(a, b, c) \
do { \
a -= b; a -= c; a ^= (c >> 13); \
b -= c; b -= a; b ^= (a << 8); \
c -= a; c -= b; c ^= (b >> 13); \
a -= b; a -= c; a ^= (c >> 12); \
b -= c; b -= a; b ^= (a << 16); \
c -= a; c -= b; c ^= (b >> 5); \
a -= b; a -= c; a ^= (c >> 3); \
b -= c; b -= a; b ^= (a << 10); \
c -= a; c -= b; c ^= (b >> 15); \
} while(0)
#define SET_POINTER(pnt, val) \
do { \
if ((pnt) != NULL) { \
(*(pnt)) = (val); \
} \
} while(0)
/*
* The following macros take care of the mmap case. When we are
* mmaping a table from a disk file, all of the pointers in the table
* structures are replaced with offsets into the file. The following
* macro, for each pointer, adds the starting address of the mmaped
* section onto each pointer/offset turning it back into a legitimate
* pointer.
*/
#ifdef NO_MMAP
#define TABLE_POINTER(table, type, pnt) (pnt)
#else
#define TABLE_POINTER(tab_p, type, pnt) \
((tab_p)->ta_mmap == NULL || (pnt) == NULL ? (pnt) : \
(type)((char *)((tab_p)->ta_mmap) + (long)(pnt)))
#endif
/*
* Macros to get at the key and the data pointers
*/
#define ENTRY_KEY_BUF(entry_p) ((entry_p)->te_key_buf)
#define ENTRY_DATA_BUF(tab_p, entry_p) \
(ENTRY_KEY_BUF(entry_p) + (entry_p)->te_key_size)
/*
* Table structures...
*/
/*
* HACK: this should be equiv as the table_entry_t without the key_buf
* char. We use this with the ENTRY_SIZE() macro above which solves
* the problem with the lack of the [0] GNU hack. We use the
* table_entry_t structure to better map the memory and make things
* faster.
*/
typedef struct table_shell_st {
unsigned int te_key_size; /* size of data */
unsigned int te_data_size; /* size of data */
struct table_shell_st *te_next_p; /* pointer to next in the list */
/* NOTE: this does not have the te_key_buf field here */
} table_shell_t;
/*
* Elements in the bucket linked-lists. The key[1] is the start of
* the key with the rest of the key and all of the data information
* packed in memory directly after the end of this structure.
*
* NOTE: if this structure is changed, the table_shell_t must be
* changed to match.
*/
typedef struct table_entry_st {
unsigned int te_key_size; /* size of data */
unsigned int te_data_size; /* size of data */
struct table_entry_st *te_next_p; /* pointer to next in the list */
unsigned char te_key_buf[1]; /* 1st byte of key buf */
} table_entry_t;
/* external structure for debuggers be able to see void */
typedef table_entry_t table_entry_ext_t;
/* main table structure */
typedef struct table_st {
unsigned int ta_magic; /* magic number */
unsigned int ta_flags; /* table's flags defined in table.h */
unsigned int ta_bucket_n; /* num of buckets, should be 2^X */
unsigned int ta_entry_n; /* num of entries in all buckets */
unsigned int ta_data_align; /* data alignment value */
table_entry_t **ta_buckets; /* array of linked lists */
table_linear_t ta_linear; /* linear tracking */
struct table_st *ta_mmap; /* mmaped table */
unsigned long ta_file_size; /* size of on-disk space */
void *ta_mem_pool; /* pointer to some memory pool */
table_mem_alloc_t ta_alloc_func; /* memory allocation function */
table_mem_resize_t ta_resize_func; /* memory resize function */
table_mem_free_t ta_free_func; /* memory free function */
} table_t;
/* external table structure for debuggers */
typedef table_t table_ext_t;
/* local comparison functions */
typedef int (*compare_t)(const void *element1_p, const void *element2_p,
table_compare_t user_compare,
const table_t *table_p, int *err_bp);
/*
* to map error to string
*/
typedef struct {
int es_error; /* error number */
char *es_string; /* assocaited string */
} error_str_t;
static error_str_t errors[] = {
{ TABLE_ERROR_NONE, "no error" },
{ TABLE_ERROR_PNT, "invalid table pointer" },
{ TABLE_ERROR_ARG_NULL, "buffer argument is null" },
{ TABLE_ERROR_SIZE, "incorrect size argument" },
{ TABLE_ERROR_OVERWRITE, "key exists and no overwrite" },
{ TABLE_ERROR_NOT_FOUND, "key does not exist" },
{ TABLE_ERROR_ALLOC, "error allocating memory" },
{ TABLE_ERROR_LINEAR, "linear access not in progress" },
{ TABLE_ERROR_OPEN, "could not open file" },
{ TABLE_ERROR_SEEK, "could not seek to position in file" },
{ TABLE_ERROR_READ, "could not read from file" },
{ TABLE_ERROR_WRITE, "could not write to file" },
{ TABLE_ERROR_MMAP_NONE, "no mmap support compiled in library" },
{ TABLE_ERROR_MMAP, "could not mmap the file" },
{ TABLE_ERROR_MMAP_OP, "operation not valid on mmap files" },
{ TABLE_ERROR_EMPTY, "table is empty" },
{ TABLE_ERROR_NOT_EMPTY, "table contains data" },
{ TABLE_ERROR_ALIGNMENT, "invalid alignment value" },
{ TABLE_ERROR_COMPARE, "problems with internal comparison" },
{ TABLE_ERROR_FREE, "memory free error" },
{ 0 }
};
#define INVALID_ERROR "invalid error code"
#endif /* ! __TABLE_LOC_H__ */

739
libs/libks/src/ks.c Normal file
View File

@ -0,0 +1,739 @@
/*
* Copyright (c) 2007-2012, Anthony Minessale II
* 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 original author; nor the names of any 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.
*/
/* Use select on windows and poll everywhere else.
Select is the devil. Especially if you are doing a lot of small socket connections.
If your FD number is bigger than 1024 you will silently create memory corruption.
If you have build errors on your platform because you don't have poll find a way to detect it and #define KS_USE_SELECT and #undef KS_USE_POLL
All of this will be upgraded to autoheadache eventually.
*/
/* TBD for win32 figure out how to tell if you have WSAPoll (vista or higher) and use it when available by #defining KS_USE_WSAPOLL (see below) */
#ifdef _MSC_VER
#define FD_SETSIZE 8192
#define KS_USE_SELECT
#else
#define KS_USE_POLL
#endif
#include <ks.h>
#ifndef WIN32
#define closesocket(x) shutdown(x, 2); close(x)
#include <fcntl.h>
#include <errno.h>
#else
#pragma warning (disable:6386)
/* These warnings need to be ignored warning in sdk header */
#include <Ws2tcpip.h>
#include <windows.h>
#ifndef errno
#define errno WSAGetLastError()
#endif
#ifndef EINTR
#define EINTR WSAEINTR
#endif
#pragma warning (default:6386)
#endif
#ifdef KS_USE_POLL
#include <poll.h>
#endif
#ifndef KS_MIN
#define KS_MIN(x,y) ((x) < (y) ? (x) : (y))
#endif
#ifndef KS_MAX
#define KS_MAX(x,y) ((x) > (y) ? (x) : (y))
#endif
#ifndef KS_CLAMP
#define KS_CLAMP(min,max,val) (KS_MIN(max,KS_MAX(val,min)))
#endif
/* Written by Marc Espie, public domain */
#define KS_CTYPE_NUM_CHARS 256
const short _ks_C_toupper_[1 + KS_CTYPE_NUM_CHARS] = {
EOF,
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, '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', 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
};
const short *_ks_toupper_tab_ = _ks_C_toupper_;
KS_DECLARE(int) ks_toupper(int c)
{
if ((unsigned int)c > 255)
return(c);
if (c < -1)
return EOF;
return((_ks_toupper_tab_ + 1)[c]);
}
const short _ks_C_tolower_[1 + KS_CTYPE_NUM_CHARS] = {
EOF,
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, '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', 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
};
const short *_ks_tolower_tab_ = _ks_C_tolower_;
KS_DECLARE(int) ks_tolower(int c)
{
if ((unsigned int)c > 255)
return(c);
if (c < -1)
return EOF;
return((_ks_tolower_tab_ + 1)[c]);
}
KS_DECLARE(const char *)ks_stristr(const char *instr, const char *str)
{
/*
** Rev History: 16/07/97 Greg Thayer Optimized
** 07/04/95 Bob Stout ANSI-fy
** 02/03/94 Fred Cole Original
** 09/01/03 Bob Stout Bug fix (lines 40-41) per Fred Bulback
**
** Hereby donated to public domain.
*/
const char *pptr, *sptr, *start;
if (!str || !instr)
return NULL;
for (start = str; *start; start++) {
/* find start of pattern in string */
for (; ((*start) && (ks_toupper(*start) != ks_toupper(*instr))); start++);
if (!*start)
return NULL;
pptr = instr;
sptr = start;
while (ks_toupper(*sptr) == ks_toupper(*pptr)) {
sptr++;
pptr++;
/* if end of pattern then pattern was found */
if (!*pptr)
return (start);
if (!*sptr)
return NULL;
}
}
return NULL;
}
#ifdef WIN32
#ifndef vsnprintf
#define vsnprintf _vsnprintf
#endif
#endif
int vasprintf(char **ret, const char *format, va_list ap);
KS_DECLARE(int) ks_vasprintf(char **ret, const char *fmt, va_list ap)
{
#if !defined(WIN32) && !defined(__sun)
return vasprintf(ret, fmt, ap);
#else
char *buf;
int len;
size_t buflen;
va_list ap2;
char *tmp = NULL;
#ifdef _MSC_VER
#if _MSC_VER >= 1500
/* hack for incorrect assumption in msvc header files for code analysis */
__analysis_assume(tmp);
#endif
ap2 = ap;
#else
va_copy(ap2, ap);
#endif
len = vsnprintf(tmp, 0, fmt, ap2);
if (len > 0 && (buf = malloc((buflen = (size_t) (len + 1)))) != NULL) {
len = vsnprintf(buf, buflen, fmt, ap);
*ret = buf;
} else {
*ret = NULL;
len = -1;
}
va_end(ap2);
return len;
#endif
}
KS_DECLARE(int) ks_snprintf(char *buffer, size_t count, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = vsnprintf(buffer, count-1, fmt, ap);
if (ret < 0)
buffer[count-1] = '\0';
va_end(ap);
return ret;
}
static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
{
if (file && func && line && level && fmt) {
return;
}
return;
}
static const char *LEVEL_NAMES[] = {
"EMERG",
"ALERT",
"CRIT",
"ERROR",
"WARNING",
"NOTICE",
"INFO",
"DEBUG",
NULL
};
static int ks_log_level = 7;
static const char *cut_path(const char *in)
{
const char *p, *ret = in;
char delims[] = "/\\";
char *i;
for (i = delims; *i; i++) {
p = in;
while ((p = strchr(p, *i)) != 0) {
ret = ++p;
}
}
return ret;
}
static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
{
const char *fp;
char *data;
va_list ap;
int ret;
if (level < 0 || level > 7) {
level = 7;
}
if (level > ks_log_level) {
return;
}
fp = cut_path(file);
va_start(ap, fmt);
ret = ks_vasprintf(&data, fmt, ap);
if (ret != -1) {
fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], fp, line, func, data);
free(data);
}
va_end(ap);
}
ks_logger_t ks_log = null_logger;
KS_DECLARE(void) ks_global_set_logger(ks_logger_t logger)
{
if (logger) {
ks_log = logger;
} else {
ks_log = null_logger;
}
}
KS_DECLARE(void) ks_global_set_default_logger(int level)
{
if (level < 0 || level > 7) {
level = 7;
}
ks_log = default_logger;
ks_log_level = level;
}
KS_DECLARE(size_t) ks_url_encode(const char *url, char *buf, size_t len)
{
const char *p;
size_t x = 0;
const char urlunsafe[] = "\r\n \"#%&+:;<=>?@[\\]^`{|}";
const char hex[] = "0123456789ABCDEF";
if (!buf) {
return 0;
}
if (!url) {
return 0;
}
len--;
for (p = url; *p; p++) {
if (x >= len) {
break;
}
if (*p < ' ' || *p > '~' || strchr(urlunsafe, *p)) {
if ((x + 3) >= len) {
break;
}
buf[x++] = '%';
buf[x++] = hex[*p >> 4];
buf[x++] = hex[*p & 0x0f];
} else {
buf[x++] = *p;
}
}
buf[x] = '\0';
return x;
}
KS_DECLARE(char *)ks_url_decode(char *s)
{
char *o;
unsigned int tmp;
for (o = s; *s; s++, o++) {
if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
*o = (char) tmp;
s += 2;
} else {
*o = *s;
}
}
*o = '\0';
return s;
}
static int ks_socket_reuseaddr(ks_socket_t socket)
{
#ifdef WIN32
BOOL reuse_addr = TRUE;
return setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse_addr, sizeof(reuse_addr));
#else
int reuse_addr = 1;
return setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));
#endif
}
struct thread_handler {
ks_listen_callback_t callback;
ks_socket_t server_sock;
ks_socket_t client_sock;
struct sockaddr_in addr;
};
static void *client_thread(ks_thread_t *me, void *obj)
{
struct thread_handler *handler = (struct thread_handler *) obj;
handler->callback(handler->server_sock, handler->client_sock, &handler->addr);
free(handler);
return NULL;
}
KS_DECLARE(ks_status_t) ks_listen(const char *host, ks_port_t port, ks_listen_callback_t callback)
{
ks_socket_t server_sock = KS_SOCK_INVALID;
struct sockaddr_in addr;
ks_status_t status = KS_SUCCESS;
if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
return KS_FAIL;
}
ks_socket_reuseaddr(server_sock);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
if (bind(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
status = KS_FAIL;
goto end;
}
if (listen(server_sock, 10000) < 0) {
status = KS_FAIL;
goto end;
}
for (;;) {
int client_sock;
struct sockaddr_in echoClntAddr;
#ifdef WIN32
int clntLen;
#else
unsigned int clntLen;
#endif
clntLen = sizeof(echoClntAddr);
if ((client_sock = accept(server_sock, (struct sockaddr *) &echoClntAddr, &clntLen)) == KS_SOCK_INVALID) {
status = KS_FAIL;
goto end;
}
callback(server_sock, client_sock, &echoClntAddr);
}
end:
if (server_sock != KS_SOCK_INVALID) {
closesocket(server_sock);
server_sock = KS_SOCK_INVALID;
}
return status;
}
KS_DECLARE(ks_status_t) ks_listen_threaded(const char *host, ks_port_t port, ks_listen_callback_t callback, int max)
{
ks_socket_t server_sock = KS_SOCK_INVALID;
struct sockaddr_in addr;
ks_status_t status = KS_SUCCESS;
struct thread_handler *handler = NULL;
if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
return KS_FAIL;
}
ks_socket_reuseaddr(server_sock);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
if (bind(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
status = KS_FAIL;
goto end;
}
if (listen(server_sock, max) < 0) {
status = KS_FAIL;
goto end;
}
for (;;) {
int client_sock;
struct sockaddr_in echoClntAddr;
#ifdef WIN32
int clntLen;
#else
unsigned int clntLen;
#endif
clntLen = sizeof(echoClntAddr);
if ((client_sock = accept(server_sock, (struct sockaddr *) &echoClntAddr, &clntLen)) == KS_SOCK_INVALID) {
status = KS_FAIL;
goto end;
}
handler = malloc(sizeof(*handler));
ks_assert(handler);
memset(handler, 0, sizeof(*handler));
handler->callback = callback;
handler->server_sock = server_sock;
handler->client_sock = client_sock;
handler->addr = echoClntAddr;
ks_thread_create_detached(client_thread, handler);
}
end:
if (server_sock != KS_SOCK_INVALID) {
closesocket(server_sock);
server_sock = KS_SOCK_INVALID;
}
return status;
}
/* USE WSAPoll on vista or higher */
#ifdef KS_USE_WSAPOLL
KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags)
{
}
#endif
#ifdef KS_USE_SELECT
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 6262 ) /* warning C6262: Function uses '98348' bytes of stack: exceeds /analyze:stacksize'16384'. Consider moving some data to heap */
#endif
KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags)
{
int s = 0, r = 0;
fd_set rfds;
fd_set wfds;
fd_set efds;
struct timeval tv;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&efds);
#ifndef WIN32
/* Wouldn't you rather know?? */
assert(sock <= FD_SETSIZE);
#endif
if ((flags & KS_POLL_READ)) {
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4127 )
FD_SET(sock, &rfds);
#pragma warning( pop )
#else
FD_SET(sock, &rfds);
#endif
}
if ((flags & KS_POLL_WRITE)) {
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4127 )
FD_SET(sock, &wfds);
#pragma warning( pop )
#else
FD_SET(sock, &wfds);
#endif
}
if ((flags & KS_POLL_ERROR)) {
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4127 )
FD_SET(sock, &efds);
#pragma warning( pop )
#else
FD_SET(sock, &efds);
#endif
}
tv.tv_sec = ms / 1000;
tv.tv_usec = (ms % 1000) * ms;
s = select(sock + 1, (flags & KS_POLL_READ) ? &rfds : NULL, (flags & KS_POLL_WRITE) ? &wfds : NULL, (flags & KS_POLL_ERROR) ? &efds : NULL, &tv);
if (s < 0) {
r = s;
} else if (s > 0) {
if ((flags & KS_POLL_READ) && FD_ISSET(sock, &rfds)) {
r |= KS_POLL_READ;
}
if ((flags & KS_POLL_WRITE) && FD_ISSET(sock, &wfds)) {
r |= KS_POLL_WRITE;
}
if ((flags & KS_POLL_ERROR) && FD_ISSET(sock, &efds)) {
r |= KS_POLL_ERROR;
}
}
return r;
}
#ifdef WIN32
#pragma warning( pop )
#endif
#endif
#ifdef KS_USE_POLL
KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags)
{
struct pollfd pfds[2] = { { 0 } };
int s = 0, r = 0;
pfds[0].fd = sock;
if ((flags & KS_POLL_READ)) {
pfds[0].events |= POLLIN;
}
if ((flags & KS_POLL_WRITE)) {
pfds[0].events |= POLLOUT;
}
if ((flags & KS_POLL_ERROR)) {
pfds[0].events |= POLLERR;
}
s = poll(pfds, 1, ms);
if (s < 0) {
r = s;
} else if (s > 0) {
if ((pfds[0].revents & POLLIN)) {
r |= KS_POLL_READ;
}
if ((pfds[0].revents & POLLOUT)) {
r |= KS_POLL_WRITE;
}
if ((pfds[0].revents & POLLERR)) {
r |= KS_POLL_ERROR;
}
}
return r;
}
#endif
KS_DECLARE(unsigned int) ks_separate_string_string(char *buf, const char *delim, char **array, unsigned int arraylen)
{
unsigned int count = 0;
char *d;
size_t dlen = strlen(delim);
array[count++] = buf;
while (count < arraylen && array[count - 1]) {
if ((d = strstr(array[count - 1], delim))) {
*d = '\0';
d += dlen;
array[count++] = d;
} else
break;
}
return count;
}

353
libs/libks/src/ks_buffer.c Normal file
View File

@ -0,0 +1,353 @@
/*
* Copyright (c) 2010-2012, Anthony Minessale II
* 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 original author; nor the names of any 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.
*/
#include "ks_buffer.h"
static unsigned buffer_id = 0;
struct ks_buffer {
unsigned char *data;
unsigned char *head;
ks_size_t used;
ks_size_t actually_used;
ks_size_t datalen;
ks_size_t max_len;
ks_size_t blocksize;
unsigned id;
int loops;
};
KS_DECLARE(ks_status_t) ks_buffer_create(ks_buffer_t **buffer, ks_size_t blocksize, ks_size_t start_len, ks_size_t max_len)
{
ks_buffer_t *new_buffer;
new_buffer = malloc(sizeof(*new_buffer));
if (new_buffer) {
memset(new_buffer, 0, sizeof(*new_buffer));
if (start_len) {
new_buffer->data = malloc(start_len);
if (!new_buffer->data) {
free(new_buffer);
return KS_FAIL;
}
memset(new_buffer->data, 0, start_len);
}
new_buffer->max_len = max_len;
new_buffer->datalen = start_len;
new_buffer->id = buffer_id++;
new_buffer->blocksize = blocksize;
new_buffer->head = new_buffer->data;
*buffer = new_buffer;
return KS_SUCCESS;
}
return KS_FAIL;
}
KS_DECLARE(ks_size_t) ks_buffer_len(ks_buffer_t *buffer)
{
ks_assert(buffer != NULL);
return buffer->datalen;
}
KS_DECLARE(ks_size_t) ks_buffer_freespace(ks_buffer_t *buffer)
{
ks_assert(buffer != NULL);
if (buffer->max_len) {
return (ks_size_t) (buffer->max_len - buffer->used);
}
return 1000000;
}
KS_DECLARE(ks_size_t) ks_buffer_inuse(ks_buffer_t *buffer)
{
ks_assert(buffer != NULL);
return buffer->used;
}
KS_DECLARE(ks_size_t) ks_buffer_seek(ks_buffer_t *buffer, ks_size_t datalen)
{
ks_size_t reading = 0;
ks_assert(buffer != NULL);
if (buffer->used < 1) {
buffer->used = 0;
return 0;
} else if (buffer->used >= datalen) {
reading = datalen;
} else {
reading = buffer->used;
}
buffer->used = buffer->actually_used - reading;
buffer->head = buffer->data + reading;
return reading;
}
KS_DECLARE(ks_size_t) ks_buffer_toss(ks_buffer_t *buffer, ks_size_t datalen)
{
ks_size_t reading = 0;
ks_assert(buffer != NULL);
if (buffer->used < 1) {
buffer->used = 0;
return 0;
} else if (buffer->used >= datalen) {
reading = datalen;
} else {
reading = buffer->used;
}
buffer->used -= reading;
buffer->head += reading;
return buffer->used;
}
KS_DECLARE(void) ks_buffer_set_loops(ks_buffer_t *buffer, int loops)
{
buffer->loops = loops;
}
KS_DECLARE(ks_size_t) ks_buffer_read_loop(ks_buffer_t *buffer, void *data, ks_size_t datalen)
{
ks_size_t len;
if ((len = ks_buffer_read(buffer, data, datalen)) < datalen) {
if (buffer->loops == 0) {
return len;
}
buffer->head = buffer->data;
buffer->used = buffer->actually_used;
len = ks_buffer_read(buffer, (char*)data + len, datalen - len);
buffer->loops--;
}
return len;
}
KS_DECLARE(ks_size_t) ks_buffer_read(ks_buffer_t *buffer, void *data, ks_size_t datalen)
{
ks_size_t reading = 0;
ks_assert(buffer != NULL);
ks_assert(data != NULL);
if (buffer->used < 1) {
buffer->used = 0;
return 0;
} else if (buffer->used >= datalen) {
reading = datalen;
} else {
reading = buffer->used;
}
memcpy(data, buffer->head, reading);
buffer->used -= reading;
buffer->head += reading;
/* if (buffer->id == 4) printf("%u o %d = %d\n", buffer->id, (unsigned)reading, (unsigned)buffer->used); */
return reading;
}
KS_DECLARE(ks_size_t) ks_buffer_packet_count(ks_buffer_t *buffer)
{
char *pe, *p, *e, *head = (char *) buffer->head;
ks_size_t x = 0;
ks_assert(buffer != NULL);
e = (head + buffer->used);
for (p = head; p && *p && p < e; p++) {
if (*p == '\n') {
pe = p+1;
if (*pe == '\r') pe++;
if (pe <= e && *pe == '\n') {
p = pe++;
x++;
}
}
}
return x;
}
KS_DECLARE(ks_size_t) ks_buffer_read_packet(ks_buffer_t *buffer, void *data, ks_size_t maxlen)
{
char *pe, *p, *e, *head = (char *) buffer->head;
ks_size_t datalen = 0;
ks_assert(buffer != NULL);
ks_assert(data != NULL);
e = (head + buffer->used);
for (p = head; p && *p && p < e; p++) {
if (*p == '\n') {
pe = p+1;
if (*pe == '\r') pe++;
if (pe <= e && *pe == '\n') {
pe++;
datalen = pe - head;
if (datalen > maxlen) {
datalen = maxlen;
}
break;
}
}
}
return ks_buffer_read(buffer, data, datalen);
}
KS_DECLARE(ks_size_t) ks_buffer_write(ks_buffer_t *buffer, const void *data, ks_size_t datalen)
{
ks_size_t freespace, actual_freespace;
ks_assert(buffer != NULL);
ks_assert(data != NULL);
ks_assert(buffer->data != NULL);
if (!datalen) {
return buffer->used;
}
actual_freespace = buffer->datalen - buffer->actually_used;
if (actual_freespace < datalen && (!buffer->max_len || (buffer->used + datalen <= buffer->max_len))) {
memmove(buffer->data, buffer->head, buffer->used);
buffer->head = buffer->data;
buffer->actually_used = buffer->used;
}
freespace = buffer->datalen - buffer->used;
/*
if (buffer->data != buffer->head) {
memmove(buffer->data, buffer->head, buffer->used);
buffer->head = buffer->data;
}
*/
if (freespace < datalen) {
ks_size_t new_size, new_block_size;
void *data1;
new_size = buffer->datalen + datalen;
new_block_size = buffer->datalen + buffer->blocksize;
if (new_block_size > new_size) {
new_size = new_block_size;
}
buffer->head = buffer->data;
data1 = realloc(buffer->data, new_size);
if (!data1) {
return 0;
}
buffer->data = data1;
buffer->head = buffer->data;
buffer->datalen = new_size;
}
freespace = buffer->datalen - buffer->used;
if (freespace < datalen) {
return 0;
} else {
memcpy(buffer->head + buffer->used, data, datalen);
buffer->used += datalen;
buffer->actually_used += datalen;
}
/* if (buffer->id == 4) printf("%u i %d = %d\n", buffer->id, (unsigned)datalen, (unsigned)buffer->used); */
return buffer->used;
}
KS_DECLARE(void) ks_buffer_zero(ks_buffer_t *buffer)
{
ks_assert(buffer != NULL);
ks_assert(buffer->data != NULL);
buffer->used = 0;
buffer->actually_used = 0;
buffer->head = buffer->data;
}
KS_DECLARE(ks_size_t) ks_buffer_zwrite(ks_buffer_t *buffer, const void *data, ks_size_t datalen)
{
ks_size_t w;
if (!(w = ks_buffer_write(buffer, data, datalen))) {
ks_buffer_zero(buffer);
return ks_buffer_write(buffer, data, datalen);
}
return w;
}
KS_DECLARE(void) ks_buffer_destroy(ks_buffer_t **buffer)
{
if (*buffer) {
free((*buffer)->data);
free(*buffer);
}
*buffer = NULL;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/

256
libs/libks/src/ks_config.c Normal file
View File

@ -0,0 +1,256 @@
/*
* Copyright (c) 2007-2012, Anthony Minessale II
* 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 original author; nor the names of any 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.
*/
#include "ks.h"
#include "ks_config.h"
KS_DECLARE(int) ks_config_open_file(ks_config_t *cfg, const char *file_path)
{
FILE *f;
const char *path = NULL;
char path_buf[1024];
if (file_path[0] == '/') {
path = file_path;
} else {
ks_snprintf(path_buf, sizeof(path_buf), "%s%s%s", KS_CONFIG_DIR, KS_PATH_SEPARATOR, file_path);
path = path_buf;
}
if (!path) {
return 0;
}
memset(cfg, 0, sizeof(*cfg));
cfg->lockto = -1;
ks_log(KS_LOG_DEBUG, "Configuration file is %s.\n", path);
f = fopen(path, "r");
if (!f) {
if (file_path[0] != '/') {
int last = -1;
char *var, *val;
ks_snprintf(path_buf, sizeof(path_buf), "%s%sopenks.conf", KS_CONFIG_DIR, KS_PATH_SEPARATOR);
path = path_buf;
if ((f = fopen(path, "r")) == 0) {
return 0;
}
cfg->file = f;
ks_set_string(cfg->path, path);
while (ks_config_next_pair(cfg, &var, &val)) {
if ((cfg->sectno != last) && !strcmp(cfg->section, file_path)) {
cfg->lockto = cfg->sectno;
return 1;
}
}
ks_config_close_file(cfg);
memset(cfg, 0, sizeof(*cfg));
return 0;
}
return 0;
} else {
cfg->file = f;
ks_set_string(cfg->path, path);
return 1;
}
}
KS_DECLARE(void) ks_config_close_file(ks_config_t *cfg)
{
if (cfg->file) {
fclose(cfg->file);
}
memset(cfg, 0, sizeof(*cfg));
}
KS_DECLARE(int) ks_config_next_pair(ks_config_t *cfg, char **var, char **val)
{
int ret = 0;
char *p, *end;
*var = *val = NULL;
if (!cfg || !cfg->file) {
return 0;
}
for (;;) {
cfg->lineno++;
if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) {
ret = 0;
break;
}
*var = cfg->buf;
if (**var == '[' && (end = strchr(*var, ']')) != 0) {
*end = '\0';
(*var)++;
if (**var == '+') {
(*var)++;
ks_copy_string(cfg->section, *var, sizeof(cfg->section));
cfg->sectno++;
if (cfg->lockto > -1 && cfg->sectno != cfg->lockto) {
break;
}
cfg->catno = 0;
cfg->lineno = 0;
*var = (char *) "";
*val = (char *) "";
return 1;
} else {
ks_copy_string(cfg->category, *var, sizeof(cfg->category));
cfg->catno++;
}
continue;
}
if (**var == '#' || **var == ';' || **var == '\n' || **var == '\r') {
continue;
}
if (!strncmp(*var, "__END__", 7)) {
break;
}
if ((end = strchr(*var, ';')) && *(end+1) == *end) {
*end = '\0';
end--;
} else if ((end = strchr(*var, '\n')) != 0) {
if (*(end - 1) == '\r') {
end--;
}
*end = '\0';
}
p = *var;
while ((*p == ' ' || *p == '\t') && p != end) {
*p = '\0';
p++;
}
*var = p;
if ((*val = strchr(*var, '=')) == 0) {
ret = -1;
/* log_printf(0, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno); */
continue;
} else {
p = *val - 1;
*(*val) = '\0';
(*val)++;
if (*(*val) == '>') {
*(*val) = '\0';
(*val)++;
}
while ((*p == ' ' || *p == '\t') && p != *var) {
*p = '\0';
p--;
}
p = *val;
while ((*p == ' ' || *p == '\t') && p != end) {
*p = '\0';
p++;
}
*val = p;
ret = 1;
break;
}
}
return ret;
}
KS_DECLARE(int) ks_config_get_cas_bits(char *strvalue, unsigned char *outbits)
{
char cas_bits[5];
unsigned char bit = 0x8;
char *double_colon = strchr(strvalue, ':');
int x = 0;
if (!double_colon) {
ks_log(KS_LOG_ERROR, "No CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", double_colon);
return -1;
}
double_colon++;
*outbits = 0;
cas_bits[4] = 0;
if (sscanf(double_colon, "%c%c%c%c", &cas_bits[0], &cas_bits[1], &cas_bits[2], &cas_bits[3]) != 4) {
ks_log(KS_LOG_ERROR, "Invalid CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", double_colon);
return -1;
}
ks_log(KS_LOG_DEBUG, "CAS bits specification found: %s\n", cas_bits);
for (; cas_bits[x]; x++) {
if ('1' == cas_bits[x]) {
*outbits |= bit;
} else if ('0' != cas_bits[x]) {
ks_log(KS_LOG_ERROR, "Invalid CAS pattern specified: %s, just 0 or 1 allowed for each bit\n");
return -1;
}
bit >>= 1;
}
return 0;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/

529
libs/libks/src/ks_json.c Normal file
View File

@ -0,0 +1,529 @@
/*
Copyright (c) 2009 Dave Gamble
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.
*/
/* cJSON */
/* JSON parser in C. */
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
#include "ks_json.h"
#include "ks.h"
static const char *ep;
KS_DECLARE(const char *)cJSON_GetErrorPtr() {return ep;}
static int cJSON_strcasecmp(const char *s1,const char *s2)
{
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
}
static void *glue_malloc(size_t theSize)
{
return(malloc(theSize));
}
static void glue_free(void *thePtr)
{
free(thePtr);
}
static void *(*cJSON_malloc)(size_t sz) = glue_malloc;
static void (*cJSON_free)(void *ptr) = glue_free;
static char* cJSON_strdup(const char* str)
{
size_t len;
char* copy;
const char *s = str ? str : "";
len = strlen(s) + 1;
if (!(copy = (char*)cJSON_malloc(len))) return 0;
memcpy(copy,s,len);
return copy;
}
KS_DECLARE(void)cJSON_InitHooks(cJSON_Hooks* hooks)
{
if (!hooks) { /* Reset hooks */
cJSON_malloc = malloc;
cJSON_free = free;
return;
}
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
}
/* Internal constructor. */
static cJSON *cJSON_New_Item()
{
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
if (node) memset(node,0,sizeof(cJSON));
return node;
}
/* Delete a cJSON structure. */
KS_DECLARE(void)cJSON_Delete(cJSON *c)
{
cJSON *next;
while (c)
{
next=c->next;
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
if (c->string) cJSON_free(c->string);
cJSON_free(c);
c=next;
}
}
/* Parse the input text to generate a number, and populate the result into item. */
static const char *parse_number(cJSON *item,const char *num)
{
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
/* Could use sscanf for this? */
if (*num=='-') sign=-1,num++; /* Has sign? */
if (*num=='0') num++; /* is zero */
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
if (*num=='e' || *num=='E') /* Exponent? */
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
}
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
item->valuedouble=n;
item->valueint=(int)n;
item->type=cJSON_Number;
return num;
}
/* Render the number nicely from the given item into a string. */
static char *print_number(cJSON *item)
{
char *str;
double d=item->valuedouble;
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
{
str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
if (str) sprintf(str,"%d",item->valueint);
}
else
{
str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
if (str)
{
if (fabs(floor(d)-d)<=DBL_EPSILON) sprintf(str,"%.0f",d);
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
else sprintf(str,"%f",d);
}
}
return str;
}
/* Parse the input text into an unescaped cstring, and populate item. */
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
static const char *parse_string(cJSON *item,const char *str)
{
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
if (*str!='\"') {ep=str;return 0;} /* not a string! */
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
if (!out) return 0;
ptr=str+1;ptr2=out;
while (*ptr!='\"' && *ptr)
{
if (*ptr!='\\') *ptr2++=*ptr++;
else
{
ptr++;
switch (*ptr)
{
case 'b': *ptr2++='\b'; break;
case 'f': *ptr2++='\f'; break;
case 'n': *ptr2++='\n'; break;
case 'r': *ptr2++='\r'; break;
case 't': *ptr2++='\t'; break;
case 'u': /* transcode utf16 to utf8. */
if (sscanf(ptr+1,"%4x",&uc) < 1) break;
ptr+=4; /* get the unicode char. */
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; // check for invalid.
if (uc>=0xD800 && uc<=0xDBFF) // UTF16 surrogate pairs.
{
if (ptr[1]!='\\' || ptr[2]!='u') break; // missing second-half of surrogate.
if (sscanf(ptr+3,"%4x",&uc2) < 1) break;
ptr+=6;
if (uc2<0xDC00 || uc2>0xDFFF) break; // invalid second-half of surrogate.
uc=0x10000 | ((uc&0x3FF)<<10) | (uc2&0x3FF);
}
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
switch (len) {
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 1: *--ptr2 =(char)(uc | firstByteMark[len]);
}
ptr2+=len;
break;
default: *ptr2++=*ptr; break;
}
ptr++;
}
}
*ptr2=0;
if (*ptr=='\"') ptr++;
item->valuestring=out;
item->type=cJSON_String;
return ptr;
}
/* Render the cstring provided to an escaped version that can be printed. */
static char *print_string_ptr(const char *str)
{
const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
if (!str) return cJSON_strdup("");
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
out=(char*)cJSON_malloc(len+3);
if (!out) return 0;
ptr2=out;ptr=str;
*ptr2++='\"';
while (*ptr)
{
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
else
{
*ptr2++='\\';
switch (token=*ptr++)
{
case '\\': *ptr2++='\\'; break;
case '\"': *ptr2++='\"'; break;
case '\b': *ptr2++='b'; break;
case '\f': *ptr2++='f'; break;
case '\n': *ptr2++='n'; break;
case '\r': *ptr2++='r'; break;
case '\t': *ptr2++='t'; break;
default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
}
}
}
*ptr2++='\"';*ptr2++=0;
return out;
}
/* Invote print_string_ptr (which is useful) on an item. */
static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
/* Predeclare these prototypes. */
static const char *parse_value(cJSON *item,const char *value);
static char *print_value(cJSON *item,int depth,int fmt);
static const char *parse_array(cJSON *item,const char *value);
static char *print_array(cJSON *item,int depth,int fmt);
static const char *parse_object(cJSON *item,const char *value);
static char *print_object(cJSON *item,int depth,int fmt);
/* Utility to jump whitespace and cr/lf */
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
/* Parse an object - create a new root, and populate. */
KS_DECLARE(cJSON *)cJSON_Parse(const char *value)
{
cJSON *c=cJSON_New_Item();
ep=0;
if (!c) return 0; /* memory fail */
if (!parse_value(c,skip(value))) {cJSON_Delete(c);return 0;}
return c;
}
/* Render a cJSON item/entity/structure to text. */
KS_DECLARE(char *) cJSON_Print(cJSON *item) {return print_value(item,0,1);}
KS_DECLARE(char *) cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
/* Parser core - when encountering text, process appropriately. */
static const char *parse_value(cJSON *item,const char *value)
{
if (!value) return 0; /* Fail on null. */
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
if (*value=='\"') { return parse_string(item,value); }
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
if (*value=='[') { return parse_array(item,value); }
if (*value=='{') { return parse_object(item,value); }
ep=value;return 0; /* failure. */
}
/* Render a value to text. */
static char *print_value(cJSON *item,int depth,int fmt)
{
char *out=0;
if (!item) return 0;
switch ((item->type)&255)
{
case cJSON_NULL: out=cJSON_strdup("null"); break;
case cJSON_False: out=cJSON_strdup("false");break;
case cJSON_True: out=cJSON_strdup("true"); break;
case cJSON_Number: out=print_number(item);break;
case cJSON_String: out=print_string(item);break;
case cJSON_Array: out=print_array(item,depth,fmt);break;
case cJSON_Object: out=print_object(item,depth,fmt);break;
}
return out;
}
/* Build an array from input text. */
static const char *parse_array(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='[') {ep=value;return 0;} /* not an array! */
item->type=cJSON_Array;
value=skip(value+1);
if (*value==']') return value+1; /* empty array. */
item->child=child=cJSON_New_Item();
if (!item->child) return 0; /* memory fail */
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
if (!value) return 0;
while (*value==',')
{
cJSON *new_item;
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_value(child,skip(value+1)));
if (!value) return 0; /* memory fail */
}
if (*value==']') return value+1; /* end of array */
ep=value;return 0; /* malformed. */
}
/* Render an array to text */
static char *print_array(cJSON *item,int depth,int fmt)
{
char **entries;
char *out=0,*ptr,*ret;int len=5;
cJSON *child=item->child;
int numentries=0,i=0,fail=0;
/* How many entries in the array? */
while (child) numentries++,child=child->next;
/* Allocate an array to hold the values for each */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!entries) return 0;
memset(entries,0,numentries*sizeof(char*));
/* Retrieve all the results: */
child=item->child;
while (child && !fail)
{
ret=print_value(child,depth+1,fmt);
entries[i++]=ret;
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
child=child->next;
}
/* If we didn't fail, try to malloc the output string */
if (!fail) out=(char*)cJSON_malloc(len);
/* If that fails, we fail. */
if (!out) fail=1;
/* Handle failure. */
if (fail)
{
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
cJSON_free(entries);
return 0;
}
/* Compose the output array. */
*out='[';
ptr=out+1;*ptr=0;
for (i=0;i<numentries;i++)
{
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
cJSON_free(entries[i]);
}
cJSON_free(entries);
*ptr++=']';*ptr++=0;
return out;
}
/* Build an object from the text. */
static const char *parse_object(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='{') {ep=value;return 0;} /* not an object! */
item->type=cJSON_Object;
value=skip(value+1);
if (*value=='}') return value+1; /* empty array. */
item->child=child=cJSON_New_Item();
if (!item->child) return 0;
value=skip(parse_string(child,skip(value)));
if (!value) return 0;
child->string=child->valuestring;child->valuestring=0;
if (*value!=':') {ep=value;return 0;} /* fail! */
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
if (!value) return 0;
while (*value==',')
{
cJSON *new_item;
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_string(child,skip(value+1)));
if (!value) return 0;
child->string=child->valuestring;child->valuestring=0;
if (*value!=':') {ep=value;return 0;} /* fail! */
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
if (!value) return 0;
}
if (*value=='}') return value+1; /* end of array */
ep=value;return 0; /* malformed. */
}
/* Render an object to text. */
static char *print_object(cJSON *item,int depth,int fmt)
{
char **entries=0,**names=0;
char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
cJSON *child=item->child;
int numentries=0,fail=0;
/* Count the number of entries. */
while (child) numentries++,child=child->next;
/* Allocate space for the names and the objects */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!entries) return 0;
names=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!names) {cJSON_free(entries);return 0;}
memset(entries,0,sizeof(char*)*numentries);
memset(names,0,sizeof(char*)*numentries);
/* Collect all the results into our arrays: */
child=item->child;depth++;if (fmt) len+=depth;
while (child)
{
names[i]=str=print_string_ptr(child->string);
entries[i++]=ret=print_value(child,depth,fmt);
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
child=child->next;
}
/* Try to allocate the output string */
if (!fail) out=(char*)cJSON_malloc(len);
if (!out) fail=1;
/* Handle failure */
if (fail)
{
for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
cJSON_free(names);cJSON_free(entries);
return 0;
}
/* Compose the output: */
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
for (i=0;i<numentries;i++)
{
if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
strcpy(ptr,names[i]);ptr+=strlen(names[i]);
*ptr++=':';if (fmt) *ptr++='\t';
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-1) *ptr++=',';
if (fmt) *ptr++='\n';*ptr=0;
cJSON_free(names[i]);cJSON_free(entries[i]);
}
cJSON_free(names);cJSON_free(entries);
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
*ptr++='}';*ptr++=0;
return out;
}
/* Get Array size/item / object item. */
KS_DECLARE(int) cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
KS_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
KS_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
/* Utility for array list handling. */
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
/* Utility for handling references. */
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
/* Add item to array/object. */
KS_DECLARE(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
KS_DECLARE(void) cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
KS_DECLARE(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
KS_DECLARE(void) cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
KS_DECLARE(cJSON *)cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
KS_DECLARE(void) cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
KS_DECLARE(cJSON *)cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
KS_DECLARE(void) cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
/* Replace array/object items with new ones. */
KS_DECLARE(void) cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
KS_DECLARE(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
/* Create basic types: */
KS_DECLARE(cJSON *)cJSON_CreateNull() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
KS_DECLARE(cJSON *)cJSON_CreateTrue() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
KS_DECLARE(cJSON *)cJSON_CreateFalse() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
KS_DECLARE(cJSON *)cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
KS_DECLARE(cJSON *)cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
KS_DECLARE(cJSON *)cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
KS_DECLARE(cJSON *)cJSON_CreateArray() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
KS_DECLARE(cJSON *)cJSON_CreateObject() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
/* Create Arrays: */
KS_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
KS_DECLARE(cJSON *)cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
KS_DECLARE(cJSON *)cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
KS_DECLARE(cJSON *)cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}

View File

@ -0,0 +1,239 @@
/*
* Cross Platform Thread/Mutex abstraction
* Copyright(C) 2007 Michael Jerris
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so.
*
* This work is provided under this license on an "as is" basis, without warranty of any kind,
* either expressed or implied, including, without limitation, warranties that the covered code
* is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire
* risk as to the quality and performance of the covered code is with you. Should any covered
* code prove defective in any respect, you (not the initial developer or any other contributor)
* assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty
* constitutes an essential part of this license. No use of any covered code is authorized hereunder
* except under this disclaimer.
*
*/
#ifdef WIN32
/* required for TryEnterCriticalSection definition. Must be defined before windows.h include */
#define _WIN32_WINNT 0x0400
#endif
#include "ks.h"
#include "ks_threadmutex.h"
#ifdef WIN32
#include <process.h>
#define KS_THREAD_CALLING_CONVENTION __stdcall
struct ks_mutex {
CRITICAL_SECTION mutex;
};
#else
#include <pthread.h>
#define KS_THREAD_CALLING_CONVENTION
struct ks_mutex {
pthread_mutex_t mutex;
};
#endif
struct ks_thread {
#ifdef WIN32
void *handle;
#else
pthread_t handle;
#endif
void *private_data;
ks_thread_function_t function;
size_t stack_size;
#ifndef WIN32
pthread_attr_t attribute;
#endif
};
size_t thread_default_stacksize = 240 * 1024;
void ks_thread_override_default_stacksize(size_t size)
{
thread_default_stacksize = size;
}
static void * KS_THREAD_CALLING_CONVENTION thread_launch(void *args)
{
void *exit_val;
ks_thread_t *thread = (ks_thread_t *)args;
exit_val = thread->function(thread, thread->private_data);
#ifndef WIN32
pthread_attr_destroy(&thread->attribute);
#endif
free(thread);
return exit_val;
}
KS_DECLARE(ks_status_t) ks_thread_create_detached(ks_thread_function_t func, void *data)
{
return ks_thread_create_detached_ex(func, data, thread_default_stacksize);
}
ks_status_t ks_thread_create_detached_ex(ks_thread_function_t func, void *data, size_t stack_size)
{
ks_thread_t *thread = NULL;
ks_status_t status = KS_FAIL;
if (!func || !(thread = (ks_thread_t *)malloc(sizeof(ks_thread_t)))) {
goto done;
}
thread->private_data = data;
thread->function = func;
thread->stack_size = stack_size;
#if defined(WIN32)
thread->handle = (void *)_beginthreadex(NULL, (unsigned)thread->stack_size, (unsigned int (__stdcall *)(void *))thread_launch, thread, 0, NULL);
if (!thread->handle) {
goto fail;
}
CloseHandle(thread->handle);
status = KS_SUCCESS;
goto done;
#else
if (pthread_attr_init(&thread->attribute) != 0) goto fail;
if (pthread_attr_setdetachstate(&thread->attribute, PTHREAD_CREATE_DETACHED) != 0) goto failpthread;
if (thread->stack_size && pthread_attr_setstacksize(&thread->attribute, thread->stack_size) != 0) goto failpthread;
if (pthread_create(&thread->handle, &thread->attribute, thread_launch, thread) != 0) goto failpthread;
status = KS_SUCCESS;
goto done;
failpthread:
pthread_attr_destroy(&thread->attribute);
#endif
fail:
if (thread) {
free(thread);
}
done:
return status;
}
KS_DECLARE(ks_status_t) ks_mutex_create(ks_mutex_t **mutex)
{
ks_status_t status = KS_FAIL;
#ifndef WIN32
pthread_mutexattr_t attr;
#endif
ks_mutex_t *check = NULL;
check = (ks_mutex_t *)malloc(sizeof(**mutex));
if (!check)
goto done;
#ifdef WIN32
InitializeCriticalSection(&check->mutex);
#else
if (pthread_mutexattr_init(&attr))
goto done;
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE))
goto fail;
if (pthread_mutex_init(&check->mutex, &attr))
goto fail;
goto success;
fail:
pthread_mutexattr_destroy(&attr);
goto done;
success:
#endif
*mutex = check;
status = KS_SUCCESS;
done:
return status;
}
KS_DECLARE(ks_status_t) ks_mutex_destroy(ks_mutex_t **mutex)
{
ks_mutex_t *mp = *mutex;
*mutex = NULL;
if (!mp) {
return KS_FAIL;
}
#ifdef WIN32
DeleteCriticalSection(&mp->mutex);
#else
if (pthread_mutex_destroy(&mp->mutex))
return KS_FAIL;
#endif
free(mp);
return KS_SUCCESS;
}
KS_DECLARE(ks_status_t) ks_mutex_lock(ks_mutex_t *mutex)
{
#ifdef WIN32
EnterCriticalSection(&mutex->mutex);
#else
if (pthread_mutex_lock(&mutex->mutex))
return KS_FAIL;
#endif
return KS_SUCCESS;
}
KS_DECLARE(ks_status_t) ks_mutex_trylock(ks_mutex_t *mutex)
{
#ifdef WIN32
if (!TryEnterCriticalSection(&mutex->mutex))
return KS_FAIL;
#else
if (pthread_mutex_trylock(&mutex->mutex))
return KS_FAIL;
#endif
return KS_SUCCESS;
}
KS_DECLARE(ks_status_t) ks_mutex_unlock(ks_mutex_t *mutex)
{
#ifdef WIN32
LeaveCriticalSection(&mutex->mutex);
#else
if (pthread_mutex_unlock(&mutex->mutex))
return KS_FAIL;
#endif
return KS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/

1768
libs/libks/src/mpool.c Normal file

File diff suppressed because it is too large Load Diff

1525
libs/libks/src/simclist.c Executable file

File diff suppressed because it is too large Load Diff

4079
libs/libks/src/table.c Normal file

File diff suppressed because it is too large Load Diff

295
libs/libks/src/table_util.c Normal file
View File

@ -0,0 +1,295 @@
/*
* Hash table utility program.
*
* Copyright 2000 by Gray Watson
*
* This file is part of the table package.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose and without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies,
* and that the name of Gray Watson not be used in advertising or
* publicity pertaining to distribution of the document or software
* without specific, written prior permission.
*
* Gray Watson makes no representations about the suitability of the
* software described herein for any purpose. It is provided "as is"
* without express or implied warranty.
*
* The author may be reached via http://256.com/gray/
*
* $Id: table_util.c,v 1.5 2000/03/09 03:30:42 gray Exp $
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include "table.h"
static char *rcs_id =
"$Id: table_util.c,v 1.5 2000/03/09 03:30:42 gray Exp $";
#define WRITE_MODE 0640 /* mode to write out table */
#define SPECIAL_CHARS "e\033^^\"\"''\\\\n\nr\rt\tb\bf\fa\007"
/*
* expand_chars
*
* DESCRIPTION:
*
* Copies a buffer into a output buffer while translates
* non-printables into %03o octal values. If it can, it will also
* translate certain \ characters (\r, \n, etc.) into \\%c. The
* routine is useful for printing out binary values.
*
* NOTE: It does _not_ add a \0 at the end of the output buffer.
*
* RETURNS:
*
* Returns the number of characters added to the output buffer.
*
* ARGUMENTS:
*
* buf - the buffer to convert.
*
* buf_size - size of the buffer. If < 0 then it will expand till it
* sees a \0 character.
*
* out - destination buffer for the convertion.
*
* out_size - size of the output buffer.
*/
int expand_chars(const void *buf, const int buf_size,
char *out, const int out_size)
{
int buf_c;
const unsigned char *buf_p, *spec_p;
char *max_p, *out_p = out;
/* setup our max pointer */
max_p = out + out_size;
/* run through the input buffer, counting the characters as we go */
for (buf_c = 0, buf_p = (const unsigned char *)buf;; buf_c++, buf_p++) {
/* did we reach the end of the buffer? */
if (buf_size < 0) {
if (*buf_p == '\0') {
break;
}
}
else {
if (buf_c >= buf_size) {
break;
}
}
/* search for special characters */
for (spec_p = (unsigned char *)SPECIAL_CHARS + 1;
*(spec_p - 1) != '\0';
spec_p += 2) {
if (*spec_p == *buf_p) {
break;
}
}
/* did we find one? */
if (*(spec_p - 1) != '\0') {
if (out_p + 2 >= max_p) {
break;
}
(void)sprintf(out_p, "\\%c", *(spec_p - 1));
out_p += 2;
continue;
}
/* print out any 7-bit printable characters */
if (*buf_p < 128 && isprint(*buf_p)) {
if (out_p + 1 >= max_p) {
break;
}
*out_p = *(char *)buf_p;
out_p += 1;
}
else {
if (out_p + 4 >= max_p) {
break;
}
(void)sprintf(out_p, "\\%03o", *buf_p);
out_p += 4;
}
}
return out_p - out;
}
/*
* dump_table
*
* DESCRIPTION:
*
* Dump a table file to the screen.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* tab_p - a table pointer that we are dumping.
*/
static void dump_table(table_t *tab_p)
{
char buf[10240];
void *key_p, *data_p;
int ret, key_size, data_size, len, entry_c;
for (ret = table_first(tab_p, (void **)&key_p, &key_size,
(void **)&data_p, &data_size), entry_c = 0;
ret == TABLE_ERROR_NONE;
ret = table_next(tab_p, (void **)&key_p, &key_size,
(void **)&data_p, &data_size), entry_c++) {
/* expand the key */
len = expand_chars(key_p, key_size, buf, sizeof(buf));
(void)printf("%d: key '%.*s' (%d), ", entry_c, len, buf, len);
/* now dump the data */
len = expand_chars(data_p, data_size, buf, sizeof(buf));
(void)printf("data '%.*s' (%d)\n", len, buf, len);
}
}
/*
* usage
*
* DESCRIPTION:
*
* Print the usage message to stderr.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* tab_p - a table pointer that we are dumping.
*/
static void usage(void)
{
(void)fprintf(stderr,
"Usage: table_util\n"
" [-b number] or --buckets num buckets to adjust table\n"
" [-o file] or --out-file output filename\n"
" [-v] or --verbose verbose messages\n"
" file input table filename\n");
exit(1);
}
int main(int argc, char **argv)
{
table_t *tab_p;
char do_write = 0, verbose = 0;
char *out_file = NULL, *in_file;
int ret, entry_n, bucket_n, num_buckets = 0;
/* process the args */
for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) {
switch (*(*argv + 1)) {
case 'b':
argc--, argv++;
if (argc == 0) {
usage();
}
num_buckets = atoi(*argv);
break;
case 'o':
argc--, argv++;
if (argc == 0) {
usage();
}
out_file = *argv;
break;
case 'v':
verbose = 1;
break;
default:
usage();
break;
}
}
if (argc != 1) {
usage();
}
/* take the last argument as the input file */
in_file = *argv;
/* read in the table from disk */
tab_p = table_read(in_file, &ret);
if (tab_p == NULL) {
(void)fprintf(stderr, "table_util: unable to table_read from '%s': %s\n",
in_file, table_strerror(ret));
exit(1);
}
/* get info about the table */
ret = table_info(tab_p, &bucket_n, &entry_n);
if (ret != TABLE_ERROR_NONE) {
(void)fprintf(stderr,
"table_util: unable to get info on table in '%s': %s\n",
in_file, table_strerror(ret));
exit(1);
}
(void)printf("Read table of %d buckets and %d entries from '%s'\n",
bucket_n, entry_n, in_file);
if (verbose) {
dump_table(tab_p);
}
if (num_buckets > 0) {
/* adjust the table's buckets */
ret = table_adjust(tab_p, num_buckets);
if (ret != TABLE_ERROR_NONE) {
(void)fprintf(stderr,
"table_util: unable to adjust table to %d buckets: %s\n",
num_buckets, table_strerror(ret));
exit(1);
}
do_write = 1;
}
/* did we modify the table at all */
if (do_write) {
if (out_file == NULL) {
out_file = in_file;
}
/* write out our table */
ret = table_write(tab_p, out_file, WRITE_MODE);
if (ret != TABLE_ERROR_NONE) {
(void)fprintf(stderr, "table_util: unable to write table to '%s': %s\n",
out_file, table_strerror(ret));
exit(1);
}
(void)printf("Wrote table to '%s'\n", out_file);
}
/* free the table */
ret = table_free(tab_p);
if (ret != TABLE_ERROR_NONE) {
(void)fprintf(stderr, "table_util: unable to free table: %s\n",
table_strerror(ret));
/* NOTE: not a critical error */
}
exit(0);
}

View File

@ -91,6 +91,7 @@ extern "C" {
#define __inline__ __inline
#endif
#if !defined(_STDINT) && !defined(uint32_t)
typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
@ -99,6 +100,7 @@ typedef __int64 int64_t;
typedef __int32 int32_t;
typedef __int16 int16_t;
typedef __int8 int8_t;
#endif
#else
#include <stdint.h>
#endif

View File

@ -1 +1 @@
Wed Aug 15 22:51:21 CDT 2012
Tue Nov 13 15:22:19 CST 2012

View File

@ -40,6 +40,9 @@ dist_man_MANS =
# man/man1/localinfo.1 man/man1/addrinfo.1 \
# man/man1/stunc.1 man/man1/sip-dig.1
noop:
@echo ok
$(dist_man_MANS): manpages
manpages:

View File

@ -254,6 +254,9 @@ if test x"$have_check" = "xyes"; then
fi
AC_CHECK_HEADERS([fnmatch.h])
AC_CHECK_LIB(pthread, pthread_setschedparam, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPARAM, 1, [Define if you have pthread_setschedparam()])])
dnl dl is currently used only in testing
AC_CHECK_LIB([dl], [dlopen], [
dnl Note: -ldl is not added to LIBS

View File

@ -744,7 +744,7 @@ void auth_check_digest(auth_mod_t *am,
auth_challenge_digest(am, as, ach);
as->as_blacklist = am->am_blacklist;
}
SU_DEBUG_5(("auth_method_digest: response did not match\n"));
SU_DEBUG_5(("auth_method_digest: response did not match\n" VA_NONE));
return;
}
@ -761,7 +761,7 @@ void auth_check_digest(auth_mod_t *am,
if (am->am_challenge)
auth_challenge_digest(am, as, ach);
SU_DEBUG_7(("auth_method_digest: successful authentication\n"));
SU_DEBUG_7(("auth_method_digest: successful authentication\n" VA_NONE));
as->as_status = 0; /* Successful authentication! */
as->as_phrase = "";
@ -1412,11 +1412,11 @@ int auth_validate_digest_nonce(auth_mod_t *am,
/* Check nonce */
if (!ar->ar_nonce) {
SU_DEBUG_5(("auth_method_digest: no nonce\n"));
SU_DEBUG_5(("auth_method_digest: no nonce\n" VA_NONE));
return -1;
}
if (base64_d((void*)nonce, (sizeof nonce), ar->ar_nonce) != (sizeof nonce)) {
SU_DEBUG_5(("auth_method_digest: too short nonce\n"));
SU_DEBUG_5(("auth_method_digest: too short nonce\n" VA_NONE));
return -1;
}
@ -1426,7 +1426,7 @@ int auth_validate_digest_nonce(auth_mod_t *am,
auth_md5_hmac_digest(am, md5, hmac, sizeof hmac);
if (memcmp(nonce->digest, hmac, sizeof nonce->digest)) {
SU_DEBUG_5(("auth_method_digest: bad nonce\n"));
SU_DEBUG_5(("auth_method_digest: bad nonce\n" VA_NONE));
return -1;
}

View File

@ -424,12 +424,12 @@ nea_server_t *nea_server_create(nta_agent_t *agent,
throttle = min_throttle;
if (!url) {
SU_DEBUG_5(("nea_server_create(): invalid url\n"));
SU_DEBUG_5(("nea_server_create(): invalid url\n" VA_NONE));
return NULL;
}
if (min_expires > expires || expires > max_expires) {
SU_DEBUG_5(("nea_server_create(): invalid expiration range\n"));
SU_DEBUG_5(("nea_server_create(): invalid expiration range\n" VA_NONE));
return NULL;
}

View File

@ -1276,7 +1276,7 @@ void agent_timer(su_root_magic_t *rm, su_timer_t *timer, nta_agent_t *agent)
if (next == latest) {
/* Do not set timer? */
SU_DEBUG_9(("nta: timer not set\n"));
SU_DEBUG_9(("nta: timer not set\n" VA_NONE));
assert(!agent->sa_out.completed->q_head);
assert(!agent->sa_out.trying->q_head);
assert(!agent->sa_out.inv_calling->q_head);
@ -2162,7 +2162,7 @@ int nta_agent_add_tport(nta_agent_t *self,
if (url_string_p(uri))
SU_DEBUG_1(("nta: %s: invalid bind URL\n", uri->us_str));
else
SU_DEBUG_1(("nta: invalid bind URL\n"));
SU_DEBUG_1(("nta: invalid bind URL\n" VA_NONE));
su_seterrno(EINVAL);
return -1;
}
@ -2249,19 +2249,19 @@ int nta_agent_add_tport(nta_agent_t *self,
/* XXX - when to use maddr? */
if ((agent_init_via(self, tport_primaries(self->sa_tports), 0)) < 0) {
error = su_errno();
SU_DEBUG_1(("nta: cannot create Via headers\n"));
SU_DEBUG_1(("nta: cannot create Via headers\n" VA_NONE));
goto error;
}
else
SU_DEBUG_9(("nta: Via fields initialized\n"));
SU_DEBUG_9(("nta: Via fields initialized\n" VA_NONE));
if ((agent_init_contact(self)) < 0) {
error = su_errno();
SU_DEBUG_1(("nta: cannot create Contact header\n"));
SU_DEBUG_1(("nta: cannot create Contact header\n" VA_NONE));
goto error;
}
else
SU_DEBUG_9(("nta: Contact header created\n"));
SU_DEBUG_9(("nta: Contact header created\n" VA_NONE));
su_free(self->sa_home, url);
ta_end(ta);
@ -2286,7 +2286,7 @@ int agent_create_master_transport(nta_agent_t *self, tagi_t *tags)
if (!self->sa_tports)
return -1;
SU_DEBUG_9(("nta: master transport created\n"));
SU_DEBUG_9(("nta: master transport created\n" VA_NONE));
return 0;
}
@ -7713,7 +7713,7 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
home = msg_home(msg);
if (!sip->sip_request || sip_complete_message(msg) < 0) {
SU_DEBUG_3(("nta: outgoing_create: incomplete request\n"));
SU_DEBUG_3(("nta: outgoing_create: incomplete request\n" VA_NONE));
return NULL;
}
@ -7900,7 +7900,7 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
}
}
else {
SU_DEBUG_1(("outgoing_create: ACK without INVITE\n"));
SU_DEBUG_1(("outgoing_create: ACK without INVITE\n" VA_NONE));
assert(!"INVITE found for ACK");
}
}
@ -7987,11 +7987,11 @@ outgoing_prepare_send(nta_outgoing_t *orq)
outgoing_send_via(orq, tp);
}
else if (orq->orq_sips) {
SU_DEBUG_3(("nta outgoing create: no secure transport\n"));
SU_DEBUG_3(("nta outgoing create: no secure transport\n" VA_NONE));
outgoing_reply(orq, SIP_416_UNSUPPORTED_URI, 1);
}
else {
SU_DEBUG_3(("nta outgoing create: no transport protocol\n"));
SU_DEBUG_3(("nta outgoing create: no transport protocol\n" VA_NONE));
outgoing_reply(orq, 503, "No transport", 1);
}
}
@ -8013,7 +8013,7 @@ outgoing_send_via(nta_outgoing_t *orq, tport_t *tp)
if (old_tp) tport_unref(old_tp);
if (outgoing_insert_via(orq, agent_tport_via(tp)) < 0) {
SU_DEBUG_3(("nta outgoing create: cannot insert Via line\n"));
SU_DEBUG_3(("nta outgoing create: cannot insert Via line\n" VA_NONE));
outgoing_reply(orq, 503, "Cannot insert Via", 1);
return;
}
@ -9211,7 +9211,7 @@ int outgoing_recv(nta_outgoing_t *_orq,
if (orq->orq_destroyed && 200 <= status && status < 300) {
if (orq->orq_uas && su_strcasecmp(sip->sip_to->a_tag, orq->orq_tag) != 0) {
/* Orphan 200 Ok to INVITE. ACK and BYE it */
SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE\n"));
SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE %p\n", (void *)orq));
return nta_msg_ackbye(sa, msg);
}
return -1; /* Proxy statelessly (RFC3261 section 16.11) */
@ -9273,7 +9273,7 @@ int outgoing_recv(nta_outgoing_t *_orq,
return outgoing_duplicate(orq, msg, sip);
/* Orphan 200 Ok to INVITE. ACK and BYE it */
SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE"));
SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE" VA_NONE));
return nta_msg_ackbye(sa, msg);
}
}

View File

@ -911,7 +911,7 @@ int hc_resolve_and_send(nth_client_t * hc)
if (msg_serialize(msg, http) < 0) {
assert(hc->hc_tport);
SU_DEBUG_3(("nth client create: invalid message"));
SU_DEBUG_3(("nth client create: invalid message" VA_NONE));
return -1;
}

View File

@ -312,20 +312,20 @@ nth_site_t *nth_site_create(nth_site_t *parent,
is_path = url->url_path != NULL;
if (is_host && is_path) {
SU_DEBUG_3(("nth_site_create(): virtual host and path simultanously\n"));
SU_DEBUG_3(("nth_site_create(): virtual host and path simultanously\n" VA_NONE));
errno = EINVAL;
goto error;
}
if (!parent && !is_host) {
SU_DEBUG_3(("nth_site_create(): host is required\n"));
SU_DEBUG_3(("nth_site_create(): host is required\n" VA_NONE));
errno = EINVAL;
goto error;
}
if (parent) {
if (!parent->site_isdir) {
SU_DEBUG_3(("nth_site_create(): invalid parent resource \n"));
SU_DEBUG_3(("nth_site_create(): invalid parent resource \n" VA_NONE));
errno = EINVAL;
goto error;
}
@ -995,7 +995,7 @@ static void server_reply(server_t *srv, tport_t *tport,
if (tport_tqsend(tport, response, NULL,
TPTAG_CLOSE_AFTER(close),
TAG_END()) == -1) {
SU_DEBUG_3(("server_reply(): cannot queue response\n"));
SU_DEBUG_3(("server_reply(): cannot queue response\n" VA_NONE));
tport_shutdown(tport, 2);
}

View File

@ -1217,6 +1217,7 @@ int nua_base_client_check_restart(nua_client_request_t *cr,
status == 500 || status == 503 ||
status == 600 || status == 603) &&
sip->sip_retry_after &&
NH_PGET(nh, retry_after_enable) &&
sip->sip_retry_after->af_delta < 3200) {
su_timer_t *timer;
char phrase[18]; /* Retry After XXXX\0 */

View File

@ -157,6 +157,7 @@ int nua_stack_set_defaults(nua_handle_t *nh,
NHP_SET(nhp, callee_caps, 0);
NHP_SET(nhp, service_route_enable, 1);
NHP_SET(nhp, path_enable, 1);
NHP_SET(nhp, retry_after_enable, 1);
NHP_SET(nhp, refer_expires, 300);
NHP_SET(nhp, refer_with_id, 1);
@ -295,6 +296,7 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags)
* NUTAG_ONLY183_100REL() \n
* NUTAG_OUTBOUND() \n
* NUTAG_PATH_ENABLE() \n
* NUTAG_RETRY_AFTER_ENABLE() \n
* NUTAG_PROXY() (aka NTATAG_DEFAULT_PROXY()) \n
* NUTAG_REFER_EXPIRES() \n
* NUTAG_REFER_WITH_ID() \n
@ -417,6 +419,7 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags)
* NUTAG_ONLY183_100REL() \n
* NUTAG_OUTBOUND() \n
* NUTAG_PATH_ENABLE() \n
* NUTAG_RETRY_AFTER_ENABLE() \n
* NUTAG_PROXY() (aka NTATAG_DEFAULT_PROXY()) \n
* NUTAG_REFER_EXPIRES() \n
* NUTAG_REFER_WITH_ID() \n
@ -801,6 +804,10 @@ static int nhp_set_tags(su_home_t *home,
else if (tag == nutag_path_enable) {
NHP_SET(nhp, path_enable, value != 0);
}
/* NUTAG_RETRY_AFTER_ENABLE(retry_after_enable) */
else if (tag == nutag_retry_after_enable) {
NHP_SET(nhp, retry_after_enable, value != 0);
}
/* NUTAG_AUTH_CACHE(auth_cache) */
else if (tag == nutag_auth_cache) {
if (value >= 0 && value < (tag_value_t)_nua_auth_cache_invalid)
@ -1494,6 +1501,7 @@ int nua_stack_set_smime_params(nua_t *nua, tagi_t const *tags)
* NUTAG_ONLY183_100REL() \n
* NUTAG_OUTBOUND() \n
* NUTAG_PATH_ENABLE() \n
* NUTAG_RETRY_AFTER_ENABLE() \n
* NUTAG_REFER_EXPIRES() \n
* NUTAG_REFER_WITH_ID() \n
* NUTAG_REFRESH_WITHOUT_SDP() \n
@ -1669,6 +1677,7 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
TIF(NUTAG_MEDIA_FEATURES, media_features),
TIF(NUTAG_SERVICE_ROUTE_ENABLE, service_route_enable),
TIF(NUTAG_PATH_ENABLE, path_enable),
TIF(NUTAG_RETRY_AFTER_ENABLE, retry_after_enable),
TIF(NUTAG_AUTH_CACHE, auth_cache),
TIF(NUTAG_REFER_EXPIRES, refer_expires),
TIF(NUTAG_REFER_WITH_ID, refer_with_id),

View File

@ -111,6 +111,10 @@ struct nua_handle_preferences
unsigned nhp_refer_with_id:1;
unsigned nhp_timer_autorequire:1;
/** Enable Retry-After */
unsigned nhp_retry_after_enable:1;
unsigned:0;
/* Default lifetime for implicit subscriptions created by REFER */
@ -210,6 +214,7 @@ struct nua_handle_preferences
unsigned nhb_initial_route:1;
unsigned nhb_proxy:1;
unsigned nhb_timer_autorequire:1;
unsigned nhb_retry_after_enable:1;
unsigned :0;
} set_bits;
unsigned set_unsigned[2];

View File

@ -967,7 +967,7 @@ static int nua_register_client_response(nua_client_request_t *cr,
if (tport && tport != nr->nr_tport) {
if (nr->nr_error_report_id) {
if (tport_release(nr->nr_tport, nr->nr_error_report_id, NULL, NULL, nr, 0) < 0)
SU_DEBUG_1(("nua_register: tport_release() failed\n"));
SU_DEBUG_1(("nua_register: tport_release() failed\n" VA_NONE));
nr->nr_error_report_id = 0;
}
tport_unref(nr->nr_tport);
@ -996,7 +996,7 @@ static int nua_register_client_response(nua_client_request_t *cr,
if (nr->nr_tport) {
if (nr->nr_error_report_id) {
if (tport_release(nr->nr_tport, nr->nr_error_report_id, NULL, NULL, nr, 0) < 0)
SU_DEBUG_1(("nua_register: tport_release() failed\n"));
SU_DEBUG_1(("nua_register: tport_release() failed\n" VA_NONE));
nr->nr_error_report_id = 0;
}
@ -1028,7 +1028,7 @@ void nua_register_connection_closed(tp_stack_t *sip_stack,
pending = nr->nr_error_report_id;
if (tport_release(tport, pending, NULL, NULL, nr, 0) < 0)
SU_DEBUG_1(("nua_register: tport_release() failed\n"));
SU_DEBUG_1(("nua_register: tport_release() failed\n" VA_NONE));
nr->nr_error_report_id = 0;
tpn = tport_name(nr->nr_tport);

View File

@ -1245,6 +1245,7 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
int status = 200;
char const *phrase = "OK", *reason = NULL;
char const *invite_branch;
char const *pl_s = NULL;
assert(cr->cr_orq);
assert(cr->cr_method == sip_method_invite);
@ -1256,6 +1257,11 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
goto error;
}
tl_gets(tags,
SIPTAG_PAYLOAD_STR_REF(pl_s),
TAG_END());
assert(ds->ds_leg);
msg = nta_outgoing_getrequest(cr->cr_orq);
@ -1305,7 +1311,7 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
while (sip->sip_supported)
sip_header_remove(msg, sip, (sip_header_t*)sip->sip_supported);
if (ss == NULL || ss->ss_state > nua_callstate_ready)
if (ss == NULL || ss->ss_state > nua_callstate_ready || pl_s)
;
else if (cr->cr_offer_recv && !cr->cr_answer_sent) {
if (nh->nh_soa == NULL) {
@ -3039,11 +3045,11 @@ nh_referral_check(nua_handle_t *nh, tagi_t const *tags)
ref->ref_event = sip_event_dup(nh->nh_home, event);
if (!nh_validate(nh->nh_nua, ref_handle)) {
SU_DEBUG_3(("nua: invalid NOTIFY_REFER handle\n"));
SU_DEBUG_3(("nua: invalid NOTIFY_REFER handle\n" VA_NONE));
return -1;
}
else if (!ref->ref_event) {
SU_DEBUG_3(("nua: NOTIFY event missing\n"));
SU_DEBUG_3(("nua: NOTIFY event missing\n" VA_NONE));
return -1;
}

View File

@ -192,7 +192,7 @@ int nua_stack_init(su_root_t *root, nua_t *nua)
dnh->nh_ds->ds_leg == NULL ||
nta_agent_set_params(nua->nua_nta, NTATAG_UA(1), TAG_END()) < 0 ||
nua_stack_init_transport(nua, nua->nua_args) < 0) {
SU_DEBUG_1(("nua: initializing SIP stack failed\n"));
SU_DEBUG_1(("nua: initializing SIP stack failed\n" VA_NONE));
return -1;
}

Some files were not shown because too many files have changed in this diff Show More