pax_global_header 0000666 0000000 0000000 00000000064 12702357234 0014517 g ustar 00root root 0000000 0000000 52 comment=caad0ef1533783729c7644a226c989c79b4c497b
rabbitmq-c-0.8.0/ 0000775 0000000 0000000 00000000000 12702357234 0013545 5 ustar 00root root 0000000 0000000 rabbitmq-c-0.8.0/.clang-format 0000664 0000000 0000000 00000002553 12702357234 0016125 0 ustar 00root root 0000000 0000000 ---
# BasedOnStyle: Google
AccessModifierOffset: -1
ConstructorInitializerIndentWidth: 4
AlignEscapedNewlinesLeft: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakTemplateDeclarations: true
AlwaysBreakBeforeMultilineStrings: true
BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: true
ColumnLimit: 80
ConstructorInitializerAllOnOneLineOrOnePerLine: true
DerivePointerBinding: true
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: true
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 60
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerBindsToType: true
SpacesBeforeTrailingComments: 2
Cpp11BracedListStyle: true
Standard: Auto
IndentWidth: 2
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Attach
IndentFunctionDeclarationAfterType: true
SpacesInParentheses: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpaceAfterControlStatementKeyword: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
...
rabbitmq-c-0.8.0/.gitattributes 0000664 0000000 0000000 00000000512 12702357234 0016436 0 ustar 00root root 0000000 0000000 # Default for those who don't have core.autocrlf set
* text=auto
# Things that should be treated like text (lines converted on checkout):
*.c text
*.h text
*.py text
*.cmake text
*.md text
# This is for the output of table_test
*.expected text
*.xml
# Exceptions to the rule:
*.ac text eol=lf
*.am text eol=lf
*.m4 text eol=lf
rabbitmq-c-0.8.0/.gitignore 0000664 0000000 0000000 00000002164 12702357234 0015540 0 ustar 00root root 0000000 0000000 *.la
*.lo
*.o
.deps
.dirstamp
.libs
/aclocal.m4
/autom4te.cache
/bin*
/build
/compile
/config.guess
/config.h
/config.h.in
/config.h.in~
/config.log
/config.status
/config.sub
/configure
/cscope.*
/depcomp
/install-sh
/libtool
/ltmain.sh
/missing
/stamp-h1
/test-suite.log
INSTALL
Makefile
Makefile.in
examples/amqp_bind
examples/amqp_connect_timeout
examples/amqp_consumer
examples/amqp_exchange_declare
examples/amqp_listen
examples/amqp_listenq
examples/amqp_producer
examples/amqp_rpc_sendstring_client
examples/amqp_sendstring
examples/amqp_unbind
examples/amqps_bind
examples/amqps_connect_timeout
examples/amqps_consumer
examples/amqps_exchange_declare
examples/amqps_listen
examples/amqps_listenq
examples/amqps_producer
examples/amqps_sendstring
examples/amqps_unbind
librabbitmq.pc
test-driver
tests/*.log
tests/*.trs
tests/test_hostcheck
tests/test_parse_url
tests/test_status_enum
tests/test_tables
tools/amqp-consume
tools/amqp-declare-queue
tools/amqp-delete-queue
tools/amqp-get
tools/amqp-publish
tools/doc/*.1
tools/doc/*.7
tools/doc/man-date.ent
.ycm_extra_conf.py?
.DS_Store
# Ignore editor swap files
*~
*.sw?
.#*
\#*#
rabbitmq-c-0.8.0/.gitmodules 0000664 0000000 0000000 00000000136 12702357234 0015722 0 ustar 00root root 0000000 0000000 [submodule "codegen"]
path = codegen
url = https://github.com/rabbitmq/rabbitmq-codegen.git
rabbitmq-c-0.8.0/.travis.yml 0000664 0000000 0000000 00000004547 12702357234 0015670 0 ustar 00root root 0000000 0000000 # Travis-CI Build for rabbitmq-c
# see travis-ci.org for details
language: c
# Use the faster container-based infrastructure.
sudo: false
env:
global:
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
# via the "travis encrypt" command using the project repo's public key
- secure: "gDwqo3jHj+HHGzFKnxL/nwZhbVeh2pItw0TbeaHcLtWubUZaf85ViEQRaXPyfnbG7l0OEQq+PjyhKAfvViVq2NP0lGeeu4VM5uMZJhsCLN594BJr39Y4XzOapg0O8mEMhQ0DU2u1Zo4LMgEcRz67aosVQOj6QV30tOzp9fnxn9U="
matrix:
include:
# Note that the first compiler in the matrix must be gcc, so that the
# coverity_scan branch hack below works correctly.
- compiler: gcc
os: linux
env: CONFIG=autotools
- compiler: gcc
os: linux
env: CONFIG=cmake
- compiler: clang
os: linux
env: CONFIG=cmake
- compiler: clang
os: linux
env: CONFIG=asan
- compiler: clang
os: linux
env: CONFIG=tsan
- compiler: clang
os: linux
env: CONFIG=scan-build
- compiler: clang
os: osx
env: CONFIG=cmake
before_install:
# ugly hack; if running a coverity scan abort all except the 1st build
# see note re gcc compiler above needing to be 1st
# also note that branch_pattern & the TRAVIS_BRANCH check must match
# unfortunately COVERITY_SCAN_BRANCH isn't defined until later in the
# build process
- if ([[ "${TRAVIS_JOB_NUMBER##*.}" != "1" ]] && [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]); then false ; fi
script:
# Don't bother building if this is being done in the coverity_scan branch.
- if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./travis.sh $CONFIG ; fi
addons:
apt:
# List of whitelisted in travis packages for ubuntu-precise can be found here:
# https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise
# List of whitelisted in travis apt-sources:
# https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
packages:
- libpopt-dev
- clang-3.7
coverity_scan:
project:
name: "alanxz/rabbitmq-c"
description: "C AMQP client for RabbitMQ"
notification_email: alan.antonuk@gmail.com
build_command_prepend: mkdir build && pushd build && cmake .. && popd
build_command: cmake --build ./build
branch_pattern: coverity_scan
rabbitmq-c-0.8.0/.ycm_extra_conf.py 0000664 0000000 0000000 00000012736 12702357234 0017206 0 ustar 00root root 0000000 0000000 # This file is NOT licensed under the GPLv3, which is the license for the rest
# of YouCompleteMe.
#
# Here's the license text for this file:
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# 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 BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to
import os
import ycm_core
# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
'-Wall',
'-Wextra',
# THIS IS IMPORTANT! Without a "-std=" flag, clang won't know which
# language to use when compiling headers. So it will guess. Badly. So C++
# headers will be compiled as C headers. You don't want that so ALWAYS specify
# a "-std=".
# For a C project, you would set this to something like 'c99' instead of
# 'c++11'.
'-std=gnu90',
# ...and the same thing goes for the magic -x option which specifies the
# language that the files to be compiled are written in. This is mostly
# relevant for c++ headers.
# For a C project, you would set this to 'c' instead of 'c++'.
'-x',
'c',
'-I', './librabbitmq',
'-D', 'HAVE_POLL',
]
# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
#
# You can get CMake to generate this file for you by adding:
# set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
# to your CMakeLists.txt file.
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = ''
if os.path.exists( compilation_database_folder ):
database = ycm_core.CompilationDatabase( compilation_database_folder )
else:
database = None
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]
def DirectoryOfThisScript():
return os.path.dirname( os.path.abspath( __file__ ) )
def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
if not working_directory:
return list( flags )
new_flags = []
make_next_absolute = False
path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
for flag in flags:
new_flag = flag
if make_next_absolute:
make_next_absolute = False
if not flag.startswith( '/' ):
new_flag = os.path.join( working_directory, flag )
for path_flag in path_flags:
if flag == path_flag:
make_next_absolute = True
break
if flag.startswith( path_flag ):
path = flag[ len( path_flag ): ]
new_flag = path_flag + os.path.join( working_directory, path )
break
if new_flag:
new_flags.append( new_flag )
return new_flags
def IsHeaderFile( filename ):
extension = os.path.splitext( filename )[ 1 ]
return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
def GetCompilationInfoForFile( filename ):
# The compilation_commands.json file generated by CMake does not have entries
# for header files. So we do our best by asking the db for flags for a
# corresponding source file, if any. If one exists, the flags for that file
# should be good enough.
if IsHeaderFile( filename ):
basename = os.path.splitext( filename )[ 0 ]
for extension in SOURCE_EXTENSIONS:
replacement_file = basename + extension
if os.path.exists( replacement_file ):
compilation_info = database.GetCompilationInfoForFile(
replacement_file )
if compilation_info.compiler_flags_:
return compilation_info
return None
return database.GetCompilationInfoForFile( filename )
def FlagsForFile( filename, **kwargs ):
if database:
# Bear in mind that compilation_info.compiler_flags_ does NOT return a
# python list, but a "list-like" StringVec object
compilation_info = GetCompilationInfoForFile( filename )
if not compilation_info:
relative_to = DirectoryOfThisScript()
return {
'flags': MakeRelativePathsInFlagsAbsolute( flags, relative_to ),
'do_cache': True
}
final_flags = MakeRelativePathsInFlagsAbsolute(
compilation_info.compiler_flags_,
compilation_info.compiler_working_dir_ )
else:
relative_to = DirectoryOfThisScript()
final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
return {
'flags': final_flags,
'do_cache': True
}
rabbitmq-c-0.8.0/AUTHORS 0000664 0000000 0000000 00000000126 12702357234 0014614 0 ustar 00root root 0000000 0000000 Tony Garnock-Jones
The RabbitMQ team
rabbitmq-c-0.8.0/CMakeLists.txt 0000664 0000000 0000000 00000031202 12702357234 0016303 0 ustar 00root root 0000000 0000000 # vim:set ts=2 sw=2 sts=2 et:
cmake_minimum_required(VERSION 2.6)
project(rabbitmq-c "C")
# Enable MACOSX_RPATH by default. See: cmake --help-policy CMP0042
if (POLICY CMP0042)
cmake_policy(SET CMP0042 NEW)
endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# Follow all steps below in order to calculate new ABI version when updating the library
# NOTE: THIS IS UNRELATED to the actual project version
#
# 1. If the library source code has changed at all since the last update, then increment revision
# 2. If any interfaces have been added, removed, or changed since the last update, increment current and set revision to 0.
# 3. If any interfaces have been added since the last public release, then increment age.
# 4. If any interfaces have been removed since the last public release, then set age to 0.
set(RMQ_SOVERSION_CURRENT 6)
set(RMQ_SOVERSION_REVISION 0)
set(RMQ_SOVERSION_AGE 2)
math(EXPR RMQ_SOVERSION_MAJOR "${RMQ_SOVERSION_CURRENT} - ${RMQ_SOVERSION_AGE}")
math(EXPR RMQ_SOVERSION_MINOR "${RMQ_SOVERSION_AGE}")
math(EXPR RMQ_SOVERSION_PATCH "${RMQ_SOVERSION_REVISION}")
set(RMQ_VERSION ${RMQ_SOVERSION_MAJOR}.${RMQ_SOVERSION_MINOR}.${RMQ_SOVERSION_PATCH})
set(RMQ_SOVERSION ${RMQ_SOVERSION_MAJOR})
file(STRINGS librabbitmq/amqp.h _API_VERSION_MAJOR REGEX "^#define AMQP_VERSION_MAJOR [0-9]+$")
file(STRINGS librabbitmq/amqp.h _API_VERSION_MINOR REGEX "^#define AMQP_VERSION_MINOR [0-9]+$")
file(STRINGS librabbitmq/amqp.h _API_VERSION_PATCH REGEX "^#define AMQP_VERSION_PATCH [0-9]+$")
string(REGEX MATCH "[0-9]+" _API_VERSION_MAJOR ${_API_VERSION_MAJOR})
string(REGEX MATCH "[0-9]+" _API_VERSION_MINOR ${_API_VERSION_MINOR})
string(REGEX MATCH "[0-9]+" _API_VERSION_PATCH ${_API_VERSION_PATCH})
# VERSION to match what is in autotools
set(VERSION ${_API_VERSION_MAJOR}.${_API_VERSION_MINOR}.${_API_VERSION_PATCH})
if (CMAKE_GENERATOR MATCHES ".*(Make|Ninja).*"
AND NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
message(STATUS "CMAKE_BUILD_TYPE not specified. Creating ${CMAKE_BUILD_TYPE} build")
endif()
include(TestCInline)
include(CheckSymbolExists)
include(CheckLibraryExists)
include(CMakePushCheckState)
include(GNUInstallDirs)
include(CheckCCompilerFlag)
# Detect if we need to link against a socket library:
cmake_push_check_state()
if (WIN32)
# Always use WinSock2 on Windows
set(SOCKET_LIBRARIES ws2_32)
else ()
# Is it in the default link?
check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO)
if (NOT (HAVE_GETADDRINFO EQUAL 1))
SET(CMAKE_REQUIRED_LIBRARIES "socket")
check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO2)
if (HAVE_GETADDRINFO2 EQUAL 1)
set(SOCKET_LIBRARIES socket)
else ()
SET(CMAKE_REQUIRED_LIBRARIES "socket;nsl")
check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO3)
if (HAVE_GETADDRINFO3 EQUAL 1)
set(SOCKET_LIBRARIES socket nsl)
else ()
message(FATAL_ERROR "Cannot find name resolution library (containing symbol getaddrinfo)")
endif ()
endif ()
endif ()
set(CMAKE_REQUIRED_LIBRARIES ${SOCKET_LIBRARIES})
check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET)
if (NOT HAVE_SOCKET EQUAL 1)
set(CMAKE_REQUIRED_LIBRARIES socket ${SOCKET_LIBRARIES})
check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET2)
if (HAVE_SOCKET2 EQUAL 1)
set(SOCKET_LIBRARIES socket ${SOCKET_LIBRARIES})
else ()
set(CMAKE_REQUIRED_LIBRARIES socket nsl ${SOCKET_LIBRARIES})
check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET3)
if (HAVE_SOCKET3 EQUAL 1)
set(SOCKET_LIBRARIES socket nsl ${SOCKET_LIBRARIES})
else ()
message(FATAL_ERROR "Cannot find socket library (containing symbol socket)")
endif ()
endif ()
endif ()
endif ()
cmake_pop_check_state()
cmake_push_check_state()
set(CMAKE_REQUIRED_LIBRARIES ${SOCKET_LIBRARIES})
if (WIN32)
check_symbol_exists(htonll Winsock2.h HAVE_HTONLL)
else (WIN32)
check_symbol_exists(htonll arpa/inet.h HAVE_HTONLL)
endif (WIN32)
cmake_pop_check_state()
cmake_push_check_state()
set(CMAKE_REQUIRED_LIBRARIES ${SOCKET_LIBRARIES})
check_symbol_exists(poll poll.h HAVE_POLL)
if (NOT HAVE_POLL)
if (WIN32)
set(HAVE_SELECT 1)
else()
check_symbol_exists(select sys/select.h HAVE_SELECT)
endif()
if (NOT HAVE_SELECT)
message(FATAL_ERROR "rabbitmq-c requires poll() or select() to be available")
endif()
endif()
cmake_pop_check_state()
check_library_exists(rt clock_gettime "time.h" CLOCK_GETTIME_NEEDS_LIBRT)
check_library_exists(rt posix_spawnp "spawn.h" POSIX_SPAWNP_NEEDS_LIBRT)
if (CLOCK_GETTIME_NEEDS_LIBRT OR POSIX_SPAWNP_NEEDS_LIBRT)
set(LIBRT rt)
endif()
if (MSVC)
set(CMAKE_C_FLAGS "/W4 /nologo ${CMAKE_C_FLAGS}")
elseif (CMAKE_C_COMPILER_ID MATCHES ".*Clang")
set(CMAKE_C_FLAGS "-Wall -Wextra -Wstrict-prototypes -Wno-unused-function -fno-common -fvisibility=hidden ${CMAKE_C_FLAGS}")
elseif (CMAKE_COMPILER_IS_GNUCC)
set(RMQ_C_FLAGS "-Wall -Wextra -Wstrict-prototypes -Wno-unused-function -fno-common")
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if (GCC_VERSION VERSION_GREATER 4.0 OR GCC_VERSION VERSION_EQUAL 4.0)
set(RMQ_C_FLAGS "${RMQ_C_FLAGS} -fvisibility=hidden")
endif()
set(CMAKE_C_FLAGS "${RMQ_C_FLAGS} ${CMAKE_C_FLAGS}")
endif ()
CHECK_C_COMPILER_FLAG("-std=gnu90" HAVE_GNU90)
if (HAVE_GNU90)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu90")
else()
CHECK_C_COMPILER_FLAG("-std=c90" HAVE_C90)
if (HAVE_C90)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c90")
endif()
endif()
option(REGENERATE_AMQP_FRAMING "Regenerate amqp_framing.h/amqp_framing.c sources (for developer use)" OFF)
mark_as_advanced(REGENERATE_AMQP_FRAMING)
if (REGENERATE_AMQP_FRAMING)
find_package(PythonInterp)
if (NOT PYTHONINTERP_FOUND)
message(FATAL_ERROR "REGENERATE_AMQP_FRAMING requires Python to be available")
endif ()
#Determine Python Version:
if(PYTHON_EXECUTABLE)
execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c
"import sys; sys.stdout.write(';'.join([str(x) for x in sys.version_info[:3]]))"
OUTPUT_VARIABLE _VERSION
RESULT_VARIABLE _PYTHON_VERSION_RESULT
ERROR_QUIET)
if(NOT _PYTHON_VERSION_RESULT)
string(REPLACE ";" "." PYTHON_VERSION_STRING "${_VERSION}")
list(GET _VERSION 0 PYTHON_VERSION_MAJOR)
list(GET _VERSION 1 PYTHON_VERSION_MINOR)
list(GET _VERSION 2 PYTHON_VERSION_PATCH)
if(PYTHON_VERSION_PATCH EQUAL 0)
# it's called "Python 2.7", not "2.7.0"
string(REGEX REPLACE "\\.0$" "" PYTHON_VERSION_STRING "${PYTHON_VERSION_STRING}")
endif()
else()
# sys.version predates sys.version_info, so use that
execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.version)"
OUTPUT_VARIABLE _VERSION
RESULT_VARIABLE _PYTHON_VERSION_RESULT
ERROR_QUIET)
if(NOT _PYTHON_VERSION_RESULT)
string(REGEX REPLACE " .*" "" PYTHON_VERSION_STRING "${_VERSION}")
string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" PYTHON_VERSION_MAJOR "${PYTHON_VERSION_STRING}")
string(REGEX REPLACE "^[0-9]+\\.([0-9])+.*" "\\1" PYTHON_VERSION_MINOR "${PYTHON_VERSION_STRING}")
if(PYTHON_VERSION_STRING MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+.*")
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PYTHON_VERSION_PATCH "${PYTHON_VERSION_STRING}")
else()
set(PYTHON_VERSION_PATCH "0")
endif()
else()
# sys.version was first documented for Python 1.5, so assume
# this is older.
set(PYTHON_VERSION_STRING "1.4")
set(PYTHON_VERSION_MAJOR "1")
set(PYTHON_VERSION_MAJOR "4")
set(PYTHON_VERSION_MAJOR "0")
endif()
endif()
unset(_PYTHON_VERSION_RESULT)
unset(_VERSION)
endif(PYTHON_EXECUTABLE)
# If we're running v3.x look for a 2to3 utility
if (PYTHON_VERSION_MAJOR GREATER 2)
get_filename_component(PYTHON_EXE_DIR ${PYTHON_EXECUTABLE} PATH)
find_program(PYTHON_2TO3_EXECUTABLE
NAMES 2to3
HINTS ${PYTHON_EXE_DIR}
)
if ("PYTHON_2TO3_EXECUTABLE-NOTFOUND" STREQUAL PYTHON_2TO3_EXECUTABLE)
message(FATAL_ERROR "Unable to find 2to3 python utility, specify python 2.7 or specify 2to3 utility")
endif ()
endif (PYTHON_VERSION_MAJOR GREATER 2)
#check for json or simplejson
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import json"
RESULT_VARIABLE CHECK_PYTHON_JSON_FAILED
)
if (CHECK_PYTHON_JSON_FAILED)
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import simplejson"
RESULT_VARIABLE CHECK_PYTHON_SIMPLEJSON_FAILED
)
if (CHECK_PYTHON_SIMPLEJSON_FAILED)
message(FATAL_ERROR "REGENERATE_AMQP_FRAMING requires a python with json or simplejson modules")
endif (CHECK_PYTHON_SIMPLEJSON_FAILED)
endif (CHECK_PYTHON_JSON_FAILED)
find_path(AMQP_CODEGEN_DIR
amqp_codegen.py
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/codegen
${CMAKE_CURRENT_SOURCE_DIR}/rabbitmq-codegen
${CMAKE_CURRENT_SOURCE_DIR}/../rabbitmq-codegen
DOC "Path to directory containing amqp_codegen.py (rabbitmq-codegen)"
NO_DEFAULT_PATH
)
if (AMQP_CODEGEN_DIR STREQUAL "AMQP_CODEGEN_DIR-NOTFOUND")
message(SEND_ERROR "REGENERATE_AMQP_FRAMING requires the amqp_codegen.py script. If this is a git clone you can:\n\ngit submodule init\ngit submodule update\n\n Or set AMQP_CODEGEN_DIR to directory containing amqp_codegen.py")
else ()
message(STATUS "Found amqp_codegen.py in ${AMQP_CODEGEN_DIR}")
endif()
endif (REGENERATE_AMQP_FRAMING)
find_package(POPT)
find_package(XmlTo)
find_package(Doxygen)
if (POPT_FOUND AND XmlTo_FOUND)
set(DO_DOCS ON)
endif()
find_package(Threads)
option(BUILD_SHARED_LIBS "Build rabbitmq-c as a shared library" ON)
option(BUILD_STATIC_LIBS "Build rabbitmq-c as a static library" ON)
option(BUILD_EXAMPLES "Build Examples" ON)
option(BUILD_TOOLS "Build Tools (requires POPT Library)" ${POPT_FOUND})
option(BUILD_TOOLS_DOCS "Build man pages for Tools (requires xmlto)" ${DO_DOCS})
option(BUILD_TESTS "Build tests (run tests with make test)" ON)
option(BUILD_API_DOCS "Build Doxygen API docs" ${DOXYGEN_FOUND})
option(ENABLE_SSL_SUPPORT "Enable SSL support" ON)
option(ENABLE_THREAD_SAFETY "Enable thread safety when using OpenSSL" ${Threads_FOUND})
if (ENABLE_SSL_SUPPORT)
find_package(OpenSSL 0.9.8 REQUIRED)
endif()
if (NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
message(FATAL_ERROR "One or both of BUILD_SHARED_LIBS or BUILD_STATIC_LIBS must be set to ON to build")
endif()
add_subdirectory(librabbitmq)
if (BUILD_EXAMPLES)
add_subdirectory(examples)
endif ()
if (BUILD_TOOLS)
if (POPT_FOUND)
add_subdirectory(tools)
else ()
message(WARNING "POpt library was not found. Tools will not be built")
endif ()
endif ()
if (BUILD_TESTS)
if (NOT BUILD_STATIC_LIBS)
message(FATAL_ERROR
"Tests can only be built against static libraries "
"(set BUILD_STATIC_LIBS=ON)")
endif ()
enable_testing()
add_subdirectory(tests)
endif (BUILD_TESTS)
if (BUILD_API_DOCS)
if (NOT DOXYGEN_FOUND)
message(FATAL_ERROR "Doxygen is required to build the API documentation")
endif ()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile @ONLY)
add_custom_target(docs
COMMAND ${DOXYGEN_EXECUTABLE}
VERBATIM
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docs
DEPENDS rabbitmq
COMMENT "Generating API documentation"
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in
)
endif ()
set(libs_private ${SOCKET_LIBRARIES} ${LIBRT})
if (ENABLE_SSL_SUPPORT)
if (SSL_ENGINE STREQUAL "OpenSSL")
set(requires_private "openssl")
endif()
if (ENABLE_THREAD_SAFETY)
set(libs_private ${libs_private} ${CMAKE_THREAD_LIBS_INIT})
endif()
endif()
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix "\${prefix}")
set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
configure_file(cmake/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq/config.h)
configure_file(librabbitmq.pc.in ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq.pc @ONLY)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/librabbitmq.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
)
if (BUILD_SHARED_LIBS)
message(STATUS "Building rabbitmq as a shared library - yes")
else ()
message(STATUS "Building rabbitmq as a shared library - no")
endif ()
if (BUILD_STATIC_LIBS)
message(STATUS "Building rabbitmq as a static library - yes")
else ()
message(STATUS "Building rabbitmq as a static library - no")
endif ()
rabbitmq-c-0.8.0/CONTRIBUTING.md 0000664 0000000 0000000 00000001624 12702357234 0016001 0 ustar 00root root 0000000 0000000 Contributing to rabbitmq-c
==========================
Thanks for contributing to rabbitmq-c. I firmly believe that participation helps
make open source software great. With that there are a few things that can be
done to make our interaction a bit smoother.
Please use the following guidelines when creating an issue or submitting a
pull request
Creating an issue
-----------------
When submitting an issue its helpful to know the following
- What version of rabbitmq-c are you using?
- What operating system and version are you running on?
- What compiler and version are you running?
-
- If its a build system issue: which build system are you using (
Submitting a pull-request
-------------------------
I love to get code contributions, a few things that can help out:
- Make sure your commits are rebased on the current master branch
- Please collapse your commits down to a couple logical commits
rabbitmq-c-0.8.0/ChangeLog.md 0000664 0000000 0000000 00000022371 12702357234 0015723 0 ustar 00root root 0000000 0000000 # Change Log
## v0.8.0 - 2016-04-09
### Added:
- SSL: peer certificate and hostname validation can now be controlled separately
using `amqp_ssl_socket_set_verify_peer` and
`amqp_ssl_socket_set_verify_hostname`.
- SSL: the desire SSL version range can now be specified using the
`amqp_ssl_socket_set_ssl_versions` function.
- Add flags to SSL examples on controlling hostname verification.
### Changed:
- SSL: SSLv2, and SSLv3 have been disabled by default.
- SSL: OpenSSL hostname validation has been improved.
- Win32 debug information is built with /Z7 on MSVC to embed debug info instead
of using a .pdb
### Fixed:
- Connection failure results in hang on Win32 (#297, #346)
- Rabbitmq-c may block when attempting to close an SSL socket (#313)
- amqp_parse_url does not correctly initialize default parameters (#319)
- x509 objects are leaked in verify_hostname (#323)
- TCP_NOPUSH doesn't work under cygwin (#335)
### Deprecated
- SSL: `amqp_ssl_socket_set_verify` is being replaced by
`amqp_ssl_socket_set_verify_peer` and `amqp_ssl_socket_set_verify_hostname`.
### Removed:
- OpenVMS build system and related files.
- Unmaintained PolarSSL, CyaSSL, and gnuTLS SSL backends
## Changes since v0.7.0 (a.k.a., v0.7.1)
- `41fa9df` Autoconf: add missing files in build system
- `ef73c06` Win32: Use WSAEWOULDBLOCK instead of EWOULDBLOCK on Win32
- `ceca348` CI: use travis-ci container based builds
- `393e2df` Lib: if channel_max is 0 use server's channel_max
- `ff47574` Lib: fix build on OpenBSD
- `8429496...0ac6430` CI: enable CI on Mac OS X in travis-ci
## Changes since v0.6.0 (a.k.a., v0.7.0)
- `3379812` Tools: Add support for heartbeats
- `d7029db` CI: Add continuous integration on Win32 using Appveyor
- `a5f7ffb` Tests: only link against static libraries
- `a16ad45...9cf7a3b` Lib: add support for EXTERNAL SASL method
- `038a9ed` Lib: fix incorrect parameters to WSAPoll on Win32
- `a240c69...14ae307` Lib: use non-blocking sockets internally
- `8d1d5cc`, `5498dc6` Lib: simplify timer/timeout logic
- `61fc4e1` Lib: add support for heartbeat checks in blocking send calls
- `f462c0f...3546a70` Lib: Fix warnings on Win32
- `ba9d8ba...112a54d` Lib: Add support for RabbitMQ auth failure extension
- `fb8e318` Lib: allow calling functions to override client-properties
- `3ef3f5f` examples: replace usleep() with nanosleep()
- `9027a94` Lib: add AMQP_VERSION code
- `9ee1718` Lib: fix res maybe returned uninitialized in amqp_merge_capbilities
- `22a36db` Lib: Fix SSL_connection status check
- `abbefd4` Lib: Fix issues with c89 compatiblity
- `2bc1f9b...816cbfc` Lib: perf improvements when sending small messages by
hinting to the OS message boundaries.
- `be2e6dd...784a0e9` Lib: add select()-based timeout implementation
- `91db548...8d77b4c` CI: add ubsan, asan, and tsan CI builds
## Changes since v0.5.2 (a.k.a., v0.6.0)
- `e1746f9` Tools: Enable support for SSL in tools.
- `9626dd5` Lib: ABI CHANGE: enable support for auto_delete, internal flags to
amqp_exchange_declare
- `ee54e27`, `656f833` Lib: check for double-close in SSL/TCP socket impl
- `cf2760d` Lib: allocate struct when method has no field.
- `513ad4a` Lib: add support for SANs in OpenSSL socket impl.
- `5348c69` Lib: add functions to get negotiated frame_max and heartbeat parms.
## Changes since v0.5.1 (a.k.a., v0.5.2)
- `fcdf0f8` Autoconf: check for htonll as declaration in a header file
- `5790ec7` SSL: correctly report hostname verification errors.
- `d60c28c` Build: disable OpenSSL deprecation warnings on OSX
- `072191a` Lib: include platform, version and copyright in AMQP handshake
- `8b448c6` Examples: print message body in amqp[s]_listen[q] examples
- `7188e5d` Tools: Add flag to set prefetch for amqp-consume tool
## Changes since v0.5.0 (a.k.a., v0.5.1)
### Enhancements:
- `a566929` SSL: Add support for wildcards in hostname verification (Mike
Steinert)
- `a78aa8a` Lib: Use poll(2) instead of select(2) for timeouts on sockets.
- `357bdb3` Lib: support for specifying frame and decoding pool sizes. (Mike
Stitt)
- `8956003` Lib: improve invalid frame detection code.
### Bug fixes:
- `b852f84` Lib: Add missing amqp_get_server_properties() function.
- `7001e82` Lib: Add missing ssize_t on Win32 (emazv72)
- `c2ce2cb` Lib: Correctly specify WINVER on Win32 when unspecified.
- `fe844e4` CMake: specify -DHAVE_CONFIG_H in examples.
- `932de5f` Lib: correct time computation on Win32 (jestor)
- `3e83192` HPUX: use gethrtime on HP-UX for timers.
- `cb1b44e` HPUX: correct include location of sys/uio.h
- `8ce585d` Lib: incorrect OOM condition when 0-lenth exchange name is received.
- `c7716b8` CMake: correct htonll detection code on platforms defined with a
macro.
- `4dc4eda` Lib: remove unused assignment.
- `45302cf` Lib: remove range-check of channel-ids.
## Changes since v0.4.1 (a.k.a., v0.5.0):
### Major changes:
- Add amqp_get_broker_properties() function 5c7c40adc1
- Remove distro-specific packaging a5749657ee
- Add -x flag to amqp-consume utilty 1d9c5291ff
- Add amqp_basic_nack() public API 9b168776fb
- Add delivery mode constants to amqp.h 5f291ea772
- Add support for connection.blocked/connection.unblocked methods ccbc24d270
### Bug fixes:
- `f8c6cee749` Examples: Destroy amqp_envelope_t in consumer example
- `ac88db56d3` CMake: fix generation of librabbitmq.pc
- `d5b35afa40` CMake: fix missing POPT_INCLUDE_DIRS variable in tools/
- `5ea6a0945a` build: provide independent locations for x64 libs
- `fac34656c0` Doc: documentation fixes
- `715901d675` Lib: Correct OpenSSL initialization under threaded conditions
- `ce64e57df8` Examples: Handle unexpected frames in amqp_consumer.c
- `bcda3e933d` CMake: Use GnuInstallDirs to generate install dirs
- `27245a4e15` Lib: correctly handle amqp_get_monotonic_timestamp on win32
- `693662ef5b` Tools: honor --persistent flag in publish utility
- `01d9c3ca60` Doc: improve documentation in amqp_ssl_socket functions
- `02d5c58ae4` autoconf: correct librabbitmq.pc generation
- `1f4e0cc48b` Doc: improve documentation in amqp_tcp_socket functions
## Changes since v0.4.0:
### Major changes:
- Removed distro-specific packaging d285d01
### Bug fixes:
- `a642602` FIX: destroy amqp_envelop_t object in consumer example
- `860dd71` FIX: correct generation of librabbitmq.pc under CMake
- `bdda7ab` FIX: amqp_socket_close() should not be exported from shlib
- `24f4131` FIX: Use correct buf/len vars when re-starting send()
## Changes since v0.3.0:
### New Features/Enhancements:
- `amqp_login_with_properties()` function to connect to a broker sending a
properties table to the broker 21b124e #101
- SSL support (Mike Steinert) 473c865 #17
- `amqp_simple_wait_frame_noblock()` function variant to wait for a frame
with a timeout f8cfc72 #119
- Allow memory to be released on a per-channel basis with
`amqp_maybe_release_buffers_on_channel()` 4a2d899 #5
- Support for AMQP heartbeats while blocking in `amqp_simple_wait_frame*()`
and `amqp_basic_publish()` daa0e66 aca5dc1
- `amqp_socket_open_noblock()` for a non-blocking socket connection
(Bogdan Padalko) 6ad770d
- `amqp_table_clone()` to do a deep-copy of an amqp_table_t 08af83a
- Add option to listen to multiple keys in `amqp_consume` tool (Brian Hammond) e6c256d
- Add contributed OpenVMS build system 448ab68
- Higher level APIs for consuming messages 33ebeed #8
- Doxygen-based API documentation.
- Many improvements to error-handling and reporting
### Bug Fixes:
- `24ffaf8` FIX: autotools was broken when dependency-tracking was disabled
- `38e741b` FIX: CMake XmlTo not found warning
- `906f04f` FIX: htonll redeclared on Win32 v8
- `8e41603` FIX: SIGPIPE not disabled on OS X/BSD #102
- `872ea49` FIX: Header issues with amqp.h on Mingw on Win32 (yoniyoni)
- `0f1f75b` FIX: potential memory leak in amqp_new_connection
- `c9f6312` FIX: missing va_end in `amqp_login()`/`amqp_login_with_properties()`
- `7bb64e4` FIX: include amqp_tcp_socket.h in dpkg (Tim Stewart)
- `ba9d1f5` FIX: Report out of buffer space in `amqp_table_encode()`
- `9496e10` FIX: Remove `abort()` on invalid parameter in `amqp_send_frame()`
- `f209420` FIX: Remote `abort()` in `amqp_simple_wait_method()`
- `f027518` FIX: Return error on socket lib init error
- `0ae534a` FIX: Correctly handle 0 return val from `SSL_read()`/`SSL_write()`
- `22e41b8` FIX: Improve error handling in socket functions
- `33c2353` FIX: Set state->socket to NULL after `amqp_socket_close()`
- `c83e728` FIX: Incorrect error code returned
- `1a19879` FIX: redecl of int i in `amqp_tcp_socket_writev()`
- `7477449` FIX: incorrect bit-shift in `amqp_error_string2()`
- `2e37bb3` FIX: correctly handle `amqp_get_sockfd()` in `amqp_simple_wait_frame()`
- `52a459b` FIX: Don't delete state in `amqp_tune_connection()` on error
- `01e38dd` FIX: Correctly handle `mach_timebase_info()` failure
- `34bffb7` FIX: Correctly disable `SIGPIPE` on platforms with `SO_NOSIGPIPE`
- `3866433` FIX: Use correct number of bits in timer precision on MacOSX
- `b6a1dfe` FIX: Squash OpenSSL deprecated warnings on MacOSX (Bogdan Padalko)
- `7a217d5` FIX: Incorrect `assert()` in `wait_frame_inner()`
- `7942af3` FIX: Correctly handle 0-length table in `amqp_table_clone()`
- `157788e` FIX: Correctly handle 0-length strings in `amqp_basic_properties_clone()`
- `4eaf771` FIX: Correctly handle 0-length message body in `amqp_read_message()`
- `59f943b` FIX: Double-free SSL on connection failure
- `7a451a4` FIX: `amqp_open_socket()` not defined
rabbitmq-c-0.8.0/LICENSE-MIT 0000664 0000000 0000000 00000002470 12702357234 0015204 0 ustar 00root root 0000000 0000000 Portions created by Alan Antonuk are Copyright (c) 2012-2013
Alan Antonuk. All Rights Reserved.
Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
All Rights Reserved.
Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
rabbitmq-c-0.8.0/Makefile.am 0000664 0000000 0000000 00000024175 12702357234 0015612 0 ustar 00root root 0000000 0000000 # vim:set ts=2 sw=2 sts=2 noet:
ACLOCAL_AMFLAGS = -I m4
AM_CFLAGS = -I$(top_srcdir)/librabbitmq
lib_LTLIBRARIES = librabbitmq/librabbitmq.la
librabbitmq_librabbitmq_la_CFLAGS = \
$(SSL_CFLAGS) \
$(AM_CFLAGS)
librabbitmq_librabbitmq_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
$(NO_UNDEFINED) \
$(SSL_LIBS)
include_HEADERS = \
librabbitmq/amqp.h \
librabbitmq/amqp_framing.h \
librabbitmq/amqp_tcp_socket.h
if SSL
include_HEADERS += librabbitmq/amqp_ssl_socket.h
endif
librabbitmq_librabbitmq_la_SOURCES = \
librabbitmq/amqp_api.c \
librabbitmq/amqp_connection.c \
librabbitmq/amqp_consumer.c \
librabbitmq/amqp_framing.c \
librabbitmq/amqp_mem.c \
librabbitmq/amqp_private.h \
librabbitmq/amqp_socket.c \
librabbitmq/amqp_socket.h \
librabbitmq/amqp_table.c \
librabbitmq/amqp_table.h \
librabbitmq/amqp_tcp_socket.c \
librabbitmq/amqp_tcp_socket.h \
librabbitmq/amqp_time.c \
librabbitmq/amqp_time.h \
librabbitmq/amqp_url.c
if SSL_OPENSSL
librabbitmq_librabbitmq_la_SOURCES += \
librabbitmq/amqp_hostcheck.c \
librabbitmq/amqp_hostcheck.h \
librabbitmq/amqp_openssl.c \
librabbitmq/amqp_openssl_hostname_validation.c \
librabbitmq/amqp_openssl_hostname_validation.h
if OS_APPLE
librabbitmq_librabbitmq_la_CFLAGS += -Wno-deprecated-declarations
endif
endif
if OS_UNIX
librabbitmq_librabbitmq_la_SOURCES += librabbitmq/unix/threads.h
librabbitmq_librabbitmq_la_CFLAGS += -I$(top_srcdir)/librabbitmq/unix
endif
if OS_WIN32
librabbitmq_librabbitmq_la_SOURCES += librabbitmq/win32/threads.h
librabbitmq_librabbitmq_la_CFLAGS += \
-I$(top_srcdir)/librabbitmq/win32 \
-I$(top_srcdir)/librabbitmq/win32/msinttypes
endif
check_PROGRAMS = \
tests/test_tables \
tests/test_parse_url \
tests/test_hostcheck \
tests/test_status_enum \
tests/test_sasl_mechanism \
tests/test_merge_capabilities
TESTS = $(check_PROGRAMS)
tests_test_tables_SOURCES = tests/test_tables.c
tests_test_tables_LDADD = librabbitmq/librabbitmq.a
tests_test_parse_url_SOURCES = tests/test_parse_url.c
tests_test_parse_url_LDADD = librabbitmq/librabbitmq.a
tests_test_hostcheck_SOURCES = \
tests/test_hostcheck.c \
librabbitmq/amqp_hostcheck.c
tests_test_status_enum_SOURCES = tests/test_status_enum.c
tests_test_status_enum_LDADD = librabbitmq/librabbitmq.a
tests_test_sasl_mechanism_SOURCES = tests/test_sasl_mechanism.c
tests_test_sasl_mechanism_LDADD = librabbitmq/librabbitmq.a
tests_test_merge_capabilities_SOURCES = tests/test_merge_capabilities.c
tests_test_merge_capabilities_LDADD = librabbitmq/librabbitmq.a
noinst_LTLIBRARIES =
if EXAMPLES
noinst_LTLIBRARIES += examples/libutils.la
examples_libutils_la_SOURCES = \
examples/utils.c \
examples/utils.h
examples_libutils_la_CFLAGS = $(AM_CFLAGS)
if OS_UNIX
examples_libutils_la_SOURCES += examples/unix/platform_utils.c
endif
if OS_WIN32
examples_libutils_la_SOURCES += examples/win32/platform_utils.c
examples_libutils_la_CFLAGS += -I$(top_srcdir)/tools/win32/msinttypes
endif
noinst_PROGRAMS = \
examples/amqp_bind \
examples/amqp_consumer \
examples/amqp_connect_timeout \
examples/amqp_exchange_declare \
examples/amqp_listen \
examples/amqp_listenq \
examples/amqp_producer \
examples/amqp_rpc_sendstring_client \
examples/amqp_sendstring \
examples/amqp_unbind
examples_amqp_sendstring_SOURCES = examples/amqp_sendstring.c
examples_amqp_sendstring_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqp_exchange_declare_SOURCES = examples/amqp_exchange_declare.c
examples_amqp_exchange_declare_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqp_listen_SOURCES = examples/amqp_listen.c
examples_amqp_listen_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqp_producer_SOURCES = examples/amqp_producer.c
examples_amqp_producer_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqp_consumer_SOURCES = examples/amqp_consumer.c
examples_amqp_consumer_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqp_connect_timeout_SOURCES = examples/amqp_connect_timeout.c
examples_amqp_connect_timeout_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqp_unbind_SOURCES = examples/amqp_unbind.c
examples_amqp_unbind_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqp_bind_SOURCES = examples/amqp_bind.c
examples_amqp_bind_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqp_listenq_SOURCES = examples/amqp_listenq.c
examples_amqp_listenq_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqp_rpc_sendstring_client_SOURCES = \
examples/amqp_rpc_sendstring_client.c
examples_amqp_rpc_sendstring_client_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
if SSL
noinst_PROGRAMS += \
examples/amqps_bind \
examples/amqps_connect_timeout \
examples/amqps_consumer \
examples/amqps_exchange_declare \
examples/amqps_listen \
examples/amqps_listenq \
examples/amqps_producer \
examples/amqps_sendstring \
examples/amqps_unbind
examples_amqps_bind_SOURCES = examples/amqps_bind.c
examples_amqps_bind_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqps_connect_timeout_SOURCES = examples/amqps_connect_timeout.c
examples_amqps_connect_timeout_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqps_consumer_SOURCES = examples/amqps_consumer.c
examples_amqps_consumer_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqps_exchange_declare_SOURCES = examples/amqps_exchange_declare.c
examples_amqps_exchange_declare_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqps_listen_SOURCES = examples/amqps_listen.c
examples_amqps_listen_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqps_listenq_SOURCES = examples/amqps_listenq.c
examples_amqps_listenq_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqps_producer_SOURCES = examples/amqps_producer.c
examples_amqps_producer_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqps_sendstring_SOURCES = examples/amqps_sendstring.c
examples_amqps_sendstring_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
examples_amqps_unbind_SOURCES = examples/amqps_unbind.c
examples_amqps_unbind_LDADD = \
examples/libutils.la \
librabbitmq/librabbitmq.la
endif
endif
if TOOLS
noinst_LTLIBRARIES += tools/libcommon.la
tools_libcommon_la_SOURCES = \
tools/common.c \
tools/common.h
tools_libcommon_la_CFLAGS = \
$(AM_CFLAGS) \
-I$(top_srcdir)/tools
tools_platform_CFLAGS = $(AM_CFLAGS)
if OS_UNIX
tools_libcommon_la_SOURCES += \
tools/unix/process.c \
tools/unix/process.h
tools_platform_CFLAGS += -I$(top_srcdir)/tools/unix
endif
if OS_WIN32
tools_libcommon_la_SOURCES += \
tools/win32/compat.c \
tools/win32/compat.h \
tools/win32/process.c \
tools/win32/process.h
tools_platform_CFLAGS += \
-I$(top_srcdir)/tools/win32 \
-I$(top_srcdir)/tools/win32/msinttypes
endif
bin_PROGRAMS = \
tools/amqp-consume \
tools/amqp-declare-queue \
tools/amqp-delete-queue \
tools/amqp-get \
tools/amqp-publish
tools_amqp_publish_SOURCES = tools/publish.c
tools_amqp_publish_CFLAGS = \
$(AM_CFLAGS) \
$(POPT_CFLAGS) \
$(tools_platform_CFLAGS) \
-I$(top_srcdir)/tools
tools_amqp_publish_LDADD = \
$(POPT_LIBS) \
tools/libcommon.la \
librabbitmq/librabbitmq.la
tools_amqp_get_SOURCES = tools/get.c
tools_amqp_get_CFLAGS = \
$(AM_CFLAGS) \
$(POPT_CFLAGS) \
$(tools_platform_CFLAGS) \
-I$(top_srcdir)/tools
tools_amqp_get_LDADD = \
$(POPT_LIBS) \
tools/libcommon.la \
librabbitmq/librabbitmq.la
tools_amqp_consume_SOURCES = tools/consume.c
tools_amqp_consume_CFLAGS = \
$(AM_CFLAGS) \
$(POPT_CFLAGS) \
$(tools_platform_CFLAGS) \
-I$(top_srcdir)/tools
tools_amqp_consume_LDADD = \
$(POPT_LIBS) \
tools/libcommon.la \
librabbitmq/librabbitmq.la
tools_amqp_declare_queue_SOURCES = tools/declare_queue.c
tools_amqp_declare_queue_CFLAGS = \
$(AM_CFLAGS) \
$(POPT_CFLAGS) \
$(tools_platform_CFLAGS) \
-I$(top_srcdir)/tools
tools_amqp_declare_queue_LDADD = \
$(POPT_LIBS) \
tools/libcommon.la \
librabbitmq/librabbitmq.la
tools_amqp_delete_queue_SOURCES = tools/delete_queue.c
tools_amqp_delete_queue_CFLAGS = \
$(AM_CFLAGS) \
$(POPT_CFLAGS) \
$(tools_platform_CFLAGS) \
-I$(top_srcdir)/tools
tools_amqp_delete_queue_LDADD = \
$(POPT_LIBS) \
tools/libcommon.la \
librabbitmq/librabbitmq.la
if DOCS
man_MANS = \
$(top_builddir)/tools/doc/amqp-publish.1 \
$(top_builddir)/tools/doc/amqp-consume.1 \
$(top_builddir)/tools/doc/amqp-get.1 \
$(top_builddir)/tools/doc/amqp-declare-queue.1 \
$(top_builddir)/tools/doc/amqp-delete-queue.1 \
$(top_builddir)/tools/doc/librabbitmq-tools.7
# xmlto's --searchpath doesn't get passed through to xmllint, so we disable
# xmllint validation with --skip-validation for the benefit of build/source
# separation as required by distcheck, debian packaging etc.
XMLTO_FLAGS = \
--skip-validation \
--searchpath $(abs_top_builddir)/tools/doc
%.1: %.xml $(top_builddir)/tools/doc/man-date.ent
$(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) -o $(top_builddir)/tools/doc man $<
%.7: %.xml $(top_builddir)/tools/doc/man-date.ent
$(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) -o $(top_builddir)/tools/doc man $<
$(top_builddir)/tools/doc/man-date.ent:
$(AM_V_at)$(MKDIR_P) $(top_builddir)/tools/doc
$(AM_V_GEN)date +'%Y-%m-%d' > $@
endif # DOCS
endif # TOOLS
EXTRA_DIST = \
AUTHORS \
CMakeLists.txt \
CONTRIBUTING.md \
ChangeLog.md \
LICENSE-MIT \
README-win32.md \
README.md \
README.vms \
THANKS \
TODO \
cmake \
codegen \
descrip.mms \
docs \
examples/CMakeLists.txt \
examples/descrip.mms \
librabbitmq/CMakeLists.txt \
librabbitmq/codegen.py \
librabbitmq/descrip.mms \
librabbitmq/win32 \
tests/CMakeLists.txt \
tests/test_tables.expected \
tests/win32 \
tools/CMakeLists.txt \
tools/doc/amqp-consume.xml \
tools/doc/amqp-declare-queue.xml \
tools/doc/amqp-delete-queue.xml \
tools/doc/amqp-get.xml \
tools/doc/amqp-publish.xml \
tools/doc/librabbitmq-tools.xml \
vms
MOSTLYCLEANFILES = \
$(man_MANS) \
$(top_builddir)/tools/doc/man-date.ent
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = librabbitmq.pc
clean-local:
-$(MAKE) -C codegen clean
distclean-local:
-$(MAKE) -C codegen distclean
rabbitmq-c-0.8.0/README.md 0000664 0000000 0000000 00000011505 12702357234 0015026 0 ustar 00root root 0000000 0000000 # RabbitMQ C AMQP client library
[](http://travis-ci.org/alanxz/rabbitmq-c)
## Introduction
This is a C-language AMQP client library for use with v2.0+ of the
[RabbitMQ](http://www.rabbitmq.com/) broker.
-
Announcements regarding the library are periodically made on the
rabbitmq-users mailing list:
-
## Latest Stable Version
The latest stable release of rabbitmq-c can be found at:
-
## Documentation
API documentation for v0.8.0+ can viewed from:
## Getting started
### Building and installing
#### Prereqs:
- [CMake v2.6 or better](http://www.cmake.org/)
- A C compiler (GCC 4.4+, clang, and MSVC are test. Other compilers may also
work)
- *Optionally* [OpenSSL](http://www.openssl.org/) v0.9.8+ to enable support for
connecting to RabbitMQ over SSL/TLS
- *Optionally* [POpt](http://freecode.com/projects/popt) to build some handy
command-line tools.
- *Optionally* [XmlTo](https://fedorahosted.org/xmlto/) to build man pages for
the handy command-line tools
- *Optionally* [Doxygen](http://www.stack.nl/~dimitri/doxygen/) to build
developer API documentation.
After downloading and extracting the source from a tarball to a directory.
([see above][Latest Stable Version]), the commands to build rabbitmq-c on most
systems are:
mkdir build && cd build
cmake ..
cmake --build [--config Release] .
The --config Release flag should be used in multi-configuration generators e.g.,
Visual Studio or XCode.
It is also possible to point the CMake GUI tool at the CMakeLists.txt in the root of
the source tree and generate build projects or IDE workspace
Installing the library and optionally specifying a prefix can be done with:
cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
cmake --build . [--config Release] --target install
More information on CMake can be found on its FAQ (http://www.cmake.org/Wiki/CMake_FAQ)
Other interesting flags that can be passed to CMake:
* `BUILD_EXAMPLES=ON/OFF` toggles building the examples. ON by default.
* `BUILD_SHARED_LIBS=ON/OFF` toggles building rabbitmq-c as a shared library.
ON by default.
* `BUILD_STATIC_LIBS=ON/OFF` toggles building rabbitmq-c as a static library.
OFF by default.
* `BUILD_TESTS=ON/OFF` toggles building test code. ON by default.
* `BUILD_TOOLS=ON/OFF` toggles building the command line tools. By default
this is ON if the build system can find the POpt header and library.
* `BUILD_TOOLS_DOCS=ON/OFF` toggles building the man pages for the command line
tools. By default this is ON if BUILD_TOOLS is ON and the build system can
find the XmlTo utility.
* `ENABLE_SSL_SUPPORT=ON/OFF` toggles building rabbitmq-c with SSL support. By
default this is ON if the OpenSSL headers and library can be found.
* `ENABLE_THREAD_SAFETY=ON/OFF` toggles OpenSSL thread-safety. By default this
is ON
* `BUILD_API_DOCS=ON/OFF` - toggles building the Doxygen API documentation, by
default this is OFF
#### autotools
For legacy purposes, a GNU autotools based build system is also maintained. The required
utilities you need are autoconf v2.59+, automake v1.9+, libtool v2.2+, and pkg-config.
Then the standard autotools build procedure will build rabbitmq-c:
autoreconf -i
./configure
make
make install
## Running the examples
Arrange for a RabbitMQ or other AMQP server to be running on
`localhost` at TCP port number 5672.
In one terminal, run
./examples/amqp_listen localhost 5672 amq.direct test
In another terminal,
./examples/amqp_sendstring localhost 5672 amq.direct test "hello world"
You should see output similar to the following in the listener's
terminal window:
Delivery 1, exchange amq.direct routingkey test
Content-type: text/plain
----
00000000: 68 65 6C 6C 6F 20 77 6F : 72 6C 64 hello world
0000000B:
## Writing applications using `librabbitmq`
Please see the `examples` directory for short examples of the use of
the `librabbitmq` library.
### Threading
You cannot share a socket, an `amqp_connection_state_t`, or a channel
between threads using `librabbitmq`. The `librabbitmq` library is
built with event-driven, single-threaded applications in mind, and
does not yet cater to any of the requirements of `pthread`ed
applications.
Your applications instead should open an AMQP connection (and an
associated socket, of course) per thread. If your program needs to
access an AMQP connection or any of its channels from more than one
thread, it is entirely responsible for designing and implementing an
appropriate locking scheme. It will generally be much simpler to have
a connection exclusive to each thread that needs AMQP service.
rabbitmq-c-0.8.0/THANKS 0000664 0000000 0000000 00000000363 12702357234 0014462 0 ustar 00root root 0000000 0000000 Thank-you to the following people for their contributions to the
codebase:
- Scott Brooks / Epic Advertising
- Frank Gönninger
- Daniel Schauenberg
rabbitmq-c-0.8.0/TODO 0000664 0000000 0000000 00000000650 12702357234 0014236 0 ustar 00root root 0000000 0000000 Deal with version-mismatch-header received from the server
Cope with unknown frame types better. Currently it gets horribly
confused about frame lengths.
Make client brutal by default, killing the program on any amqp
error. Only if the user disables this behaviour will the user get to
deal with error conditions themselves. Make use of amqp_rpc_reply
consistent (i.e. universal), and rename it something like amqp_errno.
rabbitmq-c-0.8.0/appveyor.yml 0000664 0000000 0000000 00000001750 12702357234 0016140 0 ustar 00root root 0000000 0000000 # appveyor configuration
version: '{build}'
# Limit history cloned. This matches what travis-CI currently does.
clone_depth: 50
environment:
matrix:
- GENERATOR: Visual Studio 12 Win64
BITS: 64
- GENERATOR: Visual Studio 12
BITS: 32
cache:
- c:\deps -> appveyor.yml
install:
- ps: $file = "Win${env:BITS}OpenSSL-1_0_2g.exe"
- ps: $dir = "c:\deps"
- ps: $exists = Test-Path "$dir\$file"
- ps: >-
If ($exists -ne $True) {
Write-Host "Downloading: $dir\$file."
New-Item -Path $dir -type directory -force
Start-FileDownload "http://slproweb.com/download/$file" -FileName "$dir\$file"
} Else {
Write-Host "Reusing cached: $dir\$file."
}
- ps: >-
& "$dir\$file" /silent /verysilent /sp- /suppressmsgboxes /dir="c:\OpenSSL"
before_build:
- cmake -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DBUILD_TESTS=ON -DENABLE_SSL_SUPPORT=True -G"%GENERATOR%" .
build:
project: ALL_BUILD.vcxproj
verbosity: normal
rabbitmq-c-0.8.0/cmake/ 0000775 0000000 0000000 00000000000 12702357234 0014625 5 ustar 00root root 0000000 0000000 rabbitmq-c-0.8.0/cmake/CMakePushCheckState.cmake 0000664 0000000 0000000 00000011434 12702357234 0021411 0 ustar 00root root 0000000 0000000 # This module defines two macros:
# CMAKE_PUSH_CHECK_STATE()
# and
# CMAKE_POP_CHECK_STATE()
# These two macros can be used to save and restore the state of the variables
# CMAKE_REQUIRED_FLAGS, CMAKE_REQUIRED_DEFINITIONS, CMAKE_REQUIRED_LIBRARIES
# and CMAKE_REQUIRED_INCLUDES used by the various Check-files coming with CMake,
# like e.g. check_function_exists() etc.
# The variable contents are pushed on a stack, pushing multiple times is supported.
# This is useful e.g. when executing such tests in a Find-module, where they have to be set,
# but after the Find-module has been executed they should have the same value
# as they had before.
#
# Usage:
# cmake_push_check_state()
# set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -DSOME_MORE_DEF)
# check_function_exists(...)
# cmake_pop_check_state()
#=============================================================================
# Copyright 2006-2011 Alexander Neundorf,
#
# 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 names of Kitware, Inc., the Insight Software Consortium,
# nor the names of their 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
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# ------------------------------------------------------------------------------
#
# The above copyright and license notice applies to distributions of
# CMake in source and binary form. Some source files contain additional
# notices of original copyright by their contributors; see each source
# for details. Third-party software packages supplied with CMake under
# compatible licenses provide their own copyright notices documented in
# corresponding subdirectories.
#
# ------------------------------------------------------------------------------
#
# CMake was initially developed by Kitware with the following sponsorship:
#
# * National Library of Medicine at the National Institutes of Health
# as part of the Insight Segmentation and Registration Toolkit (ITK).
#
# * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
# Visualization Initiative.
#
# * National Alliance for Medical Image Computing (NAMIC) is funded by the
# National Institutes of Health through the NIH Roadmap for Medical Research,
# Grant U54 EB005149.
#
# * Kitware, Inc.
macro(CMAKE_PUSH_CHECK_STATE)
if(NOT DEFINED _CMAKE_PUSH_CHECK_STATE_COUNTER)
set(_CMAKE_PUSH_CHECK_STATE_COUNTER 0)
endif()
math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}+1")
set(_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_INCLUDES})
set(_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_DEFINITIONS})
set(_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_LIBRARIES})
set(_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_FLAGS})
endmacro()
macro(CMAKE_POP_CHECK_STATE)
# don't pop more than we pushed
if("${_CMAKE_PUSH_CHECK_STATE_COUNTER}" GREATER "0")
set(CMAKE_REQUIRED_INCLUDES ${_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_DEFINITIONS ${_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_FLAGS ${_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}-1")
endif()
endmacro()
rabbitmq-c-0.8.0/cmake/COPYING-CMAKE-SCRIPTS 0000664 0000000 0000000 00000002456 12702357234 0017632 0 ustar 00root root 0000000 0000000 Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR 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.
rabbitmq-c-0.8.0/cmake/FindPOPT.cmake 0000664 0000000 0000000 00000002023 12702357234 0017207 0 ustar 00root root 0000000 0000000 # vim:set ts=2 sw=2 sts=2 et:
# - Try to find the popt options processing library
# The module will set the following variables
#
# POPT_FOUND - System has popt
# POPT_INCLUDE_DIR - The popt include directory
# POPT_LIBRARY - The libraries needed to use popt
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_search_module(PC_POPT QUIET popt)
endif ()
# Find the include directories
FIND_PATH(POPT_INCLUDE_DIR
NAMES popt.h
HINTS
${PC_POPT_INCLUDEDIR}
${PC_POPT_INCLUDE_DIRS}
DOC "Path containing the popt.h include file"
)
FIND_LIBRARY(POPT_LIBRARY
NAMES popt
HINTS
${PC_POPT_LIBRARYDIR}
${PC_POPT_LIBRARY_DIRS}
DOC "popt library path"
)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(POPT
REQUIRED_VARS POPT_INCLUDE_DIR POPT_LIBRARY
VERSION_VAR PC_POPT_VERSION)
MARK_AS_ADVANCED(POPT_INCLUDE_DIR POPT_LIBRARY)
rabbitmq-c-0.8.0/cmake/FindXmlTo.cmake 0000664 0000000 0000000 00000006201 12702357234 0017472 0 ustar 00root root 0000000 0000000 # vim:set ts=2 sw=2 sts=2 et:
# - Convert XML docBook files to various formats
# This will convert XML docBook files to various formats like:
# man html txt dvi ps pdf
# macro XMLTO(outfiles infiles... MODES modes...)
find_program ( XMLTO_EXECUTABLE
NAMES xmlto
DOC "path to the xmlto docbook xslt frontend"
)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(XMLTO
REQUIRED_VARS XMLTO_EXECUTABLE)
mark_as_advanced( XMLTO_EXECUTABLE )
macro ( _XMLTO_FILE outfiles mode)
#special settings
set ( XMLTO_FILEEXT_man 1 )
set ( XMLTO_MODE_html xhtml-nochunks )
if ( NOT XMLTO_MODE_${mode})
set ( XMLTO_MODE_${mode} ${mode} )
endif ( NOT XMLTO_MODE_${mode} )
if ( NOT XMLTO_FILEEXT_${mode} )
set ( XMLTO_FILEEXT_${mode} ${mode} )
endif ( NOT XMLTO_FILEEXT_${mode} )
foreach ( dbFile ${ARGN} )
#TODO: set XMLTO_FILEEXT_man to value from
if ( "${mode}" STREQUAL "man" )
file ( READ "${dbFile}" _DB_FILE_CONTENTS )
string ( REGEX MATCH "[^<]*" XMLTO_FILEEXT_${mode} "${_DB_FILE_CONTENTS}" )
string ( REGEX REPLACE "^" "" XMLTO_FILEEXT_${mode} "${XMLTO_FILEEXT_${mode}}" )
string ( REGEX REPLACE "[[:space:]]" "" XMLTO_FILEEXT_${mode} "${XMLTO_FILEEXT_${mode}}" )
endif ( "${mode}" STREQUAL "man" )
get_filename_component ( dbFilePath ${CMAKE_CURRENT_BINARY_DIR}/${dbFile} PATH )
get_filename_component ( dbFileWE ${dbFile} NAME_WE )
get_filename_component ( dbFileAbsWE ${dbFilePath}/${dbFileWE} ABSOLUTE )
add_custom_command (
OUTPUT ${dbFileAbsWE}.${XMLTO_FILEEXT_${mode}}
COMMAND ${XMLTO_EXECUTABLE} ${XMLTO_COMMAND_ARGS} -o ${dbFilePath}
${XMLTO_MODE_${mode}} "${CMAKE_CURRENT_SOURCE_DIR}/${dbFile}"
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/${dbFile}
DEPENDS ${XMLTO_DEPENDS}
VERBATIM
)
set ( ${outfiles}
${${outfiles}}
${dbFileAbsWE}.${XMLTO_FILEEXT_${mode}}
)
endforeach ( dbFile )
endmacro ( _XMLTO_FILE outfiles )
macro ( XMLTO )
set ( XMLTO_MODES )
set ( XMLTO_FILES )
set ( XMLTO_HAS_MODES false )
set ( XMLTO_ADD_DEFAULT false )
foreach ( arg ${ARGN} )
if ( ${arg} STREQUAL "MODES" )
set ( XMLTO_HAS_MODES true )
elseif ( ${arg} STREQUAL "ALL" )
set ( XMLTO_ADD_DEFAULT true )
else ( ${arg} STREQUAL "MODES" )
if ( XMLTO_HAS_MODES )
set ( XMLTO_MODES ${XMLTO_MODES} ${arg} )
else ( XMLTO_HAS_MODES )
set ( XMLTO_FILES ${XMLTO_FILES} ${arg} )
endif ( XMLTO_HAS_MODES )
endif ( ${arg} STREQUAL "MODES" )
endforeach ( arg ${ARGN} )
if ( NOT XMLTO_MODES )
set ( XMLTO_MODES html )
endif ( NOT XMLTO_MODES )
foreach ( mode ${XMLTO_MODES} )
_xmlto_file ( XMLTO_FILES_${mode} ${mode} ${XMLTO_FILES} )
if ( XMLTO_ADD_DEFAULT )
add_custom_target ( ${mode} ALL
DEPENDS ${XMLTO_FILES_${mode}}
VERBATIM
)
else ( XMLTO_ADD_DEFAULT )
add_custom_target ( ${mode}
DEPENDS ${XMLTO_FILES_${mode}}
VERBATIM
)
endif ( XMLTO_ADD_DEFAULT )
endforeach ( mode )
set ( XMLTO_MODES )
set ( XMLTO_FILES )
endmacro ( XMLTO )
rabbitmq-c-0.8.0/cmake/GNUInstallDirs.cmake 0000664 0000000 0000000 00000016425 12702357234 0020441 0 ustar 00root root 0000000 0000000 #.rst:
# GNUInstallDirs
# --------------
#
# Define GNU standard installation directories
#
# Provides install directory variables as defined for GNU software:
#
# ::
#
# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
#
# Inclusion of this module defines the following variables:
#
# ::
#
# CMAKE_INSTALL_ - destination for files of a given type
# CMAKE_INSTALL_FULL_ - corresponding absolute path
#
# where is one of:
#
# ::
#
# BINDIR - user executables (bin)
# SBINDIR - system admin executables (sbin)
# LIBEXECDIR - program executables (libexec)
# SYSCONFDIR - read-only single-machine data (etc)
# SHAREDSTATEDIR - modifiable architecture-independent data (com)
# LOCALSTATEDIR - modifiable single-machine data (var)
# LIBDIR - object code libraries (lib or lib64 or lib/ on Debian)
# INCLUDEDIR - C header files (include)
# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
# DATAROOTDIR - read-only architecture-independent data root (share)
# DATADIR - read-only architecture-independent data (DATAROOTDIR)
# INFODIR - info documentation (DATAROOTDIR/info)
# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
# MANDIR - man documentation (DATAROOTDIR/man)
# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
#
# Each CMAKE_INSTALL_ value may be passed to the DESTINATION
# options of install() commands for the corresponding file type. If the
# includer does not define a value the above-shown default will be used
# and the value will appear in the cache for editing by the user. Each
# CMAKE_INSTALL_FULL_ value contains an absolute path constructed
# from the corresponding destination by prepending (if necessary) the
# value of CMAKE_INSTALL_PREFIX.
#=============================================================================
# Copyright 2011 Nikita Krupen'ko
# Copyright 2011 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
# Installation directories
#
if(NOT DEFINED CMAKE_INSTALL_BINDIR)
set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)")
endif()
if(NOT DEFINED CMAKE_INSTALL_SBINDIR)
set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR)
set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)")
endif()
if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)")
endif()
if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR)
set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
set(_LIBDIR_DEFAULT "lib")
# Override this default 'lib' with 'lib64' iff:
# - we are on Linux system but NOT cross-compiling
# - we are NOT on debian
# - we are on a 64 bits system
# reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
# For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if
# CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu"
# See http://wiki.debian.org/Multiarch
if(CMAKE_SYSTEM_NAME MATCHES "Linux"
AND NOT CMAKE_CROSSCOMPILING)
if (EXISTS "/etc/debian_version") # is this a debian system ?
if(CMAKE_LIBRARY_ARCHITECTURE)
set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
endif()
else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
message(AUTHOR_WARNING
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
"Please enable at least one language before including GNUInstallDirs.")
else()
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(_LIBDIR_DEFAULT "lib64")
endif()
endif()
endif()
endif()
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
endif()
if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
endif()
if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR)
set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)")
endif()
if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR)
set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)")
endif()
#-----------------------------------------------------------------------------
# Values whose defaults are relative to DATAROOTDIR. Store empty values in
# the cache and store the defaults in local variables if the cache values are
# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes.
if(NOT CMAKE_INSTALL_DATADIR)
set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)")
set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}")
endif()
if(NOT CMAKE_INSTALL_INFODIR)
set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)")
set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info")
endif()
if(NOT CMAKE_INSTALL_LOCALEDIR)
set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)")
set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale")
endif()
if(NOT CMAKE_INSTALL_MANDIR)
set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)")
set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man")
endif()
if(NOT CMAKE_INSTALL_DOCDIR)
set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)")
set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}")
endif()
#-----------------------------------------------------------------------------
mark_as_advanced(
CMAKE_INSTALL_BINDIR
CMAKE_INSTALL_SBINDIR
CMAKE_INSTALL_LIBEXECDIR
CMAKE_INSTALL_SYSCONFDIR
CMAKE_INSTALL_SHAREDSTATEDIR
CMAKE_INSTALL_LOCALSTATEDIR
CMAKE_INSTALL_LIBDIR
CMAKE_INSTALL_INCLUDEDIR
CMAKE_INSTALL_OLDINCLUDEDIR
CMAKE_INSTALL_DATAROOTDIR
CMAKE_INSTALL_DATADIR
CMAKE_INSTALL_INFODIR
CMAKE_INSTALL_LOCALEDIR
CMAKE_INSTALL_MANDIR
CMAKE_INSTALL_DOCDIR
)
# Result directories
#
foreach(dir
BINDIR
SBINDIR
LIBEXECDIR
SYSCONFDIR
SHAREDSTATEDIR
LOCALSTATEDIR
LIBDIR
INCLUDEDIR
OLDINCLUDEDIR
DATAROOTDIR
DATADIR
INFODIR
LOCALEDIR
MANDIR
DOCDIR
)
if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
else()
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
endif()
endforeach()
rabbitmq-c-0.8.0/cmake/TestCInline.cmake 0000664 0000000 0000000 00000001727 12702357234 0020017 0 ustar 00root root 0000000 0000000 # vim:set ts=2 sw=2 sts=2 et:
#Inspired from http://www.cmake.org/Wiki/CMakeTestInline
IF(NOT DEFINED C_INLINE_KEYWORD)
SET(INLINE_TEST_SRC "/* Inspired by autoconf's c.m4 */
static inline int static_foo() {return 0\;}
int main(int argc, char *argv[]){return 0\;}
")
FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/CMakeTestCInline.c ${INLINE_TEST_SRC})
FOREACH(KEYWORD "inline" "__inline__" "__inline")
IF(NOT DEFINED C_INLINE)
TRY_COMPILE(C_HAS_${KEYWORD}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/CMakeTestCInline.c
COMPILE_DEFINITIONS "-Dinline=${KEYWORD}"
)
IF(C_HAS_${KEYWORD})
SET(C_INLINE ${KEYWORD})
ENDIF(C_HAS_${KEYWORD})
ENDIF(NOT DEFINED C_INLINE)
ENDFOREACH(KEYWORD)
SET(C_INLINE_KEYWORD ${C_INLINE} CACHE INTERNAL "The keyword needed by the C compiler to inline a function" FORCE)
message(STATUS "Found C inline keyword: ${C_INLINE_KEYWORD}")
ENDIF(NOT DEFINED C_INLINE_KEYWORD)
rabbitmq-c-0.8.0/cmake/config.h.in 0000664 0000000 0000000 00000000433 12702357234 0016650 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
#ifndef CONFIG_H
#define CONFIG_H
#ifndef __cplusplus
# define inline ${C_INLINE_KEYWORD}
#endif
#cmakedefine HAVE_HTONLL
#cmakedefine HAVE_SELECT
#cmakedefine HAVE_POLL
#define AMQ_PLATFORM "@CMAKE_SYSTEM@"
#endif /* CONFIG_H */
rabbitmq-c-0.8.0/codegen/ 0000775 0000000 0000000 00000000000 12702357234 0015151 5 ustar 00root root 0000000 0000000 rabbitmq-c-0.8.0/configure.ac 0000664 0000000 0000000 00000015617 12702357234 0016045 0 ustar 00root root 0000000 0000000 # vim:set ts=2 sw=2 sts=2 et:
AC_PREREQ([2.59])
m4_define([major_version], [0])
m4_define([minor_version], [8])
m4_define([micro_version], [0])
# Follow all steps below in order to calculate new ABI version when updating the library
# NOTE: THIS IS UNRELATED to the actual project version
#
# 1. If the library source code has changed at all since the last update, then increment revision
# 2. If any interfaces have been added, removed, or changed since the last update, increment current and set revision to 0.
# 3. If any interfaces have been added since the last public release, then increment age.
# 4. If any interfaces have been removed since the last public release, then set age to 0.
m4_define([soversion_current], [6])
m4_define([soversion_revision], [0])
m4_define([soversion_age], [2])
AC_INIT([rabbitmq-c], [major_version.minor_version.micro_version],
[https://github.com/alanxz/rabbitmq-c/issues], [rabbitmq-c],
[http://www.rabbitmq.com/])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([1.9 subdir-objects foreign -Wno-portability])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AC_CONFIG_SRCDIR([librabbitmq/amqp.h])
AC_GNU_SOURCE
# Initialize Libtool
LT_PREREQ([2.2])
LT_INIT([disable-static win32-dll])
# Program checks
m4_ifdef([AC_PROG_CC_89], [AC_PROG_CC_89],
[AC_MSG_WARN([Attempt c89 workaround for old versions of autoconf])
AC_PROG_CC
AX_TRY_CFLAGS([-std=gnu90], [AX_CFLAGS([-std=gnu90])])])
PKG_PROG_PKG_CONFIG([0.17])
# Environment setup
AC_CANONICAL_HOST
AC_C_INLINE
# Set compiler flags
AX_TRY_CFLAGS([-Wall], [AX_CFLAGS([-Wall])])
AX_TRY_CFLAGS([-Wextra], [AX_CFLAGS([-Wextra])])
AX_TRY_CFLAGS([-Wstrict-prototypes], [AX_CFLAGS([-Wstrict-prototypes])])
AX_TRY_CFLAGS([-Wno-unused-function], [AX_CFLAGS([-Wno-unused-function])])
AX_TRY_CFLAGS([-fno-common], [AX_CFLAGS([-fno-common])])
AX_TRY_CFLAGS([-fvisibility=hidden], [AX_CFLAGS([-fvisibility=hidden])])
AX_TRY_LDFLAGS([-no-undefined], [NO_UNDEFINED=-no-undefined])
AC_SUBST([NO_UNDEFINED])
# Libtool versioning
LT_CURRENT=soversion_current
LT_REVISION=soversion_revision
LT_AGE=soversion_age
AC_SUBST([LT_CURRENT])
AC_SUBST([LT_REVISION])
AC_SUBST([LT_AGE])
# OS setup
os_unix=no
os_apple=no
os_win32=no
AS_CASE([$host],
[*-*-mingw*],
[os_win32=yes],
[*-apple-darwin*],
[os_apple=yes; os_unix=yes],
[*],
[os_unix=yes])
AM_CONDITIONAL([OS_UNIX], [test "x$os_unix" = xyes])
AM_CONDITIONAL([OS_APPLE], [test "x$os_apple" = xyes])
AM_CONDITIONAL([OS_WIN32], [test "x$os_win32" = xyes])
AC_DEFINE([ENABLE_THREAD_SAFETY], [1], [Define to 1 to enable thread safety])
# Extra Win32 setup
AS_IF([test "x$os_win32" = xyes],
[AC_DEFINE([OS_WIN32], [1], [Define to 1 for Win32.])
AC_DEFINE([AMQP_BUILD], [1], [Define to 1 for a Win32 build.])
AS_IF([test "x$GCC" = xyes],
[AX_LDFLAGS([-lws2_32])],
[AX_LDFLAGS([ws2_32.lib])])
AS_IF([test "x$enable_static" = "xyes"],
[AS_IF([test "x$enable_shared" = "xyes"],
[AC_MSG_ERROR([select one of shared @<:@--enable-shared@:>@ or static @<:@--enable-static@:>@.])],
[AC_DEFINE([AMQP_STATIC], [1],
[Define to 1 for a static Win32 build.])])])])
# Detect which libraries we might need to use socket functions:
# Solaris needs -lsocket -lnsl
# QNX will need -lsocket
AC_SEARCH_LIBS([getaddrinfo], [socket], [],
[AC_CHECK_LIB([getaddrinfo], [socket],
[LIBS="-lsocket -lnsl $LIBS"],
[AC_MSG_ERROR([cannot find name resolution library (library with getaddrinfo symbol)])],
[-lnsl])])
AC_SEARCH_LIBS([socket], [socket], [],
[AC_CHECK_LIB([socket], [socket],
[LIBS="-lsocket -lnsl $LIBS"],
[AC_MSG_ERROR([cannot find socket library (library with socket symbol)])],
[-lnsl])])
AC_SEARCH_LIBS([clock_gettime], [rt])
AC_SEARCH_LIBS([posix_spawnp], [rt])
AC_MSG_CHECKING([if htonll is defined])
dnl # Check for htonll
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[
#include
]],
[[
return htonll(0);
]]
)],
[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_HTONLL, 1, [Define to 1 if the function (or macro) htonll exists.])
],
[
AC_MSG_RESULT(no)
]
)
# Need poll() or select()
AX_HAVE_POLL([AC_DEFINE([HAVE_POLL], [], ["Have poll()"])],
AX_HAVE_SELECT([AC_DEFINE([HAVE_SELECT], [], ["Have select()"])],
[AC_MSG_ERROR([rabbitmq-c needs poll() or select()])]))
# Configure SSL/TLS
AC_ARG_WITH([ssl],
[AS_HELP_STRING([--with-ssl=@<:@no/openssl/yes@:>@],
[enable SSL/TLS support @<:@default=openssl@:>@])],
[AS_CASE([$withval],
[yes], [with_ssl=openssl],
[*], [with_ssl=$withval])],
[with_ssl=openssl])
AS_IF([test "x$with_ssl" = "xopenssl"],
[PKG_CHECK_MODULES([SSL], [openssl >= 0.9.8], [ssl_pkg_required=openssl],
[with_ssl=no])],
[test "x$with_ssl" = "xno"],,
[AC_MSG_ERROR([unknown SSL/TLS implementation: $with_ssl])])
AM_CONDITIONAL([SSL_OPENSSL], [test "x$with_ssl" = "xopenssl"])
AM_CONDITIONAL([SSL], [test "x$with_ssl" != "xno"])
AS_IF([test "x$with_ssl" != "xno"],
[AC_DEFINE([WITH_SSL], [1], [Define to 1 if SSL/TLS is enabled.])])
# Configure AMQP command-line tools
AC_ARG_ENABLE([tools],
[AS_HELP_STRING([--enable-tools],
[build AMQP command-line tools @<:@auto@:>@])],,
[enable_tools=auto])
AS_IF([test "x$enable_tools" != "xno"],
[AX_LIB_POPT([enable_tools=yes], [enable_tools=no])])
AM_CONDITIONAL([TOOLS], [test "x$enable_tools" = "xyes"])
# Configure command-line tool documentation
AC_ARG_ENABLE([docs],
[AS_HELP_STRING([--enable-docs],
[build command-line tool documentation @<:@auto@:>@])],,
[AS_IF([test "x$enable_tools" = "xno"],
[enable_docs=no],
[enable_docs=auto])])
AC_ARG_VAR([XMLTO], [xmlto command])
AS_IF([test "x$enable_docs" != "xno"],
[AS_IF([test "x$XMLTO" = "x"],
[AC_CHECK_PROGS([XMLTO], [xmlto])])
AS_IF([test "x$XMLTO" != "x"],
[enable_docs=yes],
[enable_docs=no])])
AM_CONDITIONAL([DOCS], [test "x$enable_docs" = "xyes"])
# Configure examples
AC_ARG_ENABLE([examples],
[AS_HELP_STRING([--enable-examples],
[build example code @<:@auto@:>@])],,
[enable_examples=yes])
AM_CONDITIONAL([EXAMPLES], [test "x$enable_examples" = "xyes"])
AC_SUBST([requires_private], [$ssl_pkg_required])
AC_SUBST([libs_private], [$LIBS])
AC_DEFINE_UNQUOTED([AMQ_PLATFORM], ["$host_os"], [Host operating system string])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
librabbitmq.pc
Makefile
])
AC_OUTPUT
AC_MSG_RESULT([
$PACKAGE_NAME build options:
Host: $host
Version: $VERSION
SSL/TLS: $with_ssl
Tools: $enable_tools
Documentation: $enable_docs
Examples: $enable_examples
])
rabbitmq-c-0.8.0/coverity/ 0000775 0000000 0000000 00000000000 12702357234 0015411 5 ustar 00root root 0000000 0000000 rabbitmq-c-0.8.0/coverity/model.c 0000664 0000000 0000000 00000001217 12702357234 0016656 0 ustar 00root root 0000000 0000000 /* Functions to help coverity do static analysis on rabbitmq-c */
typedef struct {} amqp_rpc_reply_t;
/* librabbitmq/amqp_private.h */
void amqp_abort(const char *fmt, ...) { __coverity_panic__(); }
/* tools/common.h */
void die(const char* fmt, ...) { __coverity_panic__(); }
void die_errno(int err, const char* fmt, ...) { __coverity_panic__(); }
void die_amqp_error(int err, const char* fmt, ...) { __coverity_panic__(); }
void die_rpc(amqp_rpc_reply_t r, const char* fmt, ...) { __coverity_panic__(); }
/* examples/utils.h */
void die_on_amqp_error(amqp_rpc_reply_t *r) { __coverity_panic__(); }
void die_on_error(int r) { __coverity_panic__(); }
rabbitmq-c-0.8.0/docs/ 0000775 0000000 0000000 00000000000 12702357234 0014475 5 ustar 00root root 0000000 0000000 rabbitmq-c-0.8.0/docs/Doxyfile.in 0000664 0000000 0000000 00000026354 12702357234 0016622 0 ustar 00root root 0000000 0000000 # Doxyfile 1.8.4
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = rabbitmq-c
PROJECT_NUMBER = @VERSION@
PROJECT_BRIEF = "C AMQP Client library for RabbitMQ"
PROJECT_LOGO =
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 2
ALIASES =
TCL_SUBST =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
AUTOLINK_SUPPORT = YES
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = YES
LOOKUP_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_PACKAGE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = NO
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = NO
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE =
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = @CMAKE_CURRENT_SOURCE_DIR@/README.md \
@CMAKE_CURRENT_SOURCE_DIR@/ChangeLog.md \
@CMAKE_CURRENT_SOURCE_DIR@/librabbitmq \
@CMAKE_CURRENT_SOURCE_DIR@/docs
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.h \
*.md
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = amqp_private.h \
config.h
EXCLUDE_SYMBOLS =
EXAMPLE_PATH = @CMAKE_CURRENT_SOURCE_DIR@ \
@CMAKE_CURRENT_SOURCE_DIR@/examples
EXAMPLE_PATTERNS = *.c \
*.md
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE = README.md
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX = amqp_
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
HTML_DYNAMIC_SECTIONS = NO
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
GENERATE_TREEVIEW = NO
ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
USE_MATHJAX = NO
MATHJAX_FORMAT = HTML-CSS
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
MATHJAX_EXTENSIONS =
MATHJAX_CODEFILE =
SEARCHENGINE = YES
SERVER_BASED_SEARCH = NO
EXTERNAL_SEARCH = NO
SEARCHENGINE_URL =
SEARCHDATA_FILE = searchdata.xml
EXTERNAL_SEARCH_ID =
EXTRA_SEARCH_MAPPINGS =
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4
EXTRA_PACKAGES =
LATEX_HEADER =
LATEX_FOOTER =
LATEX_EXTRA_FILES =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/librabbitmq \
@CMAKE_CURRENT_BINARY_DIR@/librabbitmq
INCLUDE_FILE_PATTERNS =
PREDEFINED = AMQP_BEGIN_DECLS= \
AMQP_END_DECLS= \
AMQP_PUBLIC_FUNCTION= \
AMQP_PUBLIC_VARIABLE= \
AMQP_CALL= \
AMQP_DEPRECATED(x)=x
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
UML_LIMIT_NUM_FIELDS = 10
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
INTERACTIVE_SVG = NO
DOT_PATH =
DOTFILE_DIRS =
MSCFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
rabbitmq-c-0.8.0/examples/ 0000775 0000000 0000000 00000000000 12702357234 0015363 5 ustar 00root root 0000000 0000000 rabbitmq-c-0.8.0/examples/CMakeLists.txt 0000664 0000000 0000000 00000005241 12702357234 0020125 0 ustar 00root root 0000000 0000000 # vim:set ts=2 sw=2 sts=2 et:
include_directories(${LIBRABBITMQ_INCLUDE_DIRS})
if (WIN32)
set(PLATFORM_DIR win32)
else (WIN32)
set(PLATFORM_DIR unix)
endif (WIN32)
set(COMMON_SRCS
utils.h
utils.c
${PLATFORM_DIR}/platform_utils.c
)
add_executable(amqp_sendstring amqp_sendstring.c ${COMMON_SRCS})
target_link_libraries(amqp_sendstring ${RMQ_LIBRARY_TARGET})
add_executable(amqp_rpc_sendstring_client amqp_rpc_sendstring_client.c ${COMMON_SRCS})
target_link_libraries(amqp_rpc_sendstring_client ${RMQ_LIBRARY_TARGET})
add_executable(amqp_exchange_declare amqp_exchange_declare.c ${COMMON_SRCS})
target_link_libraries(amqp_exchange_declare ${RMQ_LIBRARY_TARGET})
add_executable(amqp_listen amqp_listen.c ${COMMON_SRCS})
target_link_libraries(amqp_listen ${RMQ_LIBRARY_TARGET})
add_executable(amqp_producer amqp_producer.c ${COMMON_SRCS})
target_link_libraries(amqp_producer ${RMQ_LIBRARY_TARGET})
add_executable(amqp_connect_timeout amqp_connect_timeout.c ${COMMON_SRCS})
target_link_libraries(amqp_connect_timeout ${RMQ_LIBRARY_TARGET})
add_executable(amqp_consumer amqp_consumer.c ${COMMON_SRCS})
target_link_libraries(amqp_consumer ${RMQ_LIBRARY_TARGET})
add_executable(amqp_unbind amqp_unbind.c ${COMMON_SRCS})
target_link_libraries(amqp_unbind ${RMQ_LIBRARY_TARGET})
add_executable(amqp_bind amqp_bind.c ${COMMON_SRCS})
target_link_libraries(amqp_bind ${RMQ_LIBRARY_TARGET})
add_executable(amqp_listenq amqp_listenq.c ${COMMON_SRCS})
target_link_libraries(amqp_listenq ${RMQ_LIBRARY_TARGET})
if (ENABLE_SSL_SUPPORT)
add_executable(amqps_connect_timeout amqps_connect_timeout.c ${COMMON_SRCS})
target_link_libraries(amqps_connect_timeout ${RMQ_LIBRARY_TARGET})
add_executable(amqps_sendstring amqps_sendstring.c ${COMMON_SRCS})
target_link_libraries(amqps_sendstring ${RMQ_LIBRARY_TARGET})
add_executable(amqps_exchange_declare amqps_exchange_declare.c ${COMMON_SRCS})
target_link_libraries(amqps_exchange_declare ${RMQ_LIBRARY_TARGET})
add_executable(amqps_listen amqps_listen.c ${COMMON_SRCS})
target_link_libraries(amqps_listen ${RMQ_LIBRARY_TARGET})
add_executable(amqps_producer amqps_producer.c ${COMMON_SRCS})
target_link_libraries(amqps_producer ${RMQ_LIBRARY_TARGET})
add_executable(amqps_consumer amqps_consumer.c ${COMMON_SRCS})
target_link_libraries(amqps_consumer ${RMQ_LIBRARY_TARGET})
add_executable(amqps_unbind amqps_unbind.c ${COMMON_SRCS})
target_link_libraries(amqps_unbind ${RMQ_LIBRARY_TARGET})
add_executable(amqps_bind amqps_bind.c ${COMMON_SRCS})
target_link_libraries(amqps_bind ${RMQ_LIBRARY_TARGET})
add_executable(amqps_listenq amqps_listenq.c ${COMMON_SRCS})
target_link_libraries(amqps_listenq ${RMQ_LIBRARY_TARGET})
endif (ENABLE_SSL_SUPPORT)
rabbitmq-c-0.8.0/examples/amqp_bind.c 0000664 0000000 0000000 00000006151 12702357234 0017464 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *exchange;
char const *bindingkey;
char const *queue;
amqp_socket_t *socket = NULL;
amqp_connection_state_t conn;
if (argc < 6) {
fprintf(stderr, "Usage: amqp_bind host port exchange bindingkey queue\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
bindingkey = argv[4];
queue = argv[5];
conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if (!socket) {
die("creating TCP socket");
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening TCP socket");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
amqp_queue_bind(conn, 1,
amqp_cstring_bytes(queue),
amqp_cstring_bytes(exchange),
amqp_cstring_bytes(bindingkey),
amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Unbinding");
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqp_connect_timeout.c 0000664 0000000 0000000 00000005771 12702357234 0021756 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by Bogdan Padalko are Copyright (c) 2013.
* Bogdan Padalko. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include
#else
# include
#endif
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port;
amqp_socket_t *socket;
amqp_connection_state_t conn;
struct timeval tval;
struct timeval *tv;
if (argc < 3) {
fprintf(stderr, "Usage: amqp_connect_timeout host port [timeout_sec [timeout_usec=0]]\n");
return 1;
}
if (argc > 3) {
tv = &tval;
tv->tv_sec = atoi(argv[3]);
if (argc > 4 ) {
tv->tv_usec = atoi(argv[4]);
} else {
tv->tv_usec = 0;
}
} else {
tv = NULL;
}
hostname = argv[1];
port = atoi(argv[2]);
conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if (!socket) {
die("creating TCP socket");
}
die_on_error(amqp_socket_open_noblock(socket, hostname, port, tv), "opening TCP socket");
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"), "Logging in");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
printf ("Done\n");
return 0;
}
rabbitmq-c-0.8.0/examples/amqp_consumer.c 0000664 0000000 0000000 00000015436 12702357234 0020411 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
#define SUMMARY_EVERY_US 1000000
static void run(amqp_connection_state_t conn)
{
uint64_t start_time = now_microseconds();
int received = 0;
int previous_received = 0;
uint64_t previous_report_time = start_time;
uint64_t next_summary_time = start_time + SUMMARY_EVERY_US;
amqp_frame_t frame;
uint64_t now;
for (;;) {
amqp_rpc_reply_t ret;
amqp_envelope_t envelope;
now = now_microseconds();
if (now > next_summary_time) {
int countOverInterval = received - previous_received;
double intervalRate = countOverInterval / ((now - previous_report_time) / 1000000.0);
printf("%d ms: Received %d - %d since last report (%d Hz)\n",
(int)(now - start_time) / 1000, received, countOverInterval, (int) intervalRate);
previous_received = received;
previous_report_time = now;
next_summary_time += SUMMARY_EVERY_US;
}
amqp_maybe_release_buffers(conn);
ret = amqp_consume_message(conn, &envelope, NULL, 0);
if (AMQP_RESPONSE_NORMAL != ret.reply_type) {
if (AMQP_RESPONSE_LIBRARY_EXCEPTION == ret.reply_type &&
AMQP_STATUS_UNEXPECTED_STATE == ret.library_error) {
if (AMQP_STATUS_OK != amqp_simple_wait_frame(conn, &frame)) {
return;
}
if (AMQP_FRAME_METHOD == frame.frame_type) {
switch (frame.payload.method.id) {
case AMQP_BASIC_ACK_METHOD:
/* if we've turned publisher confirms on, and we've published a message
* here is a message being confirmed
*/
break;
case AMQP_BASIC_RETURN_METHOD:
/* if a published message couldn't be routed and the mandatory flag was set
* this is what would be returned. The message then needs to be read.
*/
{
amqp_message_t message;
ret = amqp_read_message(conn, frame.channel, &message, 0);
if (AMQP_RESPONSE_NORMAL != ret.reply_type) {
return;
}
amqp_destroy_message(&message);
}
break;
case AMQP_CHANNEL_CLOSE_METHOD:
/* a channel.close method happens when a channel exception occurs, this
* can happen by publishing to an exchange that doesn't exist for example
*
* In this case you would need to open another channel redeclare any queues
* that were declared auto-delete, and restart any consumers that were attached
* to the previous channel
*/
return;
case AMQP_CONNECTION_CLOSE_METHOD:
/* a connection.close method happens when a connection exception occurs,
* this can happen by trying to use a channel that isn't open for example.
*
* In this case the whole connection must be restarted.
*/
return;
default:
fprintf(stderr ,"An unexpected method was received %u\n", frame.payload.method.id);
return;
}
}
}
} else {
amqp_destroy_envelope(&envelope);
}
received++;
}
}
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *exchange;
char const *bindingkey;
amqp_socket_t *socket = NULL;
amqp_connection_state_t conn;
amqp_bytes_t queuename;
if (argc < 3) {
fprintf(stderr, "Usage: amqp_consumer host port\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = "amq.direct"; /* argv[3]; */
bindingkey = "test queue"; /* argv[4]; */
conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if (!socket) {
die("creating TCP socket");
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening TCP socket");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
{
amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, 1, amqp_empty_bytes, 0, 0, 0, 1,
amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue");
queuename = amqp_bytes_malloc_dup(r->queue);
if (queuename.bytes == NULL) {
fprintf(stderr, "Out of memory while copying queue name");
return 1;
}
}
amqp_queue_bind(conn, 1, queuename, amqp_cstring_bytes(exchange), amqp_cstring_bytes(bindingkey),
amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue");
amqp_basic_consume(conn, 1, queuename, amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");
run(conn);
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqp_exchange_declare.c 0000664 0000000 0000000 00000006037 12702357234 0022014 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *exchange;
char const *exchangetype;
amqp_socket_t *socket = NULL;
amqp_connection_state_t conn;
if (argc < 5) {
fprintf(stderr, "Usage: amqp_exchange_declare host port exchange exchangetype\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
exchangetype = argv[4];
conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if (!socket) {
die("creating TCP socket");
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening TCP socket");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
amqp_exchange_declare(conn, 1, amqp_cstring_bytes(exchange), amqp_cstring_bytes(exchangetype),
0, 0, 0, 0, amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring exchange");
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqp_listen.c 0000664 0000000 0000000 00000010765 12702357234 0020054 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *exchange;
char const *bindingkey;
amqp_socket_t *socket = NULL;
amqp_connection_state_t conn;
amqp_bytes_t queuename;
if (argc < 5) {
fprintf(stderr, "Usage: amqp_listen host port exchange bindingkey\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
bindingkey = argv[4];
conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if (!socket) {
die("creating TCP socket");
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening TCP socket");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
{
amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, 1, amqp_empty_bytes, 0, 0, 0, 1,
amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue");
queuename = amqp_bytes_malloc_dup(r->queue);
if (queuename.bytes == NULL) {
fprintf(stderr, "Out of memory while copying queue name");
return 1;
}
}
amqp_queue_bind(conn, 1, queuename, amqp_cstring_bytes(exchange), amqp_cstring_bytes(bindingkey),
amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue");
amqp_basic_consume(conn, 1, queuename, amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");
{
for (;;) {
amqp_rpc_reply_t res;
amqp_envelope_t envelope;
amqp_maybe_release_buffers(conn);
res = amqp_consume_message(conn, &envelope, NULL, 0);
if (AMQP_RESPONSE_NORMAL != res.reply_type) {
break;
}
printf("Delivery %u, exchange %.*s routingkey %.*s\n",
(unsigned) envelope.delivery_tag,
(int) envelope.exchange.len, (char *) envelope.exchange.bytes,
(int) envelope.routing_key.len, (char *) envelope.routing_key.bytes);
if (envelope.message.properties._flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
printf("Content-type: %.*s\n",
(int) envelope.message.properties.content_type.len,
(char *) envelope.message.properties.content_type.bytes);
}
printf("----\n");
amqp_dump(envelope.message.body.bytes, envelope.message.body.len);
amqp_destroy_envelope(&envelope);
}
}
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqp_listenq.c 0000664 0000000 0000000 00000007544 12702357234 0020236 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *queuename;
amqp_socket_t *socket = NULL;
amqp_connection_state_t conn;
if (argc < 4) {
fprintf(stderr, "Usage: amqp_listenq host port queuename\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
queuename = argv[3];
conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if (!socket) {
die("creating TCP socket");
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening TCP socket");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
amqp_basic_consume(conn, 1, amqp_cstring_bytes(queuename), amqp_empty_bytes, 0, 0, 0, amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");
{
for (;;) {
amqp_rpc_reply_t res;
amqp_envelope_t envelope;
amqp_maybe_release_buffers(conn);
res = amqp_consume_message(conn, &envelope, NULL, 0);
if (AMQP_RESPONSE_NORMAL != res.reply_type) {
break;
}
printf("Delivery %u, exchange %.*s routingkey %.*s\n",
(unsigned) envelope.delivery_tag,
(int) envelope.exchange.len, (char *) envelope.exchange.bytes,
(int) envelope.routing_key.len, (char *) envelope.routing_key.bytes);
if (envelope.message.properties._flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
printf("Content-type: %.*s\n",
(int) envelope.message.properties.content_type.len,
(char *) envelope.message.properties.content_type.bytes);
}
printf("----\n");
amqp_dump(envelope.message.body.bytes, envelope.message.body.len);
amqp_destroy_envelope(&envelope);
}
}
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqp_producer.c 0000664 0000000 0000000 00000011600 12702357234 0020366 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
#define SUMMARY_EVERY_US 1000000
static void send_batch(amqp_connection_state_t conn,
char const *queue_name,
int rate_limit,
int message_count)
{
uint64_t start_time = now_microseconds();
int i;
int sent = 0;
int previous_sent = 0;
uint64_t previous_report_time = start_time;
uint64_t next_summary_time = start_time + SUMMARY_EVERY_US;
char message[256];
amqp_bytes_t message_bytes;
for (i = 0; i < (int)sizeof(message); i++) {
message[i] = i & 0xff;
}
message_bytes.len = sizeof(message);
message_bytes.bytes = message;
for (i = 0; i < message_count; i++) {
uint64_t now = now_microseconds();
die_on_error(amqp_basic_publish(conn,
1,
amqp_cstring_bytes("amq.direct"),
amqp_cstring_bytes(queue_name),
0,
0,
NULL,
message_bytes),
"Publishing");
sent++;
if (now > next_summary_time) {
int countOverInterval = sent - previous_sent;
double intervalRate = countOverInterval / ((now - previous_report_time) / 1000000.0);
printf("%d ms: Sent %d - %d since last report (%d Hz)\n",
(int)(now - start_time) / 1000, sent, countOverInterval, (int) intervalRate);
previous_sent = sent;
previous_report_time = now;
next_summary_time += SUMMARY_EVERY_US;
}
while (((i * 1000000.0) / (now - start_time)) > rate_limit) {
microsleep(2000);
now = now_microseconds();
}
}
{
uint64_t stop_time = now_microseconds();
int total_delta = (int)(stop_time - start_time);
printf("PRODUCER - Message count: %d\n", message_count);
printf("Total time, milliseconds: %d\n", total_delta / 1000);
printf("Overall messages-per-second: %g\n", (message_count / (total_delta / 1000000.0)));
}
}
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
int rate_limit;
int message_count;
amqp_socket_t *socket = NULL;
amqp_connection_state_t conn;
if (argc < 5) {
fprintf(stderr, "Usage: amqp_producer host port rate_limit message_count\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
rate_limit = atoi(argv[3]);
message_count = atoi(argv[4]);
conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if (!socket) {
die("creating TCP socket");
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening TCP socket");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
send_batch(conn, "test queue", rate_limit, message_count);
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqp_rpc_sendstring_client.c 0000664 0000000 0000000 00000016416 12702357234 0023137 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char *argv[])
{
char const *hostname;
int port, status;
char const *exchange;
char const *routingkey;
char const *messagebody;
amqp_socket_t *socket = NULL;
amqp_connection_state_t conn;
amqp_bytes_t reply_to_queue;
if (argc < 6) { /* minimum number of mandatory arguments */
fprintf(stderr, "usage:\namqp_rpc_sendstring_client host port exchange routingkey messagebody\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
routingkey = argv[4];
messagebody = argv[5];
/*
establish a channel that is used to connect RabbitMQ server
*/
conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if (!socket) {
die("creating TCP socket");
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening TCP socket");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
/*
create private reply_to queue
*/
{
amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, 1, amqp_empty_bytes, 0, 0, 0, 1, amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue");
reply_to_queue = amqp_bytes_malloc_dup(r->queue);
if (reply_to_queue.bytes == NULL) {
fprintf(stderr, "Out of memory while copying queue name");
return 1;
}
}
/*
send the message
*/
{
/*
set properties
*/
amqp_basic_properties_t props;
props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG |
AMQP_BASIC_DELIVERY_MODE_FLAG |
AMQP_BASIC_REPLY_TO_FLAG |
AMQP_BASIC_CORRELATION_ID_FLAG;
props.content_type = amqp_cstring_bytes("text/plain");
props.delivery_mode = 2; /* persistent delivery mode */
props.reply_to = amqp_bytes_malloc_dup(reply_to_queue);
if (props.reply_to.bytes == NULL) {
fprintf(stderr, "Out of memory while copying queue name");
return 1;
}
props.correlation_id = amqp_cstring_bytes("1");
/*
publish
*/
die_on_error(amqp_basic_publish(conn,
1,
amqp_cstring_bytes(exchange),
amqp_cstring_bytes(routingkey),
0,
0,
&props,
amqp_cstring_bytes(messagebody)),
"Publishing");
amqp_bytes_free(props.reply_to);
}
/*
wait an answer
*/
{
amqp_basic_consume(conn, 1, reply_to_queue, amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");
amqp_bytes_free(reply_to_queue);
{
amqp_frame_t frame;
int result;
amqp_basic_deliver_t *d;
amqp_basic_properties_t *p;
size_t body_target;
size_t body_received;
for (;;) {
amqp_maybe_release_buffers(conn);
result = amqp_simple_wait_frame(conn, &frame);
printf("Result: %d\n", result);
if (result < 0) {
break;
}
printf("Frame type: %u channel: %u\n", frame.frame_type, frame.channel);
if (frame.frame_type != AMQP_FRAME_METHOD) {
continue;
}
printf("Method: %s\n", amqp_method_name(frame.payload.method.id));
if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) {
continue;
}
d = (amqp_basic_deliver_t *) frame.payload.method.decoded;
printf("Delivery: %u exchange: %.*s routingkey: %.*s\n",
(unsigned) d->delivery_tag,
(int) d->exchange.len, (char *) d->exchange.bytes,
(int) d->routing_key.len, (char *) d->routing_key.bytes);
result = amqp_simple_wait_frame(conn, &frame);
if (result < 0) {
break;
}
if (frame.frame_type != AMQP_FRAME_HEADER) {
fprintf(stderr, "Expected header!");
abort();
}
p = (amqp_basic_properties_t *) frame.payload.properties.decoded;
if (p->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
printf("Content-type: %.*s\n",
(int) p->content_type.len, (char *) p->content_type.bytes);
}
printf("----\n");
body_target = (size_t)frame.payload.properties.body_size;
body_received = 0;
while (body_received < body_target) {
result = amqp_simple_wait_frame(conn, &frame);
if (result < 0) {
break;
}
if (frame.frame_type != AMQP_FRAME_BODY) {
fprintf(stderr, "Expected body!");
abort();
}
body_received += frame.payload.body_fragment.len;
assert(body_received <= body_target);
amqp_dump(frame.payload.body_fragment.bytes,
frame.payload.body_fragment.len);
}
if (body_received != body_target) {
/* Can only happen when amqp_simple_wait_frame returns <= 0 */
/* We break here to close the connection */
break;
}
/* everything was fine, we can quit now because we received the reply */
break;
}
}
}
/*
closing
*/
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqp_sendstring.c 0000664 0000000 0000000 00000007040 12702357234 0020726 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *exchange;
char const *routingkey;
char const *messagebody;
amqp_socket_t *socket = NULL;
amqp_connection_state_t conn;
if (argc < 6) {
fprintf(stderr, "Usage: amqp_sendstring host port exchange routingkey messagebody\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
routingkey = argv[4];
messagebody = argv[5];
conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if (!socket) {
die("creating TCP socket");
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening TCP socket");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
{
amqp_basic_properties_t props;
props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;
props.content_type = amqp_cstring_bytes("text/plain");
props.delivery_mode = 2; /* persistent delivery mode */
die_on_error(amqp_basic_publish(conn,
1,
amqp_cstring_bytes(exchange),
amqp_cstring_bytes(routingkey),
0,
0,
&props,
amqp_cstring_bytes(messagebody)),
"Publishing");
}
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqp_unbind.c 0000664 0000000 0000000 00000006165 12702357234 0020034 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *exchange;
char const *bindingkey;
char const *queue;
amqp_socket_t *socket = NULL;
amqp_connection_state_t conn;
if (argc < 6) {
fprintf(stderr, "Usage: amqp_unbind host port exchange bindingkey queue\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
bindingkey = argv[4];
queue = argv[5];
conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if (!socket) {
die("creating TCP socket");
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening TCP socket");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
amqp_queue_unbind(conn, 1,
amqp_cstring_bytes(queue),
amqp_cstring_bytes(exchange),
amqp_cstring_bytes(bindingkey),
amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Unbinding");
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqps_bind.c 0000664 0000000 0000000 00000007767 12702357234 0017665 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by Mike Steinert are Copyright (c) 2012-2013
* Mike Steinert. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *exchange;
char const *bindingkey;
char const *queue;
amqp_socket_t *socket;
amqp_connection_state_t conn;
if (argc < 6) {
fprintf(stderr, "Usage: amqps_bind host port exchange bindingkey queue "
"[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
bindingkey = argv[4];
queue = argv[5];
conn = amqp_new_connection();
socket = amqp_ssl_socket_new(conn);
if (!socket) {
die("creating SSL/TLS socket");
}
amqp_ssl_socket_set_verify_peer(socket, 0);
amqp_ssl_socket_set_verify_hostname(socket, 0);
if (argc > 6) {
int nextarg = 7;
status = amqp_ssl_socket_set_cacert(socket, argv[6]);
if (status) {
die("setting CA certificate");
}
if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) {
amqp_ssl_socket_set_verify_peer(socket, 1);
nextarg++;
}
if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) {
amqp_ssl_socket_set_verify_hostname(socket, 1);
nextarg++;
}
if (argc > nextarg + 1) {
status =
amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]);
if (status) {
die("setting client cert");
}
}
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening SSL/TLS connection");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
amqp_queue_bind(conn, 1,
amqp_cstring_bytes(queue),
amqp_cstring_bytes(exchange),
amqp_cstring_bytes(bindingkey),
amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Unbinding");
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqps_connect_timeout.c 0000664 0000000 0000000 00000007514 12702357234 0022136 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by Mike Steinert are Copyright (c) 2012-2013
* Mike Steinert. All Rights Reserved.
*
* Portions created by Bogdan Padalko are Copyright (c) 2013.
* Bogdan Padalko. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include
#else
# include
#endif
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port;
int timeout;
amqp_socket_t *socket;
amqp_connection_state_t conn;
struct timeval tval;
struct timeval *tv;
if (argc < 3) {
fprintf(
stderr,
"Usage: amqps_connect_timeout host port timeout_sec "
"[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
timeout = atoi(argv[3]);
if (timeout > 0) {
tv = &tval;
tv->tv_sec = timeout;
tv->tv_usec = 0;
} else {
tv = NULL;
}
conn = amqp_new_connection();
socket = amqp_ssl_socket_new(conn);
if (!socket) {
die("creating SSL/TLS socket");
}
amqp_ssl_socket_set_verify_peer(socket, 0);
amqp_ssl_socket_set_verify_hostname(socket, 0);
if (argc > 5) {
int nextarg = 6;
die_on_error(amqp_ssl_socket_set_cacert(socket, argv[5]),
"setting CA certificate");
if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) {
amqp_ssl_socket_set_verify_peer(socket, 1);
nextarg++;
}
if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) {
amqp_ssl_socket_set_verify_hostname(socket, 1);
nextarg++;
}
if (argc > nextarg + 1) {
die_on_error(
amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]),
"setting client key");
}
}
die_on_error(amqp_socket_open_noblock(socket, hostname, port, tv), "opening SSL/TLS connection");
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
printf ("Done\n");
return 0;
}
rabbitmq-c-0.8.0/examples/amqps_consumer.c 0000664 0000000 0000000 00000017253 12702357234 0020573 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by Mike Steinert are Copyright (c) 2012-2013
* Mike Steinert. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
#define SUMMARY_EVERY_US 1000000
static void run(amqp_connection_state_t conn)
{
uint64_t start_time = now_microseconds();
int received = 0;
int previous_received = 0;
uint64_t previous_report_time = start_time;
uint64_t next_summary_time = start_time + SUMMARY_EVERY_US;
amqp_frame_t frame;
uint64_t now;
for (;;) {
amqp_rpc_reply_t ret;
amqp_envelope_t envelope;
now = now_microseconds();
if (now > next_summary_time) {
int countOverInterval = received - previous_received;
double intervalRate = countOverInterval / ((now - previous_report_time) / 1000000.0);
printf("%d ms: Received %d - %d since last report (%d Hz)\n",
(int)(now - start_time) / 1000, received, countOverInterval, (int) intervalRate);
previous_received = received;
previous_report_time = now;
next_summary_time += SUMMARY_EVERY_US;
}
amqp_maybe_release_buffers(conn);
ret = amqp_consume_message(conn, &envelope, NULL, 0);
if (AMQP_RESPONSE_NORMAL != ret.reply_type) {
if (AMQP_RESPONSE_LIBRARY_EXCEPTION == ret.reply_type &&
AMQP_STATUS_UNEXPECTED_STATE == ret.library_error) {
if (AMQP_STATUS_OK != amqp_simple_wait_frame(conn, &frame)) {
return;
}
if (AMQP_FRAME_METHOD == frame.frame_type) {
switch (frame.payload.method.id) {
case AMQP_BASIC_ACK_METHOD:
/* if we've turned publisher confirms on, and we've published a message
* here is a message being confirmed
*/
break;
case AMQP_BASIC_RETURN_METHOD:
/* if a published message couldn't be routed and the mandatory flag was set
* this is what would be returned. The message then needs to be read.
*/
{
amqp_message_t message;
ret = amqp_read_message(conn, frame.channel, &message, 0);
if (AMQP_RESPONSE_NORMAL != ret.reply_type) {
return;
}
amqp_destroy_message(&message);
}
break;
case AMQP_CHANNEL_CLOSE_METHOD:
/* a channel.close method happens when a channel exception occurs, this
* can happen by publishing to an exchange that doesn't exist for example
*
* In this case you would need to open another channel redeclare any queues
* that were declared auto-delete, and restart any consumers that were attached
* to the previous channel
*/
return;
case AMQP_CONNECTION_CLOSE_METHOD:
/* a connection.close method happens when a connection exception occurs,
* this can happen by trying to use a channel that isn't open for example.
*
* In this case the whole connection must be restarted.
*/
return;
default:
fprintf(stderr ,"An unexpected method was received %u\n", frame.payload.method.id);
return;
}
}
}
} else {
amqp_destroy_envelope(&envelope);
}
received++;
}
}
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *exchange;
char const *bindingkey;
amqp_socket_t *socket;
amqp_connection_state_t conn;
amqp_bytes_t queuename;
if (argc < 3) {
fprintf(stderr, "Usage: amqps_consumer host port "
"[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = "amq.direct"; /* argv[3]; */
bindingkey = "test queue"; /* argv[4]; */
conn = amqp_new_connection();
socket = amqp_ssl_socket_new(conn);
if (!socket) {
die("creating SSL/TLS socket");
}
amqp_ssl_socket_set_verify_peer(socket, 0);
amqp_ssl_socket_set_verify_hostname(socket, 0);
if (argc > 3) {
int nextarg = 4;
status = amqp_ssl_socket_set_cacert(socket, argv[3]);
if (status) {
die("setting CA certificate");
}
if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) {
amqp_ssl_socket_set_verify_peer(socket, 1);
nextarg++;
}
if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) {
amqp_ssl_socket_set_verify_hostname(socket, 1);
nextarg++;
}
if (argc > nextarg + 1) {
status =
amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]);
if (status) {
die("setting client key");
}
}
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening SSL/TLS connection");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
{
amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, 1, amqp_empty_bytes, 0, 0, 0, 1,
amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue");
queuename = amqp_bytes_malloc_dup(r->queue);
if (queuename.bytes == NULL) {
fprintf(stderr, "Out of memory while copying queue name");
return 1;
}
}
amqp_queue_bind(conn, 1, queuename, amqp_cstring_bytes(exchange), amqp_cstring_bytes(bindingkey),
amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue");
amqp_basic_consume(conn, 1, queuename, amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");
run(conn);
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqps_exchange_declare.c 0000664 0000000 0000000 00000007700 12702357234 0022175 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by Mike Steinert are Copyright (c) 2012-2013
* Mike Steinert. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *exchange;
char const *exchangetype;
amqp_socket_t *socket;
amqp_connection_state_t conn;
if (argc < 5) {
fprintf(stderr, "Usage: amqps_exchange_declare host port exchange "
"exchangetype [cacert.pem [verifypeer] [verifyhostname] "
"[key.pem cert.pem]]\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
exchangetype = argv[4];
conn = amqp_new_connection();
socket = amqp_ssl_socket_new(conn);
if (!socket) {
die("creating SSL/TLS socket");
}
amqp_ssl_socket_set_verify_peer(socket, 0);
amqp_ssl_socket_set_verify_hostname(socket, 0);
if (argc > 5) {
int nextarg = 6;
status = amqp_ssl_socket_set_cacert(socket, argv[5]);
if (status) {
die("setting CA certificate");
}
if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) {
amqp_ssl_socket_set_verify_peer(socket, 1);
nextarg++;
}
if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) {
amqp_ssl_socket_set_verify_hostname(socket, 1);
nextarg++;
}
if (argc > nextarg + 1) {
status =
amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]);
if (status) {
die("setting client key/cert");
}
}
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening SSL/TLS connection");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
amqp_exchange_declare(conn, 1, amqp_cstring_bytes(exchange), amqp_cstring_bytes(exchangetype),
0, 0, 0, 0, amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring exchange");
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqps_listen.c 0000664 0000000 0000000 00000012604 12702357234 0020231 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by Mike Steinert are Copyright (c) 2012-2013
* Mike Steinert. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *exchange;
char const *bindingkey;
amqp_socket_t *socket;
amqp_connection_state_t conn;
amqp_bytes_t queuename;
if (argc < 5) {
fprintf(stderr, "Usage: amqps_listen host port exchange bindingkey "
"[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
bindingkey = argv[4];
conn = amqp_new_connection();
socket = amqp_ssl_socket_new(conn);
if (!socket) {
die("creating SSL/TLS socket");
}
amqp_ssl_socket_set_verify_peer(socket, 0);
amqp_ssl_socket_set_verify_hostname(socket, 0);
if (argc > 5) {
int nextarg = 6;
status = amqp_ssl_socket_set_cacert(socket, argv[5]);
if (status) {
die("setting CA certificate");
}
if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) {
amqp_ssl_socket_set_verify_peer(socket, 1);
nextarg++;
}
if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) {
amqp_ssl_socket_set_verify_hostname(socket, 1);
nextarg++;
}
if (argc > nextarg + 1) {
status =
amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]);
if (status) {
die("setting client cert");
}
}
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening SSL/TLS connection");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
{
amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, 1, amqp_empty_bytes, 0, 0, 0, 1,
amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue");
queuename = amqp_bytes_malloc_dup(r->queue);
if (queuename.bytes == NULL) {
fprintf(stderr, "Out of memory while copying queue name");
return 1;
}
}
amqp_queue_bind(conn, 1, queuename, amqp_cstring_bytes(exchange), amqp_cstring_bytes(bindingkey),
amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue");
amqp_basic_consume(conn, 1, queuename, amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");
{
for (;;) {
amqp_rpc_reply_t res;
amqp_envelope_t envelope;
amqp_maybe_release_buffers(conn);
res = amqp_consume_message(conn, &envelope, NULL, 0);
if (AMQP_RESPONSE_NORMAL != res.reply_type) {
break;
}
printf("Delivery %u, exchange %.*s routingkey %.*s\n",
(unsigned) envelope.delivery_tag,
(int) envelope.exchange.len, (char *) envelope.exchange.bytes,
(int) envelope.routing_key.len, (char *) envelope.routing_key.bytes);
if (envelope.message.properties._flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
printf("Content-type: %.*s\n",
(int) envelope.message.properties.content_type.len,
(char *) envelope.message.properties.content_type.bytes);
}
printf("----\n");
amqp_dump(envelope.message.body.bytes, envelope.message.body.len);
amqp_destroy_envelope(&envelope);
}
}
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqps_listenq.c 0000664 0000000 0000000 00000011363 12702357234 0020413 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by Mike Steinert are Copyright (c) 2012-2013
* Mike Steinert. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *queuename;
amqp_socket_t *socket;
amqp_connection_state_t conn;
if (argc < 4) {
fprintf(stderr, "Usage: amqps_listenq host port queuename "
"[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
queuename = argv[3];
conn = amqp_new_connection();
socket = amqp_ssl_socket_new(conn);
if (!socket) {
die("creating SSL/TLS socket");
}
amqp_ssl_socket_set_verify_peer(socket, 0);
amqp_ssl_socket_set_verify_hostname(socket, 0);
if (argc > 4) {
int nextarg = 5;
status = amqp_ssl_socket_set_cacert(socket, argv[4]);
if (status) {
die("setting CA certificate");
}
if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) {
amqp_ssl_socket_set_verify_peer(socket, 1);
nextarg++;
}
if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) {
amqp_ssl_socket_set_verify_hostname(socket, 1);
nextarg++;
}
if (argc > nextarg + 1) {
status =
amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]);
if (status) {
die("setting client cert");
}
}
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening SSL/TLS connection");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
amqp_basic_consume(conn, 1, amqp_cstring_bytes(queuename), amqp_empty_bytes, 0, 0, 0, amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");
{
for (;;) {
amqp_rpc_reply_t res;
amqp_envelope_t envelope;
amqp_maybe_release_buffers(conn);
res = amqp_consume_message(conn, &envelope, NULL, 0);
if (AMQP_RESPONSE_NORMAL != res.reply_type) {
break;
}
printf("Delivery %u, exchange %.*s routingkey %.*s\n",
(unsigned) envelope.delivery_tag,
(int) envelope.exchange.len, (char *) envelope.exchange.bytes,
(int) envelope.routing_key.len, (char *) envelope.routing_key.bytes);
if (envelope.message.properties._flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
printf("Content-type: %.*s\n",
(int) envelope.message.properties.content_type.len,
(char *) envelope.message.properties.content_type.bytes);
}
printf("----\n");
amqp_dump(envelope.message.body.bytes, envelope.message.body.len);
amqp_destroy_envelope(&envelope);
}
}
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqps_producer.c 0000664 0000000 0000000 00000013416 12702357234 0020560 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by Mike Steinert are Copyright (c) 2012-2013
* Mike Steinert. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include "utils.h"
#define SUMMARY_EVERY_US 1000000
static void send_batch(amqp_connection_state_t conn,
char const *queue_name,
int rate_limit,
int message_count)
{
uint64_t start_time = now_microseconds();
int i;
int sent = 0;
int previous_sent = 0;
uint64_t previous_report_time = start_time;
uint64_t next_summary_time = start_time + SUMMARY_EVERY_US;
char message[256];
amqp_bytes_t message_bytes;
for (i = 0; i < (int)sizeof(message); i++) {
message[i] = i & 0xff;
}
message_bytes.len = sizeof(message);
message_bytes.bytes = message;
for (i = 0; i < message_count; i++) {
uint64_t now = now_microseconds();
die_on_error(amqp_basic_publish(conn,
1,
amqp_cstring_bytes("amq.direct"),
amqp_cstring_bytes(queue_name),
0,
0,
NULL,
message_bytes),
"Publishing");
sent++;
if (now > next_summary_time) {
int countOverInterval = sent - previous_sent;
double intervalRate = countOverInterval / ((now - previous_report_time) / 1000000.0);
printf("%d ms: Sent %d - %d since last report (%d Hz)\n",
(int)(now - start_time) / 1000, sent, countOverInterval, (int) intervalRate);
previous_sent = sent;
previous_report_time = now;
next_summary_time += SUMMARY_EVERY_US;
}
while (((i * 1000000.0) / (now - start_time)) > rate_limit) {
microsleep(2000);
now = now_microseconds();
}
}
{
uint64_t stop_time = now_microseconds();
int total_delta = (int)(stop_time - start_time);
printf("PRODUCER - Message count: %d\n", message_count);
printf("Total time, milliseconds: %d\n", total_delta / 1000);
printf("Overall messages-per-second: %g\n", (message_count / (total_delta / 1000000.0)));
}
}
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
int rate_limit;
int message_count;
amqp_socket_t *socket;
amqp_connection_state_t conn;
if (argc < 5) {
fprintf(stderr, "Usage: amqps_producer host port rate_limit message_count "
"[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
rate_limit = atoi(argv[3]);
message_count = atoi(argv[4]);
conn = amqp_new_connection();
socket = amqp_ssl_socket_new(conn);
if (!socket) {
die("creating SSL/TLS socket");
}
amqp_ssl_socket_set_verify_peer(socket, 0);
amqp_ssl_socket_set_verify_hostname(socket, 0);
if (argc > 5) {
int nextarg = 6;
status = amqp_ssl_socket_set_cacert(socket, argv[5]);
if (status) {
die("setting CA certificate");
}
if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) {
amqp_ssl_socket_set_verify_peer(socket, 1);
nextarg++;
}
if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) {
amqp_ssl_socket_set_verify_hostname(socket, 1);
nextarg++;
}
if (argc > nextarg + 1) {
status =
amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]);
if (status) {
die("setting client cert");
}
}
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening SSL/TLS connection");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
send_batch(conn, "test queue", rate_limit, message_count);
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqps_sendstring.c 0000664 0000000 0000000 00000010675 12702357234 0021121 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by Mike Steinert are Copyright (c) 2012-2013
* Mike Steinert. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *exchange;
char const *routingkey;
char const *messagebody;
amqp_socket_t *socket;
amqp_connection_state_t conn;
if (argc < 6) {
fprintf(stderr, "Usage: amqps_sendstring host port exchange routingkey "
"messagebody [cacert.pem [verifypeer] [verifyhostname] "
"[key.pem cert.pem]]\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
routingkey = argv[4];
messagebody = argv[5];
conn = amqp_new_connection();
socket = amqp_ssl_socket_new(conn);
if (!socket) {
die("creating SSL/TLS socket");
}
amqp_ssl_socket_set_verify_peer(socket, 0);
amqp_ssl_socket_set_verify_hostname(socket, 0);
if (argc > 6) {
int nextarg = 7;
status = amqp_ssl_socket_set_cacert(socket, argv[6]);
if (status) {
die("setting CA certificate");
}
if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) {
amqp_ssl_socket_set_verify_peer(socket, 1);
nextarg++;
}
if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) {
amqp_ssl_socket_set_verify_hostname(socket, 1);
nextarg++;
}
if (argc > nextarg + 1) {
status =
amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]);
if (status) {
die("setting client cert");
}
}
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening SSL/TLS connection");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
{
amqp_basic_properties_t props;
props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;
props.content_type = amqp_cstring_bytes("text/plain");
props.delivery_mode = 2; /* persistent delivery mode */
die_on_error(amqp_basic_publish(conn,
1,
amqp_cstring_bytes(exchange),
amqp_cstring_bytes(routingkey),
0,
0,
&props,
amqp_cstring_bytes(messagebody)),
"Publishing");
}
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/amqps_unbind.c 0000664 0000000 0000000 00000010003 12702357234 0020201 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by Mike Steinert are Copyright (c) 2012-2013
* Mike Steinert. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include "utils.h"
int main(int argc, char const *const *argv)
{
char const *hostname;
int port, status;
char const *exchange;
char const *bindingkey;
char const *queue;
amqp_socket_t *socket;
amqp_connection_state_t conn;
if (argc < 6) {
fprintf(stderr, "Usage: amqps_unbind host port exchange bindingkey queue "
"[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n");
return 1;
}
hostname = argv[1];
port = atoi(argv[2]);
exchange = argv[3];
bindingkey = argv[4];
queue = argv[5];
conn = amqp_new_connection();
socket = amqp_ssl_socket_new(conn);
if (!socket) {
die("creating SSL/TLS socket");
}
amqp_ssl_socket_set_verify_peer(socket, 0);
amqp_ssl_socket_set_verify_hostname(socket, 0);
if (argc > 6) {
int nextarg = 7;
status = amqp_ssl_socket_set_cacert(socket, argv[6]);
if (status) {
die("setting CA certificate");
}
if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) {
amqp_ssl_socket_set_verify_peer(socket, 1);
nextarg++;
}
if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) {
amqp_ssl_socket_set_verify_hostname(socket, 1);
nextarg++;
}
if (argc > nextarg + 1) {
status =
amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]);
if (status) {
die("setting client cert");
}
}
}
status = amqp_socket_open(socket, hostname, port);
if (status) {
die("opening SSL/TLS connection");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
amqp_queue_unbind(conn, 1,
amqp_cstring_bytes(queue),
amqp_cstring_bytes(exchange),
amqp_cstring_bytes(bindingkey),
amqp_empty_table);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Unbinding");
die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
die_on_error(amqp_destroy_connection(conn), "Ending connection");
return 0;
}
rabbitmq-c-0.8.0/examples/unix/ 0000775 0000000 0000000 00000000000 12702357234 0016346 5 ustar 00root root 0000000 0000000 rabbitmq-c-0.8.0/examples/unix/platform_utils.c 0000664 0000000 0000000 00000003571 12702357234 0021564 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
uint64_t now_microseconds(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (uint64_t) tv.tv_sec * 1000000 + (uint64_t) tv.tv_usec;
}
void microsleep(int usec)
{
struct timespec req;
req.tv_sec = 0;
req.tv_nsec = 1000 * usec;
nanosleep(&req, NULL);
}
rabbitmq-c-0.8.0/examples/utils.c 0000664 0000000 0000000 00000011253 12702357234 0016671 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
void die(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
exit(1);
}
void die_on_error(int x, char const *context)
{
if (x < 0) {
fprintf(stderr, "%s: %s\n", context, amqp_error_string2(x));
exit(1);
}
}
void die_on_amqp_error(amqp_rpc_reply_t x, char const *context)
{
switch (x.reply_type) {
case AMQP_RESPONSE_NORMAL:
return;
case AMQP_RESPONSE_NONE:
fprintf(stderr, "%s: missing RPC reply type!\n", context);
break;
case AMQP_RESPONSE_LIBRARY_EXCEPTION:
fprintf(stderr, "%s: %s\n", context, amqp_error_string2(x.library_error));
break;
case AMQP_RESPONSE_SERVER_EXCEPTION:
switch (x.reply.id) {
case AMQP_CONNECTION_CLOSE_METHOD: {
amqp_connection_close_t *m = (amqp_connection_close_t *) x.reply.decoded;
fprintf(stderr, "%s: server connection error %uh, message: %.*s\n",
context,
m->reply_code,
(int) m->reply_text.len, (char *) m->reply_text.bytes);
break;
}
case AMQP_CHANNEL_CLOSE_METHOD: {
amqp_channel_close_t *m = (amqp_channel_close_t *) x.reply.decoded;
fprintf(stderr, "%s: server channel error %uh, message: %.*s\n",
context,
m->reply_code,
(int) m->reply_text.len, (char *) m->reply_text.bytes);
break;
}
default:
fprintf(stderr, "%s: unknown server error, method id 0x%08X\n", context, x.reply.id);
break;
}
break;
}
exit(1);
}
static void dump_row(long count, int numinrow, int *chs)
{
int i;
printf("%08lX:", count - numinrow);
if (numinrow > 0) {
for (i = 0; i < numinrow; i++) {
if (i == 8) {
printf(" :");
}
printf(" %02X", chs[i]);
}
for (i = numinrow; i < 16; i++) {
if (i == 8) {
printf(" :");
}
printf(" ");
}
printf(" ");
for (i = 0; i < numinrow; i++) {
if (isprint(chs[i])) {
printf("%c", chs[i]);
} else {
printf(".");
}
}
}
printf("\n");
}
static int rows_eq(int *a, int *b)
{
int i;
for (i=0; i<16; i++)
if (a[i] != b[i]) {
return 0;
}
return 1;
}
void amqp_dump(void const *buffer, size_t len)
{
unsigned char *buf = (unsigned char *) buffer;
long count = 0;
int numinrow = 0;
int chs[16];
int oldchs[16] = {0};
int showed_dots = 0;
size_t i;
for (i = 0; i < len; i++) {
int ch = buf[i];
if (numinrow == 16) {
int j;
if (rows_eq(oldchs, chs)) {
if (!showed_dots) {
showed_dots = 1;
printf(" .. .. .. .. .. .. .. .. : .. .. .. .. .. .. .. ..\n");
}
} else {
showed_dots = 0;
dump_row(count, numinrow, chs);
}
for (j=0; j<16; j++) {
oldchs[j] = chs[j];
}
numinrow = 0;
}
count++;
chs[numinrow++] = ch;
}
dump_row(count, numinrow, chs);
if (numinrow != 0) {
printf("%08lX:\n", count);
}
}
rabbitmq-c-0.8.0/examples/utils.h 0000664 0000000 0000000 00000003611 12702357234 0016675 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
#ifndef librabbitmq_examples_utils_h
#define librabbitmq_examples_utils_h
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
void die(const char *fmt, ...);
extern void die_on_error(int x, char const *context);
extern void die_on_amqp_error(amqp_rpc_reply_t x, char const *context);
extern void amqp_dump(void const *buffer, size_t len);
extern uint64_t now_microseconds(void);
extern void microsleep(int usec);
#endif
rabbitmq-c-0.8.0/examples/win32/ 0000775 0000000 0000000 00000000000 12702357234 0016325 5 ustar 00root root 0000000 0000000 rabbitmq-c-0.8.0/examples/win32/platform_utils.c 0000664 0000000 0000000 00000003443 12702357234 0021541 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include
#include
uint64_t now_microseconds(void)
{
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
return (((uint64_t)ft.dwHighDateTime << 32) | (uint64_t)ft.dwLowDateTime)
/ 10;
}
void microsleep(int usec)
{
Sleep(usec / 1000);
}
rabbitmq-c-0.8.0/librabbitmq.pc.in 0000664 0000000 0000000 00000000502 12702357234 0016763 0 ustar 00root root 0000000 0000000 prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: rabbitmq-c
Description: An AMQP 0-9-1 client library
Version: @VERSION@
URL: https://github.com/alanxz/rabbitmq-c
Requires.private: @requires_private@
Libs: -L${libdir} -lrabbitmq
Libs.private: @libs_private@
CFlags: -I${includedir}
rabbitmq-c-0.8.0/librabbitmq/ 0000775 0000000 0000000 00000000000 12702357234 0016035 5 ustar 00root root 0000000 0000000 rabbitmq-c-0.8.0/librabbitmq/CMakeLists.txt 0000664 0000000 0000000 00000013245 12702357234 0020602 0 ustar 00root root 0000000 0000000 # vim:set ts=2 sw=2 sts=2 et:
project(librabbitmq "C")
if (REGENERATE_AMQP_FRAMING)
set(AMQP_CODEGEN_PY "${CMAKE_CURRENT_BINARY_DIR}/amqp_codegen.py")
set(CODEGEN_PY "${CMAKE_CURRENT_BINARY_DIR}/codegen.py")
set(AMQP_SPEC_JSON_PATH "${AMQP_CODEGEN_DIR}/amqp-rabbitmq-0.9.1.json")
set(AMQP_FRAMING_H_PATH ${CMAKE_CURRENT_BINARY_DIR}/amqp_framing.h)
set(AMQP_FRAMING_C_PATH ${CMAKE_CURRENT_BINARY_DIR}/amqp_framing.c)
if (PYTHON_VERSION_MAJOR GREATER 2)
set(CONVERT_CODEGEN ${PYTHON_2TO3_EXECUTABLE} -w ${CODEGEN_PY} > codegen_2to3.out)
set(CONVERT_AMQP_CODEGEN ${PYTHON_2TO3_EXECUTABLE} -w ${AMQP_CODEGEN_PY} > amqp_codegen_2to3.out)
else ()
set(CONVERT_CODEGEN "")
set(CONVERT_AMQP_CODEGEN "")
endif ()
add_custom_command(
OUTPUT ${CODEGEN_PY}
COMMAND ${CMAKE_COMMAND} ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/codegen.py ${CODEGEN_PY}
COMMAND ${CONVERT_CODEGEN}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/codegen.py
VERBATIM)
add_custom_command(
OUTPUT ${AMQP_CODEGEN_PY}
COMMAND ${CMAKE_COMMAND} ARGS -E copy ${AMQP_CODEGEN_DIR}/amqp_codegen.py ${AMQP_CODEGEN_PY}
COMMAND ${CONVERT_AMQP_CODEGEN}
DEPENDS ${AMQP_CODEGEN_DIR}/amqp_codegen.py ${AMQP_CODEGEN_TARGET}
VERBATIM)
add_custom_command(
OUTPUT ${AMQP_FRAMING_H_PATH}
COMMAND ${PYTHON_EXECUTABLE} ARGS ${CODEGEN_PY} header ${AMQP_SPEC_JSON_PATH} ${AMQP_FRAMING_H_PATH}
DEPENDS ${AMQP_SPEC_JSON_PATH} ${CODEGEN_PY} ${AMQP_CODEGEN_PY}
VERBATIM)
add_custom_command(
OUTPUT ${AMQP_FRAMING_C_PATH}
COMMAND ${PYTHON_EXECUTABLE} ARGS ${CODEGEN_PY} body ${AMQP_SPEC_JSON_PATH} ${AMQP_FRAMING_C_PATH}
DEPENDS ${AMQP_SPEC_JSON_PATH} ${CODEGEN_PY} ${AMQP_CODEGEN_PY}
VERBATIM)
else (REGENERATE_AMQP_FRAMING)
set(AMQP_FRAMING_H_PATH ${CMAKE_CURRENT_SOURCE_DIR}/amqp_framing.h)
set(AMQP_FRAMING_C_PATH ${CMAKE_CURRENT_SOURCE_DIR}/amqp_framing.c)
endif (REGENERATE_AMQP_FRAMING)
if(WIN32)
set(SOCKET_IMPL "win32")
else(WIN32)
set(SOCKET_IMPL "unix")
endif(WIN32)
if(MSVC)
if(MSVC_VERSION LESS 1600)
set(MSINTTYPES_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/win32/msinttypes")
set(STDINT_H_INSTALL_FILE "${CMAKE_CURRENT_SOURCE_DIR}/win32/msinttypes/stdint.h")
endif(MSVC_VERSION LESS 1600)
endif(MSVC)
# NOTE: order is important here: if we generate amqp_framing.h/.c it'll be in the
# binary directory, and should shadow whats in the source directory
set(LIBRABBITMQ_INCLUDE_DIRS
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${SOCKET_IMPL}
${MSINTTYPES_INCLUDE}
)
include_directories(${LIBRABBITMQ_INCLUDE_DIRS})
set(LIBRABBITMQ_INCLUDE_DIRS
${LIBRABBITMQ_INCLUDE_DIRS}
PARENT_SCOPE)
add_definitions(-DHAVE_CONFIG_H)
if (ENABLE_SSL_SUPPORT)
add_definitions(-DWITH_SSL=1)
set(AMQP_SSL_SOCKET_H_PATH amqp_ssl_socket.h)
set(AMQP_SSL_SRCS ${AMQP_SSL_SOCKET_H_PATH}
amqp_openssl.c
amqp_openssl_hostname_validation.c
amqp_openssl_hostname_validation.h
amqp_hostcheck.c
amqp_hostcheck.h
)
include_directories(${OPENSSL_INCLUDE_DIR})
set(AMQP_SSL_LIBS ${OPENSSL_LIBRARIES})
if (APPLE)
# Apple has deprecated OpenSSL in 10.7+. This disables that warning.
set_source_files_properties(${AMQP_SSL_SRCS}
PROPERTIES COMPILE_FLAGS -Wno-deprecated-declarations)
endif()
if (ENABLE_THREAD_SAFETY)
add_definitions(-DENABLE_THREAD_SAFETY)
if (WIN32)
set(AMQP_SSL_SRCS ${AMQP_SSL_SRCS} win32/threads.h win32/threads.c)
else()
set(AMQP_SSL_SRCS ${AMQP_SSL_SRCS} unix/threads.h)
endif()
endif()
endif()
set(RABBITMQ_SOURCES
${AMQP_FRAMING_H_PATH}
${AMQP_FRAMING_C_PATH}
amqp_api.c amqp.h amqp_connection.c amqp_mem.c amqp_private.h amqp_socket.c
amqp_table.c amqp_url.c amqp_socket.h amqp_tcp_socket.c amqp_tcp_socket.h
amqp_time.c amqp_time.h
amqp_consumer.c
${AMQP_SSL_SRCS}
)
add_definitions(-DAMQP_BUILD)
set(RMQ_LIBRARIES ${AMQP_SSL_LIBS} ${SOCKET_LIBRARIES} ${LIBRT} ${CMAKE_THREAD_LIBS_INIT})
if (BUILD_SHARED_LIBS)
add_library(rabbitmq SHARED ${RABBITMQ_SOURCES})
target_link_libraries(rabbitmq ${RMQ_LIBRARIES})
if (WIN32)
set_target_properties(rabbitmq PROPERTIES VERSION ${RMQ_VERSION} OUTPUT_NAME rabbitmq.${RMQ_SOVERSION})
else (WIN32)
set_target_properties(rabbitmq PROPERTIES VERSION ${RMQ_VERSION} SOVERSION ${RMQ_SOVERSION})
endif (WIN32)
install(TARGETS rabbitmq
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
set(RMQ_LIBRARY_TARGET rabbitmq)
endif (BUILD_SHARED_LIBS)
if (BUILD_STATIC_LIBS)
add_library(rabbitmq-static STATIC ${RABBITMQ_SOURCES})
target_link_libraries(rabbitmq-static ${RMQ_LIBRARIES})
set_target_properties(rabbitmq-static PROPERTIES COMPILE_DEFINITIONS AMQP_STATIC)
if (WIN32)
set_target_properties(rabbitmq-static PROPERTIES
# Embed debugging info in the library itself instead of generating
# a .pdb file.
COMPILE_OPTIONS "/Z7"
VERSION ${RMQ_VERSION}
OUTPUT_NAME librabbitmq.${RMQ_SOVERSION})
else (WIN32)
set_target_properties(rabbitmq-static PROPERTIES VERSION ${RMQ_VERSION} SOVERSION ${RMQ_SOVERSION} OUTPUT_NAME rabbitmq)
endif (WIN32)
install(TARGETS rabbitmq-static
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
if (NOT DEFINED RMQ_LIBRARY_TARGET)
set(RMQ_LIBRARY_TARGET rabbitmq-static)
endif ()
endif (BUILD_STATIC_LIBS)
install(FILES
amqp.h
${AMQP_FRAMING_H_PATH}
amqp_tcp_socket.h
${AMQP_SSL_SOCKET_H_PATH}
${STDINT_H_INSTALL_FILE}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
set(RMQ_LIBRARY_TARGET ${RMQ_LIBRARY_TARGET} PARENT_SCOPE)
rabbitmq-c-0.8.0/librabbitmq/amqp.h 0000664 0000000 0000000 00000260257 12702357234 0017160 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/** \file */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2014
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#ifndef AMQP_H
#define AMQP_H
/** \cond HIDE_FROM_DOXYGEN */
#ifdef __cplusplus
#define AMQP_BEGIN_DECLS extern "C" {
#define AMQP_END_DECLS }
#else
#define AMQP_BEGIN_DECLS
#define AMQP_END_DECLS
#endif
/*
* \internal
* Important API decorators:
* AMQP_PUBLIC_FUNCTION - a public API function
* AMQP_PUBLIC_VARIABLE - a public API external variable
* AMQP_CALL - calling convension (used on Win32)
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(AMQP_BUILD) && !defined(AMQP_STATIC)
# define AMQP_PUBLIC_FUNCTION __declspec(dllexport)
# define AMQP_PUBLIC_VARIABLE __declspec(dllexport) extern
# else
# define AMQP_PUBLIC_FUNCTION
# if !defined(AMQP_STATIC)
# define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern
# else
# define AMQP_PUBLIC_VARIABLE extern
# endif
# endif
# define AMQP_CALL __cdecl
#elif defined(_WIN32) && defined(__BORLANDC__)
# if defined(AMQP_BUILD) && !defined(AMQP_STATIC)
# define AMQP_PUBLIC_FUNCTION __declspec(dllexport)
# define AMQP_PUBLIC_VARIABLE __declspec(dllexport) extern
# else
# define AMQP_PUBLIC_FUNCTION
# if !defined(AMQP_STATIC)
# define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern
# else
# define AMQP_PUBLIC_VARIABLE extern
# endif
# endif
# define AMQP_CALL __cdecl
#elif defined(_WIN32) && defined(__MINGW32__)
# if defined(AMQP_BUILD) && !defined(AMQP_STATIC)
# define AMQP_PUBLIC_FUNCTION __declspec(dllexport)
# define AMQP_PUBLIC_VARIABLE __declspec(dllexport) extern
# else
# define AMQP_PUBLIC_FUNCTION
# if !defined(AMQP_STATIC)
# define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern
# else
# define AMQP_PUBLIC_VARIABLE extern
# endif
# endif
# define AMQP_CALL __cdecl
#elif defined(_WIN32) && defined(__CYGWIN__)
# if defined(AMQP_BUILD) && !defined(AMQP_STATIC)
# define AMQP_PUBLIC_FUNCTION __declspec(dllexport)
# define AMQP_PUBLIC_VARIABLE __declspec(dllexport)
# else
# define AMQP_PUBLIC_FUNCTION
# if !defined(AMQP_STATIC)
# define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern
# else
# define AMQP_PUBLIC_VARIABLE extern
# endif
# endif
# define AMQP_CALL __cdecl
#elif defined(__GNUC__) && __GNUC__ >= 4
# define AMQP_PUBLIC_FUNCTION \
__attribute__ ((visibility ("default")))
# define AMQP_PUBLIC_VARIABLE \
__attribute__ ((visibility ("default"))) extern
# define AMQP_CALL
#else
# define AMQP_PUBLIC_FUNCTION
# define AMQP_PUBLIC_VARIABLE extern
# define AMQP_CALL
#endif
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
# define AMQP_DEPRECATED(function) \
function __attribute__ ((__deprecated__))
#elif defined(_MSC_VER)
# define AMQP_DEPRECATED(function) \
__declspec(deprecated) function
#else
# define AMQP_DEPRECATED(function)
#endif
/* Define ssize_t on Win32/64 platforms
See: http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-April/030649.html for details
*/
#if !defined(_W64)
#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
#define _W64 __w64
#else
#define _W64
#endif
#endif
#ifdef _MSC_VER
#ifdef _WIN64
typedef __int64 ssize_t;
#else
typedef _W64 int ssize_t;
#endif
#endif
#if defined(_WIN32) && defined(__MINGW32__)
#include
#endif
/** \endcond */
#include
#include
struct timeval;
AMQP_BEGIN_DECLS
/**
* \def AMQP_VERSION_MAJOR
*
* Major library version number compile-time constant
*
* The major version is incremented when backwards incompatible API changes
* are made.
*
* \sa AMQP_VERSION, AMQP_VERSION_STRING
*
* \since v0.4.0
*/
/**
* \def AMQP_VERSION_MINOR
*
* Minor library version number compile-time constant
*
* The minor version is incremented when new APIs are added. Existing APIs
* are left alone.
*
* \sa AMQP_VERSION, AMQP_VERSION_STRING
*
* \since v0.4.0
*/
/**
* \def AMQP_VERSION_PATCH
*
* Patch library version number compile-time constant
*
* The patch version is incremented when library code changes, but the API
* is not changed.
*
* \sa AMQP_VERSION, AMQP_VERSION_STRING
*
* \since v0.4.0
*/
/**
* \def AMQP_VERSION_IS_RELEASE
*
* Version constant set to 1 for tagged release, 0 otherwise
*
* NOTE: versions that are not tagged releases are not guaranteed to be API/ABI
* compatible with older releases, and may change commit-to-commit.
*
* \sa AMQP_VERSION, AMQP_VERSION_STRING
*
* \since v0.4.0
*/
/*
* Developer note: when changing these, be sure to update SOVERSION constants
* in CMakeLists.txt and configure.ac
*/
#define AMQP_VERSION_MAJOR 0
#define AMQP_VERSION_MINOR 8
#define AMQP_VERSION_PATCH 0
#define AMQP_VERSION_IS_RELEASE 1
/**
* \def AMQP_VERSION_CODE
*
* Helper macro to geneate a packed version code suitable for
* comparison with AMQP_VERSION.
*
* \sa amqp_version_number() AMQP_VERSION_MAJOR, AMQP_VERSION_MINOR,
* AMQP_VERSION_PATCH, AMQP_VERSION_IS_RELEASE, AMQP_VERSION
*
* \since v0.6.1
*/
#define AMQP_VERSION_CODE(major, minor, patch, release) \
((major << 24) | \
(minor << 16) | \
(patch << 8) | \
(release))
/**
* \def AMQP_VERSION
*
* Packed version number
*
* AMQP_VERSION is a 4-byte unsigned integer with the most significant byte
* set to AMQP_VERSION_MAJOR, the second most significant byte set to
* AMQP_VERSION_MINOR, third most significant byte set to AMQP_VERSION_PATCH,
* and the lowest byte set to AMQP_VERSION_IS_RELEASE.
*
* For example version 2.3.4 which is released version would be encoded as
* 0x02030401
*
* \sa amqp_version_number() AMQP_VERSION_MAJOR, AMQP_VERSION_MINOR,
* AMQP_VERSION_PATCH, AMQP_VERSION_IS_RELEASE, AMQP_VERSION_CODE
*
* \since v0.4.0
*/
#define AMQP_VERSION AMQP_VERSION_CODE(AMQP_VERSION_MAJOR, \
AMQP_VERSION_MINOR, \
AMQP_VERSION_PATCH, \
AMQP_VERSION_IS_RELEASE)
/** \cond HIDE_FROM_DOXYGEN */
#define AMQ_STRINGIFY(s) AMQ_STRINGIFY_HELPER(s)
#define AMQ_STRINGIFY_HELPER(s) #s
#define AMQ_VERSION_STRING AMQ_STRINGIFY(AMQP_VERSION_MAJOR) "." \
AMQ_STRINGIFY(AMQP_VERSION_MINOR) "." \
AMQ_STRINGIFY(AMQP_VERSION_PATCH)
/** \endcond */
/**
* \def AMQP_VERSION_STRING
*
* Version string compile-time constant
*
* Non-released versions of the library will have "-pre" appended to the
* version string
*
* \sa amqp_version()
*
* \since v0.4.0
*/
#if AMQP_VERSION_IS_RELEASE
# define AMQP_VERSION_STRING AMQ_VERSION_STRING
#else
# define AMQP_VERSION_STRING AMQ_VERSION_STRING "-pre"
#endif
/**
* Returns the rabbitmq-c version as a packed integer.
*
* See \ref AMQP_VERSION
*
* \return packed 32-bit integer representing version of library at runtime
*
* \sa AMQP_VERSION, amqp_version()
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
uint32_t
AMQP_CALL amqp_version_number(void);
/**
* Returns the rabbitmq-c version as a string.
*
* See \ref AMQP_VERSION_STRING
*
* \return a statically allocated string describing the version of rabbitmq-c.
*
* \sa amqp_version_number(), AMQP_VERSION_STRING, AMQP_VERSION
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
char const *
AMQP_CALL amqp_version(void);
/**
* \def AMQP_DEFAULT_FRAME_SIZE
*
* Default frame size (128Kb)
*
* \sa amqp_login(), amqp_login_with_properties()
*
* \since v0.4.0
*/
#define AMQP_DEFAULT_FRAME_SIZE 131072
/**
* \def AMQP_DEFAULT_MAX_CHANNELS
*
* Default maximum number of channels (0, no limit)
*
* \sa amqp_login(), amqp_login_with_properties()
*
* \since v0.4.0
*/
#define AMQP_DEFAULT_MAX_CHANNELS 0
/**
* \def AMQP_DEFAULT_HEARTBEAT
*
* Default heartbeat interval (0, heartbeat disabled)
*
* \sa amqp_login(), amqp_login_with_properties()
*
* \since v0.4.0
*/
#define AMQP_DEFAULT_HEARTBEAT 0
/**
* boolean type 0 = false, true otherwise
*
* \since v0.1
*/
typedef int amqp_boolean_t;
/**
* Method number
*
* \since v0.1
*/
typedef uint32_t amqp_method_number_t;
/**
* Bitmask for flags
*
* \since v0.1
*/
typedef uint32_t amqp_flags_t;
/**
* Channel type
*
* \since v0.1
*/
typedef uint16_t amqp_channel_t;
/**
* Buffer descriptor
*
* \since v0.1
*/
typedef struct amqp_bytes_t_ {
size_t len; /**< length of the buffer in bytes */
void *bytes; /**< pointer to the beginning of the buffer */
} amqp_bytes_t;
/**
* Decimal data type
*
* \since v0.1
*/
typedef struct amqp_decimal_t_ {
uint8_t decimals; /**< the location of the decimal point */
uint32_t value; /**< the value before the decimal point is applied */
} amqp_decimal_t;
/**
* AMQP field table
*
* An AMQP field table is a set of key-value pairs.
* A key is a UTF-8 encoded string up to 128 bytes long, and are not null
* terminated.
* A value can be one of several different datatypes. \sa amqp_field_value_kind_t
*
* \sa amqp_table_entry_t
*
* \since v0.1
*/
typedef struct amqp_table_t_ {
int num_entries; /**< length of entries array */
struct amqp_table_entry_t_ *entries; /**< an array of table entries */
} amqp_table_t;
/**
* An AMQP Field Array
*
* A repeated set of field values, all must be of the same type
*
* \since v0.1
*/
typedef struct amqp_array_t_ {
int num_entries; /**< Number of entries in the table */
struct amqp_field_value_t_ *entries; /**< linked list of field values */
} amqp_array_t;
/*
0-9 0-9-1 Qpid/Rabbit Type Remarks
---------------------------------------------------------------------------
t t Boolean
b b Signed 8-bit
B Unsigned 8-bit
U s Signed 16-bit (A1)
u Unsigned 16-bit
I I I Signed 32-bit
i Unsigned 32-bit
L l Signed 64-bit (B)
l Unsigned 64-bit
f f 32-bit float
d d 64-bit float
D D D Decimal
s Short string (A2)
S S S Long string
A Nested Array
T T T Timestamp (u64)
F F F Nested Table
V V V Void
x Byte array
Remarks:
A1, A2: Notice how the types **CONFLICT** here. In Qpid and Rabbit,
's' means a signed 16-bit integer; in 0-9-1, it means a
short string.
B: Notice how the signednesses **CONFLICT** here. In Qpid and Rabbit,
'l' means a signed 64-bit integer; in 0-9-1, it means an unsigned
64-bit integer.
I'm going with the Qpid/Rabbit types, where there's a conflict, and
the 0-9-1 types otherwise. 0-8 is a subset of 0-9, which is a subset
of the other two, so this will work for both 0-8 and 0-9-1 branches of
the code.
*/
/**
* A field table value
*
* \since v0.1
*/
typedef struct amqp_field_value_t_ {
uint8_t kind; /**< the type of the entry /sa amqp_field_value_kind_t */
union {
amqp_boolean_t boolean; /**< boolean type AMQP_FIELD_KIND_BOOLEAN */
int8_t i8; /**< int8_t type AMQP_FIELD_KIND_I8 */
uint8_t u8; /**< uint8_t type AMQP_FIELD_KIND_U8 */
int16_t i16; /**< int16_t type AMQP_FIELD_KIND_I16 */
uint16_t u16; /**< uint16_t type AMQP_FIELD_KIND_U16 */
int32_t i32; /**< int32_t type AMQP_FIELD_KIND_I32 */
uint32_t u32; /**< uint32_t type AMQP_FIELD_KIND_U32 */
int64_t i64; /**< int64_t type AMQP_FIELD_KIND_I64 */
uint64_t u64; /**< uint64_t type AMQP_FIELD_KIND_U64, AMQP_FIELD_KIND_TIMESTAMP */
float f32; /**< float type AMQP_FIELD_KIND_F32 */
double f64; /**< double type AMQP_FIELD_KIND_F64 */
amqp_decimal_t decimal; /**< amqp_decimal_t AMQP_FIELD_KIND_DECIMAL */
amqp_bytes_t bytes; /**< amqp_bytes_t type AMQP_FIELD_KIND_UTF8, AMQP_FIELD_KIND_BYTES */
amqp_table_t table; /**< amqp_table_t type AMQP_FIELD_KIND_TABLE */
amqp_array_t array; /**< amqp_array_t type AMQP_FIELD_KIND_ARRAY */
} value; /**< a union of the value */
} amqp_field_value_t;
/**
* An entry in a field-table
*
* \sa amqp_table_encode(), amqp_table_decode(), amqp_table_clone()
*
* \since v0.1
*/
typedef struct amqp_table_entry_t_ {
amqp_bytes_t key; /**< the table entry key. Its a null-terminated UTF-8 string,
* with a maximum size of 128 bytes */
amqp_field_value_t value; /**< the table entry values */
} amqp_table_entry_t;
/**
* Field value types
*
* \since v0.1
*/
typedef enum {
AMQP_FIELD_KIND_BOOLEAN = 't', /**< boolean type. 0 = false, 1 = true @see amqp_boolean_t */
AMQP_FIELD_KIND_I8 = 'b', /**< 8-bit signed integer, datatype: int8_t */
AMQP_FIELD_KIND_U8 = 'B', /**< 8-bit unsigned integer, datatype: uint8_t */
AMQP_FIELD_KIND_I16 = 's', /**< 16-bit signed integer, datatype: int16_t */
AMQP_FIELD_KIND_U16 = 'u', /**< 16-bit unsigned integer, datatype: uint16_t */
AMQP_FIELD_KIND_I32 = 'I', /**< 32-bit signed integer, datatype: int32_t */
AMQP_FIELD_KIND_U32 = 'i', /**< 32-bit unsigned integer, datatype: uint32_t */
AMQP_FIELD_KIND_I64 = 'l', /**< 64-bit signed integer, datatype: int64_t */
AMQP_FIELD_KIND_U64 = 'L', /**< 64-bit unsigned integer, datatype: uint64_t */
AMQP_FIELD_KIND_F32 = 'f', /**< single-precision floating point value, datatype: float */
AMQP_FIELD_KIND_F64 = 'd', /**< double-precision floating point value, datatype: double */
AMQP_FIELD_KIND_DECIMAL = 'D', /**< amqp-decimal value, datatype: amqp_decimal_t */
AMQP_FIELD_KIND_UTF8 = 'S', /**< UTF-8 null-terminated character string, datatype: amqp_bytes_t */
AMQP_FIELD_KIND_ARRAY = 'A', /**< field array (repeated values of another datatype. datatype: amqp_array_t */
AMQP_FIELD_KIND_TIMESTAMP = 'T',/**< 64-bit timestamp. datatype uint64_t */
AMQP_FIELD_KIND_TABLE = 'F', /**< field table. encapsulates a table inside a table entry. datatype: amqp_table_t */
AMQP_FIELD_KIND_VOID = 'V', /**< empty entry */
AMQP_FIELD_KIND_BYTES = 'x' /**< unformatted byte string, datatype: amqp_bytes_t */
} amqp_field_value_kind_t;
/**
* A list of allocation blocks
*
* \since v0.1
*/
typedef struct amqp_pool_blocklist_t_ {
int num_blocks; /**< Number of blocks in the block list */
void **blocklist; /**< Array of memory blocks */
} amqp_pool_blocklist_t;
/**
* A memory pool
*
* \since v0.1
*/
typedef struct amqp_pool_t_ {
size_t pagesize; /**< the size of the page in bytes.
* allocations less than or equal to this size are
* allocated in the pages block list
* allocations greater than this are allocated in their
* own block in the large_blocks block list */
amqp_pool_blocklist_t pages; /**< blocks that are the size of pagesize */
amqp_pool_blocklist_t large_blocks; /**< allocations larger than the pagesize */
int next_page; /**< an index to the next unused page block */
char *alloc_block; /**< pointer to the current allocation block */
size_t alloc_used; /**< number of bytes in the current allocation block that has been used */
} amqp_pool_t;
/**
* An amqp method
*
* \since v0.1
*/
typedef struct amqp_method_t_ {
amqp_method_number_t id; /**< the method id number */
void *decoded; /**< pointer to the decoded method,
* cast to the appropriate type to use */
} amqp_method_t;
/**
* An AMQP frame
*
* \since v0.1
*/
typedef struct amqp_frame_t_ {
uint8_t frame_type; /**< frame type. The types:
* - AMQP_FRAME_METHOD - use the method union member
* - AMQP_FRAME_HEADER - use the properties union member
* - AMQP_FRAME_BODY - use the body_fragment union member
*/
amqp_channel_t channel; /**< the channel the frame was received on */
union {
amqp_method_t method; /**< a method, use if frame_type == AMQP_FRAME_METHOD */
struct {
uint16_t class_id; /**< the class for the properties */
uint64_t body_size; /**< size of the body in bytes */
void *decoded; /**< the decoded properties */
amqp_bytes_t raw; /**< amqp-encoded properties structure */
} properties; /**< message header, a.k.a., properties,
use if frame_type == AMQP_FRAME_HEADER */
amqp_bytes_t body_fragment; /**< a body fragment, use if frame_type == AMQP_FRAME_BODY */
struct {
uint8_t transport_high; /**< @internal first byte of handshake */
uint8_t transport_low; /**< @internal second byte of handshake */
uint8_t protocol_version_major; /**< @internal third byte of handshake */
uint8_t protocol_version_minor; /**< @internal fourth byte of handshake */
} protocol_header; /**< Used only when doing the initial handshake with the broker,
don't use otherwise */
} payload; /**< the payload of the frame */
} amqp_frame_t;
/**
* Response type
*
* \since v0.1
*/
typedef enum amqp_response_type_enum_ {
AMQP_RESPONSE_NONE = 0, /**< the library got an EOF from the socket */
AMQP_RESPONSE_NORMAL, /**< response normal, the RPC completed successfully */
AMQP_RESPONSE_LIBRARY_EXCEPTION,/**< library error, an error occurred in the library, examine the library_error */
AMQP_RESPONSE_SERVER_EXCEPTION /**< server exception, the broker returned an error, check replay */
} amqp_response_type_enum;
/**
* Reply from a RPC method on the broker
*
* \since v0.1
*/
typedef struct amqp_rpc_reply_t_ {
amqp_response_type_enum reply_type; /**< the reply type:
* - AMQP_RESPONSE_NORMAL - the RPC completed successfully
* - AMQP_RESPONSE_SERVER_EXCEPTION - the broker returned
* an exception, check the reply field
* - AMQP_RESPONSE_LIBRARY_EXCEPTION - the library
* encountered an error, check the library_error field
*/
amqp_method_t reply; /**< in case of AMQP_RESPONSE_SERVER_EXCEPTION this
* field will be set to the method returned from the broker */
int library_error; /**< in case of AMQP_RESPONSE_LIBRARY_EXCEPTION this
* field will be set to an error code. An error
* string can be retrieved using amqp_error_string */
} amqp_rpc_reply_t;
/**
* SASL method type
*
* \since v0.1
*/
typedef enum amqp_sasl_method_enum_ {
AMQP_SASL_METHOD_UNDEFINED = -1, /**< Invalid SASL method */
AMQP_SASL_METHOD_PLAIN = 0, /**< the PLAIN SASL method for authentication to the broker */
AMQP_SASL_METHOD_EXTERNAL = 1 /**< the EXTERNAL SASL method for authentication to the broker */
} amqp_sasl_method_enum;
/**
* connection state object
*
* \since v0.1
*/
typedef struct amqp_connection_state_t_ *amqp_connection_state_t;
/**
* Socket object
*
* \since v0.4.0
*/
typedef struct amqp_socket_t_ amqp_socket_t;
/**
* Status codes
*
* \since v0.4.0
*/
/* NOTE: When updating this enum, update the strings in librabbitmq/amqp_api.c */
typedef enum amqp_status_enum_
{
AMQP_STATUS_OK = 0x0, /**< Operation successful */
AMQP_STATUS_NO_MEMORY = -0x0001, /**< Memory allocation
failed */
AMQP_STATUS_BAD_AMQP_DATA = -0x0002, /**< Incorrect or corrupt
data was received from
the broker. This is a
protocol error. */
AMQP_STATUS_UNKNOWN_CLASS = -0x0003, /**< An unknown AMQP class
was received. This is
a protocol error. */
AMQP_STATUS_UNKNOWN_METHOD = -0x0004, /**< An unknown AMQP method
was received. This is
a protocol error. */
AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED= -0x0005, /**< Unable to resolve the
* hostname */
AMQP_STATUS_INCOMPATIBLE_AMQP_VERSION = -0x0006, /**< The broker advertised
an incompaible AMQP
version */
AMQP_STATUS_CONNECTION_CLOSED = -0x0007, /**< The connection to the
broker has been closed
*/
AMQP_STATUS_BAD_URL = -0x0008, /**< malformed AMQP URL */
AMQP_STATUS_SOCKET_ERROR = -0x0009, /**< A socket error
occurred */
AMQP_STATUS_INVALID_PARAMETER = -0x000A, /**< An invalid parameter
was passed into the
function */
AMQP_STATUS_TABLE_TOO_BIG = -0x000B, /**< The amqp_table_t object
cannot be serialized
because the output
buffer is too small */
AMQP_STATUS_WRONG_METHOD = -0x000C, /**< The wrong method was
received */
AMQP_STATUS_TIMEOUT = -0x000D, /**< Operation timed out */
AMQP_STATUS_TIMER_FAILURE = -0x000E, /**< The underlying system
timer facility failed */
AMQP_STATUS_HEARTBEAT_TIMEOUT = -0x000F, /**< Timed out waiting for
heartbeat */
AMQP_STATUS_UNEXPECTED_STATE = -0x0010, /**< Unexpected protocol
state */
AMQP_STATUS_SOCKET_CLOSED = -0x0011, /**< Underlying socket is
closed */
AMQP_STATUS_SOCKET_INUSE = -0x0012, /**< Underlying socket is
already open */
AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD = -0x0013, /**< Broker does not
support the requested
SASL mechanism */
AMQP_STATUS_UNSUPPORTED = -0x0014, /**< Parameter is unsupported
in this version */
_AMQP_STATUS_NEXT_VALUE = -0x0015, /**< Internal value */
AMQP_STATUS_TCP_ERROR = -0x0100, /**< A generic TCP error
occurred */
AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR = -0x0101, /**< An error occurred trying
to initialize the
socket library*/
_AMQP_STATUS_TCP_NEXT_VALUE = -0x0102, /**< Internal value */
AMQP_STATUS_SSL_ERROR = -0x0200, /**< A generic SSL error
occurred. */
AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED= -0x0201, /**< SSL validation of
hostname against
peer certificate
failed */
AMQP_STATUS_SSL_PEER_VERIFY_FAILED = -0x0202, /**< SSL validation of peer
certificate failed. */
AMQP_STATUS_SSL_CONNECTION_FAILED = -0x0203, /**< SSL handshake failed. */
_AMQP_STATUS_SSL_NEXT_VALUE = -0x0204 /**< Internal value */
} amqp_status_enum;
/**
* AMQP delivery modes.
* Use these values for the #amqp_basic_properties_t::delivery_mode field.
*
* \since v0.5
*/
typedef enum {
AMQP_DELIVERY_NONPERSISTENT = 1, /**< Non-persistent message */
AMQP_DELIVERY_PERSISTENT = 2 /**< Persistent message */
} amqp_delivery_mode_enum;
AMQP_END_DECLS
#include
AMQP_BEGIN_DECLS
/**
* Empty bytes structure
*
* \since v0.2
*/
AMQP_PUBLIC_VARIABLE const amqp_bytes_t amqp_empty_bytes;
/**
* Empty table structure
*
* \since v0.2
*/
AMQP_PUBLIC_VARIABLE const amqp_table_t amqp_empty_table;
/**
* Empty table array structure
*
* \since v0.2
*/
AMQP_PUBLIC_VARIABLE const amqp_array_t amqp_empty_array;
/* Compatibility macros for the above, to avoid the need to update
code written against earlier versions of librabbitmq. */
/**
* \def AMQP_EMPTY_BYTES
*
* Deprecated, use \ref amqp_empty_bytes instead
*
* \deprecated use \ref amqp_empty_bytes instead
*
* \since v0.1
*/
#define AMQP_EMPTY_BYTES amqp_empty_bytes
/**
* \def AMQP_EMPTY_TABLE
*
* Deprecated, use \ref amqp_empty_table instead
*
* \deprecated use \ref amqp_empty_table instead
*
* \since v0.1
*/
#define AMQP_EMPTY_TABLE amqp_empty_table
/**
* \def AMQP_EMPTY_ARRAY
*
* Deprecated, use \ref amqp_empty_array instead
*
* \deprecated use \ref amqp_empty_array instead
*
* \since v0.1
*/
#define AMQP_EMPTY_ARRAY amqp_empty_array
/**
* Initializes an amqp_pool_t memory allocation pool for use
*
* Readies an allocation pool for use. An amqp_pool_t
* must be initialized before use
*
* \param [in] pool the amqp_pool_t structure to initialize.
* Calling this function on a pool a pool that has
* already been initialized will result in undefined
* behavior
* \param [in] pagesize the unit size that the pool will allocate
* memory chunks in. Anything allocated against the pool
* with a requested size will be carved out of a block
* this size. Allocations larger than this will be
* allocated individually
*
* \sa recycle_amqp_pool(), empty_amqp_pool(), amqp_pool_alloc(),
* amqp_pool_alloc_bytes(), amqp_pool_t
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL init_amqp_pool(amqp_pool_t *pool, size_t pagesize);
/**
* Recycles an amqp_pool_t memory allocation pool
*
* Recycles the space allocate by the pool
*
* This invalidates all allocations made against the pool before this call is
* made, any use of any allocations made before recycle_amqp_pool() is called
* will result in undefined behavior.
*
* Note: this may or may not release memory, to force memory to be released
* call empty_amqp_pool().
*
* \param [in] pool the amqp_pool_t to recycle
*
* \sa recycle_amqp_pool(), empty_amqp_pool(), amqp_pool_alloc(),
* amqp_pool_alloc_bytes()
*
* \since v0.1
*
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL recycle_amqp_pool(amqp_pool_t *pool);
/**
* Empties an amqp memory pool
*
* Releases all memory associated with an allocation pool
*
* \param [in] pool the amqp_pool_t to empty
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL empty_amqp_pool(amqp_pool_t *pool);
/**
* Allocates a block of memory from an amqp_pool_t memory pool
*
* Memory will be aligned on a 8-byte boundary. If a 0-length allocation is
* requested, a NULL pointer will be returned.
*
* \param [in] pool the allocation pool to allocate the memory from
* \param [in] amount the size of the allocation in bytes.
* \return a pointer to the memory block, or NULL if the allocation cannot
* be satisfied.
*
* \sa init_amqp_pool(), recycle_amqp_pool(), empty_amqp_pool(),
* amqp_pool_alloc_bytes()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
void *
AMQP_CALL amqp_pool_alloc(amqp_pool_t *pool, size_t amount);
/**
* Allocates a block of memory from an amqp_pool_t to an amqp_bytes_t
*
* Memory will be aligned on a 8-byte boundary. If a 0-length allocation is
* requested, output.bytes = NULL.
*
* \param [in] pool the allocation pool to allocate the memory from
* \param [in] amount the size of the allocation in bytes
* \param [in] output the location to store the pointer. On success
* output.bytes will be set to the beginning of the buffer
* output.len will be set to amount
* On error output.bytes will be set to NULL and output.len
* set to 0
*
* \sa init_amqp_pool(), recycle_amqp_pool(), empty_amqp_pool(),
* amqp_pool_alloc()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL amqp_pool_alloc_bytes(amqp_pool_t *pool, size_t amount, amqp_bytes_t *output);
/**
* Wraps a c string in an amqp_bytes_t
*
* Takes a string, calculates its length and creates an
* amqp_bytes_t that points to it. The string is not duplicated.
*
* For a given input cstr, The amqp_bytes_t output.bytes is the
* same as cstr, output.len is the length of the string not including
* the \0 terminator
*
* This function uses strlen() internally so cstr must be properly
* terminated
*
* \param [in] cstr the c string to wrap
* \return an amqp_bytes_t that describes the string
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_bytes_t
AMQP_CALL amqp_cstring_bytes(char const *cstr);
/**
* Duplicates an amqp_bytes_t buffer.
*
* The buffer is cloned and the contents copied.
*
* The memory associated with the output is allocated
* with amqp_bytes_malloc() and should be freed with
* amqp_bytes_free()
*
* \param [in] src
* \return a clone of the src
*
* \sa amqp_bytes_free(), amqp_bytes_malloc()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_bytes_t
AMQP_CALL amqp_bytes_malloc_dup(amqp_bytes_t src);
/**
* Allocates a amqp_bytes_t buffer
*
* Creates an amqp_bytes_t buffer of the specified amount, the buffer should be
* freed using amqp_bytes_free()
*
* \param [in] amount the size of the buffer in bytes
* \returns an amqp_bytes_t with amount bytes allocated.
* output.bytes will be set to NULL on error
*
* \sa amqp_bytes_free(), amqp_bytes_malloc_dup()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_bytes_t
AMQP_CALL amqp_bytes_malloc(size_t amount);
/**
* Frees an amqp_bytes_t buffer
*
* Frees a buffer allocated with amqp_bytes_malloc() or amqp_bytes_malloc_dup()
*
* Calling amqp_bytes_free on buffers not allocated with one
* of those two functions will result in undefined behavior
*
* \param [in] bytes the buffer to free
*
* \sa amqp_bytes_malloc(), amqp_bytes_malloc_dup()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL amqp_bytes_free(amqp_bytes_t bytes);
/**
* Allocate and initialize a new amqp_connection_state_t object
*
* amqp_connection_state_t objects created with this function
* should be freed with amqp_destroy_connection()
*
* \returns an opaque pointer on success, NULL or 0 on failure.
*
* \sa amqp_destroy_connection()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_connection_state_t
AMQP_CALL amqp_new_connection(void);
/**
* Get the underlying socket descriptor for the connection
*
* \warning Use the socket returned from this function carefully, incorrect use
* of the socket outside of the library will lead to undefined behavior.
* Additionally rabbitmq-c may use the socket differently version-to-version,
* what may work in one version, may break in the next version. Be sure to
* throughly test any applications that use the socket returned by this
* function especially when using a newer version of rabbitmq-c
*
* \param [in] state the connection object
* \returns the socket descriptor if one has been set, -1 otherwise
*
* \sa amqp_tcp_socket_new(), amqp_ssl_socket_new(), amqp_socket_open()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_get_sockfd(amqp_connection_state_t state);
/**
* Deprecated, use amqp_tcp_socket_new() or amqp_ssl_socket_new()
*
* \deprecated Use amqp_tcp_socket_new() or amqp_ssl_socket_new()
*
* Sets the socket descriptor associated with the connection. The socket
* should be connected to a broker, and should not be read to or written from
* before calling this function. A socket descriptor can be created and opened
* using amqp_open_socket()
*
* \param [in] state the connection object
* \param [in] sockfd the socket
*
* \sa amqp_open_socket(), amqp_tcp_socket_new(), amqp_ssl_socket_new()
*
* \since v0.1
*/
AMQP_DEPRECATED(
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL amqp_set_sockfd(amqp_connection_state_t state, int sockfd)
);
/**
* Tune client side parameters
*
* \warning This function may call abort() if the connection is in a certain
* state. As such it should probably not be called code outside the library.
* connection parameters should be specified when calling amqp_login() or
* amqp_login_with_properties()
*
* This function changes channel_max, frame_max, and heartbeat parameters, on
* the client side only. It does not try to renegotiate these parameters with
* the broker. Using this function will lead to unexpected results.
*
* \param [in] state the connection object
* \param [in] channel_max the maximum number of channels.
* The largest this can be is 65535
* \param [in] frame_max the maximum size of an frame.
* The smallest this can be is 4096
* The largest this can be is 2147483647
* Unless you know what you're doing the recommended
* size is 131072 or 128KB
* \param [in] heartbeat the number of seconds between heartbeats
*
* \return AMQP_STATUS_OK on success, an amqp_status_enum value otherwise.
* Possible error codes include:
* - AMQP_STATUS_NO_MEMORY memory allocation failed.
* - AMQP_STATUS_TIMER_FAILURE the underlying system timer indicated it
* failed.
*
* \sa amqp_login(), amqp_login_with_properties()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_tune_connection(amqp_connection_state_t state,
int channel_max,
int frame_max,
int heartbeat);
/**
* Get the maximum number of channels the connection can handle
*
* The maximum number of channels is set when connection negotiation takes
* place in amqp_login() or amqp_login_with_properties().
*
* \param [in] state the connection object
* \return the maximum number of channels. 0 if there is no limit
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_get_channel_max(amqp_connection_state_t state);
/**
* Get the maximum size of an frame the connection can handle
*
* The maximum size of an frame is set when connection negotiation takes
* place in amqp_login() or amqp_login_with_properties().
*
* \param [in] state the connection object
* \return the maximum size of an frame.
*
* \since v0.6
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_get_frame_max(amqp_connection_state_t state);
/**
* Get the number of seconds between heartbeats of the connection
*
* The number of seconds between heartbeats is set when connection
* negotiation takes place in amqp_login() or amqp_login_with_properties().
*
* \param [in] state the connection object
* \return the number of seconds between heartbeats.
*
* \since v0.6
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_get_heartbeat(amqp_connection_state_t state);
/**
* Destroys an amqp_connection_state_t object
*
* Destroys a amqp_connection_state_t object that was created with
* amqp_new_connection(). If the connection with the broker is open, it will be
* implicitly closed with a reply code of 200 (success). Any memory that
* would be freed with amqp_maybe_release_buffers() or
* amqp_maybe_release_buffers_on_channel() will be freed, and use of that
* memory will caused undefined behavior.
*
* \param [in] state the connection object
* \return AMQP_STATUS_OK on success. amqp_status_enum value failure
*
* \sa amqp_new_connection()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_destroy_connection(amqp_connection_state_t state);
/**
* Process incoming data
*
* \warning This is a low-level function intended for those who want to
* have greater control over input and output over the socket from the
* broker. Correctly using this function requires in-depth knowledge of AMQP
* and rabbitmq-c.
*
* For a given buffer of data received from the broker, decode the first
* frame in the buffer. If more than one frame is contained in the input buffer
* the return value will be less than the received_data size, the caller should
* adjust received_data buffer descriptor to point to the beginning of the
* buffer + the return value.
*
* \param [in] state the connection object
* \param [in] received_data a buffer of data received from the broker. The
* function will return the number of bytes of the buffer it used. The
* function copies these bytes to an internal buffer: this part of the buffer
* may be reused after this function successfully completes.
* \param [in,out] decoded_frame caller should pass in a pointer to an
* amqp_frame_t struct. If there is enough data in received_data for a
* complete frame, decoded_frame->frame_type will be set to something OTHER
* than 0. decoded_frame may contain members pointing to memory owned by
* the state object. This memory can be recycled with amqp_maybe_release_buffers()
* or amqp_maybe_release_buffers_on_channel()
* \return number of bytes consumed from received_data or 0 if a 0-length
* buffer was passed. A negative return value indicates failure. Possible errors:
* - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely in
* an indeterminate state making recovery unlikely. Client should note the error
* and terminate the application
* - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection
* should be shutdown immediately
* - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the
* broker. This is likely a protocol error and the connection should be
* shutdown immediately
* - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class
* was received from the broker. This is likely a protocol error and the
* connection should be shutdown immediately
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_handle_input(amqp_connection_state_t state,
amqp_bytes_t received_data,
amqp_frame_t *decoded_frame);
/**
* Check to see if connection memory can be released
*
* \deprecated This function is deprecated in favor of
* amqp_maybe_release_buffers() or amqp_maybe_release_buffers_on_channel()
*
* Checks the state of an amqp_connection_state_t object to see if
* amqp_release_buffers() can be called successfully.
*
* \param [in] state the connection object
* \returns TRUE if the buffers can be released FALSE otherwise
*
* \sa amqp_release_buffers() amqp_maybe_release_buffers()
* amqp_maybe_release_buffers_on_channel()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_boolean_t
AMQP_CALL amqp_release_buffers_ok(amqp_connection_state_t state);
/**
* Release amqp_connection_state_t owned memory
*
* \deprecated This function is deprecated in favor of
* amqp_maybe_release_buffers() or amqp_maybe_release_buffers_on_channel()
*
* \warning caller should ensure amqp_release_buffers_ok() returns true before
* calling this function. Failure to do so may result in abort() being called.
*
* Release memory owned by the amqp_connection_state_t for reuse by the
* library. Use of any memory returned by the library before this function is
* called will result in undefined behavior.
*
* \note internally rabbitmq-c tries to reuse memory when possible. As a result
* its possible calling this function may not have a noticeable effect on
* memory usage.
*
* \param [in] state the connection object
*
* \sa amqp_release_buffers_ok() amqp_maybe_release_buffers()
* amqp_maybe_release_buffers_on_channel()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL amqp_release_buffers(amqp_connection_state_t state);
/**
* Release amqp_connection_state_t owned memory
*
* Release memory owned by the amqp_connection_state_t object related to any
* channel, allowing reuse by the library. Use of any memory returned by the
* library before this function is called with result in undefined behavior.
*
* \note internally rabbitmq-c tries to reuse memory when possible. As a result
* its possible calling this function may not have a noticeable effect on
* memory usage.
*
* \param [in] state the connection object
*
* \sa amqp_maybe_release_buffers_on_channel()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL amqp_maybe_release_buffers(amqp_connection_state_t state);
/**
* Release amqp_connection_state_t owned memory related to a channel
*
* Release memory owned by the amqp_connection_state_t object related to the
* specified channel, allowing reuse by the library. Use of any memory returned
* the library for a specific channel will result in undefined behavior.
*
* \note internally rabbitmq-c tries to reuse memory when possible. As a result
* its possible calling this function may not have a noticeable effect on
* memory usage.
*
* \param [in] state the connection object
* \param [in] channel the channel specifier for which memory should be
* released. Note that the library does not care about the state of the
* channel when calling this function
*
* \sa amqp_maybe_release_buffers()
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL amqp_maybe_release_buffers_on_channel(amqp_connection_state_t state,
amqp_channel_t channel);
/**
* Send a frame to the broker
*
* \param [in] state the connection object
* \param [in] frame the frame to send to the broker
* \return AMQP_STATUS_OK on success, an amqp_status_enum value on error.
* Possible error codes:
* - AMQP_STATUS_BAD_AMQP_DATA the serialized form of the method or
* properties was too large to fit in a single AMQP frame, or the
* method contains an invalid value. The frame was not sent.
* - AMQP_STATUS_TABLE_TOO_BIG the serialized form of an amqp_table_t is
* too large to fit in a single AMQP frame. Frame was not sent.
* - AMQP_STATUS_UNKNOWN_METHOD an invalid method type was passed in
* - AMQP_STATUS_UNKNOWN_CLASS an invalid properties type was passed in
* - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. The frame
* was sent
* - AMQP_STATUS_SOCKET_ERROR
* - AMQP_STATUS_SSL_ERROR
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_send_frame(amqp_connection_state_t state, amqp_frame_t const *frame);
/**
* Compare two table entries
*
* Works just like strcmp(), comparing two the table keys, datatype, then values
*
* \param [in] entry1 the entry on the left
* \param [in] entry2 the entry on the right
* \return 0 if entries are equal, 0 < if left is greater, 0 > if right is greater
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_table_entry_cmp(void const *entry1, void const *entry2);
/**
* Open a socket to a remote host
*
* \deprecated This function is deprecated in favor of amqp_socket_open()
*
* Looks up the hostname, then attempts to open a socket to the host using
* the specified portnumber. It also sets various options on the socket to
* improve performance and correctness.
*
* \param [in] hostname this can be a hostname or IP address.
* Both IPv4 and IPv6 are acceptable
* \param [in] portnumber the port to connect on. RabbitMQ brokers
* listen on port 5672, and 5671 for SSL
* \return a positive value indicates success and is the sockfd. A negative
* value (see amqp_status_enum)is returned on failure. Possible error codes:
* - AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR Initialization of underlying socket
* library failed.
* - AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED hostname lookup failed.
* - AMQP_STATUS_SOCKET_ERROR a socket error occurred. errno or WSAGetLastError()
* may return more useful information.
*
* \note IPv6 support was added in v0.3
*
* \sa amqp_socket_open() amqp_set_sockfd()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_open_socket(char const *hostname, int portnumber);
/**
* Send initial AMQP header to the broker
*
* \warning this is a low level function intended for those who want to
* interact with the broker at a very low level. Use of this function without
* understanding what it does will result in AMQP protocol errors.
*
* This function sends the AMQP protocol header to the broker.
*
* \param [in] state the connection object
* \return AMQP_STATUS_OK on success, a negative value on failure. Possible
* error codes:
* - AMQP_STATUS_CONNECTION_CLOSED the connection to the broker was closed.
* - AMQP_STATUS_SOCKET_ERROR a socket error occurred. It is likely the
* underlying socket has been closed. errno or WSAGetLastError() may provide
* further information.
* - AMQP_STATUS_SSL_ERROR a SSL error occurred. The connection to the broker
* was closed.
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_send_header(amqp_connection_state_t state);
/**
* Checks to see if there are any incoming frames ready to be read
*
* Checks to see if there are any amqp_frame_t objects buffered by the
* amqp_connection_state_t object. Having one or more frames buffered means
* that amqp_simple_wait_frame() or amqp_simple_wait_frame_noblock() will
* return a frame without potentially blocking on a read() call.
*
* \param [in] state the connection object
* \return TRUE if there are frames enqueued, FALSE otherwise
*
* \sa amqp_simple_wait_frame() amqp_simple_wait_frame_noblock()
* amqp_data_in_buffer()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_boolean_t
AMQP_CALL amqp_frames_enqueued(amqp_connection_state_t state);
/**
* Read a single amqp_frame_t
*
* Waits for the next amqp_frame_t frame to be read from the broker.
* This function has the potential to block for a long time in the case of
* waiting for a basic.deliver method frame from the broker.
*
* The library may buffer frames. When an amqp_connection_state_t object
* has frames buffered calling amqp_simple_wait_frame() will return an
* amqp_frame_t without entering a blocking read(). You can test to see if
* an amqp_connection_state_t object has frames buffered by calling the
* amqp_frames_enqueued() function.
*
* The library has a socket read buffer. When there is data in an
* amqp_connection_state_t read buffer, amqp_simple_wait_frame() may return an
* amqp_frame_t without entering a blocking read(). You can test to see if an
* amqp_connection_state_t object has data in its read buffer by calling the
* amqp_data_in_buffer() function.
*
* \param [in] state the connection object
* \param [out] decoded_frame the frame
* \return AMQP_STATUS_OK on success, an amqp_status_enum value
* is returned otherwise. Possible errors include:
* - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely in
* an indeterminate state making recovery unlikely. Client should note the error
* and terminate the application
* - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection
* should be shutdown immediately
* - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the
* broker. This is likely a protocol error and the connection should be
* shutdown immediately
* - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class
* was received from the broker. This is likely a protocol error and the
* connection should be shutdown immediately
* - AMQP_STATUS_HEARTBEAT_TIMEOUT timed out while waiting for heartbeat
* from the broker. The connection has been closed.
* - AMQP_STATUS_TIMER_FAILURE system timer indicated failure.
* - AMQP_STATUS_SOCKET_ERROR a socket error occurred. The connection has
* been closed
* - AMQP_STATUS_SSL_ERROR a SSL socket error occurred. The connection has
* been closed.
*
* \sa amqp_simple_wait_frame_noblock() amqp_frames_enqueued()
* amqp_data_in_buffer()
*
* \note as of v0.4.0 this function will no longer return heartbeat frames
* when enabled by specifying a non-zero heartbeat value in amqp_login().
* Heartbeating is handled internally by the library.
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_simple_wait_frame(amqp_connection_state_t state,
amqp_frame_t *decoded_frame);
/**
* Read a single amqp_frame_t with a timeout.
*
* Waits for the next amqp_frame_t frame to be read from the broker, up to
* a timespan specified by tv. The function will return AMQP_STATUS_TIMEOUT
* if the timeout is reached. The tv value is not modified by the function.
*
* If a 0 timeval is specified, the function behaves as if its non-blocking: it
* will test to see if a frame can be read from the broker, and return immediately.
*
* If NULL is passed in for tv, the function will behave like
* amqp_simple_wait_frame() and block until a frame is received from the broker
*
* The library may buffer frames. When an amqp_connection_state_t object
* has frames buffered calling amqp_simple_wait_frame_noblock() will return an
* amqp_frame_t without entering a blocking read(). You can test to see if an
* amqp_connection_state_t object has frames buffered by calling the
* amqp_frames_enqueued() function.
*
* The library has a socket read buffer. When there is data in an
* amqp_connection_state_t read buffer, amqp_simple_wait_frame_noblock() may return
* an amqp_frame_t without entering a blocking read(). You can test to see if an
* amqp_connection_state_t object has data in its read buffer by calling the
* amqp_data_in_buffer() function.
*
* \note This function does not return heartbeat frames. When enabled, heartbeating
* is handed internally internally by the library
*
* \param [in,out] state the connection object
* \param [out] decoded_frame the frame
* \param [in] tv the maximum time to wait for a frame to be read. Setting
* tv->tv_sec = 0 and tv->tv_usec = 0 will do a non-blocking read. Specifying
* NULL for tv will make the function block until a frame is read.
* \return AMQP_STATUS_OK on success. An amqp_status_enum value is returned
* otherwise. Possible errors include:
* - AMQP_STATUS_TIMEOUT the timeout was reached while waiting for a frame
* from the broker.
* - AMQP_STATUS_INVALID_PARAMETER the tv parameter contains an invalid value.
* - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely in
* an indeterminate state making recovery unlikely. Client should note the error
* and terminate the application
* - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection
* should be shutdown immediately
* - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the
* broker. This is likely a protocol error and the connection should be
* shutdown immediately
* - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class
* was received from the broker. This is likely a protocol error and the
* connection should be shutdown immediately
* - AMQP_STATUS_HEARTBEAT_TIMEOUT timed out while waiting for heartbeat
* from the broker. The connection has been closed.
* - AMQP_STATUS_TIMER_FAILURE system timer indicated failure.
* - AMQP_STATUS_SOCKET_ERROR a socket error occurred. The connection has
* been closed
* - AMQP_STATUS_SSL_ERROR a SSL socket error occurred. The connection has
* been closed.
*
* \sa amqp_simple_wait_frame() amqp_frames_enqueued() amqp_data_in_buffer()
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_simple_wait_frame_noblock(amqp_connection_state_t state,
amqp_frame_t *decoded_frame,
struct timeval *tv);
/**
* Waits for a specific method from the broker
*
* \warning You probably don't want to use this function. If this function
* doesn't receive exactly the frame requested it closes the whole connection.
*
* Waits for a single method on a channel from the broker.
* If a frame is received that does not match expected_channel
* or expected_method the program will abort
*
* \param [in] state the connection object
* \param [in] expected_channel the channel that the method should be delivered on
* \param [in] expected_method the method to wait for
* \param [out] output the method
* \returns AMQP_STATUS_OK on success. An amqp_status_enum value is returned
* otherwise. Possible errors include:
* - AMQP_STATUS_WRONG_METHOD a frame containing the wrong method, wrong frame
* type or wrong channel was received. The connection is closed.
* - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely in
* an indeterminate state making recovery unlikely. Client should note the error
* and terminate the application
* - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection
* should be shutdown immediately
* - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the
* broker. This is likely a protocol error and the connection should be
* shutdown immediately
* - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class
* was received from the broker. This is likely a protocol error and the
* connection should be shutdown immediately
* - AMQP_STATUS_HEARTBEAT_TIMEOUT timed out while waiting for heartbeat
* from the broker. The connection has been closed.
* - AMQP_STATUS_TIMER_FAILURE system timer indicated failure.
* - AMQP_STATUS_SOCKET_ERROR a socket error occurred. The connection has
* been closed
* - AMQP_STATUS_SSL_ERROR a SSL socket error occurred. The connection has
* been closed.
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_simple_wait_method(amqp_connection_state_t state,
amqp_channel_t expected_channel,
amqp_method_number_t expected_method,
amqp_method_t *output);
/**
* Sends a method to the broker
*
* This is a thin wrapper around amqp_send_frame(), providing a way to send
* a method to the broker on a specified channel.
*
* \param [in] state the connection object
* \param [in] channel the channel object
* \param [in] id the method number
* \param [in] decoded the method object
* \returns AMQP_STATUS_OK on success, an amqp_status_enum value otherwise.
* Possible errors include:
* - AMQP_STATUS_BAD_AMQP_DATA the serialized form of the method or
* properties was too large to fit in a single AMQP frame, or the
* method contains an invalid value. The frame was not sent.
* - AMQP_STATUS_TABLE_TOO_BIG the serialized form of an amqp_table_t is
* too large to fit in a single AMQP frame. Frame was not sent.
* - AMQP_STATUS_UNKNOWN_METHOD an invalid method type was passed in
* - AMQP_STATUS_UNKNOWN_CLASS an invalid properties type was passed in
* - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. The frame
* was sent
* - AMQP_STATUS_SOCKET_ERROR
* - AMQP_STATUS_SSL_ERROR
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_send_method(amqp_connection_state_t state,
amqp_channel_t channel,
amqp_method_number_t id,
void *decoded);
/**
* Sends a method to the broker and waits for a method response
*
* \param [in] state the connection object
* \param [in] channel the channel object
* \param [in] request_id the method number of the request
* \param [in] expected_reply_ids a 0 terminated array of expected response
* method numbers
* \param [in] decoded_request_method the method to be sent to the broker
* \return a amqp_rpc_reply_t:
* - r.reply_type == AMQP_RESPONSE_NORMAL. RPC completed successfully
* - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an
* exception:
* - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception
* occurred, cast r.reply.decoded to amqp_channel_close_t* to see details
* of the exception. The client should amqp_send_method() a
* amqp_channel_close_ok_t. The channel must be re-opened before it
* can be used again. Any resources associated with the channel
* (auto-delete exchanges, auto-delete queues, consumers) are invalid
* and must be recreated before attempting to use them again.
* - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception
* occurred, cast r.reply.decoded to amqp_connection_close_t* to see
* details of the exception. The client amqp_send_method() a
* amqp_connection_close_ok_t and disconnect from the broker.
* - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. An exception occurred
* within the library. Examine r.library_error and compare it against
* amqp_status_enum values to determine the error.
*
* \sa amqp_simple_rpc_decoded()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_rpc_reply_t
AMQP_CALL amqp_simple_rpc(amqp_connection_state_t state,
amqp_channel_t channel,
amqp_method_number_t request_id,
amqp_method_number_t *expected_reply_ids,
void *decoded_request_method);
/**
* Sends a method to the broker and waits for a method response
*
* \param [in] state the connection object
* \param [in] channel the channel object
* \param [in] request_id the method number of the request
* \param [in] reply_id the method number expected in response
* \param [in] decoded_request_method the request method
* \return a pointer to the method returned from the broker, or NULL on error.
* On error amqp_get_rpc_reply() will return an amqp_rpc_reply_t with
* details on the error that occurred.
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
void *
AMQP_CALL amqp_simple_rpc_decoded(amqp_connection_state_t state,
amqp_channel_t channel,
amqp_method_number_t request_id,
amqp_method_number_t reply_id,
void *decoded_request_method);
/**
* Get the last global amqp_rpc_reply
*
* The API methods corresponding to most synchronous AMQP methods
* return a pointer to the decoded method result. Upon error, they
* return NULL, and we need some way of discovering what, if anything,
* went wrong. amqp_get_rpc_reply() returns the most recent
* amqp_rpc_reply_t instance corresponding to such an API operation
* for the given connection.
*
* Only use it for operations that do not themselves return
* amqp_rpc_reply_t; operations that do return amqp_rpc_reply_t
* generally do NOT update this per-connection-global amqp_rpc_reply_t
* instance.
*
* \param [in] state the connection object
* \return the most recent amqp_rpc_reply_t:
* - r.reply_type == AMQP_RESPONSE_NORMAL. RPC completed successfully
* - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an
* exception:
* - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception
* occurred, cast r.reply.decoded to amqp_channel_close_t* to see details
* of the exception. The client should amqp_send_method() a
* amqp_channel_close_ok_t. The channel must be re-opened before it
* can be used again. Any resources associated with the channel
* (auto-delete exchanges, auto-delete queues, consumers) are invalid
* and must be recreated before attempting to use them again.
* - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception
* occurred, cast r.reply.decoded to amqp_connection_close_t* to see
* details of the exception. The client amqp_send_method() a
* amqp_connection_close_ok_t and disconnect from the broker.
* - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. An exception occurred
* within the library. Examine r.library_error and compare it against
* amqp_status_enum values to determine the error.
*
* \sa amqp_simple_rpc_decoded()
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_rpc_reply_t
AMQP_CALL amqp_get_rpc_reply(amqp_connection_state_t state);
/**
* Login to the broker
*
* After using amqp_open_socket and amqp_set_sockfd, call
* amqp_login to complete connecting to the broker
*
* \param [in] state the connection object
* \param [in] vhost the virtual host to connect to on the broker. The default
* on most brokers is "/"
* \param [in] channel_max the limit for number of channels for the connection.
* 0 means no limit, and is a good default (AMQP_DEFAULT_MAX_CHANNELS)
* Note that the maximum number of channels the protocol supports
* is 65535 (2^16, with the 0-channel reserved). The server can
* set a lower channel_max and then the client will use the lowest
* of the two
* \param [in] frame_max the maximum size of an AMQP frame on the wire to
* request of the broker for this connection. 4096 is the minimum
* size, 2^31-1 is the maximum, a good default is 131072 (128KB), or
* AMQP_DEFAULT_FRAME_SIZE
* \param [in] heartbeat the number of seconds between heartbeat frames to
* request of the broker. A value of 0 disables heartbeats.
* Note rabbitmq-c only has partial support for heartbeats, as of
* v0.4.0 they are only serviced during amqp_basic_publish() and
* amqp_simple_wait_frame()/amqp_simple_wait_frame_noblock()
* \param [in] sasl_method the SASL method to authenticate with the broker.
* followed by the authentication information.
* For AMQP_SASL_METHOD_PLAIN, the AMQP_SASL_METHOD_PLAIN
* should be followed by two arguments in this order:
* const char* username, and const char* password.
* \return amqp_rpc_reply_t indicating success or failure.
* - r.reply_type == AMQP_RESPONSE_NORMAL. Login completed successfully
* - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. In most cases errors
* from the broker when logging in will be represented by the broker closing
* the socket. In this case r.library_error will be set to
* AMQP_STATUS_CONNECTION_CLOSED. This error can represent a number of
* error conditions including: invalid vhost, authentication failure.
* - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an
* exception:
* - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception
* occurred, cast r.reply.decoded to amqp_channel_close_t* to see details
* of the exception. The client should amqp_send_method() a
* amqp_channel_close_ok_t. The channel must be re-opened before it
* can be used again. Any resources associated with the channel
* (auto-delete exchanges, auto-delete queues, consumers) are invalid
* and must be recreated before attempting to use them again.
* - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception
* occurred, cast r.reply.decoded to amqp_connection_close_t* to see
* details of the exception. The client amqp_send_method() a
* amqp_connection_close_ok_t and disconnect from the broker.
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_rpc_reply_t
AMQP_CALL amqp_login(amqp_connection_state_t state, char const *vhost,
int channel_max, int frame_max, int heartbeat,
amqp_sasl_method_enum sasl_method, ...);
/**
* Login to the broker passing a properties table
*
* This function is similar to amqp_login() and differs in that it provides a
* way to pass client properties to the broker. This is commonly used to
* negotiate newer protocol features as they are supported by the broker.
*
* \param [in] state the connection object
* \param [in] vhost the virtual host to connect to on the broker. The default
* on most brokers is "/"
* \param [in] channel_max the limit for the number of channels for the connection.
* 0 means no limit, and is a good default (AMQP_DEFAULT_MAX_CHANNELS)
* Note that the maximum number of channels the protocol supports
* is 65535 (2^16, with the 0-channel reserved). The server can
* set a lower channel_max and then the client will use the lowest
* of the two
* \param [in] frame_max the maximum size of an AMQP frame ont he wire to
* request of the broker for this connection. 4096 is the minimum
* size, 2^31-1 is the maximum, a good default is 131072 (128KB), or
* AMQP_DEFAULT_FRAME_SIZE
* \param [in] heartbeat the number of seconds between heartbeat frame to
* request of the broker. A value of 0 disables heartbeats.
* Note rabbitmq-c only has partial support for hearts, as of
* v0.4.0 heartbeats are only serviced during amqp_basic_publish(),
* and amqp_simple_wait_frame()/amqp_simple_wait_frame_noblock()
* \param [in] properties a table of properties to send the broker.
* \param [in] sasl_method the SASL method to authenticate with the broker
* followed by the authentication information.
* For AMQP_SASL_METHOD_PLAN, the AMQP_SASL_METHOD_PLAIN parameter
* should be followed by two arguments in this order:
* const char* username, and const char* password.
* \return amqp_rpc_reply_t indicating success or failure.
* - r.reply_type == AMQP_RESPONSE_NORMAL. Login completed successfully
* - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. In most cases errors
* from the broker when logging in will be represented by the broker closing
* the socket. In this case r.library_error will be set to
* AMQP_STATUS_CONNECTION_CLOSED. This error can represent a number of
* error conditions including: invalid vhost, authentication failure.
* - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an
* exception:
* - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception
* occurred, cast r.reply.decoded to amqp_channel_close_t* to see details
* of the exception. The client should amqp_send_method() a
* amqp_channel_close_ok_t. The channel must be re-opened before it
* can be used again. Any resources associated with the channel
* (auto-delete exchanges, auto-delete queues, consumers) are invalid
* and must be recreated before attempting to use them again.
* - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception
* occurred, cast r.reply.decoded to amqp_connection_close_t* to see
* details of the exception. The client amqp_send_method() a
* amqp_connection_close_ok_t and disconnect from the broker.
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
amqp_rpc_reply_t
AMQP_CALL amqp_login_with_properties(amqp_connection_state_t state, char const *vhost,
int channel_max, int frame_max, int heartbeat,
const amqp_table_t *properties, amqp_sasl_method_enum sasl_method, ...);
struct amqp_basic_properties_t_;
/**
* Publish a message to the broker
*
* Publish a message on an exchange with a routing key.
*
* Note that at the AMQ protocol level basic.publish is an async method:
* this means error conditions that occur on the broker (such as publishing to
* a non-existent exchange) will not be reflected in the return value of this
* function.
*
* \param [in] state the connection object
* \param [in] channel the channel identifier
* \param [in] exchange the exchange on the broker to publish to
* \param [in] routing_key the routing key to use when publishing the message
* \param [in] mandatory indicate to the broker that the message MUST be routed
* to a queue. If the broker cannot do this it should respond with
* a basic.return method.
* \param [in] immediate indicate to the broker that the message MUST be delivered
* to a consumer immediately. If the broker cannot do this it should
* response with a basic.return method.
* \param [in] properties the properties associated with the message
* \param [in] body the message body
* \return AMQP_STATUS_OK on success, amqp_status_enum value on failure. Note
* that basic.publish is an async method, the return value from this
* function only indicates that the message data was successfully
* transmitted to the broker. It does not indicate failures that occur
* on the broker, such as publishing to a non-existent exchange.
* Possible error values:
* - AMQP_STATUS_TIMER_FAILURE: system timer facility returned an error
* the message was not sent.
* - AMQP_STATUS_HEARTBEAT_TIMEOUT: connection timed out waiting for a
* heartbeat from the broker. The message was not sent.
* - AMQP_STATUS_NO_MEMORY: memory allocation failed. The message was
* not sent.
* - AMQP_STATUS_TABLE_TOO_BIG: a table in the properties was too large
* to fit in a single frame. Message was not sent.
* - AMQP_STATUS_CONNECTION_CLOSED: the connection was closed.
* - AMQP_STATUS_SSL_ERROR: a SSL error occurred.
* - AMQP_STATUS_TCP_ERROR: a TCP error occurred. errno or
* WSAGetLastError() may provide more information
*
* Note: this function does heartbeat processing as of v0.4.0
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_basic_publish(amqp_connection_state_t state, amqp_channel_t channel,
amqp_bytes_t exchange, amqp_bytes_t routing_key,
amqp_boolean_t mandatory, amqp_boolean_t immediate,
struct amqp_basic_properties_t_ const *properties,
amqp_bytes_t body);
/**
* Closes an channel
*
* \param [in] state the connection object
* \param [in] channel the channel identifier
* \param [in] code the reason for closing the channel, AMQP_REPLY_SUCCESS is a good default
* \return amqp_rpc_reply_t indicating success or failure
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_rpc_reply_t
AMQP_CALL amqp_channel_close(amqp_connection_state_t state, amqp_channel_t channel,
int code);
/**
* Closes the entire connection
*
* Implicitly closes all channels and informs the broker the connection
* is being closed, after receiving acknowldgement from the broker it closes
* the socket.
*
* \param [in] state the connection object
* \param [in] code the reason code for closing the connection. AMQP_REPLY_SUCCESS is a good default.
* \return amqp_rpc_reply_t indicating the result
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_rpc_reply_t
AMQP_CALL amqp_connection_close(amqp_connection_state_t state, int code);
/**
* Acknowledges a message
*
* Does a basic.ack on a received message
*
* \param [in] state the connection object
* \param [in] channel the channel identifier
* \param [in] delivery_tag the delivery tag of the message to be ack'd
* \param [in] multiple if true, ack all messages up to this delivery tag, if
* false ack only this delivery tag
* \return 0 on success, 0 > on failing to send the ack to the broker.
* this will not indicate failure if something goes wrong on the broker
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_basic_ack(amqp_connection_state_t state, amqp_channel_t channel,
uint64_t delivery_tag, amqp_boolean_t multiple);
/**
* Do a basic.get
*
* Synchonously polls the broker for a message in a queue, and
* retrieves the message if a message is in the queue.
*
* \param [in] state the connection object
* \param [in] channel the channel identifier to use
* \param [in] queue the queue name to retrieve from
* \param [in] no_ack if true the message is automatically ack'ed
* if false amqp_basic_ack should be called once the message
* retrieved has been processed
* \return amqp_rpc_reply indicating success or failure
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_rpc_reply_t
AMQP_CALL amqp_basic_get(amqp_connection_state_t state, amqp_channel_t channel,
amqp_bytes_t queue, amqp_boolean_t no_ack);
/**
* Do a basic.reject
*
* Actively reject a message that has been delivered
*
* \param [in] state the connection object
* \param [in] channel the channel identifier
* \param [in] delivery_tag the delivery tag of the message to reject
* \param [in] requeue indicate to the broker whether it should requeue the
* message or just discard it.
* \return 0 on success, 0 > on failing to send the reject method to the broker.
* This will not indicate failure if something goes wrong on the broker.
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_basic_reject(amqp_connection_state_t state, amqp_channel_t channel,
uint64_t delivery_tag, amqp_boolean_t requeue);
/**
* Do a basic.nack
*
* Actively reject a message, this has the same effect as amqp_basic_reject()
* however, amqp_basic_nack() can negatively acknowledge multiple messages with
* one call much like amqp_basic_ack() can acknowledge mutliple messages with
* one call.
*
* \param [in] state the connection object
* \param [in] channel the channel identifier
* \param [in] delivery_tag the delivery tag of the message to reject
* \param [in] multiple if set to 1 negatively acknowledge all unacknowledged
* messages on this channel.
* \param [in] requeue indicate to the broker whether it should requeue the
* message or dead-letter it.
* \return AMQP_STATUS_OK on success, an amqp_status_enum value otherwise.
*
* \since v0.5.0
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_basic_nack(amqp_connection_state_t state, amqp_channel_t channel,
uint64_t delivery_tag, amqp_boolean_t multiple,
amqp_boolean_t requeue);
/**
* Check to see if there is data left in the receive buffer
*
* Can be used to see if there is data still in the buffer, if so
* calling amqp_simple_wait_frame will not immediately enter a
* blocking read.
*
* \param [in] state the connection object
* \return true if there is data in the recieve buffer, false otherwise
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
amqp_boolean_t
AMQP_CALL amqp_data_in_buffer(amqp_connection_state_t state);
/**
* Get the error string for the given error code.
*
* \deprecated This function has been deprecated in favor of
* \ref amqp_error_string2() which returns statically allocated
* string which do not need to be freed by the caller.
*
* The returned string resides on the heap; the caller is responsible
* for freeing it.
*
* \param [in] err return error code
* \return the error string
*
* \since v0.1
*/
AMQP_DEPRECATED(
AMQP_PUBLIC_FUNCTION
char *
AMQP_CALL amqp_error_string(int err)
);
/**
* Get the error string for the given error code.
*
* Get an error string associated with an error code. The string is statically
* allocated and does not need to be freed
*
* \param [in] err the error code
* \return the error string
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
const char *
AMQP_CALL amqp_error_string2(int err);
/**
* Deserialize an amqp_table_t from AMQP wireformat
*
* This is an internal function and is not typically used by
* client applications
*
* \param [in] encoded the buffer containing the serialized data
* \param [in] pool memory pool used to allocate the table entries from
* \param [in] output the amqp_table_t structure to fill in. Any existing
* entries will be erased
* \param [in,out] offset The offset into the encoded buffer to start
* reading the serialized table. It will be updated
* by this function to end of the table
* \return AMQP_STATUS_OK on success, an amqp_status_enum value on failure
* Possible error codes:
* - AMQP_STATUS_NO_MEMORY out of memory
* - AMQP_STATUS_BAD_AMQP_DATA invalid wireformat
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_decode_table(amqp_bytes_t encoded, amqp_pool_t *pool,
amqp_table_t *output, size_t *offset);
/**
* Serializes an amqp_table_t to the AMQP wireformat
*
* This is an internal function and is not typically used by
* client applications
*
* \param [in] encoded the buffer where to serialize the table to
* \param [in] input the amqp_table_t to serialize
* \param [in,out] offset The offset into the encoded buffer to start
* writing the serialized table. It will be updated
* by this function to where writing left off
* \return AMQP_STATUS_OK on success, an amqp_status_enum value on failure
* Possible error codes:
* - AMQP_STATUS_TABLE_TOO_BIG the serialized form is too large for the
* buffer
* - AMQP_STATUS_BAD_AMQP_DATA invalid table
*
* \since v0.1
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_encode_table(amqp_bytes_t encoded, amqp_table_t *input, size_t *offset);
/**
* Create a deep-copy of an amqp_table_t object
*
* Creates a deep-copy of an amqp_table_t object, using the provided pool
* object to allocate the necessary memory. This memory can be freed later by
* call recycle_amqp_pool(), or empty_amqp_pool()
*
* \param [in] original the table to copy
* \param [in,out] clone the table to copy to
* \param [in] pool the initialized memory pool to do allocations for the table
* from
* \return AMQP_STATUS_OK on success, amqp_status_enum value on failure.
* Possible error values:
* - AMQP_STATUS_NO_MEMORY - memory allocation failure.
* - AMQP_STATUS_INVALID_PARAMETER - invalid table (e.g., no key name)
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_table_clone(const amqp_table_t *original, amqp_table_t *clone, amqp_pool_t *pool);
/**
* A message object
*
* \since v0.4.0
*/
typedef struct amqp_message_t_ {
amqp_basic_properties_t properties; /**< message properties */
amqp_bytes_t body; /**< message body */
amqp_pool_t pool; /**< pool used to allocate properties */
} amqp_message_t;
/**
* Reads the next message on a channel
*
* Reads a complete message (header + body) on a specified channel. This
* function is intended to be used with amqp_basic_get() or when an
* AMQP_BASIC_DELIVERY_METHOD method is received.
*
* \param [in,out] state the connection object
* \param [in] channel the channel on which to read the message from
* \param [in,out] message a pointer to a amqp_message_t object. Caller should
* call amqp_message_destroy() when it is done using the
* fields in the message object. The caller is responsible for
* allocating/destroying the amqp_message_t object itself.
* \param [in] flags pass in 0. Currently unused.
* \returns a amqp_rpc_reply_t object. ret.reply_type == AMQP_RESPONSE_NORMAL on success.
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
amqp_rpc_reply_t
AMQP_CALL amqp_read_message(amqp_connection_state_t state,
amqp_channel_t channel,
amqp_message_t *message, int flags);
/**
* Frees memory associated with a amqp_message_t allocated in amqp_read_message
*
* \param [in] message
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL amqp_destroy_message(amqp_message_t *message);
/**
* Envelope object
*
* \since v0.4.0
*/
typedef struct amqp_envelope_t_ {
amqp_channel_t channel; /**< channel message was delivered on */
amqp_bytes_t consumer_tag; /**< the consumer tag the message was delivered to */
uint64_t delivery_tag; /**< the messages delivery tag */
amqp_boolean_t redelivered; /**< flag indicating whether this message is being redelivered */
amqp_bytes_t exchange; /**< exchange this message was published to */
amqp_bytes_t routing_key; /**< the routing key this message was published with */
amqp_message_t message; /**< the message */
} amqp_envelope_t;
/**
* Wait for and consume a message
*
* Waits for a basic.deliver method on any channel, upon receipt of
* basic.deliver it reads that message, and returns. If any other method is
* received before basic.deliver, this function will return an amqp_rpc_reply_t
* with ret.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION, and
* ret.library_error == AMQP_STATUS_UNEXPECTED_FRAME. The caller should then
* call amqp_simple_wait_frame() to read this frame and take appropriate action.
*
* This function should be used after starting a consumer with the
* amqp_basic_consume() function
*
* \param [in,out] state the connection object
* \param [in,out] envelope a pointer to a amqp_envelope_t object. Caller
* should call #amqp_destroy_envelope() when it is done using
* the fields in the envelope object. The caller is responsible
* for allocating/destroying the amqp_envelope_t object itself.
* \param [in] timeout a timeout to wait for a message delivery. Passing in
* NULL will result in blocking behavior.
* \param [in] flags pass in 0. Currently unused.
* \returns a amqp_rpc_reply_t object. ret.reply_type == AMQP_RESPONSE_NORMAL
* on success. If ret.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION, and
* ret.library_error == AMQP_STATUS_UNEXPECTED_FRAME, a frame other
* than AMQP_BASIC_DELIVER_METHOD was received, the caller should call
* amqp_simple_wait_frame() to read this frame and take appropriate
* action.
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
amqp_rpc_reply_t
AMQP_CALL amqp_consume_message(amqp_connection_state_t state,
amqp_envelope_t *envelope,
struct timeval *timeout, int flags);
/**
* Frees memory associated with a amqp_envelope_t allocated in amqp_consume_message()
*
* \param [in] envelope
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL amqp_destroy_envelope(amqp_envelope_t *envelope);
/**
* Parameters used to connect to the RabbitMQ broker
*
* \since v0.2
*/
struct amqp_connection_info {
char *user; /**< the username to authenticate with the broker, default on most broker is 'guest' */
char *password; /**< the password to authenticate with the broker, default on most brokers is 'guest' */
char *host; /**< the hostname of the broker */
char *vhost; /**< the virtual host on the broker to connect to, a good default is "/" */
int port; /**< the port that the broker is listening on, default on most brokers is 5672 */
amqp_boolean_t ssl;
};
/**
* Initialze an amqp_connection_info to default values
*
* The default values are:
* - user: "guest"
* - password: "guest"
* - host: "localhost"
* - vhost: "/"
* - port: 5672
*
* \param [out] parsed the connection info to set defaults on
*
* \since v0.2
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL amqp_default_connection_info(struct amqp_connection_info *parsed);
/**
* Parse a connection URL
*
* An amqp connection url takes the form:
*
* amqp://[$USERNAME[:$PASSWORD]\@]$HOST[:$PORT]/[$VHOST]
*
* Examples:
* amqp://guest:guest\@localhost:5672//
* amqp://guest:guest\@localhost/myvhost
*
* Any missing parts of the URL will be set to the defaults specified in
* amqp_default_connection_info. For amqps: URLs the default port will be set
* to 5671 instead of 5672 for non-SSL URLs.
*
* \note This function modifies url parameter.
*
* \param [in] url URI to parse, note that this parameter is modified by the
* function.
* \param [out] parsed the connection info gleaned from the URI. The char*
* members will point to parts of the url input parameter.
* Memory management will depend on how the url is allocated.
* \returns AMQP_STATUS_OK on success, AMQP_STATUS_BAD_URL on failure
*
* \since v0.2
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_parse_url(char *url, struct amqp_connection_info *parsed);
/* socket API */
/**
* Open a socket connection.
*
* This function opens a socket connection returned from amqp_tcp_socket_new()
* or amqp_ssl_socket_new(). This function should be called after setting
* socket options and prior to assigning the socket to an AMQP connection with
* amqp_set_socket().
*
* \param [in,out] self A socket object.
* \param [in] host Connect to this host.
* \param [in] port Connect on this remote port.
*
* \return AMQP_STATUS_OK on success, an amqp_status_enum on failure
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL
amqp_socket_open(amqp_socket_t *self, const char *host, int port);
/**
* Open a socket connection.
*
* This function opens a socket connection returned from amqp_tcp_socket_new()
* or amqp_ssl_socket_new(). This function should be called after setting
* socket options and prior to assigning the socket to an AMQP connection with
* amqp_set_socket().
*
* \param [in,out] self A socket object.
* \param [in] host Connect to this host.
* \param [in] port Connect on this remote port.
* \param [in] timeout Max allowed time to spent on opening. If NULL - run in blocking mode
*
* \return AMQP_STATUS_OK on success, an amqp_status_enum on failure.
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL
amqp_socket_open_noblock(amqp_socket_t *self, const char *host, int port, struct timeval *timeout);
/**
* Get the socket descriptor in use by a socket object.
*
* Retrieve the underlying socket descriptor. This function can be used to
* perform low-level socket operations that aren't supported by the socket
* interface. Use with caution!
*
* \param [in,out] self A socket object.
*
* \return The underlying socket descriptor, or -1 if there is no socket descriptor
* associated with
* with
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL
amqp_socket_get_sockfd(amqp_socket_t *self);
/**
* Get the socket object associated with a amqp_connection_state_t
*
* \param [in] state the connection object to get the socket from
* \return a pointer to the socket object, or NULL if one has not been assigned
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
amqp_socket_t *
amqp_get_socket(amqp_connection_state_t state);
/**
* Get the broker properties table
*
* \param [in] state the connection object
* \return a pointer to an amqp_table_t containing the properties advertised
* by the broker on connection. The connection object owns the table, it
* should not be modified.
*
* \since v0.5.0
*/
AMQP_PUBLIC_FUNCTION
amqp_table_t *
amqp_get_server_properties(amqp_connection_state_t state);
/**
* Get the client properties table
*
* Get the properties that were passed to the broker on connection.
*
* \param [in] state the connection object
* \return a pointer to an amqp_table_t containing the properties advertised
* by the client on connection. The connection object owns the table, it
* should not be modified.
*
* \since v0.7.0
*/
AMQP_PUBLIC_FUNCTION
amqp_table_t *
amqp_get_client_properties(amqp_connection_state_t state);
AMQP_END_DECLS
#endif /* AMQP_H */
rabbitmq-c-0.8.0/librabbitmq/amqp_api.c 0000664 0000000 0000000 00000027545 12702357234 0020005 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _MSC_VER
/* MSVC complains about sprintf being deprecated in favor of sprintf_s */
# define _CRT_SECURE_NO_WARNINGS
/* MSVC complains about strdup being deprecated in favor of _strdup */
# define _CRT_NONSTDC_NO_DEPRECATE
#endif
#include "amqp_private.h"
#include "amqp_time.h"
#include
#include
#include
#include
#include
#define ERROR_MASK (0x00FF)
#define ERROR_CATEGORY_MASK (0xFF00)
enum error_category_enum_ {
EC_base = 0,
EC_tcp = 1,
EC_ssl = 2
};
static const char *base_error_strings[] = {
"operation completed successfully", /* AMQP_STATUS_OK 0x0 */
"could not allocate memory", /* AMQP_STATUS_NO_MEMORY -0x0001 */
"invalid AMQP data", /* AMQP_STATUS_BAD_AQMP_DATA -0x0002 */
"unknown AMQP class id", /* AMQP_STATUS_UNKNOWN_CLASS -0x0003 */
"unknown AMQP method id", /* AMQP_STATUS_UNKNOWN_METHOD -0x0004 */
"hostname lookup failed", /* AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED -0x0005 */
"incompatible AMQP version", /* AMQP_STATUS_INCOMPATIBLE_AMQP_VERSION -0x0006 */
"connection closed unexpectedly", /* AMQP_STATUS_CONNECTION_CLOSED -0x0007 */
"could not parse AMQP URL", /* AMQP_STATUS_BAD_AMQP_URL -0x0008 */
"a socket error occurred", /* AMQP_STATUS_SOCKET_ERROR -0x0009 */
"invalid parameter", /* AMQP_STATUS_INVALID_PARAMETER -0x000A */
"table too large for buffer", /* AMQP_STATUS_TABLE_TOO_BIG -0x000B */
"unexpected method received", /* AMQP_STATUS_WRONG_METHOD -0x000C */
"request timed out", /* AMQP_STATUS_TIMEOUT -0x000D */
"system timer has failed", /* AMQP_STATUS_TIMER_FAILED -0x000E */
"heartbeat timeout, connection closed",/* AMQP_STATUS_HEARTBEAT_TIMEOUT -0x000F */
"unexpected protocol state", /* AMQP_STATUS_UNEXPECTED STATE -0x0010 */
"socket is closed", /* AMQP_STATUS_SOCKET_CLOSED -0x0011 */
"socket already open", /* AMQP_STATUS_SOCKET_INUSE -0x0012 */
"unsupported sasl method requested", /* AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD -0x0013 */
"parameter value is unsupported" /* AMQP_STATUS_UNSUPPORTED -0x0014 */
};
static const char *tcp_error_strings[] = {
"a socket error occurred", /* AMQP_STATUS_TCP_ERROR -0x0100 */
"socket library initialization failed" /* AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR -0x0101 */
};
static const char *ssl_error_strings[] = {
"a SSL error occurred", /* AMQP_STATUS_SSL_ERROR -0x0200 */
"SSL hostname verification failed", /* AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED -0x0201 */
"SSL peer cert verification failed", /* AMQP_STATUS_SSL_PEER_VERIFY_FAILED -0x0202 */
"SSL handshake failed" /* AMQP_STATUS_SSL_CONNECTION_FAILED -0x0203 */
};
static const char *unknown_error_string = "(unknown error)";
const char *amqp_error_string2(int code)
{
const char *error_string;
size_t category = (((-code) & ERROR_CATEGORY_MASK) >> 8);
size_t error = (-code) & ERROR_MASK;
switch (category) {
case EC_base:
if (error < (sizeof(base_error_strings) / sizeof(char *))) {
error_string = base_error_strings[error];
} else {
error_string = unknown_error_string;
}
break;
case EC_tcp:
if (error < (sizeof(tcp_error_strings) / sizeof(char *))) {
error_string = tcp_error_strings[error];
} else {
error_string = unknown_error_string;
}
break;
case EC_ssl:
if (error < (sizeof(ssl_error_strings) / sizeof(char *))) {
error_string = ssl_error_strings[error];
} else {
error_string = unknown_error_string;
}
break;
default:
error_string = unknown_error_string;
break;
}
return error_string;
}
char *amqp_error_string(int code)
{
/* Previously sometimes clients had to flip the sign on a return value from a
* function to get the correct error code. Now, all error codes are negative.
* To keep people's legacy code running correctly, we map all error codes to
* negative values.
*
* This is only done with this deprecated function.
*/
if (code > 0) {
code = -code;
}
return strdup(amqp_error_string2(code));
}
void amqp_abort(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fputc('\n', stderr);
abort();
}
const amqp_bytes_t amqp_empty_bytes = { 0, NULL };
const amqp_table_t amqp_empty_table = { 0, NULL };
const amqp_array_t amqp_empty_array = { 0, NULL };
int amqp_basic_publish(amqp_connection_state_t state,
amqp_channel_t channel,
amqp_bytes_t exchange,
amqp_bytes_t routing_key,
amqp_boolean_t mandatory,
amqp_boolean_t immediate,
amqp_basic_properties_t const *properties,
amqp_bytes_t body)
{
amqp_frame_t f;
size_t body_offset;
size_t usable_body_payload_size = state->frame_max - (HEADER_SIZE + FOOTER_SIZE);
int res;
amqp_basic_publish_t m;
amqp_basic_properties_t default_properties;
m.exchange = exchange;
m.routing_key = routing_key;
m.mandatory = mandatory;
m.immediate = immediate;
m.ticket = 0;
/* TODO(alanxz): this heartbeat check is happening in the wrong place, it
* should really be done in amqp_try_send/writev */
res = amqp_time_has_past(state->next_recv_heartbeat);
if (AMQP_STATUS_TIMER_FAILURE == res) {
return res;
} else if (AMQP_STATUS_TIMEOUT == res) {
res = amqp_try_recv(state);
if (AMQP_STATUS_TIMEOUT == res) {
return AMQP_STATUS_HEARTBEAT_TIMEOUT;
} else if (AMQP_STATUS_OK != res) {
return res;
}
}
res = amqp_send_method_inner(state, channel, AMQP_BASIC_PUBLISH_METHOD, &m,
AMQP_SF_MORE);
if (res < 0) {
return res;
}
if (properties == NULL) {
memset(&default_properties, 0, sizeof(default_properties));
properties = &default_properties;
}
f.frame_type = AMQP_FRAME_HEADER;
f.channel = channel;
f.payload.properties.class_id = AMQP_BASIC_CLASS;
f.payload.properties.body_size = body.len;
f.payload.properties.decoded = (void *) properties;
res = amqp_send_frame_inner(state, &f, AMQP_SF_MORE);
if (res < 0) {
return res;
}
body_offset = 0;
while (body_offset < body.len) {
size_t remaining = body.len - body_offset;
int flagz;
if (remaining == 0) {
break;
}
f.frame_type = AMQP_FRAME_BODY;
f.channel = channel;
f.payload.body_fragment.bytes = amqp_offset(body.bytes, body_offset);
if (remaining >= usable_body_payload_size) {
f.payload.body_fragment.len = usable_body_payload_size;
flagz = AMQP_SF_MORE;
} else {
f.payload.body_fragment.len = remaining;
flagz = AMQP_SF_NONE;
}
body_offset += f.payload.body_fragment.len;
res = amqp_send_frame_inner(state, &f, flagz);
if (res < 0) {
return res;
}
}
return AMQP_STATUS_OK;
}
amqp_rpc_reply_t amqp_channel_close(amqp_connection_state_t state,
amqp_channel_t channel,
int code)
{
char codestr[13];
amqp_method_number_t replies[2] = { AMQP_CHANNEL_CLOSE_OK_METHOD, 0};
amqp_channel_close_t req;
if (code < 0 || code > UINT16_MAX) {
return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER);
}
req.reply_code = (uint16_t)code;
req.reply_text.bytes = codestr;
req.reply_text.len = sprintf(codestr, "%d", code);
req.class_id = 0;
req.method_id = 0;
return amqp_simple_rpc(state, channel, AMQP_CHANNEL_CLOSE_METHOD,
replies, &req);
}
amqp_rpc_reply_t amqp_connection_close(amqp_connection_state_t state,
int code)
{
char codestr[13];
amqp_method_number_t replies[2] = { AMQP_CONNECTION_CLOSE_OK_METHOD, 0};
amqp_channel_close_t req;
if (code < 0 || code > UINT16_MAX) {
return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER);
}
req.reply_code = (uint16_t)code;
req.reply_text.bytes = codestr;
req.reply_text.len = sprintf(codestr, "%d", code);
req.class_id = 0;
req.method_id = 0;
return amqp_simple_rpc(state, 0, AMQP_CONNECTION_CLOSE_METHOD,
replies, &req);
}
int amqp_basic_ack(amqp_connection_state_t state,
amqp_channel_t channel,
uint64_t delivery_tag,
amqp_boolean_t multiple)
{
amqp_basic_ack_t m;
m.delivery_tag = delivery_tag;
m.multiple = multiple;
return amqp_send_method(state, channel, AMQP_BASIC_ACK_METHOD, &m);
}
amqp_rpc_reply_t amqp_basic_get(amqp_connection_state_t state,
amqp_channel_t channel,
amqp_bytes_t queue,
amqp_boolean_t no_ack)
{
amqp_method_number_t replies[] = { AMQP_BASIC_GET_OK_METHOD,
AMQP_BASIC_GET_EMPTY_METHOD,
0
};
amqp_basic_get_t req;
req.ticket = 0;
req.queue = queue;
req.no_ack = no_ack;
state->most_recent_api_result = amqp_simple_rpc(state, channel,
AMQP_BASIC_GET_METHOD,
replies, &req);
return state->most_recent_api_result;
}
int amqp_basic_reject(amqp_connection_state_t state,
amqp_channel_t channel,
uint64_t delivery_tag,
amqp_boolean_t requeue)
{
amqp_basic_reject_t req;
req.delivery_tag = delivery_tag;
req.requeue = requeue;
return amqp_send_method(state, channel, AMQP_BASIC_REJECT_METHOD, &req);
}
int amqp_basic_nack(amqp_connection_state_t state, amqp_channel_t channel,
uint64_t delivery_tag, amqp_boolean_t multiple,
amqp_boolean_t requeue)
{
amqp_basic_nack_t req;
req.delivery_tag = delivery_tag;
req.multiple = multiple;
req.requeue = requeue;
return amqp_send_method(state, channel, AMQP_BASIC_NACK_METHOD, &req);
}
rabbitmq-c-0.8.0/librabbitmq/amqp_connection.c 0000664 0000000 0000000 00000041745 12702357234 0021371 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2014
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _MSC_VER
# define _CRT_SECURE_NO_WARNINGS
#endif
#include "amqp_tcp_socket.h"
#include "amqp_private.h"
#include "amqp_time.h"
#include
#include
#include
#include
#include
#ifndef AMQP_INITIAL_FRAME_POOL_PAGE_SIZE
#define AMQP_INITIAL_FRAME_POOL_PAGE_SIZE 65536
#endif
#ifndef AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE
#define AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE 131072
#endif
#define ENFORCE_STATE(statevec, statenum) \
{ \
amqp_connection_state_t _check_state = (statevec); \
amqp_connection_state_enum _wanted_state = (statenum); \
if (_check_state->state != _wanted_state) \
amqp_abort( \
"Programming error: invalid AMQP connection state: expected %d, " \
"got %d", \
_wanted_state, _check_state->state); \
}
amqp_connection_state_t amqp_new_connection(void)
{
int res;
amqp_connection_state_t state =
(amqp_connection_state_t) calloc(1, sizeof(struct amqp_connection_state_t_));
if (state == NULL) {
return NULL;
}
res = amqp_tune_connection(state, 0, AMQP_INITIAL_FRAME_POOL_PAGE_SIZE, 0);
if (0 != res) {
goto out_nomem;
}
state->inbound_buffer.bytes = state->header_buffer;
state->inbound_buffer.len = sizeof(state->header_buffer);
state->state = CONNECTION_STATE_INITIAL;
/* the server protocol version response is 8 bytes, which conveniently
is also the minimum frame size */
state->target_size = 8;
state->sock_inbound_buffer.len = AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE;
state->sock_inbound_buffer.bytes = malloc(AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE);
if (state->sock_inbound_buffer.bytes == NULL) {
goto out_nomem;
}
init_amqp_pool(&state->properties_pool, 512);
return state;
out_nomem:
free(state->sock_inbound_buffer.bytes);
free(state);
return NULL;
}
int amqp_get_sockfd(amqp_connection_state_t state)
{
return state->socket ? amqp_socket_get_sockfd(state->socket) : -1;
}
void amqp_set_sockfd(amqp_connection_state_t state,
int sockfd)
{
amqp_socket_t *socket = amqp_tcp_socket_new(state);
if (!socket) {
amqp_abort("%s", strerror(errno));
}
amqp_tcp_socket_set_sockfd(socket, sockfd);
}
void amqp_set_socket(amqp_connection_state_t state, amqp_socket_t *socket)
{
amqp_socket_delete(state->socket);
state->socket = socket;
}
amqp_socket_t *
amqp_get_socket(amqp_connection_state_t state)
{
return state->socket;
}
int amqp_tune_connection(amqp_connection_state_t state,
int channel_max,
int frame_max,
int heartbeat)
{
void *newbuf;
int res;
ENFORCE_STATE(state, CONNECTION_STATE_IDLE);
state->channel_max = channel_max;
state->frame_max = frame_max;
state->heartbeat = heartbeat;
if (0 > state->heartbeat) {
state->heartbeat = 0;
}
res = amqp_time_s_from_now(&state->next_send_heartbeat,
amqp_heartbeat_send(state));
if (AMQP_STATUS_OK != res) {
return res;
}
res = amqp_time_s_from_now(&state->next_recv_heartbeat,
amqp_heartbeat_recv(state));
if (AMQP_STATUS_OK != res) {
return res;
}
state->outbound_buffer.len = frame_max;
newbuf = realloc(state->outbound_buffer.bytes, frame_max);
if (newbuf == NULL) {
return AMQP_STATUS_NO_MEMORY;
}
state->outbound_buffer.bytes = newbuf;
return AMQP_STATUS_OK;
}
int amqp_get_channel_max(amqp_connection_state_t state)
{
return state->channel_max;
}
int amqp_get_frame_max(amqp_connection_state_t state)
{
return state->frame_max;
}
int amqp_get_heartbeat(amqp_connection_state_t state)
{
return state->heartbeat;
}
int amqp_destroy_connection(amqp_connection_state_t state)
{
int status = AMQP_STATUS_OK;
if (state) {
int i;
for (i = 0; i < POOL_TABLE_SIZE; ++i) {
amqp_pool_table_entry_t *entry = state->pool_table[i];
while (NULL != entry) {
amqp_pool_table_entry_t *todelete = entry;
empty_amqp_pool(&entry->pool);
entry = entry->next;
free(todelete);
}
}
free(state->outbound_buffer.bytes);
free(state->sock_inbound_buffer.bytes);
amqp_socket_delete(state->socket);
empty_amqp_pool(&state->properties_pool);
free(state);
}
return status;
}
static void return_to_idle(amqp_connection_state_t state)
{
state->inbound_buffer.len = sizeof(state->header_buffer);
state->inbound_buffer.bytes = state->header_buffer;
state->inbound_offset = 0;
state->target_size = HEADER_SIZE;
state->state = CONNECTION_STATE_IDLE;
}
static size_t consume_data(amqp_connection_state_t state,
amqp_bytes_t *received_data)
{
/* how much data is available and will fit? */
size_t bytes_consumed = state->target_size - state->inbound_offset;
if (received_data->len < bytes_consumed) {
bytes_consumed = received_data->len;
}
memcpy(amqp_offset(state->inbound_buffer.bytes, state->inbound_offset),
received_data->bytes, bytes_consumed);
state->inbound_offset += bytes_consumed;
received_data->bytes = amqp_offset(received_data->bytes, bytes_consumed);
received_data->len -= bytes_consumed;
return bytes_consumed;
}
int amqp_handle_input(amqp_connection_state_t state,
amqp_bytes_t received_data,
amqp_frame_t *decoded_frame)
{
size_t bytes_consumed;
void *raw_frame;
/* Returning frame_type of zero indicates either insufficient input,
or a complete, ignored frame was read. */
decoded_frame->frame_type = 0;
if (received_data.len == 0) {
return AMQP_STATUS_OK;
}
if (state->state == CONNECTION_STATE_IDLE) {
state->state = CONNECTION_STATE_HEADER;
}
bytes_consumed = consume_data(state, &received_data);
/* do we have target_size data yet? if not, return with the
expectation that more will arrive */
if (state->inbound_offset < state->target_size) {
return (int)bytes_consumed;
}
raw_frame = state->inbound_buffer.bytes;
switch (state->state) {
case CONNECTION_STATE_INITIAL:
/* check for a protocol header from the server */
if (memcmp(raw_frame, "AMQP", 4) == 0) {
decoded_frame->frame_type = AMQP_PSEUDOFRAME_PROTOCOL_HEADER;
decoded_frame->channel = 0;
decoded_frame->payload.protocol_header.transport_high
= amqp_d8(raw_frame, 4);
decoded_frame->payload.protocol_header.transport_low
= amqp_d8(raw_frame, 5);
decoded_frame->payload.protocol_header.protocol_version_major
= amqp_d8(raw_frame, 6);
decoded_frame->payload.protocol_header.protocol_version_minor
= amqp_d8(raw_frame, 7);
return_to_idle(state);
return (int)bytes_consumed;
}
/* it's not a protocol header; fall through to process it as a
regular frame header */
case CONNECTION_STATE_HEADER: {
amqp_channel_t channel;
amqp_pool_t *channel_pool;
/* frame length is 3 bytes in */
channel = amqp_d16(raw_frame, 1);
state->target_size
= amqp_d32(raw_frame, 3) + HEADER_SIZE + FOOTER_SIZE;
if ((size_t)state->frame_max < state->target_size) {
return AMQP_STATUS_BAD_AMQP_DATA;
}
channel_pool = amqp_get_or_create_channel_pool(state, channel);
if (NULL == channel_pool) {
return AMQP_STATUS_NO_MEMORY;
}
amqp_pool_alloc_bytes(channel_pool, state->target_size, &state->inbound_buffer);
if (NULL == state->inbound_buffer.bytes) {
return AMQP_STATUS_NO_MEMORY;
}
memcpy(state->inbound_buffer.bytes, state->header_buffer, HEADER_SIZE);
raw_frame = state->inbound_buffer.bytes;
state->state = CONNECTION_STATE_BODY;
bytes_consumed += consume_data(state, &received_data);
/* do we have target_size data yet? if not, return with the
expectation that more will arrive */
if (state->inbound_offset < state->target_size) {
return (int)bytes_consumed;
}
}
/* fall through to process body */
case CONNECTION_STATE_BODY: {
amqp_bytes_t encoded;
int res;
amqp_pool_t *channel_pool;
/* Check frame end marker (footer) */
if (amqp_d8(raw_frame, state->target_size - 1) != AMQP_FRAME_END) {
return AMQP_STATUS_BAD_AMQP_DATA;
}
decoded_frame->frame_type = amqp_d8(raw_frame, 0);
decoded_frame->channel = amqp_d16(raw_frame, 1);
channel_pool = amqp_get_or_create_channel_pool(state, decoded_frame->channel);
if (NULL == channel_pool) {
return AMQP_STATUS_NO_MEMORY;
}
switch (decoded_frame->frame_type) {
case AMQP_FRAME_METHOD:
decoded_frame->payload.method.id = amqp_d32(raw_frame, HEADER_SIZE);
encoded.bytes = amqp_offset(raw_frame, HEADER_SIZE + 4);
encoded.len = state->target_size - HEADER_SIZE - 4 - FOOTER_SIZE;
res = amqp_decode_method(decoded_frame->payload.method.id,
channel_pool, encoded,
&decoded_frame->payload.method.decoded);
if (res < 0) {
return res;
}
break;
case AMQP_FRAME_HEADER:
decoded_frame->payload.properties.class_id
= amqp_d16(raw_frame, HEADER_SIZE);
/* unused 2-byte weight field goes here */
decoded_frame->payload.properties.body_size
= amqp_d64(raw_frame, HEADER_SIZE + 4);
encoded.bytes = amqp_offset(raw_frame, HEADER_SIZE + 12);
encoded.len = state->target_size - HEADER_SIZE - 12 - FOOTER_SIZE;
decoded_frame->payload.properties.raw = encoded;
res = amqp_decode_properties(decoded_frame->payload.properties.class_id,
channel_pool, encoded,
&decoded_frame->payload.properties.decoded);
if (res < 0) {
return res;
}
break;
case AMQP_FRAME_BODY:
decoded_frame->payload.body_fragment.len
= state->target_size - HEADER_SIZE - FOOTER_SIZE;
decoded_frame->payload.body_fragment.bytes
= amqp_offset(raw_frame, HEADER_SIZE);
break;
case AMQP_FRAME_HEARTBEAT:
break;
default:
/* Ignore the frame */
decoded_frame->frame_type = 0;
break;
}
return_to_idle(state);
return (int)bytes_consumed;
}
default:
amqp_abort("Internal error: invalid amqp_connection_state_t->state %d",
state->state);
}
}
amqp_boolean_t amqp_release_buffers_ok(amqp_connection_state_t state)
{
return (state->state == CONNECTION_STATE_IDLE);
}
void amqp_release_buffers(amqp_connection_state_t state)
{
int i;
ENFORCE_STATE(state, CONNECTION_STATE_IDLE);
for (i = 0; i < POOL_TABLE_SIZE; ++i) {
amqp_pool_table_entry_t *entry = state->pool_table[i];
for ( ;NULL != entry; entry = entry->next) {
amqp_maybe_release_buffers_on_channel(state, entry->channel);
}
}
}
void amqp_maybe_release_buffers(amqp_connection_state_t state)
{
if (amqp_release_buffers_ok(state)) {
amqp_release_buffers(state);
}
}
void amqp_maybe_release_buffers_on_channel(amqp_connection_state_t state, amqp_channel_t channel)
{
amqp_link_t *queued_link;
amqp_pool_t *pool;
if (CONNECTION_STATE_IDLE != state->state) {
return;
}
queued_link = state->first_queued_frame;
while (NULL != queued_link) {
amqp_frame_t *frame = queued_link->data;
if (channel == frame->channel) {
return;
}
queued_link = queued_link->next;
}
pool = amqp_get_channel_pool(state, channel);
if (pool != NULL) {
recycle_amqp_pool(pool);
}
}
static int amqp_frame_to_bytes(const amqp_frame_t *frame, amqp_bytes_t buffer,
amqp_bytes_t *encoded) {
void *out_frame = buffer.bytes;
size_t out_frame_len;
int res;
amqp_e8(out_frame, 0, frame->frame_type);
amqp_e16(out_frame, 1, frame->channel);
switch (frame->frame_type) {
case AMQP_FRAME_BODY: {
const amqp_bytes_t *body = &frame->payload.body_fragment;
memcpy(amqp_offset(out_frame, HEADER_SIZE), body->bytes, body->len);
out_frame_len = body->len;
break;
}
case AMQP_FRAME_METHOD: {
amqp_bytes_t method_encoded;
amqp_e32(out_frame, HEADER_SIZE, frame->payload.method.id);
method_encoded.bytes = amqp_offset(out_frame, HEADER_SIZE + 4);
method_encoded.len = buffer.len - HEADER_SIZE - 4 - FOOTER_SIZE;
res = amqp_encode_method(frame->payload.method.id,
frame->payload.method.decoded, method_encoded);
if (res < 0) {
return res;
}
out_frame_len = res + 4;
break;
}
case AMQP_FRAME_HEADER: {
amqp_bytes_t properties_encoded;
amqp_e16(out_frame, HEADER_SIZE, frame->payload.properties.class_id);
amqp_e16(out_frame, HEADER_SIZE + 2, 0); /* "weight" */
amqp_e64(out_frame, HEADER_SIZE + 4, frame->payload.properties.body_size);
properties_encoded.bytes = amqp_offset(out_frame, HEADER_SIZE + 12);
properties_encoded.len = buffer.len - HEADER_SIZE - 12 - FOOTER_SIZE;
res = amqp_encode_properties(frame->payload.properties.class_id,
frame->payload.properties.decoded,
properties_encoded);
if (res < 0) {
return res;
}
out_frame_len = res + 12;
break;
}
case AMQP_FRAME_HEARTBEAT:
out_frame_len = 0;
break;
default:
return AMQP_STATUS_INVALID_PARAMETER;
}
amqp_e32(out_frame, 3, (uint32_t)out_frame_len);
amqp_e8(out_frame, HEADER_SIZE + out_frame_len, AMQP_FRAME_END);
encoded->bytes = out_frame;
encoded->len = out_frame_len + HEADER_SIZE + FOOTER_SIZE;
return AMQP_STATUS_OK;
}
int amqp_send_frame(amqp_connection_state_t state,
const amqp_frame_t *frame) {
return amqp_send_frame_inner(state, frame, AMQP_SF_NONE);
}
int amqp_send_frame_inner(amqp_connection_state_t state,
const amqp_frame_t *frame, int flags) {
int res;
ssize_t sent;
amqp_bytes_t encoded;
/* TODO: if the AMQP_SF_MORE socket optimization can be shown to work
* correctly, then this could be un-done so that body-frames are sent as 3
* send calls, getting rid of the copy of the body content, some testing
* would need to be done to see if this would actually a win for performance.
* */
res = amqp_frame_to_bytes(frame, state->outbound_buffer, &encoded);
if (AMQP_STATUS_OK != res) {
return res;
}
start_send:
sent = amqp_try_send(state, encoded.bytes, encoded.len,
state->next_recv_heartbeat, flags);
if (0 > sent) {
return (int)sent;
}
/* A partial send has occurred, because of a heartbeat timeout, try and recv
* something */
if ((ssize_t)encoded.len != sent) {
res = amqp_try_recv(state);
if (AMQP_STATUS_TIMEOUT == res) {
return AMQP_STATUS_HEARTBEAT_TIMEOUT;
} else if (AMQP_STATUS_OK != res) {
return res;
}
encoded.bytes = (uint8_t*)encoded.bytes + sent;
encoded.len -= sent;
goto start_send;
}
res = amqp_time_s_from_now(&state->next_send_heartbeat,
amqp_heartbeat_send(state));
return res;
}
amqp_table_t *
amqp_get_server_properties(amqp_connection_state_t state)
{
return &state->server_properties;
}
amqp_table_t *
amqp_get_client_properties(amqp_connection_state_t state)
{
return &state->client_properties;
}
rabbitmq-c-0.8.0/librabbitmq/amqp_consumer.c 0000664 0000000 0000000 00000023252 12702357234 0021056 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2013-2014
* Alan Antonuk. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#include "amqp.h"
#include "amqp_private.h"
#include "amqp_socket.h"
#include
#include
static
int amqp_basic_properties_clone(amqp_basic_properties_t *original,
amqp_basic_properties_t *clone,
amqp_pool_t *pool)
{
memset(clone, 0, sizeof(*clone));
clone->_flags = original->_flags;
#define CLONE_BYTES_POOL(original, clone, pool) \
if (0 == original.len) { \
clone = amqp_empty_bytes; \
} else { \
amqp_pool_alloc_bytes(pool, original.len, &clone); \
if (NULL == clone.bytes) { \
return AMQP_STATUS_NO_MEMORY; \
} \
memcpy(clone.bytes, original.bytes, clone.len); \
}
if (clone->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
CLONE_BYTES_POOL(original->content_type, clone->content_type, pool)
}
if (clone->_flags & AMQP_BASIC_CONTENT_ENCODING_FLAG) {
CLONE_BYTES_POOL(original->content_encoding, clone->content_encoding, pool)
}
if (clone->_flags & AMQP_BASIC_HEADERS_FLAG) {
int res = amqp_table_clone(&original->headers, &clone->headers, pool);
if (AMQP_STATUS_OK != res) {
return res;
}
}
if (clone->_flags & AMQP_BASIC_DELIVERY_MODE_FLAG) {
clone->delivery_mode = original->delivery_mode;
}
if (clone->_flags & AMQP_BASIC_PRIORITY_FLAG) {
clone->priority = original->priority;
}
if (clone->_flags & AMQP_BASIC_CORRELATION_ID_FLAG) {
CLONE_BYTES_POOL(original->correlation_id, clone->correlation_id, pool)
}
if (clone->_flags & AMQP_BASIC_REPLY_TO_FLAG) {
CLONE_BYTES_POOL(original->reply_to, clone->reply_to, pool)
}
if (clone->_flags & AMQP_BASIC_EXPIRATION_FLAG) {
CLONE_BYTES_POOL(original->expiration, clone->expiration, pool)
}
if (clone->_flags & AMQP_BASIC_MESSAGE_ID_FLAG) {
CLONE_BYTES_POOL(original->message_id, clone->message_id, pool)
}
if (clone->_flags & AMQP_BASIC_TIMESTAMP_FLAG) {
clone->timestamp = original->timestamp;
}
if (clone->_flags & AMQP_BASIC_TYPE_FLAG) {
CLONE_BYTES_POOL(original->type, clone->type, pool)
}
if (clone->_flags & AMQP_BASIC_USER_ID_FLAG) {
CLONE_BYTES_POOL(original->user_id, clone->user_id, pool)
}
if (clone->_flags & AMQP_BASIC_APP_ID_FLAG) {
CLONE_BYTES_POOL(original->app_id, clone->app_id, pool)
}
if (clone->_flags & AMQP_BASIC_CLUSTER_ID_FLAG) {
CLONE_BYTES_POOL(original->cluster_id, clone->cluster_id, pool)
}
return AMQP_STATUS_OK;
#undef CLONE_BYTES_POOL
}
void amqp_destroy_message(amqp_message_t *message)
{
empty_amqp_pool(&message->pool);
amqp_bytes_free(message->body);
}
void amqp_destroy_envelope(amqp_envelope_t *envelope)
{
amqp_destroy_message(&envelope->message);
amqp_bytes_free(envelope->routing_key);
amqp_bytes_free(envelope->exchange);
amqp_bytes_free(envelope->consumer_tag);
}
static
int amqp_bytes_malloc_dup_failed(amqp_bytes_t bytes) {
if (bytes.len != 0 && bytes.bytes == NULL) {
return 1;
}
return 0;
}
amqp_rpc_reply_t
amqp_consume_message(amqp_connection_state_t state, amqp_envelope_t *envelope,
struct timeval *timeout, AMQP_UNUSED int flags)
{
int res;
amqp_frame_t frame;
amqp_basic_deliver_t *delivery_method;
amqp_rpc_reply_t ret;
memset(&ret, 0, sizeof(ret));
memset(envelope, 0, sizeof(*envelope));
res = amqp_simple_wait_frame_noblock(state, &frame, timeout);
if (AMQP_STATUS_OK != res) {
ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
ret.library_error = res;
goto error_out1;
}
if (AMQP_FRAME_METHOD != frame.frame_type
|| AMQP_BASIC_DELIVER_METHOD != frame.payload.method.id) {
amqp_put_back_frame(state, &frame);
ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
ret.library_error = AMQP_STATUS_UNEXPECTED_STATE;
goto error_out1;
}
delivery_method = frame.payload.method.decoded;
envelope->channel = frame.channel;
envelope->consumer_tag = amqp_bytes_malloc_dup(delivery_method->consumer_tag);
envelope->delivery_tag = delivery_method->delivery_tag;
envelope->redelivered = delivery_method->redelivered;
envelope->exchange = amqp_bytes_malloc_dup(delivery_method->exchange);
envelope->routing_key = amqp_bytes_malloc_dup(delivery_method->routing_key);
if (amqp_bytes_malloc_dup_failed(envelope->consumer_tag) ||
amqp_bytes_malloc_dup_failed(envelope->exchange) ||
amqp_bytes_malloc_dup_failed(envelope->routing_key)) {
ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
ret.library_error = AMQP_STATUS_NO_MEMORY;
goto error_out2;
}
ret = amqp_read_message(state, envelope->channel, &envelope->message, 0);
if (AMQP_RESPONSE_NORMAL != ret.reply_type) {
goto error_out2;
}
ret.reply_type = AMQP_RESPONSE_NORMAL;
return ret;
error_out2:
amqp_bytes_free(envelope->routing_key);
amqp_bytes_free(envelope->exchange);
amqp_bytes_free(envelope->consumer_tag);
error_out1:
return ret;
}
amqp_rpc_reply_t amqp_read_message(amqp_connection_state_t state,
amqp_channel_t channel,
amqp_message_t *message,
AMQP_UNUSED int flags)
{
amqp_frame_t frame;
amqp_rpc_reply_t ret;
size_t body_read;
char *body_read_ptr;
int res;
memset(&ret, 0, sizeof(ret));
memset(message, 0, sizeof(*message));
res = amqp_simple_wait_frame_on_channel(state, channel, &frame);
if (AMQP_STATUS_OK != res) {
ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
ret.library_error = res;
goto error_out1;
}
if (AMQP_FRAME_HEADER != frame.frame_type) {
if (AMQP_FRAME_METHOD == frame.frame_type &&
(AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id ||
AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) {
ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION;
ret.reply = frame.payload.method;
} else {
ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
ret.library_error = AMQP_STATUS_UNEXPECTED_STATE;
amqp_put_back_frame(state, &frame);
}
goto error_out1;
}
init_amqp_pool(&message->pool, 4096);
res = amqp_basic_properties_clone(frame.payload.properties.decoded,
&message->properties, &message->pool);
if (AMQP_STATUS_OK != res) {
ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
ret.library_error = res;
goto error_out3;
}
if (0 == frame.payload.properties.body_size) {
message->body = amqp_empty_bytes;
} else {
if (SIZE_MAX < frame.payload.properties.body_size) {
ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
ret.library_error = AMQP_STATUS_NO_MEMORY;
goto error_out1;
}
message->body = amqp_bytes_malloc((size_t)frame.payload.properties.body_size);
if (NULL == message->body.bytes) {
ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
ret.library_error = AMQP_STATUS_NO_MEMORY;
goto error_out1;
}
}
body_read = 0;
body_read_ptr = message->body.bytes;
while (body_read < message->body.len) {
res = amqp_simple_wait_frame_on_channel(state, channel, &frame);
if (AMQP_STATUS_OK != res) {
ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
ret.library_error = res;
goto error_out2;
}
if (AMQP_FRAME_BODY != frame.frame_type) {
if (AMQP_FRAME_METHOD == frame.frame_type &&
(AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id ||
AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) {
ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION;
ret.reply = frame.payload.method;
} else {
ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
ret.library_error = AMQP_STATUS_BAD_AMQP_DATA;
}
goto error_out2;
}
if (body_read + frame.payload.body_fragment.len > message->body.len) {
ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
ret.library_error = AMQP_STATUS_BAD_AMQP_DATA;
goto error_out2;
}
memcpy(body_read_ptr, frame.payload.body_fragment.bytes, frame.payload.body_fragment.len);
body_read += frame.payload.body_fragment.len;
body_read_ptr += frame.payload.body_fragment.len;
}
ret.reply_type = AMQP_RESPONSE_NORMAL;
return ret;
error_out2:
amqp_bytes_free(message->body);
error_out3:
empty_amqp_pool(&message->pool);
error_out1:
return ret;
}
rabbitmq-c-0.8.0/librabbitmq/amqp_framing.c 0000664 0000000 0000000 00000277406 12702357234 0020662 0 ustar 00root root 0000000 0000000 /* Generated code. Do not edit. Edit and re-run codegen.py instead.
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "amqp_private.h"
#include
#include
#include
#include
char const *amqp_constant_name(int constantNumber) {
switch (constantNumber) {
case AMQP_FRAME_METHOD: return "AMQP_FRAME_METHOD";
case AMQP_FRAME_HEADER: return "AMQP_FRAME_HEADER";
case AMQP_FRAME_BODY: return "AMQP_FRAME_BODY";
case AMQP_FRAME_HEARTBEAT: return "AMQP_FRAME_HEARTBEAT";
case AMQP_FRAME_MIN_SIZE: return "AMQP_FRAME_MIN_SIZE";
case AMQP_FRAME_END: return "AMQP_FRAME_END";
case AMQP_REPLY_SUCCESS: return "AMQP_REPLY_SUCCESS";
case AMQP_CONTENT_TOO_LARGE: return "AMQP_CONTENT_TOO_LARGE";
case AMQP_NO_ROUTE: return "AMQP_NO_ROUTE";
case AMQP_NO_CONSUMERS: return "AMQP_NO_CONSUMERS";
case AMQP_ACCESS_REFUSED: return "AMQP_ACCESS_REFUSED";
case AMQP_NOT_FOUND: return "AMQP_NOT_FOUND";
case AMQP_RESOURCE_LOCKED: return "AMQP_RESOURCE_LOCKED";
case AMQP_PRECONDITION_FAILED: return "AMQP_PRECONDITION_FAILED";
case AMQP_CONNECTION_FORCED: return "AMQP_CONNECTION_FORCED";
case AMQP_INVALID_PATH: return "AMQP_INVALID_PATH";
case AMQP_FRAME_ERROR: return "AMQP_FRAME_ERROR";
case AMQP_SYNTAX_ERROR: return "AMQP_SYNTAX_ERROR";
case AMQP_COMMAND_INVALID: return "AMQP_COMMAND_INVALID";
case AMQP_CHANNEL_ERROR: return "AMQP_CHANNEL_ERROR";
case AMQP_UNEXPECTED_FRAME: return "AMQP_UNEXPECTED_FRAME";
case AMQP_RESOURCE_ERROR: return "AMQP_RESOURCE_ERROR";
case AMQP_NOT_ALLOWED: return "AMQP_NOT_ALLOWED";
case AMQP_NOT_IMPLEMENTED: return "AMQP_NOT_IMPLEMENTED";
case AMQP_INTERNAL_ERROR: return "AMQP_INTERNAL_ERROR";
default: return "(unknown)";
}
}
amqp_boolean_t amqp_constant_is_hard_error(int constantNumber) {
switch (constantNumber) {
case AMQP_CONNECTION_FORCED: return 1;
case AMQP_INVALID_PATH: return 1;
case AMQP_FRAME_ERROR: return 1;
case AMQP_SYNTAX_ERROR: return 1;
case AMQP_COMMAND_INVALID: return 1;
case AMQP_CHANNEL_ERROR: return 1;
case AMQP_UNEXPECTED_FRAME: return 1;
case AMQP_RESOURCE_ERROR: return 1;
case AMQP_NOT_ALLOWED: return 1;
case AMQP_NOT_IMPLEMENTED: return 1;
case AMQP_INTERNAL_ERROR: return 1;
default: return 0;
}
}
char const *amqp_method_name(amqp_method_number_t methodNumber) {
switch (methodNumber) {
case AMQP_CONNECTION_START_METHOD: return "AMQP_CONNECTION_START_METHOD";
case AMQP_CONNECTION_START_OK_METHOD: return "AMQP_CONNECTION_START_OK_METHOD";
case AMQP_CONNECTION_SECURE_METHOD: return "AMQP_CONNECTION_SECURE_METHOD";
case AMQP_CONNECTION_SECURE_OK_METHOD: return "AMQP_CONNECTION_SECURE_OK_METHOD";
case AMQP_CONNECTION_TUNE_METHOD: return "AMQP_CONNECTION_TUNE_METHOD";
case AMQP_CONNECTION_TUNE_OK_METHOD: return "AMQP_CONNECTION_TUNE_OK_METHOD";
case AMQP_CONNECTION_OPEN_METHOD: return "AMQP_CONNECTION_OPEN_METHOD";
case AMQP_CONNECTION_OPEN_OK_METHOD: return "AMQP_CONNECTION_OPEN_OK_METHOD";
case AMQP_CONNECTION_CLOSE_METHOD: return "AMQP_CONNECTION_CLOSE_METHOD";
case AMQP_CONNECTION_CLOSE_OK_METHOD: return "AMQP_CONNECTION_CLOSE_OK_METHOD";
case AMQP_CONNECTION_BLOCKED_METHOD: return "AMQP_CONNECTION_BLOCKED_METHOD";
case AMQP_CONNECTION_UNBLOCKED_METHOD: return "AMQP_CONNECTION_UNBLOCKED_METHOD";
case AMQP_CHANNEL_OPEN_METHOD: return "AMQP_CHANNEL_OPEN_METHOD";
case AMQP_CHANNEL_OPEN_OK_METHOD: return "AMQP_CHANNEL_OPEN_OK_METHOD";
case AMQP_CHANNEL_FLOW_METHOD: return "AMQP_CHANNEL_FLOW_METHOD";
case AMQP_CHANNEL_FLOW_OK_METHOD: return "AMQP_CHANNEL_FLOW_OK_METHOD";
case AMQP_CHANNEL_CLOSE_METHOD: return "AMQP_CHANNEL_CLOSE_METHOD";
case AMQP_CHANNEL_CLOSE_OK_METHOD: return "AMQP_CHANNEL_CLOSE_OK_METHOD";
case AMQP_ACCESS_REQUEST_METHOD: return "AMQP_ACCESS_REQUEST_METHOD";
case AMQP_ACCESS_REQUEST_OK_METHOD: return "AMQP_ACCESS_REQUEST_OK_METHOD";
case AMQP_EXCHANGE_DECLARE_METHOD: return "AMQP_EXCHANGE_DECLARE_METHOD";
case AMQP_EXCHANGE_DECLARE_OK_METHOD: return "AMQP_EXCHANGE_DECLARE_OK_METHOD";
case AMQP_EXCHANGE_DELETE_METHOD: return "AMQP_EXCHANGE_DELETE_METHOD";
case AMQP_EXCHANGE_DELETE_OK_METHOD: return "AMQP_EXCHANGE_DELETE_OK_METHOD";
case AMQP_EXCHANGE_BIND_METHOD: return "AMQP_EXCHANGE_BIND_METHOD";
case AMQP_EXCHANGE_BIND_OK_METHOD: return "AMQP_EXCHANGE_BIND_OK_METHOD";
case AMQP_EXCHANGE_UNBIND_METHOD: return "AMQP_EXCHANGE_UNBIND_METHOD";
case AMQP_EXCHANGE_UNBIND_OK_METHOD: return "AMQP_EXCHANGE_UNBIND_OK_METHOD";
case AMQP_QUEUE_DECLARE_METHOD: return "AMQP_QUEUE_DECLARE_METHOD";
case AMQP_QUEUE_DECLARE_OK_METHOD: return "AMQP_QUEUE_DECLARE_OK_METHOD";
case AMQP_QUEUE_BIND_METHOD: return "AMQP_QUEUE_BIND_METHOD";
case AMQP_QUEUE_BIND_OK_METHOD: return "AMQP_QUEUE_BIND_OK_METHOD";
case AMQP_QUEUE_PURGE_METHOD: return "AMQP_QUEUE_PURGE_METHOD";
case AMQP_QUEUE_PURGE_OK_METHOD: return "AMQP_QUEUE_PURGE_OK_METHOD";
case AMQP_QUEUE_DELETE_METHOD: return "AMQP_QUEUE_DELETE_METHOD";
case AMQP_QUEUE_DELETE_OK_METHOD: return "AMQP_QUEUE_DELETE_OK_METHOD";
case AMQP_QUEUE_UNBIND_METHOD: return "AMQP_QUEUE_UNBIND_METHOD";
case AMQP_QUEUE_UNBIND_OK_METHOD: return "AMQP_QUEUE_UNBIND_OK_METHOD";
case AMQP_BASIC_QOS_METHOD: return "AMQP_BASIC_QOS_METHOD";
case AMQP_BASIC_QOS_OK_METHOD: return "AMQP_BASIC_QOS_OK_METHOD";
case AMQP_BASIC_CONSUME_METHOD: return "AMQP_BASIC_CONSUME_METHOD";
case AMQP_BASIC_CONSUME_OK_METHOD: return "AMQP_BASIC_CONSUME_OK_METHOD";
case AMQP_BASIC_CANCEL_METHOD: return "AMQP_BASIC_CANCEL_METHOD";
case AMQP_BASIC_CANCEL_OK_METHOD: return "AMQP_BASIC_CANCEL_OK_METHOD";
case AMQP_BASIC_PUBLISH_METHOD: return "AMQP_BASIC_PUBLISH_METHOD";
case AMQP_BASIC_RETURN_METHOD: return "AMQP_BASIC_RETURN_METHOD";
case AMQP_BASIC_DELIVER_METHOD: return "AMQP_BASIC_DELIVER_METHOD";
case AMQP_BASIC_GET_METHOD: return "AMQP_BASIC_GET_METHOD";
case AMQP_BASIC_GET_OK_METHOD: return "AMQP_BASIC_GET_OK_METHOD";
case AMQP_BASIC_GET_EMPTY_METHOD: return "AMQP_BASIC_GET_EMPTY_METHOD";
case AMQP_BASIC_ACK_METHOD: return "AMQP_BASIC_ACK_METHOD";
case AMQP_BASIC_REJECT_METHOD: return "AMQP_BASIC_REJECT_METHOD";
case AMQP_BASIC_RECOVER_ASYNC_METHOD: return "AMQP_BASIC_RECOVER_ASYNC_METHOD";
case AMQP_BASIC_RECOVER_METHOD: return "AMQP_BASIC_RECOVER_METHOD";
case AMQP_BASIC_RECOVER_OK_METHOD: return "AMQP_BASIC_RECOVER_OK_METHOD";
case AMQP_BASIC_NACK_METHOD: return "AMQP_BASIC_NACK_METHOD";
case AMQP_TX_SELECT_METHOD: return "AMQP_TX_SELECT_METHOD";
case AMQP_TX_SELECT_OK_METHOD: return "AMQP_TX_SELECT_OK_METHOD";
case AMQP_TX_COMMIT_METHOD: return "AMQP_TX_COMMIT_METHOD";
case AMQP_TX_COMMIT_OK_METHOD: return "AMQP_TX_COMMIT_OK_METHOD";
case AMQP_TX_ROLLBACK_METHOD: return "AMQP_TX_ROLLBACK_METHOD";
case AMQP_TX_ROLLBACK_OK_METHOD: return "AMQP_TX_ROLLBACK_OK_METHOD";
case AMQP_CONFIRM_SELECT_METHOD: return "AMQP_CONFIRM_SELECT_METHOD";
case AMQP_CONFIRM_SELECT_OK_METHOD: return "AMQP_CONFIRM_SELECT_OK_METHOD";
default: return NULL;
}
}
amqp_boolean_t amqp_method_has_content(amqp_method_number_t methodNumber) {
switch (methodNumber) {
case AMQP_BASIC_PUBLISH_METHOD: return 1;
case AMQP_BASIC_RETURN_METHOD: return 1;
case AMQP_BASIC_DELIVER_METHOD: return 1;
case AMQP_BASIC_GET_OK_METHOD: return 1;
default: return 0;
}
}
int amqp_decode_method(amqp_method_number_t methodNumber,
amqp_pool_t *pool,
amqp_bytes_t encoded,
void **decoded)
{
size_t offset = 0;
uint8_t bit_buffer;
switch (methodNumber) {
case AMQP_CONNECTION_START_METHOD: {
amqp_connection_start_t *m = (amqp_connection_start_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_start_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_8(encoded, &offset, &m->version_major)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_8(encoded, &offset, &m->version_minor)) return AMQP_STATUS_BAD_AMQP_DATA;
{
int res = amqp_decode_table(encoded, pool, &(m->server_properties), &offset);
if (res < 0) return res;
}
{
uint32_t len;
if (!amqp_decode_32(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->mechanisms, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint32_t len;
if (!amqp_decode_32(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->locales, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_CONNECTION_START_OK_METHOD: {
amqp_connection_start_ok_t *m = (amqp_connection_start_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_start_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
int res = amqp_decode_table(encoded, pool, &(m->client_properties), &offset);
if (res < 0) return res;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->mechanism, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint32_t len;
if (!amqp_decode_32(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->response, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->locale, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_CONNECTION_SECURE_METHOD: {
amqp_connection_secure_t *m = (amqp_connection_secure_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_secure_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint32_t len;
if (!amqp_decode_32(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->challenge, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_CONNECTION_SECURE_OK_METHOD: {
amqp_connection_secure_ok_t *m = (amqp_connection_secure_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_secure_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint32_t len;
if (!amqp_decode_32(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->response, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_CONNECTION_TUNE_METHOD: {
amqp_connection_tune_t *m = (amqp_connection_tune_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_tune_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->channel_max)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_32(encoded, &offset, &m->frame_max)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_16(encoded, &offset, &m->heartbeat)) return AMQP_STATUS_BAD_AMQP_DATA;
*decoded = m;
return 0;
}
case AMQP_CONNECTION_TUNE_OK_METHOD: {
amqp_connection_tune_ok_t *m = (amqp_connection_tune_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_tune_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->channel_max)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_32(encoded, &offset, &m->frame_max)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_16(encoded, &offset, &m->heartbeat)) return AMQP_STATUS_BAD_AMQP_DATA;
*decoded = m;
return 0;
}
case AMQP_CONNECTION_OPEN_METHOD: {
amqp_connection_open_t *m = (amqp_connection_open_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_open_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->virtual_host, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->capabilities, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->insist = (bit_buffer & (1 << 0)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_CONNECTION_OPEN_OK_METHOD: {
amqp_connection_open_ok_t *m = (amqp_connection_open_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_open_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->known_hosts, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_CONNECTION_CLOSE_METHOD: {
amqp_connection_close_t *m = (amqp_connection_close_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_close_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->reply_code)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->reply_text, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_16(encoded, &offset, &m->class_id)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_16(encoded, &offset, &m->method_id)) return AMQP_STATUS_BAD_AMQP_DATA;
*decoded = m;
return 0;
}
case AMQP_CONNECTION_CLOSE_OK_METHOD: {
amqp_connection_close_ok_t *m = (amqp_connection_close_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_close_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_CONNECTION_BLOCKED_METHOD: {
amqp_connection_blocked_t *m = (amqp_connection_blocked_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_blocked_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->reason, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_CONNECTION_UNBLOCKED_METHOD: {
amqp_connection_unblocked_t *m = (amqp_connection_unblocked_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_unblocked_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_CHANNEL_OPEN_METHOD: {
amqp_channel_open_t *m = (amqp_channel_open_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_open_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->out_of_band, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_CHANNEL_OPEN_OK_METHOD: {
amqp_channel_open_ok_t *m = (amqp_channel_open_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_open_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint32_t len;
if (!amqp_decode_32(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->channel_id, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_CHANNEL_FLOW_METHOD: {
amqp_channel_flow_t *m = (amqp_channel_flow_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_flow_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->active = (bit_buffer & (1 << 0)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_CHANNEL_FLOW_OK_METHOD: {
amqp_channel_flow_ok_t *m = (amqp_channel_flow_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_flow_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->active = (bit_buffer & (1 << 0)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_CHANNEL_CLOSE_METHOD: {
amqp_channel_close_t *m = (amqp_channel_close_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_close_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->reply_code)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->reply_text, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_16(encoded, &offset, &m->class_id)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_16(encoded, &offset, &m->method_id)) return AMQP_STATUS_BAD_AMQP_DATA;
*decoded = m;
return 0;
}
case AMQP_CHANNEL_CLOSE_OK_METHOD: {
amqp_channel_close_ok_t *m = (amqp_channel_close_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_close_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_ACCESS_REQUEST_METHOD: {
amqp_access_request_t *m = (amqp_access_request_t *) amqp_pool_alloc(pool, sizeof(amqp_access_request_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->realm, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->exclusive = (bit_buffer & (1 << 0)) ? 1 : 0;
m->passive = (bit_buffer & (1 << 1)) ? 1 : 0;
m->active = (bit_buffer & (1 << 2)) ? 1 : 0;
m->write = (bit_buffer & (1 << 3)) ? 1 : 0;
m->read = (bit_buffer & (1 << 4)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_ACCESS_REQUEST_OK_METHOD: {
amqp_access_request_ok_t *m = (amqp_access_request_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_access_request_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
*decoded = m;
return 0;
}
case AMQP_EXCHANGE_DECLARE_METHOD: {
amqp_exchange_declare_t *m = (amqp_exchange_declare_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_declare_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->type, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->passive = (bit_buffer & (1 << 0)) ? 1 : 0;
m->durable = (bit_buffer & (1 << 1)) ? 1 : 0;
m->auto_delete = (bit_buffer & (1 << 2)) ? 1 : 0;
m->internal = (bit_buffer & (1 << 3)) ? 1 : 0;
m->nowait = (bit_buffer & (1 << 4)) ? 1 : 0;
{
int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
if (res < 0) return res;
}
*decoded = m;
return 0;
}
case AMQP_EXCHANGE_DECLARE_OK_METHOD: {
amqp_exchange_declare_ok_t *m = (amqp_exchange_declare_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_declare_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_EXCHANGE_DELETE_METHOD: {
amqp_exchange_delete_t *m = (amqp_exchange_delete_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_delete_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->if_unused = (bit_buffer & (1 << 0)) ? 1 : 0;
m->nowait = (bit_buffer & (1 << 1)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_EXCHANGE_DELETE_OK_METHOD: {
amqp_exchange_delete_ok_t *m = (amqp_exchange_delete_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_delete_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_EXCHANGE_BIND_METHOD: {
amqp_exchange_bind_t *m = (amqp_exchange_bind_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_bind_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->destination, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->source, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0;
{
int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
if (res < 0) return res;
}
*decoded = m;
return 0;
}
case AMQP_EXCHANGE_BIND_OK_METHOD: {
amqp_exchange_bind_ok_t *m = (amqp_exchange_bind_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_bind_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_EXCHANGE_UNBIND_METHOD: {
amqp_exchange_unbind_t *m = (amqp_exchange_unbind_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_unbind_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->destination, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->source, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0;
{
int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
if (res < 0) return res;
}
*decoded = m;
return 0;
}
case AMQP_EXCHANGE_UNBIND_OK_METHOD: {
amqp_exchange_unbind_ok_t *m = (amqp_exchange_unbind_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_unbind_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_QUEUE_DECLARE_METHOD: {
amqp_queue_declare_t *m = (amqp_queue_declare_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_declare_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->queue, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->passive = (bit_buffer & (1 << 0)) ? 1 : 0;
m->durable = (bit_buffer & (1 << 1)) ? 1 : 0;
m->exclusive = (bit_buffer & (1 << 2)) ? 1 : 0;
m->auto_delete = (bit_buffer & (1 << 3)) ? 1 : 0;
m->nowait = (bit_buffer & (1 << 4)) ? 1 : 0;
{
int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
if (res < 0) return res;
}
*decoded = m;
return 0;
}
case AMQP_QUEUE_DECLARE_OK_METHOD: {
amqp_queue_declare_ok_t *m = (amqp_queue_declare_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_declare_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->queue, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_32(encoded, &offset, &m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_32(encoded, &offset, &m->consumer_count)) return AMQP_STATUS_BAD_AMQP_DATA;
*decoded = m;
return 0;
}
case AMQP_QUEUE_BIND_METHOD: {
amqp_queue_bind_t *m = (amqp_queue_bind_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_bind_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->queue, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0;
{
int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
if (res < 0) return res;
}
*decoded = m;
return 0;
}
case AMQP_QUEUE_BIND_OK_METHOD: {
amqp_queue_bind_ok_t *m = (amqp_queue_bind_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_bind_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_QUEUE_PURGE_METHOD: {
amqp_queue_purge_t *m = (amqp_queue_purge_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_purge_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->queue, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_QUEUE_PURGE_OK_METHOD: {
amqp_queue_purge_ok_t *m = (amqp_queue_purge_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_purge_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_32(encoded, &offset, &m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
*decoded = m;
return 0;
}
case AMQP_QUEUE_DELETE_METHOD: {
amqp_queue_delete_t *m = (amqp_queue_delete_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_delete_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->queue, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->if_unused = (bit_buffer & (1 << 0)) ? 1 : 0;
m->if_empty = (bit_buffer & (1 << 1)) ? 1 : 0;
m->nowait = (bit_buffer & (1 << 2)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_QUEUE_DELETE_OK_METHOD: {
amqp_queue_delete_ok_t *m = (amqp_queue_delete_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_delete_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_32(encoded, &offset, &m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
*decoded = m;
return 0;
}
case AMQP_QUEUE_UNBIND_METHOD: {
amqp_queue_unbind_t *m = (amqp_queue_unbind_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_unbind_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->queue, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
if (res < 0) return res;
}
*decoded = m;
return 0;
}
case AMQP_QUEUE_UNBIND_OK_METHOD: {
amqp_queue_unbind_ok_t *m = (amqp_queue_unbind_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_unbind_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_BASIC_QOS_METHOD: {
amqp_basic_qos_t *m = (amqp_basic_qos_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_qos_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_32(encoded, &offset, &m->prefetch_size)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_16(encoded, &offset, &m->prefetch_count)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->global = (bit_buffer & (1 << 0)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_BASIC_QOS_OK_METHOD: {
amqp_basic_qos_ok_t *m = (amqp_basic_qos_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_qos_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_BASIC_CONSUME_METHOD: {
amqp_basic_consume_t *m = (amqp_basic_consume_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_consume_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->queue, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->no_local = (bit_buffer & (1 << 0)) ? 1 : 0;
m->no_ack = (bit_buffer & (1 << 1)) ? 1 : 0;
m->exclusive = (bit_buffer & (1 << 2)) ? 1 : 0;
m->nowait = (bit_buffer & (1 << 3)) ? 1 : 0;
{
int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
if (res < 0) return res;
}
*decoded = m;
return 0;
}
case AMQP_BASIC_CONSUME_OK_METHOD: {
amqp_basic_consume_ok_t *m = (amqp_basic_consume_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_consume_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_BASIC_CANCEL_METHOD: {
amqp_basic_cancel_t *m = (amqp_basic_cancel_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_cancel_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_BASIC_CANCEL_OK_METHOD: {
amqp_basic_cancel_ok_t *m = (amqp_basic_cancel_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_cancel_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_BASIC_PUBLISH_METHOD: {
amqp_basic_publish_t *m = (amqp_basic_publish_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_publish_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->mandatory = (bit_buffer & (1 << 0)) ? 1 : 0;
m->immediate = (bit_buffer & (1 << 1)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_BASIC_RETURN_METHOD: {
amqp_basic_return_t *m = (amqp_basic_return_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_return_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->reply_code)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->reply_text, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_BASIC_DELIVER_METHOD: {
amqp_basic_deliver_t *m = (amqp_basic_deliver_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_deliver_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->redelivered = (bit_buffer & (1 << 0)) ? 1 : 0;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_BASIC_GET_METHOD: {
amqp_basic_get_t *m = (amqp_basic_get_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_get_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->queue, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->no_ack = (bit_buffer & (1 << 0)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_BASIC_GET_OK_METHOD: {
amqp_basic_get_ok_t *m = (amqp_basic_get_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_get_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->redelivered = (bit_buffer & (1 << 0)) ? 1 : 0;
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (!amqp_decode_32(encoded, &offset, &m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
*decoded = m;
return 0;
}
case AMQP_BASIC_GET_EMPTY_METHOD: {
amqp_basic_get_empty_t *m = (amqp_basic_get_empty_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_get_empty_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &m->cluster_id, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
*decoded = m;
return 0;
}
case AMQP_BASIC_ACK_METHOD: {
amqp_basic_ack_t *m = (amqp_basic_ack_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_ack_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->multiple = (bit_buffer & (1 << 0)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_BASIC_REJECT_METHOD: {
amqp_basic_reject_t *m = (amqp_basic_reject_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_reject_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->requeue = (bit_buffer & (1 << 0)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_BASIC_RECOVER_ASYNC_METHOD: {
amqp_basic_recover_async_t *m = (amqp_basic_recover_async_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_recover_async_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->requeue = (bit_buffer & (1 << 0)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_BASIC_RECOVER_METHOD: {
amqp_basic_recover_t *m = (amqp_basic_recover_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_recover_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->requeue = (bit_buffer & (1 << 0)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_BASIC_RECOVER_OK_METHOD: {
amqp_basic_recover_ok_t *m = (amqp_basic_recover_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_recover_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_BASIC_NACK_METHOD: {
amqp_basic_nack_t *m = (amqp_basic_nack_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_nack_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->multiple = (bit_buffer & (1 << 0)) ? 1 : 0;
m->requeue = (bit_buffer & (1 << 1)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_TX_SELECT_METHOD: {
amqp_tx_select_t *m = (amqp_tx_select_t *) amqp_pool_alloc(pool, sizeof(amqp_tx_select_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_TX_SELECT_OK_METHOD: {
amqp_tx_select_ok_t *m = (amqp_tx_select_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_tx_select_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_TX_COMMIT_METHOD: {
amqp_tx_commit_t *m = (amqp_tx_commit_t *) amqp_pool_alloc(pool, sizeof(amqp_tx_commit_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_TX_COMMIT_OK_METHOD: {
amqp_tx_commit_ok_t *m = (amqp_tx_commit_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_tx_commit_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_TX_ROLLBACK_METHOD: {
amqp_tx_rollback_t *m = (amqp_tx_rollback_t *) amqp_pool_alloc(pool, sizeof(amqp_tx_rollback_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_TX_ROLLBACK_OK_METHOD: {
amqp_tx_rollback_ok_t *m = (amqp_tx_rollback_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_tx_rollback_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
case AMQP_CONFIRM_SELECT_METHOD: {
amqp_confirm_select_t *m = (amqp_confirm_select_t *) amqp_pool_alloc(pool, sizeof(amqp_confirm_select_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0;
*decoded = m;
return 0;
}
case AMQP_CONFIRM_SELECT_OK_METHOD: {
amqp_confirm_select_ok_t *m = (amqp_confirm_select_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_confirm_select_ok_t));
if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
*decoded = m;
return 0;
}
default: return AMQP_STATUS_UNKNOWN_METHOD;
}
}
int amqp_decode_properties(uint16_t class_id,
amqp_pool_t *pool,
amqp_bytes_t encoded,
void **decoded)
{
size_t offset = 0;
amqp_flags_t flags = 0;
int flagword_index = 0;
uint16_t partial_flags;
do {
if (!amqp_decode_16(encoded, &offset, &partial_flags))
return AMQP_STATUS_BAD_AMQP_DATA;
flags |= (partial_flags << (flagword_index * 16));
flagword_index++;
} while (partial_flags & 1);
switch (class_id) {
case 10: {
amqp_connection_properties_t *p = (amqp_connection_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_properties_t));
if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
p->_flags = flags;
*decoded = p;
return 0;
}
case 20: {
amqp_channel_properties_t *p = (amqp_channel_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_properties_t));
if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
p->_flags = flags;
*decoded = p;
return 0;
}
case 30: {
amqp_access_properties_t *p = (amqp_access_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_access_properties_t));
if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
p->_flags = flags;
*decoded = p;
return 0;
}
case 40: {
amqp_exchange_properties_t *p = (amqp_exchange_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_properties_t));
if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
p->_flags = flags;
*decoded = p;
return 0;
}
case 50: {
amqp_queue_properties_t *p = (amqp_queue_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_properties_t));
if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
p->_flags = flags;
*decoded = p;
return 0;
}
case 60: {
amqp_basic_properties_t *p = (amqp_basic_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_properties_t));
if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
p->_flags = flags;
if (flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &p->content_type, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
}
if (flags & AMQP_BASIC_CONTENT_ENCODING_FLAG) {
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &p->content_encoding, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
}
if (flags & AMQP_BASIC_HEADERS_FLAG) {
{
int res = amqp_decode_table(encoded, pool, &(p->headers), &offset);
if (res < 0) return res;
}
}
if (flags & AMQP_BASIC_DELIVERY_MODE_FLAG) {
if (!amqp_decode_8(encoded, &offset, &p->delivery_mode)) return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_PRIORITY_FLAG) {
if (!amqp_decode_8(encoded, &offset, &p->priority)) return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_CORRELATION_ID_FLAG) {
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &p->correlation_id, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
}
if (flags & AMQP_BASIC_REPLY_TO_FLAG) {
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &p->reply_to, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
}
if (flags & AMQP_BASIC_EXPIRATION_FLAG) {
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &p->expiration, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
}
if (flags & AMQP_BASIC_MESSAGE_ID_FLAG) {
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &p->message_id, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
}
if (flags & AMQP_BASIC_TIMESTAMP_FLAG) {
if (!amqp_decode_64(encoded, &offset, &p->timestamp)) return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_TYPE_FLAG) {
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &p->type, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
}
if (flags & AMQP_BASIC_USER_ID_FLAG) {
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &p->user_id, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
}
if (flags & AMQP_BASIC_APP_ID_FLAG) {
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &p->app_id, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
}
if (flags & AMQP_BASIC_CLUSTER_ID_FLAG) {
{
uint8_t len;
if (!amqp_decode_8(encoded, &offset, &len)
|| !amqp_decode_bytes(encoded, &offset, &p->cluster_id, len))
return AMQP_STATUS_BAD_AMQP_DATA;
}
}
*decoded = p;
return 0;
}
case 90: {
amqp_tx_properties_t *p = (amqp_tx_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_tx_properties_t));
if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
p->_flags = flags;
*decoded = p;
return 0;
}
case 85: {
amqp_confirm_properties_t *p = (amqp_confirm_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_confirm_properties_t));
if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
p->_flags = flags;
*decoded = p;
return 0;
}
default: return AMQP_STATUS_UNKNOWN_CLASS;
}
}
int amqp_encode_method(amqp_method_number_t methodNumber,
void *decoded,
amqp_bytes_t encoded)
{
size_t offset = 0;
uint8_t bit_buffer;
switch (methodNumber) {
case AMQP_CONNECTION_START_METHOD: {
amqp_connection_start_t *m = (amqp_connection_start_t *) decoded;
if (!amqp_encode_8(encoded, &offset, m->version_major)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_8(encoded, &offset, m->version_minor)) return AMQP_STATUS_BAD_AMQP_DATA;
{
int res = amqp_encode_table(encoded, &(m->server_properties), &offset);
if (res < 0) return res;
}
if (UINT32_MAX < m->mechanisms.len
|| !amqp_encode_32(encoded, &offset, (uint32_t)m->mechanisms.len)
|| !amqp_encode_bytes(encoded, &offset, m->mechanisms))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT32_MAX < m->locales.len
|| !amqp_encode_32(encoded, &offset, (uint32_t)m->locales.len)
|| !amqp_encode_bytes(encoded, &offset, m->locales))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CONNECTION_START_OK_METHOD: {
amqp_connection_start_ok_t *m = (amqp_connection_start_ok_t *) decoded;
{
int res = amqp_encode_table(encoded, &(m->client_properties), &offset);
if (res < 0) return res;
}
if (UINT8_MAX < m->mechanism.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->mechanism.len)
|| !amqp_encode_bytes(encoded, &offset, m->mechanism))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT32_MAX < m->response.len
|| !amqp_encode_32(encoded, &offset, (uint32_t)m->response.len)
|| !amqp_encode_bytes(encoded, &offset, m->response))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->locale.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->locale.len)
|| !amqp_encode_bytes(encoded, &offset, m->locale))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CONNECTION_SECURE_METHOD: {
amqp_connection_secure_t *m = (amqp_connection_secure_t *) decoded;
if (UINT32_MAX < m->challenge.len
|| !amqp_encode_32(encoded, &offset, (uint32_t)m->challenge.len)
|| !amqp_encode_bytes(encoded, &offset, m->challenge))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CONNECTION_SECURE_OK_METHOD: {
amqp_connection_secure_ok_t *m = (amqp_connection_secure_ok_t *) decoded;
if (UINT32_MAX < m->response.len
|| !amqp_encode_32(encoded, &offset, (uint32_t)m->response.len)
|| !amqp_encode_bytes(encoded, &offset, m->response))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CONNECTION_TUNE_METHOD: {
amqp_connection_tune_t *m = (amqp_connection_tune_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->channel_max)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_32(encoded, &offset, m->frame_max)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_16(encoded, &offset, m->heartbeat)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CONNECTION_TUNE_OK_METHOD: {
amqp_connection_tune_ok_t *m = (amqp_connection_tune_ok_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->channel_max)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_32(encoded, &offset, m->frame_max)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_16(encoded, &offset, m->heartbeat)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CONNECTION_OPEN_METHOD: {
amqp_connection_open_t *m = (amqp_connection_open_t *) decoded;
if (UINT8_MAX < m->virtual_host.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->virtual_host.len)
|| !amqp_encode_bytes(encoded, &offset, m->virtual_host))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->capabilities.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->capabilities.len)
|| !amqp_encode_bytes(encoded, &offset, m->capabilities))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->insist) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CONNECTION_OPEN_OK_METHOD: {
amqp_connection_open_ok_t *m = (amqp_connection_open_ok_t *) decoded;
if (UINT8_MAX < m->known_hosts.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->known_hosts.len)
|| !amqp_encode_bytes(encoded, &offset, m->known_hosts))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CONNECTION_CLOSE_METHOD: {
amqp_connection_close_t *m = (amqp_connection_close_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->reply_code)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->reply_text.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->reply_text.len)
|| !amqp_encode_bytes(encoded, &offset, m->reply_text))
return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_16(encoded, &offset, m->class_id)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_16(encoded, &offset, m->method_id)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CONNECTION_CLOSE_OK_METHOD: {
return (int)offset;
}
case AMQP_CONNECTION_BLOCKED_METHOD: {
amqp_connection_blocked_t *m = (amqp_connection_blocked_t *) decoded;
if (UINT8_MAX < m->reason.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->reason.len)
|| !amqp_encode_bytes(encoded, &offset, m->reason))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CONNECTION_UNBLOCKED_METHOD: {
return (int)offset;
}
case AMQP_CHANNEL_OPEN_METHOD: {
amqp_channel_open_t *m = (amqp_channel_open_t *) decoded;
if (UINT8_MAX < m->out_of_band.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->out_of_band.len)
|| !amqp_encode_bytes(encoded, &offset, m->out_of_band))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CHANNEL_OPEN_OK_METHOD: {
amqp_channel_open_ok_t *m = (amqp_channel_open_ok_t *) decoded;
if (UINT32_MAX < m->channel_id.len
|| !amqp_encode_32(encoded, &offset, (uint32_t)m->channel_id.len)
|| !amqp_encode_bytes(encoded, &offset, m->channel_id))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CHANNEL_FLOW_METHOD: {
amqp_channel_flow_t *m = (amqp_channel_flow_t *) decoded;
bit_buffer = 0;
if (m->active) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CHANNEL_FLOW_OK_METHOD: {
amqp_channel_flow_ok_t *m = (amqp_channel_flow_ok_t *) decoded;
bit_buffer = 0;
if (m->active) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CHANNEL_CLOSE_METHOD: {
amqp_channel_close_t *m = (amqp_channel_close_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->reply_code)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->reply_text.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->reply_text.len)
|| !amqp_encode_bytes(encoded, &offset, m->reply_text))
return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_16(encoded, &offset, m->class_id)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_16(encoded, &offset, m->method_id)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CHANNEL_CLOSE_OK_METHOD: {
return (int)offset;
}
case AMQP_ACCESS_REQUEST_METHOD: {
amqp_access_request_t *m = (amqp_access_request_t *) decoded;
if (UINT8_MAX < m->realm.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->realm.len)
|| !amqp_encode_bytes(encoded, &offset, m->realm))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->exclusive) bit_buffer |= (1 << 0);
if (m->passive) bit_buffer |= (1 << 1);
if (m->active) bit_buffer |= (1 << 2);
if (m->write) bit_buffer |= (1 << 3);
if (m->read) bit_buffer |= (1 << 4);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_ACCESS_REQUEST_OK_METHOD: {
amqp_access_request_ok_t *m = (amqp_access_request_ok_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_EXCHANGE_DECLARE_METHOD: {
amqp_exchange_declare_t *m = (amqp_exchange_declare_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->exchange.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len)
|| !amqp_encode_bytes(encoded, &offset, m->exchange))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->type.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->type.len)
|| !amqp_encode_bytes(encoded, &offset, m->type))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->passive) bit_buffer |= (1 << 0);
if (m->durable) bit_buffer |= (1 << 1);
if (m->auto_delete) bit_buffer |= (1 << 2);
if (m->internal) bit_buffer |= (1 << 3);
if (m->nowait) bit_buffer |= (1 << 4);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
{
int res = amqp_encode_table(encoded, &(m->arguments), &offset);
if (res < 0) return res;
}
return (int)offset;
}
case AMQP_EXCHANGE_DECLARE_OK_METHOD: {
return (int)offset;
}
case AMQP_EXCHANGE_DELETE_METHOD: {
amqp_exchange_delete_t *m = (amqp_exchange_delete_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->exchange.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len)
|| !amqp_encode_bytes(encoded, &offset, m->exchange))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->if_unused) bit_buffer |= (1 << 0);
if (m->nowait) bit_buffer |= (1 << 1);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_EXCHANGE_DELETE_OK_METHOD: {
return (int)offset;
}
case AMQP_EXCHANGE_BIND_METHOD: {
amqp_exchange_bind_t *m = (amqp_exchange_bind_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->destination.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->destination.len)
|| !amqp_encode_bytes(encoded, &offset, m->destination))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->source.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->source.len)
|| !amqp_encode_bytes(encoded, &offset, m->source))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->routing_key.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len)
|| !amqp_encode_bytes(encoded, &offset, m->routing_key))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->nowait) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
{
int res = amqp_encode_table(encoded, &(m->arguments), &offset);
if (res < 0) return res;
}
return (int)offset;
}
case AMQP_EXCHANGE_BIND_OK_METHOD: {
return (int)offset;
}
case AMQP_EXCHANGE_UNBIND_METHOD: {
amqp_exchange_unbind_t *m = (amqp_exchange_unbind_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->destination.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->destination.len)
|| !amqp_encode_bytes(encoded, &offset, m->destination))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->source.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->source.len)
|| !amqp_encode_bytes(encoded, &offset, m->source))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->routing_key.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len)
|| !amqp_encode_bytes(encoded, &offset, m->routing_key))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->nowait) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
{
int res = amqp_encode_table(encoded, &(m->arguments), &offset);
if (res < 0) return res;
}
return (int)offset;
}
case AMQP_EXCHANGE_UNBIND_OK_METHOD: {
return (int)offset;
}
case AMQP_QUEUE_DECLARE_METHOD: {
amqp_queue_declare_t *m = (amqp_queue_declare_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->queue.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len)
|| !amqp_encode_bytes(encoded, &offset, m->queue))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->passive) bit_buffer |= (1 << 0);
if (m->durable) bit_buffer |= (1 << 1);
if (m->exclusive) bit_buffer |= (1 << 2);
if (m->auto_delete) bit_buffer |= (1 << 3);
if (m->nowait) bit_buffer |= (1 << 4);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
{
int res = amqp_encode_table(encoded, &(m->arguments), &offset);
if (res < 0) return res;
}
return (int)offset;
}
case AMQP_QUEUE_DECLARE_OK_METHOD: {
amqp_queue_declare_ok_t *m = (amqp_queue_declare_ok_t *) decoded;
if (UINT8_MAX < m->queue.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len)
|| !amqp_encode_bytes(encoded, &offset, m->queue))
return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_32(encoded, &offset, m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_32(encoded, &offset, m->consumer_count)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_QUEUE_BIND_METHOD: {
amqp_queue_bind_t *m = (amqp_queue_bind_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->queue.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len)
|| !amqp_encode_bytes(encoded, &offset, m->queue))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->exchange.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len)
|| !amqp_encode_bytes(encoded, &offset, m->exchange))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->routing_key.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len)
|| !amqp_encode_bytes(encoded, &offset, m->routing_key))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->nowait) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
{
int res = amqp_encode_table(encoded, &(m->arguments), &offset);
if (res < 0) return res;
}
return (int)offset;
}
case AMQP_QUEUE_BIND_OK_METHOD: {
return (int)offset;
}
case AMQP_QUEUE_PURGE_METHOD: {
amqp_queue_purge_t *m = (amqp_queue_purge_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->queue.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len)
|| !amqp_encode_bytes(encoded, &offset, m->queue))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->nowait) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_QUEUE_PURGE_OK_METHOD: {
amqp_queue_purge_ok_t *m = (amqp_queue_purge_ok_t *) decoded;
if (!amqp_encode_32(encoded, &offset, m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_QUEUE_DELETE_METHOD: {
amqp_queue_delete_t *m = (amqp_queue_delete_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->queue.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len)
|| !amqp_encode_bytes(encoded, &offset, m->queue))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->if_unused) bit_buffer |= (1 << 0);
if (m->if_empty) bit_buffer |= (1 << 1);
if (m->nowait) bit_buffer |= (1 << 2);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_QUEUE_DELETE_OK_METHOD: {
amqp_queue_delete_ok_t *m = (amqp_queue_delete_ok_t *) decoded;
if (!amqp_encode_32(encoded, &offset, m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_QUEUE_UNBIND_METHOD: {
amqp_queue_unbind_t *m = (amqp_queue_unbind_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->queue.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len)
|| !amqp_encode_bytes(encoded, &offset, m->queue))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->exchange.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len)
|| !amqp_encode_bytes(encoded, &offset, m->exchange))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->routing_key.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len)
|| !amqp_encode_bytes(encoded, &offset, m->routing_key))
return AMQP_STATUS_BAD_AMQP_DATA;
{
int res = amqp_encode_table(encoded, &(m->arguments), &offset);
if (res < 0) return res;
}
return (int)offset;
}
case AMQP_QUEUE_UNBIND_OK_METHOD: {
return (int)offset;
}
case AMQP_BASIC_QOS_METHOD: {
amqp_basic_qos_t *m = (amqp_basic_qos_t *) decoded;
if (!amqp_encode_32(encoded, &offset, m->prefetch_size)) return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_16(encoded, &offset, m->prefetch_count)) return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->global) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_QOS_OK_METHOD: {
return (int)offset;
}
case AMQP_BASIC_CONSUME_METHOD: {
amqp_basic_consume_t *m = (amqp_basic_consume_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->queue.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len)
|| !amqp_encode_bytes(encoded, &offset, m->queue))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->consumer_tag.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->consumer_tag.len)
|| !amqp_encode_bytes(encoded, &offset, m->consumer_tag))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->no_local) bit_buffer |= (1 << 0);
if (m->no_ack) bit_buffer |= (1 << 1);
if (m->exclusive) bit_buffer |= (1 << 2);
if (m->nowait) bit_buffer |= (1 << 3);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
{
int res = amqp_encode_table(encoded, &(m->arguments), &offset);
if (res < 0) return res;
}
return (int)offset;
}
case AMQP_BASIC_CONSUME_OK_METHOD: {
amqp_basic_consume_ok_t *m = (amqp_basic_consume_ok_t *) decoded;
if (UINT8_MAX < m->consumer_tag.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->consumer_tag.len)
|| !amqp_encode_bytes(encoded, &offset, m->consumer_tag))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_CANCEL_METHOD: {
amqp_basic_cancel_t *m = (amqp_basic_cancel_t *) decoded;
if (UINT8_MAX < m->consumer_tag.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->consumer_tag.len)
|| !amqp_encode_bytes(encoded, &offset, m->consumer_tag))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->nowait) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_CANCEL_OK_METHOD: {
amqp_basic_cancel_ok_t *m = (amqp_basic_cancel_ok_t *) decoded;
if (UINT8_MAX < m->consumer_tag.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->consumer_tag.len)
|| !amqp_encode_bytes(encoded, &offset, m->consumer_tag))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_PUBLISH_METHOD: {
amqp_basic_publish_t *m = (amqp_basic_publish_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->exchange.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len)
|| !amqp_encode_bytes(encoded, &offset, m->exchange))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->routing_key.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len)
|| !amqp_encode_bytes(encoded, &offset, m->routing_key))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->mandatory) bit_buffer |= (1 << 0);
if (m->immediate) bit_buffer |= (1 << 1);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_RETURN_METHOD: {
amqp_basic_return_t *m = (amqp_basic_return_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->reply_code)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->reply_text.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->reply_text.len)
|| !amqp_encode_bytes(encoded, &offset, m->reply_text))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->exchange.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len)
|| !amqp_encode_bytes(encoded, &offset, m->exchange))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->routing_key.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len)
|| !amqp_encode_bytes(encoded, &offset, m->routing_key))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_DELIVER_METHOD: {
amqp_basic_deliver_t *m = (amqp_basic_deliver_t *) decoded;
if (UINT8_MAX < m->consumer_tag.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->consumer_tag.len)
|| !amqp_encode_bytes(encoded, &offset, m->consumer_tag))
return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->redelivered) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->exchange.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len)
|| !amqp_encode_bytes(encoded, &offset, m->exchange))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->routing_key.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len)
|| !amqp_encode_bytes(encoded, &offset, m->routing_key))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_GET_METHOD: {
amqp_basic_get_t *m = (amqp_basic_get_t *) decoded;
if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->queue.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len)
|| !amqp_encode_bytes(encoded, &offset, m->queue))
return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->no_ack) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_GET_OK_METHOD: {
amqp_basic_get_ok_t *m = (amqp_basic_get_ok_t *) decoded;
if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->redelivered) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->exchange.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len)
|| !amqp_encode_bytes(encoded, &offset, m->exchange))
return AMQP_STATUS_BAD_AMQP_DATA;
if (UINT8_MAX < m->routing_key.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len)
|| !amqp_encode_bytes(encoded, &offset, m->routing_key))
return AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_32(encoded, &offset, m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_GET_EMPTY_METHOD: {
amqp_basic_get_empty_t *m = (amqp_basic_get_empty_t *) decoded;
if (UINT8_MAX < m->cluster_id.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)m->cluster_id.len)
|| !amqp_encode_bytes(encoded, &offset, m->cluster_id))
return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_ACK_METHOD: {
amqp_basic_ack_t *m = (amqp_basic_ack_t *) decoded;
if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->multiple) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_REJECT_METHOD: {
amqp_basic_reject_t *m = (amqp_basic_reject_t *) decoded;
if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->requeue) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_RECOVER_ASYNC_METHOD: {
amqp_basic_recover_async_t *m = (amqp_basic_recover_async_t *) decoded;
bit_buffer = 0;
if (m->requeue) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_RECOVER_METHOD: {
amqp_basic_recover_t *m = (amqp_basic_recover_t *) decoded;
bit_buffer = 0;
if (m->requeue) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_BASIC_RECOVER_OK_METHOD: {
return (int)offset;
}
case AMQP_BASIC_NACK_METHOD: {
amqp_basic_nack_t *m = (amqp_basic_nack_t *) decoded;
if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
bit_buffer = 0;
if (m->multiple) bit_buffer |= (1 << 0);
if (m->requeue) bit_buffer |= (1 << 1);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_TX_SELECT_METHOD: {
return (int)offset;
}
case AMQP_TX_SELECT_OK_METHOD: {
return (int)offset;
}
case AMQP_TX_COMMIT_METHOD: {
return (int)offset;
}
case AMQP_TX_COMMIT_OK_METHOD: {
return (int)offset;
}
case AMQP_TX_ROLLBACK_METHOD: {
return (int)offset;
}
case AMQP_TX_ROLLBACK_OK_METHOD: {
return (int)offset;
}
case AMQP_CONFIRM_SELECT_METHOD: {
amqp_confirm_select_t *m = (amqp_confirm_select_t *) decoded;
bit_buffer = 0;
if (m->nowait) bit_buffer |= (1 << 0);
if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
return (int)offset;
}
case AMQP_CONFIRM_SELECT_OK_METHOD: {
return (int)offset;
}
default: return AMQP_STATUS_UNKNOWN_METHOD;
}
}
int amqp_encode_properties(uint16_t class_id,
void *decoded,
amqp_bytes_t encoded)
{
size_t offset = 0;
/* Cheat, and get the flags out generically, relying on the
similarity of structure between classes */
amqp_flags_t flags = * (amqp_flags_t *) decoded; /* cheating! */
{
/* We take a copy of flags to avoid destroying it, as it is used
in the autogenerated code below. */
amqp_flags_t remaining_flags = flags;
do {
amqp_flags_t remainder = remaining_flags >> 16;
uint16_t partial_flags = remaining_flags & 0xFFFE;
if (remainder != 0) { partial_flags |= 1; }
if (!amqp_encode_16(encoded, &offset, partial_flags))
return AMQP_STATUS_BAD_AMQP_DATA;
remaining_flags = remainder;
} while (remaining_flags != 0);
}
switch (class_id) {
case 10: {
return (int)offset;
}
case 20: {
return (int)offset;
}
case 30: {
return (int)offset;
}
case 40: {
return (int)offset;
}
case 50: {
return (int)offset;
}
case 60: {
amqp_basic_properties_t *p = (amqp_basic_properties_t *) decoded;
if (flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
if (UINT8_MAX < p->content_type.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)p->content_type.len)
|| !amqp_encode_bytes(encoded, &offset, p->content_type))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_CONTENT_ENCODING_FLAG) {
if (UINT8_MAX < p->content_encoding.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)p->content_encoding.len)
|| !amqp_encode_bytes(encoded, &offset, p->content_encoding))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_HEADERS_FLAG) {
{
int res = amqp_encode_table(encoded, &(p->headers), &offset);
if (res < 0) return res;
}
}
if (flags & AMQP_BASIC_DELIVERY_MODE_FLAG) {
if (!amqp_encode_8(encoded, &offset, p->delivery_mode)) return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_PRIORITY_FLAG) {
if (!amqp_encode_8(encoded, &offset, p->priority)) return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_CORRELATION_ID_FLAG) {
if (UINT8_MAX < p->correlation_id.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)p->correlation_id.len)
|| !amqp_encode_bytes(encoded, &offset, p->correlation_id))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_REPLY_TO_FLAG) {
if (UINT8_MAX < p->reply_to.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)p->reply_to.len)
|| !amqp_encode_bytes(encoded, &offset, p->reply_to))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_EXPIRATION_FLAG) {
if (UINT8_MAX < p->expiration.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)p->expiration.len)
|| !amqp_encode_bytes(encoded, &offset, p->expiration))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_MESSAGE_ID_FLAG) {
if (UINT8_MAX < p->message_id.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)p->message_id.len)
|| !amqp_encode_bytes(encoded, &offset, p->message_id))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_TIMESTAMP_FLAG) {
if (!amqp_encode_64(encoded, &offset, p->timestamp)) return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_TYPE_FLAG) {
if (UINT8_MAX < p->type.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)p->type.len)
|| !amqp_encode_bytes(encoded, &offset, p->type))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_USER_ID_FLAG) {
if (UINT8_MAX < p->user_id.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)p->user_id.len)
|| !amqp_encode_bytes(encoded, &offset, p->user_id))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_APP_ID_FLAG) {
if (UINT8_MAX < p->app_id.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)p->app_id.len)
|| !amqp_encode_bytes(encoded, &offset, p->app_id))
return AMQP_STATUS_BAD_AMQP_DATA;
}
if (flags & AMQP_BASIC_CLUSTER_ID_FLAG) {
if (UINT8_MAX < p->cluster_id.len
|| !amqp_encode_8(encoded, &offset, (uint8_t)p->cluster_id.len)
|| !amqp_encode_bytes(encoded, &offset, p->cluster_id))
return AMQP_STATUS_BAD_AMQP_DATA;
}
return (int)offset;
}
case 90: {
return (int)offset;
}
case 85: {
return (int)offset;
}
default: return AMQP_STATUS_UNKNOWN_CLASS;
}
}
/**
* amqp_channel_open
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @returns amqp_channel_open_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_channel_open_ok_t *
AMQP_CALL amqp_channel_open(amqp_connection_state_t state, amqp_channel_t channel)
{
amqp_channel_open_t req;
req.out_of_band = amqp_empty_bytes;
return amqp_simple_rpc_decoded(state, channel, AMQP_CHANNEL_OPEN_METHOD, AMQP_CHANNEL_OPEN_OK_METHOD, &req);
}
/**
* amqp_channel_flow
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] active active
* @returns amqp_channel_flow_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_channel_flow_ok_t *
AMQP_CALL amqp_channel_flow(amqp_connection_state_t state, amqp_channel_t channel, amqp_boolean_t active)
{
amqp_channel_flow_t req;
req.active = active;
return amqp_simple_rpc_decoded(state, channel, AMQP_CHANNEL_FLOW_METHOD, AMQP_CHANNEL_FLOW_OK_METHOD, &req);
}
/**
* amqp_exchange_declare
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] exchange exchange
* @param [in] type type
* @param [in] passive passive
* @param [in] durable durable
* @param [in] auto_delete auto_delete
* @param [in] internal internal
* @param [in] arguments arguments
* @returns amqp_exchange_declare_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_exchange_declare_ok_t *
AMQP_CALL amqp_exchange_declare(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t exchange, amqp_bytes_t type, amqp_boolean_t passive, amqp_boolean_t durable, amqp_boolean_t auto_delete, amqp_boolean_t internal, amqp_table_t arguments)
{
amqp_exchange_declare_t req;
req.ticket = 0;
req.exchange = exchange;
req.type = type;
req.passive = passive;
req.durable = durable;
req.auto_delete = auto_delete;
req.internal = internal;
req.nowait = 0;
req.arguments = arguments;
return amqp_simple_rpc_decoded(state, channel, AMQP_EXCHANGE_DECLARE_METHOD, AMQP_EXCHANGE_DECLARE_OK_METHOD, &req);
}
/**
* amqp_exchange_delete
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] exchange exchange
* @param [in] if_unused if_unused
* @returns amqp_exchange_delete_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_exchange_delete_ok_t *
AMQP_CALL amqp_exchange_delete(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t exchange, amqp_boolean_t if_unused)
{
amqp_exchange_delete_t req;
req.ticket = 0;
req.exchange = exchange;
req.if_unused = if_unused;
req.nowait = 0;
return amqp_simple_rpc_decoded(state, channel, AMQP_EXCHANGE_DELETE_METHOD, AMQP_EXCHANGE_DELETE_OK_METHOD, &req);
}
/**
* amqp_exchange_bind
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] destination destination
* @param [in] source source
* @param [in] routing_key routing_key
* @param [in] arguments arguments
* @returns amqp_exchange_bind_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_exchange_bind_ok_t *
AMQP_CALL amqp_exchange_bind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t destination, amqp_bytes_t source, amqp_bytes_t routing_key, amqp_table_t arguments)
{
amqp_exchange_bind_t req;
req.ticket = 0;
req.destination = destination;
req.source = source;
req.routing_key = routing_key;
req.nowait = 0;
req.arguments = arguments;
return amqp_simple_rpc_decoded(state, channel, AMQP_EXCHANGE_BIND_METHOD, AMQP_EXCHANGE_BIND_OK_METHOD, &req);
}
/**
* amqp_exchange_unbind
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] destination destination
* @param [in] source source
* @param [in] routing_key routing_key
* @param [in] arguments arguments
* @returns amqp_exchange_unbind_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_exchange_unbind_ok_t *
AMQP_CALL amqp_exchange_unbind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t destination, amqp_bytes_t source, amqp_bytes_t routing_key, amqp_table_t arguments)
{
amqp_exchange_unbind_t req;
req.ticket = 0;
req.destination = destination;
req.source = source;
req.routing_key = routing_key;
req.nowait = 0;
req.arguments = arguments;
return amqp_simple_rpc_decoded(state, channel, AMQP_EXCHANGE_UNBIND_METHOD, AMQP_EXCHANGE_UNBIND_OK_METHOD, &req);
}
/**
* amqp_queue_declare
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] queue queue
* @param [in] passive passive
* @param [in] durable durable
* @param [in] exclusive exclusive
* @param [in] auto_delete auto_delete
* @param [in] arguments arguments
* @returns amqp_queue_declare_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_queue_declare_ok_t *
AMQP_CALL amqp_queue_declare(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_boolean_t passive, amqp_boolean_t durable, amqp_boolean_t exclusive, amqp_boolean_t auto_delete, amqp_table_t arguments)
{
amqp_queue_declare_t req;
req.ticket = 0;
req.queue = queue;
req.passive = passive;
req.durable = durable;
req.exclusive = exclusive;
req.auto_delete = auto_delete;
req.nowait = 0;
req.arguments = arguments;
return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_DECLARE_METHOD, AMQP_QUEUE_DECLARE_OK_METHOD, &req);
}
/**
* amqp_queue_bind
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] queue queue
* @param [in] exchange exchange
* @param [in] routing_key routing_key
* @param [in] arguments arguments
* @returns amqp_queue_bind_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_queue_bind_ok_t *
AMQP_CALL amqp_queue_bind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments)
{
amqp_queue_bind_t req;
req.ticket = 0;
req.queue = queue;
req.exchange = exchange;
req.routing_key = routing_key;
req.nowait = 0;
req.arguments = arguments;
return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_BIND_METHOD, AMQP_QUEUE_BIND_OK_METHOD, &req);
}
/**
* amqp_queue_purge
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] queue queue
* @returns amqp_queue_purge_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_queue_purge_ok_t *
AMQP_CALL amqp_queue_purge(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue)
{
amqp_queue_purge_t req;
req.ticket = 0;
req.queue = queue;
req.nowait = 0;
return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_PURGE_METHOD, AMQP_QUEUE_PURGE_OK_METHOD, &req);
}
/**
* amqp_queue_delete
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] queue queue
* @param [in] if_unused if_unused
* @param [in] if_empty if_empty
* @returns amqp_queue_delete_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_queue_delete_ok_t *
AMQP_CALL amqp_queue_delete(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_boolean_t if_unused, amqp_boolean_t if_empty)
{
amqp_queue_delete_t req;
req.ticket = 0;
req.queue = queue;
req.if_unused = if_unused;
req.if_empty = if_empty;
req.nowait = 0;
return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_DELETE_METHOD, AMQP_QUEUE_DELETE_OK_METHOD, &req);
}
/**
* amqp_queue_unbind
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] queue queue
* @param [in] exchange exchange
* @param [in] routing_key routing_key
* @param [in] arguments arguments
* @returns amqp_queue_unbind_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_queue_unbind_ok_t *
AMQP_CALL amqp_queue_unbind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments)
{
amqp_queue_unbind_t req;
req.ticket = 0;
req.queue = queue;
req.exchange = exchange;
req.routing_key = routing_key;
req.arguments = arguments;
return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_UNBIND_METHOD, AMQP_QUEUE_UNBIND_OK_METHOD, &req);
}
/**
* amqp_basic_qos
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] prefetch_size prefetch_size
* @param [in] prefetch_count prefetch_count
* @param [in] global global
* @returns amqp_basic_qos_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_basic_qos_ok_t *
AMQP_CALL amqp_basic_qos(amqp_connection_state_t state, amqp_channel_t channel, uint32_t prefetch_size, uint16_t prefetch_count, amqp_boolean_t global)
{
amqp_basic_qos_t req;
req.prefetch_size = prefetch_size;
req.prefetch_count = prefetch_count;
req.global = global;
return amqp_simple_rpc_decoded(state, channel, AMQP_BASIC_QOS_METHOD, AMQP_BASIC_QOS_OK_METHOD, &req);
}
/**
* amqp_basic_consume
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] queue queue
* @param [in] consumer_tag consumer_tag
* @param [in] no_local no_local
* @param [in] no_ack no_ack
* @param [in] exclusive exclusive
* @param [in] arguments arguments
* @returns amqp_basic_consume_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_basic_consume_ok_t *
AMQP_CALL amqp_basic_consume(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t consumer_tag, amqp_boolean_t no_local, amqp_boolean_t no_ack, amqp_boolean_t exclusive, amqp_table_t arguments)
{
amqp_basic_consume_t req;
req.ticket = 0;
req.queue = queue;
req.consumer_tag = consumer_tag;
req.no_local = no_local;
req.no_ack = no_ack;
req.exclusive = exclusive;
req.nowait = 0;
req.arguments = arguments;
return amqp_simple_rpc_decoded(state, channel, AMQP_BASIC_CONSUME_METHOD, AMQP_BASIC_CONSUME_OK_METHOD, &req);
}
/**
* amqp_basic_cancel
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] consumer_tag consumer_tag
* @returns amqp_basic_cancel_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_basic_cancel_ok_t *
AMQP_CALL amqp_basic_cancel(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t consumer_tag)
{
amqp_basic_cancel_t req;
req.consumer_tag = consumer_tag;
req.nowait = 0;
return amqp_simple_rpc_decoded(state, channel, AMQP_BASIC_CANCEL_METHOD, AMQP_BASIC_CANCEL_OK_METHOD, &req);
}
/**
* amqp_basic_recover
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] requeue requeue
* @returns amqp_basic_recover_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_basic_recover_ok_t *
AMQP_CALL amqp_basic_recover(amqp_connection_state_t state, amqp_channel_t channel, amqp_boolean_t requeue)
{
amqp_basic_recover_t req;
req.requeue = requeue;
return amqp_simple_rpc_decoded(state, channel, AMQP_BASIC_RECOVER_METHOD, AMQP_BASIC_RECOVER_OK_METHOD, &req);
}
/**
* amqp_tx_select
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @returns amqp_tx_select_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_tx_select_ok_t *
AMQP_CALL amqp_tx_select(amqp_connection_state_t state, amqp_channel_t channel)
{
amqp_tx_select_t req;
return amqp_simple_rpc_decoded(state, channel, AMQP_TX_SELECT_METHOD, AMQP_TX_SELECT_OK_METHOD, &req);
}
/**
* amqp_tx_commit
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @returns amqp_tx_commit_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_tx_commit_ok_t *
AMQP_CALL amqp_tx_commit(amqp_connection_state_t state, amqp_channel_t channel)
{
amqp_tx_commit_t req;
return amqp_simple_rpc_decoded(state, channel, AMQP_TX_COMMIT_METHOD, AMQP_TX_COMMIT_OK_METHOD, &req);
}
/**
* amqp_tx_rollback
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @returns amqp_tx_rollback_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_tx_rollback_ok_t *
AMQP_CALL amqp_tx_rollback(amqp_connection_state_t state, amqp_channel_t channel)
{
amqp_tx_rollback_t req;
return amqp_simple_rpc_decoded(state, channel, AMQP_TX_ROLLBACK_METHOD, AMQP_TX_ROLLBACK_OK_METHOD, &req);
}
/**
* amqp_confirm_select
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @returns amqp_confirm_select_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_confirm_select_ok_t *
AMQP_CALL amqp_confirm_select(amqp_connection_state_t state, amqp_channel_t channel)
{
amqp_confirm_select_t req;
req.nowait = 0;
return amqp_simple_rpc_decoded(state, channel, AMQP_CONFIRM_SELECT_METHOD, AMQP_CONFIRM_SELECT_OK_METHOD, &req);
}
rabbitmq-c-0.8.0/librabbitmq/amqp_framing.h 0000664 0000000 0000000 00000121523 12702357234 0020653 0 ustar 00root root 0000000 0000000 /* Generated code. Do not edit. Edit and re-run codegen.py instead.
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
/** @file amqp_framing.h */
#ifndef AMQP_FRAMING_H
#define AMQP_FRAMING_H
#include
AMQP_BEGIN_DECLS
#define AMQP_PROTOCOL_VERSION_MAJOR 0 /**< AMQP protocol version major */
#define AMQP_PROTOCOL_VERSION_MINOR 9 /**< AMQP protocol version minor */
#define AMQP_PROTOCOL_VERSION_REVISION 1 /**< AMQP protocol version revision */
#define AMQP_PROTOCOL_PORT 5672 /**< Default AMQP Port */
#define AMQP_FRAME_METHOD 1 /**< Constant: FRAME-METHOD */
#define AMQP_FRAME_HEADER 2 /**< Constant: FRAME-HEADER */
#define AMQP_FRAME_BODY 3 /**< Constant: FRAME-BODY */
#define AMQP_FRAME_HEARTBEAT 8 /**< Constant: FRAME-HEARTBEAT */
#define AMQP_FRAME_MIN_SIZE 4096 /**< Constant: FRAME-MIN-SIZE */
#define AMQP_FRAME_END 206 /**< Constant: FRAME-END */
#define AMQP_REPLY_SUCCESS 200 /**< Constant: REPLY-SUCCESS */
#define AMQP_CONTENT_TOO_LARGE 311 /**< Constant: CONTENT-TOO-LARGE */
#define AMQP_NO_ROUTE 312 /**< Constant: NO-ROUTE */
#define AMQP_NO_CONSUMERS 313 /**< Constant: NO-CONSUMERS */
#define AMQP_ACCESS_REFUSED 403 /**< Constant: ACCESS-REFUSED */
#define AMQP_NOT_FOUND 404 /**< Constant: NOT-FOUND */
#define AMQP_RESOURCE_LOCKED 405 /**< Constant: RESOURCE-LOCKED */
#define AMQP_PRECONDITION_FAILED 406 /**< Constant: PRECONDITION-FAILED */
#define AMQP_CONNECTION_FORCED 320 /**< Constant: CONNECTION-FORCED */
#define AMQP_INVALID_PATH 402 /**< Constant: INVALID-PATH */
#define AMQP_FRAME_ERROR 501 /**< Constant: FRAME-ERROR */
#define AMQP_SYNTAX_ERROR 502 /**< Constant: SYNTAX-ERROR */
#define AMQP_COMMAND_INVALID 503 /**< Constant: COMMAND-INVALID */
#define AMQP_CHANNEL_ERROR 504 /**< Constant: CHANNEL-ERROR */
#define AMQP_UNEXPECTED_FRAME 505 /**< Constant: UNEXPECTED-FRAME */
#define AMQP_RESOURCE_ERROR 506 /**< Constant: RESOURCE-ERROR */
#define AMQP_NOT_ALLOWED 530 /**< Constant: NOT-ALLOWED */
#define AMQP_NOT_IMPLEMENTED 540 /**< Constant: NOT-IMPLEMENTED */
#define AMQP_INTERNAL_ERROR 541 /**< Constant: INTERNAL-ERROR */
/* Function prototypes. */
/**
* Get constant name string from constant
*
* @param [in] constantNumber constant to get the name of
* @returns string describing the constant. String is managed by
* the library and should not be free()'d by the program
*/
AMQP_PUBLIC_FUNCTION
char const *
AMQP_CALL amqp_constant_name(int constantNumber);
/**
* Checks to see if a constant is a hard error
*
* A hard error occurs when something severe enough
* happens that the connection must be closed.
*
* @param [in] constantNumber the error constant
* @returns true if its a hard error, false otherwise
*/
AMQP_PUBLIC_FUNCTION
amqp_boolean_t
AMQP_CALL amqp_constant_is_hard_error(int constantNumber);
/**
* Get method name string from method number
*
* @param [in] methodNumber the method number
* @returns method name string. String is managed by the library
* and should not be freed()'d by the program
*/
AMQP_PUBLIC_FUNCTION
char const *
AMQP_CALL amqp_method_name(amqp_method_number_t methodNumber);
/**
* Check whether a method has content
*
* A method that has content will receive the method frame
* a properties frame, then 1 to N body frames
*
* @param [in] methodNumber the method number
* @returns true if method has content, false otherwise
*/
AMQP_PUBLIC_FUNCTION
amqp_boolean_t
AMQP_CALL amqp_method_has_content(amqp_method_number_t methodNumber);
/**
* Decodes a method from AMQP wireformat
*
* @param [in] methodNumber the method number for the decoded parameter
* @param [in] pool the memory pool to allocate the decoded method from
* @param [in] encoded the encoded byte string buffer
* @param [out] decoded pointer to the decoded method struct
* @returns 0 on success, an error code otherwise
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_decode_method(amqp_method_number_t methodNumber,
amqp_pool_t *pool,
amqp_bytes_t encoded,
void **decoded);
/**
* Decodes a header frame properties structure from AMQP wireformat
*
* @param [in] class_id the class id for the decoded parameter
* @param [in] pool the memory pool to allocate the decoded properties from
* @param [in] encoded the encoded byte string buffer
* @param [out] decoded pointer to the decoded properties struct
* @returns 0 on success, an error code otherwise
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_decode_properties(uint16_t class_id,
amqp_pool_t *pool,
amqp_bytes_t encoded,
void **decoded);
/**
* Encodes a method structure in AMQP wireformat
*
* @param [in] methodNumber the method number for the decoded parameter
* @param [in] decoded the method structure (e.g., amqp_connection_start_t)
* @param [in] encoded an allocated byte buffer for the encoded method
* structure to be written to. If the buffer isn't large enough
* to hold the encoded method, an error code will be returned.
* @returns 0 on success, an error code otherwise.
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_encode_method(amqp_method_number_t methodNumber,
void *decoded,
amqp_bytes_t encoded);
/**
* Encodes a properties structure in AMQP wireformat
*
* @param [in] class_id the class id for the decoded parameter
* @param [in] decoded the properties structure (e.g., amqp_basic_properties_t)
* @param [in] encoded an allocated byte buffer for the encoded properties to written to.
* If the buffer isn't large enough to hold the encoded method, an
* an error code will be returned
* @returns 0 on success, an error code otherwise.
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL amqp_encode_properties(uint16_t class_id,
void *decoded,
amqp_bytes_t encoded);
/* Method field records. */
#define AMQP_CONNECTION_START_METHOD ((amqp_method_number_t) 0x000A000A) /**< connection.start method id @internal 10, 10; 655370 */
/** connection.start method fields */
typedef struct amqp_connection_start_t_ {
uint8_t version_major; /**< version-major */
uint8_t version_minor; /**< version-minor */
amqp_table_t server_properties; /**< server-properties */
amqp_bytes_t mechanisms; /**< mechanisms */
amqp_bytes_t locales; /**< locales */
} amqp_connection_start_t;
#define AMQP_CONNECTION_START_OK_METHOD ((amqp_method_number_t) 0x000A000B) /**< connection.start-ok method id @internal 10, 11; 655371 */
/** connection.start-ok method fields */
typedef struct amqp_connection_start_ok_t_ {
amqp_table_t client_properties; /**< client-properties */
amqp_bytes_t mechanism; /**< mechanism */
amqp_bytes_t response; /**< response */
amqp_bytes_t locale; /**< locale */
} amqp_connection_start_ok_t;
#define AMQP_CONNECTION_SECURE_METHOD ((amqp_method_number_t) 0x000A0014) /**< connection.secure method id @internal 10, 20; 655380 */
/** connection.secure method fields */
typedef struct amqp_connection_secure_t_ {
amqp_bytes_t challenge; /**< challenge */
} amqp_connection_secure_t;
#define AMQP_CONNECTION_SECURE_OK_METHOD ((amqp_method_number_t) 0x000A0015) /**< connection.secure-ok method id @internal 10, 21; 655381 */
/** connection.secure-ok method fields */
typedef struct amqp_connection_secure_ok_t_ {
amqp_bytes_t response; /**< response */
} amqp_connection_secure_ok_t;
#define AMQP_CONNECTION_TUNE_METHOD ((amqp_method_number_t) 0x000A001E) /**< connection.tune method id @internal 10, 30; 655390 */
/** connection.tune method fields */
typedef struct amqp_connection_tune_t_ {
uint16_t channel_max; /**< channel-max */
uint32_t frame_max; /**< frame-max */
uint16_t heartbeat; /**< heartbeat */
} amqp_connection_tune_t;
#define AMQP_CONNECTION_TUNE_OK_METHOD ((amqp_method_number_t) 0x000A001F) /**< connection.tune-ok method id @internal 10, 31; 655391 */
/** connection.tune-ok method fields */
typedef struct amqp_connection_tune_ok_t_ {
uint16_t channel_max; /**< channel-max */
uint32_t frame_max; /**< frame-max */
uint16_t heartbeat; /**< heartbeat */
} amqp_connection_tune_ok_t;
#define AMQP_CONNECTION_OPEN_METHOD ((amqp_method_number_t) 0x000A0028) /**< connection.open method id @internal 10, 40; 655400 */
/** connection.open method fields */
typedef struct amqp_connection_open_t_ {
amqp_bytes_t virtual_host; /**< virtual-host */
amqp_bytes_t capabilities; /**< capabilities */
amqp_boolean_t insist; /**< insist */
} amqp_connection_open_t;
#define AMQP_CONNECTION_OPEN_OK_METHOD ((amqp_method_number_t) 0x000A0029) /**< connection.open-ok method id @internal 10, 41; 655401 */
/** connection.open-ok method fields */
typedef struct amqp_connection_open_ok_t_ {
amqp_bytes_t known_hosts; /**< known-hosts */
} amqp_connection_open_ok_t;
#define AMQP_CONNECTION_CLOSE_METHOD ((amqp_method_number_t) 0x000A0032) /**< connection.close method id @internal 10, 50; 655410 */
/** connection.close method fields */
typedef struct amqp_connection_close_t_ {
uint16_t reply_code; /**< reply-code */
amqp_bytes_t reply_text; /**< reply-text */
uint16_t class_id; /**< class-id */
uint16_t method_id; /**< method-id */
} amqp_connection_close_t;
#define AMQP_CONNECTION_CLOSE_OK_METHOD ((amqp_method_number_t) 0x000A0033) /**< connection.close-ok method id @internal 10, 51; 655411 */
/** connection.close-ok method fields */
typedef struct amqp_connection_close_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_connection_close_ok_t;
#define AMQP_CONNECTION_BLOCKED_METHOD ((amqp_method_number_t) 0x000A003C) /**< connection.blocked method id @internal 10, 60; 655420 */
/** connection.blocked method fields */
typedef struct amqp_connection_blocked_t_ {
amqp_bytes_t reason; /**< reason */
} amqp_connection_blocked_t;
#define AMQP_CONNECTION_UNBLOCKED_METHOD ((amqp_method_number_t) 0x000A003D) /**< connection.unblocked method id @internal 10, 61; 655421 */
/** connection.unblocked method fields */
typedef struct amqp_connection_unblocked_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_connection_unblocked_t;
#define AMQP_CHANNEL_OPEN_METHOD ((amqp_method_number_t) 0x0014000A) /**< channel.open method id @internal 20, 10; 1310730 */
/** channel.open method fields */
typedef struct amqp_channel_open_t_ {
amqp_bytes_t out_of_band; /**< out-of-band */
} amqp_channel_open_t;
#define AMQP_CHANNEL_OPEN_OK_METHOD ((amqp_method_number_t) 0x0014000B) /**< channel.open-ok method id @internal 20, 11; 1310731 */
/** channel.open-ok method fields */
typedef struct amqp_channel_open_ok_t_ {
amqp_bytes_t channel_id; /**< channel-id */
} amqp_channel_open_ok_t;
#define AMQP_CHANNEL_FLOW_METHOD ((amqp_method_number_t) 0x00140014) /**< channel.flow method id @internal 20, 20; 1310740 */
/** channel.flow method fields */
typedef struct amqp_channel_flow_t_ {
amqp_boolean_t active; /**< active */
} amqp_channel_flow_t;
#define AMQP_CHANNEL_FLOW_OK_METHOD ((amqp_method_number_t) 0x00140015) /**< channel.flow-ok method id @internal 20, 21; 1310741 */
/** channel.flow-ok method fields */
typedef struct amqp_channel_flow_ok_t_ {
amqp_boolean_t active; /**< active */
} amqp_channel_flow_ok_t;
#define AMQP_CHANNEL_CLOSE_METHOD ((amqp_method_number_t) 0x00140028) /**< channel.close method id @internal 20, 40; 1310760 */
/** channel.close method fields */
typedef struct amqp_channel_close_t_ {
uint16_t reply_code; /**< reply-code */
amqp_bytes_t reply_text; /**< reply-text */
uint16_t class_id; /**< class-id */
uint16_t method_id; /**< method-id */
} amqp_channel_close_t;
#define AMQP_CHANNEL_CLOSE_OK_METHOD ((amqp_method_number_t) 0x00140029) /**< channel.close-ok method id @internal 20, 41; 1310761 */
/** channel.close-ok method fields */
typedef struct amqp_channel_close_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_channel_close_ok_t;
#define AMQP_ACCESS_REQUEST_METHOD ((amqp_method_number_t) 0x001E000A) /**< access.request method id @internal 30, 10; 1966090 */
/** access.request method fields */
typedef struct amqp_access_request_t_ {
amqp_bytes_t realm; /**< realm */
amqp_boolean_t exclusive; /**< exclusive */
amqp_boolean_t passive; /**< passive */
amqp_boolean_t active; /**< active */
amqp_boolean_t write; /**< write */
amqp_boolean_t read; /**< read */
} amqp_access_request_t;
#define AMQP_ACCESS_REQUEST_OK_METHOD ((amqp_method_number_t) 0x001E000B) /**< access.request-ok method id @internal 30, 11; 1966091 */
/** access.request-ok method fields */
typedef struct amqp_access_request_ok_t_ {
uint16_t ticket; /**< ticket */
} amqp_access_request_ok_t;
#define AMQP_EXCHANGE_DECLARE_METHOD ((amqp_method_number_t) 0x0028000A) /**< exchange.declare method id @internal 40, 10; 2621450 */
/** exchange.declare method fields */
typedef struct amqp_exchange_declare_t_ {
uint16_t ticket; /**< ticket */
amqp_bytes_t exchange; /**< exchange */
amqp_bytes_t type; /**< type */
amqp_boolean_t passive; /**< passive */
amqp_boolean_t durable; /**< durable */
amqp_boolean_t auto_delete; /**< auto-delete */
amqp_boolean_t internal; /**< internal */
amqp_boolean_t nowait; /**< nowait */
amqp_table_t arguments; /**< arguments */
} amqp_exchange_declare_t;
#define AMQP_EXCHANGE_DECLARE_OK_METHOD ((amqp_method_number_t) 0x0028000B) /**< exchange.declare-ok method id @internal 40, 11; 2621451 */
/** exchange.declare-ok method fields */
typedef struct amqp_exchange_declare_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_exchange_declare_ok_t;
#define AMQP_EXCHANGE_DELETE_METHOD ((amqp_method_number_t) 0x00280014) /**< exchange.delete method id @internal 40, 20; 2621460 */
/** exchange.delete method fields */
typedef struct amqp_exchange_delete_t_ {
uint16_t ticket; /**< ticket */
amqp_bytes_t exchange; /**< exchange */
amqp_boolean_t if_unused; /**< if-unused */
amqp_boolean_t nowait; /**< nowait */
} amqp_exchange_delete_t;
#define AMQP_EXCHANGE_DELETE_OK_METHOD ((amqp_method_number_t) 0x00280015) /**< exchange.delete-ok method id @internal 40, 21; 2621461 */
/** exchange.delete-ok method fields */
typedef struct amqp_exchange_delete_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_exchange_delete_ok_t;
#define AMQP_EXCHANGE_BIND_METHOD ((amqp_method_number_t) 0x0028001E) /**< exchange.bind method id @internal 40, 30; 2621470 */
/** exchange.bind method fields */
typedef struct amqp_exchange_bind_t_ {
uint16_t ticket; /**< ticket */
amqp_bytes_t destination; /**< destination */
amqp_bytes_t source; /**< source */
amqp_bytes_t routing_key; /**< routing-key */
amqp_boolean_t nowait; /**< nowait */
amqp_table_t arguments; /**< arguments */
} amqp_exchange_bind_t;
#define AMQP_EXCHANGE_BIND_OK_METHOD ((amqp_method_number_t) 0x0028001F) /**< exchange.bind-ok method id @internal 40, 31; 2621471 */
/** exchange.bind-ok method fields */
typedef struct amqp_exchange_bind_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_exchange_bind_ok_t;
#define AMQP_EXCHANGE_UNBIND_METHOD ((amqp_method_number_t) 0x00280028) /**< exchange.unbind method id @internal 40, 40; 2621480 */
/** exchange.unbind method fields */
typedef struct amqp_exchange_unbind_t_ {
uint16_t ticket; /**< ticket */
amqp_bytes_t destination; /**< destination */
amqp_bytes_t source; /**< source */
amqp_bytes_t routing_key; /**< routing-key */
amqp_boolean_t nowait; /**< nowait */
amqp_table_t arguments; /**< arguments */
} amqp_exchange_unbind_t;
#define AMQP_EXCHANGE_UNBIND_OK_METHOD ((amqp_method_number_t) 0x00280033) /**< exchange.unbind-ok method id @internal 40, 51; 2621491 */
/** exchange.unbind-ok method fields */
typedef struct amqp_exchange_unbind_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_exchange_unbind_ok_t;
#define AMQP_QUEUE_DECLARE_METHOD ((amqp_method_number_t) 0x0032000A) /**< queue.declare method id @internal 50, 10; 3276810 */
/** queue.declare method fields */
typedef struct amqp_queue_declare_t_ {
uint16_t ticket; /**< ticket */
amqp_bytes_t queue; /**< queue */
amqp_boolean_t passive; /**< passive */
amqp_boolean_t durable; /**< durable */
amqp_boolean_t exclusive; /**< exclusive */
amqp_boolean_t auto_delete; /**< auto-delete */
amqp_boolean_t nowait; /**< nowait */
amqp_table_t arguments; /**< arguments */
} amqp_queue_declare_t;
#define AMQP_QUEUE_DECLARE_OK_METHOD ((amqp_method_number_t) 0x0032000B) /**< queue.declare-ok method id @internal 50, 11; 3276811 */
/** queue.declare-ok method fields */
typedef struct amqp_queue_declare_ok_t_ {
amqp_bytes_t queue; /**< queue */
uint32_t message_count; /**< message-count */
uint32_t consumer_count; /**< consumer-count */
} amqp_queue_declare_ok_t;
#define AMQP_QUEUE_BIND_METHOD ((amqp_method_number_t) 0x00320014) /**< queue.bind method id @internal 50, 20; 3276820 */
/** queue.bind method fields */
typedef struct amqp_queue_bind_t_ {
uint16_t ticket; /**< ticket */
amqp_bytes_t queue; /**< queue */
amqp_bytes_t exchange; /**< exchange */
amqp_bytes_t routing_key; /**< routing-key */
amqp_boolean_t nowait; /**< nowait */
amqp_table_t arguments; /**< arguments */
} amqp_queue_bind_t;
#define AMQP_QUEUE_BIND_OK_METHOD ((amqp_method_number_t) 0x00320015) /**< queue.bind-ok method id @internal 50, 21; 3276821 */
/** queue.bind-ok method fields */
typedef struct amqp_queue_bind_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_queue_bind_ok_t;
#define AMQP_QUEUE_PURGE_METHOD ((amqp_method_number_t) 0x0032001E) /**< queue.purge method id @internal 50, 30; 3276830 */
/** queue.purge method fields */
typedef struct amqp_queue_purge_t_ {
uint16_t ticket; /**< ticket */
amqp_bytes_t queue; /**< queue */
amqp_boolean_t nowait; /**< nowait */
} amqp_queue_purge_t;
#define AMQP_QUEUE_PURGE_OK_METHOD ((amqp_method_number_t) 0x0032001F) /**< queue.purge-ok method id @internal 50, 31; 3276831 */
/** queue.purge-ok method fields */
typedef struct amqp_queue_purge_ok_t_ {
uint32_t message_count; /**< message-count */
} amqp_queue_purge_ok_t;
#define AMQP_QUEUE_DELETE_METHOD ((amqp_method_number_t) 0x00320028) /**< queue.delete method id @internal 50, 40; 3276840 */
/** queue.delete method fields */
typedef struct amqp_queue_delete_t_ {
uint16_t ticket; /**< ticket */
amqp_bytes_t queue; /**< queue */
amqp_boolean_t if_unused; /**< if-unused */
amqp_boolean_t if_empty; /**< if-empty */
amqp_boolean_t nowait; /**< nowait */
} amqp_queue_delete_t;
#define AMQP_QUEUE_DELETE_OK_METHOD ((amqp_method_number_t) 0x00320029) /**< queue.delete-ok method id @internal 50, 41; 3276841 */
/** queue.delete-ok method fields */
typedef struct amqp_queue_delete_ok_t_ {
uint32_t message_count; /**< message-count */
} amqp_queue_delete_ok_t;
#define AMQP_QUEUE_UNBIND_METHOD ((amqp_method_number_t) 0x00320032) /**< queue.unbind method id @internal 50, 50; 3276850 */
/** queue.unbind method fields */
typedef struct amqp_queue_unbind_t_ {
uint16_t ticket; /**< ticket */
amqp_bytes_t queue; /**< queue */
amqp_bytes_t exchange; /**< exchange */
amqp_bytes_t routing_key; /**< routing-key */
amqp_table_t arguments; /**< arguments */
} amqp_queue_unbind_t;
#define AMQP_QUEUE_UNBIND_OK_METHOD ((amqp_method_number_t) 0x00320033) /**< queue.unbind-ok method id @internal 50, 51; 3276851 */
/** queue.unbind-ok method fields */
typedef struct amqp_queue_unbind_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_queue_unbind_ok_t;
#define AMQP_BASIC_QOS_METHOD ((amqp_method_number_t) 0x003C000A) /**< basic.qos method id @internal 60, 10; 3932170 */
/** basic.qos method fields */
typedef struct amqp_basic_qos_t_ {
uint32_t prefetch_size; /**< prefetch-size */
uint16_t prefetch_count; /**< prefetch-count */
amqp_boolean_t global; /**< global */
} amqp_basic_qos_t;
#define AMQP_BASIC_QOS_OK_METHOD ((amqp_method_number_t) 0x003C000B) /**< basic.qos-ok method id @internal 60, 11; 3932171 */
/** basic.qos-ok method fields */
typedef struct amqp_basic_qos_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_basic_qos_ok_t;
#define AMQP_BASIC_CONSUME_METHOD ((amqp_method_number_t) 0x003C0014) /**< basic.consume method id @internal 60, 20; 3932180 */
/** basic.consume method fields */
typedef struct amqp_basic_consume_t_ {
uint16_t ticket; /**< ticket */
amqp_bytes_t queue; /**< queue */
amqp_bytes_t consumer_tag; /**< consumer-tag */
amqp_boolean_t no_local; /**< no-local */
amqp_boolean_t no_ack; /**< no-ack */
amqp_boolean_t exclusive; /**< exclusive */
amqp_boolean_t nowait; /**< nowait */
amqp_table_t arguments; /**< arguments */
} amqp_basic_consume_t;
#define AMQP_BASIC_CONSUME_OK_METHOD ((amqp_method_number_t) 0x003C0015) /**< basic.consume-ok method id @internal 60, 21; 3932181 */
/** basic.consume-ok method fields */
typedef struct amqp_basic_consume_ok_t_ {
amqp_bytes_t consumer_tag; /**< consumer-tag */
} amqp_basic_consume_ok_t;
#define AMQP_BASIC_CANCEL_METHOD ((amqp_method_number_t) 0x003C001E) /**< basic.cancel method id @internal 60, 30; 3932190 */
/** basic.cancel method fields */
typedef struct amqp_basic_cancel_t_ {
amqp_bytes_t consumer_tag; /**< consumer-tag */
amqp_boolean_t nowait; /**< nowait */
} amqp_basic_cancel_t;
#define AMQP_BASIC_CANCEL_OK_METHOD ((amqp_method_number_t) 0x003C001F) /**< basic.cancel-ok method id @internal 60, 31; 3932191 */
/** basic.cancel-ok method fields */
typedef struct amqp_basic_cancel_ok_t_ {
amqp_bytes_t consumer_tag; /**< consumer-tag */
} amqp_basic_cancel_ok_t;
#define AMQP_BASIC_PUBLISH_METHOD ((amqp_method_number_t) 0x003C0028) /**< basic.publish method id @internal 60, 40; 3932200 */
/** basic.publish method fields */
typedef struct amqp_basic_publish_t_ {
uint16_t ticket; /**< ticket */
amqp_bytes_t exchange; /**< exchange */
amqp_bytes_t routing_key; /**< routing-key */
amqp_boolean_t mandatory; /**< mandatory */
amqp_boolean_t immediate; /**< immediate */
} amqp_basic_publish_t;
#define AMQP_BASIC_RETURN_METHOD ((amqp_method_number_t) 0x003C0032) /**< basic.return method id @internal 60, 50; 3932210 */
/** basic.return method fields */
typedef struct amqp_basic_return_t_ {
uint16_t reply_code; /**< reply-code */
amqp_bytes_t reply_text; /**< reply-text */
amqp_bytes_t exchange; /**< exchange */
amqp_bytes_t routing_key; /**< routing-key */
} amqp_basic_return_t;
#define AMQP_BASIC_DELIVER_METHOD ((amqp_method_number_t) 0x003C003C) /**< basic.deliver method id @internal 60, 60; 3932220 */
/** basic.deliver method fields */
typedef struct amqp_basic_deliver_t_ {
amqp_bytes_t consumer_tag; /**< consumer-tag */
uint64_t delivery_tag; /**< delivery-tag */
amqp_boolean_t redelivered; /**< redelivered */
amqp_bytes_t exchange; /**< exchange */
amqp_bytes_t routing_key; /**< routing-key */
} amqp_basic_deliver_t;
#define AMQP_BASIC_GET_METHOD ((amqp_method_number_t) 0x003C0046) /**< basic.get method id @internal 60, 70; 3932230 */
/** basic.get method fields */
typedef struct amqp_basic_get_t_ {
uint16_t ticket; /**< ticket */
amqp_bytes_t queue; /**< queue */
amqp_boolean_t no_ack; /**< no-ack */
} amqp_basic_get_t;
#define AMQP_BASIC_GET_OK_METHOD ((amqp_method_number_t) 0x003C0047) /**< basic.get-ok method id @internal 60, 71; 3932231 */
/** basic.get-ok method fields */
typedef struct amqp_basic_get_ok_t_ {
uint64_t delivery_tag; /**< delivery-tag */
amqp_boolean_t redelivered; /**< redelivered */
amqp_bytes_t exchange; /**< exchange */
amqp_bytes_t routing_key; /**< routing-key */
uint32_t message_count; /**< message-count */
} amqp_basic_get_ok_t;
#define AMQP_BASIC_GET_EMPTY_METHOD ((amqp_method_number_t) 0x003C0048) /**< basic.get-empty method id @internal 60, 72; 3932232 */
/** basic.get-empty method fields */
typedef struct amqp_basic_get_empty_t_ {
amqp_bytes_t cluster_id; /**< cluster-id */
} amqp_basic_get_empty_t;
#define AMQP_BASIC_ACK_METHOD ((amqp_method_number_t) 0x003C0050) /**< basic.ack method id @internal 60, 80; 3932240 */
/** basic.ack method fields */
typedef struct amqp_basic_ack_t_ {
uint64_t delivery_tag; /**< delivery-tag */
amqp_boolean_t multiple; /**< multiple */
} amqp_basic_ack_t;
#define AMQP_BASIC_REJECT_METHOD ((amqp_method_number_t) 0x003C005A) /**< basic.reject method id @internal 60, 90; 3932250 */
/** basic.reject method fields */
typedef struct amqp_basic_reject_t_ {
uint64_t delivery_tag; /**< delivery-tag */
amqp_boolean_t requeue; /**< requeue */
} amqp_basic_reject_t;
#define AMQP_BASIC_RECOVER_ASYNC_METHOD ((amqp_method_number_t) 0x003C0064) /**< basic.recover-async method id @internal 60, 100; 3932260 */
/** basic.recover-async method fields */
typedef struct amqp_basic_recover_async_t_ {
amqp_boolean_t requeue; /**< requeue */
} amqp_basic_recover_async_t;
#define AMQP_BASIC_RECOVER_METHOD ((amqp_method_number_t) 0x003C006E) /**< basic.recover method id @internal 60, 110; 3932270 */
/** basic.recover method fields */
typedef struct amqp_basic_recover_t_ {
amqp_boolean_t requeue; /**< requeue */
} amqp_basic_recover_t;
#define AMQP_BASIC_RECOVER_OK_METHOD ((amqp_method_number_t) 0x003C006F) /**< basic.recover-ok method id @internal 60, 111; 3932271 */
/** basic.recover-ok method fields */
typedef struct amqp_basic_recover_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_basic_recover_ok_t;
#define AMQP_BASIC_NACK_METHOD ((amqp_method_number_t) 0x003C0078) /**< basic.nack method id @internal 60, 120; 3932280 */
/** basic.nack method fields */
typedef struct amqp_basic_nack_t_ {
uint64_t delivery_tag; /**< delivery-tag */
amqp_boolean_t multiple; /**< multiple */
amqp_boolean_t requeue; /**< requeue */
} amqp_basic_nack_t;
#define AMQP_TX_SELECT_METHOD ((amqp_method_number_t) 0x005A000A) /**< tx.select method id @internal 90, 10; 5898250 */
/** tx.select method fields */
typedef struct amqp_tx_select_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_tx_select_t;
#define AMQP_TX_SELECT_OK_METHOD ((amqp_method_number_t) 0x005A000B) /**< tx.select-ok method id @internal 90, 11; 5898251 */
/** tx.select-ok method fields */
typedef struct amqp_tx_select_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_tx_select_ok_t;
#define AMQP_TX_COMMIT_METHOD ((amqp_method_number_t) 0x005A0014) /**< tx.commit method id @internal 90, 20; 5898260 */
/** tx.commit method fields */
typedef struct amqp_tx_commit_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_tx_commit_t;
#define AMQP_TX_COMMIT_OK_METHOD ((amqp_method_number_t) 0x005A0015) /**< tx.commit-ok method id @internal 90, 21; 5898261 */
/** tx.commit-ok method fields */
typedef struct amqp_tx_commit_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_tx_commit_ok_t;
#define AMQP_TX_ROLLBACK_METHOD ((amqp_method_number_t) 0x005A001E) /**< tx.rollback method id @internal 90, 30; 5898270 */
/** tx.rollback method fields */
typedef struct amqp_tx_rollback_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_tx_rollback_t;
#define AMQP_TX_ROLLBACK_OK_METHOD ((amqp_method_number_t) 0x005A001F) /**< tx.rollback-ok method id @internal 90, 31; 5898271 */
/** tx.rollback-ok method fields */
typedef struct amqp_tx_rollback_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_tx_rollback_ok_t;
#define AMQP_CONFIRM_SELECT_METHOD ((amqp_method_number_t) 0x0055000A) /**< confirm.select method id @internal 85, 10; 5570570 */
/** confirm.select method fields */
typedef struct amqp_confirm_select_t_ {
amqp_boolean_t nowait; /**< nowait */
} amqp_confirm_select_t;
#define AMQP_CONFIRM_SELECT_OK_METHOD ((amqp_method_number_t) 0x0055000B) /**< confirm.select-ok method id @internal 85, 11; 5570571 */
/** confirm.select-ok method fields */
typedef struct amqp_confirm_select_ok_t_ {
char dummy; /**< Dummy field to avoid empty struct */
} amqp_confirm_select_ok_t;
/* Class property records. */
#define AMQP_CONNECTION_CLASS (0x000A) /**< connection class id @internal 10 */
/** connection class properties */
typedef struct amqp_connection_properties_t_ {
amqp_flags_t _flags; /**< bit-mask of set fields */
char dummy; /**< Dummy field to avoid empty struct */
} amqp_connection_properties_t;
#define AMQP_CHANNEL_CLASS (0x0014) /**< channel class id @internal 20 */
/** channel class properties */
typedef struct amqp_channel_properties_t_ {
amqp_flags_t _flags; /**< bit-mask of set fields */
char dummy; /**< Dummy field to avoid empty struct */
} amqp_channel_properties_t;
#define AMQP_ACCESS_CLASS (0x001E) /**< access class id @internal 30 */
/** access class properties */
typedef struct amqp_access_properties_t_ {
amqp_flags_t _flags; /**< bit-mask of set fields */
char dummy; /**< Dummy field to avoid empty struct */
} amqp_access_properties_t;
#define AMQP_EXCHANGE_CLASS (0x0028) /**< exchange class id @internal 40 */
/** exchange class properties */
typedef struct amqp_exchange_properties_t_ {
amqp_flags_t _flags; /**< bit-mask of set fields */
char dummy; /**< Dummy field to avoid empty struct */
} amqp_exchange_properties_t;
#define AMQP_QUEUE_CLASS (0x0032) /**< queue class id @internal 50 */
/** queue class properties */
typedef struct amqp_queue_properties_t_ {
amqp_flags_t _flags; /**< bit-mask of set fields */
char dummy; /**< Dummy field to avoid empty struct */
} amqp_queue_properties_t;
#define AMQP_BASIC_CLASS (0x003C) /**< basic class id @internal 60 */
#define AMQP_BASIC_CONTENT_TYPE_FLAG (1 << 15) /**< basic.content-type property flag */
#define AMQP_BASIC_CONTENT_ENCODING_FLAG (1 << 14) /**< basic.content-encoding property flag */
#define AMQP_BASIC_HEADERS_FLAG (1 << 13) /**< basic.headers property flag */
#define AMQP_BASIC_DELIVERY_MODE_FLAG (1 << 12) /**< basic.delivery-mode property flag */
#define AMQP_BASIC_PRIORITY_FLAG (1 << 11) /**< basic.priority property flag */
#define AMQP_BASIC_CORRELATION_ID_FLAG (1 << 10) /**< basic.correlation-id property flag */
#define AMQP_BASIC_REPLY_TO_FLAG (1 << 9) /**< basic.reply-to property flag */
#define AMQP_BASIC_EXPIRATION_FLAG (1 << 8) /**< basic.expiration property flag */
#define AMQP_BASIC_MESSAGE_ID_FLAG (1 << 7) /**< basic.message-id property flag */
#define AMQP_BASIC_TIMESTAMP_FLAG (1 << 6) /**< basic.timestamp property flag */
#define AMQP_BASIC_TYPE_FLAG (1 << 5) /**< basic.type property flag */
#define AMQP_BASIC_USER_ID_FLAG (1 << 4) /**< basic.user-id property flag */
#define AMQP_BASIC_APP_ID_FLAG (1 << 3) /**< basic.app-id property flag */
#define AMQP_BASIC_CLUSTER_ID_FLAG (1 << 2) /**< basic.cluster-id property flag */
/** basic class properties */
typedef struct amqp_basic_properties_t_ {
amqp_flags_t _flags; /**< bit-mask of set fields */
amqp_bytes_t content_type; /**< content-type */
amqp_bytes_t content_encoding; /**< content-encoding */
amqp_table_t headers; /**< headers */
uint8_t delivery_mode; /**< delivery-mode */
uint8_t priority; /**< priority */
amqp_bytes_t correlation_id; /**< correlation-id */
amqp_bytes_t reply_to; /**< reply-to */
amqp_bytes_t expiration; /**< expiration */
amqp_bytes_t message_id; /**< message-id */
uint64_t timestamp; /**< timestamp */
amqp_bytes_t type; /**< type */
amqp_bytes_t user_id; /**< user-id */
amqp_bytes_t app_id; /**< app-id */
amqp_bytes_t cluster_id; /**< cluster-id */
} amqp_basic_properties_t;
#define AMQP_TX_CLASS (0x005A) /**< tx class id @internal 90 */
/** tx class properties */
typedef struct amqp_tx_properties_t_ {
amqp_flags_t _flags; /**< bit-mask of set fields */
char dummy; /**< Dummy field to avoid empty struct */
} amqp_tx_properties_t;
#define AMQP_CONFIRM_CLASS (0x0055) /**< confirm class id @internal 85 */
/** confirm class properties */
typedef struct amqp_confirm_properties_t_ {
amqp_flags_t _flags; /**< bit-mask of set fields */
char dummy; /**< Dummy field to avoid empty struct */
} amqp_confirm_properties_t;
/* API functions for methods */
/**
* amqp_channel_open
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @returns amqp_channel_open_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_channel_open_ok_t *
AMQP_CALL amqp_channel_open(amqp_connection_state_t state, amqp_channel_t channel);
/**
* amqp_channel_flow
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] active active
* @returns amqp_channel_flow_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_channel_flow_ok_t *
AMQP_CALL amqp_channel_flow(amqp_connection_state_t state, amqp_channel_t channel, amqp_boolean_t active);
/**
* amqp_exchange_declare
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] exchange exchange
* @param [in] type type
* @param [in] passive passive
* @param [in] durable durable
* @param [in] auto_delete auto_delete
* @param [in] internal internal
* @param [in] arguments arguments
* @returns amqp_exchange_declare_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_exchange_declare_ok_t *
AMQP_CALL amqp_exchange_declare(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t exchange, amqp_bytes_t type, amqp_boolean_t passive, amqp_boolean_t durable, amqp_boolean_t auto_delete, amqp_boolean_t internal, amqp_table_t arguments);
/**
* amqp_exchange_delete
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] exchange exchange
* @param [in] if_unused if_unused
* @returns amqp_exchange_delete_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_exchange_delete_ok_t *
AMQP_CALL amqp_exchange_delete(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t exchange, amqp_boolean_t if_unused);
/**
* amqp_exchange_bind
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] destination destination
* @param [in] source source
* @param [in] routing_key routing_key
* @param [in] arguments arguments
* @returns amqp_exchange_bind_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_exchange_bind_ok_t *
AMQP_CALL amqp_exchange_bind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t destination, amqp_bytes_t source, amqp_bytes_t routing_key, amqp_table_t arguments);
/**
* amqp_exchange_unbind
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] destination destination
* @param [in] source source
* @param [in] routing_key routing_key
* @param [in] arguments arguments
* @returns amqp_exchange_unbind_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_exchange_unbind_ok_t *
AMQP_CALL amqp_exchange_unbind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t destination, amqp_bytes_t source, amqp_bytes_t routing_key, amqp_table_t arguments);
/**
* amqp_queue_declare
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] queue queue
* @param [in] passive passive
* @param [in] durable durable
* @param [in] exclusive exclusive
* @param [in] auto_delete auto_delete
* @param [in] arguments arguments
* @returns amqp_queue_declare_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_queue_declare_ok_t *
AMQP_CALL amqp_queue_declare(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_boolean_t passive, amqp_boolean_t durable, amqp_boolean_t exclusive, amqp_boolean_t auto_delete, amqp_table_t arguments);
/**
* amqp_queue_bind
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] queue queue
* @param [in] exchange exchange
* @param [in] routing_key routing_key
* @param [in] arguments arguments
* @returns amqp_queue_bind_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_queue_bind_ok_t *
AMQP_CALL amqp_queue_bind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments);
/**
* amqp_queue_purge
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] queue queue
* @returns amqp_queue_purge_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_queue_purge_ok_t *
AMQP_CALL amqp_queue_purge(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue);
/**
* amqp_queue_delete
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] queue queue
* @param [in] if_unused if_unused
* @param [in] if_empty if_empty
* @returns amqp_queue_delete_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_queue_delete_ok_t *
AMQP_CALL amqp_queue_delete(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_boolean_t if_unused, amqp_boolean_t if_empty);
/**
* amqp_queue_unbind
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] queue queue
* @param [in] exchange exchange
* @param [in] routing_key routing_key
* @param [in] arguments arguments
* @returns amqp_queue_unbind_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_queue_unbind_ok_t *
AMQP_CALL amqp_queue_unbind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments);
/**
* amqp_basic_qos
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] prefetch_size prefetch_size
* @param [in] prefetch_count prefetch_count
* @param [in] global global
* @returns amqp_basic_qos_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_basic_qos_ok_t *
AMQP_CALL amqp_basic_qos(amqp_connection_state_t state, amqp_channel_t channel, uint32_t prefetch_size, uint16_t prefetch_count, amqp_boolean_t global);
/**
* amqp_basic_consume
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] queue queue
* @param [in] consumer_tag consumer_tag
* @param [in] no_local no_local
* @param [in] no_ack no_ack
* @param [in] exclusive exclusive
* @param [in] arguments arguments
* @returns amqp_basic_consume_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_basic_consume_ok_t *
AMQP_CALL amqp_basic_consume(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t consumer_tag, amqp_boolean_t no_local, amqp_boolean_t no_ack, amqp_boolean_t exclusive, amqp_table_t arguments);
/**
* amqp_basic_cancel
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] consumer_tag consumer_tag
* @returns amqp_basic_cancel_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_basic_cancel_ok_t *
AMQP_CALL amqp_basic_cancel(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t consumer_tag);
/**
* amqp_basic_recover
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @param [in] requeue requeue
* @returns amqp_basic_recover_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_basic_recover_ok_t *
AMQP_CALL amqp_basic_recover(amqp_connection_state_t state, amqp_channel_t channel, amqp_boolean_t requeue);
/**
* amqp_tx_select
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @returns amqp_tx_select_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_tx_select_ok_t *
AMQP_CALL amqp_tx_select(amqp_connection_state_t state, amqp_channel_t channel);
/**
* amqp_tx_commit
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @returns amqp_tx_commit_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_tx_commit_ok_t *
AMQP_CALL amqp_tx_commit(amqp_connection_state_t state, amqp_channel_t channel);
/**
* amqp_tx_rollback
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @returns amqp_tx_rollback_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_tx_rollback_ok_t *
AMQP_CALL amqp_tx_rollback(amqp_connection_state_t state, amqp_channel_t channel);
/**
* amqp_confirm_select
*
* @param [in] state connection state
* @param [in] channel the channel to do the RPC on
* @returns amqp_confirm_select_ok_t
*/
AMQP_PUBLIC_FUNCTION
amqp_confirm_select_ok_t *
AMQP_CALL amqp_confirm_select(amqp_connection_state_t state, amqp_channel_t channel);
AMQP_END_DECLS
#endif /* AMQP_FRAMING_H */
rabbitmq-c-0.8.0/librabbitmq/amqp_hostcheck.c 0000664 0000000 0000000 00000013272 12702357234 0021177 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* Copyright 1996-2014 Daniel Stenberg .
* Copyright 2014 Michael Steinert
*
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or other
* dealings in this Software without prior written authorization of the
* copyright holder.
*/
#include "amqp_hostcheck.h"
#include
/* Portable, consistent toupper (remember EBCDIC). Do not use toupper()
* because its behavior is altered by the current locale.
*/
static char
amqp_raw_toupper(char in)
{
switch (in) {
case 'a':
return 'A';
case 'b':
return 'B';
case 'c':
return 'C';
case 'd':
return 'D';
case 'e':
return 'E';
case 'f':
return 'F';
case 'g':
return 'G';
case 'h':
return 'H';
case 'i':
return 'I';
case 'j':
return 'J';
case 'k':
return 'K';
case 'l':
return 'L';
case 'm':
return 'M';
case 'n':
return 'N';
case 'o':
return 'O';
case 'p':
return 'P';
case 'q':
return 'Q';
case 'r':
return 'R';
case 's':
return 'S';
case 't':
return 'T';
case 'u':
return 'U';
case 'v':
return 'V';
case 'w':
return 'W';
case 'x':
return 'X';
case 'y':
return 'Y';
case 'z':
return 'Z';
}
return in;
}
/*
* amqp_raw_equal() is for doing "raw" case insensitive strings. This is meant
* to be locale independent and only compare strings we know are safe for
* this. See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for
* some further explanation to why this function is necessary.
*
* The function is capable of comparing a-z case insensitively even for
* non-ascii.
*/
static int
amqp_raw_equal(const char *first, const char *second)
{
while (*first && *second) {
if (amqp_raw_toupper(*first) != amqp_raw_toupper(*second)) {
/* get out of the loop as soon as they don't match */
break;
}
first++;
second++;
}
/* we do the comparison here (possibly again), just to make sure that if
* the loop above is skipped because one of the strings reached zero, we
* must not return this as a successful match
*/
return (amqp_raw_toupper(*first) == amqp_raw_toupper(*second));
}
static int
amqp_raw_nequal(const char *first, const char *second, size_t max)
{
while (*first && *second && max) {
if (amqp_raw_toupper(*first) != amqp_raw_toupper(*second)) {
break;
}
max--;
first++;
second++;
}
if (0 == max) {
return 1; /* they are equal this far */
}
return amqp_raw_toupper(*first) == amqp_raw_toupper(*second);
}
/*
* Match a hostname against a wildcard pattern.
* E.g.
* "foo.host.com" matches "*.host.com".
*
* We use the matching rule described in RFC6125, section 6.4.3.
* http://tools.ietf.org/html/rfc6125#section-6.4.3
*/
static amqp_hostcheck_result amqp_hostmatch(const char *hostname,
const char *pattern) {
const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
int wildcard_enabled;
size_t prefixlen, suffixlen;
pattern_wildcard = strchr(pattern, '*');
if (pattern_wildcard == NULL) {
return amqp_raw_equal(pattern, hostname) ? AMQP_HCR_MATCH
: AMQP_HCR_NO_MATCH;
}
/* We require at least 2 dots in pattern to avoid too wide wildcard match. */
wildcard_enabled = 1;
pattern_label_end = strchr(pattern, '.');
if (pattern_label_end == NULL ||
strchr(pattern_label_end + 1, '.') == NULL ||
pattern_wildcard > pattern_label_end ||
amqp_raw_nequal(pattern, "xn--", 4)) {
wildcard_enabled = 0;
}
if (!wildcard_enabled) {
return amqp_raw_equal(pattern, hostname) ? AMQP_HCR_MATCH
: AMQP_HCR_NO_MATCH;
}
hostname_label_end = strchr(hostname, '.');
if (hostname_label_end == NULL ||
!amqp_raw_equal(pattern_label_end, hostname_label_end)) {
return AMQP_HCR_NO_MATCH;
}
/* The wildcard must match at least one character, so the left-most
* label of the hostname is at least as large as the left-most label
* of the pattern.
*/
if (hostname_label_end - hostname < pattern_label_end - pattern) {
return AMQP_HCR_NO_MATCH;
}
prefixlen = pattern_wildcard - pattern;
suffixlen = pattern_label_end - (pattern_wildcard + 1);
return amqp_raw_nequal(pattern, hostname, prefixlen) &&
amqp_raw_nequal(pattern_wildcard + 1, hostname_label_end - suffixlen,
suffixlen) ? AMQP_HCR_MATCH : AMQP_HCR_NO_MATCH;
}
amqp_hostcheck_result amqp_hostcheck(const char *match_pattern,
const char *hostname) {
/* sanity check */
if (!match_pattern || !*match_pattern || !hostname || !*hostname) {
return AMQP_HCR_NO_MATCH;
}
/* trivial case */
if (amqp_raw_equal(hostname, match_pattern)) {
return AMQP_HCR_MATCH;
}
return amqp_hostmatch(hostname, match_pattern);
}
rabbitmq-c-0.8.0/librabbitmq/amqp_hostcheck.h 0000664 0000000 0000000 00000003460 12702357234 0021202 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
#ifndef librabbitmq_amqp_hostcheck_h
#define librabbitmq_amqp_hostcheck_h
/*
* Copyright 1996-2014 Daniel Stenberg .
* Copyright 2014 Michael Steinert
*
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or other
* dealings in this Software without prior written authorization of the
* copyright holder.
*/
typedef enum {
AMQP_HCR_NO_MATCH = 0,
AMQP_HCR_MATCH = 1
} amqp_hostcheck_result;
/**
* Determine whether hostname matches match_pattern.
*
* match_pattern may include wildcards.
*
* Match is performed based on the rules set forth in RFC6125 section 6.4.3.
* http://tools.ietf.org/html/rfc6125#section-6.4.3
*
* \param match_pattern RFC6125 compliant pattern
* \param hostname to match against
* \returns AMQP_HCR_MATCH if its a match, AMQP_HCR_NO_MATCH otherwise.
*/
amqp_hostcheck_result amqp_hostcheck(const char *match_pattern,
const char *hostname);
#endif
rabbitmq-c-0.8.0/librabbitmq/amqp_mem.c 0000664 0000000 0000000 00000014313 12702357234 0017777 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "amqp_private.h"
#include
#include
#include
#include
#include
#include
char const *amqp_version(void)
{
return AMQP_VERSION_STRING;
}
uint32_t amqp_version_number(void)
{
return AMQP_VERSION;
}
void init_amqp_pool(amqp_pool_t *pool, size_t pagesize)
{
pool->pagesize = pagesize ? pagesize : 4096;
pool->pages.num_blocks = 0;
pool->pages.blocklist = NULL;
pool->large_blocks.num_blocks = 0;
pool->large_blocks.blocklist = NULL;
pool->next_page = 0;
pool->alloc_block = NULL;
pool->alloc_used = 0;
}
static void empty_blocklist(amqp_pool_blocklist_t *x)
{
int i;
for (i = 0; i < x->num_blocks; i++) {
free(x->blocklist[i]);
}
if (x->blocklist != NULL) {
free(x->blocklist);
}
x->num_blocks = 0;
x->blocklist = NULL;
}
void recycle_amqp_pool(amqp_pool_t *pool)
{
empty_blocklist(&pool->large_blocks);
pool->next_page = 0;
pool->alloc_block = NULL;
pool->alloc_used = 0;
}
void empty_amqp_pool(amqp_pool_t *pool)
{
recycle_amqp_pool(pool);
empty_blocklist(&pool->pages);
}
/* Returns 1 on success, 0 on failure */
static int record_pool_block(amqp_pool_blocklist_t *x, void *block)
{
size_t blocklistlength = sizeof(void *) * (x->num_blocks + 1);
if (x->blocklist == NULL) {
x->blocklist = malloc(blocklistlength);
if (x->blocklist == NULL) {
return 0;
}
} else {
void *newbl = realloc(x->blocklist, blocklistlength);
if (newbl == NULL) {
return 0;
}
x->blocklist = newbl;
}
x->blocklist[x->num_blocks] = block;
x->num_blocks++;
return 1;
}
void *amqp_pool_alloc(amqp_pool_t *pool, size_t amount)
{
if (amount == 0) {
return NULL;
}
amount = (amount + 7) & (~7); /* round up to nearest 8-byte boundary */
if (amount > pool->pagesize) {
void *result = calloc(1, amount);
if (result == NULL) {
return NULL;
}
if (!record_pool_block(&pool->large_blocks, result)) {
free(result);
return NULL;
}
return result;
}
if (pool->alloc_block != NULL) {
assert(pool->alloc_used <= pool->pagesize);
if (pool->alloc_used + amount <= pool->pagesize) {
void *result = pool->alloc_block + pool->alloc_used;
pool->alloc_used += amount;
return result;
}
}
if (pool->next_page >= pool->pages.num_blocks) {
pool->alloc_block = calloc(1, pool->pagesize);
if (pool->alloc_block == NULL) {
return NULL;
}
if (!record_pool_block(&pool->pages, pool->alloc_block)) {
return NULL;
}
pool->next_page = pool->pages.num_blocks;
} else {
pool->alloc_block = pool->pages.blocklist[pool->next_page];
pool->next_page++;
}
pool->alloc_used = amount;
return pool->alloc_block;
}
void amqp_pool_alloc_bytes(amqp_pool_t *pool, size_t amount, amqp_bytes_t *output)
{
output->len = amount;
output->bytes = amqp_pool_alloc(pool, amount);
}
amqp_bytes_t amqp_cstring_bytes(char const *cstr)
{
amqp_bytes_t result;
result.len = strlen(cstr);
result.bytes = (void *) cstr;
return result;
}
amqp_bytes_t amqp_bytes_malloc_dup(amqp_bytes_t src)
{
amqp_bytes_t result;
result.len = src.len;
result.bytes = malloc(src.len);
if (result.bytes != NULL) {
memcpy(result.bytes, src.bytes, src.len);
}
return result;
}
amqp_bytes_t amqp_bytes_malloc(size_t amount)
{
amqp_bytes_t result;
result.len = amount;
result.bytes = malloc(amount); /* will return NULL if it fails */
return result;
}
void amqp_bytes_free(amqp_bytes_t bytes)
{
free(bytes.bytes);
}
amqp_pool_t *amqp_get_or_create_channel_pool(amqp_connection_state_t state, amqp_channel_t channel)
{
amqp_pool_table_entry_t *entry;
size_t index = channel % POOL_TABLE_SIZE;
entry = state->pool_table[index];
for ( ; NULL != entry; entry = entry->next) {
if (channel == entry->channel) {
return &entry->pool;
}
}
entry = malloc(sizeof(amqp_pool_table_entry_t));
if (NULL == entry) {
return NULL;
}
entry->channel = channel;
entry->next = state->pool_table[index];
state->pool_table[index] = entry;
init_amqp_pool(&entry->pool, state->frame_max);
return &entry->pool;
}
amqp_pool_t *amqp_get_channel_pool(amqp_connection_state_t state, amqp_channel_t channel)
{
amqp_pool_table_entry_t *entry;
size_t index = channel % POOL_TABLE_SIZE;
entry = state->pool_table[index];
for ( ; NULL != entry; entry = entry->next) {
if (channel == entry->channel) {
return &entry->pool;
}
}
return NULL;
}
int amqp_bytes_equal(amqp_bytes_t r, amqp_bytes_t l) {
if (r.len == l.len &&
(r.bytes == l.bytes || 0 == memcmp(r.bytes, l.bytes, r.len))) {
return 1;
}
return 0;
}
rabbitmq-c-0.8.0/librabbitmq/amqp_openssl.c 0000664 0000000 0000000 00000043714 12702357234 0020713 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* Portions created by Alan Antonuk are Copyright (c) 2012-2014 Alan Antonuk.
* All Rights Reserved.
*
* Portions created by Michael Steinert are Copyright (c) 2012-2014 Michael
* Steinert. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "amqp_openssl_hostname_validation.h"
#include "amqp_ssl_socket.h"
#include "amqp_socket.h"
#include "amqp_private.h"
#include "amqp_time.h"
#include "threads.h"
#include
#include
#include
#include
#include
#include
#include
#include
static int initialize_openssl(void);
static int destroy_openssl(void);
static int open_ssl_connections = 0;
static amqp_boolean_t do_initialize_openssl = 1;
static amqp_boolean_t openssl_initialized = 0;
#ifdef ENABLE_THREAD_SAFETY
static unsigned long amqp_ssl_threadid_callback(void);
static void amqp_ssl_locking_callback(int mode, int n, const char *file, int line);
#ifdef _WIN32
static long win32_create_mutex = 0;
static pthread_mutex_t openssl_init_mutex = NULL;
#else
static pthread_mutex_t openssl_init_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
static pthread_mutex_t *amqp_openssl_lockarray = NULL;
#endif /* ENABLE_THREAD_SAFETY */
struct amqp_ssl_socket_t {
const struct amqp_socket_class_t *klass;
SSL_CTX *ctx;
int sockfd;
SSL *ssl;
amqp_boolean_t verify_peer;
amqp_boolean_t verify_hostname;
int internal_error;
};
static ssize_t amqp_ssl_socket_send(void *base, const void *buf, size_t len,
AMQP_UNUSED int flags) {
struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
int res;
if (-1 == self->sockfd) {
return AMQP_STATUS_SOCKET_CLOSED;
}
/* SSL_write takes an int for length of buffer, protect against len being
* larger than larger than what SSL_write can take */
if (len > INT_MAX) {
return AMQP_STATUS_INVALID_PARAMETER;
}
ERR_clear_error();
self->internal_error = 0;
/* This will only return on error, or once the whole buffer has been
* written to the SSL stream. See SSL_MODE_ENABLE_PARTIAL_WRITE */
res = SSL_write(self->ssl, buf, (int)len);
if (0 >= res) {
self->internal_error = SSL_get_error(self->ssl, res);
/* TODO: Close connection if it isn't already? */
/* TODO: Possibly be more intelligent in reporting WHAT went wrong */
switch (self->internal_error) {
case SSL_ERROR_WANT_READ:
res = AMQP_PRIVATE_STATUS_SOCKET_NEEDREAD;
break;
case SSL_ERROR_WANT_WRITE:
res = AMQP_PRIVATE_STATUS_SOCKET_NEEDWRITE;
break;
case SSL_ERROR_ZERO_RETURN:
res = AMQP_STATUS_CONNECTION_CLOSED;
break;
default:
res = AMQP_STATUS_SSL_ERROR;
break;
}
} else {
self->internal_error = 0;
}
return (ssize_t)res;
}
static ssize_t
amqp_ssl_socket_recv(void *base,
void *buf,
size_t len,
AMQP_UNUSED int flags)
{
struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
int received;
if (-1 == self->sockfd) {
return AMQP_STATUS_SOCKET_CLOSED;
}
/* SSL_read takes an int for length of buffer, protect against len being
* larger than larger than what SSL_read can take */
if (len > INT_MAX) {
return AMQP_STATUS_INVALID_PARAMETER;
}
ERR_clear_error();
self->internal_error = 0;
received = SSL_read(self->ssl, buf, (int)len);
if (0 >= received) {
self->internal_error = SSL_get_error(self->ssl, received);
switch (self->internal_error) {
case SSL_ERROR_WANT_READ:
received = AMQP_PRIVATE_STATUS_SOCKET_NEEDREAD;
break;
case SSL_ERROR_WANT_WRITE:
received = AMQP_PRIVATE_STATUS_SOCKET_NEEDWRITE;
break;
case SSL_ERROR_ZERO_RETURN:
received = AMQP_STATUS_CONNECTION_CLOSED;
break;
default:
received = AMQP_STATUS_SSL_ERROR;
break;
}
}
return (ssize_t)received;
}
static int
amqp_ssl_socket_open(void *base, const char *host, int port, struct timeval *timeout)
{
struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
long result;
int status;
amqp_time_t deadline;
X509 *cert;
if (-1 != self->sockfd) {
return AMQP_STATUS_SOCKET_INUSE;
}
ERR_clear_error();
self->ssl = SSL_new(self->ctx);
if (!self->ssl) {
self->internal_error = ERR_peek_error();
status = AMQP_STATUS_SSL_ERROR;
goto exit;
}
status = amqp_time_from_now(&deadline, timeout);
if (AMQP_STATUS_OK != status) {
return status;
}
self->sockfd = amqp_open_socket_inner(host, port, deadline);
if (0 > self->sockfd) {
status = self->sockfd;
self->internal_error = amqp_os_socket_error();
self->sockfd = -1;
goto error_out1;
}
status = SSL_set_fd(self->ssl, self->sockfd);
if (!status) {
self->internal_error = SSL_get_error(self->ssl, status);
status = AMQP_STATUS_SSL_ERROR;
goto error_out2;
}
start_connect:
status = SSL_connect(self->ssl);
if (status != 1) {
self->internal_error = SSL_get_error(self->ssl, status);
switch (self->internal_error) {
case SSL_ERROR_WANT_READ:
status = amqp_poll(self->sockfd, AMQP_SF_POLLIN, deadline);
break;
case SSL_ERROR_WANT_WRITE:
status = amqp_poll(self->sockfd, AMQP_SF_POLLOUT, deadline);
break;
default:
status = AMQP_STATUS_SSL_CONNECTION_FAILED;
}
if (AMQP_STATUS_OK == status) {
goto start_connect;
}
goto error_out2;
}
cert = SSL_get_peer_certificate(self->ssl);
if (self->verify_peer) {
if (!cert) {
self->internal_error = 0;
status = AMQP_STATUS_SSL_PEER_VERIFY_FAILED;
goto error_out3;
}
result = SSL_get_verify_result(self->ssl);
if (X509_V_OK != result) {
self->internal_error = result;
status = AMQP_STATUS_SSL_PEER_VERIFY_FAILED;
goto error_out4;
}
}
if (self->verify_hostname) {
if (!cert) {
self->internal_error = 0;
status = AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED;
goto error_out3;
}
if (AMQP_HVR_MATCH_FOUND != amqp_ssl_validate_hostname(host, cert)) {
self->internal_error = 0;
status = AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED;
goto error_out4;
}
}
X509_free(cert);
self->internal_error = 0;
status = AMQP_STATUS_OK;
exit:
return status;
error_out4:
X509_free(cert);
error_out3:
SSL_shutdown(self->ssl);
error_out2:
amqp_os_socket_close(self->sockfd);
self->sockfd = -1;
error_out1:
SSL_free(self->ssl);
self->ssl = NULL;
goto exit;
}
static int
amqp_ssl_socket_close(void *base, amqp_socket_close_enum force)
{
struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
if (-1 == self->sockfd) {
return AMQP_STATUS_SOCKET_CLOSED;
}
if (AMQP_SC_NONE == force) {
/* don't try too hard to shutdown the connection */
SSL_shutdown(self->ssl);
}
SSL_free(self->ssl);
self->ssl = NULL;
if (amqp_os_socket_close(self->sockfd)) {
return AMQP_STATUS_SOCKET_ERROR;
}
self->sockfd = -1;
return AMQP_STATUS_OK;
}
static int
amqp_ssl_socket_get_sockfd(void *base)
{
struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
return self->sockfd;
}
static void
amqp_ssl_socket_delete(void *base)
{
struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
if (self) {
amqp_ssl_socket_close(self, AMQP_SC_NONE);
SSL_CTX_free(self->ctx);
free(self);
}
destroy_openssl();
}
static const struct amqp_socket_class_t amqp_ssl_socket_class = {
amqp_ssl_socket_send, /* send */
amqp_ssl_socket_recv, /* recv */
amqp_ssl_socket_open, /* open */
amqp_ssl_socket_close, /* close */
amqp_ssl_socket_get_sockfd, /* get_sockfd */
amqp_ssl_socket_delete /* delete */
};
amqp_socket_t *
amqp_ssl_socket_new(amqp_connection_state_t state)
{
struct amqp_ssl_socket_t *self = calloc(1, sizeof(*self));
int status;
if (!self) {
return NULL;
}
self->sockfd = -1;
self->klass = &amqp_ssl_socket_class;
self->verify_peer = 1;
self->verify_hostname = 1;
status = initialize_openssl();
if (status) {
goto error;
}
self->ctx = SSL_CTX_new(SSLv23_client_method());
if (!self->ctx) {
goto error;
}
/* Disable SSLv2 and SSLv3 */
SSL_CTX_set_options(self->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
amqp_set_socket(state, (amqp_socket_t *)self);
return (amqp_socket_t *)self;
error:
amqp_ssl_socket_delete((amqp_socket_t *)self);
return NULL;
}
int
amqp_ssl_socket_set_cacert(amqp_socket_t *base,
const char *cacert)
{
int status;
struct amqp_ssl_socket_t *self;
if (base->klass != &amqp_ssl_socket_class) {
amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
}
self = (struct amqp_ssl_socket_t *)base;
status = SSL_CTX_load_verify_locations(self->ctx, cacert, NULL);
if (1 != status) {
return AMQP_STATUS_SSL_ERROR;
}
return AMQP_STATUS_OK;
}
int
amqp_ssl_socket_set_key(amqp_socket_t *base,
const char *cert,
const char *key)
{
int status;
struct amqp_ssl_socket_t *self;
if (base->klass != &amqp_ssl_socket_class) {
amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
}
self = (struct amqp_ssl_socket_t *)base;
status = SSL_CTX_use_certificate_chain_file(self->ctx, cert);
if (1 != status) {
return AMQP_STATUS_SSL_ERROR;
}
status = SSL_CTX_use_PrivateKey_file(self->ctx, key,
SSL_FILETYPE_PEM);
if (1 != status) {
return AMQP_STATUS_SSL_ERROR;
}
return AMQP_STATUS_OK;
}
static int
password_cb(AMQP_UNUSED char *buffer,
AMQP_UNUSED int length,
AMQP_UNUSED int rwflag,
AMQP_UNUSED void *user_data)
{
amqp_abort("rabbitmq-c does not support password protected keys");
}
int
amqp_ssl_socket_set_key_buffer(amqp_socket_t *base,
const char *cert,
const void *key,
size_t n)
{
int status = AMQP_STATUS_OK;
BIO *buf = NULL;
RSA *rsa = NULL;
struct amqp_ssl_socket_t *self;
if (base->klass != &amqp_ssl_socket_class) {
amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
}
if (n > INT_MAX) {
return AMQP_STATUS_INVALID_PARAMETER;
}
self = (struct amqp_ssl_socket_t *)base;
status = SSL_CTX_use_certificate_chain_file(self->ctx, cert);
if (1 != status) {
return AMQP_STATUS_SSL_ERROR;
}
buf = BIO_new_mem_buf((void *)key, (int)n);
if (!buf) {
goto error;
}
rsa = PEM_read_bio_RSAPrivateKey(buf, NULL, password_cb, NULL);
if (!rsa) {
goto error;
}
status = SSL_CTX_use_RSAPrivateKey(self->ctx, rsa);
if (1 != status) {
goto error;
}
exit:
BIO_vfree(buf);
RSA_free(rsa);
return status;
error:
status = AMQP_STATUS_SSL_ERROR;
goto exit;
}
int
amqp_ssl_socket_set_cert(amqp_socket_t *base,
const char *cert)
{
int status;
struct amqp_ssl_socket_t *self;
if (base->klass != &amqp_ssl_socket_class) {
amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
}
self = (struct amqp_ssl_socket_t *)base;
status = SSL_CTX_use_certificate_chain_file(self->ctx, cert);
if (1 != status) {
return AMQP_STATUS_SSL_ERROR;
}
return AMQP_STATUS_OK;
}
void
amqp_ssl_socket_set_verify(amqp_socket_t *base,
amqp_boolean_t verify)
{
amqp_ssl_socket_set_verify_peer(base, verify);
amqp_ssl_socket_set_verify_hostname(base, verify);
}
void amqp_ssl_socket_set_verify_peer(amqp_socket_t *base,
amqp_boolean_t verify) {
struct amqp_ssl_socket_t *self;
if (base->klass != &amqp_ssl_socket_class) {
amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
}
self = (struct amqp_ssl_socket_t *)base;
self->verify_peer = verify;
}
void amqp_ssl_socket_set_verify_hostname(amqp_socket_t *base,
amqp_boolean_t verify) {
struct amqp_ssl_socket_t *self;
if (base->klass != &amqp_ssl_socket_class) {
amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
}
self = (struct amqp_ssl_socket_t *)base;
self->verify_hostname = verify;
}
int amqp_ssl_socket_set_ssl_versions(amqp_socket_t *base,
amqp_tls_version_t min,
amqp_tls_version_t max) {
struct amqp_ssl_socket_t *self;
if (base->klass != &amqp_ssl_socket_class) {
amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
}
self = (struct amqp_ssl_socket_t *)base;
{
long clear_options;
long set_options = 0;
#if defined(SSL_OP_NO_TLSv1_2)
amqp_tls_version_t max_supported = AMQP_TLSv1_2;
clear_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
#elif defined(SSL_OP_NO_TLSv1_1)
amqp_tls_version_t max_supported = AMQP_TLSv1_1;
clear_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
#elif defined(SSL_OP_NO_TLSv1)
amqp_tls_version_t max_supported = AMQP_TLSv1;
clear_options = SSL_OP_NO_TLSv1;
#else
# error "Need a version of OpenSSL that can support TLSv1 or greater."
#endif
if (AMQP_TLSvLATEST == max) {
max = max_supported;
}
if (AMQP_TLSvLATEST == min) {
min = max_supported;
}
if (min > max) {
return AMQP_STATUS_INVALID_PARAMETER;
}
if (max > max_supported || min > max_supported) {
return AMQP_STATUS_UNSUPPORTED;
}
if (min > AMQP_TLSv1) {
set_options |= SSL_OP_NO_TLSv1;
}
#ifdef SSL_OP_NO_TLSv1_1
if (min > AMQP_TLSv1_1 || max < AMQP_TLSv1_1) {
set_options |= SSL_OP_NO_TLSv1_1;
}
#endif
#ifdef SSL_OP_NO_TLSv1_2
if (max < AMQP_TLSv1_2) {
set_options |= SSL_OP_NO_TLSv1_2;
}
#endif
SSL_CTX_clear_options(self->ctx, clear_options);
SSL_CTX_set_options(self->ctx, set_options);
}
return AMQP_STATUS_OK;
}
void
amqp_set_initialize_ssl_library(amqp_boolean_t do_initialize)
{
if (!openssl_initialized) {
do_initialize_openssl = do_initialize;
}
}
#ifdef ENABLE_THREAD_SAFETY
unsigned long
amqp_ssl_threadid_callback(void)
{
return (unsigned long)pthread_self();
}
void
amqp_ssl_locking_callback(int mode, int n,
AMQP_UNUSED const char *file,
AMQP_UNUSED int line)
{
if (mode & CRYPTO_LOCK) {
if (pthread_mutex_lock(&amqp_openssl_lockarray[n])) {
amqp_abort("Runtime error: Failure in trying to lock OpenSSL mutex");
}
} else {
if (pthread_mutex_unlock(&amqp_openssl_lockarray[n])) {
amqp_abort("Runtime error: Failure in trying to unlock OpenSSL mutex");
}
}
}
#endif /* ENABLE_THREAD_SAFETY */
static int
initialize_openssl(void)
{
#ifdef ENABLE_THREAD_SAFETY
#ifdef _WIN32
/* No such thing as PTHREAD_INITIALIZE_MUTEX macro on Win32, so we use this */
if (NULL == openssl_init_mutex) {
while (InterlockedExchange(&win32_create_mutex, 1) == 1)
/* Loop, someone else is holding this lock */ ;
if (NULL == openssl_init_mutex) {
if (pthread_mutex_init(&openssl_init_mutex, NULL)) {
return -1;
}
}
InterlockedExchange(&win32_create_mutex, 0);
}
#endif /* _WIN32 */
if (pthread_mutex_lock(&openssl_init_mutex)) {
return -1;
}
#endif /* ENABLE_THREAD_SAFETY */
if (do_initialize_openssl) {
#ifdef ENABLE_THREAD_SAFETY
if (NULL == amqp_openssl_lockarray) {
int i = 0;
amqp_openssl_lockarray = calloc(CRYPTO_num_locks(), sizeof(pthread_mutex_t));
if (!amqp_openssl_lockarray) {
pthread_mutex_unlock(&openssl_init_mutex);
return -1;
}
for (i = 0; i < CRYPTO_num_locks(); ++i) {
if (pthread_mutex_init(&amqp_openssl_lockarray[i], NULL)) {
free(amqp_openssl_lockarray);
amqp_openssl_lockarray = NULL;
pthread_mutex_unlock(&openssl_init_mutex);
return -1;
}
}
}
if (0 == open_ssl_connections) {
CRYPTO_set_id_callback(amqp_ssl_threadid_callback);
CRYPTO_set_locking_callback(amqp_ssl_locking_callback);
}
#endif /* ENABLE_THREAD_SAFETY */
if (!openssl_initialized) {
OPENSSL_config(NULL);
SSL_library_init();
SSL_load_error_strings();
openssl_initialized = 1;
}
}
++open_ssl_connections;
#ifdef ENABLE_THREAD_SAFETY
pthread_mutex_unlock(&openssl_init_mutex);
#endif /* ENABLE_THREAD_SAFETY */
return 0;
}
static int
destroy_openssl(void)
{
#ifdef ENABLE_THREAD_SAFETY
if (pthread_mutex_lock(&openssl_init_mutex)) {
return -1;
}
#endif /* ENABLE_THREAD_SAFETY */
if (open_ssl_connections > 0) {
--open_ssl_connections;
}
#ifdef ENABLE_THREAD_SAFETY
if (0 == open_ssl_connections && do_initialize_openssl) {
/* Unsetting these allows the rabbitmq-c library to be unloaded
* safely. We do leak the amqp_openssl_lockarray. Which is only
* an issue if you repeatedly unload and load the library
*/
CRYPTO_set_locking_callback(NULL);
CRYPTO_set_id_callback(NULL);
}
pthread_mutex_unlock(&openssl_init_mutex);
#endif /* ENABLE_THREAD_SAFETY */
return 0;
}
rabbitmq-c-0.8.0/librabbitmq/amqp_openssl_hostname_validation.c 0000664 0000000 0000000 00000013707 12702357234 0025022 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* Copyright (C) 2012, iSEC Partners.
* Copyright (C) 2015 Alan Antonuk.
*
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or other
* dealings in this Software without prior written authorization of the
* copyright holder.
*/
/* Originally from:
* https://github.com/iSECPartners/ssl-conservatory
* https://wiki.openssl.org/index.php/Hostname_validation
*/
#include
#include
#include "amqp_openssl_hostname_validation.h"
#include "amqp_hostcheck.h"
#define HOSTNAME_MAX_SIZE 255
/**
* Tries to find a match for hostname in the certificate's Common Name field.
*
* Returns AMQP_HVR_MATCH_FOUND if a match was found.
* Returns AMQP_HVR_MATCH_NOT_FOUND if no matches were found.
* Returns AMQP_HVR_MALFORMED_CERTIFICATE if the Common Name had a NUL character embedded in it.
* Returns AMQP_HVR_ERROR if the Common Name could not be extracted.
*/
static amqp_hostname_validation_result amqp_matches_common_name(
const char *hostname, const X509 *server_cert) {
int common_name_loc = -1;
X509_NAME_ENTRY *common_name_entry = NULL;
ASN1_STRING *common_name_asn1 = NULL;
char *common_name_str = NULL;
// Find the position of the CN field in the Subject field of the certificate
common_name_loc = X509_NAME_get_index_by_NID(
X509_get_subject_name((X509 *)server_cert), NID_commonName, -1);
if (common_name_loc < 0) {
return AMQP_HVR_ERROR;
}
// Extract the CN field
common_name_entry = X509_NAME_get_entry(
X509_get_subject_name((X509 *)server_cert), common_name_loc);
if (common_name_entry == NULL) {
return AMQP_HVR_ERROR;
}
// Convert the CN field to a C string
common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry);
if (common_name_asn1 == NULL) {
return AMQP_HVR_ERROR;
}
common_name_str = (char *)ASN1_STRING_data(common_name_asn1);
// Make sure there isn't an embedded NUL character in the CN
if ((size_t)ASN1_STRING_length(common_name_asn1) != strlen(common_name_str)) {
return AMQP_HVR_MALFORMED_CERTIFICATE;
}
// Compare expected hostname with the CN
if (amqp_hostcheck(common_name_str, hostname) == AMQP_HCR_MATCH) {
return AMQP_HVR_MATCH_FOUND;
} else {
return AMQP_HVR_MATCH_NOT_FOUND;
}
}
/**
* Tries to find a match for hostname in the certificate's Subject Alternative
* Name extension.
*
* Returns AMQP_HVR_MATCH_FOUND if a match was found.
* Returns AMQP_HVR_MATCH_NOT_FOUND if no matches were found.
* Returns AMQP_HVR_MALFORMED_CERTIFICATE if any of the hostnames had a NUL
* character embedded in it.
* Returns AMQP_HVR_NO_SAN_PRESENT if the SAN extension was not present in the
* certificate.
*/
static amqp_hostname_validation_result amqp_matches_subject_alternative_name(
const char *hostname, const X509 *server_cert) {
amqp_hostname_validation_result result = AMQP_HVR_MATCH_NOT_FOUND;
int i;
int san_names_nb = -1;
STACK_OF(GENERAL_NAME) *san_names = NULL;
// Try to extract the names within the SAN extension from the certificate
san_names =
X509_get_ext_d2i((X509 *)server_cert, NID_subject_alt_name, NULL, NULL);
if (san_names == NULL) {
return AMQP_HVR_NO_SAN_PRESENT;
}
san_names_nb = sk_GENERAL_NAME_num(san_names);
// Check each name within the extension
for (i = 0; i < san_names_nb; i++) {
const GENERAL_NAME *current_name = sk_GENERAL_NAME_value(san_names, i);
if (current_name->type == GEN_DNS) {
// Current name is a DNS name, let's check it
char *dns_name = (char *)ASN1_STRING_data(current_name->d.dNSName);
// Make sure there isn't an embedded NUL character in the DNS name
if ((size_t)ASN1_STRING_length(current_name->d.dNSName) !=
strlen(dns_name)) {
result = AMQP_HVR_MALFORMED_CERTIFICATE;
break;
} else { // Compare expected hostname with the DNS name
if (amqp_hostcheck(dns_name, hostname) == AMQP_HCR_MATCH) {
result = AMQP_HVR_MATCH_FOUND;
break;
}
}
}
}
sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
return result;
}
/**
* Validates the server's identity by looking for the expected hostname in the
* server's certificate. As described in RFC 6125, it first tries to find a match
* in the Subject Alternative Name extension. If the extension is not present in
* the certificate, it checks the Common Name instead.
*
* Returns AMQP_HVR_MATCH_FOUND if a match was found.
* Returns AMQP_HVR_MATCH_NOT_FOUND if no matches were found.
* Returns AMQP_HVR_MALFORMED_CERTIFICATE if any of the hostnames had a NUL
* character embedded in it.
* Returns AMQP_HVR_ERROR if there was an error.
*/
amqp_hostname_validation_result amqp_ssl_validate_hostname(
const char *hostname, const X509 *server_cert) {
amqp_hostname_validation_result result;
if ((hostname == NULL) || (server_cert == NULL)) return AMQP_HVR_ERROR;
// First try the Subject Alternative Names extension
result = amqp_matches_subject_alternative_name(hostname, server_cert);
if (result == AMQP_HVR_NO_SAN_PRESENT) {
// Extension was not found: try the Common Name
result = amqp_matches_common_name(hostname, server_cert);
}
return result;
}
rabbitmq-c-0.8.0/librabbitmq/amqp_openssl_hostname_validation.h 0000664 0000000 0000000 00000004342 12702357234 0025022 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
#ifndef librabbitmq_amqp_openssl_hostname_validation_h
#define librabbitmq_amqp_openssl_hostname_validation_h
/*
* Copyright (C) 2012, iSEC Partners.
* Copyright (C) 2015 Alan Antonuk.
*
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or other
* dealings in this Software without prior written authorization of the
* copyright holder.
*/
/* Originally from:
* https://github.com/iSECPartners/ssl-conservatory
* https://wiki.openssl.org/index.php/Hostname_validation
*/
#include
typedef enum {
AMQP_HVR_MATCH_FOUND,
AMQP_HVR_MATCH_NOT_FOUND,
AMQP_HVR_NO_SAN_PRESENT,
AMQP_HVR_MALFORMED_CERTIFICATE,
AMQP_HVR_ERROR
} amqp_hostname_validation_result;
/**
* Validates the server's identity by looking for the expected hostname in the
* server's certificate. As described in RFC 6125, it first tries to find a match
* in the Subject Alternative Name extension. If the extension is not present in
* the certificate, it checks the Common Name instead.
*
* Returns AMQP_HVR_MATCH_FOUND if a match was found.
* Returns AMQP_HVR_MATCH_NOT_FOUND if no matches were found.
* Returns AMQP_HVR_MALFORMED_CERTIFICATE if any of the hostnames had a NUL
* character embedded in it.
* Returns AMQP_HVR_ERROR if there was an error.
*/
amqp_hostname_validation_result amqp_ssl_validate_hostname(
const char *hostname, const X509 *server_cert);
#endif
rabbitmq-c-0.8.0/librabbitmq/amqp_private.h 0000664 0000000 0000000 00000033301 12702357234 0020676 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
#ifndef librabbitmq_amqp_private_h
#define librabbitmq_amqp_private_h
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2014
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define AMQ_COPYRIGHT "Copyright (c) 2007-2014 VMWare Inc, Tony Garnock-Jones," \
" and Alan Antonuk."
#include "amqp.h"
#include "amqp_framing.h"
#include
#ifdef _WIN32
# ifndef WINVER
/* WINVER 0x0502 is WinXP SP2+, Windows Server 2003 SP1+
* See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx#macros_for_conditional_declarations */
# define WINVER 0x0502
# endif
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include
#else
# include
# include
#endif
/* GCC attributes */
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
#define AMQP_NORETURN \
__attribute__ ((__noreturn__))
#define AMQP_UNUSED \
__attribute__ ((__unused__))
#else
#define AMQP_NORETURN
#define AMQP_UNUSED
#endif
#if __GNUC__ >= 4
#define AMQP_PRIVATE \
__attribute__ ((visibility ("hidden")))
#else
#define AMQP_PRIVATE
#endif
char *
amqp_os_error_string(int err);
#ifdef WITH_SSL
char *
amqp_ssl_error_string(int err);
#endif
#include "amqp_socket.h"
#include "amqp_time.h"
/*
* Connection states: XXX FIX THIS
*
* - CONNECTION_STATE_INITIAL: The initial state, when we cannot be
* sure if the next thing we will get is the first AMQP frame, or a
* protocol header from the server.
*
* - CONNECTION_STATE_IDLE: The normal state between
* frames. Connections may only be reconfigured, and the
* connection's pools recycled, when in this state. Whenever we're
* in this state, the inbound_buffer's bytes pointer must be NULL;
* any other state, and it must point to a block of memory allocated
* from the frame_pool.
*
* - CONNECTION_STATE_HEADER: Some bytes of an incoming frame have
* been seen, but not a complete frame header's worth.
*
* - CONNECTION_STATE_BODY: A complete frame header has been seen, but
* the frame is not yet complete. When it is completed, it will be
* returned, and the connection will return to IDLE state.
*
*/
typedef enum amqp_connection_state_enum_ {
CONNECTION_STATE_IDLE = 0,
CONNECTION_STATE_INITIAL,
CONNECTION_STATE_HEADER,
CONNECTION_STATE_BODY
} amqp_connection_state_enum;
typedef enum amqp_status_private_enum_
{
/* 0x00xx -> AMQP_STATUS_*/
/* 0x01xx -> AMQP_STATUS_TCP_* */
/* 0x02xx -> AMQP_STATUS_SSL_* */
AMQP_PRIVATE_STATUS_SOCKET_NEEDREAD = -0x1301,
AMQP_PRIVATE_STATUS_SOCKET_NEEDWRITE = -0x1302
} amqp_status_private_enum;
/* 7 bytes up front, then payload, then 1 byte footer */
#define HEADER_SIZE 7
#define FOOTER_SIZE 1
#define AMQP_PSEUDOFRAME_PROTOCOL_HEADER 'A'
typedef struct amqp_link_t_ {
struct amqp_link_t_ *next;
void *data;
} amqp_link_t;
#define POOL_TABLE_SIZE 16
typedef struct amqp_pool_table_entry_t_ {
struct amqp_pool_table_entry_t_ *next;
amqp_pool_t pool;
amqp_channel_t channel;
} amqp_pool_table_entry_t;
struct amqp_connection_state_t_ {
amqp_pool_table_entry_t *pool_table[POOL_TABLE_SIZE];
amqp_connection_state_enum state;
int channel_max;
int frame_max;
/* Heartbeat interval in seconds. If this is <= 0, then heartbeats are not
* enabled, and next_recv_heartbeat and next_send_heartbeat are set to
* infinite */
int heartbeat;
amqp_time_t next_recv_heartbeat;
amqp_time_t next_send_heartbeat;
/* buffer for holding frame headers. Allows us to delay allocating
* the raw frame buffer until the type, channel, and size are all known
*/
char header_buffer[HEADER_SIZE + 1];
amqp_bytes_t inbound_buffer;
size_t inbound_offset;
size_t target_size;
amqp_bytes_t outbound_buffer;
amqp_socket_t *socket;
amqp_bytes_t sock_inbound_buffer;
size_t sock_inbound_offset;
size_t sock_inbound_limit;
amqp_link_t *first_queued_frame;
amqp_link_t *last_queued_frame;
amqp_rpc_reply_t most_recent_api_result;
amqp_table_t server_properties;
amqp_table_t client_properties;
amqp_pool_t properties_pool;
};
amqp_pool_t *amqp_get_or_create_channel_pool(amqp_connection_state_t connection, amqp_channel_t channel);
amqp_pool_t *amqp_get_channel_pool(amqp_connection_state_t state, amqp_channel_t channel);
static inline int amqp_heartbeat_send(amqp_connection_state_t state) {
return state->heartbeat;
}
static inline int amqp_heartbeat_recv(amqp_connection_state_t state) {
return 2 * state->heartbeat;
}
int amqp_try_recv(amqp_connection_state_t state);
static inline void *amqp_offset(void *data, size_t offset)
{
return (char *)data + offset;
}
/* This macro defines the encoding and decoding functions associated with a
simple type. */
#define DECLARE_CODEC_BASE_TYPE(bits, htonx, ntohx) \
\
static inline void amqp_e##bits(void *data, size_t offset, \
uint##bits##_t val) \
{ \
/* The AMQP data might be unaligned. So we encode and then copy the \
result into place. */ \
uint##bits##_t res = htonx(val); \
memcpy(amqp_offset(data, offset), &res, bits/8); \
} \
\
static inline uint##bits##_t amqp_d##bits(void *data, size_t offset) \
{ \
/* The AMQP data might be unaligned. So we copy the source value \
into a variable and then decode it. */ \
uint##bits##_t val; \
memcpy(&val, amqp_offset(data, offset), bits/8); \
return ntohx(val); \
} \
\
static inline int amqp_encode_##bits(amqp_bytes_t encoded, size_t *offset, \
uint##bits##_t input) \
\
{ \
size_t o = *offset; \
if ((*offset = o + bits / 8) <= encoded.len) { \
amqp_e##bits(encoded.bytes, o, input); \
return 1; \
} \
else { \
return 0; \
} \
} \
\
static inline int amqp_decode_##bits(amqp_bytes_t encoded, size_t *offset, \
uint##bits##_t *output) \
\
{ \
size_t o = *offset; \
if ((*offset = o + bits / 8) <= encoded.len) { \
*output = amqp_d##bits(encoded.bytes, o); \
return 1; \
} \
else { \
return 0; \
} \
}
/* Determine byte order */
#if defined(__GLIBC__)
# include
# if (__BYTE_ORDER == __LITTLE_ENDIAN)
# define AMQP_LITTLE_ENDIAN
# elif (__BYTE_ORDER == __BIG_ENDIAN)
# define AMQP_BIG_ENDIAN
# else
/* Don't define anything */
# endif
#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) || \
defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
# define AMQP_BIG_ENDIAN
#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) || \
defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
# define AMQP_LITTLE_ENDIAN
#elif defined(__hppa__) || defined(__HPPA__) || defined(__hppa) || \
defined(_POWER) || defined(__powerpc__) || defined(__ppc___) || \
defined(_MIPSEB) || defined(__s390__) || \
defined(__sparc) || defined(__sparc__)
# define AMQP_BIG_ENDIAN
#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) || \
defined(__amd64__) || defined(__x86_64__) || defined(_M_X64) || \
defined(__ia64) || defined(__ia64__) || defined(_M_IA64) || \
defined(__arm__) || defined(_M_ARM) || \
defined(__i386__) || defined(_M_IX86)
# define AMQP_LITTLE_ENDIAN
#else
/* Don't define anything */
#endif
#if defined(AMQP_LITTLE_ENDIAN)
#define DECLARE_XTOXLL(func) \
static inline uint64_t func##ll(uint64_t val) \
{ \
union { \
uint64_t whole; \
uint32_t halves[2]; \
} u; \
uint32_t t; \
u.whole = val; \
t = u.halves[0]; \
u.halves[0] = func##l(u.halves[1]); \
u.halves[1] = func##l(t); \
return u.whole; \
}
#elif defined(AMQP_BIG_ENDIAN)
#define DECLARE_XTOXLL(func) \
static inline uint64_t func##ll(uint64_t val) \
{ \
union { \
uint64_t whole; \
uint32_t halves[2]; \
} u; \
u.whole = val; \
u.halves[0] = func##l(u.halves[0]); \
u.halves[1] = func##l(u.halves[1]); \
return u.whole; \
}
#else
# error Endianness not known
#endif
#ifndef HAVE_HTONLL
DECLARE_XTOXLL(hton)
DECLARE_XTOXLL(ntoh)
#endif
DECLARE_CODEC_BASE_TYPE(8, (uint8_t), (uint8_t))
DECLARE_CODEC_BASE_TYPE(16, htons, ntohs)
DECLARE_CODEC_BASE_TYPE(32, htonl, ntohl)
DECLARE_CODEC_BASE_TYPE(64, htonll, ntohll)
static inline int amqp_encode_bytes(amqp_bytes_t encoded, size_t *offset,
amqp_bytes_t input)
{
size_t o = *offset;
if ((*offset = o + input.len) <= encoded.len) {
memcpy(amqp_offset(encoded.bytes, o), input.bytes, input.len);
return 1;
} else {
return 0;
}
}
static inline int amqp_decode_bytes(amqp_bytes_t encoded, size_t *offset,
amqp_bytes_t *output, size_t len)
{
size_t o = *offset;
if ((*offset = o + len) <= encoded.len) {
output->bytes = amqp_offset(encoded.bytes, o);
output->len = len;
return 1;
} else {
return 0;
}
}
AMQP_NORETURN
void
amqp_abort(const char *fmt, ...);
int amqp_bytes_equal(amqp_bytes_t r, amqp_bytes_t l);
static inline amqp_rpc_reply_t amqp_rpc_reply_error(amqp_status_enum status) {
amqp_rpc_reply_t reply;
reply.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
reply.library_error = status;
return reply;
}
int amqp_send_frame_inner(amqp_connection_state_t state,
const amqp_frame_t *frame, int flags);
#endif
rabbitmq-c-0.8.0/librabbitmq/amqp_socket.c 0000664 0000000 0000000 00000117004 12702357234 0020512 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2014
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _MSC_VER
# define _CRT_SECURE_NO_WARNINGS
#endif
#include "amqp_private.h"
#include "amqp_socket.h"
#include "amqp_table.h"
#include "amqp_time.h"
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include
# include
#else
# include /* On older BSD this must come before net includes */
# include
# include
# ifdef HAVE_SELECT
# include
# endif
# include
# include
# include
# include
# ifdef HAVE_POLL
# include
# endif
# include
#endif
static int amqp_id_in_reply_list( amqp_method_number_t expected, amqp_method_number_t *list );
static int
amqp_os_socket_init(void)
{
#ifdef _WIN32
static int called_wsastartup = 0;
if (!called_wsastartup) {
WSADATA data;
int res = WSAStartup(0x0202, &data);
if (res) {
return AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR;
}
called_wsastartup = 1;
}
return AMQP_STATUS_OK;
#else
return AMQP_STATUS_OK;
#endif
}
static int
amqp_os_socket_socket(int domain, int type, int protocol)
{
#ifdef _WIN32
/*
This cast is to squash warnings on Win64, see:
http://stackoverflow.com/questions/1953639/is-it-safe-to-cast-socket-to-int-under-win64
*/
return (int)socket(domain, type, protocol);
#else
int flags;
int s = socket(domain, type, protocol);
if (s < 0) {
return s;
}
/* Always enable CLOEXEC on the socket */
flags = fcntl(s, F_GETFD);
if (flags == -1
|| fcntl(s, F_SETFD, (long)(flags | FD_CLOEXEC)) == -1) {
int e = errno;
close(s);
errno = e;
return -1;
}
return s;
#endif
}
static int
amqp_os_socket_setsockopt(int sock, int level, int optname,
const void *optval, size_t optlen)
{
#ifdef _WIN32
/* the winsock setsockopt function has its 4th argument as a
const char * */
return setsockopt(sock, level, optname, (const char *)optval, (int)optlen);
#else
return setsockopt(sock, level, optname, optval, optlen);
#endif
}
static int
amqp_os_socket_setsockblock(int sock, int block)
{
#ifdef _WIN32
u_long nonblock = !block;
if (NO_ERROR != ioctlsocket(sock, FIONBIO, &nonblock)) {
return AMQP_STATUS_SOCKET_ERROR;
} else {
return AMQP_STATUS_OK;
}
#else
long arg;
if ((arg = fcntl(sock, F_GETFL, NULL)) < 0) {
return AMQP_STATUS_SOCKET_ERROR;
}
if (block) {
arg &= (~O_NONBLOCK);
} else {
arg |= O_NONBLOCK;
}
if (fcntl(sock, F_SETFL, arg) < 0) {
return AMQP_STATUS_SOCKET_ERROR;
}
return AMQP_STATUS_OK;
#endif
}
int
amqp_os_socket_error(void)
{
#ifdef _WIN32
return WSAGetLastError();
#else
return errno;
#endif
}
int
amqp_os_socket_close(int sockfd)
{
#ifdef _WIN32
return closesocket(sockfd);
#else
return close(sockfd);
#endif
}
ssize_t
amqp_socket_send(amqp_socket_t *self, const void *buf, size_t len, int flags)
{
assert(self);
assert(self->klass->send);
return self->klass->send(self, buf, len, flags);
}
ssize_t
amqp_socket_recv(amqp_socket_t *self, void *buf, size_t len, int flags)
{
assert(self);
assert(self->klass->recv);
return self->klass->recv(self, buf, len, flags);
}
int
amqp_socket_open(amqp_socket_t *self, const char *host, int port)
{
assert(self);
assert(self->klass->open);
return self->klass->open(self, host, port, NULL);
}
int
amqp_socket_open_noblock(amqp_socket_t *self, const char *host, int port, struct timeval *timeout)
{
assert(self);
assert(self->klass->open);
return self->klass->open(self, host, port, timeout);
}
int
amqp_socket_close(amqp_socket_t *self, amqp_socket_close_enum force)
{
assert(self);
assert(self->klass->close);
return self->klass->close(self, force);
}
void
amqp_socket_delete(amqp_socket_t *self)
{
if (self) {
assert(self->klass->delete);
self->klass->delete(self);
}
}
int
amqp_socket_get_sockfd(amqp_socket_t *self)
{
assert(self);
assert(self->klass->get_sockfd);
return self->klass->get_sockfd(self);
}
int amqp_poll(int fd, int event, amqp_time_t deadline) {
#ifdef HAVE_POLL
struct pollfd pfd;
int res;
int timeout_ms;
/* Function should only ever be called with one of these two */
assert(event == AMQP_SF_POLLIN || event == AMQP_SF_POLLOUT);
start_poll:
pfd.fd = fd;
switch (event) {
case AMQP_SF_POLLIN:
pfd.events = POLLIN;
break;
case AMQP_SF_POLLOUT:
pfd.events = POLLOUT;
break;
}
timeout_ms = amqp_time_ms_until(deadline);
if (-1 > timeout_ms) {
return timeout_ms;
}
res = poll(&pfd, 1, timeout_ms);
if (0 < res) {
/* TODO: optimize this a bit by returning the AMQP_STATUS_SOCKET_ERROR or
* equivalent when pdf.revent is POLLHUP or POLLERR, so an extra syscall
* doesn't need to be made. */
return AMQP_STATUS_OK;
} else if (0 == res) {
return AMQP_STATUS_TIMEOUT;
} else {
switch (amqp_os_socket_error()) {
case EINTR:
goto start_poll;
default:
return AMQP_STATUS_SOCKET_ERROR;
}
}
return AMQP_STATUS_OK;
#elif defined(HAVE_SELECT)
fd_set fds;
fd_set exceptfds;
fd_set *exceptfdsp;
int res;
struct timeval tv;
struct timeval *tvp;
assert((0 != (event & AMQP_SF_POLLIN)) || (0 != (event & AMQP_SF_POLLOUT)));
#ifndef _WIN32
/* On Win32 connect() failure is indicated through the exceptfds, it does not
* make any sense to allow POLLERR on any other platform or condition */
assert(0 == (event & AMQP_SF_POLLERR));
#endif
start_select:
FD_ZERO(&fds);
FD_SET(fd, &fds);
if (event & AMQP_SF_POLLERR) {
FD_ZERO(&exceptfds);
FD_SET(fd, &exceptfds);
exceptfdsp = &exceptfds;
} else {
exceptfdsp = NULL;
}
res = amqp_time_tv_until(deadline, &tv, &tvp);
if (res != AMQP_STATUS_OK) {
return res;
}
if (event & AMQP_SF_POLLIN) {
res = select(fd + 1, &fds, NULL, exceptfdsp, tvp);
} else if (event & AMQP_SF_POLLOUT) {
res = select(fd + 1, NULL, &fds, exceptfdsp, tvp);
}
if (0 < res) {
return AMQP_STATUS_OK;
} else if (0 == res) {
return AMQP_STATUS_TIMEOUT;
} else {
switch (amqp_os_socket_error()) {
case EINTR:
goto start_select;
default:
return AMQP_STATUS_SOCKET_ERROR;
}
}
#else
# error "poll() or select() is needed to compile rabbitmq-c"
#endif
}
static ssize_t do_poll(amqp_connection_state_t state, ssize_t res,
amqp_time_t deadline) {
int fd = amqp_get_sockfd(state);
if (-1 == fd) {
return AMQP_STATUS_SOCKET_CLOSED;
}
switch (res) {
case AMQP_PRIVATE_STATUS_SOCKET_NEEDREAD:
res = amqp_poll(fd, AMQP_SF_POLLIN, deadline);
break;
case AMQP_PRIVATE_STATUS_SOCKET_NEEDWRITE:
res = amqp_poll(fd, AMQP_SF_POLLOUT, deadline);
break;
}
return res;
}
ssize_t amqp_try_send(amqp_connection_state_t state, const void *buf,
size_t len, amqp_time_t deadline, int flags) {
ssize_t res;
void* buf_left = (void*)buf;
/* Assume that len is not going to be larger than ssize_t can hold. */
ssize_t len_left = (size_t)len;
start_send:
res = amqp_socket_send(state->socket, buf_left, len_left, flags);
if (res > 0) {
len_left -= res;
buf_left = (char*)buf_left + res;
if (0 == len_left) {
return (ssize_t)len;
}
goto start_send;
}
res = do_poll(state, res, deadline);
if (AMQP_STATUS_OK == res) {
goto start_send;
}
if (AMQP_STATUS_TIMEOUT == res) {
return (ssize_t)len - len_left;
}
return res;
}
int
amqp_open_socket(char const *hostname,
int portnumber)
{
return amqp_open_socket_inner(hostname, portnumber,
amqp_time_infinite());
}
int amqp_open_socket_noblock(char const *hostname,
int portnumber,
struct timeval *timeout)
{
amqp_time_t deadline;
int res = amqp_time_from_now(&deadline, timeout);
if (AMQP_STATUS_OK != res) {
return res;
}
return amqp_open_socket_inner(hostname, portnumber, deadline);
}
int amqp_open_socket_inner(char const *hostname,
int portnumber,
amqp_time_t deadline) {
struct addrinfo hint;
struct addrinfo *address_list;
struct addrinfo *addr;
char portnumber_string[33];
int sockfd = -1;
int last_error;
int one = 1; /* for setsockopt */
int res;
last_error = amqp_os_socket_init();
if (AMQP_STATUS_OK != last_error) {
return last_error;
}
memset(&hint, 0, sizeof(hint));
hint.ai_family = PF_UNSPEC; /* PF_INET or PF_INET6 */
hint.ai_socktype = SOCK_STREAM;
hint.ai_protocol = IPPROTO_TCP;
(void)sprintf(portnumber_string, "%d", portnumber);
last_error = getaddrinfo(hostname, portnumber_string, &hint, &address_list);
if (0 != last_error) {
return AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED;
}
for (addr = address_list; addr; addr = addr->ai_next) {
if (-1 != sockfd) {
amqp_os_socket_close(sockfd);
}
sockfd = amqp_os_socket_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (-1 == sockfd) {
last_error = AMQP_STATUS_SOCKET_ERROR;
continue;
}
#ifdef SO_NOSIGPIPE
if (0 != amqp_os_socket_setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one))) {
last_error = AMQP_STATUS_SOCKET_ERROR;
continue;
}
#endif /* SO_NOSIGPIPE */
if (0 != amqp_os_socket_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one))) {
last_error = AMQP_STATUS_SOCKET_ERROR;
continue;
}
if (AMQP_STATUS_OK != amqp_os_socket_setsockblock(sockfd, 0)) {
last_error = AMQP_STATUS_SOCKET_ERROR;
continue;
}
#ifdef _WIN32
res = connect(sockfd, addr->ai_addr, (int)addr->ai_addrlen);
#else
res = connect(sockfd, addr->ai_addr, addr->ai_addrlen);
#endif
if (0 == res) {
last_error = AMQP_STATUS_OK;
break;
}
#ifdef _WIN32
if (WSAEWOULDBLOCK == amqp_os_socket_error()) {
int event = AMQP_SF_POLLOUT | AMQP_SF_POLLERR;
#else
if (EINPROGRESS == amqp_os_socket_error()) {
int event = AMQP_SF_POLLOUT;
#endif
last_error = amqp_poll(sockfd, event, deadline);
if (AMQP_STATUS_OK == last_error) {
int result;
socklen_t result_len = sizeof(result);
#ifdef _WIN32
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *)&result,
(int *)&result_len) < 0
#else
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &result, &result_len) < 0
#endif
|| result != 0) {
last_error = AMQP_STATUS_SOCKET_ERROR;
} else {
last_error = AMQP_STATUS_OK;
}
}
if (last_error == AMQP_STATUS_OK || last_error == AMQP_STATUS_TIMEOUT ||
last_error == AMQP_STATUS_TIMER_FAILURE) {
/* Exit for loop on timer errors or when connection established */
break;
}
} else {
/* Error connecting */
last_error = AMQP_STATUS_SOCKET_ERROR;
break;
}
}
freeaddrinfo(address_list);
if (last_error != AMQP_STATUS_OK) {
if (-1 != sockfd) {
amqp_os_socket_close(sockfd);
}
return last_error;
}
return sockfd;
}
int amqp_send_header(amqp_connection_state_t state)
{
ssize_t res;
static const uint8_t header[8] = { 'A', 'M', 'Q', 'P', 0,
AMQP_PROTOCOL_VERSION_MAJOR,
AMQP_PROTOCOL_VERSION_MINOR,
AMQP_PROTOCOL_VERSION_REVISION
};
res = amqp_try_send(state, header, sizeof(header), amqp_time_infinite(),
AMQP_SF_NONE);
if (sizeof(header) == res) {
return AMQP_STATUS_OK;
}
return (int)res;
}
static amqp_bytes_t sasl_method_name(amqp_sasl_method_enum method)
{
amqp_bytes_t res;
switch (method) {
case AMQP_SASL_METHOD_PLAIN:
res = amqp_cstring_bytes("PLAIN");
break;
case AMQP_SASL_METHOD_EXTERNAL:
res = amqp_cstring_bytes("EXTERNAL");
break;
default:
amqp_abort("Invalid SASL method: %d", (int) method);
}
return res;
}
static int bytes_equal(amqp_bytes_t l, amqp_bytes_t r)
{
if (l.len == r.len) {
if (l.bytes && r.bytes) {
if (0 == memcmp(l.bytes, r.bytes, l.len)) {
return 1;
}
}
}
return 0;
}
int sasl_mechanism_in_list(amqp_bytes_t mechanisms,
amqp_sasl_method_enum method)
{
amqp_bytes_t mechanism;
amqp_bytes_t supported_mechanism;
uint8_t* start;
uint8_t* end;
uint8_t* current;
assert(NULL != mechanisms.bytes);
mechanism = sasl_method_name(method);
start = (uint8_t*)mechanisms.bytes;
current = start;
end = start + mechanisms.len;
for ( ; current != end; start = current + 1) {
/* HACK: SASL states that we should be parsing this string as a UTF-8
* string, which we're plainly not doing here. At this point its not worth
* dragging an entire UTF-8 parser for this one case, and this should work
* most of the time */
current = memchr(start, ' ', end - start);
if (NULL == current) {
current = end;
}
supported_mechanism.bytes = start;
supported_mechanism.len = current - start;
if (bytes_equal(mechanism, supported_mechanism)) {
return 1;
}
}
return 0;
}
static amqp_bytes_t sasl_response(amqp_pool_t *pool,
amqp_sasl_method_enum method,
va_list args)
{
amqp_bytes_t response;
switch (method) {
case AMQP_SASL_METHOD_PLAIN: {
char *username = va_arg(args, char *);
size_t username_len = strlen(username);
char *password = va_arg(args, char *);
size_t password_len = strlen(password);
char *response_buf;
amqp_pool_alloc_bytes(pool, strlen(username) + strlen(password) + 2, &response);
if (response.bytes == NULL)
/* We never request a zero-length block, because of the +2
above, so a NULL here really is ENOMEM. */
{
return response;
}
response_buf = response.bytes;
response_buf[0] = 0;
memcpy(response_buf + 1, username, username_len);
response_buf[username_len + 1] = 0;
memcpy(response_buf + username_len + 2, password, password_len);
break;
}
case AMQP_SASL_METHOD_EXTERNAL: {
char *identity = va_arg(args, char *);
size_t identity_len = strlen(identity);
amqp_pool_alloc_bytes(pool, identity_len, &response);
if (response.bytes == NULL) {
return response;
}
memcpy(response.bytes, identity, identity_len);
break;
}
default:
amqp_abort("Invalid SASL method: %d", (int) method);
}
return response;
}
amqp_boolean_t amqp_frames_enqueued(amqp_connection_state_t state)
{
return (state->first_queued_frame != NULL);
}
/*
* Check to see if we have data in our buffer. If this returns 1, we
* will avoid an immediate blocking read in amqp_simple_wait_frame.
*/
amqp_boolean_t amqp_data_in_buffer(amqp_connection_state_t state)
{
return (state->sock_inbound_offset < state->sock_inbound_limit);
}
static int consume_one_frame(amqp_connection_state_t state, amqp_frame_t *decoded_frame)
{
int res;
amqp_bytes_t buffer;
buffer.len = state->sock_inbound_limit - state->sock_inbound_offset;
buffer.bytes = ((char *) state->sock_inbound_buffer.bytes) + state->sock_inbound_offset;
res = amqp_handle_input(state, buffer, decoded_frame);
if (res < 0) {
return res;
}
state->sock_inbound_offset += res;
return AMQP_STATUS_OK;
}
static int recv_with_timeout(amqp_connection_state_t state, amqp_time_t timeout) {
ssize_t res;
int fd;
start_recv:
res = amqp_socket_recv(state->socket, state->sock_inbound_buffer.bytes,
state->sock_inbound_buffer.len, 0);
if (res < 0) {
fd = amqp_get_sockfd(state);
if (-1 == fd) {
return AMQP_STATUS_CONNECTION_CLOSED;
}
switch (res) {
default:
return (int)res;
case AMQP_PRIVATE_STATUS_SOCKET_NEEDREAD:
res = amqp_poll(fd, AMQP_SF_POLLIN, timeout);
break;
case AMQP_PRIVATE_STATUS_SOCKET_NEEDWRITE:
res = amqp_poll(fd, AMQP_SF_POLLOUT, timeout);
break;
}
if (AMQP_STATUS_OK == res) {
goto start_recv;
}
return (int)res;
}
state->sock_inbound_limit = res;
state->sock_inbound_offset = 0;
res = amqp_time_s_from_now(&state->next_recv_heartbeat,
amqp_heartbeat_recv(state));
if (AMQP_STATUS_OK != res) {
return (int)res;
}
return AMQP_STATUS_OK;
}
int amqp_try_recv(amqp_connection_state_t state) {
amqp_time_t timeout;
while (amqp_data_in_buffer(state)) {
amqp_frame_t frame;
int res = consume_one_frame(state, &frame);
if (AMQP_STATUS_OK != res) {
return res;
}
if (frame.frame_type != 0) {
amqp_pool_t *channel_pool;
amqp_frame_t *frame_copy;
amqp_link_t *link;
channel_pool = amqp_get_or_create_channel_pool(state, frame.channel);
if (NULL == channel_pool) {
return AMQP_STATUS_NO_MEMORY;
}
frame_copy = amqp_pool_alloc(channel_pool, sizeof(amqp_frame_t));
link = amqp_pool_alloc(channel_pool, sizeof(amqp_link_t));
if (frame_copy == NULL || link == NULL) {
return AMQP_STATUS_NO_MEMORY;
}
*frame_copy = frame;
link->next = NULL;
link->data = frame_copy;
if (state->last_queued_frame == NULL) {
state->first_queued_frame = link;
} else {
state->last_queued_frame->next = link;
}
state->last_queued_frame = link;
}
}
timeout = amqp_time_immediate();
return recv_with_timeout(state, timeout);
}
static int wait_frame_inner(amqp_connection_state_t state,
amqp_frame_t *decoded_frame,
struct timeval *timeout)
{
amqp_time_t deadline;
amqp_time_t timeout_deadline;
int res;
res = amqp_time_from_now(&timeout_deadline, timeout);
if (AMQP_STATUS_OK != res) {
return res;
}
for (;;) {
while (amqp_data_in_buffer(state)) {
res = consume_one_frame(state, decoded_frame);
if (AMQP_STATUS_OK != res) {
return res;
}
if (AMQP_FRAME_HEARTBEAT == decoded_frame->frame_type) {
amqp_maybe_release_buffers_on_channel(state, 0);
continue;
}
if (decoded_frame->frame_type != 0) {
/* Complete frame was read. Return it. */
return AMQP_STATUS_OK;
}
}
beginrecv:
res = amqp_time_has_past(state->next_send_heartbeat);
if (AMQP_STATUS_TIMER_FAILURE == res) {
return res;
} else if (AMQP_STATUS_TIMEOUT == res) {
amqp_frame_t heartbeat;
heartbeat.channel = 0;
heartbeat.frame_type = AMQP_FRAME_HEARTBEAT;
res = amqp_send_frame(state, &heartbeat);
if (AMQP_STATUS_OK != res) {
return res;
}
}
deadline = amqp_time_first(timeout_deadline,
amqp_time_first(state->next_recv_heartbeat,
state->next_send_heartbeat));
/* TODO this needs to wait for a _frame_ and not anything written from the
* socket */
res = recv_with_timeout(state, deadline);
if (AMQP_STATUS_TIMEOUT == res) {
if (amqp_time_equal(deadline, state->next_recv_heartbeat)) {
amqp_socket_close(state->socket, AMQP_SC_FORCE);
return AMQP_STATUS_HEARTBEAT_TIMEOUT;
} else if (amqp_time_equal(deadline, timeout_deadline)) {
return AMQP_STATUS_TIMEOUT;
} else if (amqp_time_equal(deadline, state->next_send_heartbeat)) {
/* send heartbeat happens before we do recv_with_timeout */
goto beginrecv;
} else {
amqp_abort("Internal error: unable to determine timeout reason");
}
} else if (AMQP_STATUS_OK != res) {
return res;
}
}
}
static amqp_link_t * amqp_create_link_for_frame(amqp_connection_state_t state, amqp_frame_t *frame)
{
amqp_link_t *link;
amqp_frame_t *frame_copy;
amqp_pool_t *channel_pool = amqp_get_or_create_channel_pool(state, frame->channel);
if (NULL == channel_pool) {
return NULL;
}
link = amqp_pool_alloc(channel_pool, sizeof(amqp_link_t));
frame_copy = amqp_pool_alloc(channel_pool, sizeof(amqp_frame_t));
if (NULL == link || NULL == frame_copy) {
return NULL;
}
*frame_copy = *frame;
link->data = frame_copy;
return link;
}
int amqp_queue_frame(amqp_connection_state_t state, amqp_frame_t *frame)
{
amqp_link_t *link = amqp_create_link_for_frame(state, frame);
if (NULL == link) {
return AMQP_STATUS_NO_MEMORY;
}
if (NULL == state->first_queued_frame) {
state->first_queued_frame = link;
} else {
state->last_queued_frame->next = link;
}
link->next = NULL;
state->last_queued_frame = link;
return AMQP_STATUS_OK;
}
int amqp_put_back_frame(amqp_connection_state_t state, amqp_frame_t *frame)
{
amqp_link_t *link = amqp_create_link_for_frame(state, frame);
if (NULL == link) {
return AMQP_STATUS_NO_MEMORY;
}
if (NULL == state->first_queued_frame) {
state->first_queued_frame = link;
state->last_queued_frame = link;
link->next = NULL;
} else {
link->next = state->first_queued_frame;
state->first_queued_frame = link;
}
return AMQP_STATUS_OK;
}
int amqp_simple_wait_frame_on_channel(amqp_connection_state_t state,
amqp_channel_t channel,
amqp_frame_t *decoded_frame)
{
amqp_frame_t *frame_ptr;
amqp_link_t *cur;
int res;
for (cur = state->first_queued_frame; NULL != cur; cur = cur->next) {
frame_ptr = cur->data;
if (channel == frame_ptr->channel) {
state->first_queued_frame = cur->next;
if (NULL == state->first_queued_frame) {
state->last_queued_frame = NULL;
}
*decoded_frame = *frame_ptr;
return AMQP_STATUS_OK;
}
}
for (;;) {
res = wait_frame_inner(state, decoded_frame, NULL);
if (AMQP_STATUS_OK != res) {
return res;
}
if (channel == decoded_frame->channel) {
return AMQP_STATUS_OK;
} else {
res = amqp_queue_frame(state, decoded_frame);
if (res != AMQP_STATUS_OK) {
return res;
}
}
}
}
int amqp_simple_wait_frame(amqp_connection_state_t state,
amqp_frame_t *decoded_frame)
{
return amqp_simple_wait_frame_noblock(state, decoded_frame, NULL);
}
int amqp_simple_wait_frame_noblock(amqp_connection_state_t state,
amqp_frame_t *decoded_frame,
struct timeval *timeout)
{
if (state->first_queued_frame != NULL) {
amqp_frame_t *f = (amqp_frame_t *) state->first_queued_frame->data;
state->first_queued_frame = state->first_queued_frame->next;
if (state->first_queued_frame == NULL) {
state->last_queued_frame = NULL;
}
*decoded_frame = *f;
return AMQP_STATUS_OK;
} else {
return wait_frame_inner(state, decoded_frame, timeout);
}
}
static int amqp_simple_wait_method_list(amqp_connection_state_t state,
amqp_channel_t expected_channel,
amqp_method_number_t *expected_methods,
amqp_method_t *output) {
amqp_frame_t frame;
int res = amqp_simple_wait_frame(state, &frame);
if (AMQP_STATUS_OK != res) {
return res;
}
if (AMQP_FRAME_METHOD != frame.frame_type ||
expected_channel != frame.channel ||
!amqp_id_in_reply_list(frame.payload.method.id, expected_methods)) {
return AMQP_STATUS_WRONG_METHOD;
}
*output = frame.payload.method;
return AMQP_STATUS_OK;
}
int amqp_simple_wait_method(amqp_connection_state_t state,
amqp_channel_t expected_channel,
amqp_method_number_t expected_method,
amqp_method_t *output)
{
amqp_method_number_t expected_methods[] = { 0, 0 };
expected_methods[0] = expected_method;
return amqp_simple_wait_method_list(state, expected_channel, expected_methods,
output);
}
int amqp_send_method(amqp_connection_state_t state, amqp_channel_t channel,
amqp_method_number_t id, void *decoded) {
return amqp_send_method_inner(state, channel, id, decoded, AMQP_SF_NONE);
}
int amqp_send_method_inner(amqp_connection_state_t state,
amqp_channel_t channel, amqp_method_number_t id,
void *decoded, int flags) {
amqp_frame_t frame;
frame.frame_type = AMQP_FRAME_METHOD;
frame.channel = channel;
frame.payload.method.id = id;
frame.payload.method.decoded = decoded;
return amqp_send_frame_inner(state, &frame, flags);
}
static int amqp_id_in_reply_list( amqp_method_number_t expected, amqp_method_number_t *list )
{
while ( *list != 0 ) {
if ( *list == expected ) {
return 1;
}
list++;
}
return 0;
}
amqp_rpc_reply_t amqp_simple_rpc(amqp_connection_state_t state,
amqp_channel_t channel,
amqp_method_number_t request_id,
amqp_method_number_t *expected_reply_ids,
void *decoded_request_method)
{
int status;
amqp_rpc_reply_t result;
memset(&result, 0, sizeof(result));
status = amqp_send_method(state, channel, request_id, decoded_request_method);
if (status < 0) {
result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
result.library_error = status;
return result;
}
{
amqp_frame_t frame;
retry:
status = wait_frame_inner(state, &frame, NULL);
if (status < 0) {
result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
result.library_error = status;
return result;
}
/*
* We store the frame for later processing unless it's something
* that directly affects us here, namely a method frame that is
* either
* - on the channel we want, and of the expected type, or
* - on the channel we want, and a channel.close frame, or
* - on channel zero, and a connection.close frame.
*/
if (!((frame.frame_type == AMQP_FRAME_METHOD)
&& (
((frame.channel == channel)
&& (amqp_id_in_reply_list(frame.payload.method.id, expected_reply_ids)
|| (frame.payload.method.id == AMQP_CHANNEL_CLOSE_METHOD)))
||
((frame.channel == 0)
&& (frame.payload.method.id == AMQP_CONNECTION_CLOSE_METHOD))
)
)) {
amqp_pool_t *channel_pool;
amqp_frame_t *frame_copy;
amqp_link_t *link;
channel_pool = amqp_get_or_create_channel_pool(state, frame.channel);
if (NULL == channel_pool) {
result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
result.library_error = AMQP_STATUS_NO_MEMORY;
return result;
}
frame_copy = amqp_pool_alloc(channel_pool, sizeof(amqp_frame_t));
link = amqp_pool_alloc(channel_pool, sizeof(amqp_link_t));
if (frame_copy == NULL || link == NULL) {
result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
result.library_error = AMQP_STATUS_NO_MEMORY;
return result;
}
*frame_copy = frame;
link->next = NULL;
link->data = frame_copy;
if (state->last_queued_frame == NULL) {
state->first_queued_frame = link;
} else {
state->last_queued_frame->next = link;
}
state->last_queued_frame = link;
goto retry;
}
result.reply_type = (amqp_id_in_reply_list(frame.payload.method.id, expected_reply_ids))
? AMQP_RESPONSE_NORMAL
: AMQP_RESPONSE_SERVER_EXCEPTION;
result.reply = frame.payload.method;
return result;
}
}
void *amqp_simple_rpc_decoded(amqp_connection_state_t state,
amqp_channel_t channel,
amqp_method_number_t request_id,
amqp_method_number_t reply_id,
void *decoded_request_method)
{
amqp_method_number_t replies[2];
replies[0] = reply_id;
replies[1] = 0;
state->most_recent_api_result = amqp_simple_rpc(state, channel,
request_id, replies,
decoded_request_method);
if (state->most_recent_api_result.reply_type == AMQP_RESPONSE_NORMAL) {
return state->most_recent_api_result.reply.decoded;
} else {
return NULL;
}
}
amqp_rpc_reply_t amqp_get_rpc_reply(amqp_connection_state_t state)
{
return state->most_recent_api_result;
}
/*
* Merge base and add tables. If the two tables contain an entry with the same
* key, the entry from the add table takes precedence. For entries that are both
* tables with the same key, the table is recursively merged.
*/
int amqp_merge_capabilities(const amqp_table_t *base, const amqp_table_t *add,
amqp_table_t *result, amqp_pool_t *pool) {
int i;
int res;
amqp_pool_t temp_pool;
amqp_table_t temp_result;
assert(base != NULL);
assert(result != NULL);
assert(pool != NULL);
if (NULL == add) {
return amqp_table_clone(base, result, pool);
}
init_amqp_pool(&temp_pool, 4096);
temp_result.num_entries = 0;
temp_result.entries =
amqp_pool_alloc(&temp_pool, sizeof(amqp_table_entry_t) *
(base->num_entries + add->num_entries));
if (NULL == temp_result.entries) {
res = AMQP_STATUS_NO_MEMORY;
goto error_out;
}
for (i = 0; i < base->num_entries; ++i) {
temp_result.entries[temp_result.num_entries] = base->entries[i];
temp_result.num_entries++;
}
for (i = 0; i < add->num_entries; ++i) {
amqp_table_entry_t *e =
amqp_table_get_entry_by_key(&temp_result, add->entries[i].key);
if (NULL != e) {
if (AMQP_FIELD_KIND_TABLE == add->entries[i].value.kind &&
AMQP_FIELD_KIND_TABLE == e->value.kind) {
amqp_table_entry_t *be =
amqp_table_get_entry_by_key(base, add->entries[i].key);
res = amqp_merge_capabilities(&be->value.value.table,
&add->entries[i].value.value.table,
&e->value.value.table, &temp_pool);
if (AMQP_STATUS_OK != res) {
goto error_out;
}
} else {
e->value = add->entries[i].value;
}
} else {
temp_result.entries[temp_result.num_entries] = add->entries[i];
temp_result.num_entries++;
}
}
res = amqp_table_clone(&temp_result, result, pool);
error_out:
empty_amqp_pool(&temp_pool);
return res;
}
static amqp_rpc_reply_t amqp_login_inner(amqp_connection_state_t state,
char const *vhost,
int channel_max,
int frame_max,
int heartbeat,
const amqp_table_t *client_properties,
amqp_sasl_method_enum sasl_method,
va_list vl)
{
int res;
amqp_method_t method;
uint16_t client_channel_max;
uint32_t client_frame_max;
uint16_t client_heartbeat;
uint16_t server_channel_max;
uint32_t server_frame_max;
uint16_t server_heartbeat;
amqp_rpc_reply_t result;
if (channel_max < 0 || channel_max > UINT16_MAX) {
return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER);
}
client_channel_max = (uint16_t)channel_max;
if (frame_max < 0) {
return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER);
}
client_frame_max = (uint32_t)frame_max;
if (heartbeat < 0 || heartbeat > UINT16_MAX) {
return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER);
}
client_heartbeat = (uint16_t)heartbeat;
res = amqp_send_header(state);
if (AMQP_STATUS_OK != res) {
goto error_res;
}
res = amqp_simple_wait_method(state, 0, AMQP_CONNECTION_START_METHOD,
&method);
if (res != AMQP_STATUS_OK) {
goto error_res;
}
{
amqp_connection_start_t *s = (amqp_connection_start_t *) method.decoded;
if ((s->version_major != AMQP_PROTOCOL_VERSION_MAJOR)
|| (s->version_minor != AMQP_PROTOCOL_VERSION_MINOR)) {
res = AMQP_STATUS_INCOMPATIBLE_AMQP_VERSION;
goto error_res;
}
res = amqp_table_clone(&s->server_properties, &state->server_properties,
&state->properties_pool);
if (AMQP_STATUS_OK != res) {
goto error_res;
}
/* TODO: check that our chosen SASL mechanism is in the list of
acceptable mechanisms. Or even let the application choose from
the list! */
if (!sasl_mechanism_in_list(s->mechanisms, sasl_method)) {
res = AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD;
goto error_res;
}
}
{
amqp_table_entry_t default_properties[6];
amqp_table_t default_table;
amqp_table_entry_t client_capabilities[1];
amqp_table_t client_capabilities_table;
amqp_connection_start_ok_t s;
amqp_pool_t *channel_pool;
amqp_bytes_t response_bytes;
channel_pool = amqp_get_or_create_channel_pool(state, 0);
if (NULL == channel_pool) {
res = AMQP_STATUS_NO_MEMORY;
goto error_res;
}
response_bytes = sasl_response(channel_pool,
sasl_method, vl);
if (response_bytes.bytes == NULL) {
res = AMQP_STATUS_NO_MEMORY;
goto error_res;
}
client_capabilities[0] =
amqp_table_construct_bool_entry("authentication_failure_close", 1);
client_capabilities_table.entries = client_capabilities;
client_capabilities_table.num_entries =
sizeof(client_capabilities) / sizeof(amqp_table_entry_t);
default_properties[0] =
amqp_table_construct_utf8_entry("product", "rabbitmq-c");
default_properties[1] =
amqp_table_construct_utf8_entry("version", AMQP_VERSION_STRING);
default_properties[2] =
amqp_table_construct_utf8_entry("platform", AMQ_PLATFORM);
default_properties[3] =
amqp_table_construct_utf8_entry("copyright", AMQ_COPYRIGHT);
default_properties[4] = amqp_table_construct_utf8_entry(
"information", "See https://github.com/alanxz/rabbitmq-c");
default_properties[5] = amqp_table_construct_table_entry(
"capabilities", &client_capabilities_table);
default_table.entries = default_properties;
default_table.num_entries =
sizeof(default_properties) / sizeof(amqp_table_entry_t);
res = amqp_merge_capabilities(&default_table, client_properties,
&state->client_properties, channel_pool);
if (AMQP_STATUS_OK != res) {
goto error_res;
}
s.client_properties = state->client_properties;
s.mechanism = sasl_method_name(sasl_method);
s.response = response_bytes;
s.locale = amqp_cstring_bytes("en_US");
res = amqp_send_method(state, 0, AMQP_CONNECTION_START_OK_METHOD, &s);
if (res < 0) {
goto error_res;
}
}
amqp_release_buffers(state);
{
amqp_method_number_t expected[] = { AMQP_CONNECTION_TUNE_METHOD,
AMQP_CONNECTION_CLOSE_METHOD, 0 };
res = amqp_simple_wait_method_list(state, 0, expected, &method);
if (AMQP_STATUS_OK != res) {
goto error_res;
}
}
if (AMQP_CONNECTION_CLOSE_METHOD == method.id) {
result.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION;
result.reply = method;
result.library_error = 0;
goto out;
}
{
amqp_connection_tune_t *s = (amqp_connection_tune_t *) method.decoded;
server_channel_max = s->channel_max;
server_frame_max = s->frame_max;
server_heartbeat = s->heartbeat;
}
if (server_channel_max != 0 &&
(server_channel_max < client_channel_max || client_channel_max == 0)) {
client_channel_max = server_channel_max;
} else if (server_channel_max == 0 && client_channel_max == 0) {
client_channel_max = UINT16_MAX;
}
if (server_frame_max != 0 && server_frame_max < client_frame_max) {
client_frame_max = server_frame_max;
}
if (server_heartbeat != 0 && server_heartbeat < client_heartbeat) {
client_heartbeat = server_heartbeat;
}
res = amqp_tune_connection(state, client_channel_max, client_frame_max,
client_heartbeat);
if (res < 0) {
goto error_res;
}
{
amqp_connection_tune_ok_t s;
s.frame_max = client_frame_max;
s.channel_max = client_channel_max;
s.heartbeat = client_heartbeat;
res = amqp_send_method(state, 0, AMQP_CONNECTION_TUNE_OK_METHOD, &s);
if (res < 0) {
goto error_res;
}
}
amqp_release_buffers(state);
{
amqp_method_number_t replies[] = { AMQP_CONNECTION_OPEN_OK_METHOD, 0 };
amqp_connection_open_t s;
s.virtual_host = amqp_cstring_bytes(vhost);
s.capabilities.len = 0;
s.capabilities.bytes = NULL;
s.insist = 1;
result = amqp_simple_rpc(state,
0,
AMQP_CONNECTION_OPEN_METHOD,
replies,
&s);
if (result.reply_type != AMQP_RESPONSE_NORMAL) {
goto out;
}
}
result.reply_type = AMQP_RESPONSE_NORMAL;
result.reply.id = 0;
result.reply.decoded = NULL;
result.library_error = 0;
amqp_maybe_release_buffers(state);
out:
return result;
error_res:
result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
result.reply.id = 0;
result.reply.decoded = NULL;
result.library_error = res;
goto out;
}
amqp_rpc_reply_t amqp_login(amqp_connection_state_t state,
char const *vhost,
int channel_max,
int frame_max,
int heartbeat,
amqp_sasl_method_enum sasl_method,
...)
{
va_list vl;
amqp_rpc_reply_t ret;
va_start(vl, sasl_method);
ret = amqp_login_inner(state, vhost, channel_max, frame_max, heartbeat,
&amqp_empty_table, sasl_method, vl);
va_end(vl);
return ret;
}
amqp_rpc_reply_t amqp_login_with_properties(amqp_connection_state_t state,
char const *vhost,
int channel_max,
int frame_max,
int heartbeat,
const amqp_table_t *client_properties,
amqp_sasl_method_enum sasl_method,
...)
{
va_list vl;
amqp_rpc_reply_t ret;
va_start(vl, sasl_method);
ret = amqp_login_inner(state, vhost, channel_max, frame_max, heartbeat,
client_properties, sasl_method, vl);
va_end(vl);
return ret;
}
rabbitmq-c-0.8.0/librabbitmq/amqp_socket.h 0000664 0000000 0000000 00000014477 12702357234 0020531 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk.
* All Rights Reserved.
*
* Portions created by Michael Steinert are Copyright (c) 2012-2013 Michael
* Steinert. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* An abstract socket interface.
*/
#ifndef AMQP_SOCKET_H
#define AMQP_SOCKET_H
#include "amqp_private.h"
#include "amqp_time.h"
AMQP_BEGIN_DECLS
typedef enum {
AMQP_SF_NONE = 0,
AMQP_SF_MORE = 1,
AMQP_SF_POLLIN = 2,
AMQP_SF_POLLOUT = 4,
AMQP_SF_POLLERR = 8
} amqp_socket_flag_enum;
typedef enum {
AMQP_SC_NONE = 0,
AMQP_SC_FORCE = 1
} amqp_socket_close_enum;
int
amqp_os_socket_error(void);
int
amqp_os_socket_close(int sockfd);
/* Socket callbacks. */
typedef ssize_t (*amqp_socket_send_fn)(void *, const void *, size_t, int);
typedef ssize_t (*amqp_socket_recv_fn)(void *, void *, size_t, int);
typedef int (*amqp_socket_open_fn)(void *, const char *, int, struct timeval *);
typedef int (*amqp_socket_close_fn)(void *, amqp_socket_close_enum);
typedef int (*amqp_socket_get_sockfd_fn)(void *);
typedef void (*amqp_socket_delete_fn)(void *);
/** V-table for amqp_socket_t */
struct amqp_socket_class_t {
amqp_socket_send_fn send;
amqp_socket_recv_fn recv;
amqp_socket_open_fn open;
amqp_socket_close_fn close;
amqp_socket_get_sockfd_fn get_sockfd;
amqp_socket_delete_fn delete;
};
/** Abstract base class for amqp_socket_t */
struct amqp_socket_t_ {
const struct amqp_socket_class_t *klass;
};
/**
* Set set the socket object for a connection
*
* This assigns a socket object to the connection, closing and deleting any
* existing socket
*
* \param [in] state The connection object to add the socket to
* \param [in] socket The socket object to assign to the connection
*/
void
amqp_set_socket(amqp_connection_state_t state, amqp_socket_t *socket);
/**
* Send a message from a socket.
*
* This function wraps send(2) functionality.
*
* This function will only return on error, or when all of the bytes in buf
* have been sent, or when an error occurs.
*
* \param [in,out] self A socket object.
* \param [in] buf A buffer to read from.
* \param [in] len The number of bytes in \e buf.
* \param [in]
*
* \return AMQP_STATUS_OK on success. amqp_status_enum value otherwise
*/
ssize_t
amqp_socket_send(amqp_socket_t *self, const void *buf, size_t len, int flags);
ssize_t amqp_try_send(amqp_connection_state_t state, const void *buf,
size_t len, amqp_time_t deadline, int flags);
/**
* Receive a message from a socket.
*
* This function wraps recv(2) functionality.
*
* \param [in,out] self A socket object.
* \param [out] buf A buffer to write to.
* \param [in] len The number of bytes at \e buf.
* \param [in] flags Receive flags, implementation specific.
*
* \return The number of bytes received, or < 0 on error (\ref amqp_status_enum)
*/
ssize_t
amqp_socket_recv(amqp_socket_t *self, void *buf, size_t len, int flags);
/**
* Close a socket connection and free resources.
*
* This function closes a socket connection and releases any resources used by
* the object. After calling this function the specified socket should no
* longer be referenced.
*
* \param [in,out] self A socket object.
* \param [in] force, if set, just close the socket, don't attempt a TLS
* shutdown.
*
* \return Zero upon success, non-zero otherwise.
*/
int
amqp_socket_close(amqp_socket_t *self, amqp_socket_close_enum force);
/**
* Destroy a socket object
*
* \param [in] self the socket object to delete
*/
void
amqp_socket_delete(amqp_socket_t *self);
/**
* Open a socket connection.
*
* This function opens a socket connection returned from amqp_tcp_socket_new()
* or amqp_ssl_socket_new(). This function should be called after setting
* socket options and prior to assigning the socket to an AMQP connection with
* amqp_set_socket().
*
* \param [in] host Connect to this host.
* \param [in] port Connect on this remote port.
* \param [in] timeout Max allowed time to spent on opening. If NULL - run in blocking mode
*
* \return File descriptor upon success, non-zero negative error code otherwise.
*/
int
amqp_open_socket_noblock(char const *hostname, int portnumber, struct timeval *timeout);
int amqp_open_socket_inner(char const *hostname, int portnumber,
amqp_time_t deadline);
/* Wait up to dealline for fd to become readable or writeable depending on
* event (AMQP_SF_POLLIN, AMQP_SF_POLLOUT) */
int amqp_poll(int fd, int event, amqp_time_t deadline);
int amqp_send_method_inner(amqp_connection_state_t state,
amqp_channel_t channel, amqp_method_number_t id,
void *decoded, int flags);
int
amqp_queue_frame(amqp_connection_state_t state, amqp_frame_t *frame);
int
amqp_put_back_frame(amqp_connection_state_t state, amqp_frame_t *frame);
int
amqp_simple_wait_frame_on_channel(amqp_connection_state_t state,
amqp_channel_t channel,
amqp_frame_t *decoded_frame);
int
sasl_mechanism_in_list(amqp_bytes_t mechanisms, amqp_sasl_method_enum method);
int amqp_merge_capabilities(const amqp_table_t *base, const amqp_table_t *add,
amqp_table_t *result, amqp_pool_t *pool);
AMQP_END_DECLS
#endif /* AMQP_SOCKET_H */
rabbitmq-c-0.8.0/librabbitmq/amqp_ssl_socket.h 0000664 0000000 0000000 00000016112 12702357234 0021376 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/** \file */
/*
* Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk.
* All Rights Reserved.
*
* Portions created by Michael Steinert are Copyright (c) 2012-2013 Michael
* Steinert. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef AMQP_SSL_H
#define AMQP_SSL_H
#include
AMQP_BEGIN_DECLS
/**
* Create a new SSL/TLS socket object.
*
* The returned socket object is owned by the \ref amqp_connection_state_t object
* and will be destroyed when the state object is destroyed or a new socket
* object is created.
*
* If the socket object creation fails, the \ref amqp_connection_state_t object
* will not be changed.
*
* The object returned by this function can be retrieved from the
* amqp_connection_state_t object later using the amqp_get_socket() function.
*
* Calling this function may result in the underlying SSL library being initialized.
* \sa amqp_set_initialize_ssl_library()
*
* \param [in,out] state The connection object that owns the SSL/TLS socket
* \return A new socket object or NULL if an error occurred.
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
amqp_socket_t *
AMQP_CALL
amqp_ssl_socket_new(amqp_connection_state_t state);
/**
* Set the CA certificate.
*
* \param [in,out] self An SSL/TLS socket object.
* \param [in] cacert Path to the CA cert file in PEM format.
*
* \return \ref AMQP_STATUS_OK on success an \ref amqp_status_enum value on
* failure.
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL
amqp_ssl_socket_set_cacert(amqp_socket_t *self,
const char *cacert);
/**
* Set the client key.
*
* \param [in,out] self An SSL/TLS socket object.
* \param [in] cert Path to the client certificate in PEM foramt.
* \param [in] key Path to the client key in PEM format.
*
* \return \ref AMQP_STATUS_OK on success an \ref amqp_status_enum value on
* failure.
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL
amqp_ssl_socket_set_key(amqp_socket_t *self,
const char *cert,
const char *key);
/**
* Set the client key from a buffer.
*
* \param [in,out] self An SSL/TLS socket object.
* \param [in] cert Path to the client certificate in PEM foramt.
* \param [in] key A buffer containing client key in PEM format.
* \param [in] n The length of the buffer.
*
* \return \ref AMQP_STATUS_OK on success an \ref amqp_status_enum value on
* failure.
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL
amqp_ssl_socket_set_key_buffer(amqp_socket_t *self,
const char *cert,
const void *key,
size_t n);
/**
* Enable or disable peer verification.
*
* \deprecated use \amqp_ssl_socket_set_verify_peer and
* \amqp_ssl_socket_set_verify_hostname instead.
*
* If peer verification is enabled then the common name in the server
* certificate must match the server name. Peer verification is enabled by
* default.
*
* \param [in,out] self An SSL/TLS socket object.
* \param [in] verify Enable or disable peer verification.
*
* \since v0.4.0
*/
AMQP_DEPRECATED(
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL
amqp_ssl_socket_set_verify(amqp_socket_t *self, amqp_boolean_t verify)
);
/**
* Enable or disable peer verification.
*
* Peer verification validates the certificate chain that is sent by the broker.
* Hostname validation is controlled by \amqp_ssl_socket_set_verify_peer.
*
* \param [in,out] self An SSL/TLS socket object.
* \param [in] verify enable or disable peer validation
*
* \since v0.8.0
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL
amqp_ssl_socket_set_verify_peer(amqp_socket_t *self, amqp_boolean_t verify);
/**
* Enable or disable hostname verification.
*
* Hostname verification checks the broker cert for a CN or SAN that matches the
* hostname that amqp_socket_open() is presented. Peer verification is
* controlled by \amqp_ssl_socket_set_verify_peer
*
* \since v0.8.0
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL
amqp_ssl_socket_set_verify_hostname(amqp_socket_t *self, amqp_boolean_t verify);
typedef enum {
AMQP_TLSv1 = 1,
AMQP_TLSv1_1 = 2,
AMQP_TLSv1_2 = 3,
AMQP_TLSvLATEST = 0xFFFF
} amqp_tls_version_t;
/**
* Set min and max TLS versions.
*
* Set the oldest and newest acceptable TLS versions that are acceptable when
* connecting to the broker. Set min == max to restrict to just that
* version.
*
* \param [in,out] self An SSL/TLS socket object.
* \param [in] min the minimum acceptable TLS version
* \param [in] max the maxmium acceptable TLS version
* \returns AMQP_STATUS_OK on success, AMQP_STATUS_UNSUPPORTED if OpenSSL does
* not support the requested TLS version, AMQP_STATUS_INVALID_PARAMETER if an
* invalid combination of parameters is passed.
*
* \since v0.8.0
*/
AMQP_PUBLIC_FUNCTION
int
AMQP_CALL
amqp_ssl_socket_set_ssl_versions(amqp_socket_t *self,
amqp_tls_version_t min,
amqp_tls_version_t max);
/**
* Sets whether rabbitmq-c initializes the underlying SSL library.
*
* For SSL libraries that require a one-time initialization across
* a whole program (e.g., OpenSSL) this sets whether or not rabbitmq-c
* will initialize the SSL library when the first call to
* amqp_open_socket() is made. You should call this function with
* do_init = 0 if the underlying SSL library is initialized somewhere else
* the program.
*
* Failing to initialize or double initialization of the SSL library will
* result in undefined behavior
*
* By default rabbitmq-c will initialize the underlying SSL library
*
* NOTE: calling this function after the first socket has been opened with
* amqp_open_socket() will not have any effect.
*
* \param [in] do_initialize If 0 rabbitmq-c will not initialize the SSL
* library, otherwise rabbitmq-c will initialize the
* SSL library
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL
amqp_set_initialize_ssl_library(amqp_boolean_t do_initialize);
AMQP_END_DECLS
#endif /* AMQP_SSL_H */
rabbitmq-c-0.8.0/librabbitmq/amqp_table.c 0000664 0000000 0000000 00000043630 12702357234 0020314 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2012-2013
* Alan Antonuk. All Rights Reserved.
*
* Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
* All Rights Reserved.
*
* Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
* VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "amqp_private.h"
#include "amqp_table.h"
#include
#include
#include
#include
#include
#define INITIAL_ARRAY_SIZE 16
#define INITIAL_TABLE_SIZE 16
static int amqp_decode_field_value(amqp_bytes_t encoded,
amqp_pool_t *pool,
amqp_field_value_t *entry,
size_t *offset);
static int amqp_encode_field_value(amqp_bytes_t encoded,
amqp_field_value_t *entry,
size_t *offset);
/*---------------------------------------------------------------------------*/
static int amqp_decode_array(amqp_bytes_t encoded,
amqp_pool_t *pool,
amqp_array_t *output,
size_t *offset)
{
uint32_t arraysize;
int num_entries = 0;
int allocated_entries = INITIAL_ARRAY_SIZE;
amqp_field_value_t *entries;
size_t limit;
int res;
if (!amqp_decode_32(encoded, offset, &arraysize)) {
return AMQP_STATUS_BAD_AMQP_DATA;
}
entries = malloc(allocated_entries * sizeof(amqp_field_value_t));
if (entries == NULL) {
return AMQP_STATUS_NO_MEMORY;
}
limit = *offset + arraysize;
while (*offset < limit) {
if (num_entries >= allocated_entries) {
void *newentries;
allocated_entries = allocated_entries * 2;
newentries = realloc(entries, allocated_entries * sizeof(amqp_field_value_t));
res = AMQP_STATUS_NO_MEMORY;
if (newentries == NULL) {
goto out;
}
entries = newentries;
}
res = amqp_decode_field_value(encoded, pool, &entries[num_entries],
offset);
if (res < 0) {
goto out;
}
num_entries++;
}
output->num_entries = num_entries;
output->entries = amqp_pool_alloc(pool, num_entries * sizeof(amqp_field_value_t));
/* NULL is legitimate if we requested a zero-length block. */
if (output->entries == NULL) {
if (num_entries == 0) {
res = AMQP_STATUS_OK;
} else {
res = AMQP_STATUS_NO_MEMORY;
}
goto out;
}
memcpy(output->entries, entries, num_entries * sizeof(amqp_field_value_t));
res = AMQP_STATUS_OK;
out:
free(entries);
return res;
}
int amqp_decode_table(amqp_bytes_t encoded,
amqp_pool_t *pool,
amqp_table_t *output,
size_t *offset)
{
uint32_t tablesize;
int num_entries = 0;
amqp_table_entry_t *entries;
int allocated_entries = INITIAL_TABLE_SIZE;
size_t limit;
int res;
if (!amqp_decode_32(encoded, offset, &tablesize)) {
return AMQP_STATUS_BAD_AMQP_DATA;
}
entries = malloc(allocated_entries * sizeof(amqp_table_entry_t));
if (entries == NULL) {
return AMQP_STATUS_NO_MEMORY;
}
limit = *offset + tablesize;
while (*offset < limit) {
uint8_t keylen;
res = AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_8(encoded, offset, &keylen)) {
goto out;
}
if (num_entries >= allocated_entries) {
void *newentries;
allocated_entries = allocated_entries * 2;
newentries = realloc(entries, allocated_entries * sizeof(amqp_table_entry_t));
res = AMQP_STATUS_NO_MEMORY;
if (newentries == NULL) {
goto out;
}
entries = newentries;
}
res = AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_bytes(encoded, offset, &entries[num_entries].key, keylen)) {
goto out;
}
res = amqp_decode_field_value(encoded, pool, &entries[num_entries].value,
offset);
if (res < 0) {
goto out;
}
num_entries++;
}
output->num_entries = num_entries;
output->entries = amqp_pool_alloc(pool, num_entries * sizeof(amqp_table_entry_t));
/* NULL is legitimate if we requested a zero-length block. */
if (output->entries == NULL) {
if (num_entries == 0) {
res = AMQP_STATUS_OK;
} else {
res = AMQP_STATUS_NO_MEMORY;
}
goto out;
}
memcpy(output->entries, entries, num_entries * sizeof(amqp_table_entry_t));
res = AMQP_STATUS_OK;
out:
free(entries);
return res;
}
static int amqp_decode_field_value(amqp_bytes_t encoded,
amqp_pool_t *pool,
amqp_field_value_t *entry,
size_t *offset)
{
int res = AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_decode_8(encoded, offset, &entry->kind)) {
goto out;
}
#define TRIVIAL_FIELD_DECODER(bits) if (!amqp_decode_##bits(encoded, offset, &entry->value.u##bits)) goto out; break
#define SIMPLE_FIELD_DECODER(bits, dest, how) { uint##bits##_t val; if (!amqp_decode_##bits(encoded, offset, &val)) goto out; entry->value.dest = how; } break
switch (entry->kind) {
case AMQP_FIELD_KIND_BOOLEAN:
SIMPLE_FIELD_DECODER(8, boolean, val ? 1 : 0);
case AMQP_FIELD_KIND_I8:
SIMPLE_FIELD_DECODER(8, i8, (int8_t)val);
case AMQP_FIELD_KIND_U8:
TRIVIAL_FIELD_DECODER(8);
case AMQP_FIELD_KIND_I16:
SIMPLE_FIELD_DECODER(16, i16, (int16_t)val);
case AMQP_FIELD_KIND_U16:
TRIVIAL_FIELD_DECODER(16);
case AMQP_FIELD_KIND_I32:
SIMPLE_FIELD_DECODER(32, i32, (int32_t)val);
case AMQP_FIELD_KIND_U32:
TRIVIAL_FIELD_DECODER(32);
case AMQP_FIELD_KIND_I64:
SIMPLE_FIELD_DECODER(64, i64, (int64_t)val);
case AMQP_FIELD_KIND_U64:
TRIVIAL_FIELD_DECODER(64);
case AMQP_FIELD_KIND_F32:
TRIVIAL_FIELD_DECODER(32);
/* and by punning, f32 magically gets the right value...! */
case AMQP_FIELD_KIND_F64:
TRIVIAL_FIELD_DECODER(64);
/* and by punning, f64 magically gets the right value...! */
case AMQP_FIELD_KIND_DECIMAL:
if (!amqp_decode_8(encoded, offset, &entry->value.decimal.decimals)
|| !amqp_decode_32(encoded, offset, &entry->value.decimal.value)) {
goto out;
}
break;
case AMQP_FIELD_KIND_UTF8:
/* AMQP_FIELD_KIND_UTF8 and AMQP_FIELD_KIND_BYTES have the
same implementation, but different interpretations. */
/* fall through */
case AMQP_FIELD_KIND_BYTES: {
uint32_t len;
if (!amqp_decode_32(encoded, offset, &len)
|| !amqp_decode_bytes(encoded, offset, &entry->value.bytes, len)) {
goto out;
}
break;
}
case AMQP_FIELD_KIND_ARRAY:
res = amqp_decode_array(encoded, pool, &(entry->value.array), offset);
goto out;
case AMQP_FIELD_KIND_TIMESTAMP:
TRIVIAL_FIELD_DECODER(64);
case AMQP_FIELD_KIND_TABLE:
res = amqp_decode_table(encoded, pool, &(entry->value.table), offset);
goto out;
case AMQP_FIELD_KIND_VOID:
break;
default:
goto out;
}
res = AMQP_STATUS_OK;
out:
return res;
}
/*---------------------------------------------------------------------------*/
static int amqp_encode_array(amqp_bytes_t encoded,
amqp_array_t *input,
size_t *offset)
{
size_t start = *offset;
int i, res;
*offset += 4; /* size of the array gets filled in later on */
for (i = 0; i < input->num_entries; i++) {
res = amqp_encode_field_value(encoded, &input->entries[i], offset);
if (res < 0) {
goto out;
}
}
if (!amqp_encode_32(encoded, &start, (uint32_t)(*offset - start - 4))) {
res = AMQP_STATUS_TABLE_TOO_BIG;
goto out;
}
res = AMQP_STATUS_OK;
out:
return res;
}
int amqp_encode_table(amqp_bytes_t encoded,
amqp_table_t *input,
size_t *offset)
{
size_t start = *offset;
int i, res;
*offset += 4; /* size of the table gets filled in later on */
for (i = 0; i < input->num_entries; i++) {
if (!amqp_encode_8(encoded, offset, (uint8_t)input->entries[i].key.len)) {
res = AMQP_STATUS_TABLE_TOO_BIG;
goto out;
}
if (!amqp_encode_bytes(encoded, offset, input->entries[i].key)) {
res = AMQP_STATUS_TABLE_TOO_BIG;
goto out;
}
res = amqp_encode_field_value(encoded, &input->entries[i].value, offset);
if (res < 0) {
goto out;
}
}
if (!amqp_encode_32(encoded, &start, (uint32_t)(*offset - start - 4))) {
res = AMQP_STATUS_TABLE_TOO_BIG;
goto out;
}
res = AMQP_STATUS_OK;
out:
return res;
}
static int amqp_encode_field_value(amqp_bytes_t encoded,
amqp_field_value_t *entry,
size_t *offset)
{
int res = AMQP_STATUS_BAD_AMQP_DATA;
if (!amqp_encode_8(encoded, offset, entry->kind)) {
goto out;
}
#define FIELD_ENCODER(bits, val) if (!amqp_encode_##bits(encoded, offset, val)) { \
res = AMQP_STATUS_TABLE_TOO_BIG; \
goto out; \
} \
break
switch (entry->kind) {
case AMQP_FIELD_KIND_BOOLEAN:
FIELD_ENCODER(8, entry->value.boolean ? 1 : 0);
case AMQP_FIELD_KIND_I8:
FIELD_ENCODER(8, entry->value.i8);
case AMQP_FIELD_KIND_U8:
FIELD_ENCODER(8, entry->value.u8);
case AMQP_FIELD_KIND_I16:
FIELD_ENCODER(16, entry->value.i16);
case AMQP_FIELD_KIND_U16:
FIELD_ENCODER(16, entry->value.u16);
case AMQP_FIELD_KIND_I32:
FIELD_ENCODER(32, entry->value.i32);
case AMQP_FIELD_KIND_U32:
FIELD_ENCODER(32, entry->value.u32);
case AMQP_FIELD_KIND_I64:
FIELD_ENCODER(64, entry->value.i64);
case AMQP_FIELD_KIND_U64:
FIELD_ENCODER(64, entry->value.u64);
case AMQP_FIELD_KIND_F32:
/* by punning, u32 magically gets the right value...! */
FIELD_ENCODER(32, entry->value.u32);
case AMQP_FIELD_KIND_F64:
/* by punning, u64 magically gets the right value...! */
FIELD_ENCODER(64, entry->value.u64);
case AMQP_FIELD_KIND_DECIMAL:
if (!amqp_encode_8(encoded, offset, entry->value.decimal.decimals)
|| !amqp_encode_32(encoded, offset, entry->value.decimal.value)) {
res = AMQP_STATUS_TABLE_TOO_BIG;
goto out;
}
break;
case AMQP_FIELD_KIND_UTF8:
/* AMQP_FIELD_KIND_UTF8 and AMQP_FIELD_KIND_BYTES have the
same implementation, but different interpretations. */
/* fall through */
case AMQP_FIELD_KIND_BYTES:
if (!amqp_encode_32(encoded, offset, (uint32_t)entry->value.bytes.len)
|| !amqp_encode_bytes(encoded, offset, entry->value.bytes)) {
res = AMQP_STATUS_TABLE_TOO_BIG;
goto out;
}
break;
case AMQP_FIELD_KIND_ARRAY:
res = amqp_encode_array(encoded, &entry->value.array, offset);
goto out;
case AMQP_FIELD_KIND_TIMESTAMP:
FIELD_ENCODER(64, entry->value.u64);
case AMQP_FIELD_KIND_TABLE:
res = amqp_encode_table(encoded, &entry->value.table, offset);
goto out;
case AMQP_FIELD_KIND_VOID:
break;
default:
res = AMQP_STATUS_INVALID_PARAMETER;
goto out;
}
res = AMQP_STATUS_OK;
out:
return res;
}
/*---------------------------------------------------------------------------*/
int amqp_table_entry_cmp(void const *entry1, void const *entry2)
{
amqp_table_entry_t const *p1 = (amqp_table_entry_t const *) entry1;
amqp_table_entry_t const *p2 = (amqp_table_entry_t const *) entry2;
int d;
size_t minlen;
minlen = p1->key.len;
if (p2->key.len < minlen) {
minlen = p2->key.len;
}
d = memcmp(p1->key.bytes, p2->key.bytes, minlen);
if (d != 0) {
return d;
}
return (int)p1->key.len - (int)p2->key.len;
}
static int
amqp_field_value_clone(const amqp_field_value_t *original, amqp_field_value_t *clone, amqp_pool_t *pool)
{
int i;
int res;
clone->kind = original->kind;
switch (clone->kind) {
case AMQP_FIELD_KIND_BOOLEAN:
clone->value.boolean = original->value.boolean;
break;
case AMQP_FIELD_KIND_I8:
clone->value.i8 = original->value.i8;
break;
case AMQP_FIELD_KIND_U8:
clone->value.u8 = original->value.u8;
break;
case AMQP_FIELD_KIND_I16:
clone->value.i16 = original->value.i16;
break;
case AMQP_FIELD_KIND_U16:
clone->value.u16 = original->value.u16;
break;
case AMQP_FIELD_KIND_I32:
clone->value.i32 = original->value.i32;
break;
case AMQP_FIELD_KIND_U32:
clone->value.u32 = original->value.u32;
break;
case AMQP_FIELD_KIND_I64:
clone->value.i64 = original->value.i64;
break;
case AMQP_FIELD_KIND_U64:
case AMQP_FIELD_KIND_TIMESTAMP:
clone->value.u64 = original->value.u64;
break;
case AMQP_FIELD_KIND_F32:
clone->value.f32 = original->value.f32;
break;
case AMQP_FIELD_KIND_F64:
clone->value.f64 = original->value.f64;
break;
case AMQP_FIELD_KIND_DECIMAL:
clone->value.decimal = original->value.decimal;
break;
case AMQP_FIELD_KIND_UTF8:
case AMQP_FIELD_KIND_BYTES:
if (0 == original->value.bytes.len) {
clone->value.bytes = amqp_empty_bytes;
} else {
amqp_pool_alloc_bytes(pool, original->value.bytes.len, &clone->value.bytes);
if (NULL == clone->value.bytes.bytes) {
return AMQP_STATUS_NO_MEMORY;
}
memcpy(clone->value.bytes.bytes, original->value.bytes.bytes, clone->value.bytes.len);
}
break;
case AMQP_FIELD_KIND_ARRAY:
if (0 == original->value.array.entries) {
clone->value.array = amqp_empty_array;
} else {
clone->value.array.num_entries = original->value.array.num_entries;
clone->value.array.entries = amqp_pool_alloc(pool, clone->value.array.num_entries * sizeof(amqp_field_value_t));
if (NULL == clone->value.array.entries) {
return AMQP_STATUS_NO_MEMORY;
}
for (i = 0; i < clone->value.array.num_entries; ++i) {
res = amqp_field_value_clone(&original->value.array.entries[i], &clone->value.array.entries[i], pool);
if (AMQP_STATUS_OK != res) {
return res;
}
}
}
break;
case AMQP_FIELD_KIND_TABLE:
return amqp_table_clone(&original->value.table, &clone->value.table, pool);
case AMQP_FIELD_KIND_VOID:
break;
default:
return AMQP_STATUS_INVALID_PARAMETER;
}
return AMQP_STATUS_OK;
}
static int
amqp_table_entry_clone(const amqp_table_entry_t *original, amqp_table_entry_t *clone, amqp_pool_t *pool)
{
if (0 == original->key.len) {
return AMQP_STATUS_INVALID_PARAMETER;
}
amqp_pool_alloc_bytes(pool, original->key.len, &clone->key);
if (NULL == clone->key.bytes) {
return AMQP_STATUS_NO_MEMORY;
}
memcpy(clone->key.bytes, original->key.bytes, clone->key.len);
return amqp_field_value_clone(&original->value, &clone->value, pool);
}
int
amqp_table_clone(const amqp_table_t *original, amqp_table_t *clone, amqp_pool_t *pool)
{
int i;
int res;
clone->num_entries = original->num_entries;
if (0 == clone->num_entries) {
*clone = amqp_empty_table;
return AMQP_STATUS_OK;
}
clone->entries = amqp_pool_alloc(pool, clone->num_entries * sizeof(amqp_table_entry_t));
if (NULL == clone->entries) {
return AMQP_STATUS_NO_MEMORY;
}
for (i = 0; i < clone->num_entries; ++i) {
res = amqp_table_entry_clone(&original->entries[i], &clone->entries[i], pool);
if (AMQP_STATUS_OK != res) {
goto error_out1;
}
}
return AMQP_STATUS_OK;
error_out1:
return res;
}
amqp_table_entry_t amqp_table_construct_utf8_entry(const char *key,
const char *value) {
amqp_table_entry_t ret;
ret.key = amqp_cstring_bytes(key);
ret.value.kind = AMQP_FIELD_KIND_UTF8;
ret.value.value.bytes = amqp_cstring_bytes(value);
return ret;
}
amqp_table_entry_t amqp_table_construct_table_entry(const char *key,
const amqp_table_t *value) {
amqp_table_entry_t ret;
ret.key = amqp_cstring_bytes(key);
ret.value.kind = AMQP_FIELD_KIND_TABLE;
ret.value.value.table = *value;
return ret;
}
amqp_table_entry_t amqp_table_construct_bool_entry(const char *key,
const int value) {
amqp_table_entry_t ret;
ret.key = amqp_cstring_bytes(key);
ret.value.kind = AMQP_FIELD_KIND_BOOLEAN;
ret.value.value.boolean = value;
return ret;
}
amqp_table_entry_t *amqp_table_get_entry_by_key(const amqp_table_t *table,
const amqp_bytes_t key) {
int i;
assert(table != NULL);
for (i = 0; i < table->num_entries; ++i) {
if (amqp_bytes_equal(table->entries[i].key, key)) {
return &table->entries[i];
}
}
return NULL;
}
rabbitmq-c-0.8.0/librabbitmq/amqp_table.h 0000664 0000000 0000000 00000006320 12702357234 0020314 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MIT
*
* Portions created by Alan Antonuk are Copyright (c) 2014 Alan Antonuk.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ***** END LICENSE BLOCK *****
*/
#ifndef AMQP_TABLE_H
#define AMQP_TABLE_H
#include "amqp.h"
#include "amqp_private.h"
/**
* Initializes a table entry with utf-8 string type value.
*
* \param [in] key the table entry key. The string must remain valid for the
* life of the resulting amqp_table_entry_t.
* \param [in] value the string value. The string must remain valid for the life
* of the resulting amqp_table_entry_t.
* \returns An initialized table entry.
*/
amqp_table_entry_t amqp_table_construct_utf8_entry(const char *key,
const char *value);
/**
* Initializes a table entry with table type value.
*
* \param [in] key the table entry key. The string must remain value for the
* life of the resulting amqp_table_entry_t.
* \param [in] value the amqp_table_t value. The table must remain valid for the
* life of the resulting amqp_table_entry_t.
* \returns An initialized table entry.
*/
amqp_table_entry_t amqp_table_construct_table_entry(const char *key,
const amqp_table_t *value);
/**
* Initializes a table entry with boolean type value.
*
* \param [in] key the table entry key. The string must remain value for the
* life of the resulting amqp_table_entry_t.
* \param [in] value the boolean value. 0 means false, any other value is true.
* \returns An initialized table entry.
*/
amqp_table_entry_t amqp_table_construct_bool_entry(const char *key,
const int value);
/**
* Searches a table for an entry with a matching key.
*
* \param [in] table the table to search.
* \param [in] key the string to search with.
* \returns a pointer to the table entry in the table if a matching key can be
* found, NULL otherwise.
*/
amqp_table_entry_t *amqp_table_get_entry_by_key(const amqp_table_t *table,
const amqp_bytes_t key);
#endif /* AMQP_TABLE_H */
rabbitmq-c-0.8.0/librabbitmq/amqp_tcp_socket.c 0000664 0000000 0000000 00000014303 12702357234 0021356 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* Copyright 2012-2013 Michael Steinert
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "amqp_private.h"
#include "amqp_tcp_socket.h"
#include
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include
#else
# include
# include
# include
#endif
#include
#include
struct amqp_tcp_socket_t {
const struct amqp_socket_class_t *klass;
int sockfd;
int internal_error;
int state;
};
static ssize_t
amqp_tcp_socket_send(void *base, const void *buf, size_t len, int flags)
{
struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
ssize_t res;
int flagz = 0;
if (-1 == self->sockfd) {
return AMQP_STATUS_SOCKET_CLOSED;
}
#ifdef MSG_NOSIGNAL
flagz |= MSG_NOSIGNAL;
#endif
#if defined(MSG_MORE)
if (flags & AMQP_SF_MORE) {
flagz |= MSG_MORE;
}
/* Cygwin defines TCP_NOPUSH, but trying to use it will return not
* implemented. Disable it here. */
#elif defined(TCP_NOPUSH) && !defined(__CYGWIN__)
if (flags & AMQP_SF_MORE && !(self->state & AMQP_SF_MORE)) {
int one = 1;
res = setsockopt(self->sockfd, IPPROTO_TCP, TCP_NOPUSH, &one, sizeof(one));
if (0 != res) {
self->internal_error = res;
return AMQP_STATUS_SOCKET_ERROR;
}
self->state |= AMQP_SF_MORE;
} else if (!(flags & AMQP_SF_MORE) && self->state & AMQP_SF_MORE) {
int zero = 0;
res = setsockopt(self->sockfd, IPPROTO_TCP, TCP_NOPUSH, &zero, sizeof(&zero));
if (0 != res) {
self->internal_error = res;
res = AMQP_STATUS_SOCKET_ERROR;
} else {
self->state &= ~AMQP_SF_MORE;
}
}
#endif
start:
#ifdef _WIN32
res = send(self->sockfd, buf, (int)len, flagz);
#else
res = send(self->sockfd, buf, len, flagz);
#endif
if (res < 0) {
self->internal_error = amqp_os_socket_error();
switch (self->internal_error) {
case EINTR:
goto start;
#ifdef _WIN32
case WSAEWOULDBLOCK:
#else
case EWOULDBLOCK:
#endif
#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
case EAGAIN:
#endif
res = AMQP_PRIVATE_STATUS_SOCKET_NEEDWRITE;
break;
default:
res = AMQP_STATUS_SOCKET_ERROR;
}
} else {
self->internal_error = 0;
}
return res;
}
static ssize_t
amqp_tcp_socket_recv(void *base, void *buf, size_t len, int flags)
{
struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
ssize_t ret;
if (-1 == self->sockfd) {
return AMQP_STATUS_SOCKET_CLOSED;
}
start:
#ifdef _WIN32
ret = recv(self->sockfd, buf, (int)len, flags);
#else
ret = recv(self->sockfd, buf, len, flags);
#endif
if (0 > ret) {
self->internal_error = amqp_os_socket_error();
switch (self->internal_error) {
case EINTR:
goto start;
#ifdef _WIN32
case WSAEWOULDBLOCK:
#else
case EWOULDBLOCK:
#endif
#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
case EAGAIN:
#endif
ret = AMQP_PRIVATE_STATUS_SOCKET_NEEDREAD;
break;
default:
ret = AMQP_STATUS_SOCKET_ERROR;
}
} else if (0 == ret) {
ret = AMQP_STATUS_CONNECTION_CLOSED;
}
return ret;
}
static int
amqp_tcp_socket_open(void *base, const char *host, int port, struct timeval *timeout)
{
struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
if (-1 != self->sockfd) {
return AMQP_STATUS_SOCKET_INUSE;
}
self->sockfd = amqp_open_socket_noblock(host, port, timeout);
if (0 > self->sockfd) {
int err = self->sockfd;
self->sockfd = -1;
return err;
}
return AMQP_STATUS_OK;
}
static int
amqp_tcp_socket_close(void *base, AMQP_UNUSED amqp_socket_close_enum force)
{
struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
if (-1 == self->sockfd) {
return AMQP_STATUS_SOCKET_CLOSED;
}
if (amqp_os_socket_close(self->sockfd)) {
return AMQP_STATUS_SOCKET_ERROR;
}
self->sockfd = -1;
return AMQP_STATUS_OK;
}
static int
amqp_tcp_socket_get_sockfd(void *base)
{
struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
return self->sockfd;
}
static void
amqp_tcp_socket_delete(void *base)
{
struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
if (self) {
amqp_tcp_socket_close(self, AMQP_SC_NONE);
free(self);
}
}
static const struct amqp_socket_class_t amqp_tcp_socket_class = {
amqp_tcp_socket_send, /* send */
amqp_tcp_socket_recv, /* recv */
amqp_tcp_socket_open, /* open */
amqp_tcp_socket_close, /* close */
amqp_tcp_socket_get_sockfd, /* get_sockfd */
amqp_tcp_socket_delete /* delete */
};
amqp_socket_t *
amqp_tcp_socket_new(amqp_connection_state_t state)
{
struct amqp_tcp_socket_t *self = calloc(1, sizeof(*self));
if (!self) {
return NULL;
}
self->klass = &amqp_tcp_socket_class;
self->sockfd = -1;
amqp_set_socket(state, (amqp_socket_t *)self);
return (amqp_socket_t *)self;
}
void
amqp_tcp_socket_set_sockfd(amqp_socket_t *base, int sockfd)
{
struct amqp_tcp_socket_t *self;
if (base->klass != &amqp_tcp_socket_class) {
amqp_abort("<%p> is not of type amqp_tcp_socket_t", base);
}
self = (struct amqp_tcp_socket_t *)base;
self->sockfd = sockfd;
}
rabbitmq-c-0.8.0/librabbitmq/amqp_tcp_socket.h 0000664 0000000 0000000 00000004323 12702357234 0021364 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/** \file */
/*
* Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk.
* All Rights Reserved.
*
* Portions created by Michael Steinert are Copyright (c) 2012-2013 Michael
* Steinert. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* A TCP socket connection.
*/
#ifndef AMQP_TCP_SOCKET_H
#define AMQP_TCP_SOCKET_H
#include
AMQP_BEGIN_DECLS
/**
* Create a new TCP socket.
*
* Call amqp_connection_close() to release socket resources.
*
* \return A new socket object or NULL if an error occurred.
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
amqp_socket_t *
AMQP_CALL
amqp_tcp_socket_new(amqp_connection_state_t state);
/**
* Assign an open file descriptor to a socket object.
*
* This function must not be used in conjunction with amqp_socket_open(), i.e.
* the socket connection should already be open(2) when this function is
* called.
*
* \param [in,out] self A TCP socket object.
* \param [in] sockfd An open socket descriptor.
*
* \since v0.4.0
*/
AMQP_PUBLIC_FUNCTION
void
AMQP_CALL
amqp_tcp_socket_set_sockfd(amqp_socket_t *self, int sockfd);
AMQP_END_DECLS
#endif /* AMQP_TCP_SOCKET_H */
rabbitmq-c-0.8.0/librabbitmq/amqp_time.c 0000664 0000000 0000000 00000014516 12702357234 0020164 0 ustar 00root root 0000000 0000000 /* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
/*
* Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "amqp.h"
#include "amqp_time.h"
#include
#include
#include
#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
# define AMQP_WIN_TIMER_API
#elif (defined(machintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
# define AMQP_MAC_TIMER_API
#else
# define AMQP_POSIX_TIMER_API
#endif
#ifdef AMQP_WIN_TIMER_API
#define WIN32_LEAN_AND_MEAN
#include