766 lines
18 KiB
C
766 lines
18 KiB
C
/**
|
|
* Copyright (C) 2008 Happy Fish / YuQing
|
|
*
|
|
* FastDFS may be copied only under the terms of the GNU General
|
|
* Public License V3, which may be found in the FastDFS source kit.
|
|
* Please visit the FastDFS Home Page http://www.fastken.com/ for more detail.
|
|
**/
|
|
|
|
//fdht_func.c
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <time.h>
|
|
#include "fastcommon/logger.h"
|
|
#include "fastcommon/sockopt.h"
|
|
#include "fastcommon/shared_func.h"
|
|
#include "fastcommon/ini_file_reader.h"
|
|
#include "fdht_func.h"
|
|
|
|
int fdht_split_ids(const char *szIds, int **ppIds, int *id_count)
|
|
{
|
|
char *pBuff;
|
|
char *pNumStart;
|
|
char *p;
|
|
int alloc_count;
|
|
int result;
|
|
int count;
|
|
int i;
|
|
char ch;
|
|
char *pNumStart1;
|
|
char *pNumStart2;
|
|
int nNumLen1;
|
|
int nNumLen2;
|
|
int nStart;
|
|
int nEnd;
|
|
|
|
alloc_count = getOccurCount(szIds, ',') + 1;
|
|
*id_count = 0;
|
|
*ppIds = (int *)malloc(sizeof(int) * alloc_count);
|
|
if (*ppIds == NULL)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"malloc %d bytes fail, errno: %d, error info: %s.", \
|
|
__LINE__, (int)sizeof(int) * alloc_count, \
|
|
errno, STRERROR(errno));
|
|
return errno != 0 ? errno : ENOMEM;
|
|
}
|
|
|
|
pBuff = strdup(szIds);
|
|
if (pBuff == NULL)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"strdup \"%s\" fail, errno: %d, error info: %s.", \
|
|
__LINE__, szIds, \
|
|
errno, STRERROR(errno));
|
|
free(*ppIds);
|
|
*ppIds = NULL;
|
|
return errno != 0 ? errno : ENOMEM;
|
|
}
|
|
|
|
result = 0;
|
|
p = pBuff;
|
|
while (*p != '\0')
|
|
{
|
|
while (*p == ' ' || *p == '\t') //trim prior spaces
|
|
{
|
|
p++;
|
|
}
|
|
|
|
if (*p == '\0')
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (*p >= '0' && *p <= '9')
|
|
{
|
|
pNumStart = p;
|
|
p++;
|
|
while (*p >= '0' && *p <= '9')
|
|
{
|
|
p++;
|
|
}
|
|
|
|
if (p - pNumStart == 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"invalid group ids \"%s\", " \
|
|
"which contains empty group id!", \
|
|
__LINE__, szIds);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
|
|
ch = *p;
|
|
if (!(ch == ',' || ch == '\0'))
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"invalid group ids \"%s\", which contains " \
|
|
"invalid char: %c(0x%02X)! remain string: %s", \
|
|
__LINE__, szIds, *p, *p, p);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
|
|
*p = '\0';
|
|
(*ppIds)[*id_count] = atoi(pNumStart);
|
|
(*id_count)++;
|
|
|
|
if (ch == '\0')
|
|
{
|
|
break;
|
|
}
|
|
|
|
p++; //skip ,
|
|
continue;
|
|
}
|
|
|
|
if (*p != '[')
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"invalid group ids \"%s\", which contains " \
|
|
"invalid char: %c(0x%02X)! remain string: %s", \
|
|
__LINE__, szIds, *p, *p, p);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
|
|
p++; //skip [
|
|
while (*p == ' ' || *p == '\t') //trim prior spaces
|
|
{
|
|
p++;
|
|
}
|
|
|
|
pNumStart1 = p;
|
|
while (*p >='0' && *p <= '9')
|
|
{
|
|
p++;
|
|
}
|
|
|
|
nNumLen1 = p - pNumStart1;
|
|
if (nNumLen1 == 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"invalid group ids: %s, " \
|
|
"empty entry before char %c(0x%02X), " \
|
|
"remain string: %s", \
|
|
__LINE__, szIds, *p, *p, p);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
|
|
while (*p == ' ' || *p == '\t') //trim spaces
|
|
{
|
|
p++;
|
|
}
|
|
|
|
if (*p != '-')
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"expect \"-\", but char %c(0x%02X) ocurs " \
|
|
"in group ids: %s, remain string: %s",\
|
|
__LINE__, *p, *p, szIds, p);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
|
|
*(pNumStart1 + nNumLen1) = '\0';
|
|
nStart = atoi(pNumStart1);
|
|
|
|
p++; //skip -
|
|
while (*p == ' ' || *p == '\t') //trim spaces
|
|
{
|
|
p++;
|
|
}
|
|
|
|
pNumStart2 = p;
|
|
while (*p >='0' && *p <= '9')
|
|
{
|
|
p++;
|
|
}
|
|
|
|
nNumLen2 = p - pNumStart2;
|
|
if (nNumLen2 == 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"invalid group ids: %s, " \
|
|
"empty entry before char %c(0x%02X)", \
|
|
__LINE__, szIds, *p, *p);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
|
|
/* trim tail spaces */
|
|
while (*p == ' ' || *p == '\t')
|
|
{
|
|
p++;
|
|
}
|
|
|
|
if (*p != ']')
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"expect \"]\", but char %c(0x%02X) ocurs " \
|
|
"in group ids: %s",\
|
|
__LINE__, *p, *p, szIds);
|
|
result = EINVAL;
|
|
break;
|
|
}
|
|
|
|
*(pNumStart2 + nNumLen2) = '\0';
|
|
nEnd = atoi(pNumStart2);
|
|
|
|
count = nEnd - nStart;
|
|
if (count < 0)
|
|
{
|
|
count = 0;
|
|
}
|
|
if (alloc_count < *id_count + (count + 1))
|
|
{
|
|
alloc_count += count + 1;
|
|
*ppIds = (int *)realloc(*ppIds, \
|
|
sizeof(int) * alloc_count);
|
|
if (*ppIds == NULL)
|
|
{
|
|
result = errno != 0 ? errno : ENOMEM;
|
|
logError("file: "__FILE__", line: %d, "\
|
|
"malloc %d bytes fail, " \
|
|
"errno: %d, error info: %s.", \
|
|
__LINE__, \
|
|
(int)sizeof(int) * alloc_count,\
|
|
result, STRERROR(result));
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (i=nStart; i<=nEnd; i++)
|
|
{
|
|
(*ppIds)[*id_count] = i;
|
|
(*id_count)++;
|
|
}
|
|
|
|
p++; //skip ]
|
|
/* trim spaces */
|
|
while (*p == ' ' || *p == '\t')
|
|
{
|
|
p++;
|
|
}
|
|
if (*p == ',')
|
|
{
|
|
p++; //skip ,
|
|
}
|
|
}
|
|
|
|
free(pBuff);
|
|
|
|
if (result == 0 && *id_count == 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"invalid group ids count: 0!", __LINE__);
|
|
result = EINVAL;
|
|
}
|
|
|
|
if (result != 0)
|
|
{
|
|
*id_count = 0;
|
|
free(*ppIds);
|
|
*ppIds = NULL;
|
|
}
|
|
|
|
printf("*id_count=%d\n", *id_count);
|
|
for (i=0; i<*id_count; i++)
|
|
{
|
|
printf("%d\n", (*ppIds)[i]);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static int fdht_cmp_by_ip_and_port_p(const void *p1, const void *p2)
|
|
{
|
|
int res;
|
|
|
|
res = strcmp(((FDHTServerInfo*)p1)->ip_addr, \
|
|
((FDHTServerInfo*)p2)->ip_addr);
|
|
if (res != 0)
|
|
{
|
|
return res;
|
|
}
|
|
|
|
return ((FDHTServerInfo*)p1)->port - \
|
|
((FDHTServerInfo*)p2)->port;
|
|
}
|
|
|
|
static int fdht_cmp_by_ip_and_port_pp(const void *p1, const void *p2)
|
|
{
|
|
int res;
|
|
|
|
res = strcmp((*((FDHTServerInfo **)p1))->ip_addr, \
|
|
(*((FDHTServerInfo **)p2))->ip_addr);
|
|
if (res != 0)
|
|
{
|
|
return res;
|
|
}
|
|
|
|
return ((*(FDHTServerInfo **)p1))->port - \
|
|
(*((FDHTServerInfo **)p2))->port;
|
|
}
|
|
|
|
static void fdht_insert_sorted_servers(GroupArray *pGroupArray, \
|
|
FDHTServerInfo *pInsertedServer)
|
|
{
|
|
FDHTServerInfo *pCurrent;
|
|
|
|
for (pCurrent=pGroupArray->servers + pGroupArray->server_count; \
|
|
pCurrent > pGroupArray->servers; pCurrent--)
|
|
{
|
|
if (fdht_cmp_by_ip_and_port_p(pCurrent-1, pInsertedServer)<0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
memcpy(pCurrent, pCurrent - 1, sizeof(FDHTServerInfo));
|
|
}
|
|
|
|
memcpy(pCurrent, pInsertedServer, sizeof(FDHTServerInfo));
|
|
}
|
|
|
|
int fdht_load_groups_ex(IniContext *pIniContext, \
|
|
GroupArray *pGroupArray, const bool bLoadProxyParams)
|
|
{
|
|
IniItem *pItemInfo;
|
|
IniItem *pItemEnd;
|
|
int group_id;
|
|
char item_name[32];
|
|
ServerArray *pServerArray;
|
|
FDHTServerInfo **ppServer;
|
|
FDHTServerInfo **ppServerEnd;
|
|
FDHTServerInfo **ppServers;
|
|
FDHTServerInfo *pServerInfo;
|
|
FDHTServerInfo *pServerEnd;
|
|
FDHTServerInfo *pFound;
|
|
int alloc_server_count;
|
|
char *ip_port[2];
|
|
char *pProxyIpAddr;
|
|
|
|
pGroupArray->group_count = iniGetIntValue(NULL, "group_count", \
|
|
pIniContext, 0);
|
|
if (pGroupArray->group_count <= 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"invalid group count: %d <= 0!", \
|
|
__LINE__, pGroupArray->group_count);
|
|
return EINVAL;
|
|
}
|
|
|
|
pGroupArray->groups = (ServerArray *)malloc(sizeof(ServerArray) * \
|
|
pGroupArray->group_count);
|
|
if (pGroupArray->groups == NULL)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"malloc %d bytes fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
(int)sizeof(ServerArray) * pGroupArray->group_count,\
|
|
errno, STRERROR(errno));
|
|
return errno != 0 ? errno : ENOMEM;
|
|
}
|
|
|
|
ppServers = (FDHTServerInfo **)malloc(sizeof(FDHTServerInfo *) * \
|
|
pGroupArray->group_count);
|
|
if (ppServers == NULL)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"malloc %d bytes fail, errno: %d, error info: %s", \
|
|
__LINE__, (int)sizeof(FDHTServerInfo *) * \
|
|
pGroupArray->group_count, \
|
|
errno, STRERROR(errno));
|
|
return errno != 0 ? errno : ENOMEM;
|
|
}
|
|
|
|
alloc_server_count = pGroupArray->group_count * 2;
|
|
pGroupArray->servers = (FDHTServerInfo *)malloc(sizeof(FDHTServerInfo) \
|
|
* alloc_server_count);
|
|
if (pGroupArray->servers == NULL)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"malloc %d bytes fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
(int)sizeof(FDHTServerInfo) * alloc_server_count, \
|
|
errno, STRERROR(errno));
|
|
return errno != 0 ? errno : ENOMEM;
|
|
}
|
|
|
|
pGroupArray->server_count = 0;
|
|
pServerArray = pGroupArray->groups;
|
|
for (group_id=0; group_id<pGroupArray->group_count; group_id++)
|
|
{
|
|
sprintf(item_name, "group%d", group_id);
|
|
pItemInfo = iniGetValuesEx(NULL, item_name, pIniContext, \
|
|
&(pServerArray->count));
|
|
if (pItemInfo == NULL || pServerArray->count <= 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"group %d not exist!", __LINE__, group_id);
|
|
return ENOENT;
|
|
}
|
|
|
|
pServerArray->servers = (FDHTServerInfo **)malloc( \
|
|
sizeof(FDHTServerInfo *) * pServerArray->count);
|
|
if (pServerArray->servers == NULL)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"malloc %d bytes fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
(int)sizeof(FDHTServerInfo)*pServerArray->count,
|
|
errno, STRERROR(errno));
|
|
return errno != 0 ? errno : ENOMEM;
|
|
}
|
|
|
|
ppServers[group_id] = (FDHTServerInfo *)malloc( \
|
|
sizeof(FDHTServerInfo) * pServerArray->count);
|
|
if (ppServers[group_id] == NULL)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"malloc %d bytes fail, " \
|
|
"errno: %d, error info: %s", __LINE__, \
|
|
(int)sizeof(FDHTServerInfo *)*pServerArray->count,
|
|
errno, STRERROR(errno));
|
|
return errno != 0 ? errno : ENOMEM;
|
|
}
|
|
memset(ppServers[group_id], 0, sizeof(FDHTServerInfo) * \
|
|
pServerArray->count);
|
|
|
|
ppServer = pServerArray->servers;
|
|
pServerInfo = ppServers[group_id];
|
|
pItemEnd = pItemInfo + pServerArray->count;
|
|
for (; pItemInfo<pItemEnd; pItemInfo++)
|
|
{
|
|
if (splitEx(pItemInfo->value, ':', ip_port, 2) != 2)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"\"%s\" 's value \"%s\" is invalid, "\
|
|
"correct format is hostname:port", \
|
|
__LINE__, item_name, pItemInfo->value);
|
|
return EINVAL;
|
|
}
|
|
|
|
if (getIpaddrByName(ip_port[0], pServerInfo->ip_addr, \
|
|
sizeof(pServerInfo->ip_addr)) == INADDR_NONE)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"\"%s\" 's value \"%s\" is invalid, "\
|
|
"invalid hostname: %s", \
|
|
__LINE__, item_name, \
|
|
pItemInfo->value, ip_port[0]);
|
|
return EINVAL;
|
|
}
|
|
|
|
if (strcmp(pServerInfo->ip_addr, "127.0.0.1") == 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"group%d: invalid hostname \"%s\", " \
|
|
"ip address can not be 127.0.0.1!", \
|
|
__LINE__, group_id, pItemInfo->value);
|
|
return EINVAL;
|
|
}
|
|
|
|
pServerInfo->port = atoi(ip_port[1]);
|
|
if (pServerInfo->port <= 0 || pServerInfo->port > 65535)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"\"%s\" 's value \"%s\" is invalid, "\
|
|
"invalid port: %d", \
|
|
__LINE__, item_name, \
|
|
pItemInfo->value, pServerInfo->port);
|
|
return EINVAL;
|
|
}
|
|
|
|
pServerInfo->sock = -1;
|
|
pFound = (FDHTServerInfo *)bsearch(pServerInfo, \
|
|
pGroupArray->servers, \
|
|
pGroupArray->server_count, \
|
|
sizeof(FDHTServerInfo), \
|
|
fdht_cmp_by_ip_and_port_p);
|
|
if (pFound == NULL) //not found
|
|
{
|
|
if (pGroupArray->server_count >= \
|
|
alloc_server_count)
|
|
{
|
|
alloc_server_count = \
|
|
pGroupArray->server_count + \
|
|
pGroupArray->group_count + 8;
|
|
pGroupArray->servers = (FDHTServerInfo*)
|
|
realloc(pGroupArray->servers, \
|
|
sizeof(FDHTServerInfo) * \
|
|
alloc_server_count);
|
|
if (pGroupArray->servers == NULL)
|
|
{
|
|
logError("file: "__FILE__", " \
|
|
"line: %d, malloc " \
|
|
"%d bytes fail, "
|
|
"errno: %d, " \
|
|
"error info: %s", \
|
|
__LINE__, \
|
|
(int)sizeof(FDHTServerInfo) \
|
|
* alloc_server_count, \
|
|
errno, STRERROR(errno));
|
|
return errno!=0 ? errno:ENOMEM;
|
|
}
|
|
}
|
|
|
|
fdht_insert_sorted_servers( \
|
|
pGroupArray, pServerInfo);
|
|
pGroupArray->server_count++;
|
|
}
|
|
|
|
ppServer++;
|
|
pServerInfo++;
|
|
}
|
|
|
|
pServerArray++;
|
|
}
|
|
|
|
pServerArray = pGroupArray->groups;
|
|
for (group_id=0; group_id<pGroupArray->group_count; group_id++)
|
|
{
|
|
ppServer = pServerArray->servers;
|
|
pServerEnd = ppServers[group_id] + pServerArray->count;
|
|
for (pServerInfo=ppServers[group_id]; \
|
|
pServerInfo<pServerEnd; pServerInfo++)
|
|
{
|
|
*ppServer = (FDHTServerInfo *)bsearch(pServerInfo, \
|
|
pGroupArray->servers, \
|
|
pGroupArray->server_count, \
|
|
sizeof(FDHTServerInfo), \
|
|
fdht_cmp_by_ip_and_port_p);
|
|
ppServer++;
|
|
}
|
|
|
|
qsort(pServerArray->servers, pServerArray->count, \
|
|
sizeof(FDHTServerInfo *), fdht_cmp_by_ip_and_port_pp);
|
|
ppServerEnd = pServerArray->servers + pServerArray->count;
|
|
for (ppServer=pServerArray->servers + 1; \
|
|
ppServer<ppServerEnd; ppServer++)
|
|
{
|
|
if (fdht_cmp_by_ip_and_port_pp(ppServer-1, \
|
|
ppServer) == 0)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"group: \"%s\", duplicate server: " \
|
|
"%s:%u", __LINE__, item_name, \
|
|
(*ppServer)->ip_addr, \
|
|
(*ppServer)->port);
|
|
return EINVAL;
|
|
}
|
|
}
|
|
|
|
pServerArray++;
|
|
}
|
|
|
|
for (group_id=0; group_id<pGroupArray->group_count; group_id++)
|
|
{
|
|
free(ppServers[group_id]);
|
|
}
|
|
free(ppServers);
|
|
|
|
if (alloc_server_count > pGroupArray->server_count)
|
|
{
|
|
pGroupArray->servers = (FDHTServerInfo*)realloc( \
|
|
pGroupArray->servers, sizeof(FDHTServerInfo) \
|
|
* pGroupArray->server_count);
|
|
if (pGroupArray->servers == NULL)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"malloc %d bytes fail, " \
|
|
"errno: %d, error info: %s", \
|
|
__LINE__, (int)sizeof(FDHTServerInfo) * \
|
|
pGroupArray->server_count, \
|
|
errno, STRERROR(errno));
|
|
return errno != 0 ? errno : ENOMEM;
|
|
}
|
|
}
|
|
|
|
memset(&pGroupArray->proxy_server, 0, sizeof(FDHTServerInfo));
|
|
if (!bLoadProxyParams)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
pGroupArray->use_proxy = iniGetBoolValue(NULL, "use_proxy", \
|
|
pIniContext, false);
|
|
if (!pGroupArray->use_proxy)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
pProxyIpAddr = iniGetStrValue(NULL, "proxy_addr", \
|
|
pIniContext);
|
|
if (pProxyIpAddr == NULL)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"item \"proxy_addr\" not exists!", \
|
|
__LINE__);
|
|
return ENOENT;
|
|
}
|
|
snprintf(pGroupArray->proxy_server.ip_addr, \
|
|
sizeof(pGroupArray->proxy_server.ip_addr), \
|
|
"%s", pProxyIpAddr);
|
|
|
|
pGroupArray->proxy_server.port = iniGetIntValue(NULL, "proxy_port", \
|
|
pIniContext, FDHT_DEFAULT_PROXY_PORT);
|
|
if (pGroupArray->proxy_server.port <= 0 || \
|
|
pGroupArray->proxy_server.port > 65535)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"proxy_port: %d is invalid!", \
|
|
__LINE__, pGroupArray->proxy_server.port);
|
|
return EINVAL;
|
|
}
|
|
|
|
pGroupArray->proxy_server.sock = -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int fdht_copy_group_array(GroupArray *pDestGroupArray, \
|
|
GroupArray *pSrcGroupArray)
|
|
{
|
|
ServerArray *pSrcArray;
|
|
ServerArray *pServerArray;
|
|
ServerArray *pArrayEnd;
|
|
FDHTServerInfo *pServerInfo;
|
|
FDHTServerInfo *pServerEnd;
|
|
FDHTServerInfo **ppSrcServer;
|
|
FDHTServerInfo **ppServerInfo;
|
|
FDHTServerInfo **ppServerEnd;
|
|
|
|
memcpy(pDestGroupArray, pSrcGroupArray, sizeof(GroupArray));
|
|
pDestGroupArray->groups = (ServerArray *)malloc(sizeof(ServerArray) * \
|
|
pDestGroupArray->group_count);
|
|
if (pDestGroupArray->groups == NULL)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"malloc %d bytes fail, errno: %d, error info: %s", \
|
|
__LINE__, (int)sizeof(ServerArray) * \
|
|
pDestGroupArray->group_count, \
|
|
errno, STRERROR(errno));
|
|
return errno != 0 ? errno : ENOMEM;
|
|
}
|
|
|
|
pDestGroupArray->servers = (FDHTServerInfo *)malloc( \
|
|
sizeof(FDHTServerInfo) * pDestGroupArray->server_count);
|
|
if (pDestGroupArray->servers == NULL)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"malloc %d bytes fail, errno: %d, error info: %s", \
|
|
__LINE__, (int)sizeof(FDHTServerInfo) * \
|
|
pDestGroupArray->server_count, \
|
|
errno, STRERROR(errno));
|
|
|
|
free(pDestGroupArray->groups);
|
|
pDestGroupArray->groups = NULL;
|
|
return errno != 0 ? errno : ENOMEM;
|
|
}
|
|
memcpy(pDestGroupArray->servers, pSrcGroupArray->servers, \
|
|
sizeof(FDHTServerInfo) * pDestGroupArray->server_count);
|
|
|
|
pSrcArray = pSrcGroupArray->groups;
|
|
pArrayEnd = pDestGroupArray->groups + pDestGroupArray->group_count;
|
|
for (pServerArray=pDestGroupArray->groups; pServerArray<pArrayEnd;
|
|
pServerArray++)
|
|
{
|
|
pServerArray->count = pSrcArray->count;
|
|
pServerArray->servers = (FDHTServerInfo **)malloc( \
|
|
sizeof(FDHTServerInfo *) * \
|
|
pServerArray->count);
|
|
if (pServerArray->servers == NULL)
|
|
{
|
|
logError("file: "__FILE__", line: %d, " \
|
|
"malloc %d bytes fail, " \
|
|
"errno: %d, error info: %s", \
|
|
__LINE__, (int)sizeof(FDHTServerInfo *) * \
|
|
pServerArray->count, \
|
|
errno, STRERROR(errno));
|
|
return errno != 0 ? errno : ENOMEM;
|
|
}
|
|
|
|
ppSrcServer = pSrcArray->servers;
|
|
ppServerEnd = pServerArray->servers + pServerArray->count;
|
|
for (ppServerInfo=pServerArray->servers; \
|
|
ppServerInfo<ppServerEnd; ppServerInfo++)
|
|
{
|
|
*ppServerInfo = pDestGroupArray->servers + \
|
|
(*ppSrcServer - pSrcGroupArray->servers);
|
|
ppSrcServer++;
|
|
}
|
|
|
|
pSrcArray++;
|
|
}
|
|
|
|
pServerEnd = pDestGroupArray->servers + pDestGroupArray->server_count;
|
|
for (pServerInfo=pDestGroupArray->servers; \
|
|
pServerInfo<pServerEnd; pServerInfo++)
|
|
{
|
|
if (pServerInfo->sock >= 0)
|
|
{
|
|
pServerInfo->sock = -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void fdht_free_group_array(GroupArray *pGroupArray)
|
|
{
|
|
ServerArray *pServerArray;
|
|
ServerArray *pArrayEnd;
|
|
FDHTServerInfo *pServerInfo;
|
|
FDHTServerInfo *pServerEnd;
|
|
|
|
if (pGroupArray->servers != NULL)
|
|
{
|
|
pArrayEnd = pGroupArray->groups + pGroupArray->group_count;
|
|
for (pServerArray=pGroupArray->groups; pServerArray<pArrayEnd;
|
|
pServerArray++)
|
|
{
|
|
if (pServerArray->servers == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
free(pServerArray->servers);
|
|
pServerArray->servers = NULL;
|
|
}
|
|
|
|
pServerEnd = pGroupArray->servers + pGroupArray->server_count;
|
|
for (pServerInfo=pGroupArray->servers; \
|
|
pServerInfo<pServerEnd; pServerInfo++)
|
|
{
|
|
if (pServerInfo->sock >= 0)
|
|
{
|
|
close(pServerInfo->sock);
|
|
pServerInfo->sock = -1;
|
|
}
|
|
}
|
|
|
|
free(pGroupArray->servers);
|
|
pGroupArray->servers = NULL;
|
|
}
|
|
|
|
if (pGroupArray->groups != NULL)
|
|
{
|
|
free(pGroupArray->groups);
|
|
pGroupArray->groups = NULL;
|
|
}
|
|
}
|
|
|