lnk commit front code

This commit is contained in:
lnk
2025-01-16 16:17:01 +08:00
commit 1776a2bf0d
587 changed files with 257079 additions and 0 deletions

10
.vs/VSWorkspaceState.json Normal file
View File

@@ -0,0 +1,10 @@
{
"ExpandedNodes": [
"",
"\\include",
"\\json",
"\\mms"
],
"SelectedNode": "\\mms\\main.c",
"PreviewInSolutionExplorer": false
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,54 @@
{
"Version": 1,
"WorkspaceRootPath": "D:\\canneng\\pms3.0_czy_2024-10-9\\pt61850netd_pqfe\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|D:\\canneng\\pms3.0_czy_2024-10-9\\pt61850netd_pqfe\\mms\\main.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:mms\\main.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|D:\\canneng\\pms3.0_czy_2024-10-9\\pt61850netd_pqfe\\json\\create_json.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:json\\create_json.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 1,
"Children": [
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "create_json.cpp",
"DocumentMoniker": "D:\\canneng\\pms3.0_czy_2024-10-9\\pt61850netd_pqfe\\json\\create_json.cpp",
"RelativeDocumentMoniker": "json\\create_json.cpp",
"ToolTip": "D:\\canneng\\pms3.0_czy_2024-10-9\\pt61850netd_pqfe\\json\\create_json.cpp",
"RelativeToolTip": "json\\create_json.cpp",
"ViewState": "AgIAAD8CAAAAAAAAAAAQwDMEAAAEAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-11-15T06:54:01.719Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "main.c",
"DocumentMoniker": "D:\\canneng\\pms3.0_czy_2024-10-9\\pt61850netd_pqfe\\mms\\main.c",
"RelativeDocumentMoniker": "mms\\main.c",
"ToolTip": "D:\\canneng\\pms3.0_czy_2024-10-9\\pt61850netd_pqfe\\mms\\main.c",
"RelativeToolTip": "mms\\main.c",
"ViewState": "AgIAAAcBAAAAAAAAAAAowBUBAAASAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000423|",
"WhenOpened": "2024-11-15T06:46:56.891Z",
"EditorCaption": ""
}
]
}
]
}
]
}

Binary file not shown.

BIN
.vs/slnx.sqlite Normal file

Binary file not shown.

18
.vscode/c_cpp_properties.json vendored Normal file
View File

@@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "windows-gcc-x64",
"includePath": [
"${workspaceFolder}/**"
],
"compilerPath": "C:/Users/lnk/Downloads/mingw32/bin/gcc.exe",
"cStandard": "${default}",
"cppStandard": "${default}",
"intelliSenseMode": "windows-gcc-x64",
"compilerArgs": [
""
]
}
],
"version": 4
}

24
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,24 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "C/C++ Runner: Debug Session",
"type": "cppdbg",
"request": "launch",
"args": [],
"stopAtEntry": false,
"externalConsole": true,
"cwd": "d:/canneng/pms3.0_czy_2024-10-9/pt61850netd_pqfe/mms",
"program": "d:/canneng/pms3.0_czy_2024-10-9/pt61850netd_pqfe/mms/build/Debug/outDebug",
"MIMode": "gdb",
"miDebuggerPath": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

141
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,141 @@
{
"C_Cpp_Runner.cCompilerPath": "gcc",
"C_Cpp_Runner.cppCompilerPath": "g++",
"C_Cpp_Runner.debuggerPath": "gdb",
"C_Cpp_Runner.cStandard": "",
"C_Cpp_Runner.cppStandard": "",
"C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat",
"C_Cpp_Runner.useMsvc": false,
"C_Cpp_Runner.warnings": [
"-Wall",
"-Wextra",
"-Wpedantic",
"-Wshadow",
"-Wformat=2",
"-Wcast-align",
"-Wconversion",
"-Wsign-conversion",
"-Wnull-dereference"
],
"C_Cpp_Runner.msvcWarnings": [
"/W4",
"/permissive-",
"/w14242",
"/w14287",
"/w14296",
"/w14311",
"/w14826",
"/w44062",
"/w44242",
"/w14905",
"/w14906",
"/w14263",
"/w44265",
"/w14928"
],
"C_Cpp_Runner.enableWarnings": true,
"C_Cpp_Runner.warningsAsError": false,
"C_Cpp_Runner.compilerArgs": [],
"C_Cpp_Runner.linkerArgs": [],
"C_Cpp_Runner.includePaths": [],
"C_Cpp_Runner.includeSearch": [
"*",
"**/*"
],
"C_Cpp_Runner.excludeSearch": [
"**/build",
"**/build/**",
"**/.*",
"**/.*/**",
"**/.vscode",
"**/.vscode/**"
],
"C_Cpp_Runner.useAddressSanitizer": false,
"C_Cpp_Runner.useUndefinedSanitizer": false,
"C_Cpp_Runner.useLeakSanitizer": false,
"C_Cpp_Runner.showCompilationTime": false,
"C_Cpp_Runner.useLinkTimeOptimization": false,
"C_Cpp_Runner.msvcSecureNoWarnings": false,
"files.associations": {
"array": "cpp",
"string": "cpp",
"string_view": "cpp",
"span": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"charconv": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"compare": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"format": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"semaphore": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"text_encoding": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp",
"variant": "cpp",
"chrono": "cpp",
"db_interface.h": "c",
"rdb_client.h": "c",
"bitset": "cpp",
"regex": "cpp",
"unordered_set": "cpp",
"stdlib.h": "c",
"apr_time.h": "c",
"queue": "cpp",
"xmltools.h": "c",
"simpleproducer.h": "c",
"stdbool.h": "c",
"node.h": "c",
"save2json.h": "c"
}
}

39
build-ubuntu.sh Normal file
View File

@@ -0,0 +1,39 @@
#!/bin/sh
DEBUG='-f Makefile.Debug'
RELEASE='-f Makefile.Release'
make_function()
{
qmake pt61850netd_pqfe.pro
make $1 distclean
qmake pt61850netd_pqfe.pro
make $1 clean
make $1 -j 2
make $1 install
}
echo Usage: "build-xxx.sh release/debug/all/clean/\"\" "
echo " release|\"\" : Make version release "
echo " debug : Make version debug "
echo " all : Make version debug and release"
echo " clean : Make clean "
if [ "$1" = "" ]; then
make_function "$RELEASE"
fi
if [ "$1" = "release" ]; then
make_function "$RELEASE"
fi
if [ "$1" = "debug" ]; then
make_function "$DEBUG"
fi
if [ "$1" = "all" ]; then
make_function "$RELEASE"
make_function "$DEBUG"
fi
if [ "$1" = "clean" ]; then
qmake
make distclean
fi

2
cfg_parse/CVS/Entries Normal file
View File

@@ -0,0 +1,2 @@
/cfg_parser.cpp/1.20/Tue Jan 22 07:41:32 2019//
D

View File

@@ -0,0 +1 @@
/cfg_parser.cpp////*////

View File

@@ -0,0 +1 @@
/cfg_parser.cpp////*////

View File

@@ -0,0 +1,2 @@
/cfg_parser.cpp/1.19/Fri Jan 18 02:42:35 2019//
D

1
cfg_parse/CVS/Repository Normal file
View File

@@ -0,0 +1 @@
jspqfe/src/pt61850netd_pqfe/source/cfg_parse

1
cfg_parse/CVS/Root Normal file
View File

@@ -0,0 +1 @@
:ext:lizhongming@10.0.0.2:/JoyProject

0
cfg_parse/CVS/Template Normal file
View File

View File

@@ -0,0 +1,866 @@
/*
* Description: Simple Producer demo
*/
#include <fstream> // 用于 std::ifstream
#include <sstream> // 用于 std::stringstream
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include "../mms/db_interface.h"
#include "../include/rocketmq/CProducer.h"
#include "../include/rocketmq/CMessage.h"
#include "../include/rocketmq/CSendResult.h"
#include "../include/rocketmq/SimpleProducer.h"
//测试300数据用lnk20241202
#include <ctime>
#include <QThread>
//测试300数据用
//lnk20241209添加队列选择
#include "../include/rocketmq/MQSelector.h"
#include "../include/rocketmq/MQMessageQueue.h"
//#include <atomic>
#include <vector>
#include <stdexcept>
//lnk20241209添加队列选择
#include <cstring>
// 引入提供的消费者接口头文件
#include "../include/rocketmq/CPushConsumer.h"
#include "../include/rocketmq/CCommon.h"
#include "../include/rocketmq/CMessageExt.h"
#include <map>
#include <pthread.h> // 用于互斥锁(在 C++98 中没有 std::mutex
#include <utility> // for std::pair
using namespace std;
extern std::string G_ROCKETMQ_PRODUCER;//rocketmq producer
extern std::string G_ROCKETMQ_IPPORT;//rocketmq ip+port
extern std::string G_ROCKETMQ_TOPIC;//topie
extern std::string G_ROCKETMQ_TAG;//tag
extern std::string G_ROCKETMQ_KEY;//key
#ifdef __cplusplus
extern "C" {
#endif
extern std::string G_MQCONSUMER_TOPIC_SET; // C++ 中的全局变量声明
#ifdef __cplusplus
}
#endif
extern int QUEUENUM;
extern int g_front_seg_index;
extern char subdir[128];
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//消费者连接秘钥
extern std::string G_MQCONSUMER_ACCESSKEY;
extern std::string G_MQCONSUMER_SECRETKEY;
extern std::string G_MQCONSUMER_CHANNEL;
// 前向声明 RocketMQConsumer 类
class RocketMQConsumer;
// 全局映射CPushConsumer* -> RocketMQConsumer*
std::map<CPushConsumer*, RocketMQConsumer*> g_consumerMap;//
pthread_mutex_t g_consumerMapMutex = PTHREAD_MUTEX_INITIALIZER;
class RocketMQConsumer {
public:
// 构造函数:初始化消费者并启动
RocketMQConsumer(const std::string& consumerName, const std::string& nameServer, const std::string& groupId);
// 禁用拷贝和赋值
RocketMQConsumer(const RocketMQConsumer&) {}
RocketMQConsumer& operator=(const RocketMQConsumer&) { return *this; }
// 订阅主题和标签,并注册回调
void subscribe(const std::string& topic, const std::string& tag, MessageCallBack callback);
// 启动消费者
void start();
//修改消费模式
void setConsumerMessageModel(const std::string& topic);
// 析构函数:关闭并销毁消费者
~RocketMQConsumer();
private:
CPushConsumer* consumer_; // C 接口消费者指针
//MessageCallBack messageCallback_; // 函数指针用于回调
std::map<std::pair<std::string, std::string>, MessageCallBack> callbacks_; // 订阅到回调的映射
// 静态消息处理回调
static int messageHandler(CPushConsumer* consumer, CMessageExt* msg);
// 实例消息处理函数
int handleMessage(CMessageExt* msg);
};
// 构造函数实现
RocketMQConsumer::RocketMQConsumer(const std::string& consumerName, const std::string& nameServer, const std::string& groupId)
: consumer_(NULL)//, messageCallback_(NULL)
{
// 创建消费者
consumer_ = CreatePushConsumer(consumerName.c_str());
if (consumer_ == NULL) {
std::cout << "error CreatePushConsumer"<< std::endl;
throw std::runtime_error("Failed to create push consumer.");
}
SetPushConsumerSessionCredentials(consumer_,G_MQCONSUMER_ACCESSKEY.c_str(),G_MQCONSUMER_SECRETKEY.c_str(),G_MQCONSUMER_CHANNEL.c_str());
// 设置 NameServer 地址
if (SetPushConsumerNameServerAddress(consumer_, nameServer.c_str()) != 0) {
DestroyPushConsumer(consumer_);
std::cout << "error setting nameServer"<< std::endl;
throw std::runtime_error("Failed to set NameServer address.");
}
// 设置消费者组ID
if (SetPushConsumerGroupID(consumer_, groupId.c_str()) != 0) {
DestroyPushConsumer(consumer_);
std::cout << "error setting groupId"<< std::endl;
throw std::runtime_error("Failed to set Consumer Group ID.");
}
// 设置消费模式为广播模式
if (SetPushConsumerMessageModel(consumer_, BROADCASTING) != 0) {
DestroyPushConsumer(consumer_);
std::cout << "error setting messagemodel"<< std::endl;
}
//调试用
std::string consumerlog = "./mqconsumer/" + consumerName +".log";
if ( (SetPushConsumerLogPath(consumer_,consumerlog.c_str()) || SetPushConsumerLogFileNumAndSize(consumer_,10,100) || SetPushConsumerLogLevel(consumer_,E_LOG_LEVEL_DEBUG) ) != 0) {//记录消费日志
DestroyPushConsumer(consumer_);
std::cout << "error setting logpath"<< std::endl;
}
std::cout << "logpath:" << consumerlog << std::endl;
// 注册消息回调
if (RegisterMessageCallback(consumer_, RocketMQConsumer::messageHandler) != 0) {
DestroyPushConsumer(consumer_);
std::cout << "error setting Callback"<< std::endl;
throw std::runtime_error("Failed to register message callback.");
}
// 将消费者实例添加到全局映射
pthread_mutex_lock(&g_consumerMapMutex);
g_consumerMap[consumer_] = this;
pthread_mutex_unlock(&g_consumerMapMutex);
std::cout << "RocketMQ Consumer initialized and started." << std::endl;
}
// 启动消费者
void RocketMQConsumer::start()
{
if (StartPushConsumer(consumer_) != 0) {
pthread_mutex_lock(&g_consumerMapMutex);
g_consumerMap.erase(consumer_);
pthread_mutex_unlock(&g_consumerMapMutex);
DestroyPushConsumer(consumer_);
throw std::runtime_error("Failed to start push consumer.");
}
else{
std::cout << "RocketMQ Consumer started." << std::endl;
}
}
void RocketMQConsumer::subscribe(const std::string& topic, const std::string& tag, MessageCallBack callback)
{
if (Subscribe(consumer_, topic.c_str(), tag.c_str()) != 0) {
throw std::runtime_error("Failed to subscribe to topic/tag.");
}
std::cout << "Subscribed to topic: " << topic << ", tag: " << tag << std::endl;
// 使用 std::pair 作为键
std::pair<std::string, std::string> key(topic, tag);
callbacks_[key] = callback;
}
// 静态消息处理回调实现
int RocketMQConsumer::messageHandler(CPushConsumer* consumer, CMessageExt* msg)
{
RocketMQConsumer* instance = NULL;
//调试用
std::cout << "messagehandler" << std::endl;
// 查找对应的消费者实例
pthread_mutex_lock(&g_consumerMapMutex);
std::map<CPushConsumer*, RocketMQConsumer*>::iterator it = g_consumerMap.find(consumer);
if (it != g_consumerMap.end()) {
instance = it->second;
}
pthread_mutex_unlock(&g_consumerMapMutex);
if (instance) {
return instance->handleMessage(msg);
} else {
std::cerr << "Consumer instance not found for callback." << std::endl;
return E_RECONSUME_LATER; // 默认返回重试状态
}
}
int RocketMQConsumer::handleMessage(CMessageExt* msg)
{
// 检查 msg 和 consumer_ 是否为 NULL
if (!msg || !consumer_) {
std::cerr << "Received null message or consumer." << std::endl;
return E_RECONSUME_LATER;
}
// 获取消息的主题和标签
std::string topic = GetMessageTopic(msg); // 假设存在此函数
std::string tag = GetMessageTags(msg); // 假设存在此函数
// 打印调试信息
std::cout << "Handling message for topic: " << topic << ", tag: " << tag << std::endl;
// 使用 std::pair 作为键
std::pair<std::string, std::string> key(topic, tag);
// 查找对应的回调函数
std::map<std::pair<std::string, std::string>, MessageCallBack>::iterator it = callbacks_.find(key);
if (it != callbacks_.end()) {
// 调用对应的回调函数
//调试
std::cout << "callback Handling message " <<std::endl;
return it->second(consumer_, msg);
} else {
//调试
std::cout << "there is no callback " <<std::endl;
// 如果没有找到对应的回调,执行默认处理
const char* body = GetMessageBody(msg);
const char* msgKey = GetMessageKeys(msg);
if (body) {
std::cout << "Received message body: " << body << std::endl;
} else {
std::cout << "Received message with empty body." << std::endl;
}
if (msgKey) {
std::cout << "Message Key: " << msgKey << std::endl;
} else {
std::cout << "Message Key: N/A" << std::endl;
}
return E_CONSUME_SUCCESS;
}
}
// 析构函数实现
RocketMQConsumer::~RocketMQConsumer()
{
if (consumer_) {
// 关闭消费者
ShutdownPushConsumer(consumer_);
// 从全局映射中移除
pthread_mutex_lock(&g_consumerMapMutex);
g_consumerMap.erase(consumer_);
pthread_mutex_unlock(&g_consumerMapMutex);
// 销毁消费者
DestroyPushConsumer(consumer_);
consumer_ = NULL;
std::cout << "RocketMQ Consumer shutdown and destroyed." << std::endl;
}
}
// 在 RocketMQConsumer 类中新增函数用来设置消费模式
void RocketMQConsumer::setConsumerMessageModel(const std::string& topic)
{
if (topic == G_MQCONSUMER_TOPIC_SET) {
// 设置为普通消费模式
if (SetPushConsumerMessageModel(consumer_, CLUSTERING) != 0) {
std::cout << "Error setting message model to CLUSTERING for topic: " << topic << std::endl;
} else {
std::cout << "Set consumer to CLUSTERING for topic: " << topic << std::endl;
}
} else {
// 默认设置为广播消费模式
if (SetPushConsumerMessageModel(consumer_, BROADCASTING) != 0) {
std::cout << "Error setting message model to BROADCASTING for topic: " << topic << std::endl;
} else {
std::cout << "Set consumer to BROADCASTING for topic: " << topic << std::endl;
}
}
}
// 全局消费者实例
RocketMQConsumer* g_consumer = NULL;
// 初始化消费者函数
void InitializeConsumer(
const std::string& consumerName,
const std::string& nameServer,
const std::vector<Subscription>& subscriptions) // 接收多个订阅
{
if (g_consumer == NULL) {
std::cout << "create new consumer!" << std::endl;
try {
g_consumer = new RocketMQConsumer(consumerName, nameServer,consumerName);//用消费名作为消费组不同进程不同的消费者同时消费topic的同一条消息
for (size_t i = 0; i < subscriptions.size(); ++i) {
g_consumer->setConsumerMessageModel(subscriptions[i].topic);//初始化时根据topic设置消费模式
g_consumer->subscribe(subscriptions[i].topic, subscriptions[i].tag, subscriptions[i].callback);
}
g_consumer->start();
}
catch (const std::exception& e) {
std::cerr << "Failed to initialize consumer: " << e.what() << std::endl;
throw; // 重新抛出异常
}
}
}
// 关闭并销毁消费者函数
void ShutdownAndDestroyConsumer()
{
if (g_consumer != NULL) {
delete g_consumer;
g_consumer = NULL;
}
}
// 消费消息的接口函数
void rocketmq_consumer_receive(
const std::string& consumerName,
const std::string& nameServer,
const std::vector<Subscription>& subscriptions) // 接收多个订阅
{
if (g_consumer == NULL) {
try {
//InitializeConsumer(consumerName, nameServer, topic, tag, callback);//初始化后mq库内部来完成消息的获取
InitializeConsumer(consumerName, nameServer, subscriptions); // 初始化后MQ库内部开始获取消息
}
catch (...) {
std::cerr << "Cannot consume message because consumer initialization failed." << std::endl;
return;
}
}
// 消费逻辑已通过回调处理,无需额外操作
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//封装生产者类
#if 1
// 全局或静态变量,用于维护当前队列索引
static int currentQueueId = 0;
// 队列选择器回调函数:轮询选择队列 ID
int RoundRobinSelector(int queueNum, CMessage* msg, void* arg) {
if (queueNum == 0) {
throw std::runtime_error("No available queues");
}
int queueId = currentQueueId % queueNum;
currentQueueId++;
if (currentQueueId >= 1024 - queueNum) {
currentQueueId = 0;
}
return queueId;
}
// 封装生产者的类
class RocketMQProducer {
public:
RocketMQProducer(const std::string& producerName, const std::string& nameServer)
: producer_(NULL)
{
// 创建生产者
producer_ = CreateProducer(producerName.c_str());
if (producer_ == NULL) {
throw std::runtime_error("Failed to create producer.");
}
// 设置 nameserver 地址
SetProducerNameServerAddress(producer_, nameServer.c_str());
// 启动生产者
StartProducer(producer_);
std::cout << "rocketmq_Producer initialized and started." << std::endl;
}
// 禁用拷贝和赋值
RocketMQProducer(const RocketMQProducer&) = delete;
RocketMQProducer& operator=(const RocketMQProducer&) = delete;
// 发送消息
void sendMessage(const char* strbody, const char* topic, const std::string& tags, const std::string& keys) {
CSendResult result;
CMessage* msg = NULL;
try {
// 创建消息并设置属性
msg = CreateMessage(topic);
if (msg == NULL) {
throw std::runtime_error("Failed to create message.");
}
SetMessageTags(msg, tags.c_str());
SetMessageKeys(msg, keys.c_str());
SetMessageBody(msg, strbody);
// 假设队列数量和 Broker 名称是固定的
int queueNum = QUEUENUM; // 配置的队列数量例如5
// 发送消息
int sendResult = SendMessageOnewayOrderly(
producer_,
msg,
RoundRobinSelector, // 队列选择器回调函数
&queueNum // 传递给选择器的额外参数(队列数量)
);
if (sendResult == 0) { // 假设返回 0 表示成功
std::cout << "Message sent successfully." << std::endl;
} else {
std::cout << "Failed to send message." << std::endl;
}
// 销毁消息
DestroyMessage(msg);
msg = NULL; // 防止重复销毁
}
catch (const std::runtime_error& e) {
std::cerr << "Runtime error during message sending: " << e.what() << std::endl;
// 如果消息已经创建,确保销毁它
if (msg != NULL) {
DestroyMessage(msg);
}
// 可以在这里添加更多的错误处理逻辑,比如重试、记录日志等
}
catch (const std::exception& e) {
std::cerr << "Exception during message sending: " << e.what() << std::endl;
if (msg != NULL) {
DestroyMessage(msg);
}
}
catch (...) {
std::cerr << "Unknown error during message sending." << std::endl;
if (msg != NULL) {
DestroyMessage(msg);
}
}
}
// 析构函数中关闭并销毁生产者
~RocketMQProducer() {
if (producer_) {
ShutdownProducer(producer_);
DestroyProducer(producer_);
std::cout << "rocketmq_Producer shutdown and destroyed." << std::endl;
}
}
private:
CProducer* producer_;
};
// 全局生产者实例
RocketMQProducer* g_producer = NULL;
// 初始化生产者(在程序启动时调用一次)
void InitializeProducer()
{
if (g_producer == NULL) {
try {
g_producer = new RocketMQProducer(G_ROCKETMQ_PRODUCER, G_ROCKETMQ_IPPORT);
}
catch (const std::exception& e) {
std::cerr << "Failed to initialize producer: " << e.what() << std::endl;
// 根据需求决定是否终止程序或采取其他措施
throw; // 重新抛出异常
}
}
}
// 关闭并销毁生产者(在程序结束时调用一次)
void ShutdownAndDestroyProducer()
{
if (g_producer != NULL) {
delete g_producer;
g_producer = NULL;
}
}
// 发送消息的接口函数
void rocketmq_producer_send(const char* strbody, const char* topic)
{
if (g_producer == NULL) {
try {
InitializeProducer();
}
catch (...) {
std::cerr << "Cannot send message because producer initialization failed." << std::endl;
return;
}
}
// 假设 tags 和 keys 是固定的,可以根据需要修改
std::string tags = G_ROCKETMQ_TAG;
std::string keys = G_ROCKETMQ_KEY;
try {
g_producer->sendMessage(strbody, topic, tags, keys);
}
catch (const std::exception& e) {
std::cerr << "Failed to send message: " << e.what() << std::endl;
// 处理发送失败的情况,例如记录日志或重试
}
}
#endif
//lnk20241209队列轮询
#if 0
// 全局或静态变量,用于维护当前队列索引
static int currentQueueId = 0;
// 队列选择器回调函数:轮询选择队列 ID
int RoundRobinSelector(int queueNum, CMessage* msg, void* arg) {
if (queueNum == 0) {
throw std::runtime_error("No available queues");
}
// 选择当前队列 ID并更新索引
int queueId = currentQueueId % queueNum;
currentQueueId++;
// 防止溢出,重置索引
if (currentQueueId >= 1024 - queueNum) {
currentQueueId = 0;
}
return queueId;
}
void StartSendMessage_queue(CProducer* producer, const char* strbody, const char* topic)
{
CSendResult result;
// 创建消息并设置一些属性
CMessage* msg = CreateMessage(topic);
SetMessageTags(msg, G_ROCKETMQ_TAG.c_str());
SetMessageKeys(msg, G_ROCKETMQ_KEY.c_str());
SetMessageBody(msg, strbody);
// 动态获取队列数量和 Broker 名称
int queueNum = QUEUENUM; // 假设这个是配置的队列数量比如5
// 使用 SendMessageOnewayOrderly 发送消息,传递回调函数
int sendResult = SendMessageOnewayOrderly(
producer,
msg,
RoundRobinSelector, // 传递符合 QueueSelectorCallback 签名的函数
&queueNum // 传递给选择器的额外参数(队列数量)
);
if (sendResult == 0) { // 假设返回 0 表示成功
std::cout << "Message sent successfully: " << std::endl;
} else {
std::cout << "Failed to send message: " << std::endl;
}
// 销毁消息
DestroyMessage(msg);
}
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// producer_send0测试用
void StartSendMessage(CProducer* producer)
{
CSendResult result;
// create message and set some values for it
CMessage* msg = CreateMessage(G_ROCKETMQ_TOPIC.c_str());
SetMessageTags(msg, G_ROCKETMQ_TAG.c_str());
SetMessageKeys(msg, G_ROCKETMQ_KEY.c_str());
for (int i = 0; i < 10; i++)
{
// construct different body
string strMessageBody = "this is body number";
SetMessageBody(msg, strMessageBody.c_str());
// send message
SendMessageSync(producer, msg, &result);
cout << "send message[" << i << "], result status:" << result.sendStatus << ", msgBody:" << strMessageBody << endl;
usleep(1000);
}
// destroy message
DestroyMessage(msg);
}
//producer_send 测试用
void StartSendMessage(CProducer* producer,const char* strbody)
{
CSendResult result;
// create message and set some values for it
CMessage* msg = CreateMessage(G_ROCKETMQ_TOPIC.c_str());
SetMessageTags(msg, G_ROCKETMQ_TAG.c_str());
SetMessageKeys(msg, G_ROCKETMQ_KEY.c_str());
SetMessageBody(msg, strbody);
// send message
SendMessageSync(producer, msg, &result);
cout << "result status:" << result.sendStatus << ", msgBody:" << strbody << endl;
// destroy message
DestroyMessage(msg);
}
//测试用 固定消息体
void producer_send0()
{
cout << "Producer Initializing....." << endl;
// create producer and set some values for it
CProducer* producer = CreateProducer(G_ROCKETMQ_PRODUCER.c_str());
SetProducerNameServerAddress(producer, G_ROCKETMQ_IPPORT.c_str());
// start producer
StartProducer(producer);
cout << "Producer start....." << endl;
// send message
StartSendMessage(producer);
// shutdown producer
ShutdownProducer(producer);
// destroy producer
DestroyProducer(producer);
cout << "Producer Shutdown!" << endl;
}
//测试用 可控制消息体
void producer_send(const char* strbody)
{
cout << "Producer Initializing....." << endl;
// create producer and set some values for it
CProducer* producer = CreateProducer(G_ROCKETMQ_PRODUCER.c_str());
SetProducerNameServerAddress(producer, G_ROCKETMQ_IPPORT.c_str());
// start producer
StartProducer(producer);
cout << "Producer start....." << endl;
// send message
StartSendMessage(producer, strbody);
// shutdown producer
ShutdownProducer(producer);
// destroy producer
DestroyProducer(producer);
cout << "Producer Shutdown!" << endl;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
#if 0
void rocketmq_StartSendMessage(CProducer* producer,const char* strbody,const char* topic)
{
CSendResult result;
// create message and set some values for it
CMessage* msg = CreateMessage(topic);
//多前置区分消息tag一个进程
SetMessageTags(msg, G_ROCKETMQ_TAG.c_str());
SetMessageKeys(msg, G_ROCKETMQ_KEY.c_str());
SetMessageBody(msg, strbody);
// send message
SendMessageSync(producer, msg, &result);
//cout << "rocketmq_result status:" << result.sendStatus << ", msgBody:" << strbody << endl;
// destroy message
DestroyMessage(msg);
}
void rocketmq_producer_send(const char* strbody,const char* topic)
{
cout << "rocketmq_Producer Initializing....." << endl;
// create producer and set some values for it
CProducer* producer = CreateProducer(G_ROCKETMQ_PRODUCER.c_str());
if (producer == NULL) {
std::cerr << "Failed to create producer." << std::endl;
return;
}
// nameserver
SetProducerNameServerAddress(producer, G_ROCKETMQ_IPPORT.c_str());
// start producer
StartProducer(producer);
cout << "rocketmq_Producer start....." << endl;
// send message
//rocketmq_StartSendMessage(producer,strbody,topic);
//根据队列发消息
StartSendMessage_queue(producer,strbody,topic);
// shutdown producer
ShutdownProducer(producer);
// destroy producer
DestroyProducer(producer);
cout << "rocketmq_Producer Shutdown!" << endl;
}
#endif
extern "C" {
extern std::string G_MQCONSUMER_TOPIC_RT;
void rocketmq_test_rt()
{
Ckafka_data_t data;
data.monitor_id = 123123;
data.strTopic = QString::fromStdString(G_MQCONSUMER_TOPIC_RT);
std::ifstream file("rt.txt"); // 文件中存储长字符串
std::stringstream buffer;
buffer << file.rdbuf(); // 读取整个文件内容
data.strText = QString::fromStdString(buffer.str());
data.mp_id = 123123;
my_rocketmq_send(data);
}
extern std::string G_MQCONSUMER_TOPIC_UD;
void rocketmq_test_ud()//用来测试台账更新
{
Ckafka_data_t data;
data.monitor_id = 123123;
data.strTopic = QString::fromStdString(G_MQCONSUMER_TOPIC_UD);
std::ifstream file("ud.txt"); // 文件中存储长字符串
std::stringstream buffer;
buffer << file.rdbuf(); // 读取整个文件内容
data.strText = QString::fromStdString(buffer.str());
data.mp_id = 123123;
my_rocketmq_send(data);
}
void rocketmq_test_set()//用来测试进程控制脚本
{
Ckafka_data_t data;
data.monitor_id = 123123;
data.strTopic = QString::fromStdString(G_MQCONSUMER_TOPIC_SET);
std::ifstream file("set.txt"); // 文件中存储长字符串
std::stringstream buffer;
buffer << file.rdbuf(); // 读取整个文件内容
data.strText = QString::fromStdString(buffer.str());
data.mp_id = 123123;
my_rocketmq_send(data);
}
extern std::string G_MQCONSUMER_TOPIC_RC;
void rocketmq_test_rc()
{
Ckafka_data_t data;
data.monitor_id = 123123;
data.strTopic = QString::fromStdString(G_MQCONSUMER_TOPIC_RC);
std::ifstream file("rc.txt"); // 文件中存储长字符串
std::stringstream buffer;
buffer << file.rdbuf(); // 读取整个文件内容
data.strText = QString::fromStdString(buffer.str());
data.mp_id = 123123;
my_rocketmq_send(data);
}
}
std::string to_string(long long value) {
std::stringstream ss;
ss << value;
return ss.str();
}
void rocketmq_test_300(int mpnum,int front_index) {
Ckafka_data_t data;
data.strTopic = QString::fromStdString(G_ROCKETMQ_TOPIC);
data.mp_id = "0";
// 读取文件内容
std::ifstream file("long_string.txt"); // 文件中存储长字符串
std::stringstream buffer;
buffer << file.rdbuf();
std::string file_contents = buffer.str(); // 获取文件内容
std::string base_strText = file_contents;
// 获取当前时间作为开始时间
std::time_t t = std::time(NULL);//获取当前的系统时间(自 1970 年 1 月 1 日以来的秒数,通常称为 UNIX 时间戳)
std::tm* time_info = std::localtime(&t);//将 std::time_t表示当前的 UNIX 时间戳转换为本地时间std::tm 结构)
time_info->tm_sec = 0; // 清零秒位
//time_info->tm_msec = 0; // 清零毫秒位(如果需要更精确,使用高精度时间)
// 获取当前的时间戳(秒)
std::time_t base_time_t = std::mktime(time_info);//将 std::tm 结构(本地时间)转换回 std::time_t时间戳
// 计算每条消息的时间戳,精确到分钟,毫秒和秒清零
long long current_time_ms = static_cast<long long>(base_time_t) * 1000; // 每分钟递增,单位毫秒
// 设定总的消息数量
int total_messages = mpnum;
// 循环发送 300 条消息
for (int i = 0; i < total_messages; ++i) {
// 修改 Monitor 值
data.monitor_id = front_index *10000 + 1 + i;
data.mp_id = QString::number(data.monitor_id);
std::string modified_time = to_string(current_time_ms); // 时间转换为整数类型Unix时间戳
// 替换消息中的 Monitor 和 TIME 字段(只匹配字段名,不匹配具体数值)
std::string modified_strText = base_strText;
// 替换 Monitor 字段
size_t monitor_pos = modified_strText.find("\"Monitor\"");
if (monitor_pos != std::string::npos) {
size_t colon_pos = modified_strText.find(":", monitor_pos);
size_t quote_pos = modified_strText.find("\"", colon_pos);
size_t end_quote_pos = modified_strText.find("\"", quote_pos + 1);
if (colon_pos != std::string::npos && quote_pos != std::string::npos && end_quote_pos != std::string::npos) {
modified_strText.replace(quote_pos + 1, end_quote_pos - quote_pos - 1, to_string(data.monitor_id));
}
}
// 替换 TIME 字段
size_t time_pos = modified_strText.find("\"TIME\"");
if (time_pos != std::string::npos) {
size_t colon_pos = modified_strText.find(":", time_pos);
size_t quote_pos = colon_pos;
size_t end_quote_pos = modified_strText.find(",", quote_pos + 1);
if (colon_pos != std::string::npos && quote_pos != std::string::npos && end_quote_pos != std::string::npos) {
modified_strText.replace(quote_pos + 1, end_quote_pos - quote_pos - 1, modified_time);
}
}
// 更新数据
data.strText = QString::fromStdString(modified_strText);
// 发送数据
my_rocketmq_send(data);
// 输出调试信息
std::cout << "Sent message " << (i + 1) << " with Monitor " << data.monitor_id << " and TIME " << modified_time << std::endl;
// 等待下一条消息的发送固定为1分钟
//QThread::sleep(60); // 每次发送间隔1分钟
}
std::cout << "Finished sending " << total_messages << " messages." << std::endl;
}

189
cfg_parse/base64.cpp Normal file
View File

@@ -0,0 +1,189 @@
/**
* @file: $RCSfile: base64.cpp,v $
* @brief: base64 include
*
* @version: $Revision: 1.00 $
* @date: $Date: 2024/09/24 18:34:00 $
* @author: $Author: caizhouyu $
* @state: $State: Exp $
*
* @latest: $Id: base64.cpp,v 1.00 2023/10/24 18:34:00 caizhouyu Exp $
*
*/
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "../mms/db_interface.h"
#include "../json/cjson.h"//WW 2023-08-27<32><37><EFBFBD><EFBFBD>json<6F><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include "../include/curl/curl.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
// Base64 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
const char base64_chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
//base64 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static const unsigned char base64_decode_table[] = {
//ÿ<><C3BF>16<31><36>
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //1 - 16
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //17 - 32
0,0,0,0,0,0,0,0,0,0,0,62,0,0,0,63, //33 - 48
52,53,54,55,56,57,58,59,60,61,0,0,0,0,0,0, //49 - 64
0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14, //65 - 80
15,16,17,18,19,20,21,22,23,24,25,0,0,0,0,0, //81 - 96
0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, //97 - 112
41,42,43,44,45,46,47,48,49,50,51,0,0,0,0,0 //113 - 128
};
/**
* @brief base64_decode base64<36><34><EFBFBD><EFBFBD>
* @param indata <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param inlen <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD>С
* @param outdata <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param outlen <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD>С
* @return int 0<><30><EFBFBD>ɹ<EFBFBD> -1<><31><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>
* ע<><EFBFBD><E2A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĴ<DDB5>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD>ı<EFBFBD><C4B1><EFBFBD>
*/
int base64_decode(const char* indata, int inlen, char* outdata, long* outlen)
{
if (indata == NULL || inlen <= 0 || (outdata == NULL && outlen == NULL)) {
return -1;
}
if (inlen < 4 || inlen % 4 != 0) { //<2F><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3>Ȳ<EFBFBD><C8B2><EFBFBD>4<EFBFBD>ı<EFBFBD><C4B1><EFBFBD> //inlen < 4 ||
return -1;
}
int i, j;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int len = inlen / 4 * 3;
if (indata[inlen - 1] == '=') {
len--;
}
if (indata[inlen - 2] == '=') {
len--;
}
if (outdata != NULL) {
for (i = 0, j = 0; i < inlen; i += 4, j += 3) {
outdata[j] = (base64_decode_table[(unsigned char)indata[i]] << 2) | (base64_decode_table[(unsigned char)indata[i + 1]] >> 4);
outdata[j + 1] = (base64_decode_table[(unsigned char)indata[i + 1]] << 4) | (base64_decode_table[(unsigned char)indata[i + 2]] >> 2);
outdata[j + 2] = (base64_decode_table[(unsigned char)indata[i + 2]] << 6) | (base64_decode_table[(unsigned char)indata[i + 3]]);
}
}
if (outlen != NULL) {
*outlen = len;
}
return 0;
}
// Base64 <20><><EFBFBD><EFBFBD><EBBAAF>
char* base64_encode_char(const unsigned char* data, size_t input_length, size_t* output_length) {
*output_length = 4 * ((input_length + 2) / 3); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>
char* encoded_data = (char*)malloc(*output_length + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ棬+1 Ϊ '\0'
if (encoded_data == NULL) return NULL;
for (int i = 0, j = 0; i < input_length;) {
uint32_t octet_a = i < input_length ? data[i++] : 0;
uint32_t octet_b = i < input_length ? data[i++] : 0;
uint32_t octet_c = i < input_length ? data[i++] : 0;
uint32_t triple = (octet_a << 16) | (octet_b << 8) | octet_c;
encoded_data[j++] = base64_chars[(triple >> 18) & 0x3F];
encoded_data[j++] = base64_chars[(triple >> 12) & 0x3F];
encoded_data[j++] = (i * 2 / 3) < *output_length ? base64_chars[(triple >> 6) & 0x3F] : '=';
encoded_data[j++] = (i * 2 + 1 / 3) < *output_length ? base64_chars[triple & 0x3F] : '=';
}
encoded_data[*output_length] = '\0'; // <20><><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return encoded_data;
}
/// <summary>
/// <20>ж<EFBFBD><D0B6>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ϊpower{}<7D><>ʽ
/// </summary>
/// <param name="str"><3E><><EFBFBD><EFBFBD>ȡ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD></param>
/// <param name="output"><3E><><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD></param>
/// <param name="output_size"><3E>ֶγ<D6B6><CEB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="extracted_length"><3E><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD></param>
/// <returns></returns>
bool extract_if_power(const char* str, char* output, size_t output_size, size_t* extracted_length) {
const char* prefix = "power{";
size_t prefix_length = strlen(prefix);
// <20><><EFBFBD><EFBFBD>ǰ׺
if (strncmp(str, prefix, prefix_length) != 0) {
return false; // ǰ׺<C7B0><D7BA>ƥ<EFBFBD><C6A5>
}
// <20><><EFBFBD>ұպϵĻ<CFB5><C4BB><EFBFBD><EFBFBD><EFBFBD>
const char* close_brace = strchr(str + prefix_length, '}');
if (close_brace == NULL) {
return false; // û<><C3BB><EFBFBD>ҵ<EFBFBD><D2B5>պϵĻ<CFB5><C4BB><EFBFBD><EFBFBD><EFBFBD>
}
// <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
size_t content_length = close_brace - (str + prefix_length);
if (content_length >= output_size) {
return false; // <20><><EFBFBD><EFBFBD>̫<EFBFBD><CCAB><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
strncpy(output, str + prefix_length, content_length);
output[content_length] = '\0'; // <20><><EFBFBD>ӿ<EFBFBD><D3BF><EFBFBD>ֹ<EFBFBD><D6B9>
printf("text: %s,length:%d\n", output, content_length); // ע<><EFBFBD><E2A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫȷ<D2AA><C8B7><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD>null<6C><6C>ֹ<EFBFBD><D6B9><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
*extracted_length = content_length;
return true; // <20><>ȡ<EFBFBD>ɹ<EFBFBD>
}
//int testbase64(char ** decoded_text) {
// unsigned char text[] = "power{SGVsbG8sIFdvcmxkIWV3ZA==}";
// size_t encoded_length, decoded_length;
// char encoded_text[100];
// if (extract_if_power((char*)text, encoded_text, sizeof(encoded_text), &encoded_length)) {
// // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// long decodedLen = strlen(encoded_text) * 3 / 4;
// * decoded_text = (char*)malloc(decodedLen + 1);
// // <20><><EFBFBD><EFBFBD>Base64<36><34><EFBFBD><EFBFBD>
// int success = base64_decode(encoded_text, strlen(encoded_text), *decoded_text, &decodedLen);
// if (decoded_text) {
// printf("Decoded: %s\n", (char*)decoded_text); // ע<><EFBFBD><E2A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫȷ<D2AA><C8B7><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD>null<6C><6C>ֹ<EFBFBD><D6B9><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
// free(decoded_text); // ע<><EFBFBD><E2A3BA><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD>ϲ<EFBFBD>Ӧ<EFBFBD><D3A6>ʹ<EFBFBD><CAB9>decoded_text<78><74>Ϊ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>unsigned char*
// // <20><>ʵ<EFBFBD><CAB5>Ӧ<EFBFBD><D3A6><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊchar*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>null<6C><6C>ֹ<EFBFBD><D6B9>
// }
// }
// else {
// printf(" no Decoded: %s\n", text); // ע<><EFBFBD><E2A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫȷ<D2AA><C8B7><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD>null<6C><6C>ֹ<EFBFBD><D6B9><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
// }
//
// // ע<><EFBFBD><E2A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>decoded_text<78><74>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD>Dz<EFBFBD>׼ȷ<D7BC>ģ<EFBFBD><C4A3><EFBFBD>Ϊdecoded_text<78><74>unsigned char*<2A>ҿ<EFBFBD><D2BF>ܲ<EFBFBD><DCB2><EFBFBD>null<6C><6C>ֹ<EFBFBD><D6B9><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
// // <20><>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD>decoded_textת<74><D7AA>Ϊ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
// return 0;
//}
#ifdef __cplusplus
}
#endif

14282
cfg_parse/cfg_parser.cpp Normal file

File diff suppressed because it is too large Load Diff

132
cfg_parse/datahub.cpp Normal file
View File

@@ -0,0 +1,132 @@
/**
* @file: $RCSfile: datahub.cpp,v $
* @brief: $aliyun datahub include
*
* @version: $Revision: 1.00 $
* @date: $Date: 2023/10/10 18:34:00 $
* @author: $Author: wangwei $
* @state: $State: Exp $
*
* @latest: $Id: datahub.cpp,v 1.00 2023/10/10 18:34:00 wangwei Exp $
*
*/
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "../mms/db_interface.h"
#include "../json/cjson.h"//WW 2023-08-27<32><37><EFBFBD><EFBFBD>json<6F><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include "../include/curl/curl.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
size_t req_reply_datahub(void* ptr, size_t size, size_t nmemb, void* stream)
{
//<2F><>ע<EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cookie<69><65><EFBFBD><EFBFBD>Ϣ
string* str = (string*)stream;
(*str).append((char*)ptr, size * nmemb);
//printf(">>>GetDevice in reply %s\n", (char*)ptr);
//GetCJson(ptr);
return size * nmemb;
}
void SendWebAPI_Datahub(const string strUrl,char* topic,char* data)
{
// curl<72><6C>ʼ<EFBFBD><CABC>
CURL* curl = curl_easy_init();
// curl<72><6C><EFBFBD><EFBFBD>ֵ
CURLcode res;
if (curl)
{
//<2F><><EFBFBD><EFBFBD>curl<72><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
struct curl_slist* header_list = NULL;
header_list = curl_slist_append(header_list, "Content-Type:application/json;");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧͷ<D3A6><CDB7><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_HEADER, 0);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊpost<73><74><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_POST, 1);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>URL<52><4C>ַ
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
//<2F><><EFBFBD><EFBFBD>post<73><74><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>
cJSON* json_root = cJSON_CreateObject();
//cJSON_AddItemToObject(json_root, "topic", cJSON_CreateString("ems_pq_mmxu_stat"));
//cJSON_AddItemToObject(json_root, "data", cJSON_CreateString("{\"DATA_TYPE\": \"04\",\"Monitor\": \"4563\",\"Value\": {\"FLAG\": 1,\"TIME\": 1512097260000,\"VOLTAGE\": {\"MAG\": 56.23,\"DUR\": 23,\"STARTTIME\": 1512097260000,\"ENDTIME\": 1512097283000,\"DISKIND\": \"01\",\"WAVEFILE\": \"PQMonitor_PQM1_000001_20230707_103916_596\",\"PHASIC\": \"unknow\"}}}"));
cJSON_AddItemToObject(json_root, "topic", cJSON_CreateString(topic));
cJSON_AddItemToObject(json_root, "data", cJSON_CreateString(data));
char* szjson = cJSON_Print(json_root);
//printf(">>>json %s\n", szjson);
//string strjson = szjson;
//char* pszEncodeSecret = curl_easy_escape(curl, strclientsecret.c_str(), strclientsecret.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, szjson);
//<2F><><EFBFBD><EFBFBD>ssl<73><6C>֤
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
//CURLOPT_VERBOSE<53><45>ֵΪ1ʱ<31><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ϸ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>Ϣ
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><DDBD>պ<EFBFBD>д<EFBFBD><EFBFBD><EBBAAF>
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_datahub);
string resPost0;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
//<2F><><EFBFBD>ó<EFBFBD>ʱʱ<CAB1><CAB1>
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
printf(">>>Testaliyun datahub Post in curl post\n");
// <20><><EFBFBD><EFBFBD>post<73><74><EFBFBD><EFBFBD>
res = curl_easy_perform(curl);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ɹ<EFBFBD>
if (res != CURLE_OK) {
printf("aliyun datahub failed res code: ");
}
else {
printf("aliyun datahub success,string %s", resPost0.c_str());
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>webapi<70><69><EFBFBD><EFBFBD>ֵ<EFBFBD>ж<EFBFBD>
}
curl_slist_free_all(header_list);
free(szjson);
cJSON_Delete(json_root);
}
else
{
printf(">>> token curl init failed");
}
curl_easy_cleanup(curl);
}
void DataHub_Send_Datahub(char* topic,char* data)
{
SendWebAPI_Datahub("http://127.0.0.1:8091/powerQuality/PQDATAHUB",topic,data);
}
#ifdef __cplusplus
}
#endif

10191
cfg_parse/httplib.h Normal file

File diff suppressed because it is too large Load Diff

247
cfg_parse/httprun.cpp Normal file
View File

@@ -0,0 +1,247 @@
#include <thread>
#include <iostream>
#include "httplib.h"
#include <string>
#include "../json/cjson.h"
//#include <mutex>
//#include <queue>
//std::mutex data_mutex; // 用来保护 receivedData 变量
//#include <atomic>
//std::atomic<bool> isrunning(false); // 使用原子变量保证 isrunning 的内存可见性
//std::queue<std::string> receivedData; // 用于存储接收到的数据
bool isrunning = true; //用于线程同步
std::string receivedData;
//std::queue<std::string> receivedData2; // 用于存储接收到的数据
bool isrunning2 = true; //用于线程同步
std::string receivedData2;
extern std::string HTTP_IP;
extern int HTTP_PORT;
//设置回复消息体
std::string recall_success = "{\"code\":\"A0000\", \"msg\":\"数据补招执行成功\", \"data\":null}";
std::string recall_fail = "{\"code\":\"A0002\", \"msg\":\"数据补招执行失败\", \"data\":null}";
std::string rtdata_success = "{\"code\":\"A0000\", \"msg\":\"3s数据执行成功\", \"data\":null}";
std::string rtdata_fail = "{\"code\":\"A0002\", \"msg\":\"3s数据执行失败\", \"data\":null}";
// 处理补招请求的函数
std::string HandleRecall_http(const httplib::Request& req, httplib::Response& res) {
// 打印请求的查询参数
//std::cout << "Query parameters: " << std::endl;
//std::lock_guard<std::mutex> lock(data_mutex);
if(isrunning == true){ //收到前置信号,收到信息可以处理消息
if (req.body.empty()) { //消息体为空
std::cout << "req.body.empty" << std::endl;
res.status = 400;
res.set_content(recall_fail, "application/json");
return recall_fail;
}
// 消息体不为空,解析 JSON 数据
cJSON* json_root = cJSON_Parse(req.body.c_str());
//解析失败或者消息体不为数组
if (json_root == NULL || json_root->type != cJSON_Array) {
std::cout << "json_root NULL or json_roottype not cJSON_Array" << std::endl;
res.status = 400;
res.set_content(recall_fail, "application/json");
cJSON_Delete(json_root);
return recall_fail;
}
bool is_valid = true;//默认消息体正常
//检查数组每个成员
for (cJSON* item = json_root->child; item != NULL; item = item->next) {
// 检查每个对象是否包含 monitorId、dataType、timeInterval 且不为空
cJSON* monitorId = cJSON_GetObjectItem(item, "monitorId");
cJSON* dataType = cJSON_GetObjectItem(item, "dataType");
cJSON* timeInterval = cJSON_GetObjectItem(item, "timeInterval");
//调试用
std::cout << "!timeInterval" << !timeInterval << " " << (timeInterval->type != cJSON_Array) << " "<< (timeInterval->child == NULL) << std::endl;
if (!timeInterval || //元素必须不为空
timeInterval->type != cJSON_Array || timeInterval->child == NULL) { // timeInterval 必须为非空数组
is_valid = false; //不满足结构则消息体不正常
break;
}
}
// 清理 JSON 数据
cJSON_Delete(json_root);
// 设置响应内容
if (is_valid) {
res.status = 200; //消息体正常返回补招执行成功
res.set_content(recall_success, "application/json");
receivedData = req.body; //提供给前置获取消息体处理
isrunning = false; //停止处理http收到的消息直到收到前置的信号
return recall_success;
} else {
std::cout << "json not right" << std::endl;
res.status = 400;
res.set_content(recall_fail, "application/json");
return recall_fail;
}
}
return req.body; // 返回接收到的未处理的 JSON暂时没有任何地方使用
}
// 处理实时数据请求的函数
std::string HandleRtdata_http(const httplib::Request& req, httplib::Response& res) {
if(isrunning2 == true){ //收到前置信号,收到信息可以处理消息
if (req.body.empty()) { //消息体为空
std::cout << "req.body.empty" << std::endl;
res.status = 400;
res.set_content(rtdata_fail, "application/json");
return rtdata_fail;
}
// 消息体不为空,解析 JSON 数据
cJSON* json_root = cJSON_Parse(req.body.c_str());
//解析失败或者消息体不为数组
if (json_root == NULL || json_root->type != cJSON_Array) {
std::cout << "json_root NULL or json_roottype not cJSON_Array" << std::endl;
res.status = 400;
res.set_content(rtdata_fail, "application/json");
cJSON_Delete(json_root);
return rtdata_fail;
}
bool is_valid = true;//默认消息体正常
//检查数组每个成员
for (cJSON* item = json_root->child; item != NULL; item = item->next) {
// 检查每个对象不为空
cJSON* DevSeries = cJSON_GetObjectItem(item, "DevSeries");
cJSON* Line = cJSON_GetObjectItem(item, "Line");
cJSON* RealData = cJSON_GetObjectItem(item, "RealData");
cJSON* SOEData = cJSON_GetObjectItem(item, "SOEData");
cJSON* Limit = cJSON_GetObjectItem(item, "Limit");
cJSON* Count = cJSON_GetObjectItem(item, "Count");
if (!DevSeries || !Line || !RealData || !SOEData || !Limit || !Count) {
is_valid = false; //不满足结构则消息体不正常
break;
}
}
// 清理 JSON 数据
cJSON_Delete(json_root);
// 设置响应内容
if (is_valid) {
res.status = 200; //消息体正常返回补招执行成功
res.set_content(rtdata_success, "application/json");
receivedData2 = req.body;
isrunning2 = false; //停止处理http收到的消息直到收到前置的信号
return rtdata_success;
} else {
std::cout << "json not right" << std::endl;
res.status = 400;
res.set_content(rtdata_fail, "application/json");
return rtdata_fail;
}
}
return req.body; // 返回接收到的未处理的 JSON暂时没有任何地方使用
}
//处理台账更新请求函数
std::string Handleupdate_http(const httplib::Request& req, httplib::Response& res){
}
// 获取接收到的字符串
//extern "C" std::string getReceivedData() {
extern "C" const char* getReceivedData(int fun) {
if(1 == fun){
/*if (!receivedData.empty()) {
std::string msg = receivedData.front(); // 获取队列中的第一条消息
receivedData.pop(); // 从队列中移除这条消息
return msg.c_str();
}
return "recall queue empty";*/
return receivedData.c_str();
}
if(2 == fun){
/*if (!receivedData2.empty()) {
std::string msg = receivedData2.front(); // 获取队列中的第一条消息
receivedData2.pop(); // 从队列中移除这条消息
return msg.c_str();
}
return "rtdata queue empty";*/
return receivedData2.c_str();
}
return "all queue empty";
}
// 收取信号 1是补招2是实时数据
extern "C" void threadmsgweb(int fun) {
if(1 == fun){
isrunning = true;
}
if(2 == fun){
isrunning2 = true;
}
}
// 发送信号
extern "C" bool threadmsghttp(int fun) {
if(1 == fun){
return isrunning;
}
if(2 == fun){
return isrunning2;
}
return true;
}
// 启动 HTTP 服务器的函数
extern "C" void httprun() {
//std::cout << "WebhttpThread::run() is called ...... " << std::endl;
// 创建 HTTP 服务器对象
httplib::Server svr;
// 监听路径 /powerQuality/recall绑定处理函数
svr.Post("/powerQuality/recall", HandleRecall_http); // 使用 POST 方法处理请求
// 监听路径 /powerQuality/rtdata绑定处理函数
svr.Post("/powerQuality/rtdata", HandleRtdata_http); // 使用 POST 方法处理请求
// 监听路径 /powerQuality/update绑定处理函数
svr.Post("/powerQuality/update", Handleupdate_http); // 使用 POST 方法处理请求
// 监听端口 10004
//std::cout << "Server started at http://0.0.0.0:10004" << std::endl;
if (!svr.listen(HTTP_IP, HTTP_PORT)) { // 监听所有 IP
std::cerr << "Error: Unable to start server on port 10004" << std::endl;
}
//std::cout << "WebhttpThread::run() is end ...... " << std::endl;
}

742
cfg_parse/nacos.cpp Normal file
View File

@@ -0,0 +1,742 @@
/**
* @file: $RCSfile: nacos.cpp,v $
* @brief: $aliyun datahub include
*
* @version: $Revision: 1.00 $
* @date: $Date: 2023/10/24 18:34:00 $
* @author: $Author: wangwei $
* @state: $State: Exp $
*
* @latest: $Id: nacos.cpp,v 1.00 2023/10/24 18:34:00 caizhouyu Exp $
*
*/
using namespace std;
#include <stdio.h>
/*lnk10-12*/
#include <iostream>
#include <stdlib.h>
#include <string>
#include "../mms/db_interface.h"
#include "../json/cjson.h"//WW 2023-08-27<32><37><EFBFBD><EFBFBD>json<6F><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include "../include/curl/curl.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
size_t req_reply_nacos(void* ptr, size_t size, size_t nmemb, void* stream)
{
//((std::string*)userp)->append((char*)contents, size * nmemb);
//<2F><>ע<EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cookie<69><65><EFBFBD><EFBFBD>Ϣ
string* str = (string*)stream;
(*str).append((char*)ptr, size * nmemb);
//printf(">>>GetDevice in reply %s\n", (char*)ptr);
//GetCJson(ptr);
return size * nmemb;
}
void read_nacos_param(const char* ptr, char* postgres_uid, char* postgres_pwd, char* web_clientid, char* web_clientsecret) {
//cout << ">>>GetDevice in reply" << (char*)ptr;
int flag = 1;
cJSON* json = cJSON_Parse((char*)ptr); //json<6F><6E>ʽ<EFBFBD><CABD><EFBFBD>л<EFBFBD>
cJSON* json_node;
cJSON* json_param;
if (json == NULL) {
printf("nacos error %s\n", cJSON_GetErrorPtr());
}
else {
json_node = cJSON_GetObjectItem(json, "status"); //<2F><>ȡresult
if (json_node == NULL || json_node->valuestring == NULL || json_node->valuestring == "/0" || json_node->valuestring == "" || strcmp(json_node->valuestring, "000000") != 0) {
printf("status error :%s\n", cJSON_GetErrorPtr());
flag = 0;
}
json_node = cJSON_GetObjectItem(json, "errors"); //<2F><>ȡresult
if (json_node == NULL || json_node->valuestring == NULL || json_node->valuestring == "/0" || json_node->valuestring == "" || strcmp(json_node->valuestring, "success") != 0) {
printf("errors get falie: %s\n", cJSON_GetErrorPtr());
flag = 0;
}
if (flag) {
printf("read nacos success\n");
json_param = cJSON_GetObjectItem(json, "param"); //<2F><>ȡresult
json_node = cJSON_GetObjectItem(json_param, "postgres_uid"); //<2F><>ȡresult
if (json_node != NULL && strcmp(json_node->valuestring, "null") != 0) {
strcpy(postgres_uid, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "postgres_pwd"); //<2F><>ȡresult
if (json_node != NULL && strcmp(json_node->valuestring, "null") != 0) {
//***postgres_pwd = json_node->valuestring;
strcpy(postgres_pwd, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "web_clientid"); //<2F><>ȡresult
if (json_node != NULL && strcmp(json_node->valuestring, "null") != 0) {
strcpy(web_clientid, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "web_clientsecret"); //<2F><>ȡresult
if (json_node != NULL && strcmp(json_node->valuestring, "null") != 0) {
strcpy(web_clientsecret, json_node->valuestring);
}
}
}
cJSON_Delete(json);
}
void releaseMemory(char** ptr) {
if (*ptr != NULL) {
free(*ptr); // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
}
}
void SendWebAPI_Nacos(const string strUrl, const char* code, char* postgres_uid, char* postgres_pwd, char* web_clientid, char* web_clientsecret)
{
// curl<72><6C>ʼ<EFBFBD><CABC>
CURL* curl = curl_easy_init();
// curl<72><6C><EFBFBD><EFBFBD>ֵ
CURLcode res;
if (curl)
{
//<2F><><EFBFBD><EFBFBD>curl<72><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
struct curl_slist* header_list = NULL;
header_list = curl_slist_append(header_list, "Content-Type:application/json;");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧͷ<D3A6><CDB7><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_HEADER, 0);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊpost<73><74><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_POST, 1);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>URL<52><4C>ַ
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
//<2F><><EFBFBD><EFBFBD>post<73><74><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>
cJSON* json_root = cJSON_CreateObject();
cJSON_AddItemToObject(json_root, "code", cJSON_CreateString(code));
char* szjson = cJSON_Print(json_root);
printf(">>>json %s\n", szjson);
//string strjson = szjson;
//char* pszEncodeSecret = curl_easy_escape(curl, strclientsecret.c_str(), strclientsecret.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, szjson);
//<2F><><EFBFBD><EFBFBD>ssl<73><6C>֤
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
//CURLOPT_VERBOSE<53><45>ֵΪ1ʱ<31><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ϸ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>Ϣ
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><DDBD>պ<EFBFBD>д<EFBFBD><EFBFBD><EBBAAF>
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_nacos);
string resPost0;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
//<2F><><EFBFBD>ó<EFBFBD>ʱʱ<CAB1><CAB1>
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
printf(">>>Test nacos Post in curl post\n");
// <20><><EFBFBD><EFBFBD>post<73><74><EFBFBD><EFBFBD>
res = curl_easy_perform(curl);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ɹ<EFBFBD>
if (res != CURLE_OK) {
printf("nacos failed res code: ");
}
else {
printf("nacos success,string %s", resPost0.c_str());
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>webapi<70><69><EFBFBD><EFBFBD>ֵ<EFBFBD>ж<EFBFBD>
read_nacos_param(resPost0.c_str(), postgres_uid, postgres_pwd, web_clientid, web_clientsecret);
}
curl_slist_free_all(header_list);
free(szjson);
cJSON_Delete(json_root);
}
else
{
printf(">>> nacos curl init failed");
}
curl_easy_cleanup(curl);
}
void SendWebAPI_Nacos_Ptr(const string strUrl, const char* code, char** ptr)
{
// curl<72><6C>ʼ<EFBFBD><CABC>
CURL* curl = curl_easy_init();
// curl<72><6C><EFBFBD><EFBFBD>ֵ
CURLcode res;
if (curl)
{
char url[100];
sprintf(url, "%s?code=%s", strUrl.c_str(), code);
printf(">>>json %s\n", url);
// <20><><EFBFBD><EFBFBD>URL
curl_easy_setopt(curl, CURLOPT_URL, url);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><DDBD>պ<EFBFBD>д<EFBFBD><EFBFBD><EBBAAF>
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_nacos);
string resPost0;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0);
//<2F><><EFBFBD>ó<EFBFBD>ʱʱ<CAB1><CAB1>
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
// <20><><EFBFBD><EFBFBD>post<73><74><EFBFBD><EFBFBD>
res = curl_easy_perform(curl);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ɹ<EFBFBD>
if (res != CURLE_OK) {
printf("nacos failed res code: ");
}
else {
printf(">>> nacos return str:%s \n", resPost0.c_str());
//*ptr = strdup(resPost0.c_str());
*ptr = (char*)malloc(strlen(resPost0.c_str()) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3B9BB><EFBFBD>ڴ<EFBFBD><DAB4>ռ<EFBFBD>
if (*ptr != NULL) {
strcpy(*ptr, resPost0.c_str());
}
else {
printf("Memory allocation failed!\n");
}
//printf(">>>json %s\n", *ptr);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>webapi<70><69><EFBFBD><EFBFBD>ֵ<EFBFBD>ж<EFBFBD>
}
//free(url);
}
else
{
printf(">>> nacos curl init failed");
}
curl_easy_cleanup(curl);
}
void Nacos_GetParam(char* postgres_uid, char* postgres_pwd, char* web_clientid, char* web_clientsecret)
{
SendWebAPI_Nacos("http://127.0.0.1:8091/powerQuality/PQNACOS", "200", postgres_uid, postgres_pwd, web_clientid, web_clientsecret);
}
void Nacos_GetParam_Ptr(const char* code, char** ptr)
{
SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", code, ptr);
}
void Read_Nacos_Param_Postgres(char** database_ip, char** database_port, char** postgres_database, char** postgres_username, char** postgres_password, char** postgres_schema, char** postgres_dnsname, char** postgres_tableprefix) {
char* ptr=NULL;
SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "postgres", &ptr);
//cout << ">>>GetDevice in reply" << (char*)ptr;
int flag = 1;
cJSON* json = cJSON_Parse(ptr); //json<6F><6E>ʽ<EFBFBD><CABD><EFBFBD>л<EFBFBD>
cJSON* json_node;
cJSON* json_param;
if (json == NULL) {
printf("nacos error %s\n", cJSON_GetErrorPtr());
}
else {
json_node = cJSON_GetObjectItem(json, "status"); //<2F><>ȡresult
if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) {
printf("status error :%s\n", cJSON_GetErrorPtr());
flag = 0;
}
json_node = cJSON_GetObjectItem(json, "errors"); //<2F><>ȡresult
if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) {
printf("errors get falie: %s\n", cJSON_GetErrorPtr());
flag = 0;
}
if (flag) {
printf("read nacos success\n");
json_param = cJSON_GetObjectItem(json, "param"); //<2F><>ȡresult
json_node = cJSON_GetObjectItem(json_param, "ip"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*database_ip != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*database_ip);
}
*database_ip = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*database_ip, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "port"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*database_port != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*database_port);
}
*database_port = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*database_port, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "database"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*postgres_database != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*postgres_database);
}
*postgres_database = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*postgres_database, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "username"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
//***postgres_pwd = json_node->valuestring;
if (*postgres_username != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*postgres_username);
}
*postgres_username = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*postgres_username, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "password"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*postgres_password != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*postgres_password);
}
*postgres_password = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*postgres_password, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "schema"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*postgres_schema != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*postgres_schema);
}
*postgres_schema = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*postgres_schema, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "dnsname"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*postgres_dnsname != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*postgres_dnsname);
}
*postgres_dnsname = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*postgres_dnsname, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "tablePrefix"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*postgres_tableprefix != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*postgres_tableprefix);
}
*postgres_tableprefix = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*postgres_tableprefix, json_node->valuestring);
}
}
}
if (ptr) {
free(ptr);
}
cJSON_Delete(json);
}
void Read_Nacos_Param_Kafka(char** broker_list, char** topic_stat, char** topic_pst, char** topic_plt, char** topic_event, char** topic_alarm, char** topic_sng,char** protocol ,char** mechanisms, char** service_name, char** principal, char** domain_name) {
char* ptr = NULL;
SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "kafka", &ptr);
//cout << ">>>GetDevice in reply" << (char*)ptr;
int flag = 1;
cJSON* json = cJSON_Parse(ptr); //json<6F><6E>ʽ<EFBFBD><CABD><EFBFBD>л<EFBFBD>
cJSON* json_node;
cJSON* json_param;
if (json == NULL) {
printf("nacos error %s\n", cJSON_GetErrorPtr());
}
else {
json_node = cJSON_GetObjectItem(json, "status"); //<2F><>ȡresult
if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) {
printf("status error :%s\n", cJSON_GetErrorPtr());
flag = 0;
}
json_node = cJSON_GetObjectItem(json, "errors"); //<2F><>ȡresult
if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) {
printf("errors get falie: %s\n", cJSON_GetErrorPtr());
flag = 0;
}
if (flag) {
printf("read nacos success\n");
json_param = cJSON_GetObjectItem(json, "param"); //<2F><>ȡresult
json_node = cJSON_GetObjectItem(json_param, "brokerList"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*broker_list != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*broker_list);
}
*broker_list = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*broker_list, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "hisTopic"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*topic_stat != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*topic_stat);
}
*topic_stat = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*topic_stat, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "pstTopic"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*topic_pst != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*topic_pst);
}
*topic_pst = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*topic_pst, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "pltTopic"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*topic_plt != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*topic_plt);
}
*topic_plt = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*topic_plt, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "eventTopic"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*topic_event != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*topic_event);
}
*topic_event = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*topic_event, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "almTopic"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*topic_alarm != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*topic_alarm);
}
*topic_alarm = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*topic_alarm, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "sngTopic"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*topic_sng != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*topic_sng);
}
*topic_sng = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*topic_sng, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "protocol"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*protocol != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*protocol);
}
*protocol = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*protocol, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "mechanisms"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*mechanisms != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*mechanisms);
}
*mechanisms = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*mechanisms, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "serviceName"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*service_name != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*service_name);
}
*service_name = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*service_name, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "principal"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*principal != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*principal);
}
*principal = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*principal, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "domainName"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*domain_name != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*domain_name);
}
*domain_name = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*domain_name, json_node->valuestring);
}
}
}
cJSON_Delete(json);
}
void Read_Nacos_Param_Web(char** client_id, char** client_secret, char** token_url, char** device_url, char** grant_type) {
char* ptr = NULL;
SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "web", &ptr);
//cout << ">>>GetDevice in reply" << (char*)ptr;
int flag = 1;
cJSON* json = cJSON_Parse(ptr); //json<6F><6E>ʽ<EFBFBD><CABD><EFBFBD>л<EFBFBD>
cJSON* json_node;
cJSON* json_param;
if (json == NULL) {
printf("nacos error %s\n", cJSON_GetErrorPtr());
}
else {
json_node = cJSON_GetObjectItem(json, "status"); //<2F><>ȡresult
if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) {
printf("status error :%s\n", cJSON_GetErrorPtr());
flag = 0;
}
json_node = cJSON_GetObjectItem(json, "errors"); //<2F><>ȡresult
if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) {
printf("errors get falie: %s\n", cJSON_GetErrorPtr());
flag = 0;
}
if (flag) {
printf("read nacos success\n");
json_param = cJSON_GetObjectItem(json, "param"); //<2F><>ȡresult
json_node = cJSON_GetObjectItem(json_param, "clientId"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*client_id != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*client_id);
}
*client_id = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*client_id, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "clientSecret"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*client_secret != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*client_secret);
}
*client_secret = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*client_secret, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "tokenUrl"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*token_url != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*token_url);
}
*token_url = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*token_url, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "deviceUrl"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
//***postgres_pwd = json_node->valuestring;
if (*device_url != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*device_url);
}
*device_url = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*device_url, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "grantType"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*grant_type != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*grant_type);
}
*grant_type = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*grant_type, json_node->valuestring);
}
}
}
cJSON_Delete(json);
}
void Read_Nacos_Param_Flag(int* file_flag, int* send_flag, int* front_inst, char** front_ip) {
char* ptr = NULL;
SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "flag", &ptr);
//cout << ">>>GetDevice in reply" << (char*)ptr;
int flag = 1;
cJSON* json = cJSON_Parse(ptr); //json<6F><6E>ʽ<EFBFBD><CABD><EFBFBD>л<EFBFBD>
cJSON* json_node;
cJSON* json_param;
if (json == NULL) {
printf("nacos error: %s\n", ptr);
}
else {
json_node = cJSON_GetObjectItem(json, "status"); //<2F><>ȡresult
if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) {
printf("status error :%s\n", cJSON_GetErrorPtr());
flag = 0;
}
json_node = cJSON_GetObjectItem(json, "errors"); //<2F><>ȡresult
if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) {
printf("errors get falie: %s\n", cJSON_GetErrorPtr());
flag = 0;
}
if (flag) {
printf("read nacos success\n");
json_param = cJSON_GetObjectItem(json, "param"); //<2F><>ȡresult
json_node = cJSON_GetObjectItem(json_param, "fileFlag"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
*file_flag= atoi(json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "sendFlag"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
*send_flag = atoi(json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "frontInst"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
*front_inst = atoi(json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "frontIP"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
//***postgres_pwd = json_node->valuestring;
if (*front_ip != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*front_ip);
}
*front_ip = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*front_ip, json_node->valuestring);
}
}
}
cJSON_Delete(json);
}
void Read_Nacos_Param_Recall(int* recall_len, int* recall_sta, int* recall_daily) {
char* ptr = NULL;
SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "recall", &ptr);
//cout << ">>>GetDevice in reply" << (char*)ptr;
int flag = 1;
cJSON* json = cJSON_Parse(ptr); //json<6F><6E>ʽ<EFBFBD><CABD><EFBFBD>л<EFBFBD>
cJSON* json_node;
cJSON* json_param;
if (json == NULL) {
printf("nacos error %s\n", cJSON_GetErrorPtr());
}
else {
json_node = cJSON_GetObjectItem(json, "status"); //<2F><>ȡresult
if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) {
printf("status error :%s\n", cJSON_GetErrorPtr());
flag = 0;
}
json_node = cJSON_GetObjectItem(json, "errors"); //<2F><>ȡresult
if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) {
printf("errors get falie: %s\n", cJSON_GetErrorPtr());
flag = 0;
}
if (flag) {
printf("read nacos success\n");
json_param = cJSON_GetObjectItem(json, "param"); //<2F><>ȡresult
json_node = cJSON_GetObjectItem(json_param, "recall_lenth"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
*recall_len = atoi(json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "recall_start"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
*recall_sta = atoi(json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "recall_dailytime"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
*recall_daily = atoi(json_node->valuestring);
}
}
}
cJSON_Delete(json);
}
void Read_Nacos_Param_Uds(char** uds_upload_url, char** uds_download_url, char** uds_delete_url) {
char* ptr = NULL;
SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "uds", &ptr);
//cout << ">>>GetDevice in reply" << (char*)ptr;
int flag = 1;
cJSON* json = cJSON_Parse(ptr); //json<6F><6E>ʽ<EFBFBD><CABD><EFBFBD>л<EFBFBD>
cJSON* json_node;
cJSON* json_param;
if (json == NULL) {
printf("nacos error %s\n", cJSON_GetErrorPtr());
}
else {
json_node = cJSON_GetObjectItem(json, "status"); //<2F><>ȡresult
if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) {
printf("status error :%s\n", cJSON_GetErrorPtr());
flag = 0;
}
json_node = cJSON_GetObjectItem(json, "errors"); //<2F><>ȡresult
if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) {
printf("errors get falie: %s\n", cJSON_GetErrorPtr());
flag = 0;
}
if (flag) {
printf("read nacos success\n");
json_param = cJSON_GetObjectItem(json, "param"); //<2F><>ȡresult
json_node = cJSON_GetObjectItem(json_param, "udsUploadUrl"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*uds_upload_url != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*uds_upload_url);
}
*uds_upload_url = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*uds_upload_url, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "udsDownloadUrl"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*uds_download_url != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*uds_download_url);
}
*uds_download_url = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*uds_download_url, json_node->valuestring);
}
json_node = cJSON_GetObjectItem(json_param, "UdsDeleteUrl"); //<2F><>ȡresult
if (json_node && json_node->type == cJSON_String) {
if (*uds_delete_url != NULL) {
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
free(*uds_delete_url);
}
*uds_delete_url = (char*)malloc(strlen(json_node->valuestring) + 1); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
strcpy(*uds_delete_url, json_node->valuestring);
}
}
}
cJSON_Delete(json);
}
#ifdef __cplusplus
}
#endif

306
cfg_parse/obs_huaweiyun.cpp Normal file
View File

@@ -0,0 +1,306 @@
/**
* @file: $RCSfile: obs_huaweiyun.cpp,v $
* @brief: $huaweiyun obs include
*
* @version: $Revision: 1.00 $
* @date: $Date: 2023/09/04 18:34:00 $
* @author: $Author: wangwei $
* @state: $State: Exp $
*
* @latest: $Id: obs_huaweiyun.cpp,v 1.00 2023/09/04 18:34:00 wangwei Exp $
*
*/
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "../mms/db_interface.h"
#include "../json/cjson.h"//WW 2023-08-27<32><37><EFBFBD><EFBFBD>json<6F><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include "../include/curl/curl.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
char ACCESS_KEY_ID_OBS[2048] = { "J9GS9EA79PZ60OK23LWP" };
char SECRET_ACCESS_KEY[2048] = { "BirGrAFDSLxU8ow5fffyXgZRAmMRb1R1AdqCI60d" };
char HOST_NAME[2048] = { "obs.cn-east-3.myhuaweicloud.com" };
char BUCKET_NAME_OBS[2048] = { "test-8601" };
size_t req_reply_device(void* ptr, size_t size, size_t nmemb, void* stream)
{
//<2F><>ע<EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cookie<69><65><EFBFBD><EFBFBD>Ϣ
string* str = (string*)stream;
(*str).append((char*)ptr, size * nmemb);
//printf(">>>GetDevice in reply %s\n", (char*)ptr);
//GetCJson(ptr);
return size * nmemb;
}
void SendWebAPI_Test(const string strUrl)
{
// curl<72><6C>ʼ<EFBFBD><CABC>
CURL* curl = curl_easy_init();
// curl<72><6C><EFBFBD><EFBFBD>ֵ
CURLcode res;
if (curl)
{
//<2F><><EFBFBD><EFBFBD>curl<72><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
struct curl_slist* header_list = NULL;
header_list = curl_slist_append(header_list, "Content-Type:application/json;");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧͷ<D3A6><CDB7><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_HEADER, 0);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊpost<73><74><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_POST, 1);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>URL<52><4C>ַ
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
//<2F><><EFBFBD><EFBFBD>post<73><74><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>
cJSON* json_root = cJSON_CreateObject();
cJSON* json_param = cJSON_CreateObject();
cJSON_AddItemToObject(json_root, "code", cJSON_CreateString("putObject"));
cJSON_AddItemToObject(json_root, "param", json_param);
//param<61><6D>
cJSON_AddItemToObject(json_param, "object_name", cJSON_CreateString("comtrade/pq/Device.xml"));
cJSON_AddItemToObject(json_param, "localfile_name", cJSON_CreateString("/FeProject/etc/Device_Config.xml"));
char* szjson = cJSON_Print(json_root);
printf(">>>json %s\n", szjson);
//string strjson = szjson;
//char* pszEncodeSecret = curl_easy_escape(curl, strclientsecret.c_str(), strclientsecret.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, szjson);
//<2F><><EFBFBD><EFBFBD>ssl<73><6C>֤
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
//CURLOPT_VERBOSE<53><45>ֵΪ1ʱ<31><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ϸ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>Ϣ
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><DDBD>պ<EFBFBD>д<EFBFBD><EFBFBD><EBBAAF>
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_device);
string resPost0;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
//<2F><><EFBFBD>ó<EFBFBD>ʱʱ<CAB1><CAB1>
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
printf(">>>TestHuaweiyun Obs Post in curl post\n");
// <20><><EFBFBD><EFBFBD>post<73><74><EFBFBD><EFBFBD>
res = curl_easy_perform(curl);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ɹ<EFBFBD>
if (res != CURLE_OK) {
printf("Huaweiyun Obs failed res code: " );
}
else {
printf("Huaweiyun Obs success,string %s",resPost0.c_str());
}
curl_slist_free_all(header_list);
free(szjson);
cJSON_Delete(json_root);
}
else
{
printf(">>> token curl init failed");
}
curl_easy_cleanup(curl);
}
void TestOBS()
{
SendWebAPI_Test("http://127.0.0.1:8091/powerQuality/PQOBS");
}
void SendWebAPI(const string strUrl, char* localpath, char* cloudpath,const char* code)
{
// curl<72><6C>ʼ<EFBFBD><CABC>
CURL* curl = curl_easy_init();
// curl<72><6C><EFBFBD><EFBFBD>ֵ
CURLcode res;
if (curl)
{
//<2F><><EFBFBD><EFBFBD>curl<72><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
struct curl_slist* header_list = NULL;
header_list = curl_slist_append(header_list, "Content-Type:application/json;");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧͷ<D3A6><CDB7><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_HEADER, 0);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊpost<73><74><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_POST, 1);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>URL<52><4C>ַ
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
//<2F><><EFBFBD><EFBFBD>post<73><74><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>
cJSON* json_root = cJSON_CreateObject();
cJSON* json_param = cJSON_CreateObject();
cJSON_AddItemToObject(json_root, "code", cJSON_CreateString(code));
cJSON_AddItemToObject(json_root, "param", json_param);
//param<61><6D>
cJSON_AddItemToObject(json_param, "object_name", cJSON_CreateString(cloudpath));
cJSON_AddItemToObject(json_param, "localfile_name", cJSON_CreateString(localpath));
char* szjson = cJSON_Print(json_root);
printf(">>>json %s\n", szjson);
//string strjson = szjson;
//char* pszEncodeSecret = curl_easy_escape(curl, strclientsecret.c_str(), strclientsecret.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, szjson);
//<2F><><EFBFBD><EFBFBD>ssl<73><6C>֤
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
//CURLOPT_VERBOSE<53><45>ֵΪ1ʱ<31><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ϸ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>Ϣ
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><DDBD>պ<EFBFBD>д<EFBFBD><EFBFBD><EBBAAF>
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_device);
string resPost0;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
//<2F><><EFBFBD>ó<EFBFBD>ʱʱ<CAB1><CAB1>
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
printf(">>>TestHuaweiyun Obs Post in curl post\n");
// <20><><EFBFBD><EFBFBD>post<73><74><EFBFBD><EFBFBD>
res = curl_easy_perform(curl);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ɹ<EFBFBD>
if (res != CURLE_OK) {
printf("Huaweiyun Obs failed res code: ");
}
else {
printf("Huaweiyun Obs success,string %s", resPost0.c_str());
}
curl_slist_free_all(header_list);
free(szjson);
cJSON_Delete(json_root);
}
else
{
printf(">>> token curl init failed");
}
curl_easy_cleanup(curl);
}
void OBSFile(char* localpath,char* cloudpath,const char* code)
{
SendWebAPI("http://127.0.0.1:8091/powerQuality/PQOBS",localpath,cloudpath,code);
}
void SendWebAPI_del(const string strUrl, char* cloudpath, const char* code)
{
// curl<72><6C>ʼ<EFBFBD><CABC>
CURL* curl = curl_easy_init();
// curl<72><6C><EFBFBD><EFBFBD>ֵ
CURLcode res;
if (curl)
{
//<2F><><EFBFBD><EFBFBD>curl<72><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
struct curl_slist* header_list = NULL;
header_list = curl_slist_append(header_list, "Content-Type:application/json;");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧͷ<D3A6><CDB7><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_HEADER, 0);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊpost<73><74><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_POST, 1);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>URL<52><4C>ַ
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
//<2F><><EFBFBD><EFBFBD>post<73><74><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>
cJSON* json_root = cJSON_CreateObject();
cJSON* json_param = cJSON_CreateObject();
cJSON_AddItemToObject(json_root, "code", cJSON_CreateString(code));
cJSON_AddItemToObject(json_root, "param", json_param);
//param<61><6D>
cJSON_AddItemToObject(json_param, "object_name", cJSON_CreateString(cloudpath));
cJSON_AddNullToObject(json_param, "localfile_name");
//cJSON_AddItemToObject(json_param, "localfile_name", cJSON_CreateString(localpath));
char* szjson = cJSON_Print(json_root);
printf(">>>json %s\n", szjson);
//string strjson = szjson;
//char* pszEncodeSecret = curl_easy_escape(curl, strclientsecret.c_str(), strclientsecret.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, szjson);
//<2F><><EFBFBD><EFBFBD>ssl<73><6C>֤
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
//CURLOPT_VERBOSE<53><45>ֵΪ1ʱ<31><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ϸ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>Ϣ
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><DDBD>պ<EFBFBD>д<EFBFBD><EFBFBD><EBBAAF>
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_device);
string resPost0;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
//<2F><><EFBFBD>ó<EFBFBD>ʱʱ<CAB1><CAB1>
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
printf(">>>TestHuaweiyun Obs Post in curl post\n");
// <20><><EFBFBD><EFBFBD>post<73><74><EFBFBD><EFBFBD>
res = curl_easy_perform(curl);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ɹ<EFBFBD>
if (res != CURLE_OK) {
printf("Huaweiyun Obs failed res code: ");
}
else {
printf("Huaweiyun Obs success,string %s", resPost0.c_str());
}
curl_slist_free_all(header_list);
free(szjson);
cJSON_Delete(json_root);
}
else
{
printf(">>> token curl init failed");
}
curl_easy_cleanup(curl);
}
void OBSFile_del(char* cloudpath, const char* code)
{
SendWebAPI_del("http://127.0.0.1:8091/powerQuality/PQOBS", cloudpath, code);
}
#ifdef __cplusplus
}
#endif

510
cfg_parse/oss_aliyun.cpp Normal file
View File

@@ -0,0 +1,510 @@
/**
* @file: $RCSfile: oss_aliyun.cpp,v $
* @brief: $aliyun oss include
*
* @version: $Revision: 1.01 $
* @date: $Date: 2023/08/31 23:02:00 $
* @author: $Author: wangwei $
* @state: $State: Exp $
*
* @latest: $Id: oss_aliyun.cpp,v 1.01 2023/08/31 23:02:00 wangwei Exp $
*
*/
using namespace std;
#include "aos_log.h"
#include "aos_util.h"
#include "aos_string.h"
#include "aos_status.h"
#include "oss_auth.h"
#include "oss_util.h"
#include "oss_api.h"
#include "../mms/db_interface.h"
#include <iostream>
char* OSS_ENDPOINT;
char* ACCESS_KEY_ID;
char* ACCESS_KEY_SECRET;
char* BUCKET_NAME;
//const char OSS_ENDPOINT[] = "oss-cn-nanjing.aliyuncs.com";
//const char ACCESS_KEY_ID[] = "LTAI5tER4bgJxT6Ptie7t2X7";
//const char ACCESS_KEY_SECRET[] = "dSYIC5hD3flhTNoLMAxCoKjSPdWFSz";
//const char BUCKET_NAME[] = "cn-pq-test";
const char OBJECT_NAME[] = "comtrade/temp.json";
void init_sample_request_options(oss_request_options_t *options, int is_cname);
void put_object_from_buffer();
void put_object_from_buffer_new(char* File_Name, char* data);
void put_object_from_file();
void put_object_from_file_new(char* File_Name, char* path);
void get_object_to_buffer();
void get_object_to_file();
void get_object_to_file_new(char* File_Name, char* savepath);
void delete_object();
void delete_object_new(char* File_Name);
void TestOSS()
{
apr_file_t *output = NULL;
aos_pool_t *pool = NULL;
apr_status_t ret;
// initialize http io system, call it olny once
/* <20>ڳ<EFBFBD><DAB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>aos_http_io_initialize<7A><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4>*/
printf(">>>TestOSS ini Start");
if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
return;
}
printf(">>>TestOSS put Start");
// run samples
//put_object_from_buffer();
//put_object_from_file();
put_object_from_buffer();
get_object_to_file();
//get_object_to_buffer();
//get_object_to_file();
//delete_object();
printf(">>>TestOSS put End");
// deinitialize http io system, call it olny once
aos_http_io_deinitialize();
return ;
}
void PutOSS(char* File_Name,char* data) //zw<7A>޸<EFBFBD> 2023-9-7 <20><><EFBFBD><EFBFBD>oss<73>ļ<EFBFBD>
{
apr_file_t* output = NULL;
aos_pool_t* pool = NULL;
apr_status_t ret;
// initialize http io system, call it olny once
/* <20>ڳ<EFBFBD><DAB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>aos_http_io_initialize<7A><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4>*/
printf(">>>PutOSS ini Start");
printf(File_Name);
printf(data);
if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
return;
}
printf(">>>PutOSS put Start");
put_object_from_file_new(File_Name, data);//ʹ<><CAB9>buffer<65><72><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
printf(">>>PutOSS put End");
// deinitialize http io system, call it olny once
aos_http_io_deinitialize();
return;
}
void GetOSS(char* File_Name,char* savepath) //zw<7A>޸<EFBFBD> 2023-9-7 <20><>ȡoss<73>ļ<EFBFBD>
{
apr_file_t* output = NULL;
aos_pool_t* pool = NULL;
apr_status_t ret;
// initialize http io system, call it olny once
/* <20>ڳ<EFBFBD><DAB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>aos_http_io_initialize<7A><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4>*/
printf(">>>GetOSS ini Start");
if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
return;
}
printf(">>>GetOSS put Start");
get_object_to_file_new(File_Name,savepath);//ʹ<><CAB9>buffer<65><72><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
printf(">>>GetOSS put End");
// deinitialize http io system, call it olny once
aos_http_io_deinitialize();
return;
}
void DelOSS(char* File_Name)
{
apr_file_t* output = NULL;
aos_pool_t* pool = NULL;
apr_status_t ret;
// initialize http io system, call it olny once
/* <20>ڳ<EFBFBD><DAB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>aos_http_io_initialize<7A><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4>*/
printf(">>>DelOSS ini Start");
if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
return;
}
printf(">>>DelOSS put Start");
delete_object_new(File_Name);//ʹ<><CAB9>buffer<65><72><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
printf(">>>DelOSS put End");
// deinitialize http io system, call it olny once
aos_http_io_deinitialize();
return;
}
void coutTest() {
std:: cout << "OSS_ENDPOINT:" << OSS_ENDPOINT << std::endl;
std::cout << "ACCESS_KEY_ID:" << ACCESS_KEY_ID << std::endl;
std::cout << "ACCESS_KEY_SECRET:" << ACCESS_KEY_SECRET << std::endl;
std::cout << "BUCKET_NAME:" << BUCKET_NAME << std::endl;
}
void init_sample_request_options(oss_request_options_t *options, int is_cname)
{
options->config = oss_config_create(options->pool);
aos_str_set(&options->config->endpoint, OSS_ENDPOINT);
aos_str_set(&options->config->access_key_id, ACCESS_KEY_ID);
aos_str_set(&options->config->access_key_secret, ACCESS_KEY_SECRET);
options->config->is_cname = is_cname;
options->ctl = aos_http_controller_create(options->pool, 0);
}
void put_object_from_buffer()
{
aos_pool_t *p = NULL;
aos_string_t bucket;
aos_string_t object;
int is_cname = 0;
aos_table_t *headers = NULL;
aos_table_t *resp_headers = NULL;
oss_request_options_t *options = NULL;
aos_list_t buffer;
aos_buf_t *content = NULL;
char *str = "test oss c sdk";
aos_status_t *s = NULL;
aos_pool_create(&p, NULL);
options = oss_request_options_create(p);
init_sample_request_options(options, is_cname);
headers = aos_table_make(p, 1);
apr_table_set(headers, "x-oss-meta-author", "oss");
aos_str_set(&bucket, BUCKET_NAME);
aos_str_set(&object, OBJECT_NAME);
aos_list_init(&buffer);
content = aos_buf_pack(options->pool, str, strlen(str));
aos_list_add_tail(&content->node, &buffer);
s = oss_put_object_from_buffer(options, &bucket, &object,
&buffer, headers, &resp_headers);
if (aos_status_is_ok(s)) {
printf("put object from buffer succeeded\n");
}
else {
printf("put object from buffer failed\n");
}
aos_pool_destroy(p);
}
void put_object_from_buffer_new(char* File_Name,char* data)//zw<7A>޸<EFBFBD> 2023-9-7 oss<73><73><EFBFBD><EFBFBD>
{
aos_pool_t* p = NULL;
aos_string_t bucket;
aos_string_t object;
int is_cname = 0;
aos_table_t* headers = NULL;
aos_table_t* resp_headers = NULL;
oss_request_options_t* options = NULL;
aos_list_t buffer;
aos_buf_t* content = NULL;
char* str = data;
aos_status_t* s = NULL;
aos_pool_create(&p, NULL);
options = oss_request_options_create(p);
init_sample_request_options(options, is_cname);
headers = aos_table_make(p, 1);
apr_table_set(headers, "x-oss-meta-author", "oss");
aos_str_set(&bucket, BUCKET_NAME);
aos_str_set(&object, File_Name);
aos_list_init(&buffer);
content = aos_buf_pack(options->pool, str, strlen(str));
aos_list_add_tail(&content->node, &buffer);
s = oss_put_object_from_buffer(options, &bucket, &object,
&buffer, headers, &resp_headers);
if (aos_status_is_ok(s)) {
printf("put object from buffer succeeded\n");
}
else {
printf("put object from buffer failed\n");
}
aos_pool_destroy(p);
}
void put_object_from_file()
{
aos_pool_t *p = NULL;
aos_string_t bucket;
aos_string_t object;
/* <20>Ƿ<EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD>CNAME<4D><45>0<EFBFBD><30>ʾ<EFBFBD><CABE>ʹ<EFBFBD>á<EFBFBD>*/
int is_cname = 0;
aos_table_t *headers = NULL;
aos_table_t *resp_headers = NULL;
oss_request_options_t *options = NULL;
char *filename = "/home/pq/FeProject/etc/Device_Config.xml";
aos_status_t *s = NULL;
aos_string_t file;
/* <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4>أ<EFBFBD>pool<6F><6C><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>apr_pool_t<5F><74><EFBFBD><EFBFBD>ʵ<EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD>apr<70><72><EFBFBD>С<EFBFBD>*/
aos_pool_create(&p, NULL);
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>options<6E><73><EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>endpoint<6E><74>access_key_id<69><64>acces_key_secret<65><74>is_cname<6D><65>curl<72><6C>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>*/
options = oss_request_options_create(p);
init_sample_request_options(options, is_cname);
aos_str_set(&bucket, BUCKET_NAME);
aos_str_set(&object, OBJECT_NAME);
aos_str_set(&file, filename);
s = oss_put_object_from_file(options, &bucket, &object, &file,
headers, &resp_headers);
if (aos_status_is_ok(s)) {
printf("put object from file succeeded\n");
}
else {
printf("put object from file failed, code:%d, error_code:%s, error_msg:%s, request_id:%s\n",
s->code, s->error_code, s->error_msg, s->req_id);
}
aos_pool_destroy(p);
}
void put_object_from_file_new(char* File_Name, char* path)
{
aos_pool_t* p = NULL;
aos_string_t bucket;
aos_string_t object;
/* <20>Ƿ<EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD>CNAME<4D><45>0<EFBFBD><30>ʾ<EFBFBD><CABE>ʹ<EFBFBD>á<EFBFBD>*/
int is_cname = 0;
aos_table_t* headers = NULL;
aos_table_t* resp_headers = NULL;
oss_request_options_t* options = NULL;
char* filename = path;
aos_status_t* s = NULL;
aos_string_t file;
/* <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4>أ<EFBFBD>pool<6F><6C><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>apr_pool_t<5F><74><EFBFBD><EFBFBD>ʵ<EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD>apr<70><72><EFBFBD>С<EFBFBD>*/
aos_pool_create(&p, NULL);
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>options<6E><73><EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>endpoint<6E><74>access_key_id<69><64>acces_key_secret<65><74>is_cname<6D><65>curl<72><6C>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>*/
options = oss_request_options_create(p);
init_sample_request_options(options, is_cname);
aos_str_set(&bucket, BUCKET_NAME);
aos_str_set(&object, File_Name);
aos_str_set(&file, filename);
s = oss_put_object_from_file(options, &bucket, &object, &file,
headers, &resp_headers);
if (aos_status_is_ok(s)) {
printf("put object from file succeeded\n");
}
else {
printf("put object from file failed, code:%d, error_code:%s, error_msg:%s, request_id:%s\n",
s->code, s->error_code, s->error_msg, s->req_id);
}
aos_pool_destroy(p);
}
void get_object_to_buffer()
{
aos_pool_t *p = NULL;
aos_string_t bucket;
aos_string_t object;
int is_cname = 0;
oss_request_options_t *options = NULL;
aos_table_t *headers = NULL;
aos_table_t *params = NULL;
aos_table_t *resp_headers = NULL;
aos_status_t *s = NULL;
aos_list_t buffer;
aos_buf_t *content = NULL;
char *buf = NULL;
int64_t len = 0;
int64_t size = 0;
int64_t pos = 0;
aos_pool_create(&p, NULL);
options = oss_request_options_create(p);
init_sample_request_options(options, is_cname);
aos_str_set(&bucket, BUCKET_NAME);
aos_str_set(&object, OBJECT_NAME);
aos_list_init(&buffer);
s = oss_get_object_to_buffer(options, &bucket, &object,
headers, params, &buffer, &resp_headers);
if (aos_status_is_ok(s)) {
printf("get object to buffer succeeded\n");
}
else {
printf("get object to buffer failed\n");
}
//get buffer len
aos_list_for_each_entry(aos_buf_t, content, &buffer, node) {
len += aos_buf_size(content);
}
buf = (char*)aos_pcalloc(p, (apr_size_t)(len + 1));
buf[len] = '\0';
//copy buffer content to memory
aos_list_for_each_entry(aos_buf_t, content, &buffer, node) {
size = aos_buf_size(content);
memcpy(buf + pos, content->pos, (size_t)size);
pos += size;
}
aos_pool_destroy(p);
}
void get_object_to_file()
{
aos_pool_t *p = NULL;
aos_string_t bucket;
char *download_filename = "Data/tempbuff.jpg";
aos_string_t object;
int is_cname = 0;
oss_request_options_t *options = NULL;
aos_table_t *headers = NULL;
aos_table_t *params = NULL;
aos_table_t *resp_headers = NULL;
aos_status_t *s = NULL;
aos_string_t file;
aos_pool_create(&p, NULL);
options = oss_request_options_create(p);
init_sample_request_options(options, is_cname);
aos_str_set(&bucket, BUCKET_NAME);
aos_str_set(&object, OBJECT_NAME);
headers = aos_table_make(p, 0);
aos_str_set(&file, download_filename);
s = oss_get_object_to_file(options, &bucket, &object, headers,
params, &file, &resp_headers);
if (aos_status_is_ok(s)) {
printf("get object to local file succeeded\n");
}
else {
printf("get object to local file failed\n");
}
aos_pool_destroy(p);
}
void get_object_to_file_new(char* File_Name,char* savepath)
{
aos_pool_t* p = NULL;
aos_string_t bucket;
char* download_filename = savepath;
aos_string_t object;
int is_cname = 0;
oss_request_options_t* options = NULL;
aos_table_t* headers = NULL;
aos_table_t* params = NULL;
aos_table_t* resp_headers = NULL;
aos_status_t* s = NULL;
aos_string_t file;
aos_pool_create(&p, NULL);
options = oss_request_options_create(p);
init_sample_request_options(options, is_cname);
aos_str_set(&bucket, BUCKET_NAME);
aos_str_set(&object, File_Name);
headers = aos_table_make(p, 0);
aos_str_set(&file, download_filename);
s = oss_get_object_to_file(options, &bucket, &object, headers,
params, &file, &resp_headers);
if (aos_status_is_ok(s)) {
printf("get object to local file succeeded\n");
}
else {
printf("get object to local file failed\n");
}
aos_pool_destroy(p);
}
void delete_object()
{
aos_pool_t *p = NULL;
aos_string_t bucket;
aos_string_t object;
int is_cname = 0;
oss_request_options_t *options = NULL;
aos_table_t *resp_headers = NULL;
aos_status_t *s = NULL;
aos_pool_create(&p, NULL);
options = oss_request_options_create(p);
init_sample_request_options(options, is_cname);
aos_str_set(&bucket, BUCKET_NAME);
aos_str_set(&object, OBJECT_NAME);
s = oss_delete_object(options, &bucket, &object, &resp_headers);
if (aos_status_is_ok(s)) {
printf("delete object succeed\n");
}
else {
printf("delete object failed\n");
}
aos_pool_destroy(p);
}
void delete_object_new(char* File_Name)
{
aos_pool_t* p = NULL;
aos_string_t bucket;
aos_string_t object;
int is_cname = 0;
oss_request_options_t* options = NULL;
aos_status_t* s = NULL;
aos_pool_create(&p, NULL);
options = oss_request_options_create(p);
init_sample_request_options(options, is_cname);
aos_str_set(&bucket, BUCKET_NAME);
aos_str_set(&object, File_Name);
s = oss_delete_objects_by_prefix(options, &bucket, &object);
if (aos_status_is_ok(s)) {
printf("delete object succeed\n");
}
else {
printf("delete object failed\n");
}
aos_pool_destroy(p);
}

319
cfg_parse/uds_huaweiyun.cpp Normal file

File diff suppressed because one or more lines are too long

47
fe_common.pri Normal file
View File

@@ -0,0 +1,47 @@
######################################################################
# common config for project
######################################################################
DEPENDPATH += .
CONFIG += debug_and_release
CONFIG += warn_off
CONFIG -= warn_on
CONFIG(debug, debug|release) {
TARGET = $$join(TARGET,,,d)
QMAKE_CXXFLAGS_DEBUG += -DDEBUG
}
unix {
QMAKE_CXXFLAGS_WARN_ON = -Wall
QMAKE_CXXFLAGS_WARN_OFF = -w
LIBS += -lrt -ldl
OS_VERSION = $$system(uname -a)
contains(OS_VERSION, SunOS) {
#QMAKE_CXXFLAGS +=-D_POSIX_PTHREAD_SEMANTICS
LIBS += -lsocket -lnsl
}
contains(QMAKE_CXXFLAGS, -m64) {
DEFINES +=FE_VERSION_64
}
}
win32 {
DEFINES -= UNICODE
QMAKE_INCDIR = $(QTDIR)/include
QMAKE_INCDIR_QT = $(QTDIR)/include
QMAKE_LIBDIR_QT = $(QTDIR)/lib
QMAKE_LFLAGS_RELEASE = /INCREMENTAL:no
QMAKE_LFLAGS_DEBUG += /INCREMENTAL:no
QMAKE_LFLAGS += /MACHINE:X86
QMAKE_MOC = $$(QTDIR)/bin/moc.exe
QMAKE_RCC = $$(QTDIR)/bin/rcc.exe
QMAKE_UIC = $$(QTDIR)/bin/uic.exe
QMAKE_IDC = $$(QTDIR)/bin/idc.exe
CONFIG -= warn_on
INCLUDEPATH +=$(QTDIR)/mkspecs/win32-msvc2010
QMAKE_CXXFLAGS +=-DWIN32_LEAN_AND_MEAN
#for remove ACE warning
DEFINES += _CRT_SECURE_NO_DEPRECATE _M_IX86 WIN32
}

15
include/CVS/Entries Normal file
View File

@@ -0,0 +1,15 @@
D/apr////
D/apr-linux////
D/mmslite////
/IEC60870DEF.h/1.1/Sat Nov 24 06:54:49 2018//
/ied.h/1.1/Sat Nov 24 06:54:49 2018//
/initools.h/1.1/Sat Nov 24 06:54:49 2018//
/node.h/1.1/Sat Nov 24 06:54:49 2018//
/platform.h/1.1/Sat Nov 24 06:54:50 2018//
/sasstd.h/1.1/Sat Nov 24 06:54:50 2018//
/sasstr.h/1.1/Sat Nov 24 06:54:50 2018//
/sastime.h/1.1/Sat Nov 24 06:54:50 2018//
/utf.h/1.1/Sat Nov 24 06:54:50 2018//
/xmltools.h/1.1/Sat Nov 24 06:54:50 2018//
/sas_system.h/1.2/Thu Dec 20 01:06:15 2018//
/systrace.h/1.2/Wed Apr 17 01:23:51 2019//

15
include/CVS/Entries.Extra Normal file
View File

@@ -0,0 +1,15 @@
D/apr////////
D/apr-linux////////
D/mmslite////////
/IEC60870DEF.h////*////
/ied.h////*////
/initools.h////*////
/node.h////*////
/platform.h////*////
/sasstd.h////*////
/sasstr.h////*////
/sastime.h////*////
/utf.h////*////
/xmltools.h////*////
/sas_system.h////*////
/systrace.h////*////

View File

@@ -0,0 +1,16 @@
D/apr////////
D/apr-linux////////
D/mmslite////////
/IEC60870DEF.h////*////
/ied.h////*////
/initools.h////*////
/node.h////*////
/platform.h////*////
/sasstd.h////*////
/sasstr.h////*////
/sastime.h////*////
/utf.h////*////
/xmltools.h////*////
/sas_system.h////*////
/systrace.h////*////
D/otl////////

16
include/CVS/Entries.Old Normal file
View File

@@ -0,0 +1,16 @@
D/apr////
D/apr-linux////
D/mmslite////
/IEC60870DEF.h/1.1/Sat Nov 24 06:54:49 2018//
/ied.h/1.1/Sat Nov 24 06:54:49 2018//
/initools.h/1.1/Sat Nov 24 06:54:49 2018//
/node.h/1.1/Sat Nov 24 06:54:49 2018//
/platform.h/1.1/Sat Nov 24 06:54:50 2018//
/sasstd.h/1.1/Sat Nov 24 06:54:50 2018//
/sasstr.h/1.1/Sat Nov 24 06:54:50 2018//
/sastime.h/1.1/Sat Nov 24 06:54:50 2018//
/utf.h/1.1/Sat Nov 24 06:54:50 2018//
/xmltools.h/1.1/Sat Nov 24 06:54:50 2018//
/sas_system.h/1.2/Thu Dec 20 01:06:15 2018//
/systrace.h/1.2/Wed Apr 17 01:23:51 2019//
D/otl////

1
include/CVS/Repository Normal file
View File

@@ -0,0 +1 @@
jspqfe/src/pt61850netd_pqfe/source/include

1
include/CVS/Root Normal file
View File

@@ -0,0 +1 @@
:ext:lizhongming@10.0.0.2:/JoyProject

0
include/CVS/Template Normal file
View File

1811
include/IEC60870DEF.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,78 @@
/api_version.h/1.1/Fri Nov 25 08:40:16 2005//
/apr.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_allocator.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_anylock.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_atomic.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_base64.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_buckets.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_date.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_dbd.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_dbm.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_dso.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_env.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_errno.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_file_info.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_file_io.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_fnmatch.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_general.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_getopt.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_global_mutex.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_hash.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_hooks.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_iconv.h/1.1/Fri Nov 25 08:40:30 2005//
/apr_inherit.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_ldap.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_ldap_init.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_ldap_option.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_ldap_rebind.h/1.1/Mon Mar 2 05:02:58 2015//
/apr_ldap_url.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_lib.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_md4.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_md5.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_memcache.h/1.1/Mon Mar 2 05:02:59 2015//
/apr_mmap.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_network_io.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_optional.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_optional_hooks.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_poll.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_pools.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_portable.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_proc_mutex.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_queue.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_random.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_reslist.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_ring.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_rmm.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_sdbm.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_sha1.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_shm.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_signal.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_strings.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_strmatch.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_support.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_tables.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_thread_cond.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_thread_mutex.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_thread_pool.h/1.1/Mon Mar 2 05:03:00 2015//
/apr_thread_proc.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_thread_rwlock.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_time.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_uri.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_user.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_uuid.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_version.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_want.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_xlate.h/1.1/Thu Jun 15 02:48:39 2017//
/apr_xml.h/1.1/Thu Jun 15 02:48:39 2017//
/apu.h/1.1/Thu Jun 15 02:48:39 2017//
/apu.h.in/1.1/Fri Sep 30 07:45:50 2005//
/apu.hnw/1.1/Fri Sep 30 07:45:50 2005//
/apu.hw/1.1/Fri Sep 30 07:45:50 2005//
/apu_version.h/1.1/Thu Jun 15 02:48:39 2017//
/apu_want.h/1.1/Thu Jun 15 02:48:39 2017//
/apu_want.h.in/1.1/Fri Sep 30 07:45:50 2005//
/apu_want.hnw/1.1/Fri Sep 30 07:45:50 2005//
/apu_want.hw/1.1/Fri Sep 30 07:45:50 2005//
/expat.h/1.1/Thu Jun 15 02:48:39 2017//
/expat_external.h/1.1/Mon Dec 19 07:31:20 2005//
D

View File

@@ -0,0 +1,77 @@
/api_version.h////*////
/apr.h////*////
/apr_allocator.h////*////
/apr_anylock.h////*////
/apr_atomic.h////*////
/apr_base64.h////*////
/apr_buckets.h////*////
/apr_date.h////*////
/apr_dbd.h////*////
/apr_dbm.h////*////
/apr_dso.h////*////
/apr_env.h////*////
/apr_errno.h////*////
/apr_file_info.h////*////
/apr_file_io.h////*////
/apr_fnmatch.h////*////
/apr_general.h////*////
/apr_getopt.h////*////
/apr_global_mutex.h////*////
/apr_hash.h////*////
/apr_hooks.h////*////
/apr_iconv.h////*////
/apr_inherit.h////*////
/apr_ldap.h////*////
/apr_ldap_init.h////*////
/apr_ldap_option.h////*////
/apr_ldap_rebind.h////*////
/apr_ldap_url.h////*////
/apr_lib.h////*////
/apr_md4.h////*////
/apr_md5.h////*////
/apr_memcache.h////*////
/apr_mmap.h////*////
/apr_network_io.h////*////
/apr_optional.h////*////
/apr_optional_hooks.h////*////
/apr_poll.h////*////
/apr_pools.h////*////
/apr_portable.h////*////
/apr_proc_mutex.h////*////
/apr_queue.h////*////
/apr_random.h////*////
/apr_reslist.h////*////
/apr_ring.h////*////
/apr_rmm.h////*////
/apr_sdbm.h////*////
/apr_sha1.h////*////
/apr_shm.h////*////
/apr_signal.h////*////
/apr_strings.h////*////
/apr_strmatch.h////*////
/apr_support.h////*////
/apr_tables.h////*////
/apr_thread_cond.h////*////
/apr_thread_mutex.h////*////
/apr_thread_pool.h////*////
/apr_thread_proc.h////*////
/apr_thread_rwlock.h////*////
/apr_time.h////*////
/apr_uri.h////*////
/apr_user.h////*////
/apr_uuid.h////*////
/apr_version.h////*////
/apr_want.h////*////
/apr_xlate.h////*////
/apr_xml.h////*////
/apu.h////*////
/apu.h.in////*////
/apu.hnw////*////
/apu.hw////*////
/apu_version.h////*////
/apu_want.h////*////
/apu_want.h.in////*////
/apu_want.hnw////*////
/apu_want.hw////*////
/expat.h////*////
/expat_external.h////*////

View File

@@ -0,0 +1,77 @@
/api_version.h////*////
/apr.h////*////
/apr_allocator.h////*////
/apr_anylock.h////*////
/apr_atomic.h////*////
/apr_base64.h////*////
/apr_buckets.h////*////
/apr_date.h////*////
/apr_dbd.h////*////
/apr_dbm.h////*////
/apr_dso.h////*////
/apr_env.h////*////
/apr_errno.h////*////
/apr_file_info.h////*////
/apr_file_io.h////*////
/apr_fnmatch.h////*////
/apr_general.h////*////
/apr_getopt.h////*////
/apr_global_mutex.h////*////
/apr_hash.h////*////
/apr_hooks.h////*////
/apr_iconv.h////*////
/apr_inherit.h////*////
/apr_ldap.h////*////
/apr_ldap_init.h////*////
/apr_ldap_option.h////*////
/apr_ldap_rebind.h////*////
/apr_ldap_url.h////*////
/apr_lib.h////*////
/apr_md4.h////*////
/apr_md5.h////*////
/apr_memcache.h////*////
/apr_mmap.h////*////
/apr_network_io.h////*////
/apr_optional.h////*////
/apr_optional_hooks.h////*////
/apr_poll.h////*////
/apr_pools.h////*////
/apr_portable.h////*////
/apr_proc_mutex.h////*////
/apr_queue.h////*////
/apr_random.h////*////
/apr_reslist.h////*////
/apr_ring.h////*////
/apr_rmm.h////*////
/apr_sdbm.h////*////
/apr_sha1.h////*////
/apr_shm.h////*////
/apr_signal.h////*////
/apr_strings.h////*////
/apr_strmatch.h////*////
/apr_support.h////*////
/apr_tables.h////*////
/apr_thread_cond.h////*////
/apr_thread_mutex.h////*////
/apr_thread_pool.h////*////
/apr_thread_proc.h////*////
/apr_thread_rwlock.h////*////
/apr_time.h////*////
/apr_uri.h////*////
/apr_user.h////*////
/apr_uuid.h////*////
/apr_version.h////*////
/apr_want.h////*////
/apr_xlate.h////*////
/apr_xml.h////*////
/apu.h////*////
/apu.h.in////*////
/apu.hnw////*////
/apu.hw////*////
/apu_version.h////*////
/apu_want.h////*////
/apu_want.h.in////*////
/apu_want.hnw////*////
/apu_want.hw////*////
/expat.h////*////
/expat_external.h////*////

View File

@@ -0,0 +1,78 @@
/api_version.h/0/dummy timestamp//
/apr.h/0/dummy timestamp//
/apr_allocator.h/0/dummy timestamp//
/apr_anylock.h/0/dummy timestamp//
/apr_atomic.h/0/dummy timestamp//
/apr_base64.h/0/dummy timestamp//
/apr_buckets.h/0/dummy timestamp//
/apr_date.h/0/dummy timestamp//
/apr_dbd.h/0/dummy timestamp//
/apr_dbm.h/0/dummy timestamp//
/apr_dso.h/0/dummy timestamp//
/apr_env.h/0/dummy timestamp//
/apr_errno.h/0/dummy timestamp//
/apr_file_info.h/0/dummy timestamp//
/apr_file_io.h/0/dummy timestamp//
/apr_fnmatch.h/0/dummy timestamp//
/apr_general.h/0/dummy timestamp//
/apr_getopt.h/0/dummy timestamp//
/apr_global_mutex.h/0/dummy timestamp//
/apr_hash.h/0/dummy timestamp//
/apr_hooks.h/0/dummy timestamp//
/apr_iconv.h/0/dummy timestamp//
/apr_inherit.h/0/dummy timestamp//
/apr_ldap.h/0/dummy timestamp//
/apr_ldap_init.h/0/dummy timestamp//
/apr_ldap_option.h/0/dummy timestamp//
/apr_ldap_rebind.h/0/dummy timestamp//
/apr_ldap_url.h/0/dummy timestamp//
/apr_lib.h/0/dummy timestamp//
/apr_md4.h/0/dummy timestamp//
/apr_md5.h/0/dummy timestamp//
/apr_memcache.h/0/dummy timestamp//
/apr_mmap.h/0/dummy timestamp//
/apr_network_io.h/0/dummy timestamp//
/apr_optional.h/0/dummy timestamp//
/apr_optional_hooks.h/0/dummy timestamp//
/apr_poll.h/0/dummy timestamp//
/apr_pools.h/0/dummy timestamp//
/apr_portable.h/0/dummy timestamp//
/apr_proc_mutex.h/0/dummy timestamp//
/apr_queue.h/0/dummy timestamp//
/apr_random.h/0/dummy timestamp//
/apr_reslist.h/0/dummy timestamp//
/apr_ring.h/0/dummy timestamp//
/apr_rmm.h/0/dummy timestamp//
/apr_sdbm.h/0/dummy timestamp//
/apr_sha1.h/0/dummy timestamp//
/apr_shm.h/0/dummy timestamp//
/apr_signal.h/0/dummy timestamp//
/apr_strings.h/0/dummy timestamp//
/apr_strmatch.h/0/dummy timestamp//
/apr_support.h/0/dummy timestamp//
/apr_tables.h/0/dummy timestamp//
/apr_thread_cond.h/0/dummy timestamp//
/apr_thread_mutex.h/0/dummy timestamp//
/apr_thread_pool.h/0/dummy timestamp//
/apr_thread_proc.h/0/dummy timestamp//
/apr_thread_rwlock.h/0/dummy timestamp//
/apr_time.h/0/dummy timestamp//
/apr_uri.h/0/dummy timestamp//
/apr_user.h/0/dummy timestamp//
/apr_uuid.h/0/dummy timestamp//
/apr_version.h/0/dummy timestamp//
/apr_want.h/0/dummy timestamp//
/apr_xlate.h/0/dummy timestamp//
/apr_xml.h/0/dummy timestamp//
/apu.h/0/dummy timestamp//
/apu.h.in/0/dummy timestamp//
/apu.hnw/0/dummy timestamp//
/apu.hw/0/dummy timestamp//
/apu_version.h/0/dummy timestamp//
/apu_want.h/0/dummy timestamp//
/apu_want.h.in/0/dummy timestamp//
/apu_want.hnw/0/dummy timestamp//
/apu_want.hw/0/dummy timestamp//
/expat.h/0/dummy timestamp//
/expat_external.h/0/dummy timestamp//
D

View File

@@ -0,0 +1 @@
jspqfe/src/pt61850netd_pqfe/source/include/apr-linux

View File

@@ -0,0 +1 @@
:ext:lizhongming@10.0.0.2:/JoyProject

View File

View File

@@ -0,0 +1,132 @@
/* Copyright 2000-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef API_VERSION_H
#define API_VERSION_H
/**
* @file api_version.h
* @brief APR-iconv Versioning Interface
*
* APR-iconv's Version
*
* There are several different mechanisms for accessing the version. There
* is a string form, and a set of numbers; in addition, there are constants
* which can be compiled into your application, and you can query the library
* being used for its actual version.
*
* Note that it is possible for an application to detect that it has been
* compiled against a different version of API by use of the compile-time
* constants and the use of the run-time query function.
*
* API version numbering follows the guidelines specified in:
*
* http://apr.apache.org/versioning.html
*/
/* The numeric compile-time version constants. These constants are the
* authoritative version numbers for API.
*/
/** major version
* Major API changes that could cause compatibility problems for older
* programs such as structure size changes. No binary compatibility is
* possible across a change in the major version.
*/
#define API_MAJOR_VERSION 1
/** minor version
* Minor API changes that do not cause binary compatibility problems.
* Reset to 0 when upgrading API_MAJOR_VERSION
*/
#define API_MINOR_VERSION 1
/** patch level
* The Patch Level never includes API changes, simply bug fixes.
* Reset to 0 when upgrading API_MINOR_VERSION
*/
#define API_PATCH_VERSION 1
/**
* The symbol API_IS_DEV_VERSION is only defined for internal,
* "development" copies of API. It is undefined for released versions
* of API.
*/
/* #define API_IS_DEV_VERSION */
#if defined(API_IS_DEV_VERSION) || defined(DOXYGEN)
/** Internal: string form of the "is dev" flag */
#define API_IS_DEV_STRING "-dev"
#else
#define API_IS_DEV_STRING ""
#endif
#ifndef API_STRINGIFY
/** Properly quote a value as a string in the C preprocessor */
#define API_STRINGIFY(n) API_STRINGIFY_HELPER(n)
/** Helper macro for API_STRINGIFY */
#define API_STRINGIFY_HELPER(n) #n
#endif
/** The formatted string of API's version */
#define API_VERSION_STRING \
API_STRINGIFY(API_MAJOR_VERSION) "." \
API_STRINGIFY(API_MINOR_VERSION) "." \
API_STRINGIFY(API_PATCH_VERSION) \
API_IS_DEV_STRING
/** An alternative formatted string of APR's version */
/* macro for Win32 .rc files using numeric csv representation */
#define API_VERSION_STRING_CSV API_MAJOR_VERSION ##, \
##API_MINOR_VERSION ##, \
##API_PATCH_VERSION
#ifndef API_VERSION_ONLY
/* The C language API to access the version at run time,
* as opposed to compile time. API_VERSION_ONLY may be defined
* externally when preprocessing apr_version.h to obtain strictly
* the C Preprocessor macro declarations.
*/
#include "apr_version.h"
#include "apr_iconv.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Return APR-iconv's version information information in a numeric form.
*
* @param pvsn Pointer to a version structure for returning the version
* information.
*/
API_DECLARE(void) api_version(apr_version_t *pvsn);
/** Return API's version information as a string. */
API_DECLARE(const char *) api_version_string(void);
#ifdef __cplusplus
}
#endif
#endif /* ndef API_VERSION_ONLY */
#endif /* ndef API_VERSION_H */

512
include/apr-linux/apr.h Normal file
View File

@@ -0,0 +1,512 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_H
#define APR_H
/* GENERATED FILE WARNING! DO NOT EDIT apr.h
*
* You must modify apr.h.in instead.
*
* And please, make an effort to stub apr.hw and apr.hnw in the process.
*/
/**
* @file apr.h
* @brief APR Platform Definitions
* @remark This is a generated header generated from include/apr.h.in by
* ./configure, or copied from include/apr.hw or include/apr.hnw
* for Win32 or Netware by those build environments, respectively.
*/
/**
* @defgroup APR Apache Portability Runtime library
* @{
*/
/**
* @defgroup apr_platform Platform Definitions
* @{
* @warning
* <strong><em>The actual values of macros and typedefs on this page<br>
* are platform specific and should NOT be relied upon!</em></strong>
*/
/* So that we can use inline on some critical functions, and use
* GNUC attributes (such as to get -Wall warnings for printf-like
* functions). Only do this in gcc 2.7 or later ... it may work
* on earlier stuff, but why chance it.
*
* We've since discovered that the gcc shipped with NeXT systems
* as "cc" is completely broken. It claims to be __GNUC__ and so
* on, but it doesn't implement half of the things that __GNUC__
* means. In particular it's missing inline and the __attribute__
* stuff. So we hack around it. PR#1613. -djg
*/
#if !defined(__GNUC__) || __GNUC__ < 2 || \
(__GNUC__ == 2 && __GNUC_MINOR__ < 7) ||\
defined(NEXT)
#ifndef __attribute__
#define __attribute__(__x)
#endif
#define APR_INLINE
#define APR_HAS_INLINE 0
#else
#define APR_INLINE __inline__
#define APR_HAS_INLINE 1
#endif
#define APR_HAVE_ARPA_INET_H 1
#define APR_HAVE_CONIO_H 0
#define APR_HAVE_CRYPT_H 1
#define APR_HAVE_CTYPE_H 1
#define APR_HAVE_DIRENT_H 1
#define APR_HAVE_ERRNO_H 1
#define APR_HAVE_FCNTL_H 1
#define APR_HAVE_IO_H 0
#define APR_HAVE_LIMITS_H 1
#define APR_HAVE_NETDB_H 1
#define APR_HAVE_NETINET_IN_H 1
#define APR_HAVE_NETINET_SCTP_H 0
#define APR_HAVE_NETINET_SCTP_UIO_H 0
#define APR_HAVE_NETINET_TCP_H 1
#define APR_HAVE_PTHREAD_H 1
#define APR_HAVE_SEMAPHORE_H 1
#define APR_HAVE_SIGNAL_H 1
#define APR_HAVE_STDARG_H 1
#define APR_HAVE_STDINT_H 1
#define APR_HAVE_STDIO_H 1
#define APR_HAVE_STDLIB_H 1
#define APR_HAVE_STRING_H 1
#define APR_HAVE_STRINGS_H 1
#define APR_HAVE_SYS_IOCTL_H 1
#define APR_HAVE_SYS_SENDFILE_H 1
#define APR_HAVE_SYS_SIGNAL_H 1
#define APR_HAVE_SYS_SOCKET_H 1
#define APR_HAVE_SYS_SOCKIO_H 0
#define APR_HAVE_SYS_SYSLIMITS_H 0
#define APR_HAVE_SYS_TIME_H 1
#define APR_HAVE_SYS_TYPES_H 1
#define APR_HAVE_SYS_UIO_H 1
#define APR_HAVE_SYS_UN_H 1
#define APR_HAVE_SYS_WAIT_H 1
#define APR_HAVE_TIME_H 1
#define APR_HAVE_UNISTD_H 1
#define APR_HAVE_WINDOWS_H 0
#define APR_HAVE_WINSOCK2_H 0
/** @} */
/** @} */
/* We don't include our conditional headers within the doxyblocks
* or the extern "C" namespace
*/
#if APR_HAVE_WINDOWS_H
#include <windows.h>
#endif
#if APR_HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
#if APR_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if APR_HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS)
/* C99 7.18.4 requires that stdint.h only exposes INT64_C
* and UINT64_C for C++ implementations if this is defined: */
#define __STDC_CONSTANT_MACROS
#endif
#if APR_HAVE_STDINT_H
#include <stdint.h>
#endif
#if APR_HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef OS2
#define INCL_DOS
#define INCL_DOSERRORS
#include <os2.h>
#endif
/* header files for PATH_MAX, _POSIX_PATH_MAX */
#if APR_HAVE_LIMITS_H
#include <limits.h>
#else
#if APR_HAVE_SYS_SYSLIMITS_H
#include <sys/syslimits.h>
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup apr_platform
* @ingroup APR
* @{
*/
#define APR_HAVE_SHMEM_MMAP_TMP 1
#define APR_HAVE_SHMEM_MMAP_SHM 1
#define APR_HAVE_SHMEM_MMAP_ZERO 1
#define APR_HAVE_SHMEM_SHMGET_ANON 1
#define APR_HAVE_SHMEM_SHMGET 1
#define APR_HAVE_SHMEM_MMAP_ANON 1
#define APR_HAVE_SHMEM_BEOS 0
#define APR_USE_SHMEM_MMAP_TMP 0
#define APR_USE_SHMEM_MMAP_SHM 0
#define APR_USE_SHMEM_MMAP_ZERO 0
#define APR_USE_SHMEM_SHMGET_ANON 0
#define APR_USE_SHMEM_SHMGET 1
#define APR_USE_SHMEM_MMAP_ANON 1
#define APR_USE_SHMEM_BEOS 0
#define APR_USE_FLOCK_SERIALIZE 0
#define APR_USE_SYSVSEM_SERIALIZE 1
#define APR_USE_POSIXSEM_SERIALIZE 0
#define APR_USE_FCNTL_SERIALIZE 0
#define APR_USE_PROC_PTHREAD_SERIALIZE 0
#define APR_USE_PTHREAD_SERIALIZE 1
#define APR_HAS_FLOCK_SERIALIZE 1
#define APR_HAS_SYSVSEM_SERIALIZE 1
#define APR_HAS_POSIXSEM_SERIALIZE 1
#define APR_HAS_FCNTL_SERIALIZE 1
#define APR_HAS_PROC_PTHREAD_SERIALIZE 1
#define APR_PROCESS_LOCK_IS_GLOBAL 0
#define APR_HAVE_CORKABLE_TCP 1
#define APR_HAVE_GETRLIMIT 1
#define APR_HAVE_IN_ADDR 1
#define APR_HAVE_INET_ADDR 1
#define APR_HAVE_INET_NETWORK 1
#define APR_HAVE_IPV6 1
#define APR_HAVE_MEMMOVE 1
#define APR_HAVE_SETRLIMIT 1
#define APR_HAVE_SIGACTION 1
#define APR_HAVE_SIGSUSPEND 1
#define APR_HAVE_SIGWAIT 1
#define APR_HAVE_SA_STORAGE 1
#define APR_HAVE_STRCASECMP 1
#define APR_HAVE_STRDUP 1
#define APR_HAVE_STRICMP 0
#define APR_HAVE_STRNCASECMP 1
#define APR_HAVE_STRNICMP 0
#define APR_HAVE_STRSTR 1
#define APR_HAVE_MEMCHR 1
#define APR_HAVE_STRUCT_RLIMIT 1
#define APR_HAVE_UNION_SEMUN 0
#define APR_HAVE_SCTP 0
#define APR_HAVE_IOVEC 1
/* APR Feature Macros */
#define APR_HAS_SHARED_MEMORY 1
#define APR_HAS_THREADS 1
#define APR_HAS_SENDFILE 1
#define APR_HAS_MMAP 1
#define APR_HAS_FORK 1
#define APR_HAS_RANDOM 1
#define APR_HAS_OTHER_CHILD 1
#define APR_HAS_DSO 1
#define APR_HAS_SO_ACCEPTFILTER 0
#define APR_HAS_UNICODE_FS 0
#define APR_HAS_PROC_INVOKED 0
#define APR_HAS_USER 1
#define APR_HAS_LARGE_FILES 1
#define APR_HAS_XTHREAD_FILES 0
#define APR_HAS_OS_UUID 0
#define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 0
/* APR sets APR_FILES_AS_SOCKETS to 1 on systems where it is possible
* to poll on files/pipes.
*/
#define APR_FILES_AS_SOCKETS 1
/* This macro indicates whether or not EBCDIC is the native character set.
*/
#define APR_CHARSET_EBCDIC 0
/* If we have a TCP implementation that can be "corked", what flag
* do we use?
*/
#define APR_TCP_NOPUSH_FLAG TCP_CORK
/* Is the TCP_NODELAY socket option inherited from listening sockets?
*/
#define APR_TCP_NODELAY_INHERITED 1
/* Is the O_NONBLOCK flag inherited from listening sockets?
*/
#define APR_O_NONBLOCK_INHERITED 0
/* Typedefs that APR needs. */
typedef unsigned char apr_byte_t;
typedef short apr_int16_t;
typedef unsigned short apr_uint16_t;
typedef int apr_int32_t;
typedef unsigned int apr_uint32_t;
typedef long long apr_int64_t;
typedef unsigned long long apr_uint64_t;
typedef size_t apr_size_t;
typedef ssize_t apr_ssize_t;
typedef off64_t apr_off_t;
typedef socklen_t apr_socklen_t;
typedef unsigned long apr_ino_t;
#define APR_SIZEOF_VOIDP 4
#if APR_SIZEOF_VOIDP == 8
typedef apr_uint64_t apr_uintptr_t;
#else
typedef apr_uint32_t apr_uintptr_t;
#endif
/* Are we big endian? */
#define APR_IS_BIGENDIAN 0
/* Mechanisms to properly type numeric literals */
#define APR_INT64_C(val) INT64_C(val)
#define APR_UINT64_C(val) UINT64_C(val)
#ifdef INT16_MIN
#define APR_INT16_MIN INT16_MIN
#else
#define APR_INT16_MIN (-0x7fff - 1)
#endif
#ifdef INT16_MAX
#define APR_INT16_MAX INT16_MAX
#else
#define APR_INT16_MAX (0x7fff)
#endif
#ifdef UINT16_MAX
#define APR_UINT16_MAX UINT16_MAX
#else
#define APR_UINT16_MAX (0xffff)
#endif
#ifdef INT32_MIN
#define APR_INT32_MIN INT32_MIN
#else
#define APR_INT32_MIN (-0x7fffffff - 1)
#endif
#ifdef INT32_MAX
#define APR_INT32_MAX INT32_MAX
#else
#define APR_INT32_MAX 0x7fffffff
#endif
#ifdef UINT32_MAX
#define APR_UINT32_MAX UINT32_MAX
#else
#define APR_UINT32_MAX (0xffffffffU)
#endif
#ifdef INT64_MIN
#define APR_INT64_MIN INT64_MIN
#else
#define APR_INT64_MIN (APR_INT64_C(-0x7fffffffffffffff) - 1)
#endif
#ifdef INT64_MAX
#define APR_INT64_MAX INT64_MAX
#else
#define APR_INT64_MAX APR_INT64_C(0x7fffffffffffffff)
#endif
#ifdef UINT64_MAX
#define APR_UINT64_MAX UINT64_MAX
#else
#define APR_UINT64_MAX APR_UINT64_C(0xffffffffffffffff)
#endif
#define APR_SIZE_MAX (~((apr_size_t)0))
/* Definitions that APR programs need to work properly. */
/**
* APR public API wrap for C++ compilers.
*/
#ifdef __cplusplus
#define APR_BEGIN_DECLS extern "C" {
#define APR_END_DECLS }
#else
#define APR_BEGIN_DECLS
#define APR_END_DECLS
#endif
/**
* Thread callbacks from APR functions must be declared with APR_THREAD_FUNC,
* so that they follow the platform's calling convention.
* <PRE>
*
* void* APR_THREAD_FUNC my_thread_entry_fn(apr_thread_t *thd, void *data);
*
* </PRE>
*/
#define APR_THREAD_FUNC
/**
* The public APR functions are declared with APR_DECLARE(), so they may
* use the most appropriate calling convention. Public APR functions with
* variable arguments must use APR_DECLARE_NONSTD().
*
* @remark Both the declaration and implementations must use the same macro.
*
* <PRE>
* APR_DECLARE(rettype) apr_func(args)
* </PRE>
* @see APR_DECLARE_NONSTD @see APR_DECLARE_DATA
* @remark Note that when APR compiles the library itself, it passes the
* symbol -DAPR_DECLARE_EXPORT to the compiler on some platforms (e.g. Win32)
* to export public symbols from the dynamic library build.\n
* The user must define the APR_DECLARE_STATIC when compiling to target
* the static APR library on some platforms (e.g. Win32.) The public symbols
* are neither exported nor imported when APR_DECLARE_STATIC is defined.\n
* By default, compiling an application and including the APR public
* headers, without defining APR_DECLARE_STATIC, will prepare the code to be
* linked to the dynamic library.
*/
#define APR_DECLARE(type) type
/**
* The public APR functions using variable arguments are declared with
* APR_DECLARE_NONSTD(), as they must follow the C language calling convention.
* @see APR_DECLARE @see APR_DECLARE_DATA
* @remark Both the declaration and implementations must use the same macro.
* <PRE>
*
* APR_DECLARE_NONSTD(rettype) apr_func(args, ...);
*
* </PRE>
*/
#define APR_DECLARE_NONSTD(type) type
/**
* The public APR variables are declared with AP_MODULE_DECLARE_DATA.
* This assures the appropriate indirection is invoked at compile time.
* @see APR_DECLARE @see APR_DECLARE_NONSTD
* @remark Note that the declaration and implementations use different forms,
* but both must include the macro.
*
* <PRE>
*
* extern APR_DECLARE_DATA type apr_variable;\n
* APR_DECLARE_DATA type apr_variable = value;
*
* </PRE>
*/
#define APR_DECLARE_DATA
/* Define APR_SSIZE_T_FMT.
* If ssize_t is an integer we define it to be "d",
* if ssize_t is a long int we define it to be "ld",
* if ssize_t is neither we declare an error here.
* I looked for a better way to define this here, but couldn't find one, so
* to find the logic for this definition search for "ssize_t_fmt" in
* configure.in.
*/
#define APR_SSIZE_T_FMT "d"
/* And APR_SIZE_T_FMT */
#define APR_SIZE_T_FMT "u"
/* And APR_OFF_T_FMT */
#define APR_OFF_T_FMT APR_INT64_T_FMT
/* And APR_PID_T_FMT */
#define APR_PID_T_FMT "d"
/* And APR_INT64_T_FMT */
#define APR_INT64_T_FMT "lld"
/* And APR_UINT64_T_FMT */
#define APR_UINT64_T_FMT "llu"
/* And APR_UINT64_T_HEX_FMT */
#define APR_UINT64_T_HEX_FMT "llx"
/* Does the proc mutex lock threads too */
#define APR_PROC_MUTEX_IS_GLOBAL 0
/* Local machine definition for console and log output. */
#define APR_EOL_STR "\n"
#if APR_HAVE_SYS_WAIT_H
#ifdef WEXITSTATUS
#define apr_wait_t int
#else
#define apr_wait_t union wait
#define WEXITSTATUS(status) (int)((status).w_retcode)
#define WTERMSIG(status) (int)((status).w_termsig)
#endif /* !WEXITSTATUS */
#elif defined(__MINGW32__)
typedef int apr_wait_t;
#endif /* HAVE_SYS_WAIT_H */
#if defined(PATH_MAX)
#define APR_PATH_MAX PATH_MAX
#elif defined(_POSIX_PATH_MAX)
#define APR_PATH_MAX _POSIX_PATH_MAX
#else
#error no decision has been made on APR_PATH_MAX for your platform
#endif
#define APR_DSOPATH "LD_LIBRARY_PATH"
/** @} */
/* Definitions that only Win32 programs need to compile properly. */
/* XXX These simply don't belong here, perhaps in apr_portable.h
* based on some APR_HAVE_PID/GID/UID?
*/
#ifdef __MINGW32__
#ifndef __GNUC__
typedef int pid_t;
#endif
typedef int uid_t;
typedef int gid_t;
#endif
#ifdef __cplusplus
}
#endif
#endif /* APR_H */

View File

@@ -0,0 +1,167 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_ALLOCATOR_H
#define APR_ALLOCATOR_H
/**
* @file apr_allocator.h
* @brief APR Internal Memory Allocation
*/
#include "apr.h"
#include "apr_errno.h"
#define APR_WANT_MEMFUNC /**< For no good reason? */
#include "apr_want.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup apr_allocator Internal Memory Allocation
* @ingroup APR
* @{
*/
/** the allocator structure */
typedef struct apr_allocator_t apr_allocator_t;
/** the structure which holds information about the allocation */
typedef struct apr_memnode_t apr_memnode_t;
/** basic memory node structure
* @note The next, ref and first_avail fields are available for use by the
* caller of apr_allocator_alloc(), the remaining fields are read-only.
* The next field has to be used with caution and sensibly set when the
* memnode is passed back to apr_allocator_free(). See apr_allocator_free()
* for details.
* The ref and first_avail fields will be properly restored by
* apr_allocator_free().
*/
struct apr_memnode_t {
apr_memnode_t *next; /**< next memnode */
apr_memnode_t **ref; /**< reference to self */
apr_uint32_t index; /**< size */
apr_uint32_t free_index; /**< how much free */
char *first_avail; /**< pointer to first free memory */
char *endp; /**< pointer to end of free memory */
};
/** The base size of a memory node - aligned. */
#define APR_MEMNODE_T_SIZE APR_ALIGN_DEFAULT(sizeof(apr_memnode_t))
/** Symbolic constants */
#define APR_ALLOCATOR_MAX_FREE_UNLIMITED 0
/**
* View a new allocator key status
* @param allocator The allocator we have just created.
*
*/
APR_DECLARE(apr_status_t) apr_allocator_status();
/**
* Create a new allocator
* @param allocator The allocator we have just created.
*
*/
APR_DECLARE(apr_status_t) apr_allocator_create(apr_allocator_t **allocator);
/**
* Destroy an allocator
* @param allocator The allocator to be destroyed
* @remark Any memnodes not given back to the allocator prior to destroying
* will _not_ be free()d.
*/
APR_DECLARE(void) apr_allocator_destroy(apr_allocator_t *allocator);
/**
* Allocate a block of mem from the allocator
* @param allocator The allocator to allocate from
* @param size The size of the mem to allocate (excluding the
* memnode structure)
*/
APR_DECLARE(apr_memnode_t *) apr_allocator_alloc(apr_allocator_t *allocator,
apr_size_t size);
/**
* Free a list of blocks of mem, giving them back to the allocator.
* The list is typically terminated by a memnode with its next field
* set to NULL.
* @param allocator The allocator to give the mem back to
* @param memnode The memory node to return
*/
APR_DECLARE(void) apr_allocator_free(apr_allocator_t *allocator,
apr_memnode_t *memnode);
#include "apr_pools.h"
/**
* Set the owner of the allocator
* @param allocator The allocator to set the owner for
* @param pool The pool that is to own the allocator
* @remark Typically pool is the highest level pool using the allocator
*/
/*
* XXX: see if we can come up with something a bit better. Currently
* you can make a pool an owner, but if the pool doesn't use the allocator
* the allocator will never be destroyed.
*/
APR_DECLARE(void) apr_allocator_owner_set(apr_allocator_t *allocator,
apr_pool_t *pool);
/**
* Get the current owner of the allocator
* @param allocator The allocator to get the owner from
*/
APR_DECLARE(apr_pool_t *) apr_allocator_owner_get(apr_allocator_t *allocator);
/**
* Set the current threshold at which the allocator should start
* giving blocks back to the system.
* @param allocator The allocator the set the threshold on
* @param size The threshold. 0 == unlimited.
*/
APR_DECLARE(void) apr_allocator_max_free_set(apr_allocator_t *allocator,
apr_size_t size);
#include "apr_thread_mutex.h"
#if APR_HAS_THREADS
/**
* Set a mutex for the allocator to use
* @param allocator The allocator to set the mutex for
* @param mutex The mutex
*/
APR_DECLARE(void) apr_allocator_mutex_set(apr_allocator_t *allocator,
apr_thread_mutex_t *mutex);
/**
* Get the mutex currently set for the allocator
* @param allocator The allocator
*/
APR_DECLARE(apr_thread_mutex_t *) apr_allocator_mutex_get(
apr_allocator_t *allocator);
#endif /* APR_HAS_THREADS */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !APR_ALLOCATOR_H */

View File

@@ -0,0 +1,128 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file apr_anylock.h
* @brief APR-Util transparent any lock flavor wrapper
*/
#ifndef APR_ANYLOCK_H
#define APR_ANYLOCK_H
#include "apr_proc_mutex.h"
#include "apr_thread_mutex.h"
#include "apr_thread_rwlock.h"
/** Structure that may contain any APR lock type */
typedef struct apr_anylock_t {
/** Indicates what type of lock is in lock */
enum tm_lock {
apr_anylock_none, /**< None */
apr_anylock_procmutex, /**< Process-based */
apr_anylock_threadmutex, /**< Thread-based */
apr_anylock_readlock, /**< Read lock */
apr_anylock_writelock /**< Write lock */
} type;
/** Union of all possible APR locks */
union apr_anylock_u_t {
apr_proc_mutex_t *pm; /**< Process mutex */
#if APR_HAS_THREADS
apr_thread_mutex_t *tm; /**< Thread mutex */
apr_thread_rwlock_t *rw; /**< Read-write lock */
#endif
} lock;
} apr_anylock_t;
#if APR_HAS_THREADS
/** Lock an apr_anylock_t structure */
#define APR_ANYLOCK_LOCK(lck) \
(((lck)->type == apr_anylock_none) \
? APR_SUCCESS \
: (((lck)->type == apr_anylock_threadmutex) \
? apr_thread_mutex_lock((lck)->lock.tm) \
: (((lck)->type == apr_anylock_procmutex) \
? apr_proc_mutex_lock((lck)->lock.pm) \
: (((lck)->type == apr_anylock_readlock) \
? apr_thread_rwlock_rdlock((lck)->lock.rw) \
: (((lck)->type == apr_anylock_writelock) \
? apr_thread_rwlock_wrlock((lck)->lock.rw) \
: APR_EINVAL)))))
#else /* APR_HAS_THREADS */
#define APR_ANYLOCK_LOCK(lck) \
(((lck)->type == apr_anylock_none) \
? APR_SUCCESS \
: (((lck)->type == apr_anylock_procmutex) \
? apr_proc_mutex_lock((lck)->lock.pm) \
: APR_EINVAL))
#endif /* APR_HAS_THREADS */
#if APR_HAS_THREADS
/** Try to lock an apr_anylock_t structure */
#define APR_ANYLOCK_TRYLOCK(lck) \
(((lck)->type == apr_anylock_none) \
? APR_SUCCESS \
: (((lck)->type == apr_anylock_threadmutex) \
? apr_thread_mutex_trylock((lck)->lock.tm) \
: (((lck)->type == apr_anylock_procmutex) \
? apr_proc_mutex_trylock((lck)->lock.pm) \
: (((lck)->type == apr_anylock_readlock) \
? apr_thread_rwlock_tryrdlock((lck)->lock.rw) \
: (((lck)->type == apr_anylock_writelock) \
? apr_thread_rwlock_trywrlock((lck)->lock.rw) \
: APR_EINVAL)))))
#else /* APR_HAS_THREADS */
#define APR_ANYLOCK_TRYLOCK(lck) \
(((lck)->type == apr_anylock_none) \
? APR_SUCCESS \
: (((lck)->type == apr_anylock_procmutex) \
? apr_proc_mutex_trylock((lck)->lock.pm) \
: APR_EINVAL))
#endif /* APR_HAS_THREADS */
#if APR_HAS_THREADS
/** Unlock an apr_anylock_t structure */
#define APR_ANYLOCK_UNLOCK(lck) \
(((lck)->type == apr_anylock_none) \
? APR_SUCCESS \
: (((lck)->type == apr_anylock_threadmutex) \
? apr_thread_mutex_unlock((lck)->lock.tm) \
: (((lck)->type == apr_anylock_procmutex) \
? apr_proc_mutex_unlock((lck)->lock.pm) \
: ((((lck)->type == apr_anylock_readlock) || \
((lck)->type == apr_anylock_writelock)) \
? apr_thread_rwlock_unlock((lck)->lock.rw) \
: APR_EINVAL))))
#else /* APR_HAS_THREADS */
#define APR_ANYLOCK_UNLOCK(lck) \
(((lck)->type == apr_anylock_none) \
? APR_SUCCESS \
: (((lck)->type == apr_anylock_procmutex) \
? apr_proc_mutex_unlock((lck)->lock.pm) \
: APR_EINVAL))
#endif /* APR_HAS_THREADS */
#endif /* !APR_ANYLOCK_H */

View File

@@ -0,0 +1,140 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_ATOMIC_H
#define APR_ATOMIC_H
/**
* @file apr_atomic.h
* @brief APR Atomic Operations
*/
#include "apr.h"
#include "apr_pools.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup apr_atomic Atomic Operations
* @ingroup APR
* @{
*/
/**
* this function is required on some platforms to initialize the
* atomic operation's internal structures
* @param p pool
* @return APR_SUCCESS on successful completion
* @remark Programs do NOT need to call this directly. APR will call this
* automatically from apr_initialize.
* @internal
*/
APR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *p);
/*
* Atomic operations on 32-bit values
* Note: Each of these functions internally implements a memory barrier
* on platforms that require it
*/
/**
* atomically read an apr_uint32_t from memory
* @param mem the pointer
*/
APR_DECLARE(apr_uint32_t) apr_atomic_read32(volatile apr_uint32_t *mem);
/**
* atomically set an apr_uint32_t in memory
* @param mem pointer to the object
* @param val value that the object will assume
*/
APR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val);
/**
* atomically add 'val' to an apr_uint32_t
* @param mem pointer to the object
* @param val amount to add
* @return old value pointed to by mem
*/
APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val);
/**
* atomically subtract 'val' from an apr_uint32_t
* @param mem pointer to the object
* @param val amount to subtract
*/
APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val);
/**
* atomically increment an apr_uint32_t by 1
* @param mem pointer to the object
* @return old value pointed to by mem
*/
APR_DECLARE(apr_uint32_t) apr_atomic_inc32(volatile apr_uint32_t *mem);
/**
* atomically decrement an apr_uint32_t by 1
* @param mem pointer to the atomic value
* @return zero if the value becomes zero on decrement, otherwise non-zero
*/
APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem);
/**
* compare an apr_uint32_t's value with 'cmp'.
* If they are the same swap the value with 'with'
* @param mem pointer to the value
* @param with what to swap it with
* @param cmp the value to compare it to
* @return the old value of *mem
*/
APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with,
apr_uint32_t cmp);
/**
* exchange an apr_uint32_t's value with 'val'.
* @param mem pointer to the value
* @param val what to swap it with
* @return the old value of *mem
*/
APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val);
/**
* compare the pointer's value with cmp.
* If they are the same swap the value with 'with'
* @param mem pointer to the pointer
* @param with what to swap it with
* @param cmp the value to compare it to
* @return the old value of the pointer
*/
APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void *cmp);
/**
* exchange a pair of pointer values
* @param mem pointer to the pointer
* @param with what to swap it with
* @return the old value of the pointer
*/
APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !APR_ATOMIC_H */

View File

@@ -0,0 +1,112 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* The apr_vsnprintf/apr_snprintf functions are based on, and used with the
* permission of, the SIO stdio-replacement strx_* functions by Panos
* Tsirigotis <panos@alumni.cs.colorado.edu> for xinetd.
*/
/**
* @file apr_base64.h
* @brief APR-UTIL Base64 Encoding
*/
#ifndef APR_BASE64_H
#define APR_BASE64_H
#include "apu.h"
#include "apr_general.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup APR_Util_Base64 Base64 Encoding
* @ingroup APR_Util
* @{
*/
/* Simple BASE64 encode/decode functions.
*
* As we might encode binary strings, hence we require the length of
* the incoming plain source. And return the length of what we decoded.
*
* The decoding function takes any non valid char (i.e. whitespace, \0
* or anything non A-Z,0-9 etc as terminal.
*
* plain strings/binary sequences are not assumed '\0' terminated. Encoded
* strings are neither. But probably should.
*
*/
/**
* Given the length of an un-encrypted string, get the length of the
* encrypted string.
* @param len the length of an unencrypted string.
* @return the length of the string after it is encrypted
*/
APU_DECLARE(int) apr_base64_encode_len(int len);
/**
* Encode a text string using base64encoding.
* @param coded_dst The destination string for the encoded string.
* @param plain_src The original string in plain text
* @param len_plain_src The length of the plain text string
* @return the length of the encoded string
*/
APU_DECLARE(int) apr_base64_encode(char * coded_dst, const char *plain_src,
int len_plain_src);
/**
* Encode an EBCDIC string using base64encoding.
* @param coded_dst The destination string for the encoded string.
* @param plain_src The original string in plain text
* @param len_plain_src The length of the plain text string
* @return the length of the encoded string
*/
APU_DECLARE(int) apr_base64_encode_binary(char * coded_dst,
const unsigned char *plain_src,
int len_plain_src);
/**
* Determine the maximum buffer length required to decode the plain text
* string given the encoded string.
* @param coded_src The encoded string
* @return the maximum required buffer length for the plain text string
*/
APU_DECLARE(int) apr_base64_decode_len(const char * coded_src);
/**
* Decode a string to plain text
* @param plain_dst The destination string for the plain text
* @param coded_src The encoded string
* @return the length of the plain text string
*/
APU_DECLARE(int) apr_base64_decode(char * plain_dst, const char *coded_src);
/**
* Decode an EBCDIC string to plain text
* @param plain_dst The destination string for the plain text
* @param coded_src The encoded string
* @return the length of the plain text string
*/
APU_DECLARE(int) apr_base64_decode_binary(unsigned char * plain_dst,
const char *coded_src);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !APR_BASE64_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,106 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_DATE_H
#define APR_DATE_H
/**
* @file apr_date.h
* @brief APR-UTIL date routines
*/
/**
* @defgroup APR_Util_Date Date routines
* @ingroup APR_Util
* @{
*/
/*
* apr_date.h: prototypes for date parsing utility routines
*/
#include "apu.h"
#include "apr_time.h"
#ifdef __cplusplus
extern "C" {
#endif
/** A bad date. */
#define APR_DATE_BAD ((apr_time_t)0)
/**
* Compare a string to a mask
* @param data The string to compare
* @param mask Mask characters (arbitrary maximum is 256 characters):
* <PRE>
* '\@' - uppercase letter
* '\$' - lowercase letter
* '\&' - hex digit
* '#' - digit
* '~' - digit or space
* '*' - swallow remaining characters
* </PRE>
* @remark The mask tests for an exact match for any other character
* @return 1 if the string matches, 0 otherwise
*/
APU_DECLARE(int) apr_date_checkmask(const char *data, const char *mask);
/**
* Parses an HTTP date in one of three standard forms:
* <PRE>
* Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
* Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
* Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
* </PRE>
* @param date The date in one of the three formats above
* @return the apr_time_t number of microseconds since 1 Jan 1970 GMT, or
* 0 if this would be out of range or if the date is invalid.
*/
APU_DECLARE(apr_time_t) apr_date_parse_http(const char *date);
/**
* Parses a string resembling an RFC 822 date. This is meant to be
* leinent in its parsing of dates. Hence, this will parse a wider
* range of dates than apr_date_parse_http.
*
* The prominent mailer (or poster, if mailer is unknown) that has
* been seen in the wild is included for the unknown formats.
* <PRE>
* Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
* Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
* Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
* Sun, 6 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
* Sun, 06 Nov 94 08:49:37 GMT ; RFC 822
* Sun, 6 Nov 94 08:49:37 GMT ; RFC 822
* Sun, 06 Nov 94 08:49 GMT ; Unknown [drtr\@ast.cam.ac.uk]
* Sun, 6 Nov 94 08:49 GMT ; Unknown [drtr\@ast.cam.ac.uk]
* Sun, 06 Nov 94 8:49:37 GMT ; Unknown [Elm 70.85]
* Sun, 6 Nov 94 8:49:37 GMT ; Unknown [Elm 70.85]
* </PRE>
*
* @param date The date in one of the formats above
* @return the apr_time_t number of microseconds since 1 Jan 1970 GMT, or
* 0 if this would be out of range or if the date is invalid.
*/
APU_DECLARE(apr_time_t) apr_date_parse_rfc(const char *date);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !APR_DATE_H */

551
include/apr-linux/apr_dbd.h Normal file
View File

@@ -0,0 +1,551 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Overview of what this is and does:
* http://www.apache.org/~niq/dbd.html
*/
#ifndef APR_DBD_H
#define APR_DBD_H
#include "apu.h"
#include "apr_pools.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file apr_dbd.h
* @brief APR-UTIL DBD library
*/
/**
* @defgroup APR_Util_DBD DBD routines
* @ingroup APR_Util
* @{
*/
/**
* Mapping of C to SQL types, used for prepared statements.
* @remarks
* For apr_dbd_p[v]query/select functions, in and out parameters are always
* const char * (i.e. regular nul terminated strings). LOB types are passed
* with four (4) arguments: payload, length, table and column, all as const
* char *, where table and column are reserved for future use by Oracle.
* @remarks
* For apr_dbd_p[v]bquery/select functions, in and out parameters are
* described next to each enumeration constant and are generally native binary
* types or some APR data type. LOB types are passed with four (4) arguments:
* payload (char*), length (apr_size_t*), table (char*) and column (char*).
* Table and column are reserved for future use by Oracle.
*/
typedef enum {
APR_DBD_TYPE_NONE,
APR_DBD_TYPE_TINY, /**< \%hhd : in, out: char* */
APR_DBD_TYPE_UTINY, /**< \%hhu : in, out: unsigned char* */
APR_DBD_TYPE_SHORT, /**< \%hd : in, out: short* */
APR_DBD_TYPE_USHORT, /**< \%hu : in, out: unsigned short* */
APR_DBD_TYPE_INT, /**< \%d : in, out: int* */
APR_DBD_TYPE_UINT, /**< \%u : in, out: unsigned int* */
APR_DBD_TYPE_LONG, /**< \%ld : in, out: long* */
APR_DBD_TYPE_ULONG, /**< \%lu : in, out: unsigned long* */
APR_DBD_TYPE_LONGLONG, /**< \%lld : in, out: apr_int64_t* */
APR_DBD_TYPE_ULONGLONG, /**< \%llu : in, out: apr_uint64_t* */
APR_DBD_TYPE_FLOAT, /**< \%f : in, out: float* */
APR_DBD_TYPE_DOUBLE, /**< \%lf : in, out: double* */
APR_DBD_TYPE_STRING, /**< \%s : in: char*, out: char** */
APR_DBD_TYPE_TEXT, /**< \%pDt : in: char*, out: char** */
APR_DBD_TYPE_TIME, /**< \%pDi : in: char*, out: char** */
APR_DBD_TYPE_DATE, /**< \%pDd : in: char*, out: char** */
APR_DBD_TYPE_DATETIME, /**< \%pDa : in: char*, out: char** */
APR_DBD_TYPE_TIMESTAMP, /**< \%pDs : in: char*, out: char** */
APR_DBD_TYPE_ZTIMESTAMP, /**< \%pDz : in: char*, out: char** */
APR_DBD_TYPE_BLOB, /**< \%pDb : in: char* apr_size_t* char* char*, out: apr_bucket_brigade* */
APR_DBD_TYPE_CLOB, /**< \%pDc : in: char* apr_size_t* char* char*, out: apr_bucket_brigade* */
APR_DBD_TYPE_NULL /**< \%pDn : in: void*, out: void** */
} apr_dbd_type_e;
/* These are opaque structs. Instantiation is up to each backend */
typedef struct apr_dbd_driver_t apr_dbd_driver_t;
typedef struct apr_dbd_t apr_dbd_t;
typedef struct apr_dbd_transaction_t apr_dbd_transaction_t;
typedef struct apr_dbd_results_t apr_dbd_results_t;
typedef struct apr_dbd_row_t apr_dbd_row_t;
typedef struct apr_dbd_prepared_t apr_dbd_prepared_t;
/** apr_dbd_init: perform once-only initialisation. Call once only.
*
* @param pool - pool to register any shutdown cleanups, etc
*/
APU_DECLARE(apr_status_t) apr_dbd_init(apr_pool_t *pool);
/** apr_dbd_get_driver: get the driver struct for a name
*
* @param pool - (process) pool to register cleanup
* @param name - driver name
* @param driver - pointer to driver struct.
* @return APR_SUCCESS for success
* @return APR_ENOTIMPL for no driver (when DSO not enabled)
* @return APR_EDSOOPEN if DSO driver file can't be opened
* @return APR_ESYMNOTFOUND if the driver file doesn't contain a driver
*/
APU_DECLARE(apr_status_t) apr_dbd_get_driver(apr_pool_t *pool, const char *name,
const apr_dbd_driver_t **driver);
/** apr_dbd_open_ex: open a connection to a backend
*
* @param pool - working pool
* @param params - arguments to driver (implementation-dependent)
* @param handle - pointer to handle to return
* @param driver - driver struct.
* @param error - descriptive error.
* @return APR_SUCCESS for success
* @return APR_EGENERAL if driver exists but connection failed
* @remarks PostgreSQL: the params is passed directly to the PQconnectdb()
* function (check PostgreSQL documentation for more details on the syntax).
* @remarks SQLite2: the params is split on a colon, with the first part used
* as the filename and second part converted to an integer and used as file
* mode.
* @remarks SQLite3: the params is passed directly to the sqlite3_open()
* function as a filename to be opened (check SQLite3 documentation for more
* details).
* @remarks Oracle: the params can have "user", "pass", "dbname" and "server"
* keys, each followed by an equal sign and a value. Such key/value pairs can
* be delimited by space, CR, LF, tab, semicolon, vertical bar or comma.
* @remarks MySQL: the params can have "host", "port", "user", "pass",
* "dbname", "sock", "flags" "fldsz" and "group" keys, each followed by an
* equal sign and a value. Such key/value pairs can be delimited by space,
* CR, LF, tab, semicolon, vertical bar or comma. For now, "flags" can only
* recognise CLIENT_FOUND_ROWS (check MySQL manual for details). The value
* associated with "fldsz" determines maximum amount of memory (in bytes) for
* each of the fields in the result set of prepared statements. By default,
* this value is 1 MB. The value associated with "group" determines which
* group from configuration file to use (see MYSQL_READ_DEFAULT_GROUP option
* of mysql_options() in MySQL manual).
* @remarks FreeTDS: the params can have "username", "password", "appname",
* "dbname", "host", "charset", "lang" and "server" keys, each followed by an
* equal sign and a value.
*/
APU_DECLARE(apr_status_t) apr_dbd_open_ex(const apr_dbd_driver_t *driver,
apr_pool_t *pool, const char *params,
apr_dbd_t **handle,
const char **error);
/** apr_dbd_open: open a connection to a backend
*
* @param pool - working pool
* @param params - arguments to driver (implementation-dependent)
* @param handle - pointer to handle to return
* @param driver - driver struct.
* @return APR_SUCCESS for success
* @return APR_EGENERAL if driver exists but connection failed
* @see apr_dbd_open_ex
*/
APU_DECLARE(apr_status_t) apr_dbd_open(const apr_dbd_driver_t *driver,
apr_pool_t *pool, const char *params,
apr_dbd_t **handle);
/** apr_dbd_close: close a connection to a backend
*
* @param handle - handle to close
* @param driver - driver struct.
* @return APR_SUCCESS for success or error status
*/
APU_DECLARE(apr_status_t) apr_dbd_close(const apr_dbd_driver_t *driver,
apr_dbd_t *handle);
/* apr-function-shaped versions of things */
/** apr_dbd_name: get the name of the driver
*
* @param driver - the driver
* @return - name
*/
APU_DECLARE(const char*) apr_dbd_name(const apr_dbd_driver_t *driver);
/** apr_dbd_native_handle: get native database handle of the underlying db
*
* @param driver - the driver
* @param handle - apr_dbd handle
* @return - native handle
*/
APU_DECLARE(void*) apr_dbd_native_handle(const apr_dbd_driver_t *driver,
apr_dbd_t *handle);
/** check_conn: check status of a database connection
*
* @param driver - the driver
* @param pool - working pool
* @param handle - the connection to check
* @return APR_SUCCESS or error
*/
APU_DECLARE(int) apr_dbd_check_conn(const apr_dbd_driver_t *driver, apr_pool_t *pool,
apr_dbd_t *handle);
/** apr_dbd_set_dbname: select database name. May be a no-op if not supported.
*
* @param driver - the driver
* @param pool - working pool
* @param handle - the connection
* @param name - the database to select
* @return 0 for success or error code
*/
APU_DECLARE(int) apr_dbd_set_dbname(const apr_dbd_driver_t *driver, apr_pool_t *pool,
apr_dbd_t *handle, const char *name);
/** apr_dbd_transaction_start: start a transaction. May be a no-op.
*
* @param driver - the driver
* @param pool - a pool to use for error messages (if any).
* @param handle - the db connection
* @param trans - ptr to a transaction. May be null on entry
* @return 0 for success or error code
* @remarks Note that transaction modes, set by calling
* apr_dbd_transaction_mode_set(), will affect all query/select calls within
* a transaction. By default, any error in query/select during a transaction
* will cause the transaction to inherit the error code and any further
* query/select calls will fail immediately. Put transaction in "ignore
* errors" mode to avoid that. Use "rollback" mode to do explicit rollback.
*/
APU_DECLARE(int) apr_dbd_transaction_start(const apr_dbd_driver_t *driver,
apr_pool_t *pool,
apr_dbd_t *handle,
apr_dbd_transaction_t **trans);
/** apr_dbd_transaction_end: end a transaction
* (commit on success, rollback on error).
* May be a no-op.
*
* @param driver - the driver
* @param handle - the db connection
* @param trans - the transaction.
* @return 0 for success or error code
*/
APU_DECLARE(int) apr_dbd_transaction_end(const apr_dbd_driver_t *driver,
apr_pool_t *pool,
apr_dbd_transaction_t *trans);
#define APR_DBD_TRANSACTION_COMMIT 0x00 /**< commit the transaction */
#define APR_DBD_TRANSACTION_ROLLBACK 0x01 /**< rollback the transaction */
#define APR_DBD_TRANSACTION_IGNORE_ERRORS 0x02 /**< ignore transaction errors */
/** apr_dbd_transaction_mode_get: get the mode of transaction
*
* @param driver - the driver
* @param trans - the transaction
* @return mode of transaction
*/
APU_DECLARE(int) apr_dbd_transaction_mode_get(const apr_dbd_driver_t *driver,
apr_dbd_transaction_t *trans);
/** apr_dbd_transaction_mode_set: set the mode of transaction
*
* @param driver - the driver
* @param trans - the transaction
* @param mode - new mode of the transaction
* @return the mode of transaction in force after the call
*/
APU_DECLARE(int) apr_dbd_transaction_mode_set(const apr_dbd_driver_t *driver,
apr_dbd_transaction_t *trans,
int mode);
/** apr_dbd_query: execute an SQL query that doesn't return a result set
*
* @param driver - the driver
* @param handle - the connection
* @param nrows - number of rows affected.
* @param statement - the SQL statement to execute
* @return 0 for success or error code
*/
APU_DECLARE(int) apr_dbd_query(const apr_dbd_driver_t *driver, apr_dbd_t *handle,
int *nrows, const char *statement);
/** apr_dbd_select: execute an SQL query that returns a result set
*
* @param driver - the driver
* @param pool - pool to allocate the result set
* @param handle - the connection
* @param res - pointer to result set pointer. May point to NULL on entry
* @param statement - the SQL statement to execute
* @param random - 1 to support random access to results (seek any row);
* 0 to support only looping through results in order
* (async access - faster)
* @return 0 for success or error code
*/
APU_DECLARE(int) apr_dbd_select(const apr_dbd_driver_t *driver, apr_pool_t *pool,
apr_dbd_t *handle, apr_dbd_results_t **res,
const char *statement, int random);
/** apr_dbd_num_cols: get the number of columns in a results set
*
* @param driver - the driver
* @param res - result set.
* @return number of columns
*/
APU_DECLARE(int) apr_dbd_num_cols(const apr_dbd_driver_t *driver,
apr_dbd_results_t *res);
/** apr_dbd_num_tuples: get the number of rows in a results set
* of a synchronous select
*
* @param driver - the driver
* @param res - result set.
* @return number of rows, or -1 if the results are asynchronous
*/
APU_DECLARE(int) apr_dbd_num_tuples(const apr_dbd_driver_t *driver,
apr_dbd_results_t *res);
/** apr_dbd_get_row: get a row from a result set
*
* @param driver - the driver
* @param pool - pool to allocate the row
* @param res - result set pointer
* @param row - pointer to row pointer. May point to NULL on entry
* @param rownum - row number (counting from 1), or -1 for "next row".
* Ignored if random access is not supported.
* @return 0 for success, -1 for rownum out of range or data finished
*/
APU_DECLARE(int) apr_dbd_get_row(const apr_dbd_driver_t *driver, apr_pool_t *pool,
apr_dbd_results_t *res, apr_dbd_row_t **row,
int rownum);
/** apr_dbd_get_entry: get an entry from a row
*
* @param driver - the driver
* @param row - row pointer
* @param col - entry number
* @return value from the row, or NULL if col is out of bounds.
*/
APU_DECLARE(const char*) apr_dbd_get_entry(const apr_dbd_driver_t *driver,
apr_dbd_row_t *row, int col);
/** apr_dbd_get_name: get an entry name from a result set
*
* @param driver - the driver
* @param res - result set pointer
* @param col - entry number
* @return name of the entry, or NULL if col is out of bounds.
*/
APU_DECLARE(const char*) apr_dbd_get_name(const apr_dbd_driver_t *driver,
apr_dbd_results_t *res, int col);
/** apr_dbd_error: get current error message (if any)
*
* @param driver - the driver
* @param handle - the connection
* @param errnum - error code from operation that returned an error
* @return the database current error message, or message for errnum
* (implementation-dependent whether errnum is ignored)
*/
APU_DECLARE(const char*) apr_dbd_error(const apr_dbd_driver_t *driver,
apr_dbd_t *handle, int errnum);
/** apr_dbd_escape: escape a string so it is safe for use in query/select
*
* @param driver - the driver
* @param pool - pool to alloc the result from
* @param string - the string to escape
* @param handle - the connection
* @return the escaped, safe string
*/
APU_DECLARE(const char*) apr_dbd_escape(const apr_dbd_driver_t *driver,
apr_pool_t *pool, const char *string,
apr_dbd_t *handle);
/** apr_dbd_prepare: prepare a statement
*
* @param driver - the driver
* @param pool - pool to alloc the result from
* @param handle - the connection
* @param query - the SQL query
* @param label - A label for the prepared statement.
* use NULL for temporary prepared statements
* (eg within a Request in httpd)
* @param statement - statement to prepare. May point to null on entry.
* @return 0 for success or error code
* @remarks To specify parameters of the prepared query, use \%s, \%d etc.
* (see below for full list) in place of database specific parameter syntax
* (e.g. for PostgreSQL, this would be $1, $2, for SQLite3 this would be ?
* etc.). For instance: "SELECT name FROM customers WHERE name=%s" would be
* a query that this function understands.
* @remarks Here is the full list of format specifiers that this function
* understands and what they map to in SQL: \%hhd (TINY INT), \%hhu (UNSIGNED
* TINY INT), \%hd (SHORT), \%hu (UNSIGNED SHORT), \%d (INT), \%u (UNSIGNED
* INT), \%ld (LONG), \%lu (UNSIGNED LONG), \%lld (LONG LONG), \%llu
* (UNSIGNED LONG LONG), \%f (FLOAT, REAL), \%lf (DOUBLE PRECISION), \%s
* (VARCHAR), \%pDt (TEXT), \%pDi (TIME), \%pDd (DATE), \%pDa (DATETIME),
* \%pDs (TIMESTAMP), \%pDz (TIMESTAMP WITH TIME ZONE), \%pDb (BLOB), \%pDc
* (CLOB) and \%pDn (NULL). Not all databases have support for all these
* types, so the underlying driver will attempt the "best match" where
* possible. A \% followed by any letter not in the above list will be
* interpreted as VARCHAR (i.e. \%s).
*/
APU_DECLARE(int) apr_dbd_prepare(const apr_dbd_driver_t *driver, apr_pool_t *pool,
apr_dbd_t *handle, const char *query,
const char *label,
apr_dbd_prepared_t **statement);
/** apr_dbd_pquery: query using a prepared statement + args
*
* @param driver - the driver
* @param pool - working pool
* @param handle - the connection
* @param nrows - number of rows affected.
* @param statement - the prepared statement to execute
* @param nargs - ignored (for backward compatibility only)
* @param args - args to prepared statement
* @return 0 for success or error code
*/
APU_DECLARE(int) apr_dbd_pquery(const apr_dbd_driver_t *driver, apr_pool_t *pool,
apr_dbd_t *handle, int *nrows,
apr_dbd_prepared_t *statement, int nargs,
const char **args);
/** apr_dbd_pselect: select using a prepared statement + args
*
* @param driver - the driver
* @param pool - working pool
* @param handle - the connection
* @param res - pointer to query results. May point to NULL on entry
* @param statement - the prepared statement to execute
* @param random - Whether to support random-access to results
* @param nargs - ignored (for backward compatibility only)
* @param args - args to prepared statement
* @return 0 for success or error code
*/
APU_DECLARE(int) apr_dbd_pselect(const apr_dbd_driver_t *driver, apr_pool_t *pool,
apr_dbd_t *handle, apr_dbd_results_t **res,
apr_dbd_prepared_t *statement, int random,
int nargs, const char **args);
/** apr_dbd_pvquery: query using a prepared statement + args
*
* @param driver - the driver
* @param pool - working pool
* @param handle - the connection
* @param nrows - number of rows affected.
* @param statement - the prepared statement to execute
* @param ... - varargs list
* @return 0 for success or error code
*/
APU_DECLARE_NONSTD(int) apr_dbd_pvquery(const apr_dbd_driver_t *driver,
apr_pool_t *pool,
apr_dbd_t *handle, int *nrows,
apr_dbd_prepared_t *statement, ...);
/** apr_dbd_pvselect: select using a prepared statement + args
*
* @param driver - the driver
* @param pool - working pool
* @param handle - the connection
* @param res - pointer to query results. May point to NULL on entry
* @param statement - the prepared statement to execute
* @param random - Whether to support random-access to results
* @param ... - varargs list
* @return 0 for success or error code
*/
APU_DECLARE_NONSTD(int) apr_dbd_pvselect(const apr_dbd_driver_t *driver,
apr_pool_t *pool, apr_dbd_t *handle,
apr_dbd_results_t **res,
apr_dbd_prepared_t *statement,
int random, ...);
/** apr_dbd_pbquery: query using a prepared statement + binary args
*
* @param driver - the driver
* @param pool - working pool
* @param handle - the connection
* @param nrows - number of rows affected.
* @param statement - the prepared statement to execute
* @param args - binary args to prepared statement
* @return 0 for success or error code
*/
APU_DECLARE(int) apr_dbd_pbquery(const apr_dbd_driver_t *driver,
apr_pool_t *pool, apr_dbd_t *handle,
int *nrows, apr_dbd_prepared_t *statement,
const void **args);
/** apr_dbd_pbselect: select using a prepared statement + binary args
*
* @param driver - the driver
* @param pool - working pool
* @param handle - the connection
* @param res - pointer to query results. May point to NULL on entry
* @param statement - the prepared statement to execute
* @param random - Whether to support random-access to results
* @param args - binary args to prepared statement
* @return 0 for success or error code
*/
APU_DECLARE(int) apr_dbd_pbselect(const apr_dbd_driver_t *driver,
apr_pool_t *pool,
apr_dbd_t *handle, apr_dbd_results_t **res,
apr_dbd_prepared_t *statement, int random,
const void **args);
/** apr_dbd_pvbquery: query using a prepared statement + binary args
*
* @param driver - the driver
* @param pool - working pool
* @param handle - the connection
* @param nrows - number of rows affected.
* @param statement - the prepared statement to execute
* @param ... - varargs list of binary args
* @return 0 for success or error code
*/
APU_DECLARE_NONSTD(int) apr_dbd_pvbquery(const apr_dbd_driver_t *driver,
apr_pool_t *pool,
apr_dbd_t *handle, int *nrows,
apr_dbd_prepared_t *statement, ...);
/** apr_dbd_pvbselect: select using a prepared statement + binary args
*
* @param driver - the driver
* @param pool - working pool
* @param handle - the connection
* @param res - pointer to query results. May point to NULL on entry
* @param statement - the prepared statement to execute
* @param random - Whether to support random-access to results
* @param ... - varargs list of binary args
* @return 0 for success or error code
*/
APU_DECLARE_NONSTD(int) apr_dbd_pvbselect(const apr_dbd_driver_t *driver,
apr_pool_t *pool, apr_dbd_t *handle,
apr_dbd_results_t **res,
apr_dbd_prepared_t *statement,
int random, ...);
/** apr_dbd_datum_get: get a binary entry from a row
*
* @param driver - the driver
* @param row - row pointer
* @param col - entry number
* @param type - type of data to get
* @param data - pointer to data, allocated by the caller
* @return APR_SUCCESS on success, APR_ENOENT if data is NULL or APR_EGENERAL
*/
APU_DECLARE(apr_status_t) apr_dbd_datum_get(const apr_dbd_driver_t *driver,
apr_dbd_row_t *row, int col,
apr_dbd_type_e type, void *data);
/** @} */
#ifdef __cplusplus
}
#endif
#endif

224
include/apr-linux/apr_dbm.h Normal file
View File

@@ -0,0 +1,224 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_DBM_H
#define APR_DBM_H
#include "apu.h"
#include "apr.h"
#include "apr_errno.h"
#include "apr_pools.h"
#include "apr_file_info.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file apr_dbm.h
* @brief APR-UTIL DBM library
*/
/**
* @defgroup APR_Util_DBM DBM routines
* @ingroup APR_Util
* @{
*/
/**
* Structure for referencing a dbm
*/
typedef struct apr_dbm_t apr_dbm_t;
/**
* Structure for referencing the datum record within a dbm
*/
typedef struct
{
/** pointer to the 'data' to retrieve/store in the DBM */
char *dptr;
/** size of the 'data' to retrieve/store in the DBM */
apr_size_t dsize;
} apr_datum_t;
/* modes to open the DB */
#define APR_DBM_READONLY 1 /**< open for read-only access */
#define APR_DBM_READWRITE 2 /**< open for read-write access */
#define APR_DBM_RWCREATE 3 /**< open for r/w, create if needed */
#define APR_DBM_RWTRUNC 4 /**< open for r/w, truncating an existing
DB if present */
/**
* Open a dbm file by file name and type of DBM
* @param dbm The newly opened database
* @param type The type of the DBM (not all may be available at run time)
* <pre>
* GDBM for GDBM files
* SDBM for SDBM files
* DB for berkeley DB files
* NDBM for NDBM files
* default for the default DBM type
* </pre>
* @param name The dbm file name to open
* @param mode The flag value
* <PRE>
* APR_DBM_READONLY open for read-only access
* APR_DBM_READWRITE open for read-write access
* APR_DBM_RWCREATE open for r/w, create if needed
* APR_DBM_RWTRUNC open for r/w, truncate if already there
* </PRE>
* @param perm Permissions to apply to if created
* @param cntxt The pool to use when creating the dbm
* @remark The dbm name may not be a true file name, as many dbm packages
* append suffixes for seperate data and index files.
*/
APU_DECLARE(apr_status_t) apr_dbm_open_ex(apr_dbm_t **dbm, const char* type,
const char *name,
apr_int32_t mode, apr_fileperms_t perm,
apr_pool_t *cntxt);
/**
* Open a dbm file by file name
* @param dbm The newly opened database
* @param name The dbm file name to open
* @param mode The flag value
* <PRE>
* APR_DBM_READONLY open for read-only access
* APR_DBM_READWRITE open for read-write access
* APR_DBM_RWCREATE open for r/w, create if needed
* APR_DBM_RWTRUNC open for r/w, truncate if already there
* </PRE>
* @param perm Permissions to apply to if created
* @param cntxt The pool to use when creating the dbm
* @remark The dbm name may not be a true file name, as many dbm packages
* append suffixes for seperate data and index files.
*/
APU_DECLARE(apr_status_t) apr_dbm_open(apr_dbm_t **dbm, const char *name,
apr_int32_t mode, apr_fileperms_t perm,
apr_pool_t *cntxt);
/**
* Close a dbm file previously opened by apr_dbm_open
* @param dbm The database to close
*/
APU_DECLARE(void) apr_dbm_close(apr_dbm_t *dbm);
/**
* Fetch a dbm record value by key
* @param dbm The database
* @param key The key datum to find this record
* @param pvalue The value datum retrieved for this record
*/
APU_DECLARE(apr_status_t) apr_dbm_fetch(apr_dbm_t *dbm, apr_datum_t key,
apr_datum_t *pvalue);
/**
* Store a dbm record value by key
* @param dbm The database
* @param key The key datum to store this record by
* @param value The value datum to store in this record
*/
APU_DECLARE(apr_status_t) apr_dbm_store(apr_dbm_t *dbm, apr_datum_t key,
apr_datum_t value);
/**
* Delete a dbm record value by key
* @param dbm The database
* @param key The key datum of the record to delete
* @remark It is not an error to delete a non-existent record.
*/
APU_DECLARE(apr_status_t) apr_dbm_delete(apr_dbm_t *dbm, apr_datum_t key);
/**
* Search for a key within the dbm
* @param dbm The database
* @param key The datum describing a key to test
*/
APU_DECLARE(int) apr_dbm_exists(apr_dbm_t *dbm, apr_datum_t key);
/**
* Retrieve the first record key from a dbm
* @param dbm The database
* @param pkey The key datum of the first record
*/
APU_DECLARE(apr_status_t) apr_dbm_firstkey(apr_dbm_t *dbm, apr_datum_t *pkey);
/**
* Retrieve the next record key from a dbm
* @param dbm The database
* @param pkey The key datum of the next record
*/
APU_DECLARE(apr_status_t) apr_dbm_nextkey(apr_dbm_t *dbm, apr_datum_t *pkey);
/**
* Proactively toss any memory associated with the apr_datum_t.
* @param dbm The database
* @param data The datum to free.
*/
APU_DECLARE(void) apr_dbm_freedatum(apr_dbm_t *dbm, apr_datum_t data);
/**
* Report more information when an apr_dbm function fails.
* @param dbm The database
* @param errcode A DBM-specific value for the error (for logging). If this
* isn't needed, it may be NULL.
* @param errbuf Location to store the error text
* @param errbufsize The size of the provided buffer
* @return The errbuf parameter, for convenience.
*/
APU_DECLARE(char *) apr_dbm_geterror(apr_dbm_t *dbm, int *errcode,
char *errbuf, apr_size_t errbufsize);
/**
* If the specified file/path were passed to apr_dbm_open(), return the
* actual file/path names which would be (created and) used. At most, two
* files may be used; used2 may be NULL if only one file is used.
* @param pool The pool for allocating used1 and used2.
* @param type The type of DBM you require info on
* @param pathname The path name to generate used-names from.
* @param used1 The first pathname used by the apr_dbm implementation.
* @param used2 The second pathname used by apr_dbm. If only one file is
* used by the specific implementation, this will be set to NULL.
* @return An error if the specified type is invalid.
* @remark The dbm file(s) don't need to exist. This function only manipulates
* the pathnames.
*/
APU_DECLARE(apr_status_t) apr_dbm_get_usednames_ex(apr_pool_t *pool,
const char *type,
const char *pathname,
const char **used1,
const char **used2);
/**
* If the specified file/path were passed to apr_dbm_open(), return the
* actual file/path names which would be (created and) used. At most, two
* files may be used; used2 may be NULL if only one file is used.
* @param pool The pool for allocating used1 and used2.
* @param pathname The path name to generate used-names from.
* @param used1 The first pathname used by the apr_dbm implementation.
* @param used2 The second pathname used by apr_dbm. If only one file is
* used by the specific implementation, this will be set to NULL.
* @remark The dbm file(s) don't need to exist. This function only manipulates
* the pathnames.
*/
APU_DECLARE(void) apr_dbm_get_usednames(apr_pool_t *pool,
const char *pathname,
const char **used1,
const char **used2);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !APR_DBM_H */

View File

@@ -0,0 +1,94 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_DSO_DOT_H
#define APR_DSO_DOT_H
/**
* @file apr_dso.h
* @brief APR Dynamic Object Handling Routines
*/
#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup apr_dso Dynamic Object Handling
* @ingroup APR
* @{
*/
#if APR_HAS_DSO || defined(DOXYGEN)
/**
* Structure for referencing dynamic objects
*/
typedef struct apr_dso_handle_t apr_dso_handle_t;
/**
* Structure for referencing symbols from dynamic objects
*/
typedef void * apr_dso_handle_sym_t;
/**
* Load a DSO library.
* @param res_handle Location to store new handle for the DSO.
* @param path Path to the DSO library
* @param ctx Pool to use.
* @bug We aught to provide an alternative to RTLD_GLOBAL, which
* is the only supported method of loading DSOs today.
*/
APR_DECLARE(apr_status_t) apr_dso_load(apr_dso_handle_t **res_handle,
const char *path, apr_pool_t *ctx);
/**
* Close a DSO library.
* @param handle handle to close.
*/
APR_DECLARE(apr_status_t) apr_dso_unload(apr_dso_handle_t *handle);
/**
* Load a symbol from a DSO handle.
* @param ressym Location to store the loaded symbol
* @param handle handle to load the symbol from.
* @param symname Name of the symbol to load.
*/
APR_DECLARE(apr_status_t) apr_dso_sym(apr_dso_handle_sym_t *ressym,
apr_dso_handle_t *handle,
const char *symname);
/**
* Report more information when a DSO function fails.
* @param dso The dso handle that has been opened
* @param buf Location to store the dso error
* @param bufsize The size of the provided buffer
*/
APR_DECLARE(const char *) apr_dso_error(apr_dso_handle_t *dso, char *buf, apr_size_t bufsize);
#endif /* APR_HAS_DSO */
/** @} */
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,67 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_ENV_H
#define APR_ENV_H
/**
* @file apr_env.h
* @brief APR Environment functions
*/
#include "apr_errno.h"
#include "apr_pools.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_env Functions for manupulating the environment
* @ingroup APR
* @{
*/
/**
* Get the value of an environment variable
* @param value the returned value, allocated from @a pool
* @param envvar the name of the environment variable
* @param pool where to allocate @a value and any temporary storage from
*/
APR_DECLARE(apr_status_t) apr_env_get(char **value, const char *envvar,
apr_pool_t *pool);
/**
* Set the value of an environment variable
* @param envvar the name of the environment variable
* @param value the value to set
* @param pool where to allocate temporary storage from
*/
APR_DECLARE(apr_status_t) apr_env_set(const char *envvar, const char *value,
apr_pool_t *pool);
/**
* Delete a variable from the environment
* @param envvar the name of the environment variable
* @param pool where to allocate temporary storage from
*/
APR_DECLARE(apr_status_t) apr_env_delete(const char *envvar, apr_pool_t *pool);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ! APR_ENV_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,427 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_FILE_INFO_H
#define APR_FILE_INFO_H
/**
* @file apr_file_info.h
* @brief APR File Information
*/
#include "apr.h"
#include "apr_user.h"
#include "apr_pools.h"
#include "apr_tables.h"
#include "apr_time.h"
#include "apr_errno.h"
#if APR_HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_file_info File Information
* @ingroup APR
* @{
*/
/* Many applications use the type member to determine the
* existance of a file or initialization of the file info,
* so the APR_NOFILE value must be distinct from APR_UNKFILE.
*/
/** apr_filetype_e values for the filetype member of the
* apr_file_info_t structure
* @warning: Not all of the filetypes below can be determined.
* For example, a given platform might not correctly report
* a socket descriptor as APR_SOCK if that type isn't
* well-identified on that platform. In such cases where
* a filetype exists but cannot be described by the recognized
* flags below, the filetype will be APR_UNKFILE. If the
* filetype member is not determined, the type will be APR_NOFILE.
*/
typedef enum {
APR_NOFILE = 0, /**< no file type determined */
APR_REG, /**< a regular file */
APR_DIR, /**< a directory */
APR_CHR, /**< a character device */
APR_BLK, /**< a block device */
APR_PIPE, /**< a FIFO / pipe */
APR_LNK, /**< a symbolic link */
APR_SOCK, /**< a [unix domain] socket */
APR_UNKFILE = 127 /**< a file of some other unknown type */
} apr_filetype_e;
/**
* @defgroup apr_file_permissions File Permissions flags
* @{
*/
#define APR_FPROT_USETID 0x8000 /**< Set user id */
#define APR_FPROT_UREAD 0x0400 /**< Read by user */
#define APR_FPROT_UWRITE 0x0200 /**< Write by user */
#define APR_FPROT_UEXECUTE 0x0100 /**< Execute by user */
#define APR_FPROT_GSETID 0x4000 /**< Set group id */
#define APR_FPROT_GREAD 0x0040 /**< Read by group */
#define APR_FPROT_GWRITE 0x0020 /**< Write by group */
#define APR_FPROT_GEXECUTE 0x0010 /**< Execute by group */
#define APR_FPROT_WSTICKY 0x2000 /**< Sticky bit */
#define APR_FPROT_WREAD 0x0004 /**< Read by others */
#define APR_FPROT_WWRITE 0x0002 /**< Write by others */
#define APR_FPROT_WEXECUTE 0x0001 /**< Execute by others */
#define APR_FPROT_OS_DEFAULT 0x0FFF /**< use OS's default permissions */
/* additional permission flags for apr_file_copy and apr_file_append */
#define APR_FPROT_FILE_SOURCE_PERMS 0x1000 /**< Copy source file's permissions */
/* backcompat */
#define APR_USETID APR_FPROT_USETID /**< @deprecated @see APR_FPROT_USETID */
#define APR_UREAD APR_FPROT_UREAD /**< @deprecated @see APR_FPROT_UREAD */
#define APR_UWRITE APR_FPROT_UWRITE /**< @deprecated @see APR_FPROT_UWRITE */
#define APR_UEXECUTE APR_FPROT_UEXECUTE /**< @deprecated @see APR_FPROT_UEXECUTE */
#define APR_GSETID APR_FPROT_GSETID /**< @deprecated @see APR_FPROT_GSETID */
#define APR_GREAD APR_FPROT_GREAD /**< @deprecated @see APR_FPROT_GREAD */
#define APR_GWRITE APR_FPROT_GWRITE /**< @deprecated @see APR_FPROT_GWRITE */
#define APR_GEXECUTE APR_FPROT_GEXECUTE /**< @deprecated @see APR_FPROT_GEXECUTE */
#define APR_WSTICKY APR_FPROT_WSTICKY /**< @deprecated @see APR_FPROT_WSTICKY */
#define APR_WREAD APR_FPROT_WREAD /**< @deprecated @see APR_FPROT_WREAD */
#define APR_WWRITE APR_FPROT_WWRITE /**< @deprecated @see APR_FPROT_WWRITE */
#define APR_WEXECUTE APR_FPROT_WEXECUTE /**< @deprecated @see APR_FPROT_WEXECUTE */
#define APR_OS_DEFAULT APR_FPROT_OS_DEFAULT /**< @deprecated @see APR_FPROT_OS_DEFAULT */
#define APR_FILE_SOURCE_PERMS APR_FPROT_FILE_SOURCE_PERMS /**< @deprecated @see APR_FPROT_FILE_SOURCE_PERMS */
/** @} */
/**
* Structure for referencing directories.
*/
typedef struct apr_dir_t apr_dir_t;
/**
* Structure for determining file permissions.
*/
typedef apr_int32_t apr_fileperms_t;
#if (defined WIN32) || (defined NETWARE)
/**
* Structure for determining the device the file is on.
*/
typedef apr_uint32_t apr_dev_t;
#else
/**
* Structure for determining the device the file is on.
*/
typedef dev_t apr_dev_t;
#endif
/**
* @defgroup apr_file_stat Stat Functions
* @{
*/
/** file info structure */
typedef struct apr_finfo_t apr_finfo_t;
#define APR_FINFO_LINK 0x00000001 /**< Stat the link not the file itself if it is a link */
#define APR_FINFO_MTIME 0x00000010 /**< Modification Time */
#define APR_FINFO_CTIME 0x00000020 /**< Creation or inode-changed time */
#define APR_FINFO_ATIME 0x00000040 /**< Access Time */
#define APR_FINFO_SIZE 0x00000100 /**< Size of the file */
#define APR_FINFO_CSIZE 0x00000200 /**< Storage size consumed by the file */
#define APR_FINFO_DEV 0x00001000 /**< Device */
#define APR_FINFO_INODE 0x00002000 /**< Inode */
#define APR_FINFO_NLINK 0x00004000 /**< Number of links */
#define APR_FINFO_TYPE 0x00008000 /**< Type */
#define APR_FINFO_USER 0x00010000 /**< User */
#define APR_FINFO_GROUP 0x00020000 /**< Group */
#define APR_FINFO_UPROT 0x00100000 /**< User protection bits */
#define APR_FINFO_GPROT 0x00200000 /**< Group protection bits */
#define APR_FINFO_WPROT 0x00400000 /**< World protection bits */
#define APR_FINFO_ICASE 0x01000000 /**< if dev is case insensitive */
#define APR_FINFO_NAME 0x02000000 /**< ->name in proper case */
#define APR_FINFO_MIN 0x00008170 /**< type, mtime, ctime, atime, size */
#define APR_FINFO_IDENT 0x00003000 /**< dev and inode */
#define APR_FINFO_OWNER 0x00030000 /**< user and group */
#define APR_FINFO_PROT 0x00700000 /**< all protections */
#define APR_FINFO_NORM 0x0073b170 /**< an atomic unix apr_stat() */
#define APR_FINFO_DIRENT 0x02000000 /**< an atomic unix apr_dir_read() */
/**
* The file information structure. This is analogous to the POSIX
* stat structure.
*/
struct apr_finfo_t {
/** Allocates memory and closes lingering handles in the specified pool */
apr_pool_t *pool;
/** The bitmask describing valid fields of this apr_finfo_t structure
* including all available 'wanted' fields and potentially more */
apr_int32_t valid;
/** The access permissions of the file. Mimics Unix access rights. */
apr_fileperms_t protection;
/** The type of file. One of APR_REG, APR_DIR, APR_CHR, APR_BLK, APR_PIPE,
* APR_LNK or APR_SOCK. If the type is undetermined, the value is APR_NOFILE.
* If the type cannot be determined, the value is APR_UNKFILE.
*/
apr_filetype_e filetype;
/** The user id that owns the file */
apr_uid_t user;
/** The group id that owns the file */
apr_gid_t group;
/** The inode of the file. */
apr_ino_t inode;
/** The id of the device the file is on. */
apr_dev_t device;
/** The number of hard links to the file. */
apr_int32_t nlink;
/** The size of the file */
apr_off_t size;
/** The storage size consumed by the file */
apr_off_t csize;
/** The time the file was last accessed */
apr_time_t atime;
/** The time the file was last modified */
apr_time_t mtime;
/** The time the file was created, or the inode was last changed */
apr_time_t ctime;
/** The pathname of the file (possibly unrooted) */
const char *fname;
/** The file's name (no path) in filesystem case */
const char *name;
/** The file's handle, if accessed (can be submitted to apr_duphandle) */
struct apr_file_t *filehand;
};
/**
* get the specified file's stats. The file is specified by filename,
* instead of using a pre-opened file.
* @param finfo Where to store the information about the file, which is
* never touched if the call fails.
* @param fname The name of the file to stat.
* @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_
values
* @param pool the pool to use to allocate the new file.
*
* @note If @c APR_INCOMPLETE is returned all the fields in @a finfo may
* not be filled in, and you need to check the @c finfo->valid bitmask
* to verify that what you're looking for is there.
*/
APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo, const char *fname,
apr_int32_t wanted, apr_pool_t *pool);
/** @} */
/**
* @defgroup apr_dir Directory Manipulation Functions
* @{
*/
/**
* Open the specified directory.
* @param new_dir The opened directory descriptor.
* @param dirname The full path to the directory (use / on all systems)
* @param pool The pool to use.
*/
APR_DECLARE(apr_status_t) apr_dir_open(apr_dir_t **new_dir,
const char *dirname,
apr_pool_t *pool);
/**
* close the specified directory.
* @param thedir the directory descriptor to close.
*/
APR_DECLARE(apr_status_t) apr_dir_close(apr_dir_t *thedir);
/**
* Read the next entry from the specified directory.
* @param finfo the file info structure and filled in by apr_dir_read
* @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_
values
* @param thedir the directory descriptor returned from apr_dir_open
* @remark No ordering is guaranteed for the entries read.
*
* @note If @c APR_INCOMPLETE is returned all the fields in @a finfo may
* not be filled in, and you need to check the @c finfo->valid bitmask
* to verify that what you're looking for is there.
*/
APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
apr_dir_t *thedir);
/**
* Rewind the directory to the first entry.
* @param thedir the directory descriptor to rewind.
*/
APR_DECLARE(apr_status_t) apr_dir_rewind(apr_dir_t *thedir);
/** @} */
/**
* @defgroup apr_filepath Filepath Manipulation Functions
* @{
*/
/** Cause apr_filepath_merge to fail if addpath is above rootpath
* @bug in APR 0.9 and 1.x, this flag's behavior is undefined
* if the rootpath is NULL or empty. In APR 2.0 this should be
* changed to imply NOTABSOLUTE if the rootpath is NULL or empty.
*/
#define APR_FILEPATH_NOTABOVEROOT 0x01
/** internal: Only meaningful with APR_FILEPATH_NOTABOVEROOT */
#define APR_FILEPATH_SECUREROOTTEST 0x02
/** Cause apr_filepath_merge to fail if addpath is above rootpath,
* even given a rootpath /foo/bar and an addpath ../bar/bash
*/
#define APR_FILEPATH_SECUREROOT 0x03
/** Fail apr_filepath_merge if the merged path is relative */
#define APR_FILEPATH_NOTRELATIVE 0x04
/** Fail apr_filepath_merge if the merged path is absolute */
#define APR_FILEPATH_NOTABSOLUTE 0x08
/** Return the file system's native path format (e.g. path delimiters
* of ':' on MacOS9, '\' on Win32, etc.) */
#define APR_FILEPATH_NATIVE 0x10
/** Resolve the true case of existing directories and file elements
* of addpath, (resolving any aliases on Win32) and append a proper
* trailing slash if a directory
*/
#define APR_FILEPATH_TRUENAME 0x20
/**
* Extract the rootpath from the given filepath
* @param rootpath the root file path returned with APR_SUCCESS or APR_EINCOMPLETE
* @param filepath the pathname to parse for its root component
* @param flags the desired rules to apply, from
* <PRE>
* APR_FILEPATH_NATIVE Use native path seperators (e.g. '\' on Win32)
* APR_FILEPATH_TRUENAME Tests that the root exists, and makes it proper
* </PRE>
* @param p the pool to allocate the new path string from
* @remark on return, filepath points to the first non-root character in the
* given filepath. In the simplest example, given a filepath of "/foo",
* returns the rootpath of "/" and filepath points at "foo". This is far
* more complex on other platforms, which will canonicalize the root form
* to a consistant format, given the APR_FILEPATH_TRUENAME flag, and also
* test for the validity of that root (e.g., that a drive d:/ or network
* share //machine/foovol/).
* The function returns APR_ERELATIVE if filepath isn't rooted (an
* error), APR_EINCOMPLETE if the root path is ambigious (but potentially
* legitimate, e.g. "/" on Windows is incomplete because it doesn't specify
* the drive letter), or APR_EBADPATH if the root is simply invalid.
* APR_SUCCESS is returned if filepath is an absolute path.
*/
APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath,
const char **filepath,
apr_int32_t flags,
apr_pool_t *p);
/**
* Merge additional file path onto the previously processed rootpath
* @param newpath the merged paths returned
* @param rootpath the root file path (NULL uses the current working path)
* @param addpath the path to add to the root path
* @param flags the desired APR_FILEPATH_ rules to apply when merging
* @param p the pool to allocate the new path string from
* @remark if the flag APR_FILEPATH_TRUENAME is given, and the addpath
* contains wildcard characters ('*', '?') on platforms that don't support
* such characters within filenames, the paths will be merged, but the
* result code will be APR_EPATHWILD, and all further segments will not
* reflect the true filenames including the wildcard and following segments.
*/
APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
const char *rootpath,
const char *addpath,
apr_int32_t flags,
apr_pool_t *p);
/**
* Split a search path into separate components
* @param pathelts the returned components of the search path
* @param liststr the search path (e.g., <tt>getenv("PATH")</tt>)
* @param p the pool to allocate the array and path components from
* @remark empty path componenta do not become part of @a pathelts.
* @remark the path separator in @a liststr is system specific;
* e.g., ':' on Unix, ';' on Windows, etc.
*/
APR_DECLARE(apr_status_t) apr_filepath_list_split(apr_array_header_t **pathelts,
const char *liststr,
apr_pool_t *p);
/**
* Merge a list of search path components into a single search path
* @param liststr the returned search path; may be NULL if @a pathelts is empty
* @param pathelts the components of the search path
* @param p the pool to allocate the search path from
* @remark emtpy strings in the source array are ignored.
* @remark the path separator in @a liststr is system specific;
* e.g., ':' on Unix, ';' on Windows, etc.
*/
APR_DECLARE(apr_status_t) apr_filepath_list_merge(char **liststr,
apr_array_header_t *pathelts,
apr_pool_t *p);
/**
* Return the default file path (for relative file names)
* @param path the default path string returned
* @param flags optional flag APR_FILEPATH_NATIVE to retrieve the
* default file path in os-native format.
* @param p the pool to allocate the default path string from
*/
APR_DECLARE(apr_status_t) apr_filepath_get(char **path, apr_int32_t flags,
apr_pool_t *p);
/**
* Set the default file path (for relative file names)
* @param path the default path returned
* @param p the pool to allocate any working storage
*/
APR_DECLARE(apr_status_t) apr_filepath_set(const char *path, apr_pool_t *p);
/** The FilePath character encoding is unknown */
#define APR_FILEPATH_ENCODING_UNKNOWN 0
/** The FilePath character encoding is locale-dependent */
#define APR_FILEPATH_ENCODING_LOCALE 1
/** The FilePath character encoding is UTF-8 */
#define APR_FILEPATH_ENCODING_UTF8 2
/**
* Determine the encoding used internally by the FilePath functions
* @param style points to a variable which receives the encoding style flag
* @param p the pool to allocate any working storage
* @remark Use @c apr_os_locale_encoding and/or @c apr_os_default_encoding
* to get the name of the path encoding if it's not UTF-8.
*/
APR_DECLARE(apr_status_t) apr_filepath_encoding(int *style, apr_pool_t *p);
/** @} */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ! APR_FILE_INFO_H */

View File

@@ -0,0 +1,925 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_FILE_IO_H
#define APR_FILE_IO_H
/**
* @file apr_file_io.h
* @brief APR File I/O Handling
*/
#include "apr.h"
#include "apr_pools.h"
#include "apr_time.h"
#include "apr_errno.h"
#include "apr_file_info.h"
#include "apr_inherit.h"
#define APR_WANT_STDIO /**< for SEEK_* */
#define APR_WANT_IOVEC /**< for apr_file_writev */
#include "apr_want.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_file_io File I/O Handling Functions
* @ingroup APR
* @{
*/
/**
* @defgroup apr_file_open_flags File Open Flags/Routines
* @{
*/
/* Note to implementors: Values in the range 0x00100000--0x80000000
are reserved for platform-specific values. */
#define APR_FOPEN_READ 0x00001 /**< Open the file for reading */
#define APR_FOPEN_WRITE 0x00002 /**< Open the file for writing */
#define APR_FOPEN_CREATE 0x00004 /**< Create the file if not there */
#define APR_FOPEN_APPEND 0x00008 /**< Append to the end of the file */
#define APR_FOPEN_TRUNCATE 0x00010 /**< Open the file and truncate
to 0 length */
#define APR_FOPEN_BINARY 0x00020 /**< Open the file in binary mode */
#define APR_FOPEN_EXCL 0x00040 /**< Open should fail if APR_CREATE
and file exists. */
#define APR_FOPEN_BUFFERED 0x00080 /**< Open the file for buffered I/O */
#define APR_FOPEN_DELONCLOSE 0x00100 /**< Delete the file after close */
#define APR_FOPEN_XTHREAD 0x00200 /**< Platform dependent tag to open
the file for use across multiple
threads */
#define APR_FOPEN_SHARELOCK 0x00400 /**< Platform dependent support for
higher level locked read/write
access to support writes across
process/machines */
#define APR_FOPEN_NOCLEANUP 0x00800 /**< Do not register a cleanup
when the file is opened */
#define APR_FOPEN_SENDFILE_ENABLED 0x01000 /**< Advisory flag that this
file should support
apr_socket_sendfile operation */
#define APR_FOPEN_LARGEFILE 0x04000 /**< Platform dependent flag to enable
* large file support, see WARNING below
*/
#define APR_FOPEN_SPARSE 0x08000 /**< Platform dependent flag to enable
* sparse file support, see WARNING below
*/
/* backcompat */
#define APR_READ APR_FOPEN_READ /**< @deprecated @see APR_FOPEN_READ */
#define APR_WRITE APR_FOPEN_WRITE /**< @deprecated @see APR_FOPEN_WRITE */
#define APR_CREATE APR_FOPEN_CREATE /**< @deprecated @see APR_FOPEN_CREATE */
#define APR_APPEND APR_FOPEN_APPEND /**< @deprecated @see APR_FOPEN_APPEND */
#define APR_TRUNCATE APR_FOPEN_TRUNCATE /**< @deprecated @see APR_FOPEN_TRUNCATE */
#define APR_BINARY APR_FOPEN_BINARY /**< @deprecated @see APR_FOPEN_BINARY */
#define APR_EXCL APR_FOPEN_EXCL /**< @deprecated @see APR_FOPEN_EXCL */
#define APR_BUFFERED APR_FOPEN_BUFFERED /**< @deprecated @see APR_FOPEN_BUFFERED */
#define APR_DELONCLOSE APR_FOPEN_DELONCLOSE /**< @deprecated @see APR_FOPEN_DELONCLOSE */
#define APR_XTHREAD APR_FOPEN_XTHREAD /**< @deprecated @see APR_FOPEN_XTHREAD */
#define APR_SHARELOCK APR_FOPEN_SHARELOCK /**< @deprecated @see APR_FOPEN_SHARELOCK */
#define APR_FILE_NOCLEANUP APR_FOPEN_NOCLEANUP /**< @deprecated @see APR_FOPEN_NOCLEANUP */
#define APR_SENDFILE_ENABLED APR_FOPEN_SENDFILE_ENABLED /**< @deprecated @see APR_FOPEN_SENDFILE_ENABLED */
#define APR_LARGEFILE APR_FOPEN_LARGEFILE /**< @deprecated @see APR_FOPEN_LARGEFILE */
/** @warning APR_FOPEN_LARGEFILE flag only has effect on some
* platforms where sizeof(apr_off_t) == 4. Where implemented, it
* allows opening and writing to a file which exceeds the size which
* can be represented by apr_off_t (2 gigabytes). When a file's size
* does exceed 2Gb, apr_file_info_get() will fail with an error on the
* descriptor, likewise apr_stat()/apr_lstat() will fail on the
* filename. apr_dir_read() will fail with APR_INCOMPLETE on a
* directory entry for a large file depending on the particular
* APR_FINFO_* flags. Generally, it is not recommended to use this
* flag.
*
* @warning APR_FOPEN_SPARSE may, depending on platform, convert a
* normal file to a sparse file. Some applications may be unable
* to decipher a sparse file, so it's critical that the sparse file
* flag should only be used for files accessed only by APR or other
* applications known to be able to decipher them. APR does not
* guarentee that it will compress the file into sparse segments
* if it was previously created and written without the sparse flag.
* On platforms which do not understand, or on file systems which
* cannot handle sparse files, the flag is ignored by apr_file_open().
*/
/** @} */
/**
* @defgroup apr_file_seek_flags File Seek Flags
* @{
*/
/* flags for apr_file_seek */
/** Set the file position */
#define APR_SET SEEK_SET
/** Current */
#define APR_CUR SEEK_CUR
/** Go to end of file */
#define APR_END SEEK_END
/** @} */
/**
* @defgroup apr_file_attrs_set_flags File Attribute Flags
* @{
*/
/* flags for apr_file_attrs_set */
#define APR_FILE_ATTR_READONLY 0x01 /**< File is read-only */
#define APR_FILE_ATTR_EXECUTABLE 0x02 /**< File is executable */
#define APR_FILE_ATTR_HIDDEN 0x04 /**< File is hidden */
/** @} */
/**
* @defgroup apr_file_writev{_full} max iovec size
* @{
*/
#if defined(DOXYGEN)
#define APR_MAX_IOVEC_SIZE 1024 /**< System dependent maximum
size of an iovec array */
#elif defined(IOV_MAX)
#define APR_MAX_IOVEC_SIZE IOV_MAX
#elif defined(MAX_IOVEC)
#define APR_MAX_IOVEC_SIZE MAX_IOVEC
#else
#define APR_MAX_IOVEC_SIZE 1024
#endif
/** @} */
/** File attributes */
typedef apr_uint32_t apr_fileattrs_t;
/** Type to pass as whence argument to apr_file_seek. */
typedef int apr_seek_where_t;
/**
* Structure for referencing files.
*/
typedef struct apr_file_t apr_file_t;
/* File lock types/flags */
/**
* @defgroup apr_file_lock_types File Lock Types
* @{
*/
#define APR_FLOCK_SHARED 1 /**< Shared lock. More than one process
or thread can hold a shared lock
at any given time. Essentially,
this is a "read lock", preventing
writers from establishing an
exclusive lock. */
#define APR_FLOCK_EXCLUSIVE 2 /**< Exclusive lock. Only one process
may hold an exclusive lock at any
given time. This is analogous to
a "write lock". */
#define APR_FLOCK_TYPEMASK 0x000F /**< mask to extract lock type */
#define APR_FLOCK_NONBLOCK 0x0010 /**< do not block while acquiring the
file lock */
/** @} */
/**
* Open the specified file.
* @param newf The opened file descriptor.
* @param fname The full path to the file (using / on all systems)
* @param flag Or'ed value of:
* <PRE>
* APR_READ open for reading
* APR_WRITE open for writing
* APR_CREATE create the file if not there
* APR_APPEND file ptr is set to end prior to all writes
* APR_TRUNCATE set length to zero if file exists
* APR_BINARY not a text file (This flag is ignored on
* UNIX because it has no meaning)
* APR_BUFFERED buffer the data. Default is non-buffered
* APR_EXCL return error if APR_CREATE and file exists
* APR_DELONCLOSE delete the file after closing.
* APR_XTHREAD Platform dependent tag to open the file
* for use across multiple threads
* APR_SHARELOCK Platform dependent support for higher
* level locked read/write access to support
* writes across process/machines
* APR_FILE_NOCLEANUP Do not register a cleanup with the pool
* passed in on the <EM>pool</EM> argument (see below).
* The apr_os_file_t handle in apr_file_t will not
* be closed when the pool is destroyed.
* APR_SENDFILE_ENABLED Open with appropriate platform semantics
* for sendfile operations. Advisory only,
* apr_socket_sendfile does not check this flag.
* </PRE>
* @param perm Access permissions for file.
* @param pool The pool to use.
* @remark If perm is APR_OS_DEFAULT and the file is being created,
* appropriate default permissions will be used.
* @remark By default, the returned file descriptor will not be
* inherited by child processes created by apr_proc_create(). This
* can be changed using apr_file_inherit_set().
*/
APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **newf, const char *fname,
apr_int32_t flag, apr_fileperms_t perm,
apr_pool_t *pool);
/**
* Close the specified file.
* @param file The file descriptor to close.
*/
APR_DECLARE(apr_status_t) apr_file_close(apr_file_t *file);
/**
* Delete the specified file.
* @param path The full path to the file (using / on all systems)
* @param pool The pool to use.
* @remark If the file is open, it won't be removed until all
* instances are closed.
*/
APR_DECLARE(apr_status_t) apr_file_remove(const char *path, apr_pool_t *pool);
/**
* Rename the specified file.
* @param from_path The full path to the original file (using / on all systems)
* @param to_path The full path to the new file (using / on all systems)
* @param pool The pool to use.
* @warning If a file exists at the new location, then it will be
* overwritten. Moving files or directories across devices may not be
* possible.
*/
APR_DECLARE(apr_status_t) apr_file_rename(const char *from_path,
const char *to_path,
apr_pool_t *pool);
/**
* Copy the specified file to another file.
* @param from_path The full path to the original file (using / on all systems)
* @param to_path The full path to the new file (using / on all systems)
* @param perms Access permissions for the new file if it is created.
* In place of the usual or'd combination of file permissions, the
* value APR_FILE_SOURCE_PERMS may be given, in which case the source
* file's permissions are copied.
* @param pool The pool to use.
* @remark The new file does not need to exist, it will be created if required.
* @warning If the new file already exists, its contents will be overwritten.
*/
APR_DECLARE(apr_status_t) apr_file_copy(const char *from_path,
const char *to_path,
apr_fileperms_t perms,
apr_pool_t *pool);
/**
* Append the specified file to another file.
* @param from_path The full path to the source file (use / on all systems)
* @param to_path The full path to the destination file (use / on all systems)
* @param perms Access permissions for the destination file if it is created.
* In place of the usual or'd combination of file permissions, the
* value APR_FILE_SOURCE_PERMS may be given, in which case the source
* file's permissions are copied.
* @param pool The pool to use.
* @remark The new file does not need to exist, it will be created if required.
*/
APR_DECLARE(apr_status_t) apr_file_append(const char *from_path,
const char *to_path,
apr_fileperms_t perms,
apr_pool_t *pool);
/**
* Are we at the end of the file
* @param fptr The apr file we are testing.
* @remark Returns APR_EOF if we are at the end of file, APR_SUCCESS otherwise.
*/
APR_DECLARE(apr_status_t) apr_file_eof(apr_file_t *fptr);
/**
* Open standard error as an apr file pointer.
* @param thefile The apr file to use as stderr.
* @param pool The pool to allocate the file out of.
*
* @remark The only reason that the apr_file_open_std* functions exist
* is that you may not always have a stderr/out/in on Windows. This
* is generally a problem with newer versions of Windows and services.
*
* @remark The other problem is that the C library functions generally work
* differently on Windows and Unix. So, by using apr_file_open_std*
* functions, you can get a handle to an APR struct that works with
* the APR functions which are supposed to work identically on all
* platforms.
*/
APR_DECLARE(apr_status_t) apr_file_open_stderr(apr_file_t **thefile,
apr_pool_t *pool);
/**
* open standard output as an apr file pointer.
* @param thefile The apr file to use as stdout.
* @param pool The pool to allocate the file out of.
*
* @remark See remarks for apr_file_open_stderr.
*/
APR_DECLARE(apr_status_t) apr_file_open_stdout(apr_file_t **thefile,
apr_pool_t *pool);
/**
* open standard input as an apr file pointer.
* @param thefile The apr file to use as stdin.
* @param pool The pool to allocate the file out of.
*
* @remark See remarks for apr_file_open_stderr.
*/
APR_DECLARE(apr_status_t) apr_file_open_stdin(apr_file_t **thefile,
apr_pool_t *pool);
/**
* open standard error as an apr file pointer, with flags.
* @param thefile The apr file to use as stderr.
* @param flags The flags to open the file with. Only the APR_EXCL,
* APR_BUFFERED, APR_XTHREAD, APR_SHARELOCK,
* APR_SENDFILE_ENABLED and APR_LARGEFILE flags should
* be used. The APR_WRITE flag will be set unconditionally.
* @param pool The pool to allocate the file out of.
*
* @remark See remarks for apr_file_open_stderr.
*/
APR_DECLARE(apr_status_t) apr_file_open_flags_stderr(apr_file_t **thefile,
apr_int32_t flags,
apr_pool_t *pool);
/**
* open standard output as an apr file pointer, with flags.
* @param thefile The apr file to use as stdout.
* @param flags The flags to open the file with. Only the APR_EXCL,
* APR_BUFFERED, APR_XTHREAD, APR_SHARELOCK,
* APR_SENDFILE_ENABLED and APR_LARGEFILE flags should
* be used. The APR_WRITE flag will be set unconditionally.
* @param pool The pool to allocate the file out of.
*
* @remark See remarks for apr_file_open_stderr.
*/
APR_DECLARE(apr_status_t) apr_file_open_flags_stdout(apr_file_t **thefile,
apr_int32_t flags,
apr_pool_t *pool);
/**
* open standard input as an apr file pointer, with flags.
* @param thefile The apr file to use as stdin.
* @param flags The flags to open the file with. Only the APR_EXCL,
* APR_BUFFERED, APR_XTHREAD, APR_SHARELOCK,
* APR_SENDFILE_ENABLED and APR_LARGEFILE flags should
* be used. The APR_READ flag will be set unconditionally.
* @param pool The pool to allocate the file out of.
*
* @remark See remarks for apr_file_open_stderr.
*/
APR_DECLARE(apr_status_t) apr_file_open_flags_stdin(apr_file_t **thefile,
apr_int32_t flags,
apr_pool_t *pool);
/**
* Read data from the specified file.
* @param thefile The file descriptor to read from.
* @param buf The buffer to store the data to.
* @param nbytes On entry, the number of bytes to read; on exit, the number
* of bytes read.
*
* @remark apr_file_read will read up to the specified number of
* bytes, but never more. If there isn't enough data to fill that
* number of bytes, all of the available data is read. The third
* argument is modified to reflect the number of bytes read. If a
* char was put back into the stream via ungetc, it will be the first
* character returned.
*
* @remark It is not possible for both bytes to be read and an APR_EOF
* or other error to be returned. APR_EINTR is never returned.
*/
APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf,
apr_size_t *nbytes);
/**
* Write data to the specified file.
* @param thefile The file descriptor to write to.
* @param buf The buffer which contains the data.
* @param nbytes On entry, the number of bytes to write; on exit, the number
* of bytes written.
*
* @remark apr_file_write will write up to the specified number of
* bytes, but never more. If the OS cannot write that many bytes, it
* will write as many as it can. The third argument is modified to
* reflect the * number of bytes written.
*
* @remark It is possible for both bytes to be written and an error to
* be returned. APR_EINTR is never returned.
*/
APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf,
apr_size_t *nbytes);
/**
* Write data from iovec array to the specified file.
* @param thefile The file descriptor to write to.
* @param vec The array from which to get the data to write to the file.
* @param nvec The number of elements in the struct iovec array. This must
* be smaller than APR_MAX_IOVEC_SIZE. If it isn't, the function
* will fail with APR_EINVAL.
* @param nbytes The number of bytes written.
*
* @remark It is possible for both bytes to be written and an error to
* be returned. APR_EINTR is never returned.
*
* @remark apr_file_writev is available even if the underlying
* operating system doesn't provide writev().
*/
APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile,
const struct iovec *vec,
apr_size_t nvec, apr_size_t *nbytes);
/**
* Read data from the specified file, ensuring that the buffer is filled
* before returning.
* @param thefile The file descriptor to read from.
* @param buf The buffer to store the data to.
* @param nbytes The number of bytes to read.
* @param bytes_read If non-NULL, this will contain the number of bytes read.
*
* @remark apr_file_read will read up to the specified number of
* bytes, but never more. If there isn't enough data to fill that
* number of bytes, then the process/thread will block until it is
* available or EOF is reached. If a char was put back into the
* stream via ungetc, it will be the first character returned.
*
* @remark It is possible for both bytes to be read and an error to be
* returned. And if *bytes_read is less than nbytes, an accompanying
* error is _always_ returned.
*
* @remark APR_EINTR is never returned.
*/
APR_DECLARE(apr_status_t) apr_file_read_full(apr_file_t *thefile, void *buf,
apr_size_t nbytes,
apr_size_t *bytes_read);
/**
* Write data to the specified file, ensuring that all of the data is
* written before returning.
* @param thefile The file descriptor to write to.
* @param buf The buffer which contains the data.
* @param nbytes The number of bytes to write.
* @param bytes_written If non-NULL, set to the number of bytes written.
*
* @remark apr_file_write will write up to the specified number of
* bytes, but never more. If the OS cannot write that many bytes, the
* process/thread will block until they can be written. Exceptional
* error such as "out of space" or "pipe closed" will terminate with
* an error.
*
* @remark It is possible for both bytes to be written and an error to
* be returned. And if *bytes_written is less than nbytes, an
* accompanying error is _always_ returned.
*
* @remark APR_EINTR is never returned.
*/
APR_DECLARE(apr_status_t) apr_file_write_full(apr_file_t *thefile,
const void *buf,
apr_size_t nbytes,
apr_size_t *bytes_written);
/**
* Write data from iovec array to the specified file, ensuring that all of the
* data is written before returning.
* @param thefile The file descriptor to write to.
* @param vec The array from which to get the data to write to the file.
* @param nvec The number of elements in the struct iovec array. This must
* be smaller than APR_MAX_IOVEC_SIZE. If it isn't, the function
* will fail with APR_EINVAL.
* @param nbytes The number of bytes written.
*
* @remark apr_file_writev_full is available even if the underlying
* operating system doesn't provide writev().
*/
APR_DECLARE(apr_status_t) apr_file_writev_full(apr_file_t *thefile,
const struct iovec *vec,
apr_size_t nvec,
apr_size_t *nbytes);
/**
* Write a character into the specified file.
* @param ch The character to write.
* @param thefile The file descriptor to write to
*/
APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile);
/**
* Read a character from the specified file.
* @param ch The character to read into
* @param thefile The file descriptor to read from
*/
APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile);
/**
* Put a character back onto a specified stream.
* @param ch The character to write.
* @param thefile The file descriptor to write to
*/
APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile);
/**
* Read a string from the specified file.
* @param str The buffer to store the string in.
* @param len The length of the string
* @param thefile The file descriptor to read from
* @remark The buffer will be NUL-terminated if any characters are stored.
*/
APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len,
apr_file_t *thefile);
/**
* Write the string into the specified file.
* @param str The string to write.
* @param thefile The file descriptor to write to
*/
APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile);
/**
* Flush the file's buffer.
* @param thefile The file descriptor to flush
*/
APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile);
/**
* Duplicate the specified file descriptor.
* @param new_file The structure to duplicate into.
* @param old_file The file to duplicate.
* @param p The pool to use for the new file.
* @remark *new_file must point to a valid apr_file_t, or point to NULL.
*/
APR_DECLARE(apr_status_t) apr_file_dup(apr_file_t **new_file,
apr_file_t *old_file,
apr_pool_t *p);
/**
* Duplicate the specified file descriptor and close the original
* @param new_file The old file that is to be closed and reused
* @param old_file The file to duplicate
* @param p The pool to use for the new file
*
* @remark new_file MUST point at a valid apr_file_t. It cannot be NULL.
*/
APR_DECLARE(apr_status_t) apr_file_dup2(apr_file_t *new_file,
apr_file_t *old_file,
apr_pool_t *p);
/**
* Move the specified file descriptor to a new pool
* @param new_file Pointer in which to return the new apr_file_t
* @param old_file The file to move
* @param p The pool to which the descriptor is to be moved
* @remark Unlike apr_file_dup2(), this function doesn't do an
* OS dup() operation on the underlying descriptor; it just
* moves the descriptor's apr_file_t wrapper to a new pool.
* @remark The new pool need not be an ancestor of old_file's pool.
* @remark After calling this function, old_file may not be used
*/
APR_DECLARE(apr_status_t) apr_file_setaside(apr_file_t **new_file,
apr_file_t *old_file,
apr_pool_t *p);
/**
* Give the specified apr file handle a new buffer
* @param thefile The file handle that is to be modified
* @param buffer The buffer
* @param bufsize The size of the buffer
* @remark It is possible to add a buffer to previously unbuffered
* file handles, the APR_BUFFERED flag will be added to
* the file handle's flags. Likewise, with buffer=NULL and
* bufsize=0 arguments it is possible to make a previously
* buffered file handle unbuffered.
*/
APR_DECLARE(apr_status_t) apr_file_buffer_set(apr_file_t *thefile,
char * buffer,
apr_size_t bufsize);
/**
* Get the size of any buffer for the specified apr file handle
* @param thefile The file handle
*/
APR_DECLARE(apr_size_t) apr_file_buffer_size_get(apr_file_t *thefile);
/**
* Move the read/write file offset to a specified byte within a file.
* @param thefile The file descriptor
* @param where How to move the pointer, one of:
* <PRE>
* APR_SET -- set the offset to offset
* APR_CUR -- add the offset to the current position
* APR_END -- add the offset to the current file size
* </PRE>
* @param offset The offset to move the pointer to.
* @remark The third argument is modified to be the offset the pointer
was actually moved to.
*/
APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile,
apr_seek_where_t where,
apr_off_t *offset);
/**
* Create an anonymous pipe.
* @param in The newly created pipe's file for reading.
* @param out The newly created pipe's file for writing.
* @param pool The pool to operate on.
* @remark By default, the returned file descriptors will be inherited
* by child processes created using apr_proc_create(). This can be
* changed using apr_file_inherit_unset().
* @bug Some platforms cannot toggle between blocking and nonblocking,
* and when passing a pipe as a standard handle to an application which
* does not expect it, a non-blocking stream will fluxor the client app.
* @deprecated @see apr_file_pipe_create_ex
*/
APR_DECLARE(apr_status_t) apr_file_pipe_create(apr_file_t **in,
apr_file_t **out,
apr_pool_t *pool);
/**
* Create an anonymous pipe which portably supports async timeout options.
* @param in The newly created pipe's file for reading.
* @param out The newly created pipe's file for writing.
* @param blocking one of these values defined in apr_thread_proc.h;
* <pre>
* APR_FULL_BLOCK
* APR_READ_BLOCK
* APR_WRITE_BLOCK
* APR_FULL_NONBLOCK
* </pre>
* @remark By default, the returned file descriptors will be inherited
* by child processes created using apr_proc_create(). This can be
* changed using apr_file_inherit_unset().
* @remark Some platforms cannot toggle between blocking and nonblocking,
* and when passing a pipe as a standard handle to an application which
* does not expect it, a non-blocking stream will fluxor the client app.
* Use this function rather than apr_file_pipe_create to create pipes
* where one or both ends require non-blocking semantics.
*/
APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in,
apr_file_t **out,
apr_int32_t blocking,
apr_pool_t *p);
/**
* Create a named pipe.
* @param filename The filename of the named pipe
* @param perm The permissions for the newly created pipe.
* @param pool The pool to operate on.
*/
APR_DECLARE(apr_status_t) apr_file_namedpipe_create(const char *filename,
apr_fileperms_t perm,
apr_pool_t *pool);
/**
* Get the timeout value for a pipe or manipulate the blocking state.
* @param thepipe The pipe we are getting a timeout for.
* @param timeout The current timeout value in microseconds.
*/
APR_DECLARE(apr_status_t) apr_file_pipe_timeout_get(apr_file_t *thepipe,
apr_interval_time_t *timeout);
/**
* Set the timeout value for a pipe or manipulate the blocking state.
* @param thepipe The pipe we are setting a timeout on.
* @param timeout The timeout value in microseconds. Values < 0 mean wait
* forever, 0 means do not wait at all.
*/
APR_DECLARE(apr_status_t) apr_file_pipe_timeout_set(apr_file_t *thepipe,
apr_interval_time_t timeout);
/** file (un)locking functions. */
/**
* Establish a lock on the specified, open file. The lock may be advisory
* or mandatory, at the discretion of the platform. The lock applies to
* the file as a whole, rather than a specific range. Locks are established
* on a per-thread/process basis; a second lock by the same thread will not
* block.
* @param thefile The file to lock.
* @param type The type of lock to establish on the file.
*/
APR_DECLARE(apr_status_t) apr_file_lock(apr_file_t *thefile, int type);
/**
* Remove any outstanding locks on the file.
* @param thefile The file to unlock.
*/
APR_DECLARE(apr_status_t) apr_file_unlock(apr_file_t *thefile);
/**accessor and general file_io functions. */
/**
* return the file name of the current file.
* @param new_path The path of the file.
* @param thefile The currently open file.
*/
APR_DECLARE(apr_status_t) apr_file_name_get(const char **new_path,
apr_file_t *thefile);
/**
* Return the data associated with the current file.
* @param data The user data associated with the file.
* @param key The key to use for retreiving data associated with this file.
* @param file The currently open file.
*/
APR_DECLARE(apr_status_t) apr_file_data_get(void **data, const char *key,
apr_file_t *file);
/**
* Set the data associated with the current file.
* @param file The currently open file.
* @param data The user data to associate with the file.
* @param key The key to use for assocaiteing data with the file.
* @param cleanup The cleanup routine to use when the file is destroyed.
*/
APR_DECLARE(apr_status_t) apr_file_data_set(apr_file_t *file, void *data,
const char *key,
apr_status_t (*cleanup)(void *));
/**
* Write a string to a file using a printf format.
* @param fptr The file to write to.
* @param format The format string
* @param ... The values to substitute in the format string
* @return The number of bytes written
*/
APR_DECLARE_NONSTD(int) apr_file_printf(apr_file_t *fptr,
const char *format, ...)
__attribute__((format(printf,2,3)));
/**
* set the specified file's permission bits.
* @param fname The file (name) to apply the permissions to.
* @param perms The permission bits to apply to the file.
*
* @warning Some platforms may not be able to apply all of the
* available permission bits; APR_INCOMPLETE will be returned if some
* permissions are specified which could not be set.
*
* @warning Platforms which do not implement this feature will return
* APR_ENOTIMPL.
*/
APR_DECLARE(apr_status_t) apr_file_perms_set(const char *fname,
apr_fileperms_t perms);
/**
* Set attributes of the specified file.
* @param fname The full path to the file (using / on all systems)
* @param attributes Or'd combination of
* <PRE>
* APR_FILE_ATTR_READONLY - make the file readonly
* APR_FILE_ATTR_EXECUTABLE - make the file executable
* APR_FILE_ATTR_HIDDEN - make the file hidden
* </PRE>
* @param attr_mask Mask of valid bits in attributes.
* @param pool the pool to use.
* @remark This function should be used in preference to explict manipulation
* of the file permissions, because the operations to provide these
* attributes are platform specific and may involve more than simply
* setting permission bits.
* @warning Platforms which do not implement this feature will return
* APR_ENOTIMPL.
*/
APR_DECLARE(apr_status_t) apr_file_attrs_set(const char *fname,
apr_fileattrs_t attributes,
apr_fileattrs_t attr_mask,
apr_pool_t *pool);
/**
* Set the mtime of the specified file.
* @param fname The full path to the file (using / on all systems)
* @param mtime The mtime to apply to the file.
* @param pool The pool to use.
* @warning Platforms which do not implement this feature will return
* APR_ENOTIMPL.
*/
APR_DECLARE(apr_status_t) apr_file_mtime_set(const char *fname,
apr_time_t mtime,
apr_pool_t *pool);
/**
* Create a new directory on the file system.
* @param path the path for the directory to be created. (use / on all systems)
* @param perm Permissions for the new direcoty.
* @param pool the pool to use.
*/
APR_DECLARE(apr_status_t) apr_dir_make(const char *path, apr_fileperms_t perm,
apr_pool_t *pool);
/** Creates a new directory on the file system, but behaves like
* 'mkdir -p'. Creates intermediate directories as required. No error
* will be reported if PATH already exists.
* @param path the path for the directory to be created. (use / on all systems)
* @param perm Permissions for the new direcoty.
* @param pool the pool to use.
*/
APR_DECLARE(apr_status_t) apr_dir_make_recursive(const char *path,
apr_fileperms_t perm,
apr_pool_t *pool);
/**
* Remove directory from the file system.
* @param path the path for the directory to be removed. (use / on all systems)
* @param pool the pool to use.
* @remark Removing a directory which is in-use (e.g., the current working
* directory, or during apr_dir_read, or with an open file) is not portable.
*/
APR_DECLARE(apr_status_t) apr_dir_remove(const char *path, apr_pool_t *pool);
/**
* get the specified file's stats.
* @param finfo Where to store the information about the file.
* @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_ values
* @param thefile The file to get information about.
*/
APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo,
apr_int32_t wanted,
apr_file_t *thefile);
/**
* Truncate the file's length to the specified offset
* @param fp The file to truncate
* @param offset The offset to truncate to.
* @remark The read/write file offset is repositioned to offset.
*/
APR_DECLARE(apr_status_t) apr_file_trunc(apr_file_t *fp, apr_off_t offset);
/**
* Retrieve the flags that were passed into apr_file_open()
* when the file was opened.
* @return apr_int32_t the flags
*/
APR_DECLARE(apr_int32_t) apr_file_flags_get(apr_file_t *f);
/**
* Get the pool used by the file.
*/
APR_POOL_DECLARE_ACCESSOR(file);
/**
* Set a file to be inherited by child processes.
*
*/
APR_DECLARE_INHERIT_SET(file);
/**
* Unset a file from being inherited by child processes.
*/
APR_DECLARE_INHERIT_UNSET(file);
/**
* Open a temporary file
* @param fp The apr file to use as a temporary file.
* @param templ The template to use when creating a temp file.
* @param flags The flags to open the file with. If this is zero,
* the file is opened with
* APR_CREATE | APR_READ | APR_WRITE | APR_EXCL | APR_DELONCLOSE
* @param p The pool to allocate the file out of.
* @remark
* This function generates a unique temporary file name from template.
* The last six characters of template must be XXXXXX and these are replaced
* with a string that makes the filename unique. Since it will be modified,
* template must not be a string constant, but should be declared as a character
* array.
*
*/
APR_DECLARE(apr_status_t) apr_file_mktemp(apr_file_t **fp, char *templ,
apr_int32_t flags, apr_pool_t *p);
/**
* Find an existing directory suitable as a temporary storage location.
* @param temp_dir The temp directory.
* @param p The pool to use for any necessary allocations.
* @remark
* This function uses an algorithm to search for a directory that an
* an application can use for temporary storage. Once such a
* directory is found, that location is cached by the library. Thus,
* callers only pay the cost of this algorithm once if that one time
* is successful.
*
*/
APR_DECLARE(apr_status_t) apr_temp_dir_get(const char **temp_dir,
apr_pool_t *p);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ! APR_FILE_IO_H */

View File

@@ -0,0 +1,149 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)fnmatch.h 8.1 (Berkeley) 6/2/93
*/
/* This file has been modified by the Apache Software Foundation. */
#ifndef _APR_FNMATCH_H_
#define _APR_FNMATCH_H_
/**
* @file apr_fnmatch.h
* @brief APR FNMatch Functions
*/
#include "apr_errno.h"
#include "apr_tables.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup apr_fnmatch Filename Matching Functions
* @ingroup APR
* @{
*/
#define APR_FNM_NOMATCH 1 /**< Match failed. */
#define APR_FNM_NOESCAPE 0x01 /**< Disable backslash escaping. */
#define APR_FNM_PATHNAME 0x02 /**< Slash must be matched by slash. */
#define APR_FNM_PERIOD 0x04 /**< Period must be matched by period. */
#define APR_FNM_CASE_BLIND 0x08 /**< Compare characters case-insensitively.
* @remark This flag is an Apache addition
*/
/**
* Try to match the string to the given pattern, return APR_SUCCESS if
* match, else return APR_FNM_NOMATCH. Note that there is no such thing as
* an illegal pattern.
*
* With all flags unset, a pattern is interpreted as such:
*
* PATTERN: Backslash followed by any character, including another
* backslash.<br/>
* MATCHES: That character exactly.
*
* <p>
* PATTERN: ?<br/>
* MATCHES: Any single character.
* </p>
*
* <p>
* PATTERN: *<br/>
* MATCHES: Any sequence of zero or more characters. (Note that multiple
* *s in a row are equivalent to one.)
*
* PATTERN: Any character other than \?*[ or a \ at the end of the pattern<br/>
* MATCHES: That character exactly. (Case sensitive.)
*
* PATTERN: [ followed by a class description followed by ]<br/>
* MATCHES: A single character described by the class description.
* (Never matches, if the class description reaches until the
* end of the string without a ].) If the first character of
* the class description is ^ or !, the sense of the description
* is reversed. The rest of the class description is a list of
* single characters or pairs of characters separated by -. Any
* of those characters can have a backslash in front of them,
* which is ignored; this lets you use the characters ] and -
* in the character class, as well as ^ and ! at the
* beginning. The pattern matches a single character if it
* is one of the listed characters or falls into one of the
* listed ranges (inclusive, case sensitive). Ranges with
* the first character larger than the second are legal but
* never match. Edge cases: [] never matches, and [^] and [!]
* always match without consuming a character.
*
* Note that these patterns attempt to match the entire string, not
* just find a substring matching the pattern.
*
* @param pattern The pattern to match to
* @param strings The string we are trying to match
* @param flags flags to use in the match. Bitwise OR of:
* <pre>
* APR_FNM_NOESCAPE Disable backslash escaping
* APR_FNM_PATHNAME Slash must be matched by slash
* APR_FNM_PERIOD Period must be matched by period
* APR_FNM_CASE_BLIND Compare characters case-insensitively.
* </pre>
*/
APR_DECLARE(apr_status_t) apr_fnmatch(const char *pattern,
const char *strings, int flags);
/**
* Determine if the given pattern is a regular expression.
* @param pattern The pattern to search for glob characters.
* @return non-zero if pattern has any glob characters in it
*/
APR_DECLARE(int) apr_fnmatch_test(const char *pattern);
/**
* Find all files that match a specified pattern.
* @param pattern The pattern to use for finding files.
* @param result Array to use when storing the results
* @param p The pool to use.
* @return non-zero if pattern has any glob characters in it
*/
APR_DECLARE(apr_status_t) apr_match_glob(const char *pattern,
apr_array_header_t **result,
apr_pool_t *p);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !_APR_FNMATCH_H_ */

View File

@@ -0,0 +1,241 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_GENERAL_H
#define APR_GENERAL_H
/**
* @file apr_general.h
* This is collection of oddballs that didn't fit anywhere else,
* and might move to more appropriate headers with the release
* of APR 1.0.
* @brief APR Miscellaneous library routines
*/
#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#if APR_HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_general Miscellaneous library routines
* @ingroup APR
* This is collection of oddballs that didn't fit anywhere else,
* and might move to more appropriate headers with the release
* of APR 1.0.
* @{
*/
/** FALSE */
#ifndef FALSE
#define FALSE 0
#endif
/** TRUE */
#ifndef TRUE
#define TRUE (!FALSE)
#endif
/** a space */
#define APR_ASCII_BLANK '\040'
/** a carrige return */
#define APR_ASCII_CR '\015'
/** a line feed */
#define APR_ASCII_LF '\012'
/** a tab */
#define APR_ASCII_TAB '\011'
/** signal numbers typedef */
typedef int apr_signum_t;
/**
* Finding offsets of elements within structures.
* Taken from the X code... they've sweated portability of this stuff
* so we don't have to. Sigh...
* @param p_type pointer type name
* @param field data field within the structure pointed to
* @return offset
*/
#if defined(CRAY) || (defined(__arm) && !defined(LINUX))
#ifdef __STDC__
#define APR_OFFSET(p_type,field) _Offsetof(p_type,field)
#else
#ifdef CRAY2
#define APR_OFFSET(p_type,field) \
(sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))
#else /* !CRAY2 */
#define APR_OFFSET(p_type,field) ((unsigned int)&(((p_type)NULL)->field))
#endif /* !CRAY2 */
#endif /* __STDC__ */
#else /* ! (CRAY || __arm) */
#define APR_OFFSET(p_type,field) \
((long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))
#endif /* !CRAY */
/**
* Finding offsets of elements within structures.
* @param s_type structure type name
* @param field data field within the structure
* @return offset
*/
#if defined(offsetof) && !defined(__cplusplus)
#define APR_OFFSETOF(s_type,field) offsetof(s_type,field)
#else
#define APR_OFFSETOF(s_type,field) APR_OFFSET(s_type*,field)
#endif
#ifndef DOXYGEN
/* A couple of prototypes for functions in case some platform doesn't
* have it
*/
#if (!APR_HAVE_STRCASECMP) && (APR_HAVE_STRICMP)
#define strcasecmp(s1, s2) stricmp(s1, s2)
#elif (!APR_HAVE_STRCASECMP)
int strcasecmp(const char *a, const char *b);
#endif
#if (!APR_HAVE_STRNCASECMP) && (APR_HAVE_STRNICMP)
#define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
#elif (!APR_HAVE_STRNCASECMP)
int strncasecmp(const char *a, const char *b, size_t n);
#endif
#endif
/**
* Alignment macros
*/
/* APR_ALIGN() is only to be used to align on a power of 2 boundary */
#define APR_ALIGN(size, boundary) \
(((size) + ((boundary) - 1)) & ~((boundary) - 1))
/** Default alignment */
#define APR_ALIGN_DEFAULT(size) APR_ALIGN(size, 8)
/**
* String and memory functions
*/
/* APR_STRINGIFY is defined here, and also in apr_release.h, so wrap it */
#ifndef APR_STRINGIFY
/** Properly quote a value as a string in the C preprocessor */
#define APR_STRINGIFY(n) APR_STRINGIFY_HELPER(n)
/** Helper macro for APR_STRINGIFY */
#define APR_STRINGIFY_HELPER(n) #n
#endif
#if (!APR_HAVE_MEMMOVE)
#define memmove(a,b,c) bcopy(b,a,c)
#endif
#if (!APR_HAVE_MEMCHR)
void *memchr(const void *s, int c, size_t n);
#endif
/** @} */
/**
* @defgroup apr_library Library initialization and termination
* @{
*/
/**
* Setup any APR internal data structures. This MUST be the first function
* called for any APR library.
* @remark See apr_app_initialize if this is an application, rather than
* a library consumer of apr.
*/
APR_DECLARE(apr_status_t) apr_initialize(void);
/**
* Set up an application with normalized argc, argv (and optionally env) in
* order to deal with platform-specific oddities, such as Win32 services,
* code pages and signals. This must be the first function called for any
* APR program.
* @param argc Pointer to the argc that may be corrected
* @param argv Pointer to the argv that may be corrected
* @param env Pointer to the env that may be corrected, may be NULL
* @remark See apr_initialize if this is a library consumer of apr.
* Otherwise, this call is identical to apr_initialize, and must be closed
* with a call to apr_terminate at the end of program execution.
*/
APR_DECLARE(apr_status_t) apr_app_initialize(int *argc,
char const * const * *argv,
char const * const * *env);
/**
* Tear down any APR internal data structures which aren't torn down
* automatically.
* @remark An APR program must call this function at termination once it
* has stopped using APR services. The APR developers suggest using
* atexit to ensure this is called. When using APR from a language
* other than C that has problems with the calling convention, use
* apr_terminate2() instead.
*/
APR_DECLARE_NONSTD(void) apr_terminate(void);
/**
* Tear down any APR internal data structures which aren't torn down
* automatically, same as apr_terminate
* @remark An APR program must call either the apr_terminate or apr_terminate2
* function once it it has finished using APR services. The APR
* developers suggest using atexit(apr_terminate) to ensure this is done.
* apr_terminate2 exists to allow non-c language apps to tear down apr,
* while apr_terminate is recommended from c language applications.
*/
APR_DECLARE(void) apr_terminate2(void);
/** @} */
/**
* @defgroup apr_random Random Functions
* @{
*/
#if APR_HAS_RANDOM || defined(DOXYGEN)
/* TODO: I'm not sure this is the best place to put this prototype...*/
/**
* Generate random bytes.
* @param buf Buffer to fill with random bytes
* @param length Length of buffer in bytes
*/
APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char * buf,
apr_size_t length);
#endif
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ! APR_GENERAL_H */

View File

@@ -0,0 +1,160 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_GETOPT_H
#define APR_GETOPT_H
/**
* @file apr_getopt.h
* @brief APR Command Arguments (getopt)
*/
#include "apr_pools.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_getopt Command Argument Parsing
* @ingroup APR
* @{
*/
/**
* An @c apr_getopt_t error callback function.
*
* @a arg is this @c apr_getopt_t's @c errarg member.
*/
typedef void (apr_getopt_err_fn_t)(void *arg, const char *err, ...);
/** @see apr_getopt_t */
typedef struct apr_getopt_t apr_getopt_t;
/**
* Structure to store command line argument information.
*/
struct apr_getopt_t {
/** context for processing */
apr_pool_t *cont;
/** function to print error message (NULL == no messages) */
apr_getopt_err_fn_t *errfn;
/** user defined first arg to pass to error message */
void *errarg;
/** index into parent argv vector */
int ind;
/** character checked for validity */
int opt;
/** reset getopt */
int reset;
/** count of arguments */
int argc;
/** array of pointers to arguments */
const char **argv;
/** argument associated with option */
char const* place;
/** set to nonzero to support interleaving options with regular args */
int interleave;
/** start of non-option arguments skipped for interleaving */
int skip_start;
/** end of non-option arguments skipped for interleaving */
int skip_end;
};
/** @see apr_getopt_option_t */
typedef struct apr_getopt_option_t apr_getopt_option_t;
/**
* Structure used to describe options that getopt should search for.
*/
struct apr_getopt_option_t {
/** long option name, or NULL if option has no long name */
const char *name;
/** option letter, or a value greater than 255 if option has no letter */
int optch;
/** nonzero if option takes an argument */
int has_arg;
/** a description of the option */
const char *description;
};
/**
* Initialize the arguments for parsing by apr_getopt().
* @param os The options structure created for apr_getopt()
* @param cont The pool to operate on
* @param argc The number of arguments to parse
* @param argv The array of arguments to parse
* @remark Arguments 3 and 4 are most commonly argc and argv from main(argc, argv)
* The (*os)->errfn is initialized to fprintf(stderr... but may be overridden.
*/
APR_DECLARE(apr_status_t) apr_getopt_init(apr_getopt_t **os, apr_pool_t *cont,
int argc, const char * const *argv);
/**
* Parse the options initialized by apr_getopt_init().
* @param os The apr_opt_t structure returned by apr_getopt_init()
* @param opts A string of characters that are acceptable options to the
* program. Characters followed by ":" are required to have an
* option associated
* @param option_ch The next option character parsed
* @param option_arg The argument following the option character:
* @return There are four potential status values on exit. They are:
* <PRE>
* APR_EOF -- No more options to parse
* APR_BADCH -- Found a bad option character
* APR_BADARG -- No argument followed the option flag
* APR_SUCCESS -- The next option was found.
* </PRE>
*/
APR_DECLARE(apr_status_t) apr_getopt(apr_getopt_t *os, const char *opts,
char *option_ch, const char **option_arg);
/**
* Parse the options initialized by apr_getopt_init(), accepting long
* options beginning with "--" in addition to single-character
* options beginning with "-".
* @param os The apr_getopt_t structure created by apr_getopt_init()
* @param opts A pointer to a list of apr_getopt_option_t structures, which
* can be initialized with { "name", optch, has_args }. has_args
* is nonzero if the option requires an argument. A structure
* with an optch value of 0 terminates the list.
* @param option_ch Receives the value of "optch" from the apr_getopt_option_t
* structure corresponding to the next option matched.
* @param option_arg Receives the argument following the option, if any.
* @return There are four potential status values on exit. They are:
* <PRE>
* APR_EOF -- No more options to parse
* APR_BADCH -- Found a bad option character
* APR_BADARG -- No argument followed the option flag
* APR_SUCCESS -- The next option was found.
* </PRE>
* When APR_SUCCESS is returned, os->ind gives the index of the first
* non-option argument. On error, a message will be printed to stdout unless
* os->err is set to 0. If os->interleave is set to nonzero, options can come
* after arguments, and os->argv will be permuted to leave non-option arguments
* at the end (the original argv is unaffected).
*/
APR_DECLARE(apr_status_t) apr_getopt_long(apr_getopt_t *os,
const apr_getopt_option_t *opts,
int *option_ch,
const char **option_arg);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ! APR_GETOPT_H */

View File

@@ -0,0 +1,153 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_GLOBAL_MUTEX_H
#define APR_GLOBAL_MUTEX_H
/**
* @file apr_global_mutex.h
* @brief APR Global Locking Routines
*/
#include "apr.h"
#include "apr_proc_mutex.h" /* only for apr_lockmech_e */
#include "apr_pools.h"
#include "apr_errno.h"
#if APR_PROC_MUTEX_IS_GLOBAL
#include "apr_proc_mutex.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup APR_GlobalMutex Global Locking Routines
* @ingroup APR
* @{
*/
#if !APR_PROC_MUTEX_IS_GLOBAL || defined(DOXYGEN)
/** Opaque global mutex structure. */
typedef struct apr_global_mutex_t apr_global_mutex_t;
/* Function definitions */
/**
* Create and initialize a mutex that can be used to synchronize both
* processes and threads. Note: There is considerable overhead in using
* this API if only cross-process or cross-thread mutual exclusion is
* required. See apr_proc_mutex.h and apr_thread_mutex.h for more
* specialized lock routines.
* @param mutex the memory address where the newly created mutex will be
* stored.
* @param fname A file name to use if the lock mechanism requires one. This
* argument should always be provided. The lock code itself will
* determine if it should be used.
* @param mech The mechanism to use for the interprocess lock, if any; one of
* <PRE>
* APR_LOCK_FCNTL
* APR_LOCK_FLOCK
* APR_LOCK_SYSVSEM
* APR_LOCK_POSIXSEM
* APR_LOCK_PROC_PTHREAD
* APR_LOCK_DEFAULT pick the default mechanism for the platform
* </PRE>
* @param pool the pool from which to allocate the mutex.
* @warning Check APR_HAS_foo_SERIALIZE defines to see if the platform supports
* APR_LOCK_foo. Only APR_LOCK_DEFAULT is portable.
*/
APR_DECLARE(apr_status_t) apr_global_mutex_create(apr_global_mutex_t **mutex,
const char *fname,
apr_lockmech_e mech,
apr_pool_t *pool);
/**
* Re-open a mutex in a child process.
* @param mutex The newly re-opened mutex structure.
* @param fname A file name to use if the mutex mechanism requires one. This
* argument should always be provided. The mutex code itself will
* determine if it should be used. This filename should be the
* same one that was passed to apr_global_mutex_create().
* @param pool The pool to operate on.
* @remark This function must be called to maintain portability, even
* if the underlying lock mechanism does not require it.
*/
APR_DECLARE(apr_status_t) apr_global_mutex_child_init(
apr_global_mutex_t **mutex,
const char *fname,
apr_pool_t *pool);
/**
* Acquire the lock for the given mutex. If the mutex is already locked,
* the current thread will be put to sleep until the lock becomes available.
* @param mutex the mutex on which to acquire the lock.
*/
APR_DECLARE(apr_status_t) apr_global_mutex_lock(apr_global_mutex_t *mutex);
/**
* Attempt to acquire the lock for the given mutex. If the mutex has already
* been acquired, the call returns immediately with APR_EBUSY. Note: it
* is important that the APR_STATUS_IS_EBUSY(s) macro be used to determine
* if the return value was APR_EBUSY, for portability reasons.
* @param mutex the mutex on which to attempt the lock acquiring.
*/
APR_DECLARE(apr_status_t) apr_global_mutex_trylock(apr_global_mutex_t *mutex);
/**
* Release the lock for the given mutex.
* @param mutex the mutex from which to release the lock.
*/
APR_DECLARE(apr_status_t) apr_global_mutex_unlock(apr_global_mutex_t *mutex);
/**
* Destroy the mutex and free the memory associated with the lock.
* @param mutex the mutex to destroy.
*/
APR_DECLARE(apr_status_t) apr_global_mutex_destroy(apr_global_mutex_t *mutex);
/**
* Get the pool used by this global_mutex.
* @return apr_pool_t the pool
*/
APR_POOL_DECLARE_ACCESSOR(global_mutex);
#else /* APR_PROC_MUTEX_IS_GLOBAL */
/* Some platforms [e.g. Win32] have cross process locks that are truly
* global locks, since there isn't the concept of cross-process locks.
* Define these platforms in terms of an apr_proc_mutex_t.
*/
#define apr_global_mutex_t apr_proc_mutex_t
#define apr_global_mutex_create apr_proc_mutex_create
#define apr_global_mutex_child_init apr_proc_mutex_child_init
#define apr_global_mutex_lock apr_proc_mutex_lock
#define apr_global_mutex_trylock apr_proc_mutex_trylock
#define apr_global_mutex_unlock apr_proc_mutex_unlock
#define apr_global_mutex_destroy apr_proc_mutex_destroy
#define apr_global_mutex_pool_get apr_proc_mutex_pool_get
#endif
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ndef APR_GLOBAL_MUTEX_H */

View File

@@ -0,0 +1,257 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_HASH_H
#define APR_HASH_H
/**
* @file apr_hash.h
* @brief APR Hash Tables
*/
#include "apr_pools.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup apr_hash Hash Tables
* @ingroup APR
* @{
*/
/**
* When passing a key to apr_hash_set or apr_hash_get, this value can be
* passed to indicate a string-valued key, and have apr_hash compute the
* length automatically.
*
* @remark apr_hash will use strlen(key) for the length. The NUL terminator
* is not included in the hash value (why throw a constant in?).
* Since the hash table merely references the provided key (rather
* than copying it), apr_hash_this() will return the NUL-term'd key.
*/
#define APR_HASH_KEY_STRING (-1)
/**
* Abstract type for hash tables.
*/
typedef struct apr_hash_t apr_hash_t;
/**
* Abstract type for scanning hash tables.
*/
typedef struct apr_hash_index_t apr_hash_index_t;
/**
* Callback functions for calculating hash values.
* @param key The key.
* @param klen The length of the key, or APR_HASH_KEY_STRING to use the string
* length. If APR_HASH_KEY_STRING then returns the actual key length.
*/
typedef unsigned int (*apr_hashfunc_t)(const char *key, apr_ssize_t *klen);
/**
* The default hash function.
*/
unsigned int apr_hashfunc_default(const char *key, apr_ssize_t *klen);
/**
* Create a hash table.
* @param pool The pool to allocate the hash table out of
* @return The hash table just created
*/
APR_DECLARE(apr_hash_t *) apr_hash_make(apr_pool_t *pool);
/**
* Create a hash table with a custom hash function
* @param pool The pool to allocate the hash table out of
* @param hash_func A custom hash function.
* @return The hash table just created
*/
APR_DECLARE(apr_hash_t *) apr_hash_make_custom(apr_pool_t *pool,
apr_hashfunc_t hash_func);
/**
* Make a copy of a hash table
* @param pool The pool from which to allocate the new hash table
* @param h The hash table to clone
* @return The hash table just created
* @remark Makes a shallow copy
*/
APR_DECLARE(apr_hash_t *) apr_hash_copy(apr_pool_t *pool,
const apr_hash_t *h);
/**
* Associate a value with a key in a hash table.
* @param ht The hash table
* @param key Pointer to the key
* @param klen Length of the key. Can be APR_HASH_KEY_STRING to use the string length.
* @param val Value to associate with the key
* @remark If the value is NULL the hash entry is deleted.
*/
APR_DECLARE(void) apr_hash_set(apr_hash_t *ht, const void *key,
apr_ssize_t klen, const void *val);
/**
* Look up the value associated with a key in a hash table.
* @param ht The hash table
* @param key Pointer to the key
* @param klen Length of the key. Can be APR_HASH_KEY_STRING to use the string length.
* @return Returns NULL if the key is not present.
*/
APR_DECLARE(void *) apr_hash_get(apr_hash_t *ht, const void *key,
apr_ssize_t klen);
/**
* Start iterating over the entries in a hash table.
* @param p The pool to allocate the apr_hash_index_t iterator. If this
* pool is NULL, then an internal, non-thread-safe iterator is used.
* @param ht The hash table
* @remark There is no restriction on adding or deleting hash entries during
* an iteration (although the results may be unpredictable unless all you do
* is delete the current entry) and multiple iterations can be in
* progress at the same time.
*/
/**
* @example
*
* <PRE>
*
* int sum_values(apr_pool_t *p, apr_hash_t *ht)
* {
* apr_hash_index_t *hi;
* void *val;
* int sum = 0;
* for (hi = apr_hash_first(p, ht); hi; hi = apr_hash_next(hi)) {
* apr_hash_this(hi, NULL, NULL, &val);
* sum += *(int *)val;
* }
* return sum;
* }
* </PRE>
*/
APR_DECLARE(apr_hash_index_t *) apr_hash_first(apr_pool_t *p, apr_hash_t *ht);
/**
* Continue iterating over the entries in a hash table.
* @param hi The iteration state
* @return a pointer to the updated iteration state. NULL if there are no more
* entries.
*/
APR_DECLARE(apr_hash_index_t *) apr_hash_next(apr_hash_index_t *hi);
/**
* Get the current entry's details from the iteration state.
* @param hi The iteration state
* @param key Return pointer for the pointer to the key.
* @param klen Return pointer for the key length.
* @param val Return pointer for the associated value.
* @remark The return pointers should point to a variable that will be set to the
* corresponding data, or they may be NULL if the data isn't interesting.
*/
APR_DECLARE(void) apr_hash_this(apr_hash_index_t *hi, const void **key,
apr_ssize_t *klen, void **val);
/**
* Get the number of key/value pairs in the hash table.
* @param ht The hash table
* @return The number of key/value pairs in the hash table.
*/
APR_DECLARE(unsigned int) apr_hash_count(apr_hash_t *ht);
/**
* Clear any key/value pairs in the hash table.
* @param ht The hash table
*/
APR_DECLARE(void) apr_hash_clear(apr_hash_t *ht);
/**
* Merge two hash tables into one new hash table. The values of the overlay
* hash override the values of the base if both have the same key. Both
* hash tables must use the same hash function.
* @param p The pool to use for the new hash table
* @param overlay The table to add to the initial table
* @param base The table that represents the initial values of the new table
* @return A new hash table containing all of the data from the two passed in
*/
APR_DECLARE(apr_hash_t *) apr_hash_overlay(apr_pool_t *p,
const apr_hash_t *overlay,
const apr_hash_t *base);
/**
* Merge two hash tables into one new hash table. If the same key
* is present in both tables, call the supplied merge function to
* produce a merged value for the key in the new table. Both
* hash tables must use the same hash function.
* @param p The pool to use for the new hash table
* @param h1 The first of the tables to merge
* @param h2 The second of the tables to merge
* @param merger A callback function to merge values, or NULL to
* make values from h1 override values from h2 (same semantics as
* apr_hash_overlay())
* @param data Client data to pass to the merger function
* @return A new hash table containing all of the data from the two passed in
*/
APR_DECLARE(apr_hash_t *) apr_hash_merge(apr_pool_t *p,
const apr_hash_t *h1,
const apr_hash_t *h2,
void * (*merger)(apr_pool_t *p,
const void *key,
apr_ssize_t klen,
const void *h1_val,
const void *h2_val,
const void *data),
const void *data);
/**
* Get the current entry's details from the table state.
* @param p The pool to allocate the apr_hash_index_t iterator. If this
* pool is NULL, then an internal, non-thread-safe iterator is used.
* @param classkey Return pointer for the pointer to the key.
* @param classtable Return pointer for the associated value.
* @remark The return pointers should point to a variable that will be set to the
* corresponding data, or they may be NULL if the data isn't interesting.
*/
APR_DECLARE(void*) apr_class_retrieve(apr_hash_t *classtable,
const char *classkey);
/**
* Register myclass into a new hash table. The values of the overlay
* hash override the values of the base if both have the same key..
* @param p The pool to use for the new hash table
* @param classtable The first of the tables to merge
* @param classkey The second of the tables to merge
* @param newclass The table to add to the initial table
* @return A new hash table containing all of the data from the two passed in
*/
APR_DECLARE(void) apr_class_register(apr_hash_t **classtable,
const char *classkey,
void *newclass,
apr_pool_t *p);
/**
* Get a pointer to the pool which the hash table was created in
*/
APR_POOL_DECLARE_ACCESSOR(hash);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !APR_HASH_H */

View File

@@ -0,0 +1,256 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_HOOKS_H
#define APR_HOOKS_H
#include "apu.h"
/* For apr_array_header_t */
#include "apr_tables.h"
/**
* @file apr_hooks.h
* @brief Apache hook functions
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup APR_Util_Hook Hook Functions
* @ingroup APR_Util
* @{
*/
/** macro to return the prototype of the hook function */
#define APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
link##_DECLARE(apr_array_header_t *) ns##_hook_get_##name(void)
/** macro to declare the hook correctly */
#define APR_DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args) \
typedef ret ns##_HOOK_##name##_t args; \
link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf, \
const char * const *aszPre, \
const char * const *aszSucc, int nOrder); \
link##_DECLARE(ret) ns##_run_##name args; \
APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name); \
typedef struct ns##_LINK_##name##_t \
{ \
ns##_HOOK_##name##_t *pFunc; \
const char *szName; \
const char * const *aszPredecessors; \
const char * const *aszSuccessors; \
int nOrder; \
} ns##_LINK_##name##_t;
/** macro to declare the hook structure */
#define APR_HOOK_STRUCT(members) \
static struct { members } _hooks;
/** macro to link the hook structure */
#define APR_HOOK_LINK(name) \
apr_array_header_t *link_##name;
/** macro to implement the hook */
#define APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf,const char * const *aszPre, \
const char * const *aszSucc,int nOrder) \
{ \
ns##_LINK_##name##_t *pHook; \
if(!_hooks.link_##name) \
{ \
_hooks.link_##name=apr_array_make(apr_hook_global_pool,1,sizeof(ns##_LINK_##name##_t)); \
apr_hook_sort_register(#name,&_hooks.link_##name); \
} \
pHook=apr_array_push(_hooks.link_##name); \
pHook->pFunc=pf; \
pHook->aszPredecessors=aszPre; \
pHook->aszSuccessors=aszSucc; \
pHook->nOrder=nOrder; \
pHook->szName=apr_hook_debug_current; \
if(apr_hook_debug_enabled) \
apr_hook_debug_show(#name,aszPre,aszSucc); \
} \
APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
{ \
return _hooks.link_##name; \
}
/**
* Implement a hook that has no return code, and therefore runs all of the
* registered functions
* @param ns The namespace prefix of the hook functions
* @param link The linkage declaration prefix of the hook
* @param name The name of the hook
* @param args_decl The declaration of the arguments for the hook
* @param args_use The names for the arguments for the hook
* @note The link prefix FOO corresponds to FOO_DECLARE() macros, which
* provide export linkage from the module that IMPLEMENTs the hook, and
* import linkage from external modules that link to the hook's module.
*/
#define APR_IMPLEMENT_EXTERNAL_HOOK_VOID(ns,link,name,args_decl,args_use) \
APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
link##_DECLARE(void) ns##_run_##name args_decl \
{ \
ns##_LINK_##name##_t *pHook; \
int n; \
\
if(!_hooks.link_##name) \
return; \
\
pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
pHook[n].pFunc args_use; \
}
/* FIXME: note that this returns ok when nothing is run. I suspect it should
really return decline, but that breaks Apache currently - Ben
*/
/**
* Implement a hook that runs until one of the functions returns something
* other than OK or DECLINE
* @param ns The namespace prefix of the hook functions
* @param link The linkage declaration prefix of the hook
* @param ret Type to return
* @param name The name of the hook
* @param args_decl The declaration of the arguments for the hook
* @param args_use The names for the arguments for the hook
* @param ok Success value
* @param decline Decline value
* @note The link prefix FOO corresponds to FOO_DECLARE() macros, which
* provide export linkage from the module that IMPLEMENTs the hook, and
* import linkage from external modules that link to the hook's module.
*/
#define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ns,link,ret,name,args_decl,args_use,ok,decline) \
APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
link##_DECLARE(ret) ns##_run_##name args_decl \
{ \
ns##_LINK_##name##_t *pHook; \
int n; \
ret rv; \
\
if(!_hooks.link_##name) \
return ok; \
\
pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
{ \
rv=pHook[n].pFunc args_use; \
\
if(rv != ok && rv != decline) \
return rv; \
} \
return ok; \
}
/**
* Implement a hook that runs until the first function returns something
* other than the value of decline
* @param ns The namespace prefix of the hook functions
* @param link The linkage declaration prefix of the hook
* @param name The name of the hook
* @param ret Type to return
* @param args_decl The declaration of the arguments for the hook
* @param args_use The names for the arguments for the hook
* @param decline Decline value
* @note The link prefix FOO corresponds to FOO_DECLARE() macros, which
* provide export linkage from the module that IMPLEMENTs the hook, and
* import linkage from external modules that link to the hook's module.
*/
#define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ns,link,ret,name,args_decl,args_use,decline) \
APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
link##_DECLARE(ret) ns##_run_##name args_decl \
{ \
ns##_LINK_##name##_t *pHook; \
int n; \
ret rv; \
\
if(!_hooks.link_##name) \
return decline; \
\
pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
{ \
rv=pHook[n].pFunc args_use; \
\
if(rv != decline) \
return rv; \
} \
return decline; \
}
/* Hook orderings */
/** run this hook first, before ANYTHING */
#define APR_HOOK_REALLY_FIRST (-10)
/** run this hook first */
#define APR_HOOK_FIRST 0
/** run this hook somewhere */
#define APR_HOOK_MIDDLE 10
/** run this hook after every other hook which is defined*/
#define APR_HOOK_LAST 20
/** run this hook last, after EVERYTHING */
#define APR_HOOK_REALLY_LAST 30
/**
* The global pool used to allocate any memory needed by the hooks.
*/
APU_DECLARE_DATA extern apr_pool_t *apr_hook_global_pool;
/**
* A global variable to determine if debugging information about the
* hooks functions should be printed
*/
APU_DECLARE_DATA extern int apr_hook_debug_enabled;
/**
* The name of the module that is currently registering a function
*/
APU_DECLARE_DATA extern const char *apr_hook_debug_current;
/**
* Register a hook function to be sorted
* @param szHookName The name of the Hook the function is registered for
* @param aHooks The array which stores all of the functions for this hook
*/
APU_DECLARE(void) apr_hook_sort_register(const char *szHookName,
apr_array_header_t **aHooks);
/**
* Sort all of the registerd functions for a given hook
*/
APU_DECLARE(void) apr_hook_sort_all(void);
/**
* Print all of the information about the current hook. This is used for
* debugging purposes.
* @param szName The name of the hook
* @param aszPre All of the functions in the predecessor array
* @param aszSucc All of the functions in the successor array
*/
APU_DECLARE(void) apr_hook_debug_show(const char *szName,
const char * const *aszPre,
const char * const *aszSucc);
/**
* Remove all currently registered functions.
*/
APU_DECLARE(void) apr_hook_deregister_all(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* APR_HOOKS_H */

View File

@@ -0,0 +1,129 @@
/*-
* Copyright (c) 1999,2000
* Konstantin Chuguev. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Konstantin Chuguev
* and its contributors.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifndef APR_ICONV_H
#define APR_ICONV_H
#include "apr.h"
#include "apr_pools.h"
#include <stddef.h>
/**
* API_DECLARE_EXPORT is defined when building the libapriconv dynamic
* library, so that all public symbols are exported.
*
* API_DECLARE_STATIC is defined when including the apriconv public headers,
* to provide static linkage when the dynamic library may be unavailable.
*
* API_DECLARE_STATIC and API_DECLARE_EXPORT are left undefined when
* including the apr-iconv public headers, to import and link the symbols
* from the dynamic libapriconv library and assure appropriate indirection
* and calling conventions at compile time.
*/
#if defined(DOXYGEN) || !defined(WIN32)
/**
* The public apr-iconv functions are declared with API_DECLARE(), so they
* use the most portable calling convention. Public apr-iconv functions
* with variable arguments must use API_DECLARE_NONSTD().
*
* @deffunc API_DECLARE(rettype) apr_func(args);
*/
#define API_DECLARE(type) type
/**
* The private apr-iconv functions are declared with API_DECLARE_NONSTD(),
* so they use the most optimal C language calling conventions.
*
* @deffunc API_DECLARE(rettype) apr_func(args);
*/
#define API_DECLARE_NONSTD(type) type
/**
* All exported apr-iconv variables are declared with API_DECLARE_DATA
* This assures the appropriate indirection is invoked at compile time.
*
* @deffunc API_DECLARE_DATA type apr_variable;
* @tip extern API_DECLARE_DATA type apr_variable; syntax is required for
* declarations within headers to properly import the variable.
*/
#define API_DECLARE_DATA
#elif defined(API_DECLARE_STATIC)
#define API_DECLARE(type) type __stdcall
#define API_DECLARE_NONSTD(type) type __cdecl
#define API_DECLARE_DATA
#elif defined(API_DECLARE_EXPORT)
#define API_DECLARE(type) __declspec(dllexport) type __stdcall
#define API_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl
#define API_DECLARE_DATA __declspec(dllexport)
#else
#define API_DECLARE(type) __declspec(dllimport) type __stdcall
#define API_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl
#define API_DECLARE_DATA __declspec(dllimport)
#endif
/*
* apr_iconv_t: charset conversion descriptor type
*/
typedef void *apr_iconv_t;
/* __BEGIN_DECLS */
/**
* Create a conversion descriptor.
* @param to name of charset to convert to.
* @param from name of charset of the input bytes.
* @param pool pool to alloc memory.
* @param cd conversion descriptor created in pool.
*/
API_DECLARE(apr_status_t) apr_iconv_open(const char *to, const char *from,
apr_pool_t *pool, apr_iconv_t *cd);
/**
* Perform character set conversion.
* @param cd conversion descriptor created by apr_iconv_open().
* @param inbuf input buffer.
* @param inbytesleft bytes to convert.
* @param outbuf output buffer.
* @param outbytesleft space (in bytes) available in outbuf.
* @param translated number of input bytes converted.
*/
API_DECLARE(apr_status_t) apr_iconv(apr_iconv_t cd,
const char **inbuf, apr_size_t *inbytesleft,
char **outbuf, apr_size_t *outbytesleft,
apr_size_t *translated);
/**
* Deallocate descriptor for character set conversion.
* @param cd conversion descriptor.
* @param pool pool used in the apr_iconv_open().
*/
API_DECLARE(apr_status_t) apr_iconv_close(apr_iconv_t cd, apr_pool_t *pool);
/* __END_DECLS */
#endif /* APR_ICONV_H */

View File

@@ -0,0 +1,51 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_INHERIT_H
#define APR_INHERIT_H
/**
* @file apr_inherit.h
* @brief APR File Handle Inheritance Helpers
* @remark This internal header includes internal declaration helpers
* for other headers to declare apr_foo_inherit_[un]set functions.
*/
/**
* Prototype for type-specific declarations of apr_foo_inherit_set
* functions.
* @remark Doxygen unwraps this macro (via doxygen.conf) to provide
* actual help for each specific occurance of apr_foo_inherit_set.
* @remark the linkage is specified for APR. It would be possible to expand
* the macros to support other linkages.
*/
#define APR_DECLARE_INHERIT_SET(type) \
APR_DECLARE(apr_status_t) apr_##type##_inherit_set( \
apr_##type##_t *the##type)
/**
* Prototype for type-specific declarations of apr_foo_inherit_unset
* functions.
* @remark Doxygen unwraps this macro (via doxygen.conf) to provide
* actual help for each specific occurance of apr_foo_inherit_unset.
* @remark the linkage is specified for APR. It would be possible to expand
* the macros to support other linkages.
*/
#define APR_DECLARE_INHERIT_UNSET(type) \
APR_DECLARE(apr_status_t) apr_##type##_inherit_unset( \
apr_##type##_t *the##type)
#endif /* ! APR_INHERIT_H */

View File

@@ -0,0 +1,193 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* apr_ldap.h is generated from apr_ldap.h.in by configure -- do not edit apr_ldap.h
*/
/**
* @file apr_ldap.h
* @brief APR-UTIL LDAP
*/
#ifndef APU_LDAP_H
#define APU_LDAP_H
/**
* @defgroup APR_Util_LDAP LDAP
* @ingroup APR_Util
* @{
*/
/* this will be defined if LDAP support was compiled into apr-util */
#define APR_HAS_LDAP 0
/* identify the LDAP toolkit used */
#define APR_HAS_NETSCAPE_LDAPSDK 0
#define APR_HAS_SOLARIS_LDAPSDK 0
#define APR_HAS_NOVELL_LDAPSDK 0
#define APR_HAS_MOZILLA_LDAPSDK 0
#define APR_HAS_OPENLDAP_LDAPSDK 0
#define APR_HAS_MICROSOFT_LDAPSDK 0
#define APR_HAS_TIVOLI_LDAPSDK 0
#define APR_HAS_ZOS_LDAPSDK 0
#define APR_HAS_OTHER_LDAPSDK 0
/*
* Handle the case when LDAP is enabled
*/
#if APR_HAS_LDAP
/*
* The following #defines are DEPRECATED and should not be used for
* anything. They remain to maintain binary compatibility.
* The original code defined the OPENLDAP SDK as present regardless
* of what really was there, which was way bogus. In addition, the
* apr_ldap_url_parse*() functions have been rewritten specifically for
* APR, so the APR_HAS_LDAP_URL_PARSE macro is forced to zero.
*/
#if APR_HAS_TIVOLI_LDAPSDK
#define APR_HAS_LDAP_SSL 0
#else
#define APR_HAS_LDAP_SSL 1
#endif
#define APR_HAS_LDAP_URL_PARSE 0
#if APR_HAS_OPENLDAP_LDAPSDK && !defined(LDAP_DEPRECATED)
/* Ensure that the "deprecated" interfaces are still exposed
* with OpenLDAP >= 2.3; these were exposed by default in earlier
* releases. */
#define LDAP_DEPRECATED 1
#endif
/*
* Include the standard LDAP header files.
*/
/*
* Detected standard functions
*/
#define APR_HAS_LDAPSSL_CLIENT_INIT 0
#define APR_HAS_LDAPSSL_CLIENT_DEINIT 0
#define APR_HAS_LDAPSSL_ADD_TRUSTED_CERT 0
#define APR_HAS_LDAP_START_TLS_S 0
#define APR_HAS_LDAP_SSLINIT 0
#define APR_HAS_LDAPSSL_INIT 0
#define APR_HAS_LDAPSSL_INSTALL_ROUTINES 0
/*
* Make sure the secure LDAP port is defined
*/
#ifndef LDAPS_PORT
#define LDAPS_PORT 636 /* ldaps:/// default LDAP over TLS port */
#endif
/*
* For ldap function calls that input a size limit on the number of returned elements
* Some SDKs do not have the define for LDAP_DEFAULT_LIMIT (-1) or LDAP_NO_LIMIT (0)
*/
#if APR_HAS_ZOS_LDAPSDK || APR_HAS_MICROSOFT_LDAPSDK
#define APR_LDAP_SIZELIMIT LDAP_NO_LIMIT
#else
#ifdef LDAP_DEFAULT_LIMIT
#define APR_LDAP_SIZELIMIT LDAP_DEFAULT_LIMIT
#else
#define APR_LDAP_SIZELIMIT -1 /* equivalent to LDAP_DEFAULT_LIMIT */
#endif
#endif
/*
* z/OS is missing some defines
*/
#ifndef LDAP_VERSION_MAX
#define LDAP_VERSION_MAX LDAP_VERSION
#endif
#if APR_HAS_ZOS_LDAPSDK
#define LDAP_VENDOR_NAME "IBM z/OS"
#endif
/* Note: Macros defining const casting has been removed in APR v1.0,
* pending real support for LDAP v2.0 toolkits.
*
* In the mean time, please use an LDAP v3.0 toolkit.
*/
#if LDAP_VERSION_MAX <= 2
#error Support for LDAP v2.0 toolkits has been removed from apr-util. Please use an LDAP v3.0 toolkit.
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* This structure allows the C LDAP API error codes to be returned
* along with plain text error messages that explain to us mere mortals
* what really happened.
*/
typedef struct apr_ldap_err_t {
const char *reason;
const char *msg;
int rc;
} apr_ldap_err_t;
#ifdef __cplusplus
}
#endif
/* The MS SDK returns LDAP_UNAVAILABLE when the backend has closed the connection
* between LDAP calls. Protect with APR_HAS_MICROSOFT_LDAPSDK in case someone
* manually chooses another SDK on Windows
*/
#if APR_HAS_MICROSOFT_LDAPSDK
#define APR_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN \
|| (s) == LDAP_UNAVAILABLE)
#else
#define APR_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN)
#endif
/* These symbols are not actually exported in a DSO build, but mapped into
* a private exported function array for apr_ldap_stub to bind dynamically.
* Rename them appropriately to protect the global namespace.
*/
#ifdef APU_DSO_LDAP_BUILD
#define apr_ldap_info apr__ldap_info
#define apr_ldap_init apr__ldap_init
#define apr_ldap_ssl_init apr__ldap_ssl_init
#define apr_ldap_ssl_deinit apr__ldap_ssl_deinit
#define apr_ldap_get_option apr__ldap_get_option
#define apr_ldap_set_option apr__ldap_set_option
#define apr_ldap_rebind_init apr__ldap_rebind_init
#define apr_ldap_rebind_add apr__ldap_rebind_add
#define apr_ldap_rebind_remove apr__ldap_rebind_remove
#define APU_DECLARE_LDAP(type) type
#else
#define APU_DECLARE_LDAP(type) APU_DECLARE(type)
#endif
#include "apr_ldap_url.h"
#include "apr_ldap_init.h"
#include "apr_ldap_option.h"
#include "apr_ldap_rebind.h"
/** @} */
#endif /* APR_HAS_LDAP */
#endif /* APU_LDAP_H */

View File

@@ -0,0 +1,166 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file apr_ldap_init.h
* @brief APR-UTIL LDAP ldap_init() functions
*/
#ifndef APR_LDAP_INIT_H
#define APR_LDAP_INIT_H
/**
* @defgroup APR_Util_LDAP LDAP
* @ingroup APR_Util
* @{
*/
#include "apr_ldap.h"
#if APR_HAS_LDAP
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Macro to detect security related return values.
*/
#if defined(LDAP_INSUFFICIENT_ACCESS)
#define APU_LDAP_INSUFFICIENT_ACCESS LDAP_INSUFFICIENT_ACCESS
#elif defined(LDAP_INSUFFICIENT_RIGHTS)
#define APU_LDAP_INSUFFICIENT_ACCESS LDAP_INSUFFICIENT_RIGHTS
#elif defined(APR_HAS_MICROSOFT_LDAPSDK)
/* The macros above fail to contemplate that LDAP_RETCODE values
* may be represented by an enum. autoconf tests would be much
* more robust.
*/
#define APU_LDAP_INSUFFICIENT_ACCESS LDAP_INSUFFICIENT_RIGHTS
#else
#error The security return codes must be added to support this LDAP toolkit.
#endif
#if defined(LDAP_SECURITY_ERROR)
#define APU_LDAP_SECURITY_ERROR LDAP_SECURITY_ERROR
#else
#define APU_LDAP_SECURITY_ERROR(n) \
(LDAP_INAPPROPRIATE_AUTH == n) ? 1 \
: (LDAP_INVALID_CREDENTIALS == n) ? 1 \
: (APU_LDAP_INSUFFICIENT_ACCESS == n) ? 1 \
: 0
#endif
/**
* APR LDAP SSL Initialise function
*
* This function initialises SSL on the underlying LDAP toolkit
* if this is necessary.
*
* If a CA certificate is provided, this is set, however the setting
* of certificates via this method has been deprecated and will be removed in
* APR v2.0.
*
* The apr_ldap_set_option() function with the APR_LDAP_OPT_TLS_CERT option
* should be used instead to set certificates.
*
* If SSL support is not available on this platform, or a problem
* was encountered while trying to set the certificate, the function
* will return APR_EGENERAL. Further LDAP specific error information
* can be found in result_err.
* @param pool The pool to use
* @param cert_auth_file The name of the certificate to use, can be NULL
* @param cert_file_type The type of certificate specified. See the
* apr_ldap_set_option() APR_LDAP_OPT_TLS_CERT option for details.
* @param result_err The returned result
*/
APU_DECLARE_LDAP(int) apr_ldap_ssl_init(apr_pool_t *pool,
const char *cert_auth_file,
int cert_file_type,
apr_ldap_err_t **result_err);
/**
* APR LDAP SSL De-Initialise function
*
* This function tears down any SSL certificate setup previously
* set using apr_ldap_ssl_init(). It should be called to clean
* up if a graceful restart of a service is attempted.
* @todo currently we do not check whether apr_ldap_ssl_init()
* has been called first - we probably should.
*/
APU_DECLARE_LDAP(int) apr_ldap_ssl_deinit(void);
/**
* APR LDAP initialise function
*
* This function is responsible for initialising an LDAP
* connection in a toolkit independant way. It does the
* job of ldap_init() from the C api.
*
* It handles both the SSL and non-SSL case, and attempts
* to hide the complexity setup from the user. This function
* assumes that any certificate setup necessary has already
* been done.
*
* If SSL or STARTTLS needs to be enabled, and the underlying
* toolkit supports it, the following values are accepted for
* secure:
*
* APR_LDAP_NONE: No encryption
* APR_LDAP_SSL: SSL encryption (ldaps://)
* APR_LDAP_STARTTLS: Force STARTTLS on ldap://
* @remark The Novell toolkit is only able to set the SSL mode via this
* function. To work around this limitation, set the SSL mode here if no
* per connection client certificates are present, otherwise set secure
* APR_LDAP_NONE here, then set the per connection client certificates,
* followed by setting the SSL mode via apr_ldap_set_option(). As Novell
* does not support per connection client certificates, this problem is
* worked around while still being compatible with other LDAP toolkits.
* @param pool The pool to use
* @param ldap The LDAP handle
* @param hostname The name of the host to connect to. This can be either a
* DNS name, or an IP address.
* @param portno The port to connect to
* @param secure The security mode to set
* @param result_err The returned result
*/
APU_DECLARE_LDAP(int) apr_ldap_init(apr_pool_t *pool,
LDAP **ldap,
const char *hostname,
int portno,
int secure,
apr_ldap_err_t **result_err);
/**
* APR LDAP info function
*
* This function returns a string describing the LDAP toolkit
* currently in use. The string is placed inside result_err->reason.
* @param pool The pool to use
* @param result_err The returned result
*/
APU_DECLARE_LDAP(int) apr_ldap_info(apr_pool_t *pool,
apr_ldap_err_t **result_err);
#ifdef __cplusplus
}
#endif
#endif /* APR_HAS_LDAP */
/** @} */
#endif /* APR_LDAP_URL_H */

View File

@@ -0,0 +1,255 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file apr_ldap_option.h
* @brief APR-UTIL LDAP ldap_*_option() functions
*/
#ifndef APR_LDAP_OPTION_H
#define APR_LDAP_OPTION_H
/**
* @defgroup APR_Util_LDAP LDAP
* @ingroup APR_Util
* @{
*/
#include "apr_ldap.h"
#if APR_HAS_LDAP
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
* The following defines handle the different TLS certificate
* options available. If these options are missing, APR will try and
* emulate support for this using the deprecated ldap_start_tls_s()
* function.
*/
/**
* Set SSL mode to one of APR_LDAP_NONE, APR_LDAP_SSL, APR_LDAP_STARTTLS
* or APR_LDAP_STOPTLS.
*/
#define APR_LDAP_OPT_TLS 0x6fff
/**
* Set zero or more CA certificates, client certificates or private
* keys globally, or per connection (where supported).
*/
#define APR_LDAP_OPT_TLS_CERT 0x6ffe
/**
* Set the LDAP library to no verify the server certificate. This means
* all servers are considered trusted.
*/
#define APR_LDAP_OPT_VERIFY_CERT 0x6ffd
/**
* Set the LDAP library to indicate if referrals should be chased during
* LDAP searches.
*/
#define APR_LDAP_OPT_REFERRALS 0x6ffc
/**
* Set the LDAP library to indicate a maximum number of referral hops to
* chase before giving up on the search.
*/
#define APR_LDAP_OPT_REFHOPLIMIT 0x6ffb
/**
* Structures for the apr_set_option() cases
*/
/**
* APR_LDAP_OPT_TLS_CERT
*
* This structure includes possible options to set certificates on
* system initialisation. Different SDKs have different certificate
* requirements, and to achieve this multiple certificates must be
* specified at once passed as an (apr_array_header_t *).
*
* Netscape:
* Needs the CA cert database (cert7.db), the client cert database (key3.db)
* and the security module file (secmod.db) set at the system initialisation
* time. Three types are supported: APR_LDAP_CERT7_DB, APR_LDAP_KEY3_DB and
* APR_LDAP_SECMOD.
*
* To specify a client cert connection, a certificate nickname needs to be
* provided with a type of APR_LDAP_CERT.
* int ldapssl_enable_clientauth( LDAP *ld, char *keynickname,
* char *keypasswd, char *certnickname );
* keynickname is currently not used, and should be set to ""
*
* Novell:
* Needs CA certificates and client certificates set at system initialisation
* time. Three types are supported: APR_LDAP_CA*, APR_LDAP_CERT* and
* APR_LDAP_KEY*.
*
* Certificates cannot be specified per connection.
*
* The functions used are:
* ldapssl_add_trusted_cert(serverTrustedRoot, serverTrustedRootEncoding);
* Clients certs and keys are set at system initialisation time with
* int ldapssl_set_client_cert (
* void *cert,
* int type
* void *password);
* type can be LDAPSSL_CERT_FILETYPE_B64 or LDAPSSL_CERT_FILETYPE_DER
* ldapssl_set_client_private_key(clientPrivateKey,
* clientPrivateKeyEncoding,
* clientPrivateKeyPassword);
*
* OpenSSL:
* Needs one or more CA certificates to be set at system initialisation time
* with a type of APR_LDAP_CA*.
*
* May have one or more client certificates set per connection with a type of
* APR_LDAP_CERT*, and keys with APR_LDAP_KEY*.
*/
/** CA certificate type unknown */
#define APR_LDAP_CA_TYPE_UNKNOWN 0
/** binary DER encoded CA certificate */
#define APR_LDAP_CA_TYPE_DER 1
/** PEM encoded CA certificate */
#define APR_LDAP_CA_TYPE_BASE64 2
/** Netscape/Mozilla cert7.db CA certificate database */
#define APR_LDAP_CA_TYPE_CERT7_DB 3
/** Netscape/Mozilla secmod file */
#define APR_LDAP_CA_TYPE_SECMOD 4
/** Client certificate type unknown */
#define APR_LDAP_CERT_TYPE_UNKNOWN 5
/** binary DER encoded client certificate */
#define APR_LDAP_CERT_TYPE_DER 6
/** PEM encoded client certificate */
#define APR_LDAP_CERT_TYPE_BASE64 7
/** Netscape/Mozilla key3.db client certificate database */
#define APR_LDAP_CERT_TYPE_KEY3_DB 8
/** Netscape/Mozilla client certificate nickname */
#define APR_LDAP_CERT_TYPE_NICKNAME 9
/** Private key type unknown */
#define APR_LDAP_KEY_TYPE_UNKNOWN 10
/** binary DER encoded private key */
#define APR_LDAP_KEY_TYPE_DER 11
/** PEM encoded private key */
#define APR_LDAP_KEY_TYPE_BASE64 12
/** PKCS#12 encoded client certificate */
#define APR_LDAP_CERT_TYPE_PFX 13
/** PKCS#12 encoded private key */
#define APR_LDAP_KEY_TYPE_PFX 14
/** Openldap directory full of base64-encoded cert
* authorities with hashes in corresponding .0 directory
*/
#define APR_LDAP_CA_TYPE_CACERTDIR_BASE64 15
/**
* Certificate structure.
*
* This structure is used to store certificate details. An array of
* these structures is passed to apr_ldap_set_option() to set CA
* and client certificates.
* @param type Type of certificate APR_LDAP_*_TYPE_*
* @param path Path, file or nickname of the certificate
* @param password Optional password, can be NULL
*/
typedef struct apr_ldap_opt_tls_cert_t apr_ldap_opt_tls_cert_t;
struct apr_ldap_opt_tls_cert_t {
int type;
const char *path;
const char *password;
};
/**
* APR_LDAP_OPT_TLS
*
* This sets the SSL level on the LDAP handle.
*
* Netscape/Mozilla:
* Supports SSL, but not STARTTLS
* SSL is enabled by calling ldapssl_install_routines().
*
* Novell:
* Supports SSL and STARTTLS.
* SSL is enabled by calling ldapssl_install_routines(). Note that calling
* other ldap functions before ldapssl_install_routines() may cause this
* function to fail.
* STARTTLS is enabled by calling ldapssl_start_tls_s() after calling
* ldapssl_install_routines() (check this).
*
* OpenLDAP:
* Supports SSL and supports STARTTLS, but none of this is documented:
* http://www.openldap.org/lists/openldap-software/200409/msg00618.html
* Documentation for both SSL support and STARTTLS has been deleted from
* the OpenLDAP documentation and website.
*/
/** No encryption */
#define APR_LDAP_NONE 0
/** SSL encryption (ldaps://) */
#define APR_LDAP_SSL 1
/** TLS encryption (STARTTLS) */
#define APR_LDAP_STARTTLS 2
/** end TLS encryption (STOPTLS) */
#define APR_LDAP_STOPTLS 3
/**
* APR LDAP get option function
*
* This function gets option values from a given LDAP session if
* one was specified. It maps to the native ldap_get_option() function.
* @param pool The pool to use
* @param ldap The LDAP handle
* @param option The LDAP_OPT_* option to return
* @param outvalue The value returned (if any)
* @param result_err The apr_ldap_err_t structure contained detailed results
* of the operation.
*/
APU_DECLARE_LDAP(int) apr_ldap_get_option(apr_pool_t *pool,
LDAP *ldap,
int option,
void *outvalue,
apr_ldap_err_t **result_err);
/**
* APR LDAP set option function
*
* This function sets option values to a given LDAP session if
* one was specified. It maps to the native ldap_set_option() function.
*
* Where an option is not supported by an LDAP toolkit, this function
* will try and apply legacy functions to achieve the same effect,
* depending on the platform.
* @param pool The pool to use
* @param ldap The LDAP handle
* @param option The LDAP_OPT_* option to set
* @param invalue The value to set
* @param result_err The apr_ldap_err_t structure contained detailed results
* of the operation.
*/
APU_DECLARE_LDAP(int) apr_ldap_set_option(apr_pool_t *pool,
LDAP *ldap,
int option,
const void *invalue,
apr_ldap_err_t **result_err);
#ifdef __cplusplus
}
#endif
#endif /* APR_HAS_LDAP */
/** @} */
#endif /* APR_LDAP_OPTION_H */

View File

@@ -0,0 +1,87 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* The APR LDAP rebind functions provide an implementation of
* a rebind procedure that can be used to allow clients to chase referrals,
* using the same credentials used to log in originally.
*
* Use of this implementation is optional.
*
* @file apu_ldap_rebind.h
* @brief Apache LDAP library
*/
#ifndef APU_LDAP_REBIND_H
#define APU_LDAP_REBIND_H
/*
* Handle the case when LDAP is enabled
*/
#if APR_HAS_LDAP
/**
* APR LDAP initialize rebind lock
*
* This function creates the lock for controlling access to the xref list..
* @param pool Pool to use when creating the xref_lock.
*/
APU_DECLARE_LDAP(apr_status_t) apr_ldap_rebind_init(apr_pool_t *pool);
/**
* APR LDAP rebind_add function
*
* This function creates a cross reference entry for the specified ldap
* connection. The rebind callback function will look up this ldap
* connection so it can retrieve the bindDN and bindPW for use in any
* binds while referrals are being chased.
*
* This function will add the callback to the LDAP handle passed in.
*
* A cleanup is registered within the pool provided to remove this
* entry when the pool is removed. Alternatively apr_ldap_rebind_remove()
* can be called to explicitly remove the entry at will.
*
* @param pool The pool to use
* @param ld The LDAP connectionhandle
* @param bindDN The bind DN to be used for any binds while chasing
* referrals on this ldap connection.
* @param bindPW The bind Password to be used for any binds while
* chasing referrals on this ldap connection.
*/
APU_DECLARE_LDAP(apr_status_t) apr_ldap_rebind_add(apr_pool_t *pool,
LDAP *ld,
const char *bindDN,
const char *bindPW);
/**
* APR LDAP rebind_remove function
*
* This function removes the rebind cross reference entry for the
* specified ldap connection.
*
* If not explicitly removed, this function will be called automatically
* when the pool is cleaned up.
*
* @param ld The LDAP connectionhandle
*/
APU_DECLARE_LDAP(apr_status_t) apr_ldap_rebind_remove(LDAP *ld);
#endif /* APR_HAS_LDAP */
#endif /* APU_LDAP_REBIND_H */

View File

@@ -0,0 +1,117 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file apr_ldap_url.h
* @brief APR-UTIL LDAP ldap_init() functions
*/
#ifndef APR_LDAP_URL_H
#define APR_LDAP_URL_H
/**
* @defgroup APR_Util_LDAP LDAP
* @ingroup APR_Util
* @{
*/
#if APR_HAS_LDAP
#include "apu.h"
#include "apr_pools.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** Structure to access an exploded LDAP URL */
typedef struct apr_ldap_url_desc_t {
struct apr_ldap_url_desc_t *lud_next;
char *lud_scheme;
char *lud_host;
int lud_port;
char *lud_dn;
char **lud_attrs;
int lud_scope;
char *lud_filter;
char **lud_exts;
int lud_crit_exts;
} apr_ldap_url_desc_t;
#ifndef APR_LDAP_URL_SUCCESS
#define APR_LDAP_URL_SUCCESS 0x00 /* Success */
#define APR_LDAP_URL_ERR_MEM 0x01 /* can't allocate memory space */
#define APR_LDAP_URL_ERR_PARAM 0x02 /* parameter is bad */
#define APR_LDAP_URL_ERR_BADSCHEME 0x03 /* URL doesn't begin with "ldap[si]://" */
#define APR_LDAP_URL_ERR_BADENCLOSURE 0x04 /* URL is missing trailing ">" */
#define APR_LDAP_URL_ERR_BADURL 0x05 /* URL is bad */
#define APR_LDAP_URL_ERR_BADHOST 0x06 /* host port is bad */
#define APR_LDAP_URL_ERR_BADATTRS 0x07 /* bad (or missing) attributes */
#define APR_LDAP_URL_ERR_BADSCOPE 0x08 /* scope string is invalid (or missing) */
#define APR_LDAP_URL_ERR_BADFILTER 0x09 /* bad or missing filter */
#define APR_LDAP_URL_ERR_BADEXTS 0x0a /* bad or missing extensions */
#endif
/**
* Is this URL an ldap url? ldap://
* @param url The url to test
*/
APU_DECLARE(int) apr_ldap_is_ldap_url(const char *url);
/**
* Is this URL an SSL ldap url? ldaps://
* @param url The url to test
*/
APU_DECLARE(int) apr_ldap_is_ldaps_url(const char *url);
/**
* Is this URL an ldap socket url? ldapi://
* @param url The url to test
*/
APU_DECLARE(int) apr_ldap_is_ldapi_url(const char *url);
/**
* Parse an LDAP URL.
* @param pool The pool to use
* @param url_in The URL to parse
* @param ludpp The structure to return the exploded URL
* @param result_err The result structure of the operation
*/
APU_DECLARE(int) apr_ldap_url_parse_ext(apr_pool_t *pool,
const char *url_in,
apr_ldap_url_desc_t **ludpp,
apr_ldap_err_t **result_err);
/**
* Parse an LDAP URL.
* @param pool The pool to use
* @param url_in The URL to parse
* @param ludpp The structure to return the exploded URL
* @param result_err The result structure of the operation
*/
APU_DECLARE(int) apr_ldap_url_parse(apr_pool_t *pool,
const char *url_in,
apr_ldap_url_desc_t **ludpp,
apr_ldap_err_t **result_err);
#ifdef __cplusplus
}
#endif
#endif /* APR_HAS_LDAP */
/** @} */
#endif /* APR_LDAP_URL_H */

240
include/apr-linux/apr_lib.h Normal file
View File

@@ -0,0 +1,240 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_LIB_H
#define APR_LIB_H
/**
* @file apr_lib.h
* This is collection of oddballs that didn't fit anywhere else,
* and might move to more appropriate headers with the release
* of APR 1.0.
* @brief APR general purpose library routines
*/
#include "apr.h"
#include "apr_errno.h"
#if APR_HAVE_CTYPE_H
#include <ctype.h>
#endif
#if APR_HAVE_STDARG_H
#include <stdarg.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_lib General Purpose Library Routines
* @ingroup APR
* This is collection of oddballs that didn't fit anywhere else,
* and might move to more appropriate headers with the release
* of APR 1.0.
* @{
*/
/** A constant representing a 'large' string. */
#define HUGE_STRING_LEN 8192
/*
* Define the structures used by the APR general-purpose library.
*/
/** @see apr_vformatter_buff_t */
typedef struct apr_vformatter_buff_t apr_vformatter_buff_t;
/**
* Structure used by the variable-formatter routines.
*/
struct apr_vformatter_buff_t {
/** The current position */
char *curpos;
/** The end position of the format string */
char *endpos;
};
/**
* return the final element of the pathname
* @param pathname The path to get the final element of
* @return the final element of the path
* @remark
* <PRE>
* For example:
* "/foo/bar/gum" -> "gum"
* "/foo/bar/gum/" -> ""
* "gum" -> "gum"
* "bs\\path\\stuff" -> "stuff"
* </PRE>
*/
APR_DECLARE(const char *) apr_filepath_name_get(const char *pathname);
/**
* apr_killpg
* Small utility macros to make things easier to read. Not usually a
* goal, to be sure..
*/
#ifdef WIN32
#define apr_killpg(x, y)
#else /* WIN32 */
#ifdef NO_KILLPG
#define apr_killpg(x, y) (kill (-(x), (y)))
#else /* NO_KILLPG */
#define apr_killpg(x, y) (killpg ((x), (y)))
#endif /* NO_KILLPG */
#endif /* WIN32 */
/**
* apr_vformatter() is a generic printf-style formatting routine
* with some extensions.
* @param flush_func The function to call when the buffer is full
* @param c The buffer to write to
* @param fmt The format string
* @param ap The arguments to use to fill out the format string.
*
* @remark
* <PRE>
* The extensions are:
*
* %%pA takes a struct in_addr *, and prints it as a.b.c.d
* %%pI takes an apr_sockaddr_t * and prints it as a.b.c.d:port or
* [ipv6-address]:port
* %%pT takes an apr_os_thread_t * and prints it in decimal
* ('0' is printed if !APR_HAS_THREADS)
* %%pt takes an apr_os_thread_t * and prints it in hexadecimal
* ('0' is printed if !APR_HAS_THREADS)
* %%pm takes an apr_status_t * and prints the appropriate error
* string (from apr_strerror) corresponding to that error code.
* %%pp takes a void * and outputs it in hex
* %%pB takes a apr_uint32_t * as bytes and outputs it's apr_strfsize
* %%pF same as above, but takes a apr_off_t *
* %%pS same as above, but takes a apr_size_t *
*
* %%pt is only available from APR 1.2.0 onwards.
* %%pm, %%pB, %%pF and %%pS are only available from APR 1.3.0 onwards.
*
* The %%p hacks are to force gcc's printf warning code to skip
* over a pointer argument without complaining. This does
* mean that the ANSI-style %%p (output a void * in hex format) won't
* work as expected at all, but that seems to be a fair trade-off
* for the increased robustness of having printf-warnings work.
*
* Additionally, apr_vformatter allows for arbitrary output methods
* using the apr_vformatter_buff and flush_func.
*
* The apr_vformatter_buff has two elements curpos and endpos.
* curpos is where apr_vformatter will write the next byte of output.
* It proceeds writing output to curpos, and updating curpos, until
* either the end of output is reached, or curpos == endpos (i.e. the
* buffer is full).
*
* If the end of output is reached, apr_vformatter returns the
* number of bytes written.
*
* When the buffer is full, the flush_func is called. The flush_func
* can return -1 to indicate that no further output should be attempted,
* and apr_vformatter will return immediately with -1. Otherwise
* the flush_func should flush the buffer in whatever manner is
* appropriate, re apr_pool_t nitialize curpos and endpos, and return 0.
*
* Note that flush_func is only invoked as a result of attempting to
* write another byte at curpos when curpos >= endpos. So for
* example, it's possible when the output exactly matches the buffer
* space available that curpos == endpos will be true when
* apr_vformatter returns.
*
* apr_vformatter does not call out to any other code, it is entirely
* self-contained. This allows the callers to do things which are
* otherwise "unsafe". For example, apr_psprintf uses the "scratch"
* space at the unallocated end of a block, and doesn't actually
* complete the allocation until apr_vformatter returns. apr_psprintf
* would be completely broken if apr_vformatter were to call anything
* that used this same pool. Similarly http_bprintf() uses the "scratch"
* space at the end of its output buffer, and doesn't actually note
* that the space is in use until it either has to flush the buffer
* or until apr_vformatter returns.
* </PRE>
*/
APR_DECLARE(int) apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *b),
apr_vformatter_buff_t *c, const char *fmt,
va_list ap);
/**
* Display a prompt and read in the password from stdin.
* @param prompt The prompt to display
* @param pwbuf Buffer to store the password
* @param bufsize The length of the password buffer.
* @remark If the password entered must be truncated to fit in
* the provided buffer, APR_ENAMETOOLONG will be returned.
* Note that the bufsize paramater is passed by reference for no
* reason; its value will never be modified by the apr_password_get()
* function.
*/
APR_DECLARE(apr_status_t) apr_password_get(const char *prompt, char *pwbuf,
apr_size_t *bufsize);
/** @} */
/**
* @defgroup apr_ctype ctype functions
* These macros allow correct support of 8-bit characters on systems which
* support 8-bit characters. Pretty dumb how the cast is required, but
* that's legacy libc for ya. These new macros do not support EOF like
* the standard macros do. Tough.
* @{
*/
/** @see isalnum */
#define apr_isalnum(c) (isalnum(((unsigned char)(c))))
/** @see isalpha */
#define apr_isalpha(c) (isalpha(((unsigned char)(c))))
/** @see iscntrl */
#define apr_iscntrl(c) (iscntrl(((unsigned char)(c))))
/** @see isdigit */
#define apr_isdigit(c) (isdigit(((unsigned char)(c))))
/** @see isgraph */
#define apr_isgraph(c) (isgraph(((unsigned char)(c))))
/** @see islower*/
#define apr_islower(c) (islower(((unsigned char)(c))))
/** @see isascii */
#ifdef isascii
#define apr_isascii(c) (isascii(((unsigned char)(c))))
#else
#define apr_isascii(c) (((c) & ~0x7f)==0)
#endif
/** @see isprint */
#define apr_isprint(c) (isprint(((unsigned char)(c))))
/** @see ispunct */
#define apr_ispunct(c) (ispunct(((unsigned char)(c))))
/** @see isspace */
#define apr_isspace(c) (isspace(((unsigned char)(c))))
/** @see isupper */
#define apr_isupper(c) (isupper(((unsigned char)(c))))
/** @see isxdigit */
#define apr_isxdigit(c) (isxdigit(((unsigned char)(c))))
/** @see tolower */
#define apr_tolower(c) (tolower(((unsigned char)(c))))
/** @see toupper */
#define apr_toupper(c) (toupper(((unsigned char)(c))))
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ! APR_LIB_H */

135
include/apr-linux/apr_md4.h Normal file
View File

@@ -0,0 +1,135 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* This is derived from material copyright RSA Data Security, Inc.
* Their notice is reproduced below in its entirety.
*
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
* rights reserved.
*
* License to copy and use this software is granted provided that it
* is identified as the "RSA Data Security, Inc. MD4 Message-Digest
* Algorithm" in all material mentioning or referencing this software
* or this function.
*
* License is also granted to make and use derivative works provided
* that such works are identified as "derived from the RSA Data
* Security, Inc. MD4 Message-Digest Algorithm" in all material
* mentioning or referencing the derived work.
*
* RSA Data Security, Inc. makes no representations concerning either
* the merchantability of this software or the suitability of this
* software for any particular purpose. It is provided "as is"
* without express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this
* documentation and/or software.
*/
#ifndef APR_MD4_H
#define APR_MD4_H
#include "apu.h"
#include "apr_xlate.h"
/**
* @file apr_md4.h
* @brief APR-UTIL MD4 Library
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup APR_Util_MD4 MD4 Library
* @ingroup APR_Util
* @{
*/
/** The digestsize for MD4 */
#define APR_MD4_DIGESTSIZE 16
/** @see apr_md4_ctx_t */
typedef struct apr_md4_ctx_t apr_md4_ctx_t;
/** MD4 context. */
struct apr_md4_ctx_t {
/** state (ABCD) */
apr_uint32_t state[4];
/** number of bits, modulo 2^64 (lsb first) */
apr_uint32_t count[2];
/** input buffer */
unsigned char buffer[64];
#if APR_HAS_XLATE
/** translation handle */
apr_xlate_t *xlate;
#endif
};
/**
* MD4 Initialize. Begins an MD4 operation, writing a new context.
* @param context The MD4 context to initialize.
*/
APU_DECLARE(apr_status_t) apr_md4_init(apr_md4_ctx_t *context);
#if APR_HAS_XLATE
/**
* MDr4 translation setup. Provides the APR translation handle to be used
* for translating the content before calculating the digest.
* @param context The MD4 content to set the translation for.
* @param xlate The translation handle to use for this MD4 context
*/
APU_DECLARE(apr_status_t) apr_md4_set_xlate(apr_md4_ctx_t *context,
apr_xlate_t *xlate);
#else
#define apr_md4_set_xlate(context, xlate) APR_ENOTIMPL
#endif
/**
* MD4 block update operation. Continue an MD4 message-digest operation,
* processing another message block, and updating the context.
* @param context The MD4 content to update.
* @param input next message block to update
* @param inputLen The length of the next message block
*/
APU_DECLARE(apr_status_t) apr_md4_update(apr_md4_ctx_t *context,
const unsigned char *input,
apr_size_t inputLen);
/**
* MD4 finalization. Ends an MD4 message-digest operation, writing the
* message digest and zeroing the context
* @param digest The final MD4 digest
* @param context The MD4 content we are finalizing.
*/
APU_DECLARE(apr_status_t) apr_md4_final(
unsigned char digest[APR_MD4_DIGESTSIZE],
apr_md4_ctx_t *context);
/**
* MD4 digest computation
* @param digest The MD4 digest
* @param input message block to use
* @param inputLen The length of the message block
*/
APU_DECLARE(apr_status_t) apr_md4(unsigned char digest[APR_MD4_DIGESTSIZE],
const unsigned char *input,
apr_size_t inputLen);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !APR_MD4_H */

162
include/apr-linux/apr_md5.h Normal file
View File

@@ -0,0 +1,162 @@
/*
* This is work is derived from material Copyright RSA Data Security, Inc.
*
* The RSA copyright statement and Licence for that original material is
* included below. This is followed by the Apache copyright statement and
* licence for the modifications made to that material.
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_MD5_H
#define APR_MD5_H
#include "apu.h"
#include "apr_xlate.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file apr_md5.h
* @brief APR MD5 Routines
*/
/**
* @defgroup APR_MD5 MD5 Routines
* @ingroup APR
* @{
*/
/** The MD5 digest size */
#define APR_MD5_DIGESTSIZE 16
/** @see apr_md5_ctx_t */
typedef struct apr_md5_ctx_t apr_md5_ctx_t;
/** MD5 context. */
struct apr_md5_ctx_t {
/** state (ABCD) */
apr_uint32_t state[4];
/** number of bits, modulo 2^64 (lsb first) */
apr_uint32_t count[2];
/** input buffer */
unsigned char buffer[64];
/** translation handle
* ignored if xlate is unsupported
*/
apr_xlate_t *xlate;
};
/**
* MD5 Initialize. Begins an MD5 operation, writing a new context.
* @param context The MD5 context to initialize.
*/
APU_DECLARE(apr_status_t) apr_md5_init(apr_md5_ctx_t *context);
/**
* MD5 translation setup. Provides the APR translation handle to be used
* for translating the content before calculating the digest.
* @param context The MD5 content to set the translation for.
* @param xlate The translation handle to use for this MD5 context
*/
APU_DECLARE(apr_status_t) apr_md5_set_xlate(apr_md5_ctx_t *context,
apr_xlate_t *xlate);
/**
* MD5 block update operation. Continue an MD5 message-digest operation,
* processing another message block, and updating the context.
* @param context The MD5 content to update.
* @param input next message block to update
* @param inputLen The length of the next message block
*/
APU_DECLARE(apr_status_t) apr_md5_update(apr_md5_ctx_t *context,
const void *input,
apr_size_t inputLen);
/**
* MD5 finalization. Ends an MD5 message-digest operation, writing the
* message digest and zeroing the context
* @param digest The final MD5 digest
* @param context The MD5 content we are finalizing.
*/
APU_DECLARE(apr_status_t) apr_md5_final(unsigned char digest[APR_MD5_DIGESTSIZE],
apr_md5_ctx_t *context);
/**
* MD5 in one step
* @param digest The final MD5 digest
* @param input The message block to use
* @param inputLen The length of the message block
*/
APU_DECLARE(apr_status_t) apr_md5(unsigned char digest[APR_MD5_DIGESTSIZE],
const void *input,
apr_size_t inputLen);
/**
* Encode a password using an MD5 algorithm
* @param password The password to encode
* @param salt The salt to use for the encoding
* @param result The string to store the encoded password in
* @param nbytes The size of the result buffer
*/
APU_DECLARE(apr_status_t) apr_md5_encode(const char *password, const char *salt,
char *result, apr_size_t nbytes);
/**
* Validate hashes created by APR-supported algorithms: md5 and sha1.
* hashes created by crypt are supported only on platforms that provide
* crypt(3), so don't rely on that function unless you know that your
* application will be run only on platforms that support it. On platforms
* that don't support crypt(3), this falls back to a clear text string
* comparison.
* @param passwd The password to validate
* @param hash The password to validate against
*/
APU_DECLARE(apr_status_t) apr_password_validate(const char *passwd,
const char *hash);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !APR_MD5_H */

View File

@@ -0,0 +1,446 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_MEMCACHE_H
#define APR_MEMCACHE_H
/**
* @file apr_memcache.h
* @brief Client interface for memcached
* @remark To use this interface you must have a separate memcached
* server running. See the memcached website at http://www.danga.com/memcached/
* for more information.
*/
#include "apr.h"
#include "apr_pools.h"
#include "apr_time.h"
#include "apr_strings.h"
#include "apr_network_io.h"
#include "apr_ring.h"
#include "apr_buckets.h"
#include "apr_reslist.h"
#include "apr_hash.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup APR_Util_MC Memcached Client Routines
* @ingroup APR_Util
* @{
*/
/** Specifies the status of a memcached server */
typedef enum
{
APR_MC_SERVER_LIVE, /**< Server is alive and responding to requests */
APR_MC_SERVER_DEAD /**< Server is not responding to requests */
} apr_memcache_server_status_t;
/** Opaque memcache client connection object */
typedef struct apr_memcache_conn_t apr_memcache_conn_t;
/** Memcache Server Info Object */
typedef struct apr_memcache_server_t apr_memcache_server_t;
struct apr_memcache_server_t
{
const char *host; /**< Hostname of this Server */
apr_port_t port; /**< Port of this Server */
apr_memcache_server_status_t status; /**< @see apr_memcache_server_status_t */
#if APR_HAS_THREADS || defined(DOXYGEN)
apr_reslist_t *conns; /**< Resource list of actual client connections */
#else
apr_memcache_conn_t *conn;
#endif
apr_pool_t *p; /** Pool to use for private allocations */
#if APR_HAS_THREADS
apr_thread_mutex_t *lock;
#endif
apr_time_t btime;
};
/* Custom hash callback function prototype, user for server selection.
* @param baton user selected baton
* @param data data to hash
* @param data_len length of data
*/
typedef apr_uint32_t (*apr_memcache_hash_func)(void *baton,
const char *data,
const apr_size_t data_len);
typedef struct apr_memcache_t apr_memcache_t;
/* Custom Server Select callback function prototype.
* @param baton user selected baton
* @param mc memcache instance, use mc->live_servers to select a node
* @param hash hash of the selected key.
*/
typedef apr_memcache_server_t* (*apr_memcache_server_func)(void *baton,
apr_memcache_t *mc,
const apr_uint32_t hash);
/** Container for a set of memcached servers */
struct apr_memcache_t
{
apr_uint32_t flags; /**< Flags, Not currently used */
apr_uint16_t nalloc; /**< Number of Servers Allocated */
apr_uint16_t ntotal; /**< Number of Servers Added */
apr_memcache_server_t **live_servers; /**< Array of Servers */
apr_pool_t *p; /** Pool to use for allocations */
void *hash_baton;
apr_memcache_hash_func hash_func;
void *server_baton;
apr_memcache_server_func server_func;
};
/** Returned Data from a multiple get */
typedef struct
{
apr_status_t status;
const char* key;
apr_size_t len;
char *data;
apr_uint16_t flags;
} apr_memcache_value_t;
/**
* Creates a crc32 hash used to split keys between servers
* @param data Data to be hashed
* @param data_len Length of the data to use
* @return crc32 hash of data
* @remark The crc32 hash is not compatible with old memcached clients.
*/
APU_DECLARE(apr_uint32_t) apr_memcache_hash(apr_memcache_t *mc,
const char *data,
const apr_size_t data_len);
/**
* Pure CRC32 Hash. Used by some clients.
*/
APU_DECLARE(apr_uint32_t) apr_memcache_hash_crc32(void *baton,
const char *data,
const apr_size_t data_len);
/**
* hash compatible with the standard Perl Client.
*/
APU_DECLARE(apr_uint32_t) apr_memcache_hash_default(void *baton,
const char *data,
const apr_size_t data_len);
/**
* Picks a server based on a hash
* @param mc The memcache client object to use
* @param hash Hashed value of a Key
* @return server that controls specified hash
* @see apr_memcache_hash
*/
APU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server_hash(apr_memcache_t *mc,
const apr_uint32_t hash);
/**
* server selection compatible with the standard Perl Client.
*/
APU_DECLARE(apr_memcache_server_t *)
apr_memcache_find_server_hash_default(void *baton,
apr_memcache_t *mc,
const apr_uint32_t hash);
/**
* Adds a server to a client object
* @param mc The memcache client object to use
* @param ms Server to add
* @remark Adding servers is not thread safe, and should be done once at startup.
* @warning Changing servers after startup may cause keys to go to
* different servers.
*/
APU_DECLARE(apr_status_t) apr_memcache_add_server(apr_memcache_t *mc,
apr_memcache_server_t *server);
/**
* Finds a Server object based on a hostname/port pair
* @param mc The memcache client object to use
* @param host Hostname of the server
* @param port Port of the server
* @return Server with matching Hostname and Port, or NULL if none was found.
*/
APU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server(apr_memcache_t *mc,
const char *host,
apr_port_t port);
/**
* Enables a Server for use again
* @param mc The memcache client object to use
* @param ms Server to Activate
*/
APU_DECLARE(apr_status_t) apr_memcache_enable_server(apr_memcache_t *mc,
apr_memcache_server_t *ms);
/**
* Disable a Server
* @param mc The memcache client object to use
* @param ms Server to Disable
*/
APU_DECLARE(apr_status_t) apr_memcache_disable_server(apr_memcache_t *mc,
apr_memcache_server_t *ms);
/**
* Creates a new Server Object
* @param p Pool to use
* @param host hostname of the server
* @param port port of the server
* @param min minimum number of client sockets to open
* @param smax soft maximum number of client connections to open
* @param max hard maximum number of client connections
* @param ttl time to live in seconds of a client connection
* @param ns location of the new server object
* @see apr_reslist_create
* @remark min, smax, and max are only used when APR_HAS_THREADS
*/
APU_DECLARE(apr_status_t) apr_memcache_server_create(apr_pool_t *p,
const char *host,
apr_port_t port,
apr_uint32_t min,
apr_uint32_t smax,
apr_uint32_t max,
apr_uint32_t ttl,
apr_memcache_server_t **ns);
/**
* Creates a new memcached client object
* @param p Pool to use
* @param max_servers maximum number of servers
* @param flags Not currently used
* @param mc location of the new memcache client object
*/
APU_DECLARE(apr_status_t) apr_memcache_create(apr_pool_t *p,
apr_uint16_t max_servers,
apr_uint32_t flags,
apr_memcache_t **mc);
/**
* Gets a value from the server, allocating the value out of p
* @param mc client to use
* @param p Pool to use
* @param key null terminated string containing the key
* @param baton location of the allocated value
* @param len length of data at baton
* @param flags any flags set by the client for this key
* @return
*/
APU_DECLARE(apr_status_t) apr_memcache_getp(apr_memcache_t *mc,
apr_pool_t *p,
const char* key,
char **baton,
apr_size_t *len,
apr_uint16_t *flags);
/**
* Add a key to a hash for a multiget query
* if the hash (*value) is NULL it will be created
* @param data_pool pool from where the hash and their items are created from
* @param key null terminated string containing the key
* @param values hash of keys and values that this key will be added to
* @return
*/
APU_DECLARE(void)
apr_memcache_add_multget_key(apr_pool_t *data_pool,
const char* key,
apr_hash_t **values);
/**
* Gets multiple values from the server, allocating the values out of p
* @param mc client to use
* @param temp_pool Pool used for tempoary allocations. May be cleared inside this
* call.
* @param data_pool Pool used to allocate data for the returned values.
* @param values hash of apr_memcache_value_t keyed by strings, contains the
* result of the multiget call.
* @return
*/
APU_DECLARE(apr_status_t)
apr_memcache_multgetp(apr_memcache_t *mc,
apr_pool_t *temp_pool,
apr_pool_t *data_pool,
apr_hash_t *values);
/**
* Sets a value by key on the server
* @param mc client to use
* @param key null terminated string containing the key
* @param baton data to store on the server
* @param len length of data at baton
* @param timeout time in seconds for the data to live on the server
* @param flags any flags set by the client for this key
*/
APU_DECLARE(apr_status_t) apr_memcache_set(apr_memcache_t *mc,
const char *key,
char *baton,
const apr_size_t data_size,
apr_uint32_t timeout,
apr_uint16_t flags);
/**
* Adds value by key on the server
* @param mc client to use
* @param key null terminated string containing the key
* @param baton data to store on the server
* @param len length of data at baton
* @param timeout time for the data to live on the server
* @param flags any flags set by the client for this key
* @return APR_SUCCESS if the key was added, APR_EEXIST if the key
* already exists on the server.
*/
APU_DECLARE(apr_status_t) apr_memcache_add(apr_memcache_t *mc,
const char *key,
char *baton,
const apr_size_t data_size,
apr_uint32_t timeout,
apr_uint16_t flags);
/**
* Replaces value by key on the server
* @param mc client to use
* @param key null terminated string containing the key
* @param baton data to store on the server
* @param len length of data at baton
* @param timeout time for the data to live on the server
* @param flags any flags set by the client for this key
* @return APR_SUCCESS if the key was added, APR_EEXIST if the key
* did not exist on the server.
*/
APU_DECLARE(apr_status_t) apr_memcache_replace(apr_memcache_t *mc,
const char *key,
char *data,
const apr_size_t data_size,
apr_uint32_t timeout,
apr_uint16_t flags);
/**
* Deletes a key from a server
* @param mc client to use
* @param key null terminated string containing the key
* @param timeout time for the delete to stop other clients from adding
*/
APU_DECLARE(apr_status_t) apr_memcache_delete(apr_memcache_t *mc,
const char *key,
apr_uint32_t timeout);
/**
* Increments a value
* @param mc client to use
* @param key null terminated string containing the key
* @param n number to increment by
* @param nv new value after incrmenting
*/
APU_DECLARE(apr_status_t) apr_memcache_incr(apr_memcache_t *mc,
const char *key,
apr_int32_t n,
apr_uint32_t *nv);
/**
* Decrements a value
* @param mc client to use
* @param key null terminated string containing the key
* @param n number to decrement by
* @param nv new value after decrementing
*/
APU_DECLARE(apr_status_t) apr_memcache_decr(apr_memcache_t *mc,
const char *key,
apr_int32_t n,
apr_uint32_t *new_value);
/**
* Query a server's version
* @param ms server to query
* @param p Pool to allocate answer from
* @param baton location to store server version string
* @param len length of the server version string
*/
APU_DECLARE(apr_status_t) apr_memcache_version(apr_memcache_server_t *ms,
apr_pool_t *p,
char **baton);
typedef struct
{
/** Version string of this server */
const char *version;
/** Process id of this server process */
apr_uint32_t pid;
/** Number of seconds this server has been running */
apr_uint32_t uptime;
/** current UNIX time according to the server */
apr_time_t time;
/** The size of a pointer on the current machine */
apr_uint32_t pointer_size;
/** Accumulated user time for this process */
apr_time_t rusage_user;
/** Accumulated system time for this process */
apr_time_t rusage_system;
/** Current number of items stored by the server */
apr_uint32_t curr_items;
/** Total number of items stored by this server */
apr_uint32_t total_items;
/** Current number of bytes used by this server to store items */
apr_uint64_t bytes;
/** Number of open connections */
apr_uint32_t curr_connections;
/** Total number of connections opened since the server started running */
apr_uint32_t total_connections;
/** Number of connection structures allocated by the server */
apr_uint32_t connection_structures;
/** Cumulative number of retrieval requests */
apr_uint32_t cmd_get;
/** Cumulative number of storage requests */
apr_uint32_t cmd_set;
/** Number of keys that have been requested and found present */
apr_uint32_t get_hits;
/** Number of items that have been requested and not found */
apr_uint32_t get_misses;
/** Number of items removed from cache because they passed their
expiration time */
apr_uint64_t evictions;
/** Total number of bytes read by this server */
apr_uint64_t bytes_read;
/** Total number of bytes sent by this server */
apr_uint64_t bytes_written;
/** Number of bytes this server is allowed to use for storage. */
apr_uint32_t limit_maxbytes;
/** Number of threads the server is running (if built with threading) */
apr_uint32_t threads;
} apr_memcache_stats_t;
/**
* Query a server for statistics
* @param ms server to query
* @param p Pool to allocate answer from
* @param stats location of the new statistics structure
*/
APU_DECLARE(apr_status_t) apr_memcache_stats(apr_memcache_server_t *ms,
apr_pool_t *p,
apr_memcache_stats_t **stats);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* APR_MEMCACHE_H */

View File

@@ -0,0 +1,171 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_MMAP_H
#define APR_MMAP_H
/**
* @file apr_mmap.h
* @brief APR MMAP routines
*/
#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_ring.h"
#include "apr_file_io.h" /* for apr_file_t */
#ifdef BEOS
#include <kernel/OS.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_mmap MMAP (Memory Map) Routines
* @ingroup APR
* @{
*/
/** MMap opened for reading */
#define APR_MMAP_READ 1
/** MMap opened for writing */
#define APR_MMAP_WRITE 2
/** @see apr_mmap_t */
typedef struct apr_mmap_t apr_mmap_t;
/**
* @remark
* As far as I can tell the only really sane way to store an MMAP is as a
* void * and a length. BeOS requires this area_id, but that's just a little
* something extra. I am exposing this type, because it doesn't make much
* sense to keep it private, and opening it up makes some stuff easier in
* Apache.
*/
/** The MMAP structure */
struct apr_mmap_t {
/** The pool the mmap structure was allocated out of. */
apr_pool_t *cntxt;
#ifdef BEOS
/** An area ID. Only valid on BeOS */
area_id area;
#endif
#ifdef WIN32
/** The handle of the file mapping */
HANDLE mhandle;
/** The start of the real memory page area (mapped view) */
void *mv;
/** The physical start, size and offset */
apr_off_t pstart;
apr_size_t psize;
apr_off_t poffset;
#endif
/** The start of the memory mapped area */
void *mm;
/** The amount of data in the mmap */
apr_size_t size;
/** ring of apr_mmap_t's that reference the same
* mmap'ed region; acts in place of a reference count */
APR_RING_ENTRY(apr_mmap_t) link;
};
#if APR_HAS_MMAP || defined(DOXYGEN)
/** @def APR_MMAP_THRESHOLD
* Files have to be at least this big before they're mmap()d. This is to deal
* with systems where the expense of doing an mmap() and an munmap() outweighs
* the benefit for small files. It shouldn't be set lower than 1.
*/
#ifdef MMAP_THRESHOLD
# define APR_MMAP_THRESHOLD MMAP_THRESHOLD
#else
# ifdef SUNOS4
# define APR_MMAP_THRESHOLD (8*1024)
# else
# define APR_MMAP_THRESHOLD 1
# endif /* SUNOS4 */
#endif /* MMAP_THRESHOLD */
/** @def APR_MMAP_LIMIT
* Maximum size of MMap region
*/
#ifdef MMAP_LIMIT
# define APR_MMAP_LIMIT MMAP_LIMIT
#else
# define APR_MMAP_LIMIT (4*1024*1024)
#endif /* MMAP_LIMIT */
/** Can this file be MMaped */
#define APR_MMAP_CANDIDATE(filelength) \
((filelength >= APR_MMAP_THRESHOLD) && (filelength < APR_MMAP_LIMIT))
/* Function definitions */
/**
* Create a new mmap'ed file out of an existing APR file.
* @param newmmap The newly created mmap'ed file.
* @param file The file turn into an mmap.
* @param offset The offset into the file to start the data pointer at.
* @param size The size of the file
* @param flag bit-wise or of:
* <PRE>
* APR_MMAP_READ MMap opened for reading
* APR_MMAP_WRITE MMap opened for writing
* </PRE>
* @param cntxt The pool to use when creating the mmap.
*/
APR_DECLARE(apr_status_t) apr_mmap_create(apr_mmap_t **newmmap,
apr_file_t *file, apr_off_t offset,
apr_size_t size, apr_int32_t flag,
apr_pool_t *cntxt);
/**
* Duplicate the specified MMAP.
* @param new_mmap The structure to duplicate into.
* @param old_mmap The mmap to duplicate.
* @param p The pool to use for new_mmap.
*/
APR_DECLARE(apr_status_t) apr_mmap_dup(apr_mmap_t **new_mmap,
apr_mmap_t *old_mmap,
apr_pool_t *p);
/**
* Remove a mmap'ed.
* @param mm The mmap'ed file.
*/
APR_DECLARE(apr_status_t) apr_mmap_delete(apr_mmap_t *mm);
/**
* Move the pointer into the mmap'ed file to the specified offset.
* @param addr The pointer to the offset specified.
* @param mm The mmap'ed file.
* @param offset The offset to move to.
*/
APR_DECLARE(apr_status_t) apr_mmap_offset(void **addr, apr_mmap_t *mm,
apr_off_t offset);
#endif /* APR_HAS_MMAP */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ! APR_MMAP_H */

View File

@@ -0,0 +1,842 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_NETWORK_IO_H
#define APR_NETWORK_IO_H
/**
* @file apr_network_io.h
* @brief APR Network library
*/
#include "apr.h"
#include "apr_pools.h"
#include "apr_file_io.h"
#include "apr_errno.h"
#include "apr_inherit.h"
#if APR_HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_network_io Network Routines
* @ingroup APR
* @{
*/
#ifndef APR_MAX_SECS_TO_LINGER
/** Maximum seconds to linger */
#define APR_MAX_SECS_TO_LINGER 30
#endif
#ifndef APRMAXHOSTLEN
/** Maximum hostname length */
#define APRMAXHOSTLEN 256
#endif
#ifndef APR_ANYADDR
/** Default 'any' address */
#define APR_ANYADDR "0.0.0.0"
#endif
/**
* @defgroup apr_sockopt Socket option definitions
* @{
*/
#define APR_SO_LINGER 1 /**< Linger */
#define APR_SO_KEEPALIVE 2 /**< Keepalive */
#define APR_SO_DEBUG 4 /**< Debug */
#define APR_SO_NONBLOCK 8 /**< Non-blocking IO */
#define APR_SO_REUSEADDR 16 /**< Reuse addresses */
#define APR_SO_BROADCAST 32 /**< Permit sending of broadcast msgs */
#define APR_SO_SNDBUF 64 /**< Send buffer */
#define APR_SO_RCVBUF 128 /**< Receive buffer */
#define APR_SO_DISCONNECTED 256 /**< Disconnected */
#define APR_TCP_NODELAY 512 /**< For SCTP sockets, this is mapped
* to STCP_NODELAY internally.
*/
#define APR_TCP_NOPUSH 1024 /**< No push */
#define APR_RESET_NODELAY 2048 /**< This flag is ONLY set internally
* when we set APR_TCP_NOPUSH with
* APR_TCP_NODELAY set to tell us that
* APR_TCP_NODELAY should be turned on
* again when NOPUSH is turned off
*/
#define APR_INCOMPLETE_READ 4096 /**< Set on non-blocking sockets
* (timeout != 0) on which the
* previous read() did not fill a buffer
* completely. the next apr_socket_recv()
* will first call select()/poll() rather than
* going straight into read(). (Can also
* be set by an application to force a
* select()/poll() call before the next
* read, in cases where the app expects
* that an immediate read would fail.)
*/
#define APR_INCOMPLETE_WRITE 8192 /**< like APR_INCOMPLETE_READ, but for write
* @see APR_INCOMPLETE_READ
*/
#define APR_IPV6_V6ONLY 16384 /**< Don't accept IPv4 connections on an
* IPv6 listening socket.
*/
#define APR_TCP_DEFER_ACCEPT 32768 /**< Delay accepting of new connections
* until data is available.
* @see apr_socket_accept_filter
*/
/** @} */
/** Define what type of socket shutdown should occur. */
typedef enum {
APR_SHUTDOWN_READ, /**< no longer allow read request */
APR_SHUTDOWN_WRITE, /**< no longer allow write requests */
APR_SHUTDOWN_READWRITE /**< no longer allow read or write requests */
} apr_shutdown_how_e;
#define APR_IPV4_ADDR_OK 0x01 /**< @see apr_sockaddr_info_get() */
#define APR_IPV6_ADDR_OK 0x02 /**< @see apr_sockaddr_info_get() */
#if (!APR_HAVE_IN_ADDR)
/**
* We need to make sure we always have an in_addr type, so APR will just
* define it ourselves, if the platform doesn't provide it.
*/
struct in_addr {
apr_uint32_t s_addr; /**< storage to hold the IP# */
};
#endif
/** @def APR_INADDR_NONE
* Not all platforms have a real INADDR_NONE. This macro replaces
* INADDR_NONE on all platforms.
*/
#ifdef INADDR_NONE
#define APR_INADDR_NONE INADDR_NONE
#else
#define APR_INADDR_NONE ((unsigned int) 0xffffffff)
#endif
/**
* @def APR_INET
* Not all platforms have these defined, so we'll define them here
* The default values come from FreeBSD 4.1.1
*/
#define APR_INET AF_INET
/** @def APR_UNSPEC
* Let the system decide which address family to use
*/
#ifdef AF_UNSPEC
#define APR_UNSPEC AF_UNSPEC
#else
#define APR_UNSPEC 0
#endif
#if APR_HAVE_IPV6
/** @def APR_INET6
* IPv6 Address Family. Not all platforms may have this defined.
*/
#define APR_INET6 AF_INET6
#endif
/**
* @defgroup IP_Proto IP Protocol Definitions for use when creating sockets
* @{
*/
#define APR_PROTO_TCP 6 /**< TCP */
#define APR_PROTO_UDP 17 /**< UDP */
#define APR_PROTO_SCTP 132 /**< SCTP */
/** @} */
/**
* Enum used to denote either the local and remote endpoint of a
* connection.
*/
typedef enum {
APR_LOCAL, /**< Socket information for local end of connection */
APR_REMOTE /**< Socket information for remote end of connection */
} apr_interface_e;
/**
* The specific declaration of inet_addr's ... some platforms fall back
* inet_network (this is not good, but necessary)
*/
#if APR_HAVE_INET_ADDR
#define apr_inet_addr inet_addr
#elif APR_HAVE_INET_NETWORK /* only DGUX, as far as I know */
/**
* @warning
* not generally safe... inet_network() and inet_addr() perform
* different functions */
#define apr_inet_addr inet_network
#endif
/** A structure to represent sockets */
typedef struct apr_socket_t apr_socket_t;
/**
* A structure to encapsulate headers and trailers for apr_socket_sendfile
*/
typedef struct apr_hdtr_t apr_hdtr_t;
/** A structure to represent in_addr */
typedef struct in_addr apr_in_addr_t;
/** A structure to represent an IP subnet */
typedef struct apr_ipsubnet_t apr_ipsubnet_t;
/** @remark use apr_uint16_t just in case some system has a short that isn't 16 bits... */
typedef apr_uint16_t apr_port_t;
/** @remark It's defined here as I think it should all be platform safe...
* @see apr_sockaddr_t
*/
typedef struct apr_sockaddr_t apr_sockaddr_t;
/**
* APRs socket address type, used to ensure protocol independence
*/
struct apr_sockaddr_t {
/** The pool to use... */
apr_pool_t *pool;
/** The hostname */
char *hostname;
/** Either a string of the port number or the service name for the port */
char *servname;
/** The numeric port */
apr_port_t port;
/** The family */
apr_int32_t family;
/** How big is the sockaddr we're using? */
apr_socklen_t salen;
/** How big is the ip address structure we're using? */
int ipaddr_len;
/** How big should the address buffer be? 16 for v4 or 46 for v6
* used in inet_ntop... */
int addr_str_len;
/** This points to the IP address structure within the appropriate
* sockaddr structure. */
void *ipaddr_ptr;
/** If multiple addresses were found by apr_sockaddr_info_get(), this
* points to a representation of the next address. */
apr_sockaddr_t *next;
/** Union of either IPv4 or IPv6 sockaddr. */
union {
/** IPv4 sockaddr structure */
struct sockaddr_in sin;
#if APR_HAVE_IPV6
/** IPv6 sockaddr structure */
struct sockaddr_in6 sin6;
#endif
#if APR_HAVE_SA_STORAGE
/** Placeholder to ensure that the size of this union is not
* dependent on whether APR_HAVE_IPV6 is defined. */
struct sockaddr_storage sas;
#endif
} sa;
};
#if APR_HAS_SENDFILE
/**
* Support reusing the socket on platforms which support it (from disconnect,
* specifically Win32.
* @remark Optional flag passed into apr_socket_sendfile()
*/
#define APR_SENDFILE_DISCONNECT_SOCKET 1
#endif
/** A structure to encapsulate headers and trailers for apr_socket_sendfile */
struct apr_hdtr_t {
/** An iovec to store the headers sent before the file. */
struct iovec* headers;
/** number of headers in the iovec */
int numheaders;
/** An iovec to store the trailers sent after the file. */
struct iovec* trailers;
/** number of trailers in the iovec */
int numtrailers;
};
/* function definitions */
/**
* Create a socket.
* @param new_sock The new socket that has been set up.
* @param family The address family of the socket (e.g., APR_INET).
* @param type The type of the socket (e.g., SOCK_STREAM).
* @param protocol The protocol of the socket (e.g., APR_PROTO_TCP).
* @param cont The pool for the apr_socket_t and associated storage.
*/
APR_DECLARE(apr_status_t) apr_socket_create(apr_socket_t **new_sock,
int family, int type,
int protocol,
apr_pool_t *cont);
/**
* Shutdown either reading, writing, or both sides of a socket.
* @param thesocket The socket to close
* @param how How to shutdown the socket. One of:
* <PRE>
* APR_SHUTDOWN_READ no longer allow read requests
* APR_SHUTDOWN_WRITE no longer allow write requests
* APR_SHUTDOWN_READWRITE no longer allow read or write requests
* </PRE>
* @see apr_shutdown_how_e
* @remark This does not actually close the socket descriptor, it just
* controls which calls are still valid on the socket.
*/
APR_DECLARE(apr_status_t) apr_socket_shutdown(apr_socket_t *thesocket,
apr_shutdown_how_e how);
/**
* Close a socket.
* @param thesocket The socket to close
*/
APR_DECLARE(apr_status_t) apr_socket_close(apr_socket_t *thesocket);
/**
* Bind the socket to its associated port
* @param sock The socket to bind
* @param sa The socket address to bind to
* @remark This may be where we will find out if there is any other process
* using the selected port.
*/
APR_DECLARE(apr_status_t) apr_socket_bind(apr_socket_t *sock,
apr_sockaddr_t *sa);
/**
* Listen to a bound socket for connections.
* @param sock The socket to listen on
* @param backlog The number of outstanding connections allowed in the sockets
* listen queue. If this value is less than zero, the listen
* queue size is set to zero.
*/
APR_DECLARE(apr_status_t) apr_socket_listen(apr_socket_t *sock,
apr_int32_t backlog);
/**
* Accept a new connection request
* @param new_sock A copy of the socket that is connected to the socket that
* made the connection request. This is the socket which should
* be used for all future communication.
* @param sock The socket we are listening on.
* @param connection_pool The pool for the new socket.
*/
APR_DECLARE(apr_status_t) apr_socket_accept(apr_socket_t **new_sock,
apr_socket_t *sock,
apr_pool_t *connection_pool);
/**
* Issue a connection request to a socket either on the same machine
* or a different one.
* @param sock The socket we wish to use for our side of the connection
* @param sa The address of the machine we wish to connect to.
*/
APR_DECLARE(apr_status_t) apr_socket_connect(apr_socket_t *sock,
apr_sockaddr_t *sa);
/**
* Create apr_sockaddr_t from hostname, address family, and port.
* @param sa The new apr_sockaddr_t.
* @param hostname The hostname or numeric address string to resolve/parse, or
* NULL to build an address that corresponds to 0.0.0.0 or ::
* @param family The address family to use, or APR_UNSPEC if the system should
* decide.
* @param port The port number.
* @param flags Special processing flags:
* <PRE>
* APR_IPV4_ADDR_OK first query for IPv4 addresses; only look
* for IPv6 addresses if the first query failed;
* only valid if family is APR_UNSPEC and hostname
* isn't NULL; mutually exclusive with
* APR_IPV6_ADDR_OK
* APR_IPV6_ADDR_OK first query for IPv6 addresses; only look
* for IPv4 addresses if the first query failed;
* only valid if family is APR_UNSPEC and hostname
* isn't NULL and APR_HAVE_IPV6; mutually exclusive
* with APR_IPV4_ADDR_OK
* </PRE>
* @param p The pool for the apr_sockaddr_t and associated storage.
*/
APR_DECLARE(apr_status_t) apr_sockaddr_info_get(apr_sockaddr_t **sa,
const char *hostname,
apr_int32_t family,
apr_port_t port,
apr_int32_t flags,
apr_pool_t *p);
/**
* Look up the host name from an apr_sockaddr_t.
* @param hostname The hostname.
* @param sa The apr_sockaddr_t.
* @param flags Special processing flags.
*/
APR_DECLARE(apr_status_t) apr_getnameinfo(char **hostname,
apr_sockaddr_t *sa,
apr_int32_t flags);
/**
* Parse hostname/IP address with scope id and port.
*
* Any of the following strings are accepted:
* 8080 (just the port number)
* www.apache.org (just the hostname)
* www.apache.org:8080 (hostname and port number)
* [fe80::1]:80 (IPv6 numeric address string only)
* [fe80::1%eth0] (IPv6 numeric address string and scope id)
*
* Invalid strings:
* (empty string)
* [abc] (not valid IPv6 numeric address string)
* abc:65536 (invalid port number)
*
* @param addr The new buffer containing just the hostname. On output, *addr
* will be NULL if no hostname/IP address was specfied.
* @param scope_id The new buffer containing just the scope id. On output,
* *scope_id will be NULL if no scope id was specified.
* @param port The port number. On output, *port will be 0 if no port was
* specified.
* ### FIXME: 0 is a legal port (per RFC 1700). this should
* ### return something besides zero if the port is missing.
* @param str The input string to be parsed.
* @param p The pool from which *addr and *scope_id are allocated.
* @remark If scope id shouldn't be allowed, check for scope_id != NULL in
* addition to checking the return code. If addr/hostname should be
* required, check for addr == NULL in addition to checking the
* return code.
*/
APR_DECLARE(apr_status_t) apr_parse_addr_port(char **addr,
char **scope_id,
apr_port_t *port,
const char *str,
apr_pool_t *p);
/**
* Get name of the current machine
* @param buf A buffer to store the hostname in.
* @param len The maximum length of the hostname that can be stored in the
* buffer provided. The suggested length is APRMAXHOSTLEN + 1.
* @param cont The pool to use.
* @remark If the buffer was not large enough, an error will be returned.
*/
APR_DECLARE(apr_status_t) apr_gethostname(char *buf, int len, apr_pool_t *cont);
/**
* Return the data associated with the current socket
* @param data The user data associated with the socket.
* @param key The key to associate with the user data.
* @param sock The currently open socket.
*/
APR_DECLARE(apr_status_t) apr_socket_data_get(void **data, const char *key,
apr_socket_t *sock);
/**
* Set the data associated with the current socket.
* @param sock The currently open socket.
* @param data The user data to associate with the socket.
* @param key The key to associate with the data.
* @param cleanup The cleanup to call when the socket is destroyed.
*/
APR_DECLARE(apr_status_t) apr_socket_data_set(apr_socket_t *sock, void *data,
const char *key,
apr_status_t (*cleanup)(void*));
/**
* Send data over a network.
* @param sock The socket to send the data over.
* @param buf The buffer which contains the data to be sent.
* @param len On entry, the number of bytes to send; on exit, the number
* of bytes sent.
* @remark
* <PRE>
* This functions acts like a blocking write by default. To change
* this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
* socket option.
*
* It is possible for both bytes to be sent and an error to be returned.
*
* APR_EINTR is never returned.
* </PRE>
*/
APR_DECLARE(apr_status_t) apr_socket_send(apr_socket_t *sock, const char *buf,
apr_size_t *len);
/**
* Send multiple packets of data over a network.
* @param sock The socket to send the data over.
* @param vec The array of iovec structs containing the data to send
* @param nvec The number of iovec structs in the array
* @param len Receives the number of bytes actually written
* @remark
* <PRE>
* This functions acts like a blocking write by default. To change
* this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
* socket option.
* The number of bytes actually sent is stored in argument 3.
*
* It is possible for both bytes to be sent and an error to be returned.
*
* APR_EINTR is never returned.
* </PRE>
*/
APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock,
const struct iovec *vec,
apr_int32_t nvec, apr_size_t *len);
/**
* @param sock The socket to send from
* @param where The apr_sockaddr_t describing where to send the data
* @param flags The flags to use
* @param buf The data to send
* @param len The length of the data to send
*/
APR_DECLARE(apr_status_t) apr_socket_sendto(apr_socket_t *sock,
apr_sockaddr_t *where,
apr_int32_t flags, const char *buf,
apr_size_t *len);
/**
* Read data from a socket. On success, the address of the peer from
* which the data was sent is copied into the @param from parameter,
* and the @param len parameter is updated to give the number of bytes
* written to @param buf.
* @param from Updated with the address from which the data was received
* @param sock The socket to use
* @param flags The flags to use
* @param buf The buffer to use
* @param len The length of the available buffer
*/
APR_DECLARE(apr_status_t) apr_socket_recvfrom(apr_sockaddr_t *from,
apr_socket_t *sock,
apr_int32_t flags, char *buf,
apr_size_t *len);
#if APR_HAS_SENDFILE || defined(DOXYGEN)
/**
* Send a file from an open file descriptor to a socket, along with
* optional headers and trailers
* @param sock The socket to which we're writing
* @param file The open file from which to read
* @param hdtr A structure containing the headers and trailers to send
* @param offset Offset into the file where we should begin writing
* @param len (input) - Number of bytes to send from the file
* (output) - Number of bytes actually sent,
* including headers, file, and trailers
* @param flags APR flags that are mapped to OS specific flags
* @remark This functions acts like a blocking write by default. To change
* this behavior, use apr_socket_timeout_set() or the
* APR_SO_NONBLOCK socket option.
* The number of bytes actually sent is stored in the len parameter.
* The offset parameter is passed by reference for no reason; its
* value will never be modified by the apr_socket_sendfile() function.
*/
APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock,
apr_file_t *file,
apr_hdtr_t *hdtr,
apr_off_t *offset,
apr_size_t *len,
apr_int32_t flags);
#endif /* APR_HAS_SENDFILE */
/**
* Read data from a network.
* @param sock The socket to read the data from.
* @param buf The buffer to store the data in.
* @param len On entry, the number of bytes to receive; on exit, the number
* of bytes received.
* @remark
* <PRE>
* This functions acts like a blocking read by default. To change
* this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
* socket option.
* The number of bytes actually received is stored in argument 3.
*
* It is possible for both bytes to be received and an APR_EOF or
* other error to be returned.
*
* APR_EINTR is never returned.
* </PRE>
*/
APR_DECLARE(apr_status_t) apr_socket_recv(apr_socket_t *sock,
char *buf, apr_size_t *len);
/**
* Setup socket options for the specified socket
* @param sock The socket to set up.
* @param opt The option we would like to configure. One of:
* <PRE>
* APR_SO_DEBUG -- turn on debugging information
* APR_SO_KEEPALIVE -- keep connections active
* APR_SO_LINGER -- lingers on close if data is present
* APR_SO_NONBLOCK -- Turns blocking on/off for socket
* When this option is enabled, use
* the APR_STATUS_IS_EAGAIN() macro to
* see if a send or receive function
* could not transfer data without
* blocking.
* APR_SO_REUSEADDR -- The rules used in validating addresses
* supplied to bind should allow reuse
* of local addresses.
* APR_SO_SNDBUF -- Set the SendBufferSize
* APR_SO_RCVBUF -- Set the ReceiveBufferSize
* </PRE>
* @param on Value for the option.
*/
APR_DECLARE(apr_status_t) apr_socket_opt_set(apr_socket_t *sock,
apr_int32_t opt, apr_int32_t on);
/**
* Setup socket timeout for the specified socket
* @param sock The socket to set up.
* @param t Value for the timeout.
* <PRE>
* t > 0 -- read and write calls return APR_TIMEUP if specified time
* elapsess with no data read or written
* t == 0 -- read and write calls never block
* t < 0 -- read and write calls block
* </PRE>
*/
APR_DECLARE(apr_status_t) apr_socket_timeout_set(apr_socket_t *sock,
apr_interval_time_t t);
/**
* Query socket options for the specified socket
* @param sock The socket to query
* @param opt The option we would like to query. One of:
* <PRE>
* APR_SO_DEBUG -- turn on debugging information
* APR_SO_KEEPALIVE -- keep connections active
* APR_SO_LINGER -- lingers on close if data is present
* APR_SO_NONBLOCK -- Turns blocking on/off for socket
* APR_SO_REUSEADDR -- The rules used in validating addresses
* supplied to bind should allow reuse
* of local addresses.
* APR_SO_SNDBUF -- Set the SendBufferSize
* APR_SO_RCVBUF -- Set the ReceiveBufferSize
* APR_SO_DISCONNECTED -- Query the disconnected state of the socket.
* (Currently only used on Windows)
* </PRE>
* @param on Socket option returned on the call.
*/
APR_DECLARE(apr_status_t) apr_socket_opt_get(apr_socket_t *sock,
apr_int32_t opt, apr_int32_t *on);
/**
* Query socket timeout for the specified socket
* @param sock The socket to query
* @param t Socket timeout returned from the query.
*/
APR_DECLARE(apr_status_t) apr_socket_timeout_get(apr_socket_t *sock,
apr_interval_time_t *t);
/**
* Query the specified socket if at the OOB/Urgent data mark
* @param sock The socket to query
* @param atmark Is set to true if socket is at the OOB/urgent mark,
* otherwise is set to false.
*/
APR_DECLARE(apr_status_t) apr_socket_atmark(apr_socket_t *sock,
int *atmark);
/**
* Return an address associated with a socket; either the address to
* which the socket is bound locally or the the address of the peer
* to which the socket is connected.
* @param sa The returned apr_sockaddr_t.
* @param which Whether to retrieve the local or remote address
* @param sock The socket to use
*/
APR_DECLARE(apr_status_t) apr_socket_addr_get(apr_sockaddr_t **sa,
apr_interface_e which,
apr_socket_t *sock);
/**
* Return the IP address (in numeric address string format) in
* an APR socket address. APR will allocate storage for the IP address
* string from the pool of the apr_sockaddr_t.
* @param addr The IP address.
* @param sockaddr The socket address to reference.
*/
APR_DECLARE(apr_status_t) apr_sockaddr_ip_get(char **addr,
apr_sockaddr_t *sockaddr);
/**
* Write the IP address (in numeric address string format) of the APR
* socket address @a sockaddr into the buffer @a buf (of size @a buflen).
* @param sockaddr The socket address to reference.
*/
APR_DECLARE(apr_status_t) apr_sockaddr_ip_getbuf(char *buf, apr_size_t buflen,
apr_sockaddr_t *sockaddr);
/**
* See if the IP addresses in two APR socket addresses are
* equivalent. Appropriate logic is present for comparing
* IPv4-mapped IPv6 addresses with IPv4 addresses.
*
* @param addr1 One of the APR socket addresses.
* @param addr2 The other APR socket address.
* @remark The return value will be non-zero if the addresses
* are equivalent.
*/
APR_DECLARE(int) apr_sockaddr_equal(const apr_sockaddr_t *addr1,
const apr_sockaddr_t *addr2);
/**
* Return the type of the socket.
* @param sock The socket to query.
* @param type The returned type (e.g., SOCK_STREAM).
*/
APR_DECLARE(apr_status_t) apr_socket_type_get(apr_socket_t *sock,
int *type);
/**
* Given an apr_sockaddr_t and a service name, set the port for the service
* @param sockaddr The apr_sockaddr_t that will have its port set
* @param servname The name of the service you wish to use
*/
APR_DECLARE(apr_status_t) apr_getservbyname(apr_sockaddr_t *sockaddr,
const char *servname);
/**
* Build an ip-subnet representation from an IP address and optional netmask or
* number-of-bits.
* @param ipsub The new ip-subnet representation
* @param ipstr The input IP address string
* @param mask_or_numbits The input netmask or number-of-bits string, or NULL
* @param p The pool to allocate from
*/
APR_DECLARE(apr_status_t) apr_ipsubnet_create(apr_ipsubnet_t **ipsub,
const char *ipstr,
const char *mask_or_numbits,
apr_pool_t *p);
/**
* Test the IP address in an apr_sockaddr_t against a pre-built ip-subnet
* representation.
* @param ipsub The ip-subnet representation
* @param sa The socket address to test
* @return non-zero if the socket address is within the subnet, 0 otherwise
*/
APR_DECLARE(int) apr_ipsubnet_test(apr_ipsubnet_t *ipsub, apr_sockaddr_t *sa);
#if APR_HAS_SO_ACCEPTFILTER || defined(DOXYGEN)
/**
* Set an OS level accept filter.
* @param sock The socket to put the accept filter on.
* @param name The accept filter
* @param args Any extra args to the accept filter. Passing NULL here removes
* the accept filter.
*/
apr_status_t apr_socket_accept_filter(apr_socket_t *sock, char *name,
char *args);
#endif
/**
* Return the protocol of the socket.
* @param sock The socket to query.
* @param protocol The returned protocol (e.g., APR_PROTO_TCP).
*/
APR_DECLARE(apr_status_t) apr_socket_protocol_get(apr_socket_t *sock,
int *protocol);
/**
* Get the pool used by the socket.
*/
APR_POOL_DECLARE_ACCESSOR(socket);
/**
* Set a socket to be inherited by child processes.
*/
APR_DECLARE_INHERIT_SET(socket);
/**
* Unset a socket from being inherited by child processes.
*/
APR_DECLARE_INHERIT_UNSET(socket);
/**
* @defgroup apr_mcast IP Multicast
* @{
*/
/**
* Join a Multicast Group
* @param sock The socket to join a multicast group
* @param join The address of the multicast group to join
* @param iface Address of the interface to use. If NULL is passed, the
* default multicast interface will be used. (OS Dependent)
* @param source Source Address to accept transmissions from (non-NULL
* implies Source-Specific Multicast)
*/
APR_DECLARE(apr_status_t) apr_mcast_join(apr_socket_t *sock,
apr_sockaddr_t *join,
apr_sockaddr_t *iface,
apr_sockaddr_t *source);
/**
* Leave a Multicast Group. All arguments must be the same as
* apr_mcast_join.
* @param sock The socket to leave a multicast group
* @param addr The address of the multicast group to leave
* @param iface Address of the interface to use. If NULL is passed, the
* default multicast interface will be used. (OS Dependent)
* @param source Source Address to accept transmissions from (non-NULL
* implies Source-Specific Multicast)
*/
APR_DECLARE(apr_status_t) apr_mcast_leave(apr_socket_t *sock,
apr_sockaddr_t *addr,
apr_sockaddr_t *iface,
apr_sockaddr_t *source);
/**
* Set the Multicast Time to Live (ttl) for a multicast transmission.
* @param sock The socket to set the multicast ttl
* @param ttl Time to live to Assign. 0-255, default=1
* @remark If the TTL is 0, packets will only be seen by sockets on
* the local machine, and only when multicast loopback is enabled.
*/
APR_DECLARE(apr_status_t) apr_mcast_hops(apr_socket_t *sock,
apr_byte_t ttl);
/**
* Toggle IP Multicast Loopback
* @param sock The socket to set multicast loopback
* @param opt 0=disable, 1=enable
*/
APR_DECLARE(apr_status_t) apr_mcast_loopback(apr_socket_t *sock,
apr_byte_t opt);
/**
* Set the Interface to be used for outgoing Multicast Transmissions.
* @param sock The socket to set the multicast interface on
* @param iface Address of the interface to use for Multicast
*/
APR_DECLARE(apr_status_t) apr_mcast_interface(apr_socket_t *sock,
apr_sockaddr_t *iface);
/** @} */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ! APR_NETWORK_IO_H */

View File

@@ -0,0 +1,92 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_OPTIONAL_H
#define APR_OPTIONAL_H
#include "apu.h"
/**
* @file apr_optional.h
* @brief APR-UTIL registration of functions exported by modules
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup APR_Util_Opt Optional Functions
* @ingroup APR_Util
*
* Typesafe registration and retrieval of functions that may not be present
* (i.e. functions exported by optional modules)
* @{
*/
/**
* The type of an optional function.
* @param name The name of the function
*/
#define APR_OPTIONAL_FN_TYPE(name) apr_OFN_##name##_t
/**
* Declare an optional function.
* @param ret The return type of the function
* @param name The name of the function
* @param args The function arguments (including brackets)
*/
#define APR_DECLARE_OPTIONAL_FN(ret,name,args) \
typedef ret (APR_OPTIONAL_FN_TYPE(name)) args
/**
* XXX: This doesn't belong here, then!
* Private function! DO NOT USE!
* @internal
*/
typedef void (apr_opt_fn_t)(void);
/** @internal */
APU_DECLARE_NONSTD(void) apr_dynamic_fn_register(const char *szName,
apr_opt_fn_t *pfn);
/**
* Register an optional function. This can be later retrieved, type-safely, by
* name. Like all global functions, the name must be unique. Note that,
* confusingly but correctly, the function itself can be static!
* @param name The name of the function
*/
#define APR_REGISTER_OPTIONAL_FN(name) do { \
APR_OPTIONAL_FN_TYPE(name) *apu__opt = name; \
apr_dynamic_fn_register(#name,(apr_opt_fn_t *)apu__opt); \
} while (0)
/** @internal
* Private function! DO NOT USE!
*/
APU_DECLARE(apr_opt_fn_t *) apr_dynamic_fn_retrieve(const char *szName);
/**
* Retrieve an optional function. Returns NULL if the function is not present.
* @param name The name of the function
*/
#define APR_RETRIEVE_OPTIONAL_FN(name) \
(APR_OPTIONAL_FN_TYPE(name) *)apr_dynamic_fn_retrieve(#name)
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* APR_OPTIONAL_H */

View File

@@ -0,0 +1,117 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file apr_optional_hooks.h
* @brief Apache optional hook functions
*/
#ifndef APR_OPTIONAL_HOOK_H
#define APR_OPTIONAL_HOOK_H
#include "apr_tables.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup APR_Util_OPT_HOOK Optional Hook Functions
* @ingroup APR_Util_Hook
* @{
*/
/**
* Function to implemnt the APR_OPTIONAL_HOOK Macro
* @internal
* @see APR_OPTIONAL_HOOK
*
* @param name The name of the hook
* @param pfn A pointer to a function that will be called
* @param aszPre a NULL-terminated array of strings that name modules whose hooks should precede this one
* @param aszSucc a NULL-terminated array of strings that name modules whose hooks should succeed this one
* @param nOrder an integer determining order before honouring aszPre and aszSucc (for example HOOK_MIDDLE)
*/
APU_DECLARE(void) apr_optional_hook_add(const char *szName,void (*pfn)(void),
const char * const *aszPre,
const char * const *aszSucc,
int nOrder);
/**
* Hook to an optional hook.
*
* @param ns The namespace prefix of the hook functions
* @param name The name of the hook
* @param pfn A pointer to a function that will be called
* @param aszPre a NULL-terminated array of strings that name modules whose hooks should precede this one
* @param aszSucc a NULL-terminated array of strings that name modules whose hooks should succeed this one
* @param nOrder an integer determining order before honouring aszPre and aszSucc (for example HOOK_MIDDLE)
*/
#define APR_OPTIONAL_HOOK(ns,name,pfn,aszPre,aszSucc,nOrder) do { \
ns##_HOOK_##name##_t *apu__hook = pfn; \
apr_optional_hook_add(#name,(void (*)(void))apu__hook,aszPre, aszSucc, nOrder); \
} while (0)
/**
* @internal
* @param szName - the name of the function
* @return the hook structure for a given hook
*/
APU_DECLARE(apr_array_header_t *) apr_optional_hook_get(const char *szName);
/**
* Implement an optional hook that runs until one of the functions
* returns something other than OK or DECLINE.
*
* @param ns The namespace prefix of the hook functions
* @param link The linkage declaration prefix of the hook
* @param ret The type of the return value of the hook
* @param ret The type of the return value of the hook
* @param name The name of the hook
* @param args_decl The declaration of the arguments for the hook
* @param args_use The names for the arguments for the hook
* @param ok Success value
* @param decline Decline value
*/
#define APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ns,link,ret,name,args_decl,args_use,ok,decline) \
link##_DECLARE(ret) ns##_run_##name args_decl \
{ \
ns##_LINK_##name##_t *pHook; \
int n; \
ret rv; \
apr_array_header_t *pHookArray=apr_optional_hook_get(#name); \
\
if(!pHookArray) \
return ok; \
\
pHook=(ns##_LINK_##name##_t *)pHookArray->elts; \
for(n=0 ; n < pHookArray->nelts ; ++n) \
{ \
rv=(pHook[n].pFunc)args_use; \
\
if(rv != ok && rv != decline) \
return rv; \
} \
return ok; \
}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* APR_OPTIONAL_HOOK_H */

View File

@@ -0,0 +1,255 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_POLL_H
#define APR_POLL_H
/**
* @file apr_poll.h
* @brief APR Poll interface
*/
#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_inherit.h"
#include "apr_file_io.h"
#include "apr_network_io.h"
#if APR_HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_poll Poll Routines
* @ingroup APR
* @{
*/
/**
* Poll options
*/
#define APR_POLLIN 0x001 /**< Can read without blocking */
#define APR_POLLPRI 0x002 /**< Priority data available */
#define APR_POLLOUT 0x004 /**< Can write without blocking */
#define APR_POLLERR 0x010 /**< Pending error */
#define APR_POLLHUP 0x020 /**< Hangup occurred */
#define APR_POLLNVAL 0x040 /**< Descriptior invalid */
/**
* Pollset Flags
*/
#define APR_POLLSET_THREADSAFE 0x001 /**< Adding or Removing a Descriptor is thread safe */
#define APR_POLLSET_NOCOPY 0x002 /**< Descriptors passed to apr_pollset_create() are not copied */
/** Used in apr_pollfd_t to determine what the apr_descriptor is */
typedef enum {
APR_NO_DESC, /**< nothing here */
APR_POLL_SOCKET, /**< descriptor refers to a socket */
APR_POLL_FILE, /**< descriptor refers to a file */
APR_POLL_LASTDESC /**< @deprecated descriptor is the last one in the list */
} apr_datatype_e ;
/** Union of either an APR file or socket. */
typedef union {
apr_file_t *f; /**< file */
apr_socket_t *s; /**< socket */
} apr_descriptor;
/** @see apr_pollfd_t */
typedef struct apr_pollfd_t apr_pollfd_t;
/** Poll descriptor set. */
struct apr_pollfd_t {
apr_pool_t *p; /**< associated pool */
apr_datatype_e desc_type; /**< descriptor type */
apr_int16_t reqevents; /**< requested events */
apr_int16_t rtnevents; /**< returned events */
apr_descriptor desc; /**< @see apr_descriptor */
void *client_data; /**< allows app to associate context */
};
/* General-purpose poll API for arbitrarily large numbers of
* file descriptors
*/
/** Opaque structure used for pollset API */
typedef struct apr_pollset_t apr_pollset_t;
/**
* Setup a pollset object
* @param pollset The pointer in which to return the newly created object
* @param size The maximum number of descriptors that this pollset can hold
* @param p The pool from which to allocate the pollset
* @param flags Optional flags to modify the operation of the pollset.
*
* @remark If flags equals APR_POLLSET_THREADSAFE, then a pollset is
* created on which it is safe to make concurrent calls to
* apr_pollset_add(), apr_pollset_remove() and apr_pollset_poll() from
* separate threads. This feature is only supported on some
* platforms; the apr_pollset_create() call will fail with
* APR_ENOTIMPL on platforms where it is not supported.
*/
APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
apr_uint32_t size,
apr_pool_t *p,
apr_uint32_t flags);
/**
* Destroy a pollset object
* @param pollset The pollset to destroy
*/
APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset);
/**
* Add a socket or file descriptor to a pollset
* @param pollset The pollset to which to add the descriptor
* @param descriptor The descriptor to add
* @remark If you set client_data in the descriptor, that value
* will be returned in the client_data field whenever this
* descriptor is signalled in apr_pollset_poll().
* @remark If the pollset has been created with APR_POLLSET_THREADSAFE
* and thread T1 is blocked in a call to apr_pollset_poll() for
* this same pollset that is being modified via apr_pollset_add()
* in thread T2, the currently executing apr_pollset_poll() call in
* T1 will either: (1) automatically include the newly added descriptor
* in the set of descriptors it is watching or (2) return immediately
* with APR_EINTR. Option (1) is recommended, but option (2) is
* allowed for implementations where option (1) is impossible
* or impractical.
*/
APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
const apr_pollfd_t *descriptor);
/**
* Remove a descriptor from a pollset
* @param pollset The pollset from which to remove the descriptor
* @param descriptor The descriptor to remove
* @remark If the pollset has been created with APR_POLLSET_THREADSAFE
* and thread T1 is blocked in a call to apr_pollset_poll() for
* this same pollset that is being modified via apr_pollset_remove()
* in thread T2, the currently executing apr_pollset_poll() call in
* T1 will either: (1) automatically exclude the newly added descriptor
* in the set of descriptors it is watching or (2) return immediately
* with APR_EINTR. Option (1) is recommended, but option (2) is
* allowed for implementations where option (1) is impossible
* or impractical.
*/
APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
const apr_pollfd_t *descriptor);
/**
* Block for activity on the descriptor(s) in a pollset
* @param pollset The pollset to use
* @param timeout Timeout in microseconds
* @param num Number of signalled descriptors (output parameter)
* @param descriptors Array of signalled descriptors (output parameter)
*/
APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset,
apr_interval_time_t timeout,
apr_int32_t *num,
const apr_pollfd_t **descriptors);
/**
* Poll the descriptors in the poll structure
* @param aprset The poll structure we will be using.
* @param numsock The number of descriptors we are polling
* @param nsds The number of descriptors signalled (output parameter)
* @param timeout The amount of time in microseconds to wait. This is
* a maximum, not a minimum. If a descriptor is signalled, we
* will wake up before this time. A negative number means
* wait until a descriptor is signalled.
* @remark The number of descriptors signalled is returned in the third argument.
* This is a blocking call, and it will not return until either a
* descriptor has been signalled, or the timeout has expired.
* @remark The rtnevents field in the apr_pollfd_t array will only be filled-
* in if the return value is APR_SUCCESS.
*/
APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t numsock,
apr_int32_t *nsds,
apr_interval_time_t timeout);
/** Opaque structure used for pollset API */
typedef struct apr_pollcb_t apr_pollcb_t;
/**
* Setup a pollcb object
* @param pollcb The pointer in which to return the newly created object
* @param size The maximum number of descriptors that a single _poll can return.
* @param p The pool from which to allocate the pollcb
* @param flags Optional flags to modify the operation of the pollcb.
*
* @remark Pollcb is only supported on some platforms; the apr_pollcb_create()
* call will fail with APR_ENOTIMPL on platforms where it is not supported.
*/
APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb,
apr_uint32_t size,
apr_pool_t *pool,
apr_uint32_t flags);
/**
* Add a socket or file descriptor to a pollcb
* @param pollcb The pollcb to which to add the descriptor
* @param descriptor The descriptor to add
* @remark If you set client_data in the descriptor, that value
* will be returned in the client_data field whenever this
* descriptor is signalled in apr_pollcb_poll().
* @remark Unlike the apr_pollset API, the descriptor is not copied, and users
* must retain the memory used by descriptor, as the same pointer will be
* returned to them from apr_pollcb_poll.
*/
APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
apr_pollfd_t *descriptor);
/**
* Remove a descriptor from a pollcb
* @param pollcb The pollcb from which to remove the descriptor
* @param descriptor The descriptor to remove
*/
APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
apr_pollfd_t *descriptor);
/** Function prototype for pollcb handlers
* @param baton Opaque baton passed into apr_pollcb_poll
* @param descriptor Contains the notification for an active descriptor,
* the rtnevents member contains what events were triggered
* for this descriptor.
*/
typedef apr_status_t (*apr_pollcb_cb_t)(void *baton, apr_pollfd_t *descriptor);
/**
* Block for activity on the descriptor(s) in a pollcb
* @param pollcb The pollcb to use
* @param timeout Timeout in microseconds
* @param func Callback function to call for each active socket
* @param baton Opaque baton passed to the callback function.
*/
APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb,
apr_interval_time_t timeout,
apr_pollcb_cb_t func,
void *baton);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ! APR_POLL_H */

View File

@@ -0,0 +1,741 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_POOLS_H
#define APR_POOLS_H
/**
* @file apr_pools.h
* @brief APR memory allocation
*
* Resource allocation routines...
*
* designed so that we don't have to keep track of EVERYTHING so that
* it can be explicitly freed later (a fundamentally unsound strategy ---
* particularly in the presence of die()).
*
* Instead, we maintain pools, and allocate items (both memory and I/O
* handlers) from the pools --- currently there are two, one for per
* transaction info, and one for config info. When a transaction is over,
* we can delete everything in the per-transaction apr_pool_t without fear,
* and without thinking too hard about it either.
*/
#include "apr.h"
#include "apr_errno.h"
#include "apr_general.h" /* for APR_STRINGIFY */
#define APR_WANT_MEMFUNC /**< for no good reason? */
#include "apr_want.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup apr_pools Memory Pool Functions
* @ingroup APR
* @{
*/
/** The fundamental pool type */
typedef struct apr_pool_t apr_pool_t;
/**
* Declaration helper macro to construct apr_foo_pool_get()s.
*
* This standardized macro is used by opaque (APR) data types to return
* the apr_pool_t that is associated with the data type.
*
* APR_POOL_DECLARE_ACCESSOR() is used in a header file to declare the
* accessor function. A typical usage and result would be:
* <pre>
* APR_POOL_DECLARE_ACCESSOR(file);
* becomes:
* APR_DECLARE(apr_pool_t *) apr_file_pool_get(apr_file_t *ob);
* </pre>
* @remark Doxygen unwraps this macro (via doxygen.conf) to provide
* actual help for each specific occurance of apr_foo_pool_get.
* @remark the linkage is specified for APR. It would be possible to expand
* the macros to support other linkages.
*/
#define APR_POOL_DECLARE_ACCESSOR(type) \
APR_DECLARE(apr_pool_t *) apr_##type##_pool_get \
(const apr_##type##_t *the##type)
/**
* Implementation helper macro to provide apr_foo_pool_get()s.
*
* In the implementation, the APR_POOL_IMPLEMENT_ACCESSOR() is used to
* actually define the function. It assumes the field is named "pool".
*/
#define APR_POOL_IMPLEMENT_ACCESSOR(type) \
APR_DECLARE(apr_pool_t *) apr_##type##_pool_get \
(const apr_##type##_t *the##type) \
{ return the##type->pool; }
/**
* Pool debug levels
*
* <pre>
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
* ---------------------------------
* | | | | | | | | x | General debug code enabled (useful in
* combination with --with-efence).
*
* | | | | | | | x | | Verbose output on stderr (report
* CREATE, CLEAR, DESTROY).
*
* | | | | x | | | | | Verbose output on stderr (report
* PALLOC, PCALLOC).
*
* | | | | | | x | | | Lifetime checking. On each use of a
* pool, check its lifetime. If the pool
* is out of scope, abort().
* In combination with the verbose flag
* above, it will output LIFE in such an
* event prior to aborting.
*
* | | | | | x | | | | Pool owner checking. On each use of a
* pool, check if the current thread is the
* pools owner. If not, abort(). In
* combination with the verbose flag above,
* it will output OWNER in such an event
* prior to aborting. Use the debug
* function apr_pool_owner_set() to switch
* a pools ownership.
*
* When no debug level was specified, assume general debug mode.
* If level 0 was specified, debugging is switched off
* </pre>
*/
#if defined(APR_POOL_DEBUG)
/* If APR_POOL_DEBUG is blank, we get 1; if it is a number, we get -1. */
#if (APR_POOL_DEBUG - APR_POOL_DEBUG -1 == 1)
#undef APR_POOL_DEBUG
#define APR_POOL_DEBUG 1
#endif
#else
#define APR_POOL_DEBUG 0
#endif
/** the place in the code where the particular function was called */
#define APR_POOL__FILE_LINE__ __FILE__ ":" APR_STRINGIFY(__LINE__)
/** A function that is called when allocation fails. */
typedef int (*apr_abortfunc_t)(int retcode);
/*
* APR memory structure manipulators (pools, tables, and arrays).
*/
/*
* Initialization
*/
/**
* Setup all of the internal structures required to use pools
* @remark Programs do NOT need to call this directly. APR will call this
* automatically from apr_initialize.
* @internal
*/
APR_DECLARE(apr_status_t) apr_pool_initialize(void);
/**
* Tear down all of the internal structures required to use pools
* @remark Programs do NOT need to call this directly. APR will call this
* automatically from apr_terminate.
* @internal
*/
APR_DECLARE(void) apr_pool_terminate(void);
/*
* Pool creation/destruction
*/
#include "apr_allocator.h"
/**
* Create a new pool.
* @param newpool The pool we have just created.
* @param parent The parent pool. If this is NULL, the new pool is a root
* pool. If it is non-NULL, the new pool will inherit all
* of its parent pool's attributes, except the apr_pool_t will
* be a sub-pool.
* @param abort_fn A function to use if the pool cannot allocate more memory.
* @param allocator The allocator to use with the new pool. If NULL the
* allocator of the parent pool will be used.
*/
APR_DECLARE(apr_status_t) apr_pool_create_ex(apr_pool_t **newpool,
apr_pool_t *parent,
apr_abortfunc_t abort_fn,
apr_allocator_t *allocator);
/**
* Create a new pool.
* @param newpool The pool we have just created.
* @param abort_fn A function to use if the pool cannot allocate more memory.
* @param allocator The allocator to use with the new pool. If NULL the
* new allocator will be crated with newpool as owner.
*/
APR_DECLARE(apr_status_t) apr_pool_create_core_ex(apr_pool_t **newpool,
apr_abortfunc_t abort_fn,
apr_allocator_t *allocator);
/**
* Debug version of apr_pool_create_ex.
* @param newpool @see apr_pool_create.
* @param parent @see apr_pool_create.
* @param abort_fn @see apr_pool_create.
* @param allocator @see apr_pool_create.
* @param file_line Where the function is called from.
* This is usually APR_POOL__FILE_LINE__.
* @remark Only available when APR_POOL_DEBUG is defined.
* Call this directly if you have you apr_pool_create_ex
* calls in a wrapper function and wish to override
* the file_line argument to reflect the caller of
* your wrapper function. If you do not have
* apr_pool_create_ex in a wrapper, trust the macro
* and don't call apr_pool_create_ex_debug directly.
*/
APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool,
apr_pool_t *parent,
apr_abortfunc_t abort_fn,
apr_allocator_t *allocator,
const char *file_line);
#if APR_POOL_DEBUG
#define apr_pool_create_ex(newpool, parent, abort_fn, allocator) \
apr_pool_create_ex_debug(newpool, parent, abort_fn, allocator, \
APR_POOL__FILE_LINE__)
#endif
/**
* Debug version of apr_pool_create_core_ex.
* @param newpool @see apr_pool_create.
* @param abort_fn @see apr_pool_create.
* @param allocator @see apr_pool_create.
* @param file_line Where the function is called from.
* This is usually APR_POOL__FILE_LINE__.
* @remark Only available when APR_POOL_DEBUG is defined.
* Call this directly if you have you apr_pool_create_core_ex
* calls in a wrapper function and wish to override
* the file_line argument to reflect the caller of
* your wrapper function. If you do not have
* apr_pool_create_core_ex in a wrapper, trust the macro
* and don't call apr_pool_create_core_ex_debug directly.
*/
APR_DECLARE(apr_status_t) apr_pool_create_core_ex_debug(apr_pool_t **newpool,
apr_abortfunc_t abort_fn,
apr_allocator_t *allocator,
const char *file_line);
#if APR_POOL_DEBUG
#define apr_pool_create_core_ex(newpool, abort_fn, allocator) \
apr_pool_create_core_ex_debug(newpool, abort_fn, allocator, \
APR_POOL__FILE_LINE__)
#endif
/**
* Create a new pool.
* @param newpool The pool we have just created.
* @param parent The parent pool. If this is NULL, the new pool is a root
* pool. If it is non-NULL, the new pool will inherit all
* of its parent pool's attributes, except the apr_pool_t will
* be a sub-pool.
*/
#if defined(DOXYGEN)
APR_DECLARE(apr_status_t) apr_pool_create(apr_pool_t **newpool,
apr_pool_t *parent);
#else
#if APR_POOL_DEBUG
#define apr_pool_create(newpool, parent) \
apr_pool_create_ex_debug(newpool, parent, NULL, NULL, \
APR_POOL__FILE_LINE__)
#else
#define apr_pool_create(newpool, parent) \
apr_pool_create_ex(newpool, parent, NULL, NULL)
#endif
#endif
/**
* Create a new pool.
* @param newpool The pool we have just created.
*/
#if defined(DOXYGEN)
APR_DECLARE(apr_status_t) apr_pool_create_core(apr_pool_t **newpool);
#else
#if APR_POOL_DEBUG
#define apr_pool_create_core(newpool) \
apr_pool_create_core_ex_debug(newpool, NULL, NULL, \
APR_POOL__FILE_LINE__)
#else
#define apr_pool_create_core(newpool) \
apr_pool_create_core_ex(newpool, NULL, NULL)
#endif
#endif
/**
* Find the pools allocator
* @param pool The pool to get the allocator from.
*/
APR_DECLARE(apr_allocator_t *) apr_pool_allocator_get(apr_pool_t *pool);
/**
* Clear all memory in the pool and run all the cleanups. This also destroys all
* subpools.
* @param p The pool to clear
* @remark This does not actually free the memory, it just allows the pool
* to re-use this memory for the next allocation.
* @see apr_pool_destroy()
*/
APR_DECLARE(void) apr_pool_clear(apr_pool_t *p);
/**
* Debug version of apr_pool_clear.
* @param p See: apr_pool_clear.
* @param file_line Where the function is called from.
* This is usually APR_POOL__FILE_LINE__.
* @remark Only available when APR_POOL_DEBUG is defined.
* Call this directly if you have you apr_pool_clear
* calls in a wrapper function and wish to override
* the file_line argument to reflect the caller of
* your wrapper function. If you do not have
* apr_pool_clear in a wrapper, trust the macro
* and don't call apr_pool_destroy_clear directly.
*/
APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *p,
const char *file_line);
#if APR_POOL_DEBUG
#define apr_pool_clear(p) \
apr_pool_clear_debug(p, APR_POOL__FILE_LINE__)
#endif
/**
* Destroy the pool. This takes similar action as apr_pool_clear() and then
* frees all the memory.
* @param p The pool to destroy
* @remark This will actually free the memory
*/
APR_DECLARE(void) apr_pool_destroy(apr_pool_t *p);
/**
* Debug version of apr_pool_destroy.
* @param p See: apr_pool_destroy.
* @param file_line Where the function is called from.
* This is usually APR_POOL__FILE_LINE__.
* @remark Only available when APR_POOL_DEBUG is defined.
* Call this directly if you have you apr_pool_destroy
* calls in a wrapper function and wish to override
* the file_line argument to reflect the caller of
* your wrapper function. If you do not have
* apr_pool_destroy in a wrapper, trust the macro
* and don't call apr_pool_destroy_debug directly.
*/
APR_DECLARE(void) apr_pool_destroy_debug(apr_pool_t *p,
const char *file_line);
#if APR_POOL_DEBUG
#define apr_pool_destroy(p) \
apr_pool_destroy_debug(p, APR_POOL__FILE_LINE__)
#endif
/*
* Memory allocation
*/
/**
* Allocate a block of memory from a pool
* @param p The pool to allocate from
* @param size The amount of memory to allocate
* @return The allocated memory
*/
APR_DECLARE(void *) apr_palloc(apr_pool_t *p, apr_size_t size);
/**
* Debug version of apr_palloc
* @param p See: apr_palloc
* @param size See: apr_palloc
* @param file_line Where the function is called from.
* This is usually APR_POOL__FILE_LINE__.
* @return See: apr_palloc
*/
APR_DECLARE(void *) apr_palloc_debug(apr_pool_t *p, apr_size_t size,
const char *file_line);
#if APR_POOL_DEBUG
#define apr_palloc(p, size) \
apr_palloc_debug(p, size, APR_POOL__FILE_LINE__)
#endif
/**
* Allocate a block of memory from a pool and set all of the memory to 0
* @param p The pool to allocate from
* @param size The amount of memory to allocate
* @return The allocated memory
*/
#if defined(DOXYGEN)
APR_DECLARE(void *) apr_pcalloc(apr_pool_t *p, apr_size_t size);
#elif !APR_POOL_DEBUG
#define apr_pcalloc(p, size) memset(apr_palloc(p, size), 0, size)
#endif
/**
* Debug version of apr_pcalloc
* @param p See: apr_pcalloc
* @param size See: apr_pcalloc
* @param file_line Where the function is called from.
* This is usually APR_POOL__FILE_LINE__.
* @return See: apr_pcalloc
*/
APR_DECLARE(void *) apr_pcalloc_debug(apr_pool_t *p, apr_size_t size,
const char *file_line);
#if APR_POOL_DEBUG
#define apr_pcalloc(p, size) \
apr_pcalloc_debug(p, size, APR_POOL__FILE_LINE__)
#endif
/*
* Pool Properties
*/
/**
* Set the function to be called when an allocation failure occurs.
* @remark If the program wants APR to exit on a memory allocation error,
* then this function can be called to set the callback to use (for
* performing cleanup and then exiting). If this function is not called,
* then APR will return an error and expect the calling program to
* deal with the error accordingly.
*/
APR_DECLARE(void) apr_pool_abort_set(apr_abortfunc_t abortfunc,
apr_pool_t *pool);
/**
* Get the abort function associated with the specified pool.
* @param pool The pool for retrieving the abort function.
* @return The abort function for the given pool.
*/
APR_DECLARE(apr_abortfunc_t) apr_pool_abort_get(apr_pool_t *pool);
/**
* Get the parent pool of the specified pool.
* @param pool The pool for retrieving the parent pool.
* @return The parent of the given pool.
*/
APR_DECLARE(apr_pool_t *) apr_pool_parent_get(apr_pool_t *pool);
/**
* Determine if pool a is an ancestor of pool b.
* @param a The pool to search
* @param b The pool to search for
* @return True if a is an ancestor of b, NULL is considered an ancestor
* of all pools.
* @remark if compiled with APR_POOL_DEBUG, this function will also
* return true if A is a pool which has been guaranteed by the caller
* (using apr_pool_join) to have a lifetime at least as long as some
* ancestor of pool B.
*/
APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b);
/**
* Tag a pool (give it a name)
* @param pool The pool to tag
* @param tag The tag
*/
APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag);
/*
* User data management
*/
/**
* Set the data associated with the current pool
* @param data The user data associated with the pool.
* @param key The key to use for association
* @param cleanup The cleanup program to use to cleanup the data (NULL if none)
* @param pool The current pool
* @warning The data to be attached to the pool should have a life span
* at least as long as the pool it is being attached to.
*
* Users of APR must take EXTREME care when choosing a key to
* use for their data. It is possible to accidentally overwrite
* data by choosing a key that another part of the program is using.
* Therefore it is advised that steps are taken to ensure that unique
* keys are used for all of the userdata objects in a particular pool
* (the same key in two different pools or a pool and one of its
* subpools is okay) at all times. Careful namespace prefixing of
* key names is a typical way to help ensure this uniqueness.
*
*/
APR_DECLARE(apr_status_t) apr_pool_userdata_set(
const void *data,
const char *key,
apr_status_t (*cleanup)(void *),
apr_pool_t *pool);
/**
* Set the data associated with the current pool
* @param data The user data associated with the pool.
* @param key The key to use for association
* @param cleanup The cleanup program to use to cleanup the data (NULL if none)
* @param pool The current pool
* @note same as apr_pool_userdata_set(), except that this version doesn't
* make a copy of the key (this function is useful, for example, when
* the key is a string literal)
* @warning This should NOT be used if the key could change addresses by
* any means between the apr_pool_userdata_setn() call and a
* subsequent apr_pool_userdata_get() on that key, such as if a
* static string is used as a userdata key in a DSO and the DSO could
* be unloaded and reloaded between the _setn() and the _get(). You
* MUST use apr_pool_userdata_set() in such cases.
* @warning More generally, the key and the data to be attached to the
* pool should have a life span at least as long as the pool itself.
*
*/
APR_DECLARE(apr_status_t) apr_pool_userdata_setn(
const void *data,
const char *key,
apr_status_t (*cleanup)(void *),
apr_pool_t *pool);
/**
* Return the data associated with the current pool.
* @param data The user data associated with the pool.
* @param key The key for the data to retrieve
* @param pool The current pool.
*/
APR_DECLARE(apr_status_t) apr_pool_userdata_get(void **data, const char *key,
apr_pool_t *pool);
/**
* @defgroup PoolCleanup Pool Cleanup Functions
*
* Cleanups are performed in the reverse order they were registered. That is:
* Last In, First Out. A cleanup function can safely allocate memory from
* the pool that is being cleaned up. It can also safely register additional
* cleanups which will be run LIFO, directly after the current cleanup
* terminates. Cleanups have to take caution in calling functions that
* create subpools. Subpools, created during cleanup will NOT automatically
* be cleaned up. In other words, cleanups are to clean up after themselves.
*
* @{
*/
/**
* Register a function to be called when a pool is cleared or destroyed
* @param p The pool register the cleanup with
* @param data The data to pass to the cleanup function.
* @param plain_cleanup The function to call when the pool is cleared
* or destroyed
* @param child_cleanup The function to call when a child process is about
* to exec - this function is called in the child, obviously!
*/
APR_DECLARE(void) apr_pool_cleanup_register(
apr_pool_t *p,
const void *data,
apr_status_t (*plain_cleanup)(void *),
apr_status_t (*child_cleanup)(void *));
/**
* Register a function to be called when a pool is cleared or destroyed.
*
* Unlike apr_pool_cleanup_register which register a cleanup
* that is called AFTER all subpools are destroyed this function register
* a function that will be called before any of the subpool is destoryed.
*
* @param p The pool register the cleanup with
* @param data The data to pass to the cleanup function.
* @param plain_cleanup The function to call when the pool is cleared
* or destroyed
*/
APR_DECLARE(void) apr_pool_pre_cleanup_register(
apr_pool_t *p,
const void *data,
apr_status_t (*plain_cleanup)(void *));
/**
* Remove a previously registered cleanup function.
*
* The cleanup most recently registered with @a p having the same values of
* @a data and @a cleanup will be removed.
*
* @param p The pool to remove the cleanup from
* @param data The data of the registered cleanup
* @param cleanup The function to remove from cleanup
* @remarks For some strange reason only the plain_cleanup is handled by this
* function
*/
APR_DECLARE(void) apr_pool_cleanup_kill(apr_pool_t *p, const void *data,
apr_status_t (*cleanup)(void *));
/**
* Replace the child cleanup function of a previously registered cleanup.
*
* The cleanup most recently registered with @a p having the same values of
* @a data and @a plain_cleanup will have the registered child cleanup
* function replaced with @a child_cleanup.
*
* @param p The pool of the registered cleanup
* @param data The data of the registered cleanup
* @param plain_cleanup The plain cleanup function of the registered cleanup
* @param child_cleanup The function to register as the child cleanup
*/
APR_DECLARE(void) apr_pool_child_cleanup_set(
apr_pool_t *p,
const void *data,
apr_status_t (*plain_cleanup)(void *),
apr_status_t (*child_cleanup)(void *));
/**
* Run the specified cleanup function immediately and unregister it.
*
* The cleanup most recently registered with @a p having the same values of
* @a data and @a cleanup will be removed and @a cleanup will be called
* with @a data as the argument.
*
* @param p The pool to remove the cleanup from
* @param data The data to remove from cleanup
* @param cleanup The function to remove from cleanup
*/
APR_DECLARE(apr_status_t) apr_pool_cleanup_run(
apr_pool_t *p,
void *data,
apr_status_t (*cleanup)(void *));
/**
* An empty cleanup function.
*
* Passed to apr_pool_cleanup_register() when no cleanup is required.
*
* @param data The data to cleanup, will not be used by this function.
*/
APR_DECLARE_NONSTD(apr_status_t) apr_pool_cleanup_null(void *data);
/**
* Run all registered child cleanups, in preparation for an exec()
* call in a forked child -- close files, etc., but *don't* flush I/O
* buffers, *don't* wait for subprocesses, and *don't* free any
* memory.
*/
APR_DECLARE(void) apr_pool_cleanup_for_exec(void);
/** @} */
/**
* @defgroup PoolDebug Pool Debugging functions.
*
* pools have nested lifetimes -- sub_pools are destroyed when the
* parent pool is cleared. We allow certain liberties with operations
* on things such as tables (and on other structures in a more general
* sense) where we allow the caller to insert values into a table which
* were not allocated from the table's pool. The table's data will
* remain valid as long as all the pools from which its values are
* allocated remain valid.
*
* For example, if B is a sub pool of A, and you build a table T in
* pool B, then it's safe to insert data allocated in A or B into T
* (because B lives at most as long as A does, and T is destroyed when
* B is cleared/destroyed). On the other hand, if S is a table in
* pool A, it is safe to insert data allocated in A into S, but it
* is *not safe* to insert data allocated from B into S... because
* B can be cleared/destroyed before A is (which would leave dangling
* pointers in T's data structures).
*
* In general we say that it is safe to insert data into a table T
* if the data is allocated in any ancestor of T's pool. This is the
* basis on which the APR_POOL_DEBUG code works -- it tests these ancestor
* relationships for all data inserted into tables. APR_POOL_DEBUG also
* provides tools (apr_pool_find, and apr_pool_is_ancestor) for other
* folks to implement similar restrictions for their own data
* structures.
*
* However, sometimes this ancestor requirement is inconvenient --
* sometimes it's necessary to create a sub pool where the sub pool is
* guaranteed to have the same lifetime as the parent pool. This is a
* guarantee implemented by the *caller*, not by the pool code. That
* is, the caller guarantees they won't destroy the sub pool
* individually prior to destroying the parent pool.
*
* In this case the caller must call apr_pool_join() to indicate this
* guarantee to the APR_POOL_DEBUG code.
*
* These functions are only implemented when #APR_POOL_DEBUG is set.
*
* @{
*/
#if APR_POOL_DEBUG || defined(DOXYGEN)
/**
* Guarantee that a subpool has the same lifetime as the parent.
* @param p The parent pool
* @param sub The subpool
*/
APR_DECLARE(void) apr_pool_join(apr_pool_t *p, apr_pool_t *sub);
/**
* Find a pool from something allocated in it.
* @param mem The thing allocated in the pool
* @return The pool it is allocated in
*/
APR_DECLARE(apr_pool_t *) apr_pool_find(const void *mem);
/**
* Report the number of bytes currently in the pool
* @param p The pool to inspect
* @param recurse Recurse/include the subpools' sizes
* @return The number of bytes
*/
APR_DECLARE(apr_size_t) apr_pool_num_bytes(apr_pool_t *p, int recurse);
/**
* Lock a pool
* @param pool The pool to lock
* @param flag The flag
*/
APR_DECLARE(void) apr_pool_lock(apr_pool_t *pool, int flag);
/* @} */
#else /* APR_POOL_DEBUG or DOXYGEN */
#ifdef apr_pool_join
#undef apr_pool_join
#endif
#define apr_pool_join(a,b)
#ifdef apr_pool_lock
#undef apr_pool_lock
#endif
#define apr_pool_lock(pool, lock)
#endif /* APR_POOL_DEBUG or DOXYGEN */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !APR_POOLS_H */

View File

@@ -0,0 +1,506 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* This header file is where you should put ANY platform specific information.
* This should be the only header file that programs need to include that
* actually has platform dependant code which refers to the .
*/
#ifndef APR_PORTABLE_H
#define APR_PORTABLE_H
/**
* @file apr_portable.h
* @brief APR Portability Routines
*/
#include "apr.h"
#include "apr_pools.h"
#include "apr_thread_proc.h"
#include "apr_file_io.h"
#include "apr_network_io.h"
#include "apr_errno.h"
#include "apr_global_mutex.h"
#include "apr_proc_mutex.h"
#include "apr_time.h"
#include "apr_dso.h"
#include "apr_shm.h"
#if APR_HAVE_DIRENT_H
#include <dirent.h>
#endif
#if APR_HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if APR_HAVE_PTHREAD_H
#include <pthread.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_portabile Portability Routines
* @ingroup APR
* @{
*/
#ifdef WIN32
/* The primitives for Windows types */
typedef HANDLE apr_os_file_t;
typedef HANDLE apr_os_dir_t;
typedef SOCKET apr_os_sock_t;
typedef HANDLE apr_os_proc_mutex_t;
typedef HANDLE apr_os_thread_t;
typedef HANDLE apr_os_proc_t;
typedef DWORD apr_os_threadkey_t;
typedef FILETIME apr_os_imp_time_t;
typedef SYSTEMTIME apr_os_exp_time_t;
typedef HANDLE apr_os_dso_handle_t;
typedef HANDLE apr_os_shm_t;
#elif defined(OS2)
typedef HFILE apr_os_file_t;
typedef HDIR apr_os_dir_t;
typedef int apr_os_sock_t;
typedef HMTX apr_os_proc_mutex_t;
typedef TID apr_os_thread_t;
typedef PID apr_os_proc_t;
typedef PULONG apr_os_threadkey_t;
typedef struct timeval apr_os_imp_time_t;
typedef struct tm apr_os_exp_time_t;
typedef HMODULE apr_os_dso_handle_t;
typedef void* apr_os_shm_t;
#elif defined(__BEOS__)
#include <kernel/OS.h>
#include <kernel/image.h>
struct apr_os_proc_mutex_t {
sem_id sem;
int32 ben;
};
typedef int apr_os_file_t;
typedef DIR apr_os_dir_t;
typedef int apr_os_sock_t;
typedef struct apr_os_proc_mutex_t apr_os_proc_mutex_t;
typedef thread_id apr_os_thread_t;
typedef thread_id apr_os_proc_t;
typedef int apr_os_threadkey_t;
typedef struct timeval apr_os_imp_time_t;
typedef struct tm apr_os_exp_time_t;
typedef image_id apr_os_dso_handle_t;
typedef void* apr_os_shm_t;
#elif defined(NETWARE)
typedef int apr_os_file_t;
typedef DIR apr_os_dir_t;
typedef int apr_os_sock_t;
typedef NXMutex_t apr_os_proc_mutex_t;
typedef NXThreadId_t apr_os_thread_t;
typedef long apr_os_proc_t;
typedef NXKey_t apr_os_threadkey_t;
typedef struct timeval apr_os_imp_time_t;
typedef struct tm apr_os_exp_time_t;
typedef void * apr_os_dso_handle_t;
typedef void* apr_os_shm_t;
#else
/* Any other OS should go above this one. This is the lowest common
* denominator typedefs for all UNIX-like systems. :)
*/
/** Basic OS process mutex structure. */
struct apr_os_proc_mutex_t {
#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
/** Value used for SYS V Semaphore, FCNTL and FLOCK serialization */
int crossproc;
#endif
#if APR_HAS_PROC_PTHREAD_SERIALIZE
/** Value used for PTHREAD serialization */
pthread_mutex_t *pthread_interproc;
#endif
#if APR_HAS_THREADS
/* If no threads, no need for thread locks */
#if APR_USE_PTHREAD_SERIALIZE
/** This value is currently unused within APR and Apache */
pthread_mutex_t *intraproc;
#endif
#endif
};
typedef int apr_os_file_t; /**< native file */
typedef DIR apr_os_dir_t; /**< native dir */
typedef int apr_os_sock_t; /**< native dir */
typedef struct apr_os_proc_mutex_t apr_os_proc_mutex_t; /**< native proces
* mutex
*/
#if APR_HAS_THREADS && APR_HAVE_PTHREAD_H
typedef pthread_t apr_os_thread_t; /**< native thread */
typedef pthread_key_t apr_os_threadkey_t; /**< native thread address
* space */
#endif
typedef pid_t apr_os_proc_t; /**< native pid */
typedef struct timeval apr_os_imp_time_t; /**< native timeval */
typedef struct tm apr_os_exp_time_t; /**< native tm */
/** @var apr_os_dso_handle_t
* native dso types
*/
#if defined(HPUX) || defined(HPUX10) || defined(HPUX11)
#include <dl.h>
typedef shl_t apr_os_dso_handle_t;
#elif defined(DARWIN)
#include <mach-o/dyld.h>
typedef NSModule apr_os_dso_handle_t;
#else
typedef void * apr_os_dso_handle_t;
#endif
typedef void* apr_os_shm_t; /**< native SHM */
#endif
/**
* @typedef apr_os_sock_info_t
* @brief alias for local OS socket
*/
/**
* everything APR needs to know about an active socket to construct
* an APR socket from it; currently, this is platform-independent
*/
struct apr_os_sock_info_t {
apr_os_sock_t *os_sock; /**< always required */
struct sockaddr *local; /**< NULL if not yet bound */
struct sockaddr *remote; /**< NULL if not connected */
int family; /**< always required (APR_INET, APR_INET6, etc.) */
int type; /**< always required (SOCK_STREAM, SOCK_DGRAM, etc.) */
int protocol; /**< 0 or actual protocol (APR_PROTO_SCTP, APR_PROTO_TCP, etc.) */
};
typedef struct apr_os_sock_info_t apr_os_sock_info_t;
#if APR_PROC_MUTEX_IS_GLOBAL || defined(DOXYGEN)
/** Opaque global mutex type */
#define apr_os_global_mutex_t apr_os_proc_mutex_t
/** @return apr_os_global_mutex */
#define apr_os_global_mutex_get apr_os_proc_mutex_get
#else
/** Thread and process mutex for those platforms where process mutexes
* are not held in threads.
*/
struct apr_os_global_mutex_t {
apr_pool_t *pool;
apr_proc_mutex_t *proc_mutex;
#if APR_HAS_THREADS
apr_thread_mutex_t *thread_mutex;
#endif /* APR_HAS_THREADS */
};
typedef struct apr_os_global_mutex_t apr_os_global_mutex_t;
APR_DECLARE(apr_status_t) apr_os_global_mutex_get(apr_os_global_mutex_t *ospmutex,
apr_global_mutex_t *pmutex);
#endif
/**
* convert the file from apr type to os specific type.
* @param thefile The os specific file we are converting to
* @param file The apr file to convert.
* @remark On Unix, it is only possible to get a file descriptor from
* an apr file type.
*/
APR_DECLARE(apr_status_t) apr_os_file_get(apr_os_file_t *thefile,
apr_file_t *file);
/**
* convert the dir from apr type to os specific type.
* @param thedir The os specific dir we are converting to
* @param dir The apr dir to convert.
*/
APR_DECLARE(apr_status_t) apr_os_dir_get(apr_os_dir_t **thedir,
apr_dir_t *dir);
/**
* Convert the socket from an apr type to an OS specific socket
* @param thesock The socket to convert.
* @param sock The os specifc equivelant of the apr socket..
*/
APR_DECLARE(apr_status_t) apr_os_sock_get(apr_os_sock_t *thesock,
apr_socket_t *sock);
/**
* Convert the proc mutex from os specific type to apr type
* @param ospmutex The os specific proc mutex we are converting to.
* @param pmutex The apr proc mutex to convert.
*/
APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(apr_os_proc_mutex_t *ospmutex,
apr_proc_mutex_t *pmutex);
/**
* Get the exploded time in the platforms native format.
* @param ostime the native time format
* @param aprtime the time to convert
*/
APR_DECLARE(apr_status_t) apr_os_exp_time_get(apr_os_exp_time_t **ostime,
apr_time_exp_t *aprtime);
/**
* Get the imploded time in the platforms native format.
* @param ostime the native time format
* @param aprtime the time to convert
*/
APR_DECLARE(apr_status_t) apr_os_imp_time_get(apr_os_imp_time_t **ostime,
apr_time_t *aprtime);
/**
* convert the shm from apr type to os specific type.
* @param osshm The os specific shm representation
* @param shm The apr shm to convert.
*/
APR_DECLARE(apr_status_t) apr_os_shm_get(apr_os_shm_t *osshm,
apr_shm_t *shm);
#if APR_HAS_THREADS || defined(DOXYGEN)
/**
* @defgroup apr_os_thread Thread portability Routines
* @{
*/
/**
* convert the thread to os specific type from apr type.
* @param thethd The apr thread to convert
* @param thd The os specific thread we are converting to
*/
APR_DECLARE(apr_status_t) apr_os_thread_get(apr_os_thread_t **thethd,
apr_thread_t *thd);
/**
* convert the thread private memory key to os specific type from an apr type.
* @param thekey The apr handle we are converting from.
* @param key The os specific handle we are converting to.
*/
APR_DECLARE(apr_status_t) apr_os_threadkey_get(apr_os_threadkey_t *thekey,
apr_threadkey_t *key);
/**
* convert the thread from os specific type to apr type.
* @param thd The apr thread we are converting to.
* @param thethd The os specific thread to convert
* @param cont The pool to use if it is needed.
*/
APR_DECLARE(apr_status_t) apr_os_thread_put(apr_thread_t **thd,
apr_os_thread_t *thethd,
apr_pool_t *cont);
/**
* convert the thread private memory key from os specific type to apr type.
* @param key The apr handle we are converting to.
* @param thekey The os specific handle to convert
* @param cont The pool to use if it is needed.
*/
APR_DECLARE(apr_status_t) apr_os_threadkey_put(apr_threadkey_t **key,
apr_os_threadkey_t *thekey,
apr_pool_t *cont);
/**
* Get the thread ID
*/
APR_DECLARE(apr_os_thread_t) apr_os_thread_current(void);
/**
* Compare two thread id's
* @param tid1 1st Thread ID to compare
* @param tid2 2nd Thread ID to compare
*/
APR_DECLARE(int) apr_os_thread_equal(apr_os_thread_t tid1,
apr_os_thread_t tid2);
/** @} */
#endif /* APR_HAS_THREADS */
/**
* convert the file from os specific type to apr type.
* @param file The apr file we are converting to.
* @param thefile The os specific file to convert
* @param flags The flags that were used to open this file.
* @param cont The pool to use if it is needed.
* @remark On Unix, it is only possible to put a file descriptor into
* an apr file type.
*/
APR_DECLARE(apr_status_t) apr_os_file_put(apr_file_t **file,
apr_os_file_t *thefile,
apr_int32_t flags, apr_pool_t *cont);
/**
* convert the file from os specific type to apr type.
* @param file The apr file we are converting to.
* @param thefile The os specific pipe to convert
* @param cont The pool to use if it is needed.
* @remark On Unix, it is only possible to put a file descriptor into
* an apr file type.
*/
APR_DECLARE(apr_status_t) apr_os_pipe_put(apr_file_t **file,
apr_os_file_t *thefile,
apr_pool_t *cont);
/**
* convert the file from os specific type to apr type.
* @param file The apr file we are converting to.
* @param thefile The os specific pipe to convert
* @param register_cleanup A cleanup will be registered on the apr_file_t
* to issue apr_file_close().
* @param cont The pool to use if it is needed.
* @remark On Unix, it is only possible to put a file descriptor into
* an apr file type.
*/
APR_DECLARE(apr_status_t) apr_os_pipe_put_ex(apr_file_t **file,
apr_os_file_t *thefile,
int register_cleanup,
apr_pool_t *cont);
/**
* convert the dir from os specific type to apr type.
* @param dir The apr dir we are converting to.
* @param thedir The os specific dir to convert
* @param cont The pool to use when creating to apr directory.
*/
APR_DECLARE(apr_status_t) apr_os_dir_put(apr_dir_t **dir,
apr_os_dir_t *thedir,
apr_pool_t *cont);
/**
* Convert a socket from the os specific type to the apr type
* @param sock The pool to use.
* @param thesock The socket to convert to.
* @param cont The socket we are converting to an apr type.
* @remark If it is a true socket, it is best to call apr_os_sock_make()
* and provide APR with more information about the socket.
*/
APR_DECLARE(apr_status_t) apr_os_sock_put(apr_socket_t **sock,
apr_os_sock_t *thesock,
apr_pool_t *cont);
/**
* Create a socket from an existing descriptor and local and remote
* socket addresses.
* @param apr_sock The new socket that has been set up
* @param os_sock_info The os representation of the socket handle and
* other characteristics of the socket
* @param cont The pool to use
* @remark If you only know the descriptor/handle or if it isn't really
* a true socket, use apr_os_sock_put() instead.
*/
APR_DECLARE(apr_status_t) apr_os_sock_make(apr_socket_t **apr_sock,
apr_os_sock_info_t *os_sock_info,
apr_pool_t *cont);
/**
* Convert the proc mutex from os specific type to apr type
* @param pmutex The apr proc mutex we are converting to.
* @param ospmutex The os specific proc mutex to convert.
* @param cont The pool to use if it is needed.
*/
APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
apr_os_proc_mutex_t *ospmutex,
apr_pool_t *cont);
/**
* Put the imploded time in the APR format.
* @param aprtime the APR time format
* @param ostime the time to convert
* @param cont the pool to use if necessary
*/
APR_DECLARE(apr_status_t) apr_os_imp_time_put(apr_time_t *aprtime,
apr_os_imp_time_t **ostime,
apr_pool_t *cont);
/**
* Put the exploded time in the APR format.
* @param aprtime the APR time format
* @param ostime the time to convert
* @param cont the pool to use if necessary
*/
APR_DECLARE(apr_status_t) apr_os_exp_time_put(apr_time_exp_t *aprtime,
apr_os_exp_time_t **ostime,
apr_pool_t *cont);
/**
* convert the shared memory from os specific type to apr type.
* @param shm The apr shm representation of osshm
* @param osshm The os specific shm identity
* @param cont The pool to use if it is needed.
* @remark On fork()ed architectures, this is typically nothing more than
* the memory block mapped. On non-fork architectures, this is typically
* some internal handle to pass the mapping from process to process.
*/
APR_DECLARE(apr_status_t) apr_os_shm_put(apr_shm_t **shm,
apr_os_shm_t *osshm,
apr_pool_t *cont);
#if APR_HAS_DSO || defined(DOXYGEN)
/**
* @defgroup apr_os_dso DSO (Dynamic Loading) Portabiliity Routines
* @{
*/
/**
* convert the dso handle from os specific to apr
* @param dso The apr handle we are converting to
* @param thedso the os specific handle to convert
* @param pool the pool to use if it is needed
*/
APR_DECLARE(apr_status_t) apr_os_dso_handle_put(apr_dso_handle_t **dso,
apr_os_dso_handle_t thedso,
apr_pool_t *pool);
/**
* convert the apr dso handle into an os specific one
* @param aprdso The apr dso handle to convert
* @param dso The os specific dso to return
*/
APR_DECLARE(apr_status_t) apr_os_dso_handle_get(apr_os_dso_handle_t *dso,
apr_dso_handle_t *aprdso);
#if APR_HAS_OS_UUID
/**
* Private: apr-util's apr_uuid module when supported by the platform
*/
APR_DECLARE(apr_status_t) apr_os_uuid_get(unsigned char *uuid_data);
#endif
/** @} */
#endif /* APR_HAS_DSO */
/**
* Get the name of the system default characer set.
* @param pool the pool to allocate the name from, if needed
*/
APR_DECLARE(const char*) apr_os_default_encoding(apr_pool_t *pool);
/**
* Get the name of the current locale character set.
* @param pool the pool to allocate the name from, if needed
* @remark Defers to apr_os_default_encoding if the current locale's
* data can't be retreved on this system.
*/
APR_DECLARE(const char*) apr_os_locale_encoding(apr_pool_t *pool);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ! APR_PORTABLE_H */

View File

@@ -0,0 +1,166 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_PROC_MUTEX_H
#define APR_PROC_MUTEX_H
/**
* @file apr_proc_mutex.h
* @brief APR Process Locking Routines
*/
#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_proc_mutex Process Locking Routines
* @ingroup APR
* @{
*/
/**
* Enumerated potential types for APR process locking methods
* @warning Check APR_HAS_foo_SERIALIZE defines to see if the platform supports
* APR_LOCK_foo. Only APR_LOCK_DEFAULT is portable.
*/
typedef enum {
APR_LOCK_FCNTL, /**< fcntl() */
APR_LOCK_FLOCK, /**< flock() */
APR_LOCK_SYSVSEM, /**< System V Semaphores */
APR_LOCK_PROC_PTHREAD, /**< POSIX pthread process-based locking */
APR_LOCK_POSIXSEM, /**< POSIX semaphore process-based locking */
APR_LOCK_DEFAULT /**< Use the default process lock */
} apr_lockmech_e;
/** Opaque structure representing a process mutex. */
typedef struct apr_proc_mutex_t apr_proc_mutex_t;
/* Function definitions */
/**
* Create and initialize a mutex that can be used to synchronize processes.
* @param mutex the memory address where the newly created mutex will be
* stored.
* @param fname A file name to use if the lock mechanism requires one. This
* argument should always be provided. The lock code itself will
* determine if it should be used.
* @param mech The mechanism to use for the interprocess lock, if any; one of
* <PRE>
* APR_LOCK_FCNTL
* APR_LOCK_FLOCK
* APR_LOCK_SYSVSEM
* APR_LOCK_POSIXSEM
* APR_LOCK_PROC_PTHREAD
* APR_LOCK_DEFAULT pick the default mechanism for the platform
* </PRE>
* @param pool the pool from which to allocate the mutex.
* @see apr_lockmech_e
* @warning Check APR_HAS_foo_SERIALIZE defines to see if the platform supports
* APR_LOCK_foo. Only APR_LOCK_DEFAULT is portable.
*/
APR_DECLARE(apr_status_t) apr_proc_mutex_create(apr_proc_mutex_t **mutex,
const char *fname,
apr_lockmech_e mech,
apr_pool_t *pool);
/**
* Re-open a mutex in a child process.
* @param mutex The newly re-opened mutex structure.
* @param fname A file name to use if the mutex mechanism requires one. This
* argument should always be provided. The mutex code itself will
* determine if it should be used. This filename should be the
* same one that was passed to apr_proc_mutex_create().
* @param pool The pool to operate on.
* @remark This function must be called to maintain portability, even
* if the underlying lock mechanism does not require it.
*/
APR_DECLARE(apr_status_t) apr_proc_mutex_child_init(apr_proc_mutex_t **mutex,
const char *fname,
apr_pool_t *pool);
/**
* Acquire the lock for the given mutex. If the mutex is already locked,
* the current thread will be put to sleep until the lock becomes available.
* @param mutex the mutex on which to acquire the lock.
*/
APR_DECLARE(apr_status_t) apr_proc_mutex_lock(apr_proc_mutex_t *mutex);
/**
* Attempt to acquire the lock for the given mutex. If the mutex has already
* been acquired, the call returns immediately with APR_EBUSY. Note: it
* is important that the APR_STATUS_IS_EBUSY(s) macro be used to determine
* if the return value was APR_EBUSY, for portability reasons.
* @param mutex the mutex on which to attempt the lock acquiring.
*/
APR_DECLARE(apr_status_t) apr_proc_mutex_trylock(apr_proc_mutex_t *mutex);
/**
* Release the lock for the given mutex.
* @param mutex the mutex from which to release the lock.
*/
APR_DECLARE(apr_status_t) apr_proc_mutex_unlock(apr_proc_mutex_t *mutex);
/**
* Destroy the mutex and free the memory associated with the lock.
* @param mutex the mutex to destroy.
*/
APR_DECLARE(apr_status_t) apr_proc_mutex_destroy(apr_proc_mutex_t *mutex);
/**
* Destroy the mutex and free the memory associated with the lock.
* @param mutex the mutex to destroy.
* @note This function is generally used to kill a cleanup on an already
* created mutex
*/
APR_DECLARE(apr_status_t) apr_proc_mutex_cleanup(void *mutex);
/**
* Return the name of the lockfile for the mutex, or NULL
* if the mutex doesn't use a lock file
*/
APR_DECLARE(const char *) apr_proc_mutex_lockfile(apr_proc_mutex_t *mutex);
/**
* Display the name of the mutex, as it relates to the actual method used.
* This matches the valid options for Apache's AcceptMutex directive
* @param mutex the name of the mutex
*/
APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex);
/**
* Display the name of the default mutex: APR_LOCK_DEFAULT
*/
APR_DECLARE(const char *) apr_proc_mutex_defname(void);
/**
* Get the pool used by this proc_mutex.
* @return apr_pool_t the pool
*/
APR_POOL_DECLARE_ACCESSOR(proc_mutex);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ! APR_PROC_MUTEX_H */

View File

@@ -0,0 +1,138 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_QUEUE_H
#define APR_QUEUE_H
/**
* @file apr_queue.h
* @brief Thread Safe FIFO bounded queue
* @note Since most implementations of the queue are backed by a condition
* variable implementation, it isn't available on systems without threads.
* Although condition variables are some times available without threads.
*/
#include "apu.h"
#include "apr_errno.h"
#include "apr_pools.h"
#if APR_HAS_THREADS
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup APR_Util_FIFO Thread Safe FIFO bounded queue
* @ingroup APR_Util
* @{
*/
/**
* opaque structure
*/
typedef struct apr_queue_t apr_queue_t;
/**
* create a FIFO queue
* @param queue The new queue
* @param queue_capacity maximum size of the queue
* @param a pool to allocate queue from
*/
APU_DECLARE(apr_status_t) apr_queue_create(apr_queue_t **queue,
unsigned int queue_capacity,
apr_pool_t *a);
/**
* push/add a object to the queue, blocking if the queue is already full
*
* @param queue the queue
* @param data the data
* @returns APR_EINTR the blocking was interrupted (try again)
* @returns APR_EOF the queue has been terminated
* @returns APR_SUCCESS on a successfull push
*/
APU_DECLARE(apr_status_t) apr_queue_push(apr_queue_t *queue, void *data);
/**
* pop/get an object from the queue, blocking if the queue is already empty
*
* @param queue the queue
* @param data the data
* @returns APR_EINTR the blocking was interrupted (try again)
* @returns APR_EOF if the queue has been terminated
* @returns APR_SUCCESS on a successfull pop
*/
APU_DECLARE(apr_status_t) apr_queue_pop(apr_queue_t *queue, void **data);
/**
* push/add a object to the queue, returning immediatly if the queue is full
*
* @param queue the queue
* @param data the data
* @returns APR_EINTR the blocking operation was interrupted (try again)
* @returns APR_EAGAIN the queue is full
* @returns APR_EOF the queue has been terminated
* @returns APR_SUCCESS on a successfull push
*/
APU_DECLARE(apr_status_t) apr_queue_trypush(apr_queue_t *queue, void *data);
/**
* pop/get an object to the queue, returning immediatly if the queue is empty
*
* @param queue the queue
* @param data the data
* @returns APR_EINTR the blocking operation was interrupted (try again)
* @returns APR_EAGAIN the queue is empty
* @returns APR_EOF the queue has been terminated
* @returns APR_SUCCESS on a successfull push
*/
APU_DECLARE(apr_status_t) apr_queue_trypop(apr_queue_t *queue, void **data);
/**
* returns the size of the queue.
*
* @warning this is not threadsafe, and is intended for reporting/monitoring
* of the queue.
* @param queue the queue
* @returns the size of the queue
*/
APU_DECLARE(unsigned int) apr_queue_size(apr_queue_t *queue);
/**
* interrupt all the threads blocking on this queue.
*
* @param queue the queue
*/
APU_DECLARE(apr_status_t) apr_queue_interrupt_all(apr_queue_t *queue);
/**
* terminate all queue, sendinging a interupt to all the
* blocking threads
*
* @param queue the queue
*/
APU_DECLARE(apr_status_t) apr_queue_term(apr_queue_t *queue);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* APR_HAS_THREADS */
#endif /* APRQUEUE_H */

View File

@@ -0,0 +1,153 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_RANDOM_H
#define APR_RANDOM_H
/**
* @file apr_random.h
* @brief APR PRNG routines
*/
#include "apr_pools.h"
#include "apr_thread_proc.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_random PRNG Routines
* @ingroup APR
* @{
*/
typedef struct apr_crypto_hash_t apr_crypto_hash_t;
typedef void apr_crypto_hash_init_t(apr_crypto_hash_t *hash);
typedef void apr_crypto_hash_add_t(apr_crypto_hash_t *hash, const void *data,
apr_size_t bytes);
typedef void apr_crypto_hash_finish_t(apr_crypto_hash_t *hash,
unsigned char *result);
/* FIXME: make this opaque */
struct apr_crypto_hash_t {
apr_crypto_hash_init_t *init;
apr_crypto_hash_add_t *add;
apr_crypto_hash_finish_t *finish;
apr_size_t size;
void *data;
};
/**
* Allocate and initialize the SHA-256 context
* @param p The pool to allocate from
*/
APR_DECLARE(apr_crypto_hash_t *) apr_crypto_sha256_new(apr_pool_t *p);
/** Opaque PRNG structure. */
typedef struct apr_random_t apr_random_t;
/**
* Initialize a PRNG state
* @param g The PRNG state
* @param p The pool to allocate from
* @param pool_hash Pool hash functions
* @param key_hash Key hash functions
* @param prng_hash PRNG hash functions
*/
APR_DECLARE(void) apr_random_init(apr_random_t *g, apr_pool_t *p,
apr_crypto_hash_t *pool_hash,
apr_crypto_hash_t *key_hash,
apr_crypto_hash_t *prng_hash);
/**
* Allocate and initialize (apr_crypto_sha256_new) a new PRNG state.
* @param p The pool to allocate from
*/
APR_DECLARE(apr_random_t *) apr_random_standard_new(apr_pool_t *p);
/**
* Mix the randomness pools.
* @param g The PRNG state
* @param entropy_ Entropy buffer
* @param bytes Length of entropy_ in bytes
*/
APR_DECLARE(void) apr_random_add_entropy(apr_random_t *g,
const void *entropy_,
apr_size_t bytes);
/**
* Generate cryptographically insecure random bytes.
* @param g The RNG state
* @param random Buffer to fill with random bytes
* @param bytes Length of buffer in bytes
*/
APR_DECLARE(apr_status_t) apr_random_insecure_bytes(apr_random_t *g,
void *random,
apr_size_t bytes);
/**
* Generate cryptographically secure random bytes.
* @param g The RNG state
* @param random Buffer to fill with random bytes
* @param bytes Length of buffer in bytes
*/
APR_DECLARE(apr_status_t) apr_random_secure_bytes(apr_random_t *g,
void *random,
apr_size_t bytes);
/**
* Ensures that E bits of conditional entropy are mixed into the PRNG
* before any further randomness is extracted.
* @param g The RNG state
*/
APR_DECLARE(void) apr_random_barrier(apr_random_t *g);
/**
* Return APR_SUCCESS if the cryptographic PRNG has been seeded with
* enough data, APR_ENOTENOUGHENTROPY otherwise.
* @param r The RNG state
*/
APR_DECLARE(apr_status_t) apr_random_secure_ready(apr_random_t *r);
/**
* Return APR_SUCCESS if the PRNG has been seeded with enough data,
* APR_ENOTENOUGHENTROPY otherwise.
* @param r The PRNG state
*/
APR_DECLARE(apr_status_t) apr_random_insecure_ready(apr_random_t *r);
/**
* Mix the randomness pools after forking.
* @param proc The resulting process handle from apr_proc_fork()
* @remark Call this in the child after forking to mix the randomness
* pools. Note that its generally a bad idea to fork a process with a
* real PRNG in it - better to have the PRNG externally and get the
* randomness from there. However, if you really must do it, then you
* should supply all your entropy to all the PRNGs - don't worry, they
* won't produce the same output.
* @remark Note that apr_proc_fork() calls this for you, so only weird
* applications need ever call it themselves.
* @internal
*/
APR_DECLARE(void) apr_random_after_fork(apr_proc_t *proc);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !APR_RANDOM_H */

View File

@@ -0,0 +1,150 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_RESLIST_H
#define APR_RESLIST_H
/**
* @file apr_reslist.h
* @brief APR-UTIL Resource List Routines
*/
#include "apr.h"
#include "apu.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_time.h"
#if APR_HAS_THREADS
/**
* @defgroup APR_Util_RL Resource List Routines
* @ingroup APR_Util
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** Opaque resource list object */
typedef struct apr_reslist_t apr_reslist_t;
/* Generic constructor called by resource list when it needs to create a
* resource.
* @param resource opaque resource
* @param param flags
* @param pool Pool
*/
typedef apr_status_t (*apr_reslist_constructor)(void **resource, void *params,
apr_pool_t *pool);
/* Generic destructor called by resource list when it needs to destroy a
* resource.
* @param resource opaque resource
* @param param flags
* @param pool Pool
*/
typedef apr_status_t (*apr_reslist_destructor)(void *resource, void *params,
apr_pool_t *pool);
/**
* Create a new resource list with the following parameters:
* @param reslist An address where the pointer to the new resource
* list will be stored.
* @param pool The pool to use for local storage and management
* @param min Allowed minimum number of available resources. Zero
* creates new resources only when needed.
* @param smax Resources will be destroyed to meet this maximum
* restriction as they expire.
* @param hmax Absolute maximum limit on the number of total resources.
* @param ttl If non-zero, sets the maximum amount of time a resource
* may be available while exceeding the soft limit.
* @param con Constructor routine that is called to create a new resource.
* @param de Destructor routine that is called to destroy an expired resource.
* @param params Passed to constructor and deconstructor
* @param pool The pool from which to create this resoure list. Also the
* same pool that is passed to the constructor and destructor
* routines.
*/
APU_DECLARE(apr_status_t) apr_reslist_create(apr_reslist_t **reslist,
int min, int smax, int hmax,
apr_interval_time_t ttl,
apr_reslist_constructor con,
apr_reslist_destructor de,
void *params,
apr_pool_t *pool);
/**
* Destroy the given resource list and all resources controlled by
* this list.
* FIXME: Should this block until all resources become available,
* or maybe just destroy all the free ones, or maybe destroy
* them even though they might be in use by something else?
* Currently it will abort if there are resources that haven't
* been released, so there is an assumption that all resources
* have been released to the list before calling this function.
* @param reslist The reslist to destroy
*/
APU_DECLARE(apr_status_t) apr_reslist_destroy(apr_reslist_t *reslist);
/**
* Retrieve a resource from the list, creating a new one if necessary.
* If we have met our maximum number of resources, we will block
* until one becomes available.
*/
APU_DECLARE(apr_status_t) apr_reslist_acquire(apr_reslist_t *reslist,
void **resource);
/**
* Return a resource back to the list of available resources.
*/
APU_DECLARE(apr_status_t) apr_reslist_release(apr_reslist_t *reslist,
void *resource);
/**
* Set the timeout the acquire will wait for a free resource
* when the maximum number of resources is exceeded.
* @param reslist The resource list.
* @param timeout Timeout to wait. The zero waits forewer.
*/
APU_DECLARE(void) apr_reslist_timeout_set(apr_reslist_t *reslist,
apr_interval_time_t timeout);
/**
* Return the number of outstanding resources.
* @param reslist The resource list.
*/
APU_DECLARE(apr_uint32_t) apr_reslist_acquired_count(apr_reslist_t *reslist);
/**
* Invalidate a resource in the pool - e.g. a database connection
* that returns a "lost connection" error and can't be restored.
* Use this instead of apr_reslist_release if the resource is bad.
*/
APU_DECLARE(apr_status_t) apr_reslist_invalidate(apr_reslist_t *reslist,
void *resource);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* APR_HAS_THREADS */
#endif /* ! APR_RESLIST_H */

View File

@@ -0,0 +1,513 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This code draws heavily from the 4.4BSD <sys/queue.h> macros
* and Dean Gaudet's "splim/ring.h".
* <http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/queue.h>
* <http://www.arctic.org/~dean/splim/>
*
* We'd use Dean's code directly if we could guarantee the
* availability of inline functions.
*/
#ifndef APR_RING_H
#define APR_RING_H
/**
* @file apr_ring.h
* @brief APR Rings
*/
/*
* for offsetof()
*/
#include "apr_general.h"
/**
* @defgroup apr_ring Ring Macro Implementations
* @ingroup APR
* A ring is a kind of doubly-linked list that can be manipulated
* without knowing where its head is.
* @{
*/
/**
* The Ring Element
*
* A ring element struct is linked to the other elements in the ring
* through its ring entry field, e.g.
* <pre>
* struct my_element_t {
* APR_RING_ENTRY(my_element_t) link;
* int foo;
* char *bar;
* };
* </pre>
*
* An element struct may be put on more than one ring if it has more
* than one APR_RING_ENTRY field. Each APR_RING_ENTRY has a corresponding
* APR_RING_HEAD declaration.
*
* @warning For strict C standards compliance you should put the APR_RING_ENTRY
* first in the element struct unless the head is always part of a larger
* object with enough earlier fields to accommodate the offsetof() used
* to compute the ring sentinel below. You can usually ignore this caveat.
*/
#define APR_RING_ENTRY(elem) \
struct { \
struct elem * volatile next; \
struct elem * volatile prev; \
}
/**
* The Ring Head
*
* Each ring is managed via its head, which is a struct declared like this:
* <pre>
* APR_RING_HEAD(my_ring_t, my_element_t);
* struct my_ring_t ring, *ringp;
* </pre>
*
* This struct looks just like the element link struct so that we can
* be sure that the typecasting games will work as expected.
*
* The first element in the ring is next after the head, and the last
* element is just before the head.
*/
#define APR_RING_HEAD(head, elem) \
struct head { \
struct elem *next; \
struct elem *prev; \
}
/**
* The Ring Sentinel
*
* This is the magic pointer value that occurs before the first and
* after the last elements in the ring, computed from the address of
* the ring's head. The head itself isn't an element, but in order to
* get rid of all the special cases when dealing with the ends of the
* ring, we play typecasting games to make it look like one.
*
* Here is a diagram to illustrate the arrangements of the next and
* prev pointers of each element in a single ring. Note that they point
* to the start of each element, not to the APR_RING_ENTRY structure.
*
* <pre>
* +->+------+<-+ +->+------+<-+ +->+------+<-+
* | |struct| | | |struct| | | |struct| |
* / | elem | \/ | elem | \/ | elem | \
* ... | | /\ | | /\ | | ...
* +------+ | | +------+ | | +------+
* ...--|prev | | +--|ring | | +--|prev |
* | next|--+ | entry|--+ | next|--...
* +------+ +------+ +------+
* | etc. | | etc. | | etc. |
* : : : : : :
* </pre>
*
* The APR_RING_HEAD is nothing but a bare APR_RING_ENTRY. The prev
* and next pointers in the first and last elements don't actually
* point to the head, they point to a phantom place called the
* sentinel. Its value is such that last->next->next == first because
* the offset from the sentinel to the head's next pointer is the same
* as the offset from the start of an element to its next pointer.
* This also works in the opposite direction.
*
* <pre>
* last first
* +->+------+<-+ +->sentinel<-+ +->+------+<-+
* | |struct| | | | | |struct| |
* / | elem | \/ \/ | elem | \
* ... | | /\ /\ | | ...
* +------+ | | +------+ | | +------+
* ...--|prev | | +--|ring | | +--|prev |
* | next|--+ | head|--+ | next|--...
* +------+ +------+ +------+
* | etc. | | etc. |
* : : : :
* </pre>
*
* Note that the offset mentioned above is different for each kind of
* ring that the element may be on, and each kind of ring has a unique
* name for its APR_RING_ENTRY in each element, and has its own type
* for its APR_RING_HEAD.
*
* Note also that if the offset is non-zero (which is required if an
* element has more than one APR_RING_ENTRY), the unreality of the
* sentinel may have bad implications on very perverse implementations
* of C -- see the warning in APR_RING_ENTRY.
*
* @param hp The head of the ring
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_SENTINEL(hp, elem, link) \
(struct elem *)((char *)(&(hp)->next) - APR_OFFSETOF(struct elem, link))
/**
* The first element of the ring
* @param hp The head of the ring
*/
#define APR_RING_FIRST(hp) (hp)->next
/**
* The last element of the ring
* @param hp The head of the ring
*/
#define APR_RING_LAST(hp) (hp)->prev
/**
* The next element in the ring
* @param ep The current element
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_NEXT(ep, link) (ep)->link.next
/**
* The previous element in the ring
* @param ep The current element
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_PREV(ep, link) (ep)->link.prev
/**
* Initialize a ring
* @param hp The head of the ring
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_INIT(hp, elem, link) do { \
APR_RING_FIRST((hp)) = APR_RING_SENTINEL((hp), elem, link); \
APR_RING_LAST((hp)) = APR_RING_SENTINEL((hp), elem, link); \
} while (0)
/**
* Determine if a ring is empty
* @param hp The head of the ring
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
* @return true or false
*/
#define APR_RING_EMPTY(hp, elem, link) \
(APR_RING_FIRST((hp)) == APR_RING_SENTINEL((hp), elem, link))
/**
* Initialize a singleton element
* @param ep The element
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_ELEM_INIT(ep, link) do { \
APR_RING_NEXT((ep), link) = (ep); \
APR_RING_PREV((ep), link) = (ep); \
} while (0)
/**
* Splice the sequence ep1..epN into the ring before element lep
* (..lep.. becomes ..ep1..epN..lep..)
* @warning This doesn't work for splicing before the first element or on
* empty rings... see APR_RING_SPLICE_HEAD for one that does
* @param lep Element in the ring to splice before
* @param ep1 First element in the sequence to splice in
* @param epN Last element in the sequence to splice in
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_SPLICE_BEFORE(lep, ep1, epN, link) do { \
APR_RING_NEXT((epN), link) = (lep); \
APR_RING_PREV((ep1), link) = APR_RING_PREV((lep), link); \
APR_RING_NEXT(APR_RING_PREV((lep), link), link) = (ep1); \
APR_RING_PREV((lep), link) = (epN); \
} while (0)
/**
* Splice the sequence ep1..epN into the ring after element lep
* (..lep.. becomes ..lep..ep1..epN..)
* @warning This doesn't work for splicing after the last element or on
* empty rings... see APR_RING_SPLICE_TAIL for one that does
* @param lep Element in the ring to splice after
* @param ep1 First element in the sequence to splice in
* @param epN Last element in the sequence to splice in
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_SPLICE_AFTER(lep, ep1, epN, link) do { \
APR_RING_PREV((ep1), link) = (lep); \
APR_RING_NEXT((epN), link) = APR_RING_NEXT((lep), link); \
APR_RING_PREV(APR_RING_NEXT((lep), link), link) = (epN); \
APR_RING_NEXT((lep), link) = (ep1); \
} while (0)
/**
* Insert the element nep into the ring before element lep
* (..lep.. becomes ..nep..lep..)
* @warning This doesn't work for inserting before the first element or on
* empty rings... see APR_RING_INSERT_HEAD for one that does
* @param lep Element in the ring to insert before
* @param nep Element to insert
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_INSERT_BEFORE(lep, nep, link) \
APR_RING_SPLICE_BEFORE((lep), (nep), (nep), link)
/**
* Insert the element nep into the ring after element lep
* (..lep.. becomes ..lep..nep..)
* @warning This doesn't work for inserting after the last element or on
* empty rings... see APR_RING_INSERT_TAIL for one that does
* @param lep Element in the ring to insert after
* @param nep Element to insert
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_INSERT_AFTER(lep, nep, link) \
APR_RING_SPLICE_AFTER((lep), (nep), (nep), link)
/**
* Splice the sequence ep1..epN into the ring before the first element
* (..hp.. becomes ..hp..ep1..epN..)
* @param hp Head of the ring
* @param ep1 First element in the sequence to splice in
* @param epN Last element in the sequence to splice in
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_SPLICE_HEAD(hp, ep1, epN, elem, link) \
APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((hp), elem, link), \
(ep1), (epN), link)
/**
* Splice the sequence ep1..epN into the ring after the last element
* (..hp.. becomes ..ep1..epN..hp..)
* @param hp Head of the ring
* @param ep1 First element in the sequence to splice in
* @param epN Last element in the sequence to splice in
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_SPLICE_TAIL(hp, ep1, epN, elem, link) \
APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((hp), elem, link), \
(ep1), (epN), link)
/**
* Insert the element nep into the ring before the first element
* (..hp.. becomes ..hp..nep..)
* @param hp Head of the ring
* @param nep Element to insert
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_INSERT_HEAD(hp, nep, elem, link) \
APR_RING_SPLICE_HEAD((hp), (nep), (nep), elem, link)
/**
* Insert the element nep into the ring after the last element
* (..hp.. becomes ..nep..hp..)
* @param hp Head of the ring
* @param nep Element to insert
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_INSERT_TAIL(hp, nep, elem, link) \
APR_RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)
/**
* Concatenate ring h2 onto the end of ring h1, leaving h2 empty.
* @param h1 Head of the ring to concatenate onto
* @param h2 Head of the ring to concatenate
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_CONCAT(h1, h2, elem, link) do { \
if (!APR_RING_EMPTY((h2), elem, link)) { \
APR_RING_SPLICE_BEFORE(APR_RING_SENTINEL((h1), elem, link), \
APR_RING_FIRST((h2)), \
APR_RING_LAST((h2)), link); \
APR_RING_INIT((h2), elem, link); \
} \
} while (0)
/**
* Prepend ring h2 onto the beginning of ring h1, leaving h2 empty.
* @param h1 Head of the ring to prepend onto
* @param h2 Head of the ring to prepend
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_PREPEND(h1, h2, elem, link) do { \
if (!APR_RING_EMPTY((h2), elem, link)) { \
APR_RING_SPLICE_AFTER(APR_RING_SENTINEL((h1), elem, link), \
APR_RING_FIRST((h2)), \
APR_RING_LAST((h2)), link); \
APR_RING_INIT((h2), elem, link); \
} \
} while (0)
/**
* Unsplice a sequence of elements from a ring
* @warning The unspliced sequence is left with dangling pointers at either end
* @param ep1 First element in the sequence to unsplice
* @param epN Last element in the sequence to unsplice
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_UNSPLICE(ep1, epN, link) do { \
APR_RING_NEXT(APR_RING_PREV((ep1), link), link) = \
APR_RING_NEXT((epN), link); \
APR_RING_PREV(APR_RING_NEXT((epN), link), link) = \
APR_RING_PREV((ep1), link); \
} while (0)
/**
* Remove a single element from a ring
* @warning The unspliced element is left with dangling pointers at either end
* @param ep Element to remove
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_REMOVE(ep, link) \
APR_RING_UNSPLICE((ep), (ep), link)
/**
* Iterate over a ring
* @param ep The current element
* @param head The head of the ring
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_FOREACH(ep, head, elem, link) \
for (ep = APR_RING_FIRST(head); \
ep != APR_RING_SENTINEL(head, elem, link); \
ep = APR_RING_NEXT(ep, link))
/**
* Iterate over a ring safe against removal of the current element
* @param ep1 The current element
* @param ep2 Iteration cursor
* @param head The head of the ring
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_FOREACH_SAFE(ep1, ep2, head, elem, link) \
for (ep1 = APR_RING_FIRST(head), ep2 = APR_RING_NEXT(ep1, link); \
ep1 != APR_RING_SENTINEL(head, elem, link); \
ep1 = ep2, ep2 = APR_RING_NEXT(ep1, link))
/* Debugging tools: */
#ifdef APR_RING_DEBUG
#include <stdio.h>
#include <assert.h>
#define APR_RING_CHECK_ONE(msg, ptr) \
fprintf(stderr, "*** %s %p\n", msg, ptr)
#define APR_RING_CHECK(hp, elem, link, msg) \
APR_RING_CHECK_ELEM(APR_RING_SENTINEL(hp, elem, link), elem, link, msg)
#define APR_RING_CHECK_ELEM(ep, elem, link, msg) do { \
struct elem *start = (ep); \
struct elem *here = start; \
fprintf(stderr, "*** ring check start -- %s\n", msg); \
do { \
fprintf(stderr, "\telem %p\n", here); \
fprintf(stderr, "\telem->next %p\n", \
APR_RING_NEXT(here, link)); \
fprintf(stderr, "\telem->prev %p\n", \
APR_RING_PREV(here, link)); \
fprintf(stderr, "\telem->next->prev %p\n", \
APR_RING_PREV(APR_RING_NEXT(here, link), link)); \
fprintf(stderr, "\telem->prev->next %p\n", \
APR_RING_NEXT(APR_RING_PREV(here, link), link)); \
if (APR_RING_PREV(APR_RING_NEXT(here, link), link) != here) { \
fprintf(stderr, "\t*** elem->next->prev != elem\n"); \
break; \
} \
if (APR_RING_NEXT(APR_RING_PREV(here, link), link) != here) { \
fprintf(stderr, "\t*** elem->prev->next != elem\n"); \
break; \
} \
here = APR_RING_NEXT(here, link); \
} while (here != start); \
fprintf(stderr, "*** ring check end\n"); \
} while (0)
#define APR_RING_CHECK_CONSISTENCY(hp, elem, link) \
APR_RING_CHECK_ELEM_CONSISTENCY(APR_RING_SENTINEL(hp, elem, link),\
elem, link)
#define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) do { \
struct elem *start = (ep); \
struct elem *here = start; \
do { \
assert(APR_RING_PREV(APR_RING_NEXT(here, link), link) == here); \
assert(APR_RING_NEXT(APR_RING_PREV(here, link), link) == here); \
here = APR_RING_NEXT(here, link); \
} while (here != start); \
} while (0)
#else
/**
* Print a single pointer value to STDERR
* (This is a no-op unless APR_RING_DEBUG is defined.)
* @param msg Descriptive message
* @param ptr Pointer value to print
*/
#define APR_RING_CHECK_ONE(msg, ptr)
/**
* Dump all ring pointers to STDERR, starting with the head and looping all
* the way around the ring back to the head. Aborts if an inconsistency
* is found.
* (This is a no-op unless APR_RING_DEBUG is defined.)
* @param hp Head of the ring
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
* @param msg Descriptive message
*/
#define APR_RING_CHECK(hp, elem, link, msg)
/**
* Loops around a ring and checks all the pointers for consistency. Pops
* an assertion if any inconsistency is found. Same idea as APR_RING_CHECK()
* except that it's silent if all is well.
* (This is a no-op unless APR_RING_DEBUG is defined.)
* @param hp Head of the ring
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_CHECK_CONSISTENCY(hp, elem, link)
/**
* Dump all ring pointers to STDERR, starting with the given element and
* looping all the way around the ring back to that element. Aborts if
* an inconsistency is found.
* (This is a no-op unless APR_RING_DEBUG is defined.)
* @param ep The element
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
* @param msg Descriptive message
*/
#define APR_RING_CHECK_ELEM(ep, elem, link, msg)
/**
* Loops around a ring, starting with the given element, and checks all
* the pointers for consistency. Pops an assertion if any inconsistency
* is found. Same idea as APR_RING_CHECK_ELEM() except that it's silent
* if all is well.
* (This is a no-op unless APR_RING_DEBUG is defined.)
* @param ep The element
* @param elem The name of the element struct
* @param link The name of the APR_RING_ENTRY in the element struct
*/
#define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link)
#endif
/** @} */
#endif /* !APR_RING_H */

137
include/apr-linux/apr_rmm.h Normal file
View File

@@ -0,0 +1,137 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_RMM_H
#define APR_RMM_H
/**
* @file apr_rmm.h
* @brief APR-UTIL Relocatable Memory Management Routines
*/
/**
* @defgroup APR_Util_RMM Relocatable Memory Management Routines
* @ingroup APR_Util
* @{
*/
#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apu.h"
#include "apr_anylock.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** Structure to access Relocatable, Managed Memory */
typedef struct apr_rmm_t apr_rmm_t;
/** Fundamental allocation unit, within a specific apr_rmm_t */
typedef apr_size_t apr_rmm_off_t;
/**
* Initialize a relocatable memory block to be managed by the apr_rmm API.
* @param rmm The relocatable memory block
* @param lock An apr_anylock_t of the appropriate type of lock, or NULL
* if no locking is required.
* @param membuf The block of relocatable memory to be managed
* @param memsize The size of relocatable memory block to be managed
* @param cont The pool to use for local storage and management
* @remark Both @param membuf and @param memsize must be aligned
* (for instance using APR_ALIGN_DEFAULT).
*/
APU_DECLARE(apr_status_t) apr_rmm_init(apr_rmm_t **rmm, apr_anylock_t *lock,
void *membuf, apr_size_t memsize,
apr_pool_t *cont);
/**
* Destroy a managed memory block.
* @param rmm The relocatable memory block to destroy
*/
APU_DECLARE(apr_status_t) apr_rmm_destroy(apr_rmm_t *rmm);
/**
* Attach to a relocatable memory block already managed by the apr_rmm API.
* @param rmm The relocatable memory block
* @param lock An apr_anylock_t of the appropriate type of lock
* @param membuf The block of relocatable memory already under management
* @param cont The pool to use for local storage and management
*/
APU_DECLARE(apr_status_t) apr_rmm_attach(apr_rmm_t **rmm, apr_anylock_t *lock,
void *membuf, apr_pool_t *cont);
/**
* Detach from the managed block of memory.
* @param rmm The relocatable memory block to detach from
*/
APU_DECLARE(apr_status_t) apr_rmm_detach(apr_rmm_t *rmm);
/**
* Allocate memory from the block of relocatable memory.
* @param rmm The relocatable memory block
* @param reqsize How much memory to allocate
*/
APU_DECLARE(apr_rmm_off_t) apr_rmm_malloc(apr_rmm_t *rmm, apr_size_t reqsize);
/**
* Realloc memory from the block of relocatable memory.
* @param rmm The relocatable memory block
* @param entity The memory allocation to realloc
* @param reqsize The new size
*/
APU_DECLARE(apr_rmm_off_t) apr_rmm_realloc(apr_rmm_t *rmm, void *entity, apr_size_t reqsize);
/**
* Allocate memory from the block of relocatable memory and initialize it to zero.
* @param rmm The relocatable memory block
* @param reqsize How much memory to allocate
*/
APU_DECLARE(apr_rmm_off_t) apr_rmm_calloc(apr_rmm_t *rmm, apr_size_t reqsize);
/**
* Free allocation returned by apr_rmm_malloc or apr_rmm_calloc.
* @param rmm The relocatable memory block
* @param entity The memory allocation to free
*/
APU_DECLARE(apr_status_t) apr_rmm_free(apr_rmm_t *rmm, apr_rmm_off_t entity);
/**
* Retrieve the physical address of a relocatable allocation of memory
* @param rmm The relocatable memory block
* @param entity The memory allocation to free
* @return address The address, aligned with APR_ALIGN_DEFAULT.
*/
APU_DECLARE(void *) apr_rmm_addr_get(apr_rmm_t *rmm, apr_rmm_off_t entity);
/**
* Compute the offset of a relocatable allocation of memory
* @param rmm The relocatable memory block
* @param entity The physical address to convert to an offset
*/
APU_DECLARE(apr_rmm_off_t) apr_rmm_offset_get(apr_rmm_t *rmm, void *entity);
/**
* Compute the required overallocation of memory needed to fit n allocs
* @param n The number of alloc/calloc regions desired
*/
APU_DECLARE(apr_size_t) apr_rmm_overhead_get(int n);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* ! APR_RMM_H */

View File

@@ -0,0 +1,176 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* sdbm - ndbm work-alike hashed database library
* based on Per-Ake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
* author: oz@nexus.yorku.ca
* status: ex-public domain
*/
#ifndef APR_SDBM_H
#define APR_SDBM_H
#include "apu.h"
#include "apr_errno.h"
#include "apr_file_io.h" /* for apr_fileperms_t */
/**
* @file apr_sdbm.h
* @brief apr-util SDBM library
*/
/**
* @defgroup APR_Util_DBM_SDBM SDBM library
* @ingroup APR_Util_DBM
* @{
*/
/**
* Structure for referencing an sdbm
*/
typedef struct apr_sdbm_t apr_sdbm_t;
/**
* Structure for referencing the datum record within an sdbm
*/
typedef struct {
/** pointer to the data stored/retrieved */
char *dptr;
/** size of data */
/* apr_ssize_t for release 2.0??? */
int dsize;
} apr_sdbm_datum_t;
/* The extensions used for the database files */
/** SDBM Directory file extension */
#define APR_SDBM_DIRFEXT ".dir"
/** SDBM page file extension */
#define APR_SDBM_PAGFEXT ".pag"
/* flags to sdbm_store */
#define APR_SDBM_INSERT 0 /**< Insert */
#define APR_SDBM_REPLACE 1 /**< Replace */
#define APR_SDBM_INSERTDUP 2 /**< Insert with duplicates */
/**
* Open an sdbm database by file name
* @param db The newly opened database
* @param name The sdbm file to open
* @param mode The flag values (APR_READ and APR_BINARY flags are implicit)
* <PRE>
* APR_WRITE open for read-write access
* APR_CREATE create the sdbm if it does not exist
* APR_TRUNCATE empty the contents of the sdbm
* APR_EXCL fail for APR_CREATE if the file exists
* APR_DELONCLOSE delete the sdbm when closed
* APR_SHARELOCK support locking across process/machines
* </PRE>
* @param perms Permissions to apply to if created
* @param p The pool to use when creating the sdbm
* @remark The sdbm name is not a true file name, as sdbm appends suffixes
* for seperate data and index files.
*/
APU_DECLARE(apr_status_t) apr_sdbm_open(apr_sdbm_t **db, const char *name,
apr_int32_t mode,
apr_fileperms_t perms, apr_pool_t *p);
/**
* Close an sdbm file previously opened by apr_sdbm_open
* @param db The database to close
*/
APU_DECLARE(apr_status_t) apr_sdbm_close(apr_sdbm_t *db);
/**
* Lock an sdbm database for concurency of multiple operations
* @param db The database to lock
* @param type The lock type
* <PRE>
* APR_FLOCK_SHARED
* APR_FLOCK_EXCLUSIVE
* </PRE>
* @remark Calls to apr_sdbm_lock may be nested. All apr_sdbm functions
* perform implicit locking. Since an APR_FLOCK_SHARED lock cannot be
* portably promoted to an APR_FLOCK_EXCLUSIVE lock, apr_sdbm_store and
* apr_sdbm_delete calls will fail if an APR_FLOCK_SHARED lock is held.
* The apr_sdbm_lock call requires the database to be opened with the
* APR_SHARELOCK mode value.
*/
APU_DECLARE(apr_status_t) apr_sdbm_lock(apr_sdbm_t *db, int type);
/**
* Release an sdbm lock previously aquired by apr_sdbm_lock
* @param db The database to unlock
*/
APU_DECLARE(apr_status_t) apr_sdbm_unlock(apr_sdbm_t *db);
/**
* Fetch an sdbm record value by key
* @param db The database
* @param value The value datum retrieved for this record
* @param key The key datum to find this record
*/
APU_DECLARE(apr_status_t) apr_sdbm_fetch(apr_sdbm_t *db,
apr_sdbm_datum_t *value,
apr_sdbm_datum_t key);
/**
* Store an sdbm record value by key
* @param db The database
* @param key The key datum to store this record by
* @param value The value datum to store in this record
* @param opt The method used to store the record
* <PRE>
* APR_SDBM_INSERT return an error if the record exists
* APR_SDBM_REPLACE overwrite any existing record for key
* </PRE>
*/
APU_DECLARE(apr_status_t) apr_sdbm_store(apr_sdbm_t *db, apr_sdbm_datum_t key,
apr_sdbm_datum_t value, int opt);
/**
* Delete an sdbm record value by key
* @param db The database
* @param key The key datum of the record to delete
* @remark It is not an error to delete a non-existent record.
*/
APU_DECLARE(apr_status_t) apr_sdbm_delete(apr_sdbm_t *db,
const apr_sdbm_datum_t key);
/**
* Retrieve the first record key from a dbm
* @param db The database
* @param key The key datum of the first record
* @remark The keys returned are not ordered. To traverse the list of keys
* for an sdbm opened with APR_SHARELOCK, the caller must use apr_sdbm_lock
* prior to retrieving the first record, and hold the lock until after the
* last call to apr_sdbm_nextkey.
*/
APU_DECLARE(apr_status_t) apr_sdbm_firstkey(apr_sdbm_t *db, apr_sdbm_datum_t *key);
/**
* Retrieve the next record key from an sdbm
* @param db The database
* @param key The key datum of the next record
*/
APU_DECLARE(apr_status_t) apr_sdbm_nextkey(apr_sdbm_t *db, apr_sdbm_datum_t *key);
/**
* Returns true if the sdbm database opened for read-only access
* @param db The database to test
*/
APU_DECLARE(int) apr_sdbm_rdonly(apr_sdbm_t *db);
/** @} */
#endif /* APR_SDBM_H */

View File

@@ -0,0 +1,121 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* NIST Secure Hash Algorithm
* heavily modified by Uwe Hollerbach uh@alumni.caltech edu
* from Peter C. Gutmann's implementation as found in
* Applied Cryptography by Bruce Schneier
* This code is hereby placed in the public domain
*/
#ifndef APR_SHA1_H
#define APR_SHA1_H
#include "apu.h"
#include "apr_general.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file apr_sha1.h
* @brief APR-UTIL SHA1 library
*/
/** size of the SHA1 DIGEST */
#define APR_SHA1_DIGESTSIZE 20
/**
* Define the Magic String prefix that identifies a password as being
* hashed using our algorithm.
*/
#define APR_SHA1PW_ID "{SHA}"
/** length of the SHA Password */
#define APR_SHA1PW_IDLEN 5
/** @see apr_sha1_ctx_t */
typedef struct apr_sha1_ctx_t apr_sha1_ctx_t;
/**
* SHA1 context structure
*/
struct apr_sha1_ctx_t {
/** message digest */
apr_uint32_t digest[5];
/** 64-bit bit counts */
apr_uint32_t count_lo, count_hi;
/** SHA data buffer */
apr_uint32_t data[16];
/** unprocessed amount in data */
int local;
};
/**
* Provide a means to SHA1 crypt/encode a plaintext password in a way which
* makes password file compatible with those commonly use in netscape web
* and ldap installations.
* @param clear The plaintext password
* @param len The length of the plaintext password
* @param out The encrypted/encoded password
* @note SHA1 support is useful for migration purposes, but is less
* secure than Apache's password format, since Apache's (MD5)
* password format uses a random eight character salt to generate
* one of many possible hashes for the same password. Netscape
* uses plain SHA1 without a salt, so the same password
* will always generate the same hash, making it easier
* to break since the search space is smaller.
*/
APU_DECLARE(void) apr_sha1_base64(const char *clear, int len, char *out);
/**
* Initialize the SHA digest
* @param context The SHA context to initialize
*/
APU_DECLARE(void) apr_sha1_init(apr_sha1_ctx_t *context);
/**
* Update the SHA digest
* @param context The SHA1 context to update
* @param input The buffer to add to the SHA digest
* @param inputLen The length of the input buffer
*/
APU_DECLARE(void) apr_sha1_update(apr_sha1_ctx_t *context, const char *input,
unsigned int inputLen);
/**
* Update the SHA digest with binary data
* @param context The SHA1 context to update
* @param input The buffer to add to the SHA digest
* @param inputLen The length of the input buffer
*/
APU_DECLARE(void) apr_sha1_update_binary(apr_sha1_ctx_t *context,
const unsigned char *input,
unsigned int inputLen);
/**
* Finish computing the SHA digest
* @param digest the output buffer in which to store the digest
* @param context The context to finalize
*/
APU_DECLARE(void) apr_sha1_final(unsigned char digest[APR_SHA1_DIGESTSIZE],
apr_sha1_ctx_t *context);
#ifdef __cplusplus
}
#endif
#endif /* APR_SHA1_H */

146
include/apr-linux/apr_shm.h Normal file
View File

@@ -0,0 +1,146 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_SHM_H
#define APR_SHM_H
/**
* @file apr_shm.h
* @brief APR Shared Memory Routines
*/
#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_shm Shared Memory Routines
* @ingroup APR
* @{
*/
/**
* Private, platform-specific data struture representing a shared memory
* segment.
*/
typedef struct apr_shm_t apr_shm_t;
/**
* Create and make accessable a shared memory segment.
* @param m The shared memory structure to create.
* @param reqsize The desired size of the segment.
* @param filename The file to use for shared memory on platforms that
* require it.
* @param pool the pool from which to allocate the shared memory
* structure.
* @remark A note about Anonymous vs. Named shared memory segments:
* Not all plaforms support anonymous shared memory segments, but in
* some cases it is prefered over other types of shared memory
* implementations. Passing a NULL 'file' parameter to this function
* will cause the subsystem to use anonymous shared memory segments.
* If such a system is not available, APR_ENOTIMPL is returned.
* @remark A note about allocation sizes:
* On some platforms it is necessary to store some metainformation
* about the segment within the actual segment. In order to supply
* the caller with the requested size it may be necessary for the
* implementation to request a slightly greater segment length
* from the subsystem. In all cases, the apr_shm_baseaddr_get()
* function will return the first usable byte of memory.
*
*/
APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m,
apr_size_t reqsize,
const char *filename,
apr_pool_t *pool);
/**
* Remove named resource associated with a shared memory segment,
* preventing attachments to the resource, but not destroying it.
* @param filename The filename associated with shared-memory segment which
* needs to be removed
* @param pool The pool used for file operations
* @remark This function is only supported on platforms which support
* name-based shared memory segments, and will return APR_ENOTIMPL on
* platforms without such support. Removing the file while the shm
* is in use is not entirely portable, caller may use this to enhance
* obscurity of the resource, but be prepared for the the call to fail,
* and for concurrent attempts to create a resource of the same name
* to also fail. The pool cleanup of apr_shm_create (apr_shm_destroy)
* also removes the named resource.
*/
APR_DECLARE(apr_status_t) apr_shm_remove(const char *filename,
apr_pool_t *pool);
/**
* Destroy a shared memory segment and associated memory.
* @param m The shared memory segment structure to destroy.
*/
APR_DECLARE(apr_status_t) apr_shm_destroy(apr_shm_t *m);
/**
* Attach to a shared memory segment that was created
* by another process.
* @param m The shared memory structure to create.
* @param filename The file used to create the original segment.
* (This MUST match the original filename.)
* @param pool the pool from which to allocate the shared memory
* structure for this process.
*/
APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m,
const char *filename,
apr_pool_t *pool);
/**
* Detach from a shared memory segment without destroying it.
* @param m The shared memory structure representing the segment
* to detach from.
*/
APR_DECLARE(apr_status_t) apr_shm_detach(apr_shm_t *m);
/**
* Retrieve the base address of the shared memory segment.
* NOTE: This address is only usable within the callers address
* space, since this API does not guarantee that other attaching
* processes will maintain the same address mapping.
* @param m The shared memory segment from which to retrieve
* the base address.
* @return address, aligned by APR_ALIGN_DEFAULT.
*/
APR_DECLARE(void *) apr_shm_baseaddr_get(const apr_shm_t *m);
/**
* Retrieve the length of a shared memory segment in bytes.
* @param m The shared memory segment from which to retrieve
* the segment length.
*/
APR_DECLARE(apr_size_t) apr_shm_size_get(const apr_shm_t *m);
/**
* Get the pool used by this shared memory segment.
*/
APR_POOL_DECLARE_ACCESSOR(shm);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* APR_SHM_T */

View File

@@ -0,0 +1,109 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_SIGNAL_H
#define APR_SIGNAL_H
/**
* @file apr_signal.h
* @brief APR Signal Handling
*/
#include "apr.h"
#include "apr_pools.h"
#if APR_HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_signal Signal Handling
* @ingroup APR
* @{
*/
#if APR_HAVE_SIGACTION || defined(DOXYGEN)
#if defined(DARWIN) && !defined(__cplusplus) && !defined(_ANSI_SOURCE)
/* work around Darwin header file bugs
* http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2657228.html
*/
#undef SIG_DFL
#undef SIG_IGN
#undef SIG_ERR
#define SIG_DFL (void (*)(int))0
#define SIG_IGN (void (*)(int))1
#define SIG_ERR (void (*)(int))-1
#endif
/** Function prototype for signal handlers */
typedef void apr_sigfunc_t(int);
/**
* Set the signal handler function for a given signal
* @param signo The signal (eg... SIGWINCH)
* @param func the function to get called
*/
APR_DECLARE(apr_sigfunc_t *) apr_signal(int signo, apr_sigfunc_t * func);
#if defined(SIG_IGN) && !defined(SIG_ERR)
#define SIG_ERR ((apr_sigfunc_t *) -1)
#endif
#else /* !APR_HAVE_SIGACTION */
#define apr_signal(a, b) signal(a, b)
#endif
/**
* Get the description for a specific signal number
* @param signum The signal number
* @return The description of the signal
*/
APR_DECLARE(const char *) apr_signal_description_get(int signum);
/**
* APR-private function for initializing the signal package
* @internal
* @param pglobal The internal, global pool
*/
void apr_signal_init(apr_pool_t *pglobal);
/**
* Block the delivery of a particular signal
* @param signum The signal number
* @return status
*/
APR_DECLARE(apr_status_t) apr_signal_block(int signum);
/**
* Enable the delivery of a particular signal
* @param signum The signal number
* @return status
*/
APR_DECLARE(apr_status_t) apr_signal_unblock(int signum);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* APR_SIGNAL_H */

View File

@@ -0,0 +1,361 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Portions of this file are covered by */
/* -*- mode: c; c-file-style: "k&r" -*-
strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef APR_STRINGS_H
#define APR_STRINGS_H
/**
* @file apr_strings.h
* @brief APR Strings library
*/
#include "apr.h"
#include "apr_errno.h"
#include "apr_pools.h"
#define APR_WANT_IOVEC
#include "apr_want.h"
#if APR_HAVE_STDARG_H
#include <stdarg.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup apr_strings String routines
* @ingroup APR
* @{
*/
/**
* Do a natural order comparison of two strings.
* @param a The first string to compare
* @param b The second string to compare
* @return Either <0, 0, or >0. If the first string is less than the second
* this returns <0, if they are equivalent it returns 0, and if the
* first string is greater than second string it retuns >0.
*/
APR_DECLARE(int) apr_strnatcmp(char const *a, char const *b);
/**
* Do a natural order comparison of two strings ignoring the case of the
* strings.
* @param a The first string to compare
* @param b The second string to compare
* @return Either <0, 0, or >0. If the first string is less than the second
* this returns <0, if they are equivalent it returns 0, and if the
* first string is greater than second string it retuns >0.
*/
APR_DECLARE(int) apr_strnatcasecmp(char const *a, char const *b);
/**
* duplicate a string into memory allocated out of a pool
* @param p The pool to allocate out of
* @param s The string to duplicate
* @return The new string
*/
APR_DECLARE(char *) apr_pstrdup(apr_pool_t *p, const char *s);
/**
* Create a null-terminated string by making a copy of a sequence
* of characters and appending a null byte
* @param p The pool to allocate out of
* @param s The block of characters to duplicate
* @param n The number of characters to duplicate
* @return The new string
* @remark This is a faster alternative to apr_pstrndup, for use
* when you know that the string being duplicated really
* has 'n' or more characters. If the string might contain
* fewer characters, use apr_pstrndup.
*/
APR_DECLARE(char *) apr_pstrmemdup(apr_pool_t *p, const char *s, apr_size_t n);
/**
* Duplicate at most n characters of a string into memory allocated
* out of a pool; the new string will be NUL-terminated
* @param p The pool to allocate out of
* @param s The string to duplicate
* @param n The maximum number of characters to duplicate
* @return The new string
* @remark The amount of memory allocated from the pool is the length
* of the returned string including the NUL terminator
*/
APR_DECLARE(char *) apr_pstrndup(apr_pool_t *p, const char *s, apr_size_t n);
/**
* Duplicate a block of memory.
*
* @param p The pool to allocate from
* @param m The memory to duplicate
* @param n The number of bytes to duplicate
* @return The new block of memory
*/
APR_DECLARE(void *) apr_pmemdup(apr_pool_t *p, const void *m, apr_size_t n);
/**
* Concatenate multiple strings, allocating memory out a pool
* @param p The pool to allocate out of
* @param ... The strings to concatenate. The final string must be NULL
* @return The new string
*/
APR_DECLARE_NONSTD(char *) apr_pstrcat(apr_pool_t *p, ...);
/**
* Concatenate multiple strings specified in a writev-style vector
* @param p The pool from which to allocate
* @param vec The strings to concatenate
* @param nvec The number of strings to concatenate
* @param nbytes (output) strlen of new string (pass in NULL to omit)
* @return The new string
*/
APR_DECLARE(char *) apr_pstrcatv(apr_pool_t *p, const struct iovec *vec,
apr_size_t nvec, apr_size_t *nbytes);
/**
* printf-style style printing routine. The data is output to a string
* allocated from a pool
* @param p The pool to allocate out of
* @param fmt The format of the string
* @param ap The arguments to use while printing the data
* @return The new string
*/
APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *p, const char *fmt, va_list ap);
/**
* printf-style style printing routine. The data is output to a string
* allocated from a pool
* @param p The pool to allocate out of
* @param fmt The format of the string
* @param ... The arguments to use while printing the data
* @return The new string
*/
APR_DECLARE_NONSTD(char *) apr_psprintf(apr_pool_t *p, const char *fmt, ...)
__attribute__((format(printf,2,3)));
/**
* Copy up to dst_size characters from src to dst; does not copy
* past a NUL terminator in src, but always terminates dst with a NUL
* regardless.
* @param dst The destination string
* @param src The source string
* @param dst_size The space available in dst; dst always receives
* NUL termination, so if src is longer than
* dst_size, the actual number of characters copied is
* dst_size - 1.
* @return Pointer to the NUL terminator of the destination string, dst
* @remark
* <PRE>
* Note the differences between this function and strncpy():
* 1) strncpy() doesn't always NUL terminate; apr_cpystrn() does.
* 2) strncpy() pads the destination string with NULs, which is often
* unnecessary; apr_cpystrn() does not.
* 3) strncpy() returns a pointer to the beginning of the dst string;
* apr_cpystrn() returns a pointer to the NUL terminator of dst,
* to allow a check for truncation.
* </PRE>
*/
APR_DECLARE(char *) apr_cpystrn(char *dst, const char *src,
apr_size_t dst_size);
/**
* Strip spaces from a string
* @param dest The destination string. It is okay to modify the string
* in place. Namely dest == src
* @param src The string to rid the spaces from.
* @return The destination string, dest.
*/
APR_DECLARE(char *) apr_collapse_spaces(char *dest, const char *src);
/**
* Convert the arguments to a program from one string to an array of
* strings terminated by a NULL pointer
* @param arg_str The arguments to convert
* @param argv_out Output location. This is a pointer to an array of strings.
* @param token_context Pool to use.
*/
APR_DECLARE(apr_status_t) apr_tokenize_to_argv(const char *arg_str,
char ***argv_out,
apr_pool_t *token_context);
/**
* Split a string into separate null-terminated tokens. The tokens are
* delimited in the string by one or more characters from the sep
* argument.
* @param str The string to separate; this should be specified on the
* first call to apr_strtok() for a given string, and NULL
* on subsequent calls.
* @param sep The set of delimiters
* @param last Internal state saved by apr_strtok() between calls.
* @return The next token from the string
*/
APR_DECLARE(char *) apr_strtok(char *str, const char *sep, char **last);
/**
* @defgroup APR_Strings_Snprintf snprintf implementations
* @warning
* These are snprintf implementations based on apr_vformatter().
*
* Note that various standards and implementations disagree on the return
* value of snprintf, and side-effects due to %n in the formatting string.
* apr_snprintf (and apr_vsnprintf) behaves as follows:
*
* Process the format string until the entire string is exhausted, or
* the buffer fills. If the buffer fills then stop processing immediately
* (so no further %n arguments are processed), and return the buffer
* length. In all cases the buffer is NUL terminated. It will return the
* number of characters inserted into the buffer, not including the
* terminating NUL. As a special case, if len is 0, apr_snprintf will
* return the number of characters that would have been inserted if
* the buffer had been infinite (in this case, *buffer can be NULL)
*
* In no event does apr_snprintf return a negative number.
* @{
*/
/**
* snprintf routine based on apr_vformatter. This means it understands the
* same extensions.
* @param buf The buffer to write to
* @param len The size of the buffer
* @param format The format string
* @param ... The arguments to use to fill out the format string.
*/
APR_DECLARE_NONSTD(int) apr_snprintf(char *buf, apr_size_t len,
const char *format, ...)
__attribute__((format(printf,3,4)));
/**
* vsnprintf routine based on apr_vformatter. This means it understands the
* same extensions.
* @param buf The buffer to write to
* @param len The size of the buffer
* @param format The format string
* @param ap The arguments to use to fill out the format string.
*/
APR_DECLARE(int) apr_vsnprintf(char *buf, apr_size_t len, const char *format,
va_list ap);
/** @} */
/**
* create a string representation of an int, allocated from a pool
* @param p The pool from which to allocate
* @param n The number to format
* @return The string representation of the number
*/
APR_DECLARE(char *) apr_itoa(apr_pool_t *p, int n);
/**
* create a string representation of a long, allocated from a pool
* @param p The pool from which to allocate
* @param n The number to format
* @return The string representation of the number
*/
APR_DECLARE(char *) apr_ltoa(apr_pool_t *p, long n);
/**
* create a string representation of an apr_off_t, allocated from a pool
* @param p The pool from which to allocate
* @param n The number to format
* @return The string representation of the number
*/
APR_DECLARE(char *) apr_off_t_toa(apr_pool_t *p, apr_off_t n);
/**
* Convert a numeric string into an apr_off_t numeric value.
* @param offset The value of the parsed string.
* @param buf The string to parse. It may contain optional whitespace,
* followed by an optional '+' (positive, default) or '-' (negative)
* character, followed by an optional '0x' prefix if base is 0 or 16,
* followed by numeric digits appropriate for base.
* @param end A pointer to the end of the valid character in buf. If
* not NULL, it is set to the first invalid character in buf.
* @param base A numeric base in the range between 2 and 36 inclusive,
* or 0. If base is zero, buf will be treated as base ten unless its
* digits are prefixed with '0x', in which case it will be treated as
* base 16.
* @bug *end breaks type safety; where *buf is const, *end needs to be
* declared as const in APR 2.0
*/
APR_DECLARE(apr_status_t) apr_strtoff(apr_off_t *offset, const char *buf,
char **end, int base);
/**
* parse a numeric string into a 64-bit numeric value
* @param buf The string to parse. It may contain optional whitespace,
* followed by an optional '+' (positive, default) or '-' (negative)
* character, followed by an optional '0x' prefix if base is 0 or 16,
* followed by numeric digits appropriate for base.
* @param end A pointer to the end of the valid character in buf. If
* not NULL, it is set to the first invalid character in buf.
* @param base A numeric base in the range between 2 and 36 inclusive,
* or 0. If base is zero, buf will be treated as base ten unless its
* digits are prefixed with '0x', in which case it will be treated as
* base 16.
* @return The numeric value of the string. On overflow, errno is set
* to ERANGE.
*/
APR_DECLARE(apr_int64_t) apr_strtoi64(const char *buf, char **end, int base);
/**
* parse a base-10 numeric string into a 64-bit numeric value.
* Equivalent to apr_strtoi64(buf, (char**)NULL, 10).
* @param buf The string to parse
* @return The numeric value of the string
*/
APR_DECLARE(apr_int64_t) apr_atoi64(const char *buf);
/**
* Format a binary size (magnitiudes are 2^10 rather than 10^3) from an apr_off_t,
* as bytes, K, M, T, etc, to a four character compacted human readable string.
* @param size The size to format
* @param buf The 5 byte text buffer (counting the trailing null)
* @return The buf passed to apr_strfsize()
* @remark All negative sizes report ' - ', apr_strfsize only formats positive values.
*/
APR_DECLARE(char *) apr_strfsize(apr_off_t size, char *buf);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !APR_STRINGS_H */

View File

@@ -0,0 +1,81 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APR_STRMATCH_H
#define APR_STRMATCH_H
/**
* @file apr_strmatch.h
* @brief APR-UTIL string matching routines
*/
#include "apu.h"
#include "apr_pools.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup APR_Util_StrMatch String matching routines
* @ingroup APR_Util
* @{
*/
/** @see apr_strmatch_pattern */
typedef struct apr_strmatch_pattern apr_strmatch_pattern;
/**
* Precompiled search pattern
*/
struct apr_strmatch_pattern {
/** Function called to compare */
const char *(*compare)(const apr_strmatch_pattern *this_pattern,
const char *s, apr_size_t slen);
const char *pattern; /**< Current pattern */
apr_size_t length; /**< Current length */
void *context; /**< hook to add precomputed metadata */
};
#if defined(DOXYGEN)
/**
* Search for a precompiled pattern within a string
* @param pattern The pattern
* @param s The string in which to search for the pattern
* @param slen The length of s (excluding null terminator)
* @return A pointer to the first instance of the pattern in s, or
* NULL if not found
*/
APU_DECLARE(const char *) apr_strmatch(const apr_strmatch_pattern *pattern,
const char *s, apr_size_t slen);
#else
#define apr_strmatch(pattern, s, slen) (*((pattern)->compare))((pattern), (s), (slen))
#endif
/**
* Precompile a pattern for matching using the Boyer-Moore-Horspool algorithm
* @param p The pool from which to allocate the pattern
* @param s The pattern string
* @param case_sensitive Whether the matching should be case-sensitive
* @return a pointer to the compiled pattern, or NULL if compilation fails
*/
APU_DECLARE(const apr_strmatch_pattern *) apr_strmatch_precompile(apr_pool_t *p, const char *s, int case_sensitive);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* !APR_STRMATCH_H */

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