This commit is contained in:
dongxiancun 2019-06-18 16:03:53 +08:00
commit 828d210387
23 changed files with 5797 additions and 1620 deletions

238
Common/uthash/utarray.h Normal file
View File

@ -0,0 +1,238 @@
/*
Copyright (c) 2008-2018, Troy D. Hanson http://troydhanson.github.com/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* a dynamic array implementation using macros
*/
#ifndef UTARRAY_H
#define UTARRAY_H
#define UTARRAY_VERSION 2.1.0
#include <stddef.h> /* size_t */
#include <string.h> /* memset, etc */
#include <stdlib.h> /* exit */
#ifdef __GNUC__
#define UTARRAY_UNUSED __attribute__((__unused__))
#else
#define UTARRAY_UNUSED
#endif
#ifndef oom
#define oom() exit(-1)
#endif
typedef void (ctor_f)(void *dst, const void *src);
typedef void (dtor_f)(void *elt);
typedef void (init_f)(void *elt);
typedef struct {
size_t sz;
init_f *init;
ctor_f *copy;
dtor_f *dtor;
} UT_icd;
typedef struct {
unsigned i,n;/* i: index of next available slot, n: num slots */
UT_icd icd; /* initializer, copy and destructor functions */
char *d; /* n slots of size icd->sz*/
} UT_array;
#define utarray_init(a,_icd) do { \
memset(a,0,sizeof(UT_array)); \
(a)->icd = *(_icd); \
} while(0)
#define utarray_done(a) do { \
if ((a)->n) { \
if ((a)->icd.dtor) { \
unsigned _ut_i; \
for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \
(a)->icd.dtor(utarray_eltptr(a,_ut_i)); \
} \
} \
free((a)->d); \
} \
(a)->n=0; \
} while(0)
#define utarray_new(a,_icd) do { \
(a) = (UT_array*)malloc(sizeof(UT_array)); \
if ((a) == NULL) oom(); \
utarray_init(a,_icd); \
} while(0)
#define utarray_free(a) do { \
utarray_done(a); \
free(a); \
} while(0)
#define utarray_reserve(a,by) do { \
if (((a)->i+(by)) > (a)->n) { \
char *utarray_tmp; \
while (((a)->i+(by)) > (a)->n) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \
utarray_tmp=(char*)realloc((a)->d, (a)->n*(a)->icd.sz); \
if (utarray_tmp == NULL) oom(); \
(a)->d=utarray_tmp; \
} \
} while(0)
#define utarray_push_back(a,p) do { \
utarray_reserve(a,1); \
if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,(a)->i++), p); } \
else { memcpy(_utarray_eltptr(a,(a)->i++), p, (a)->icd.sz); }; \
} while(0)
#define utarray_pop_back(a) do { \
if ((a)->icd.dtor) { (a)->icd.dtor( _utarray_eltptr(a,--((a)->i))); } \
else { (a)->i--; } \
} while(0)
#define utarray_extend_back(a) do { \
utarray_reserve(a,1); \
if ((a)->icd.init) { (a)->icd.init(_utarray_eltptr(a,(a)->i)); } \
else { memset(_utarray_eltptr(a,(a)->i),0,(a)->icd.sz); } \
(a)->i++; \
} while(0)
#define utarray_len(a) ((a)->i)
#define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL)
#define _utarray_eltptr(a,j) ((a)->d + ((a)->icd.sz * (j)))
#define utarray_insert(a,p,j) do { \
if ((j) > (a)->i) utarray_resize(a,j); \
utarray_reserve(a,1); \
if ((j) < (a)->i) { \
memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j), \
((a)->i - (j))*((a)->icd.sz)); \
} \
if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,j), p); } \
else { memcpy(_utarray_eltptr(a,j), p, (a)->icd.sz); }; \
(a)->i++; \
} while(0)
#define utarray_inserta(a,w,j) do { \
if (utarray_len(w) == 0) break; \
if ((j) > (a)->i) utarray_resize(a,j); \
utarray_reserve(a,utarray_len(w)); \
if ((j) < (a)->i) { \
memmove(_utarray_eltptr(a,(j)+utarray_len(w)), \
_utarray_eltptr(a,j), \
((a)->i - (j))*((a)->icd.sz)); \
} \
if ((a)->icd.copy) { \
unsigned _ut_i; \
for(_ut_i=0;_ut_i<(w)->i;_ut_i++) { \
(a)->icd.copy(_utarray_eltptr(a, (j) + _ut_i), _utarray_eltptr(w, _ut_i)); \
} \
} else { \
memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0), \
utarray_len(w)*((a)->icd.sz)); \
} \
(a)->i += utarray_len(w); \
} while(0)
#define utarray_resize(dst,num) do { \
unsigned _ut_i; \
if ((dst)->i > (unsigned)(num)) { \
if ((dst)->icd.dtor) { \
for (_ut_i = (num); _ut_i < (dst)->i; ++_ut_i) { \
(dst)->icd.dtor(_utarray_eltptr(dst, _ut_i)); \
} \
} \
} else if ((dst)->i < (unsigned)(num)) { \
utarray_reserve(dst, (num) - (dst)->i); \
if ((dst)->icd.init) { \
for (_ut_i = (dst)->i; _ut_i < (unsigned)(num); ++_ut_i) { \
(dst)->icd.init(_utarray_eltptr(dst, _ut_i)); \
} \
} else { \
memset(_utarray_eltptr(dst, (dst)->i), 0, (dst)->icd.sz*((num) - (dst)->i)); \
} \
} \
(dst)->i = (num); \
} while(0)
#define utarray_concat(dst,src) do { \
utarray_inserta(dst, src, utarray_len(dst)); \
} while(0)
#define utarray_erase(a,pos,len) do { \
if ((a)->icd.dtor) { \
unsigned _ut_i; \
for (_ut_i = 0; _ut_i < (len); _ut_i++) { \
(a)->icd.dtor(utarray_eltptr(a, (pos) + _ut_i)); \
} \
} \
if ((a)->i > ((pos) + (len))) { \
memmove(_utarray_eltptr(a, pos), _utarray_eltptr(a, (pos) + (len)), \
((a)->i - ((pos) + (len))) * (a)->icd.sz); \
} \
(a)->i -= (len); \
} while(0)
#define utarray_renew(a,u) do { \
if (a) utarray_clear(a); \
else utarray_new(a, u); \
} while(0)
#define utarray_clear(a) do { \
if ((a)->i > 0) { \
if ((a)->icd.dtor) { \
unsigned _ut_i; \
for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \
(a)->icd.dtor(_utarray_eltptr(a, _ut_i)); \
} \
} \
(a)->i = 0; \
} \
} while(0)
#define utarray_sort(a,cmp) do { \
qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \
} while(0)
#define utarray_find(a,v,cmp) bsearch((v),(a)->d,(a)->i,(a)->icd.sz,cmp)
#define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL)
#define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : ((((a)->i) > (utarray_eltidx(a,e)+1)) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL))
#define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) > 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL))
#define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL)
#define utarray_eltidx(a,e) (((char*)(e) >= (a)->d) ? (((char*)(e) - (a)->d)/(a)->icd.sz) : -1)
/* last we pre-define a few icd for common utarrays of ints and strings */
static void utarray_str_cpy(void *dst, const void *src) {
char **_src = (char**)src, **_dst = (char**)dst;
*_dst = (*_src == NULL) ? NULL : strdup(*_src);
}
static void utarray_str_dtor(void *elt) {
char **eltc = (char**)elt;
if (*eltc != NULL) free(*eltc);
}
static const UT_icd ut_str_icd UTARRAY_UNUSED = {sizeof(char*),NULL,utarray_str_cpy,utarray_str_dtor};
static const UT_icd ut_int_icd UTARRAY_UNUSED = {sizeof(int),NULL,NULL,NULL};
static const UT_icd ut_ptr_icd UTARRAY_UNUSED = {sizeof(void*),NULL,NULL,NULL};
#endif /* UTARRAY_H */

1227
Common/uthash/uthash.h Normal file

File diff suppressed because it is too large Load Diff

1073
Common/uthash/utlist.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,108 @@
/*
Copyright (c) 2015-2018, Troy D. Hanson http://troydhanson.github.com/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* a ring-buffer implementation using macros
*/
#ifndef UTRINGBUFFER_H
#define UTRINGBUFFER_H
#define UTRINGBUFFER_VERSION 2.1.0
#include <stdlib.h>
#include <string.h>
#include "utarray.h" // for "UT_icd"
typedef struct {
unsigned i; /* index of next available slot; wraps at n */
unsigned n; /* capacity */
unsigned char f; /* full */
UT_icd icd; /* initializer, copy and destructor functions */
char *d; /* n slots of size icd->sz */
} UT_ringbuffer;
#define utringbuffer_init(a, _n, _icd) do { \
memset(a, 0, sizeof(UT_ringbuffer)); \
(a)->icd = *(_icd); \
(a)->n = (_n); \
if ((a)->n) { (a)->d = (char*)malloc((a)->n * (_icd)->sz); } \
} while(0)
#define utringbuffer_clear(a) do { \
if ((a)->icd.dtor) { \
if ((a)->f) { \
unsigned _ut_i; \
for (_ut_i = 0; _ut_i < (a)->n; ++_ut_i) { \
(a)->icd.dtor(utringbuffer_eltptr(a, _ut_i)); \
} \
} else { \
unsigned _ut_i; \
for (_ut_i = 0; _ut_i < (a)->i; ++_ut_i) { \
(a)->icd.dtor(utringbuffer_eltptr(a, _ut_i)); \
} \
} \
} \
(a)->i = 0; \
(a)->f = 0; \
} while(0)
#define utringbuffer_done(a) do { \
utringbuffer_clear(a); \
free((a)->d); (a)->d = NULL; \
(a)->n = 0; \
} while(0)
#define utringbuffer_new(a,n,_icd) do { \
a = (UT_ringbuffer*)malloc(sizeof(UT_ringbuffer)); \
utringbuffer_init(a, n, _icd); \
} while(0)
#define utringbuffer_free(a) do { \
utringbuffer_done(a); \
free(a); \
} while(0)
#define utringbuffer_push_back(a,p) do { \
if ((a)->icd.dtor && (a)->f) { (a)->icd.dtor(_utringbuffer_internalptr(a,(a)->i)); } \
if ((a)->icd.copy) { (a)->icd.copy( _utringbuffer_internalptr(a,(a)->i), p); } \
else { memcpy(_utringbuffer_internalptr(a,(a)->i), p, (a)->icd.sz); }; \
if (++(a)->i == (a)->n) { (a)->i = 0; (a)->f = 1; } \
} while(0)
#define utringbuffer_len(a) ((a)->f ? (a)->n : (a)->i)
#define utringbuffer_empty(a) ((a)->i == 0 && !(a)->f)
#define utringbuffer_full(a) ((a)->f != 0)
#define _utringbuffer_real_idx(a,j) ((a)->f ? ((j) + (a)->i) % (a)->n : (j))
#define _utringbuffer_internalptr(a,j) ((void*)((a)->d + ((a)->icd.sz * (j))))
#define utringbuffer_eltptr(a,j) ((0 <= (j) && (j) < utringbuffer_len(a)) ? _utringbuffer_internalptr(a,_utringbuffer_real_idx(a,j)) : NULL)
#define _utringbuffer_fake_idx(a,j) ((a)->f ? ((j) + (a)->n - (a)->i) % (a)->n : (j))
#define _utringbuffer_internalidx(a,e) (((char*)(e) >= (a)->d) ? (((char*)(e) - (a)->d)/(a)->icd.sz) : -1)
#define utringbuffer_eltidx(a,e) _utringbuffer_fake_idx(a, _utringbuffer_internalidx(a,e))
#define utringbuffer_front(a) utringbuffer_eltptr(a,0)
#define utringbuffer_next(a,e) ((e)==NULL ? utringbuffer_front(a) : utringbuffer_eltptr(a, utringbuffer_eltidx(a,e)+1))
#define utringbuffer_prev(a,e) ((e)==NULL ? utringbuffer_back(a) : utringbuffer_eltptr(a, utringbuffer_eltidx(a,e)-1))
#define utringbuffer_back(a) (utringbuffer_empty(a) ? NULL : utringbuffer_eltptr(a, utringbuffer_len(a) - 1))
#endif /* UTRINGBUFFER_H */

88
Common/uthash/utstack.h Normal file
View File

@ -0,0 +1,88 @@
/*
Copyright (c) 2018-2018, Troy D. Hanson http://troydhanson.github.com/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UTSTACK_H
#define UTSTACK_H
#define UTSTACK_VERSION 2.1.0
/*
* This file contains macros to manipulate a singly-linked list as a stack.
*
* To use utstack, your structure must have a "next" pointer.
*
* ----------------.EXAMPLE -------------------------
* struct item {
* int id;
* struct item *next;
* }
*
* struct item *stack = NULL:
*
* int main() {
* int count;
* struct item *tmp;
* struct item *item = malloc(sizeof *item);
* item->id = 42;
* STACK_COUNT(stack, tmp, count); assert(count == 0);
* STACK_PUSH(stack, item);
* STACK_COUNT(stack, tmp, count); assert(count == 1);
* STACK_POP(stack, item);
* free(item);
* STACK_COUNT(stack, tmp, count); assert(count == 0);
* }
* --------------------------------------------------
*/
#define STACK_TOP(head) (head)
#define STACK_EMPTY(head) (!(head))
#define STACK_PUSH(head,add) \
STACK_PUSH2(head,add,next)
#define STACK_PUSH2(head,add,next) \
do { \
(add)->next = (head); \
(head) = (add); \
} while (0)
#define STACK_POP(head,result) \
STACK_POP2(head,result,next)
#define STACK_POP2(head,result,next) \
do { \
(result) = (head); \
(head) = (head)->next; \
} while (0)
#define STACK_COUNT(head,el,counter) \
STACK_COUNT2(head,el,counter,next) \
#define STACK_COUNT2(head,el,counter,next) \
do { \
(counter) = 0; \
for ((el) = (head); el; (el) = (el)->next) { ++(counter); } \
} while (0)
#endif /* UTSTACK_H */

398
Common/uthash/utstring.h Normal file
View File

@ -0,0 +1,398 @@
/*
Copyright (c) 2008-2018, Troy D. Hanson http://troydhanson.github.com/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* a dynamic string implementation using macros
*/
#ifndef UTSTRING_H
#define UTSTRING_H
#define UTSTRING_VERSION 2.1.0
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#ifdef __GNUC__
#define UTSTRING_UNUSED __attribute__((__unused__))
#else
#define UTSTRING_UNUSED
#endif
#ifndef oom
#define oom() exit(-1)
#endif
typedef struct {
char *d; /* pointer to allocated buffer */
size_t n; /* allocated capacity */
size_t i; /* index of first unused byte */
} UT_string;
#define utstring_reserve(s,amt) \
do { \
if (((s)->n - (s)->i) < (size_t)(amt)) { \
char *utstring_tmp = (char*)realloc( \
(s)->d, (s)->n + (amt)); \
if (utstring_tmp == NULL) oom(); \
(s)->d = utstring_tmp; \
(s)->n += (amt); \
} \
} while(0)
#define utstring_init(s) \
do { \
(s)->n = 0; (s)->i = 0; (s)->d = NULL; \
utstring_reserve(s,100); \
(s)->d[0] = '\0'; \
} while(0)
#define utstring_done(s) \
do { \
if ((s)->d != NULL) free((s)->d); \
(s)->n = 0; \
} while(0)
#define utstring_free(s) \
do { \
utstring_done(s); \
free(s); \
} while(0)
#define utstring_new(s) \
do { \
(s) = (UT_string*)malloc(sizeof(UT_string)); \
if (!(s)) oom(); \
utstring_init(s); \
} while(0)
#define utstring_renew(s) \
do { \
if (s) { \
utstring_clear(s); \
} else { \
utstring_new(s); \
} \
} while(0)
#define utstring_clear(s) \
do { \
(s)->i = 0; \
(s)->d[0] = '\0'; \
} while(0)
#define utstring_bincpy(s,b,l) \
do { \
utstring_reserve((s),(l)+1); \
if (l) memcpy(&(s)->d[(s)->i], b, l); \
(s)->i += (l); \
(s)->d[(s)->i]='\0'; \
} while(0)
#define utstring_concat(dst,src) \
do { \
utstring_reserve((dst),((src)->i)+1); \
if ((src)->i) memcpy(&(dst)->d[(dst)->i], (src)->d, (src)->i); \
(dst)->i += (src)->i; \
(dst)->d[(dst)->i]='\0'; \
} while(0)
#define utstring_len(s) ((s)->i)
#define utstring_body(s) ((s)->d)
UTSTRING_UNUSED static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {
int n;
va_list cp;
for (;;) {
#ifdef _WIN32
cp = ap;
#else
va_copy(cp, ap);
#endif
n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp);
va_end(cp);
if ((n > -1) && ((size_t) n < (s->n-s->i))) {
s->i += n;
return;
}
/* Else try again with more space. */
if (n > -1) utstring_reserve(s,n+1); /* exact */
else utstring_reserve(s,(s->n)*2); /* 2x */
}
}
#ifdef __GNUC__
/* support printf format checking (2=the format string, 3=start of varargs) */
static void utstring_printf(UT_string *s, const char *fmt, ...)
__attribute__ (( format( printf, 2, 3) ));
#endif
UTSTRING_UNUSED static void utstring_printf(UT_string *s, const char *fmt, ...) {
va_list ap;
va_start(ap,fmt);
utstring_printf_va(s,fmt,ap);
va_end(ap);
}
/*******************************************************************************
* begin substring search functions *
******************************************************************************/
/* Build KMP table from left to right. */
UTSTRING_UNUSED static void _utstring_BuildTable(
const char *P_Needle,
size_t P_NeedleLen,
long *P_KMP_Table)
{
long i, j;
i = 0;
j = i - 1;
P_KMP_Table[i] = j;
while (i < (long) P_NeedleLen)
{
while ( (j > -1) && (P_Needle[i] != P_Needle[j]) )
{
j = P_KMP_Table[j];
}
i++;
j++;
if (i < (long) P_NeedleLen)
{
if (P_Needle[i] == P_Needle[j])
{
P_KMP_Table[i] = P_KMP_Table[j];
}
else
{
P_KMP_Table[i] = j;
}
}
else
{
P_KMP_Table[i] = j;
}
}
return;
}
/* Build KMP table from right to left. */
UTSTRING_UNUSED static void _utstring_BuildTableR(
const char *P_Needle,
size_t P_NeedleLen,
long *P_KMP_Table)
{
long i, j;
i = P_NeedleLen - 1;
j = i + 1;
P_KMP_Table[i + 1] = j;
while (i >= 0)
{
while ( (j < (long) P_NeedleLen) && (P_Needle[i] != P_Needle[j]) )
{
j = P_KMP_Table[j + 1];
}
i--;
j--;
if (i >= 0)
{
if (P_Needle[i] == P_Needle[j])
{
P_KMP_Table[i + 1] = P_KMP_Table[j + 1];
}
else
{
P_KMP_Table[i + 1] = j;
}
}
else
{
P_KMP_Table[i + 1] = j;
}
}
return;
}
/* Search data from left to right. ( Multiple search mode. ) */
UTSTRING_UNUSED static long _utstring_find(
const char *P_Haystack,
size_t P_HaystackLen,
const char *P_Needle,
size_t P_NeedleLen,
long *P_KMP_Table)
{
long i, j;
long V_FindPosition = -1;
/* Search from left to right. */
i = j = 0;
while ( (j < (int)P_HaystackLen) && (((P_HaystackLen - j) + i) >= P_NeedleLen) )
{
while ( (i > -1) && (P_Needle[i] != P_Haystack[j]) )
{
i = P_KMP_Table[i];
}
i++;
j++;
if (i >= (int)P_NeedleLen)
{
/* Found. */
V_FindPosition = j - i;
break;
}
}
return V_FindPosition;
}
/* Search data from right to left. ( Multiple search mode. ) */
UTSTRING_UNUSED static long _utstring_findR(
const char *P_Haystack,
size_t P_HaystackLen,
const char *P_Needle,
size_t P_NeedleLen,
long *P_KMP_Table)
{
long i, j;
long V_FindPosition = -1;
/* Search from right to left. */
j = (P_HaystackLen - 1);
i = (P_NeedleLen - 1);
while ( (j >= 0) && (j >= i) )
{
while ( (i < (int)P_NeedleLen) && (P_Needle[i] != P_Haystack[j]) )
{
i = P_KMP_Table[i + 1];
}
i--;
j--;
if (i < 0)
{
/* Found. */
V_FindPosition = j + 1;
break;
}
}
return V_FindPosition;
}
/* Search data from left to right. ( One time search mode. ) */
UTSTRING_UNUSED static long utstring_find(
UT_string *s,
long P_StartPosition, /* Start from 0. -1 means last position. */
const char *P_Needle,
size_t P_NeedleLen)
{
long V_StartPosition;
long V_HaystackLen;
long *V_KMP_Table;
long V_FindPosition = -1;
if (P_StartPosition < 0)
{
V_StartPosition = s->i + P_StartPosition;
}
else
{
V_StartPosition = P_StartPosition;
}
V_HaystackLen = s->i - V_StartPosition;
if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) )
{
V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1));
if (V_KMP_Table != NULL)
{
_utstring_BuildTable(P_Needle, P_NeedleLen, V_KMP_Table);
V_FindPosition = _utstring_find(s->d + V_StartPosition,
V_HaystackLen,
P_Needle,
P_NeedleLen,
V_KMP_Table);
if (V_FindPosition >= 0)
{
V_FindPosition += V_StartPosition;
}
free(V_KMP_Table);
}
}
return V_FindPosition;
}
/* Search data from right to left. ( One time search mode. ) */
UTSTRING_UNUSED static long utstring_findR(
UT_string *s,
long P_StartPosition, /* Start from 0. -1 means last position. */
const char *P_Needle,
size_t P_NeedleLen)
{
long V_StartPosition;
long V_HaystackLen;
long *V_KMP_Table;
long V_FindPosition = -1;
if (P_StartPosition < 0)
{
V_StartPosition = s->i + P_StartPosition;
}
else
{
V_StartPosition = P_StartPosition;
}
V_HaystackLen = V_StartPosition + 1;
if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) )
{
V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1));
if (V_KMP_Table != NULL)
{
_utstring_BuildTableR(P_Needle, P_NeedleLen, V_KMP_Table);
V_FindPosition = _utstring_findR(s->d,
V_HaystackLen,
P_Needle,
P_NeedleLen,
V_KMP_Table);
free(V_KMP_Table);
}
}
return V_FindPosition;
}
/*******************************************************************************
* end substring search functions *
******************************************************************************/
#endif /* UTSTRING_H */

View File

@ -28,9 +28,9 @@ MAKE_FLAGS += -j$(shell cat /proc/cpuinfo | grep processor | wc -l)
endif
endif
.PHONY : demo conntrack netlink trace
.PHONY : demo conntrack netlink trace openrpc configm
all: demo conntrack netlink trace
all: demo conntrack netlink trace openrpc configm
ifeq ($(OPT), install)
#$(shell `find ../release -name "*.zip" -delete`)
@ -111,3 +111,26 @@ else
$(MLOG)make all $(MAKE_FLAGS) -C Platform/build -f user.trace.test.Makefile MLOG=$(MLOG) DISABLE_WARRING=$(DIS_BUILD_WARRING) MAKE_TARGET=trace-test
endif
openrpc:
ifeq ($(OPT), clean)
$(MLOG)make $(MAKE_FLAGS) -C Platform/build -f user.openrpc.Makefile cleanall MLOG=$(MLOG) MAKE_TARGET=openrpc
else ifeq ($(OPT), install)
$(MLOG)make $(MAKE_FLAGS) -C Platform/build -f user.openrpc.Makefile install DIR=$(DIR) MLOG=$(MLOG) MAKE_TARGET=openrpc
else
$(MLOG)make all $(MAKE_FLAGS) -C Platform/build -f user.openrpc.Makefile MLOG=$(MLOG) DISABLE_WARRING=$(DIS_BUILD_WARRING) MAKE_TARGET=openrpc
endif
configm:
ifeq ($(OPT), clean)
$(MLOG)make $(MAKE_FLAGS) -C Platform/build -f user.configm.Makefile cleanall MLOG=$(MLOG) MAKE_TARGET=configm
$(MLOG)make $(MAKE_FLAGS) -C Platform/build -f user.configmapi.Makefile cleanall MLOG=$(MLOG) MAKE_TARGET=configm-api
$(MLOG)make $(MAKE_FLAGS) -C Platform/build -f user.configmtest.Makefile cleanall MLOG=$(MLOG) MAKE_TARGET=configmtest
else ifeq ($(OPT), install)
$(MLOG)make $(MAKE_FLAGS) -C Platform/build -f user.configm.Makefile install DIR=$(DIR) MLOG=$(MLOG) MAKE_TARGET=configm
$(MLOG)make $(MAKE_FLAGS) -C Platform/build -f user.configmapi.Makefile install DIR=$(DIR) MLOG=$(MLOG) MAKE_TARGET=configm-api
$(MLOG)make $(MAKE_FLAGS) -C Platform/build -f user.configmtest.Makefile install DIR=$(DIR) MLOG=$(MLOG) MAKE_TARGET=configmtest
else
$(MLOG)make all $(MAKE_FLAGS) -C Platform/build -f user.configm.Makefile MLOG=$(MLOG) DISABLE_WARRING=$(DIS_BUILD_WARRING) MAKE_TARGET=configm
$(MLOG)make all $(MAKE_FLAGS) -C Platform/build -f user.configmapi.Makefile MLOG=$(MLOG) DISABLE_WARRING=$(DIS_BUILD_WARRING) MAKE_TARGET=configm-api
$(MLOG)make all $(MAKE_FLAGS) -C Platform/build -f user.configmtest.Makefile MLOG=$(MLOG) DISABLE_WARRING=$(DIS_BUILD_WARRING) MAKE_TARGET=configmtest
endif

View File

@ -1,5 +1,5 @@
# target name, the target name must have the same name of c source file
TARGET_NAME=test-trace
TARGET_NAME=configm
# target
# for linux module driver: KO
@ -21,7 +21,7 @@ DEBUG = TRUE
PLAT_LINUX ?= TRUE
PLAT_ARM64 ?= TRUE
VPATH = ../user/configm
VPATH = ../user/configm/config-server
# source code
@ -34,28 +34,28 @@ PLAT_LINUX_SRCS = $(COMMON_SRCS)
PLAT_ARM64_SRCS = $(COMMON_SRCS)
# gcc CFLAGS
PLAT_ARM64_CFLAGS := -I../user/configm/include -I../../Common -I../common/configm -I../common/rpc -I../common/rpc/hashtable
PLAT_ARM64_CFLAGS := -I../user/configm/config-server/include -I../../Common -I../common/configm -I../common/rpc -I../common/rpc/hashtable
PLAT_LINUX_CFLAGS := $(PLAT_ARM64_CFLAGS)
PLAT_ARM64_LDFLAGS :=
PLAT_LINUX_LDFLAGS :=
#gcc libs
ARM64_LIBS := -lpthread -lpthread -lev -lm
LINUX_LIBS := -lpthread -lpthread -lev -lm
ARM64_LIBS := ../thirdparty/arm64/libev.so ./libopenrpc-arm64.so -lpthread -lm
LINUX_LIBS := ../thirdparty/x86_64/libev.so ./libopenrpc-linux.so -lpthread -lm
ifeq ($(PLAT_ARM64), TRUE)
DEPEND_LIB += ./debug/libopenrpc.so
USER_CLEAN_ITEMS += ./libopenrpc.so
DEPEND_LIB += ../thirdparty/arm64/libev.so ./debug/libopenrpc-arm64.so
USER_CLEAN_ITEMS += ./libopenrpc-arm64.so
endif
ifeq ($(PLAT_LINUX), TRUE)
DEPEND_LIB += ./debug/libopenrpc.so
USER_CLEAN_ITEMS += ./debug/libopenrpc.soo
DEPEND_LIB += ../thirdparty/x86_64/libev.so ./debug/libopenrpc-linux.so
USER_CLEAN_ITEMS += ./libopenrpc-linux.so
endif
# this line must be at below of thus, because of...
include ../../Common/common.Makefile

View File

@ -0,0 +1,77 @@
# target name, the target name must have the same name of c source file
TARGET_NAME=libconfigmapi
# target
# for linux module driver: KO
# for application: EXE
# for dynamic library: DLL
TARGET_TYPE = DLL
# target object
# for application: APP
# for device driver: DRV
TARGET_OBJ = APP
# custom install dir
TARGET_BOX =
#debug mode or release mode
DEBUG = TRUE
PLAT_LINUX ?= TRUE
PLAT_ARM64 ?= TRUE
VPATH = ../user/configm/config-api
# source code
# set the source file, don't used .o because of ...
COMMON_SRCS = configclient.c
# MRS Board Source Files
PLAT_LINUX_SRCS = $(COMMON_SRCS)
PLAT_ARM64_SRCS = $(COMMON_SRCS)
# gcc CFLAGS
PLAT_ARM64_CFLAGS := -fPIC -I../../Common -I../common/configm -I../common/rpc -I../common/rpc/hashtable
PLAT_LINUX_CFLAGS := $(PLAT_ARM64_CFLAGS)
PLAT_ARM64_LDFLAGS := -fPIC -shared
PLAT_LINUX_LDFLAGS := $(PLAT_ARM64_LDFLAGS)
#gcc libs
ARM64_LIBS := ../thirdparty/arm64/libev.so ./libopenrpc-arm64.so -lpthread -lm
LINUX_LIBS := ../thirdparty/x86_64/libev.so ./libopenrpc-linux.so -lpthread -lm
ifeq ($(PLAT_ARM64), TRUE)
DEPEND_LIB += ../thirdparty/arm64/libev.so ./debug/libopenrpc-arm64.so
USER_CLEAN_ITEMS += ./libopenrpc-arm64.so
endif
ifeq ($(PLAT_LINUX), TRUE)
DEPEND_LIB += ../thirdparty/x86_64/libev.so ./debug/libopenrpc-linux.so
USER_CLEAN_ITEMS += ./libopenrpc-linux.so
endif
# this line must be at below of thus, because of...
include ../../Common/common.Makefile
ifneq ($(MAKECMDGOALS), clean)
ifneq ($(MAKECMDGOALS), cleanall)
ifneq ($(notdir $(DEPEND_LIB)), $(wildcard $(DEPEND_LIB)))
$(shell $(CP) $(DEPEND_LIB) ./)
endif
endif
endif
ifeq ($(MAKECMDGOALS), )
$(shell find ./ -name "$(TARGET)-*.ko" -delete)
else
ifeq ($(MAKECMDGOALS), all)
$(shell find ./ -name "$(TARGET)-*.ko" -delete)
endif
endif

View File

@ -0,0 +1,77 @@
# target name, the target name must have the same name of c source file
TARGET_NAME=configmtest
# target
# for linux module driver: KO
# for application: EXE
# for dynamic library: DLL
TARGET_TYPE = EXE
# target object
# for application: APP
# for device driver: DRV
TARGET_OBJ = APP
# custom install dir
TARGET_BOX =
#debug mode or release mode
DEBUG = TRUE
PLAT_LINUX ?= TRUE
PLAT_ARM64 ?= TRUE
VPATH = ../user/configm/config-test
# source code
# set the source file, don't used .o because of ...
COMMON_SRCS = configtest.c
# MRS Board Source Files
PLAT_LINUX_SRCS = $(COMMON_SRCS)
PLAT_ARM64_SRCS = $(COMMON_SRCS)
# gcc CFLAGS
PLAT_ARM64_CFLAGS := -I../user/configm/config-server/include -I../../Common -I../common/configm -I../common/rpc -I../common/rpc/hashtable
PLAT_LINUX_CFLAGS := $(PLAT_ARM64_CFLAGS)
PLAT_ARM64_LDFLAGS :=
PLAT_LINUX_LDFLAGS :=
#gcc libs
ARM64_LIBS := ../thirdparty/arm64/libev.so ./libopenrpc-arm64.so ./libconfigmapi-arm64.so -lpthread -lm
LINUX_LIBS := ../thirdparty/x86_64/libev.so ./libopenrpc-linux.so ./libconfigmapi-linux.so -lpthread -lm
ifeq ($(PLAT_ARM64), TRUE)
DEPEND_LIB += ../thirdparty/arm64/libev.so ./debug/libopenrpc-arm64.so ./debug/libconfigmapi-arm64.so
USER_CLEAN_ITEMS += ./libconfigmapi-arm64.so
endif
ifeq ($(PLAT_LINUX), TRUE)
DEPEND_LIB += ../thirdparty/x86_64/libev.so ./debug/libopenrpc-linux.so ./debug/libconfigmapi-linux.so
USER_CLEAN_ITEMS += ./libconfigmapi-linux.so
endif
# this line must be at below of thus, because of...
include ../../Common/common.Makefile
ifneq ($(MAKECMDGOALS), clean)
ifneq ($(MAKECMDGOALS), cleanall)
ifneq ($(notdir $(DEPEND_LIB)), $(wildcard $(DEPEND_LIB)))
$(shell $(CP) $(DEPEND_LIB) ./)
endif
endif
endif
ifeq ($(MAKECMDGOALS), )
$(shell find ./ -name "$(TARGET)-*.ko" -delete)
else
ifeq ($(MAKECMDGOALS), all)
$(shell find ./ -name "$(TARGET)-*.ko" -delete)
endif
endif

View File

@ -1,5 +1,5 @@
# target name, the target name must have the same name of c source file
TARGET_NAME=test-trace
TARGET_NAME=libopenrpc
# target
# for linux module driver: KO
@ -34,7 +34,7 @@ PLAT_LINUX_SRCS = $(COMMON_SRCS)
PLAT_ARM64_SRCS = $(COMMON_SRCS)
# gcc CFLAGS
PLAT_ARM64_CFLAGS := -fPIC -I../../Common -I../common/rpc
PLAT_ARM64_CFLAGS := -fPIC -I../../Common -I../common/rpc -I../common/rpc/hashtable
PLAT_LINUX_CFLAGS := $(PLAT_ARM64_CFLAGS)
@ -43,16 +43,16 @@ PLAT_LINUX_LDFLAGS := $(PLAT_ARM64_LDFLAGS)
#gcc libs
ARM64_LIBS := -lpthread -lev -lm
LINUX_LIBS := -lpthread -lev -lm
ARM64_LIBS := ../thirdparty/arm64/libev.so -lpthread -lm
LINUX_LIBS := ../thirdparty/x86_64/libev.so -lpthread -lm
ifeq ($(PLAT_ARM64), TRUE)
DEPEND_LIB +=
DEPEND_LIB += ../thirdparty/arm64/libev.so
USER_CLEAN_ITEMS +=
endif
ifeq ($(PLAT_LINUX), TRUE)
DEPEND_LIB +=
DEPEND_LIB += ../thirdparty/x86_64/libev.so
USER_CLEAN_ITEMS +=
endif

View File

@ -3,14 +3,9 @@
#include "rpc_common.h"
#include "ipconfig.h"
#include "configmapi.h"
/* 类型定义 */
#define CONFIG_FROM_WEB 0x00000001
#define CONFIG_FROM_NETOPEER 0x00000010
#define CONFIG_FROM_RECOVER1 0x01000000
#define CONFIG_FROM_RECOVER2 0x02000000
/* IP CONFIG */
#define IPCONFIG_MODULE 0x00000001
@ -52,10 +47,6 @@
#define CONFIG_RECOVERY_DONE "/tmp/config_recovery"
typedef struct _config_message config_msg_t;
typedef struct _config_service config_service_t;
typedef ret_code (*cm_config_chk)(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len);
@ -72,16 +63,6 @@ typedef ret_code (*cm_config_get_all)(uint source, uint64 config_id,
pointer output, short *single_len,
int *output_len);
/* 结构体定义 */
/* 配置消息 */
struct _config_message {
uint64 config_id; /*配置ID*/
uint source; /*配置来源*/
uint config_type; /*配置类型adddelset*/
char config_buff[0]; /*配置数据缓存*/
};
/* 配置注册 */
struct _config_service {
uint64 config_id; /* 配置ID全局唯一用于寻找对应的配置业务*/
@ -94,15 +75,10 @@ struct _config_service {
cm_config_get_all getall_callback; /* 获取所有配置接口 */
};
/* 函数声明 */
typedef struct _config_service config_service_t;
ret_code web_config_exec_sync(uint config_type, uint64 config_id,
char* config_data, int config_len,
char**output, int *output_len);
ret_code web_config_exec_async(uint config_type, uint64 config_id,
char* config_data, int config_len,
rpc_callback callback, pointer data);
#endif /* RPC_COMMON_H_ */

View File

@ -0,0 +1,32 @@
#ifndef CONFIGMAPI_H_
#define CONFIGMAPI_H_
#include "rpc_common.h"
#define CONFIG_FROM_WEB 0x00000001
#define CONFIG_FROM_NETOPEER 0x00000010
#define CONFIG_FROM_RECOVER1 0x01000000
#define CONFIG_FROM_RECOVER2 0x02000000
/* 结构体定义 */
/* 配置消息 */
struct _config_message {
uint64 config_id; /*配置ID*/
uint source; /*配置来源*/
uint config_type; /*配置类型adddelset*/
char config_buff[0]; /*配置数据缓存*/
};
typedef struct _config_message config_msg_t;
/* 函数声明 */
ret_code web_config_exec_sync(uint config_type, uint64 config_id,
char* config_data, int config_len,
char**output, int *output_len);
ret_code web_config_exec_async(uint config_type, uint64 config_id,
char* config_data, int config_len,
rpc_callback callback, pointer data);
#endif /* RPC_COMMON_H_ */

854
Platform/common/rpc/ev.h Executable file
View File

@ -0,0 +1,854 @@
/*
* libev native API header
*
* Copyright (c) 2007,2008,2009,2010,2011,2012,2015 Marc Alexander Lehmann <libev@schmorp.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
* CIAL, 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 OTH-
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License ("GPL") version 2 or any later version,
* in which case the provisions of the GPL are applicable instead of
* the above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the BSD license, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file under
* either the BSD or the GPL.
*/
#ifndef EV_H_
#define EV_H_
#ifdef __cplusplus
# define EV_CPP(x) x
# if __cplusplus >= 201103L
# define EV_THROW noexcept
# else
# define EV_THROW throw ()
# endif
#else
# define EV_CPP(x)
# define EV_THROW
#endif
EV_CPP(extern "C" {)
/*****************************************************************************/
/* pre-4.0 compatibility */
#ifndef EV_COMPAT3
# define EV_COMPAT3 1
#endif
#ifndef EV_FEATURES
# if defined __OPTIMIZE_SIZE__
# define EV_FEATURES 0x7c
# else
# define EV_FEATURES 0x7f
# endif
#endif
#define EV_FEATURE_CODE ((EV_FEATURES) & 1)
#define EV_FEATURE_DATA ((EV_FEATURES) & 2)
#define EV_FEATURE_CONFIG ((EV_FEATURES) & 4)
#define EV_FEATURE_API ((EV_FEATURES) & 8)
#define EV_FEATURE_WATCHERS ((EV_FEATURES) & 16)
#define EV_FEATURE_BACKENDS ((EV_FEATURES) & 32)
#define EV_FEATURE_OS ((EV_FEATURES) & 64)
/* these priorities are inclusive, higher priorities will be invoked earlier */
#ifndef EV_MINPRI
# define EV_MINPRI (EV_FEATURE_CONFIG ? -2 : 0)
#endif
#ifndef EV_MAXPRI
# define EV_MAXPRI (EV_FEATURE_CONFIG ? +2 : 0)
#endif
#ifndef EV_MULTIPLICITY
# define EV_MULTIPLICITY EV_FEATURE_CONFIG
#endif
#ifndef EV_PERIODIC_ENABLE
# define EV_PERIODIC_ENABLE EV_FEATURE_WATCHERS
#endif
#ifndef EV_STAT_ENABLE
# define EV_STAT_ENABLE EV_FEATURE_WATCHERS
#endif
#ifndef EV_PREPARE_ENABLE
# define EV_PREPARE_ENABLE EV_FEATURE_WATCHERS
#endif
#ifndef EV_CHECK_ENABLE
# define EV_CHECK_ENABLE EV_FEATURE_WATCHERS
#endif
#ifndef EV_IDLE_ENABLE
# define EV_IDLE_ENABLE EV_FEATURE_WATCHERS
#endif
#ifndef EV_FORK_ENABLE
# define EV_FORK_ENABLE EV_FEATURE_WATCHERS
#endif
#ifndef EV_CLEANUP_ENABLE
# define EV_CLEANUP_ENABLE EV_FEATURE_WATCHERS
#endif
#ifndef EV_SIGNAL_ENABLE
# define EV_SIGNAL_ENABLE EV_FEATURE_WATCHERS
#endif
#ifndef EV_CHILD_ENABLE
# ifdef _WIN32
# define EV_CHILD_ENABLE 0
# else
# define EV_CHILD_ENABLE EV_FEATURE_WATCHERS
#endif
#endif
#ifndef EV_ASYNC_ENABLE
# define EV_ASYNC_ENABLE EV_FEATURE_WATCHERS
#endif
#ifndef EV_EMBED_ENABLE
# define EV_EMBED_ENABLE EV_FEATURE_WATCHERS
#endif
#ifndef EV_WALK_ENABLE
# define EV_WALK_ENABLE 0 /* not yet */
#endif
/*****************************************************************************/
#if EV_CHILD_ENABLE && !EV_SIGNAL_ENABLE
# undef EV_SIGNAL_ENABLE
# define EV_SIGNAL_ENABLE 1
#endif
/*****************************************************************************/
typedef double ev_tstamp;
#include <string.h> /* for memmove */
#ifndef EV_ATOMIC_T
# include <signal.h>
# define EV_ATOMIC_T sig_atomic_t volatile
#endif
#if EV_STAT_ENABLE
# ifdef _WIN32
# include <time.h>
# include <sys/types.h>
# endif
# include <sys/stat.h>
#endif
/* support multiple event loops? */
#if EV_MULTIPLICITY
struct ev_loop;
# define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */
# define EV_P_ EV_P, /* a loop as first of multiple parameters */
# define EV_A loop /* a loop as sole argument to a function call */
# define EV_A_ EV_A, /* a loop as first of multiple arguments */
# define EV_DEFAULT_UC ev_default_loop_uc_ () /* the default loop, if initialised, as sole arg */
# define EV_DEFAULT_UC_ EV_DEFAULT_UC, /* the default loop as first of multiple arguments */
# define EV_DEFAULT ev_default_loop (0) /* the default loop as sole arg */
# define EV_DEFAULT_ EV_DEFAULT, /* the default loop as first of multiple arguments */
#else
# define EV_P void
# define EV_P_
# define EV_A
# define EV_A_
# define EV_DEFAULT
# define EV_DEFAULT_
# define EV_DEFAULT_UC
# define EV_DEFAULT_UC_
# undef EV_EMBED_ENABLE
#endif
/* EV_INLINE is used for functions in header files */
#if __STDC_VERSION__ >= 199901L || __GNUC__ >= 3
# define EV_INLINE static inline
#else
# define EV_INLINE static
#endif
#ifdef EV_API_STATIC
# define EV_API_DECL static
#else
# define EV_API_DECL extern
#endif
/* EV_PROTOTYPES can be used to switch of prototype declarations */
#ifndef EV_PROTOTYPES
# define EV_PROTOTYPES 1
#endif
/*****************************************************************************/
#define EV_VERSION_MAJOR 4
#define EV_VERSION_MINOR 22
/* eventmask, revents, events... */
enum {
EV_UNDEF = (int)0xFFFFFFFF, /* guaranteed to be invalid */
EV_NONE = 0x00, /* no events */
EV_READ = 0x01, /* ev_io detected read will not block */
EV_WRITE = 0x02, /* ev_io detected write will not block */
EV__IOFDSET = 0x80, /* internal use only */
EV_IO = EV_READ, /* alias for type-detection */
EV_TIMER = 0x00000100, /* timer timed out */
#if EV_COMPAT3
EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */
#endif
EV_PERIODIC = 0x00000200, /* periodic timer timed out */
EV_SIGNAL = 0x00000400, /* signal was received */
EV_CHILD = 0x00000800, /* child/pid had status change */
EV_STAT = 0x00001000, /* stat data changed */
EV_IDLE = 0x00002000, /* event loop is idling */
EV_PREPARE = 0x00004000, /* event loop about to poll */
EV_CHECK = 0x00008000, /* event loop finished poll */
EV_EMBED = 0x00010000, /* embedded event loop needs sweep */
EV_FORK = 0x00020000, /* event loop resumed in child */
EV_CLEANUP = 0x00040000, /* event loop resumed in child */
EV_ASYNC = 0x00080000, /* async intra-loop signal */
EV_CUSTOM = 0x01000000, /* for use by user code */
EV_ERROR = (int)0x80000000 /* sent when an error occurs */
};
/* can be used to add custom fields to all watchers, while losing binary compatibility */
#ifndef EV_COMMON
# define EV_COMMON void *data;
#endif
#ifndef EV_CB_DECLARE
# define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents);
#endif
#ifndef EV_CB_INVOKE
# define EV_CB_INVOKE(watcher,revents) (watcher)->cb (EV_A_ (watcher), (revents))
#endif
/* not official, do not use */
#define EV_CB(type,name) void name (EV_P_ struct ev_ ## type *w, int revents)
/*
* struct member types:
* private: you may look at them, but not change them,
* and they might not mean anything to you.
* ro: can be read anytime, but only changed when the watcher isn't active.
* rw: can be read and modified anytime, even when the watcher is active.
*
* some internal details that might be helpful for debugging:
*
* active is either 0, which means the watcher is not active,
* or the array index of the watcher (periodics, timers)
* or the array index + 1 (most other watchers)
* or simply 1 for watchers that aren't in some array.
* pending is either 0, in which case the watcher isn't,
* or the array index + 1 in the pendings array.
*/
#if EV_MINPRI == EV_MAXPRI
# define EV_DECL_PRIORITY
#elif !defined (EV_DECL_PRIORITY)
# define EV_DECL_PRIORITY int priority;
#endif
/* shared by all watchers */
#define EV_WATCHER(type) \
int active; /* private */ \
int pending; /* private */ \
EV_DECL_PRIORITY /* private */ \
EV_COMMON /* rw */ \
EV_CB_DECLARE (type) /* private */
#define EV_WATCHER_LIST(type) \
EV_WATCHER (type) \
struct ev_watcher_list *next; /* private */
#define EV_WATCHER_TIME(type) \
EV_WATCHER (type) \
ev_tstamp at; /* private */
/* base class, nothing to see here unless you subclass */
typedef struct ev_watcher
{
EV_WATCHER (ev_watcher)
} ev_watcher;
/* base class, nothing to see here unless you subclass */
typedef struct ev_watcher_list
{
EV_WATCHER_LIST (ev_watcher_list)
} ev_watcher_list;
/* base class, nothing to see here unless you subclass */
typedef struct ev_watcher_time
{
EV_WATCHER_TIME (ev_watcher_time)
} ev_watcher_time;
/* invoked when fd is either EV_READable or EV_WRITEable */
/* revent EV_READ, EV_WRITE */
typedef struct ev_io
{
EV_WATCHER_LIST (ev_io)
int fd; /* ro */
int events; /* ro */
} ev_io;
/* invoked after a specific time, repeatable (based on monotonic clock) */
/* revent EV_TIMEOUT */
typedef struct ev_timer
{
EV_WATCHER_TIME (ev_timer)
ev_tstamp repeat; /* rw */
} ev_timer;
/* invoked at some specific time, possibly repeating at regular intervals (based on UTC) */
/* revent EV_PERIODIC */
typedef struct ev_periodic
{
EV_WATCHER_TIME (ev_periodic)
ev_tstamp offset; /* rw */
ev_tstamp interval; /* rw */
ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) EV_THROW; /* rw */
} ev_periodic;
/* invoked when the given signal has been received */
/* revent EV_SIGNAL */
typedef struct ev_signal
{
EV_WATCHER_LIST (ev_signal)
int signum; /* ro */
} ev_signal;
/* invoked when sigchld is received and waitpid indicates the given pid */
/* revent EV_CHILD */
/* does not support priorities */
typedef struct ev_child
{
EV_WATCHER_LIST (ev_child)
int flags; /* private */
int pid; /* ro */
int rpid; /* rw, holds the received pid */
int rstatus; /* rw, holds the exit status, use the macros from sys/wait.h */
} ev_child;
#if EV_STAT_ENABLE
/* st_nlink = 0 means missing file or other error */
# ifdef _WIN32
typedef struct _stati64 ev_statdata;
# else
typedef struct stat ev_statdata;
# endif
/* invoked each time the stat data changes for a given path */
/* revent EV_STAT */
typedef struct ev_stat
{
EV_WATCHER_LIST (ev_stat)
ev_timer timer; /* private */
ev_tstamp interval; /* ro */
const char *path; /* ro */
ev_statdata prev; /* ro */
ev_statdata attr; /* ro */
int wd; /* wd for inotify, fd for kqueue */
} ev_stat;
#endif
#if EV_IDLE_ENABLE
/* invoked when the nothing else needs to be done, keeps the process from blocking */
/* revent EV_IDLE */
typedef struct ev_idle
{
EV_WATCHER (ev_idle)
} ev_idle;
#endif
/* invoked for each run of the mainloop, just before the blocking call */
/* you can still change events in any way you like */
/* revent EV_PREPARE */
typedef struct ev_prepare
{
EV_WATCHER (ev_prepare)
} ev_prepare;
/* invoked for each run of the mainloop, just after the blocking call */
/* revent EV_CHECK */
typedef struct ev_check
{
EV_WATCHER (ev_check)
} ev_check;
#if EV_FORK_ENABLE
/* the callback gets invoked before check in the child process when a fork was detected */
/* revent EV_FORK */
typedef struct ev_fork
{
EV_WATCHER (ev_fork)
} ev_fork;
#endif
#if EV_CLEANUP_ENABLE
/* is invoked just before the loop gets destroyed */
/* revent EV_CLEANUP */
typedef struct ev_cleanup
{
EV_WATCHER (ev_cleanup)
} ev_cleanup;
#endif
#if EV_EMBED_ENABLE
/* used to embed an event loop inside another */
/* the callback gets invoked when the event loop has handled events, and can be 0 */
typedef struct ev_embed
{
EV_WATCHER (ev_embed)
struct ev_loop *other; /* ro */
ev_io io; /* private */
ev_prepare prepare; /* private */
ev_check check; /* unused */
ev_timer timer; /* unused */
ev_periodic periodic; /* unused */
ev_idle idle; /* unused */
ev_fork fork; /* private */
#if EV_CLEANUP_ENABLE
ev_cleanup cleanup; /* unused */
#endif
} ev_embed;
#endif
#if EV_ASYNC_ENABLE
/* invoked when somebody calls ev_async_send on the watcher */
/* revent EV_ASYNC */
typedef struct ev_async
{
EV_WATCHER (ev_async)
EV_ATOMIC_T sent; /* private */
} ev_async;
# define ev_async_pending(w) (+(w)->sent)
#endif
/* the presence of this union forces similar struct layout */
union ev_any_watcher
{
struct ev_watcher w;
struct ev_watcher_list wl;
struct ev_io io;
struct ev_timer timer;
struct ev_periodic periodic;
struct ev_signal signal;
struct ev_child child;
#if EV_STAT_ENABLE
struct ev_stat stat;
#endif
#if EV_IDLE_ENABLE
struct ev_idle idle;
#endif
struct ev_prepare prepare;
struct ev_check check;
#if EV_FORK_ENABLE
struct ev_fork fork;
#endif
#if EV_CLEANUP_ENABLE
struct ev_cleanup cleanup;
#endif
#if EV_EMBED_ENABLE
struct ev_embed embed;
#endif
#if EV_ASYNC_ENABLE
struct ev_async async;
#endif
};
/* flag bits for ev_default_loop and ev_loop_new */
enum {
/* the default */
EVFLAG_AUTO = 0x00000000U, /* not quite a mask */
/* flag bits */
EVFLAG_NOENV = 0x01000000U, /* do NOT consult environment */
EVFLAG_FORKCHECK = 0x02000000U, /* check for a fork in each iteration */
/* debugging/feature disable */
EVFLAG_NOINOTIFY = 0x00100000U, /* do not attempt to use inotify */
#if EV_COMPAT3
EVFLAG_NOSIGFD = 0, /* compatibility to pre-3.9 */
#endif
EVFLAG_SIGNALFD = 0x00200000U, /* attempt to use signalfd */
EVFLAG_NOSIGMASK = 0x00400000U /* avoid modifying the signal mask */
};
/* method bits to be ored together */
enum {
EVBACKEND_SELECT = 0x00000001U, /* about anywhere */
EVBACKEND_POLL = 0x00000002U, /* !win */
EVBACKEND_EPOLL = 0x00000004U, /* linux */
EVBACKEND_KQUEUE = 0x00000008U, /* bsd */
EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */
EVBACKEND_PORT = 0x00000020U, /* solaris 10 */
EVBACKEND_ALL = 0x0000003FU, /* all known backends */
EVBACKEND_MASK = 0x0000FFFFU /* all future backends */
};
#if EV_PROTOTYPES
EV_API_DECL int ev_version_major (void) EV_THROW;
EV_API_DECL int ev_version_minor (void) EV_THROW;
EV_API_DECL unsigned int ev_supported_backends (void) EV_THROW;
EV_API_DECL unsigned int ev_recommended_backends (void) EV_THROW;
EV_API_DECL unsigned int ev_embeddable_backends (void) EV_THROW;
EV_API_DECL ev_tstamp ev_time (void) EV_THROW;
EV_API_DECL void ev_sleep (ev_tstamp delay) EV_THROW; /* sleep for a while */
/* Sets the allocation function to use, works like realloc.
* It is used to allocate and free memory.
* If it returns zero when memory needs to be allocated, the library might abort
* or take some potentially destructive action.
* The default is your system realloc function.
*/
EV_API_DECL void ev_set_allocator (void *(*cb)(void *ptr, long size) EV_THROW) EV_THROW;
/* set the callback function to call on a
* retryable syscall error
* (such as failed select, poll, epoll_wait)
*/
EV_API_DECL void ev_set_syserr_cb (void (*cb)(const char *msg) EV_THROW) EV_THROW;
#if EV_MULTIPLICITY
/* the default loop is the only one that handles signals and child watchers */
/* you can call this as often as you like */
EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_THROW;
#ifdef EV_API_STATIC
EV_API_DECL struct ev_loop *ev_default_loop_ptr;
#endif
EV_INLINE struct ev_loop *
ev_default_loop_uc_ (void) EV_THROW
{
extern struct ev_loop *ev_default_loop_ptr;
return ev_default_loop_ptr;
}
EV_INLINE int
ev_is_default_loop (EV_P) EV_THROW
{
return EV_A == EV_DEFAULT_UC;
}
/* create and destroy alternative loops that don't handle signals */
EV_API_DECL struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0)) EV_THROW;
EV_API_DECL ev_tstamp ev_now (EV_P) EV_THROW; /* time w.r.t. timers and the eventloop, updated after each poll */
#else
EV_API_DECL int ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_THROW; /* returns true when successful */
EV_API_DECL ev_tstamp ev_rt_now;
EV_INLINE ev_tstamp
ev_now (void) EV_THROW
{
return ev_rt_now;
}
/* looks weird, but ev_is_default_loop (EV_A) still works if this exists */
EV_INLINE int
ev_is_default_loop (void) EV_THROW
{
return 1;
}
#endif /* multiplicity */
/* destroy event loops, also works for the default loop */
EV_API_DECL void ev_loop_destroy (EV_P);
/* this needs to be called after fork, to duplicate the loop */
/* when you want to re-use it in the child */
/* you can call it in either the parent or the child */
/* you can actually call it at any time, anywhere :) */
EV_API_DECL void ev_loop_fork (EV_P) EV_THROW;
EV_API_DECL unsigned int ev_backend (EV_P) EV_THROW; /* backend in use by loop */
EV_API_DECL void ev_now_update (EV_P) EV_THROW; /* update event loop time */
#if EV_WALK_ENABLE
/* walk (almost) all watchers in the loop of a given type, invoking the */
/* callback on every such watcher. The callback might stop the watcher, */
/* but do nothing else with the loop */
EV_API_DECL void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_THROW;
#endif
#endif /* prototypes */
/* ev_run flags values */
enum {
EVRUN_NOWAIT = 1, /* do not block/wait */
EVRUN_ONCE = 2 /* block *once* only */
};
/* ev_break how values */
enum {
EVBREAK_CANCEL = 0, /* undo unloop */
EVBREAK_ONE = 1, /* unloop once */
EVBREAK_ALL = 2 /* unloop all loops */
};
#if EV_PROTOTYPES
EV_API_DECL int ev_run (EV_P_ int flags EV_CPP (= 0));
EV_API_DECL void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)) EV_THROW; /* break out of the loop */
/*
* ref/unref can be used to add or remove a refcount on the mainloop. every watcher
* keeps one reference. if you have a long-running watcher you never unregister that
* should not keep ev_loop from running, unref() after starting, and ref() before stopping.
*/
EV_API_DECL void ev_ref (EV_P) EV_THROW;
EV_API_DECL void ev_unref (EV_P) EV_THROW;
/*
* convenience function, wait for a single event, without registering an event watcher
* if timeout is < 0, do wait indefinitely
*/
EV_API_DECL void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_THROW;
# if EV_FEATURE_API
EV_API_DECL unsigned int ev_iteration (EV_P) EV_THROW; /* number of loop iterations */
EV_API_DECL unsigned int ev_depth (EV_P) EV_THROW; /* #ev_loop enters - #ev_loop leaves */
EV_API_DECL void ev_verify (EV_P) EV_THROW; /* abort if loop data corrupted */
EV_API_DECL void ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_THROW; /* sleep at least this time, default 0 */
EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_THROW; /* sleep at least this time, default 0 */
/* advanced stuff for threading etc. support, see docs */
EV_API_DECL void ev_set_userdata (EV_P_ void *data) EV_THROW;
EV_API_DECL void *ev_userdata (EV_P) EV_THROW;
typedef void (*ev_loop_callback)(EV_P);
EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW;
/* C++ doesn't allow the use of the ev_loop_callback typedef here, so we need to spell it out */
EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW;
EV_API_DECL unsigned int ev_pending_count (EV_P) EV_THROW; /* number of pending events, if any */
EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */
/*
* stop/start the timer handling.
*/
EV_API_DECL void ev_suspend (EV_P) EV_THROW;
EV_API_DECL void ev_resume (EV_P) EV_THROW;
#endif
#endif
/* these may evaluate ev multiple times, and the other arguments at most once */
/* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */
#define ev_init(ev,cb_) do { \
((ev_watcher *)(void *)(ev))->active = \
((ev_watcher *)(void *)(ev))->pending = 0; \
ev_set_priority ((ev), 0); \
ev_set_cb ((ev), cb_); \
} while (0)
#define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_) | EV__IOFDSET; } while (0)
#define ev_timer_set(ev,after_,repeat_) do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0)
#define ev_periodic_set(ev,ofs_,ival_,rcb_) do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0)
#define ev_signal_set(ev,signum_) do { (ev)->signum = (signum_); } while (0)
#define ev_child_set(ev,pid_,trace_) do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0)
#define ev_stat_set(ev,path_,interval_) do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0)
#define ev_idle_set(ev) /* nop, yes, this is a serious in-joke */
#define ev_prepare_set(ev) /* nop, yes, this is a serious in-joke */
#define ev_check_set(ev) /* nop, yes, this is a serious in-joke */
#define ev_embed_set(ev,other_) do { (ev)->other = (other_); } while (0)
#define ev_fork_set(ev) /* nop, yes, this is a serious in-joke */
#define ev_cleanup_set(ev) /* nop, yes, this is a serious in-joke */
#define ev_async_set(ev) /* nop, yes, this is a serious in-joke */
#define ev_io_init(ev,cb,fd,events) do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)
#define ev_timer_init(ev,cb,after,repeat) do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0)
#define ev_periodic_init(ev,cb,ofs,ival,rcb) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(ofs),(ival),(rcb)); } while (0)
#define ev_signal_init(ev,cb,signum) do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0)
#define ev_child_init(ev,cb,pid,trace) do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0)
#define ev_stat_init(ev,cb,path,interval) do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0)
#define ev_idle_init(ev,cb) do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0)
#define ev_prepare_init(ev,cb) do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0)
#define ev_check_init(ev,cb) do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0)
#define ev_embed_init(ev,cb,other) do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0)
#define ev_fork_init(ev,cb) do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0)
#define ev_cleanup_init(ev,cb) do { ev_init ((ev), (cb)); ev_cleanup_set ((ev)); } while (0)
#define ev_async_init(ev,cb) do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0)
#define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */
#define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */
#define ev_cb_(ev) (ev)->cb /* rw */
#define ev_cb(ev) (memmove (&ev_cb_ (ev), &((ev_watcher *)(ev))->cb, sizeof (ev_cb_ (ev))), (ev)->cb)
#if EV_MINPRI == EV_MAXPRI
# define ev_priority(ev) ((ev), EV_MINPRI)
# define ev_set_priority(ev,pri) ((ev), (pri))
#else
# define ev_priority(ev) (+(((ev_watcher *)(void *)(ev))->priority))
# define ev_set_priority(ev,pri) ( (ev_watcher *)(void *)(ev))->priority = (pri)
#endif
#define ev_periodic_at(ev) (+((ev_watcher_time *)(ev))->at)
#ifndef ev_set_cb
# define ev_set_cb(ev,cb_) (ev_cb_ (ev) = (cb_), memmove (&((ev_watcher *)(ev))->cb, &ev_cb_ (ev), sizeof (ev_cb_ (ev))))
#endif
/* stopping (enabling, adding) a watcher does nothing if it is already running */
/* stopping (disabling, deleting) a watcher does nothing unless it's already running */
#if EV_PROTOTYPES
/* feeds an event into a watcher as if the event actually occurred */
/* accepts any ev_watcher type */
EV_API_DECL void ev_feed_event (EV_P_ void *w, int revents) EV_THROW;
EV_API_DECL void ev_feed_fd_event (EV_P_ int fd, int revents) EV_THROW;
#if EV_SIGNAL_ENABLE
EV_API_DECL void ev_feed_signal (int signum) EV_THROW;
EV_API_DECL void ev_feed_signal_event (EV_P_ int signum) EV_THROW;
#endif
EV_API_DECL void ev_invoke (EV_P_ void *w, int revents);
EV_API_DECL int ev_clear_pending (EV_P_ void *w) EV_THROW;
EV_API_DECL void ev_io_start (EV_P_ ev_io *w) EV_THROW;
EV_API_DECL void ev_io_stop (EV_P_ ev_io *w) EV_THROW;
EV_API_DECL void ev_timer_start (EV_P_ ev_timer *w) EV_THROW;
EV_API_DECL void ev_timer_stop (EV_P_ ev_timer *w) EV_THROW;
/* stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */
EV_API_DECL void ev_timer_again (EV_P_ ev_timer *w) EV_THROW;
/* return remaining time */
EV_API_DECL ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW;
#if EV_PERIODIC_ENABLE
EV_API_DECL void ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW;
EV_API_DECL void ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW;
EV_API_DECL void ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW;
#endif
/* only supported in the default loop */
#if EV_SIGNAL_ENABLE
EV_API_DECL void ev_signal_start (EV_P_ ev_signal *w) EV_THROW;
EV_API_DECL void ev_signal_stop (EV_P_ ev_signal *w) EV_THROW;
#endif
/* only supported in the default loop */
# if EV_CHILD_ENABLE
EV_API_DECL void ev_child_start (EV_P_ ev_child *w) EV_THROW;
EV_API_DECL void ev_child_stop (EV_P_ ev_child *w) EV_THROW;
# endif
# if EV_STAT_ENABLE
EV_API_DECL void ev_stat_start (EV_P_ ev_stat *w) EV_THROW;
EV_API_DECL void ev_stat_stop (EV_P_ ev_stat *w) EV_THROW;
EV_API_DECL void ev_stat_stat (EV_P_ ev_stat *w) EV_THROW;
# endif
# if EV_IDLE_ENABLE
EV_API_DECL void ev_idle_start (EV_P_ ev_idle *w) EV_THROW;
EV_API_DECL void ev_idle_stop (EV_P_ ev_idle *w) EV_THROW;
# endif
#if EV_PREPARE_ENABLE
EV_API_DECL void ev_prepare_start (EV_P_ ev_prepare *w) EV_THROW;
EV_API_DECL void ev_prepare_stop (EV_P_ ev_prepare *w) EV_THROW;
#endif
#if EV_CHECK_ENABLE
EV_API_DECL void ev_check_start (EV_P_ ev_check *w) EV_THROW;
EV_API_DECL void ev_check_stop (EV_P_ ev_check *w) EV_THROW;
#endif
# if EV_FORK_ENABLE
EV_API_DECL void ev_fork_start (EV_P_ ev_fork *w) EV_THROW;
EV_API_DECL void ev_fork_stop (EV_P_ ev_fork *w) EV_THROW;
# endif
# if EV_CLEANUP_ENABLE
EV_API_DECL void ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW;
EV_API_DECL void ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_THROW;
# endif
# if EV_EMBED_ENABLE
/* only supported when loop to be embedded is in fact embeddable */
EV_API_DECL void ev_embed_start (EV_P_ ev_embed *w) EV_THROW;
EV_API_DECL void ev_embed_stop (EV_P_ ev_embed *w) EV_THROW;
EV_API_DECL void ev_embed_sweep (EV_P_ ev_embed *w) EV_THROW;
# endif
# if EV_ASYNC_ENABLE
EV_API_DECL void ev_async_start (EV_P_ ev_async *w) EV_THROW;
EV_API_DECL void ev_async_stop (EV_P_ ev_async *w) EV_THROW;
EV_API_DECL void ev_async_send (EV_P_ ev_async *w) EV_THROW;
# endif
#if EV_COMPAT3
#define EVLOOP_NONBLOCK EVRUN_NOWAIT
#define EVLOOP_ONESHOT EVRUN_ONCE
#define EVUNLOOP_CANCEL EVBREAK_CANCEL
#define EVUNLOOP_ONE EVBREAK_ONE
#define EVUNLOOP_ALL EVBREAK_ALL
#if EV_PROTOTYPES
EV_INLINE void ev_loop (EV_P_ int flags) { ev_run (EV_A_ flags); }
EV_INLINE void ev_unloop (EV_P_ int how ) { ev_break (EV_A_ how ); }
EV_INLINE void ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); }
EV_INLINE void ev_default_fork (void) { ev_loop_fork (EV_DEFAULT); }
#if EV_FEATURE_API
EV_INLINE unsigned int ev_loop_count (EV_P) { return ev_iteration (EV_A); }
EV_INLINE unsigned int ev_loop_depth (EV_P) { return ev_depth (EV_A); }
EV_INLINE void ev_loop_verify (EV_P) { ev_verify (EV_A); }
#endif
#endif
#else
typedef struct ev_loop ev_loop;
#endif
#endif
EV_CPP(})
#endif

BIN
Platform/thirdparty/arm64/libev.so vendored Normal file

Binary file not shown.

BIN
Platform/thirdparty/x86_64/libev.so vendored Executable file

Binary file not shown.

View File

@ -0,0 +1,117 @@
#include <stdlib.h>
#include <stdio.h>
#include "rpc.h"
#include "configmapi.h"
rpc_client *config_client = NULL;
rpc_client *config_client_get()
{
if(config_client == NULL)
{
config_client = rpc_client_connect_ex("ConfigManger#0");
if(config_client == NULL)
{
rpc_log_error("connect ConfigManger#0 error\n");
return NULL;
}
}
return config_client;
}
ret_code config_construct_msg(uint config_type, uint64 config_id,
char* config_data, int config_len,
config_msg_t **config_msg, int *msg_len)
{
config_msg_t *pconfig_msg;
if(config_data == NULL)
{
return RET_NULLP;
}
*msg_len = sizeof(config_msg_t) + config_len;
pconfig_msg= (config_msg_t *) malloc(*msg_len);
if(pconfig_msg == NULL)
{
return RET_NOMEM;
}
pconfig_msg->source = CONFIG_FROM_WEB;
pconfig_msg->config_type = config_type;
pconfig_msg->config_id = config_id;
memcpy(pconfig_msg->config_buff, config_data, config_len);
*config_msg = pconfig_msg;
return RET_OK;
}
ret_code config_destroy_msg(config_msg_t *config_msg, int msg_len)
{
if(config_msg)
{
memset(config_msg, 0, msg_len);
free(config_msg);
}
}
ret_code web_config_exec_sync(uint config_type, uint64 config_id,
char* config_data, int config_len,
char**output, int *output_len)
{
rpc_client * client = config_client_get();
ret_code code = RET_OK ;
config_msg_t *config_msg;
int msg_len = 0;
if(client == NULL)
{
return RET_ERR;
}
code = config_construct_msg(config_type, config_id, config_data,
config_len, &config_msg, &msg_len);
ASSERT_RET(code);
code = rpc_client_call(client, "ConfigManger#0", "cm_config_process",
config_msg, msg_len, (pointer)output, output_len);
ASSERT_RET_NO(code);
config_destroy_msg(config_msg, msg_len);
return code;
}
ret_code web_config_exec_async(uint config_type, uint64 config_id,
char* config_data, int config_len,
rpc_callback callback, pointer data)
{
rpc_client * client = config_client_get();
config_msg_t *config_msg;
int msg_len = 0;
ret_code ret = RET_OK ;
if(client == NULL)
{
return RET_ERR;
}
ret = config_construct_msg(config_type, config_id, config_data,
config_len, &config_msg, &msg_len);
ASSERT_RET(ret);
ret = rpc_client_call_async(client, "ConfigManger#0", "cm_config_process",
config_msg, msg_len, callback, data);
config_destroy_msg(config_msg, msg_len);
return ret;
}

View File

@ -1,374 +1,374 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "rpc.h"
#include "configm.h"
config_service_t g_config_service[] = CONFIG_SERVICE_ARRAY;
void test_big_data(rpc_conn *conn, pointer input, int input_len, void* data) {
char buf[input_len];
memcpy(buf, input, input_len);
buf[input_len] = '\0';
printf("get data is %s\n", buf);
//sleep(15);
rpc_return_null(conn);
}
config_service_t *cm_config_service_get(uint64 config_id)
{
int len = sizeof(g_config_service) / sizeof(config_service_t);
int config_idx;
for(config_idx = 0; config_idx < len; config_idx++)
{
if(config_id == g_config_service[config_idx].config_id)
{
return &(g_config_service[config_idx]);
}
}
return NULL;
}
ret_code cm_config_rec_pre(char **input, short **input_len,
char **output, int *output_len)
{
/*if((access(CONFIG_RECOVERY_DONE, F_OK))!=-1)
{
return RET_ERR;
} */
*input = rpc_new(char, CM_BUFF_SIZE);
*input_len = rpc_new(short, CM_BUFF_SIZE);
*output = rpc_new(char, CM_BUFF_SIZE);
*output_len = CM_BUFF_SIZE;
if(*input == NULL
|| *input_len == NULL
|| *output == NULL)
{
return RET_NOMEM;
}
memset(*input, 0, CM_BUFF_SIZE);
memset(*input_len, 0, CM_BUFF_SIZE * sizeof(short));
memset(*output, 0, CM_BUFF_SIZE);
rpc_log_info("==>config revocery start\n");
return RET_OK;
}
ret_code cm_config_rec_done(char *input, short *input_len,char *output)
{
int fd;
memset(input, 0, CM_BUFF_SIZE);
memset(input_len, 0, CM_BUFF_SIZE * sizeof(short));
memset(output, 0, CM_BUFF_SIZE);
free(input);
free(input_len);
free(output);
fd = open(CONFIG_RECOVERY_DONE, O_CREAT);
if(fd <= 0)
{
rpc_log_error("create recovery file error");
}
else
{
close(fd);
}
rpc_log_info("==>config revocery done!\n");
return RET_OK;
}
ret_code cm_config_get_allconfig(uint source,
config_service_t *config_svr,
char *input_array,
short *len_array,
int *total_len)
{
ret_code ret = RET_OK;
memset(input_array, 0, CM_BUFF_SIZE);
memset(len_array, 0, CM_BUFF_SIZE*sizeof(short));
*total_len = 0;
ret = config_svr->getall_callback(source, config_svr->config_id,
input_array, len_array, total_len);
ASSERT_RET(ret);
return ret;
}
ret_code cm_config_config_rec(uint source,
config_service_t *config_svr,
char *input_array, short *len_array,
int total_len, char *output, int *output_len)
{
uint config_type = CM_CONFIG_SET;
ret_code ret = RET_OK;
int len_tem = 0;
int idx = 0;
if(config_svr->multi_inst == TRUE)
{
config_type = CM_CONFIG_ADD;
}
while(len_tem < total_len)
{
config_svr->proc_callback(source, config_type,
input_array, len_array[idx],
output, output_len);
input_array = input_array + len_array[idx];
len_tem = len_tem + len_array[idx];
idx++;
}
return RET_OK;
}
/* 配置恢复 */
void cm_config_recovery()
{
int len = sizeof(g_config_service) / sizeof(config_service_t);
config_service_t *config_svr;
char *input_array = NULL;
short *len_array = NULL;
char *output = NULL;
int output_len;
int total_len = 0;
ret_code ret = RET_OK;
int config_idx;
int recover_idx = 1,recover_phase;
ret = cm_config_rec_pre(&input_array, &len_array, &output, &output_len);
ASSERT_RET_VOID(ret);
while(recover_idx <= 2)
{
if(recover_idx == 1)
{
recover_phase = CONFIG_FROM_RECOVER1;
}
else if(recover_idx == 2)
{
recover_phase = CONFIG_FROM_RECOVER2;
}
else
{
break;
}
for(config_idx = 0; config_idx < len; config_idx++)
{
config_svr = &(g_config_service[config_idx]);
if(config_svr->recovery != TRUE)
{
continue;
}
cm_config_get_allconfig(recover_phase,
config_svr, input_array,
len_array, &total_len);
cm_config_config_rec(recover_phase, config_svr,
input_array, len_array, total_len,
output, &output_len);
}
recover_idx++;
}
cm_config_rec_done(input_array, len_array, output);
return;
}
/* 配置处理入口函数,所有的配置,均在此函数中处理 */
void cm_config_process(rpc_conn *conn, pointer input, int input_len, void* data)
{
config_service_t *config_svr;
config_msg_t *config_msg;
char *cm_get_buff = NULL;
ret_code ret = RET_OK;
int config_len = 0;
short* single_len = NULL;
int buff_len = CM_BUFF_SIZE;
int index = 0;
if(conn == NULL || input == NULL)
{
rpc_return_error(conn, RET_NULLP, "NULL pointer");
return;
}
/*parse message*/
if(input_len < sizeof(config_msg_t))
{
rpc_return_error(conn, RET_NOMEM, "not enough memery");
return;
}
config_msg = (config_msg_t *)input;
config_len = input_len - sizeof(config_msg_t);
rpc_log_info("recv config from %d, config type is %d config id is 0x%llx ,len is %x\r\n",
config_msg->source, config_msg->config_type, config_msg->config_id,
config_len);
config_svr = cm_config_service_get(config_msg->config_id);
if(config_svr == NULL)
{
rpc_return_error(conn, RET_NULLP, "NULL pointer");
return;
}
/*source check*/
if(!(config_svr->config_id & config_msg->config_id))
{
rpc_return_error(conn, RET_CHKERR, "source check error!\r\n");
return;
}
cm_get_buff = rpc_new(char, buff_len);
if(cm_get_buff == NULL)
{
rpc_return_error(conn, RET_NOMEM, "not enough memery");
return;
}
memset(cm_get_buff, 0, buff_len);
/*config check*/
if(config_svr->chk_callback)
{
ret = config_svr->chk_callback(config_msg->source,
config_msg->config_type,
config_msg->config_buff,
config_len,
cm_get_buff,
&buff_len);
if(ret != RET_OK)
{
rpc_return_error(conn, ret, cm_get_buff);
goto exit;
}
}
/*config exec*/
switch(config_msg->config_type)
{
case CM_CONFIG_GET:
if(config_svr->get_callback)
{
ret = config_svr->get_callback(config_msg->source,
config_msg->config_buff,
config_len,
cm_get_buff,
&buff_len);
}
break;
case CM_CONFIG_GET_ALL:
if(config_svr->getall_callback)
{
single_len = rpc_new(short, CM_BUFF_SIZE);
if(single_len == NULL)
{
rpc_return_error(conn, RET_NOMEM, "not enough memery");
goto exit;
}
ret = config_svr->getall_callback(config_msg->source,
config_svr->config_id,
cm_get_buff,
single_len,
&buff_len);
}
break;
default:
if(config_svr->proc_callback)
{
ret = config_svr->proc_callback(config_msg->source,
config_msg->config_type,
config_msg->config_buff,
config_len,
cm_get_buff,
&buff_len);
}
break;
}
if(buff_len > CM_BUFF_SIZE)
{
ret = RET_NOMEM;
}
if(ret != RET_OK)
{
rpc_return_error(conn, ret, cm_get_buff);
goto exit;
}
rpc_return(conn, cm_get_buff, buff_len);
exit:
rpc_free(cm_get_buff);
if(single_len != NULL)
{
rpc_free(single_len);
}
return;
}
int main(int argc, char **argv)
{
rpc_server *server;
if (server= rpc_server_create_ex("ConfigManger#0"))
{
rpc_log_info("start server\n");
}
else
{
rpc_log_error("start server error\n");
return EXIT_FAILURE;
}
/* 配置恢复 */
cm_config_recovery();
/* 注册配置处理函数 */
rpc_server_regservice(server, "ConfigManger#0", "cm_config_process", cm_config_process);
rpc_server_regservice(server, "ConfigManger#0", "test_big_data", test_big_data);
for(;;)
{
rpc_sleep(1000);
}
return EXIT_SUCCESS;
}
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "rpc.h"
#include "configm.h"
config_service_t g_config_service[] = CONFIG_SERVICE_ARRAY;
void test_big_data(rpc_conn *conn, pointer input, int input_len, void* data) {
char buf[input_len];
memcpy(buf, input, input_len);
buf[input_len] = '\0';
printf("get data is %s\n", buf);
//sleep(15);
rpc_return_null(conn);
}
config_service_t *cm_config_service_get(uint64 config_id)
{
int len = sizeof(g_config_service) / sizeof(config_service_t);
int config_idx;
for(config_idx = 0; config_idx < len; config_idx++)
{
if(config_id == g_config_service[config_idx].config_id)
{
return &(g_config_service[config_idx]);
}
}
return NULL;
}
ret_code cm_config_rec_pre(char **input, short **input_len,
char **output, int *output_len)
{
/*if((access(CONFIG_RECOVERY_DONE, F_OK))!=-1)
{
return RET_ERR;
} */
*input = rpc_new(char, CM_BUFF_SIZE);
*input_len = rpc_new(short, CM_BUFF_SIZE);
*output = rpc_new(char, CM_BUFF_SIZE);
*output_len = CM_BUFF_SIZE;
if(*input == NULL
|| *input_len == NULL
|| *output == NULL)
{
return RET_NOMEM;
}
memset(*input, 0, CM_BUFF_SIZE);
memset(*input_len, 0, CM_BUFF_SIZE * sizeof(short));
memset(*output, 0, CM_BUFF_SIZE);
rpc_log_info("==>config revocery start\n");
return RET_OK;
}
ret_code cm_config_rec_done(char *input, short *input_len,char *output)
{
int fd;
memset(input, 0, CM_BUFF_SIZE);
memset(input_len, 0, CM_BUFF_SIZE * sizeof(short));
memset(output, 0, CM_BUFF_SIZE);
free(input);
free(input_len);
free(output);
fd = open(CONFIG_RECOVERY_DONE, O_CREAT, 0777);
if(fd <= 0)
{
rpc_log_error("create recovery file error");
}
else
{
close(fd);
}
rpc_log_info("==>config revocery done!\n");
return RET_OK;
}
ret_code cm_config_get_allconfig(uint source,
config_service_t *config_svr,
char *input_array,
short *len_array,
int *total_len)
{
ret_code ret = RET_OK;
memset(input_array, 0, CM_BUFF_SIZE);
memset(len_array, 0, CM_BUFF_SIZE*sizeof(short));
*total_len = 0;
ret = config_svr->getall_callback(source, config_svr->config_id,
input_array, len_array, total_len);
ASSERT_RET(ret);
return ret;
}
ret_code cm_config_config_rec(uint source,
config_service_t *config_svr,
char *input_array, short *len_array,
int total_len, char *output, int *output_len)
{
uint config_type = CM_CONFIG_SET;
ret_code ret = RET_OK;
int len_tem = 0;
int idx = 0;
if(config_svr->multi_inst == TRUE)
{
config_type = CM_CONFIG_ADD;
}
while(len_tem < total_len)
{
config_svr->proc_callback(source, config_type,
input_array, len_array[idx],
output, output_len);
input_array = input_array + len_array[idx];
len_tem = len_tem + len_array[idx];
idx++;
}
return RET_OK;
}
/* 配置恢复 */
void cm_config_recovery()
{
int len = sizeof(g_config_service) / sizeof(config_service_t);
config_service_t *config_svr;
char *input_array = NULL;
short *len_array = NULL;
char *output = NULL;
int output_len;
int total_len = 0;
ret_code ret = RET_OK;
int config_idx;
int recover_idx = 1,recover_phase;
ret = cm_config_rec_pre(&input_array, &len_array, &output, &output_len);
ASSERT_RET_VOID(ret);
while(recover_idx <= 2)
{
if(recover_idx == 1)
{
recover_phase = CONFIG_FROM_RECOVER1;
}
else if(recover_idx == 2)
{
recover_phase = CONFIG_FROM_RECOVER2;
}
else
{
break;
}
for(config_idx = 0; config_idx < len; config_idx++)
{
config_svr = &(g_config_service[config_idx]);
if(config_svr->recovery != TRUE)
{
continue;
}
cm_config_get_allconfig(recover_phase,
config_svr, input_array,
len_array, &total_len);
cm_config_config_rec(recover_phase, config_svr,
input_array, len_array, total_len,
output, &output_len);
}
recover_idx++;
}
cm_config_rec_done(input_array, len_array, output);
return;
}
/* 配置处理入口函数,所有的配置,均在此函数中处理 */
void cm_config_process(rpc_conn *conn, pointer input, int input_len, void* data)
{
config_service_t *config_svr;
config_msg_t *config_msg;
char *cm_get_buff = NULL;
ret_code ret = RET_OK;
int config_len = 0;
short* single_len = NULL;
int buff_len = CM_BUFF_SIZE;
int index = 0;
if(conn == NULL || input == NULL)
{
rpc_return_error(conn, RET_NULLP, "NULL pointer");
return;
}
/*parse message*/
if(input_len < sizeof(config_msg_t))
{
rpc_return_error(conn, RET_NOMEM, "not enough memery");
return;
}
config_msg = (config_msg_t *)input;
config_len = input_len - sizeof(config_msg_t);
rpc_log_info("recv config from %d, config type is %d config id is 0x%llx ,len is %x\r\n",
config_msg->source, config_msg->config_type, config_msg->config_id,
config_len);
config_svr = cm_config_service_get(config_msg->config_id);
if(config_svr == NULL)
{
rpc_return_error(conn, RET_NULLP, "NULL pointer");
return;
}
/*source check*/
if(!(config_svr->config_id & config_msg->config_id))
{
rpc_return_error(conn, RET_CHKERR, "source check error!\r\n");
return;
}
cm_get_buff = rpc_new(char, buff_len);
if(cm_get_buff == NULL)
{
rpc_return_error(conn, RET_NOMEM, "not enough memery");
return;
}
memset(cm_get_buff, 0, buff_len);
/*config check*/
if(config_svr->chk_callback)
{
ret = config_svr->chk_callback(config_msg->source,
config_msg->config_type,
config_msg->config_buff,
config_len,
cm_get_buff,
&buff_len);
if(ret != RET_OK)
{
rpc_return_error(conn, ret, cm_get_buff);
goto exit;
}
}
/*config exec*/
switch(config_msg->config_type)
{
case CM_CONFIG_GET:
if(config_svr->get_callback)
{
ret = config_svr->get_callback(config_msg->source,
config_msg->config_buff,
config_len,
cm_get_buff,
&buff_len);
}
break;
case CM_CONFIG_GET_ALL:
if(config_svr->getall_callback)
{
single_len = rpc_new(short, CM_BUFF_SIZE);
if(single_len == NULL)
{
rpc_return_error(conn, RET_NOMEM, "not enough memery");
goto exit;
}
ret = config_svr->getall_callback(config_msg->source,
config_svr->config_id,
cm_get_buff,
single_len,
&buff_len);
}
break;
default:
if(config_svr->proc_callback)
{
ret = config_svr->proc_callback(config_msg->source,
config_msg->config_type,
config_msg->config_buff,
config_len,
cm_get_buff,
&buff_len);
}
break;
}
if(buff_len > CM_BUFF_SIZE)
{
ret = RET_NOMEM;
}
if(ret != RET_OK)
{
rpc_return_error(conn, ret, cm_get_buff);
goto exit;
}
rpc_return(conn, cm_get_buff, buff_len);
exit:
rpc_free(cm_get_buff);
if(single_len != NULL)
{
rpc_free(single_len);
}
return;
}
int main(int argc, char **argv)
{
rpc_server *server;
if (server= rpc_server_create_ex("ConfigManger#0"))
{
rpc_log_info("start server\n");
}
else
{
rpc_log_error("start server error\n");
return EXIT_FAILURE;
}
/* 配置恢复 */
cm_config_recovery();
/* 注册配置处理函数 */
rpc_server_regservice(server, "ConfigManger#0", "cm_config_process", cm_config_process);
rpc_server_regservice(server, "ConfigManger#0", "test_big_data", test_big_data);
for(;;)
{
rpc_sleep(1000);
}
return EXIT_SUCCESS;
}

View File

@ -1,93 +1,93 @@
#ifndef IPCONFIG_H_
#define IPCONFIG_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#define MAX_IF_NUM 32
#define INTERFACE_NAMSIZ 20
/* Max bit/byte length of IPv4 address. */
#define IPV4_MAX_BYTELEN 4
#define IPV4_MAX_BITLEN 32
#define IPV4_MAX_PREFIXLEN 32
#define IPV4_DEFAULT_PREFIXLEN 16
#define IPV4_ADDR_CMP(D,S) memcmp ((D), (S), IPV4_MAX_BYTELEN)
#define IPV4_ADDR_COPY(D,S) ipv4_addr_copy((D), (S))
#define IPV4_NET0(a) ((((uint)(a)) & 0xff000000) == 0x00000000)
#define IPV4_NET127(a) ((((uint)(a)) & 0xff000000) == 0x7f000000)
#define IPV4_LINKLOCAL(a) ((((uint)(a)) & 0xffff0000) == 0xa9fe0000)
#define IPV4_CLASS_DE(a) ((((uint)(a)) & 0xe0000000) == 0xe0000000)
#define IPV4_MC_LINKLOCAL(a) ((((uint)(a)) & 0xffffff00) == 0xe0000000)
#define IPV4_ADDR_SAME(A,B) ipv4_addr_same((A), (B))
static inline boolean ipv4_addr_same(const struct in_addr *a,
const struct in_addr *b)
{
return (a->s_addr == b->s_addr);
}
static inline void ipv4_addr_copy(struct in_addr *dst,
const struct in_addr *src)
{
dst->s_addr = src->s_addr;
}
/* NOTE: This routine expects the address argument in network byte order. */
static inline int ipv4_martian(struct in_addr *addr)
{
in_addr_t ip = ntohl(addr->s_addr);
if (IPV4_NET0(ip) || IPV4_NET127(ip) || IPV4_CLASS_DE(ip))
{
return TRUE;
}
return FALSE;
}
/* 配置消息 */
struct _ip_config_str {
char ifname[INTERFACE_NAMSIZ];
uchar family;
uchar prefixlen;
struct in_addr prefix __attribute__((aligned(8)));
};
typedef struct _ip_config_str ip_config_t;
/* 业务模块函数声明 */
/* ip config */
ret_code ip_config_chk(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len);
ret_code ip_config_proc(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len);
ret_code ip_config_get(uint source,
pointer input, int input_len,
pointer output, int *output_len);
ret_code ip_config_get_all(uint source, uint64 config_id,
pointer output, short *single_len,
int *output_len);
#endif /* IPCONFIG_H_ */
#ifndef IPCONFIG_H_
#define IPCONFIG_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#define MAX_IF_NUM 32
#define INTERFACE_NAMSIZ 20
/* Max bit/byte length of IPv4 address. */
#define IPV4_MAX_BYTELEN 4
#define IPV4_MAX_BITLEN 32
#define IPV4_MAX_PREFIXLEN 32
#define IPV4_DEFAULT_PREFIXLEN 16
#define IPV4_ADDR_CMP(D,S) memcmp ((D), (S), IPV4_MAX_BYTELEN)
#define IPV4_ADDR_COPY(D,S) ipv4_addr_copy((D), (S))
#define IPV4_NET0(a) ((((uint)(a)) & 0xff000000) == 0x00000000)
#define IPV4_NET127(a) ((((uint)(a)) & 0xff000000) == 0x7f000000)
#define IPV4_LINKLOCAL(a) ((((uint)(a)) & 0xffff0000) == 0xa9fe0000)
#define IPV4_CLASS_DE(a) ((((uint)(a)) & 0xe0000000) == 0xe0000000)
#define IPV4_MC_LINKLOCAL(a) ((((uint)(a)) & 0xffffff00) == 0xe0000000)
#define IPV4_ADDR_SAME(A,B) ipv4_addr_same((A), (B))
static inline boolean ipv4_addr_same(const struct in_addr *a,
const struct in_addr *b)
{
return (a->s_addr == b->s_addr);
}
static inline void ipv4_addr_copy(struct in_addr *dst,
const struct in_addr *src)
{
dst->s_addr = src->s_addr;
}
/* NOTE: This routine expects the address argument in network byte order. */
static inline int ipv4_martian(struct in_addr *addr)
{
in_addr_t ip = ntohl(addr->s_addr);
if (IPV4_NET0(ip) || IPV4_NET127(ip) || IPV4_CLASS_DE(ip))
{
return TRUE;
}
return FALSE;
}
/* 配置消息 */
struct _ip_config_str {
char ifname[INTERFACE_NAMSIZ];
uchar family;
uchar prefixlen;
struct in_addr prefix __attribute__((aligned(8)));
};
typedef struct _ip_config_str ip_config_t;
/* 业务模块函数声明 */
/* ip config */
ret_code ip_config_chk(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len);
ret_code ip_config_proc(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len);
ret_code ip_config_get(uint source,
pointer input, int input_len,
pointer output, int *output_len);
ret_code ip_config_get_all(uint source, uint64 config_id,
pointer output, short *single_len,
int *output_len);
#endif /* IPCONFIG_H_ */

View File

@ -1,10 +1,10 @@
#ifndef PARSEFILE_H_
#define PARSEFILE_H_
#define IFCONFIG_PATH "/etc/network/interfaces"
#define IF_BUFF_LEN 64
void set_if_config(char *if_name, char *conf_name, char *conf_buff);
void del_if_config(char *if_name, char *conf_buff);
#endif
#ifndef PARSEFILE_H_
#define PARSEFILE_H_
#define IFCONFIG_PATH "/etc/network/interfaces"
#define IF_BUFF_LEN 64
void set_if_config(char *if_name, char *conf_name, char *conf_buff);
void del_if_config(char *if_name, char *conf_buff);
#endif

View File

@ -1,389 +1,389 @@
#include "configm.h"
#include "ipconfig.h"
#include "rpc.h"
#include "parsefile.h"
uchar ip_masklen(struct in_addr netmask)
{
uint tmp = ~ntohl(netmask.s_addr);
if (tmp)
/* clz: count leading zeroes. sadly, the behaviour of this
* builtin
* is undefined for a 0 argument, even though most CPUs give 32
*/
return __builtin_clz(tmp);
else
return 32;
}
/* Convert masklen into IP address's netmask (network byte order). */
void masklen2ip(const int masklen, struct in_addr *netmask)
{
if(masklen < 0 || masklen > IPV4_MAX_BITLEN)
{
return;
}
/* left shift is only defined for less than the size of the type.
* we unconditionally use long long in case the target platform
* has defined behaviour for << 32 (or has a 64-bit left shift) */
if (sizeof(unsigned long long) > 4)
netmask->s_addr = htonl(0xffffffffULL << (32 - masklen));
else
netmask->s_addr =
htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
}
void ip_save_file(ip_config_t *ip_conf, uint config_type)
{
char *addr_name = "address";
char *mask_name = "netmask";
struct in_addr netmask;
char addr_buff[IF_BUFF_LEN] = {0};
char mask_buff[IF_BUFF_LEN] = {0};
if(config_type == CM_CONFIG_SET)
{
sprintf(addr_buff, "address %s\n", inet_ntoa(ip_conf->prefix));
masklen2ip(ip_conf->prefixlen, &netmask);
sprintf(mask_buff, "netmask %s\n", inet_ntoa(netmask));
printf("%s,%s\r\n",addr_buff, mask_buff);
set_if_config(ip_conf->ifname, addr_name, addr_buff);
set_if_config(ip_conf->ifname, mask_name, mask_buff);
}
else if(config_type == CM_CONFIG_DEL)
{
del_if_config(ip_conf->ifname, addr_name);
del_if_config(ip_conf->ifname, mask_name);
}
}
/* call ioctl system call */
ret_code if_ioctl(unsigned long request, caddr_t ifreq, int *ret)
{
int sock;
int err = 0;
*ret = 0;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
{
rpc_log_error("Cannot create UDP socket");
return RET_SOCKERR;
}
if ((*ret = ioctl(sock, request, ifreq)) < 0)
{
err = errno;
rpc_log_error("Ioctl error: %s\n", strerror(errno));
}
close(sock);
if (*ret < 0)
{
errno = err;
*ret = err;
return RET_SYSERR;
}
return RET_OK;
}
ret_code if_set_prefix(ip_config_t *ip_conf, int *code)
{
ret_code ret;
struct ifreq ifreq;
struct sockaddr_in addr;
struct sockaddr_in mask;
strncpy(ifreq.ifr_name, ip_conf->ifname, sizeof(ifreq.ifr_name));
addr.sin_addr = ip_conf->prefix;
addr.sin_family = ip_conf->family;
memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in));
ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq, code);
ASSERT_RET(ret);
if(ip_conf->prefix.s_addr != 0)
{
masklen2ip(ip_conf->prefixlen, &mask.sin_addr);
mask.sin_family = ip_conf->family;
memcpy(&ifreq.ifr_netmask, &mask, sizeof(struct sockaddr_in));
ret = if_ioctl(SIOCSIFNETMASK, (caddr_t)&ifreq, code);
ASSERT_RET(ret);
}
return 0;
}
ret_code if_get_prefix_all(ip_config_t *ip_conf, int *cnt, int *code)
{
struct ifreq ifreq[MAX_IF_NUM];
struct sockaddr_in *addr;
struct ifreq netmask;
struct ifconf ifc;
int if_count = 0;
ret_code ret;
int mask_ret;
int i;
memset(&ifc, 0, sizeof(struct ifconf));
memset(&ifreq, 0, MAX_IF_NUM * sizeof(struct ifreq));
ifc.ifc_len = MAX_IF_NUM * sizeof(struct ifreq);
ifc.ifc_buf = (char *)ifreq;
ret = if_ioctl(SIOCGIFCONF, (caddr_t)&ifc, code);
ASSERT_RET(ret);
if_count = ifc.ifc_len / (sizeof(struct ifreq));
rpc_log_info("if num is %d\n", if_count);
if(if_count * sizeof(ip_config_t) > CM_BUFF_SIZE)
{
ret = RET_NOMEM;
ASSERT_RET(ret);
}
*cnt = 0;
for(i = 0; i < if_count; i++)
{
rpc_log_info("get interface %s info\n", ifreq[i].ifr_name);
strncpy(ip_conf[i].ifname, ifreq[i].ifr_name, INTERFACE_NAMSIZ);
ip_conf[i].family = AF_INET;
ip_conf[i].prefix = ((struct sockaddr_in *)&(ifreq[i].ifr_addr))->sin_addr;
memset(&netmask, 0, sizeof(netmask));
strncpy(netmask.ifr_name, ifreq[i].ifr_name, INTERFACE_NAMSIZ);
ret = if_ioctl(SIOCGIFNETMASK, (caddr_t)&netmask, &mask_ret);
ASSERT_RET_NO(ret);
addr = ( struct sockaddr_in * )&(netmask.ifr_netmask );
ip_conf[i].prefixlen = ip_masklen(addr->sin_addr);
(*cnt)++;
}
return RET_OK;
}
ret_code if_get_prefix(ip_config_t *ip_conf, int *code)
{
struct sockaddr_in *addr;
struct ifreq netmask;
struct ifreq ifreq;
ret_code ret = RET_OK;
int mask_ret;
int i;
if(ip_conf->family != AF_INET)
{
ret = RET_INPUTERR;
}
ASSERT_RET(ret);
memset(&ifreq, 0, sizeof(struct ifreq));
rpc_log_info("get interface %s info\n", ip_conf->ifname);
strncpy(ifreq.ifr_name, ip_conf->ifname, sizeof(ifreq.ifr_name));
ret = if_ioctl(SIOCGIFADDR, (caddr_t)&ifreq, code);
ASSERT_RET(ret);
ip_conf->prefix = ((struct sockaddr_in *)&(ifreq.ifr_addr))->sin_addr;
memset(&ifreq, 0, sizeof(ifreq));
strncpy(ifreq.ifr_name, ip_conf->ifname, sizeof(ifreq.ifr_name));
ret = if_ioctl(SIOCGIFNETMASK, (caddr_t)&ifreq, &mask_ret);
ASSERT_RET_NO(ret);
addr = ( struct sockaddr_in * )&(ifreq.ifr_netmask);
ip_conf->prefixlen = ip_masklen(addr->sin_addr);
return ret;
}
ret_code ip_config_set_chk(uint source,uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
ip_config_t *ip_conf;
ip_conf = (ip_config_t *)input;
if(input_len < sizeof(ip_config_t)
|| strlen(ip_conf->ifname) == 0)
{
ret = RET_INPUTERR;
}
if (ipv4_martian(&ip_conf->prefix))
{
ret = RET_IPINVALID;
}
ASSERT_RET(ret);
if(ip_conf->prefixlen == 0 || ip_conf->prefixlen > IPV4_MAX_PREFIXLEN)
{
ip_conf->prefixlen = IPV4_DEFAULT_PREFIXLEN;
}
return RET_OK;
}
ret_code ip_config_get_chk(uint source,uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
ip_config_t *ip_conf;
ip_conf = (ip_config_t *)input;
if(input_len < sizeof(ip_config_t)
|| strlen(ip_conf->ifname) == 0 )
{
ret = RET_INPUTERR;
}
return ret;
}
ret_code ip_config_getall_chk(uint source,uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
if(*output_len < MAX_IF_NUM * sizeof(ip_config_t))
{
ret = RET_INPUTERR;
}
return ret;
}
ret_code ip_config_chk(uint source,uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
int code = 0;
switch (config_type)
{
case CM_CONFIG_SET:
case CM_CONFIG_DEL:
ret = ip_config_set_chk(source, config_type,
input, input_len,
output, output_len);
break;
case CM_CONFIG_GET:
ret = ip_config_get_chk(source, config_type,
input, input_len,
output, output_len);
break;
case CM_CONFIG_GET_ALL:
ret = ip_config_getall_chk(source, config_type,
input, input_len,
output, output_len);
break;
default:
ret = RET_NOTSUPPORT;
}
RET_ERR_FORMART(ret, code, output, *output_len);
return ret;
}
ret_code ip_config_proc(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
ip_config_t *ip_conf;
ret_code ret = RET_OK;
int code;
ip_conf = (ip_config_t *)input;
if(config_type == CM_CONFIG_DEL)
{
ip_conf->prefix.s_addr = 0;
ip_conf->prefixlen = IPV4_DEFAULT_PREFIXLEN;
}
rpc_log_info("config type is %d, if %s ip %s prefixlen %d\n",
config_type, ip_conf->ifname,
inet_ntoa(ip_conf->prefix),
ip_conf->prefixlen);
ret = if_set_prefix(ip_conf, &code);
RET_ERR_FORMART(ret, code, output, *output_len);
ASSERT_RET(ret);
ip_save_file(ip_conf, config_type);
return RET_OK;
}
ret_code ip_config_get(uint source,
pointer input, int input_len,
pointer output, int *output_len)
{
ip_config_t *ip_conf;
ret_code ret = RET_OK;
int code;
ip_conf = (ip_config_t *)input;
ret = if_get_prefix(ip_conf, &code);
RET_ERR_FORMART(ret, code, output, *output_len);
ASSERT_RET(ret);
memcpy(output, ip_conf, sizeof(ip_config_t));
*output_len = sizeof(ip_config_t);
return ret;
}
ret_code ip_config_get_all(uint source, uint64 config_id,
pointer output, short *single_len,
int *output_len)
{
ip_config_t ip_conf;
ret_code ret;
int count = 0;
int code;
rpc_log_info("ip_config_get_all\r\n");
ret = if_get_prefix_all((ip_config_t *)output, &count, &code);
RET_ERR_FORMART(ret, code, output, *output_len);
ASSERT_RET(ret);
*single_len = sizeof(ip_config_t);
*output_len = count * sizeof(ip_config_t);
return RET_OK;
}
#include "configm.h"
#include "ipconfig.h"
#include "rpc.h"
#include "parsefile.h"
uchar ip_masklen(struct in_addr netmask)
{
uint tmp = ~ntohl(netmask.s_addr);
if (tmp)
/* clz: count leading zeroes. sadly, the behaviour of this
* builtin
* is undefined for a 0 argument, even though most CPUs give 32
*/
return __builtin_clz(tmp);
else
return 32;
}
/* Convert masklen into IP address's netmask (network byte order). */
void masklen2ip(const int masklen, struct in_addr *netmask)
{
if(masklen < 0 || masklen > IPV4_MAX_BITLEN)
{
return;
}
/* left shift is only defined for less than the size of the type.
* we unconditionally use long long in case the target platform
* has defined behaviour for << 32 (or has a 64-bit left shift) */
if (sizeof(unsigned long long) > 4)
netmask->s_addr = htonl(0xffffffffULL << (32 - masklen));
else
netmask->s_addr =
htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
}
void ip_save_file(ip_config_t *ip_conf, uint config_type)
{
char *addr_name = "address";
char *mask_name = "netmask";
struct in_addr netmask;
char addr_buff[IF_BUFF_LEN] = {0};
char mask_buff[IF_BUFF_LEN] = {0};
if(config_type == CM_CONFIG_SET)
{
sprintf(addr_buff, "address %s\n", inet_ntoa(ip_conf->prefix));
masklen2ip(ip_conf->prefixlen, &netmask);
sprintf(mask_buff, "netmask %s\n", inet_ntoa(netmask));
printf("%s,%s\r\n",addr_buff, mask_buff);
set_if_config(ip_conf->ifname, addr_name, addr_buff);
set_if_config(ip_conf->ifname, mask_name, mask_buff);
}
else if(config_type == CM_CONFIG_DEL)
{
del_if_config(ip_conf->ifname, addr_name);
del_if_config(ip_conf->ifname, mask_name);
}
}
/* call ioctl system call */
ret_code if_ioctl(unsigned long request, caddr_t ifreq, int *ret)
{
int sock;
int err = 0;
*ret = 0;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
{
rpc_log_error("Cannot create UDP socket");
return RET_SOCKERR;
}
if ((*ret = ioctl(sock, request, ifreq)) < 0)
{
err = errno;
rpc_log_error("Ioctl error: %s\n", strerror(errno));
}
close(sock);
if (*ret < 0)
{
errno = err;
*ret = err;
return RET_SYSERR;
}
return RET_OK;
}
ret_code if_set_prefix(ip_config_t *ip_conf, int *code)
{
ret_code ret;
struct ifreq ifreq;
struct sockaddr_in addr;
struct sockaddr_in mask;
strncpy(ifreq.ifr_name, ip_conf->ifname, sizeof(ifreq.ifr_name));
addr.sin_addr = ip_conf->prefix;
addr.sin_family = ip_conf->family;
memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in));
ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq, code);
ASSERT_RET(ret);
if(ip_conf->prefix.s_addr != 0)
{
masklen2ip(ip_conf->prefixlen, &mask.sin_addr);
mask.sin_family = ip_conf->family;
memcpy(&ifreq.ifr_netmask, &mask, sizeof(struct sockaddr_in));
ret = if_ioctl(SIOCSIFNETMASK, (caddr_t)&ifreq, code);
ASSERT_RET(ret);
}
return 0;
}
ret_code if_get_prefix_all(ip_config_t *ip_conf, int *cnt, int *code)
{
struct ifreq ifreq[MAX_IF_NUM];
struct sockaddr_in *addr;
struct ifreq netmask;
struct ifconf ifc;
int if_count = 0;
ret_code ret;
int mask_ret;
int i;
memset(&ifc, 0, sizeof(struct ifconf));
memset(&ifreq, 0, MAX_IF_NUM * sizeof(struct ifreq));
ifc.ifc_len = MAX_IF_NUM * sizeof(struct ifreq);
ifc.ifc_buf = (char *)ifreq;
ret = if_ioctl(SIOCGIFCONF, (caddr_t)&ifc, code);
ASSERT_RET(ret);
if_count = ifc.ifc_len / (sizeof(struct ifreq));
rpc_log_info("if num is %d\n", if_count);
if(if_count * sizeof(ip_config_t) > CM_BUFF_SIZE)
{
ret = RET_NOMEM;
ASSERT_RET(ret);
}
*cnt = 0;
for(i = 0; i < if_count; i++)
{
rpc_log_info("get interface %s info\n", ifreq[i].ifr_name);
strncpy(ip_conf[i].ifname, ifreq[i].ifr_name, INTERFACE_NAMSIZ);
ip_conf[i].family = AF_INET;
ip_conf[i].prefix = ((struct sockaddr_in *)&(ifreq[i].ifr_addr))->sin_addr;
memset(&netmask, 0, sizeof(netmask));
strncpy(netmask.ifr_name, ifreq[i].ifr_name, sizeof(netmask.ifr_name));
ret = if_ioctl(SIOCGIFNETMASK, (caddr_t)&netmask, &mask_ret);
ASSERT_RET_NO(ret);
addr = ( struct sockaddr_in * )&(netmask.ifr_netmask );
ip_conf[i].prefixlen = ip_masklen(addr->sin_addr);
(*cnt)++;
}
return RET_OK;
}
ret_code if_get_prefix(ip_config_t *ip_conf, int *code)
{
struct sockaddr_in *addr;
struct ifreq netmask;
struct ifreq ifreq;
ret_code ret = RET_OK;
int mask_ret;
int i;
if(ip_conf->family != AF_INET)
{
ret = RET_INPUTERR;
}
ASSERT_RET(ret);
memset(&ifreq, 0, sizeof(struct ifreq));
rpc_log_info("get interface %s info\n", ip_conf->ifname);
strncpy(ifreq.ifr_name, ip_conf->ifname, sizeof(ifreq.ifr_name));
ret = if_ioctl(SIOCGIFADDR, (caddr_t)&ifreq, code);
ASSERT_RET(ret);
ip_conf->prefix = ((struct sockaddr_in *)&(ifreq.ifr_addr))->sin_addr;
memset(&ifreq, 0, sizeof(ifreq));
strncpy(ifreq.ifr_name, ip_conf->ifname, sizeof(ifreq.ifr_name));
ret = if_ioctl(SIOCGIFNETMASK, (caddr_t)&ifreq, &mask_ret);
ASSERT_RET_NO(ret);
addr = ( struct sockaddr_in * )&(ifreq.ifr_netmask);
ip_conf->prefixlen = ip_masklen(addr->sin_addr);
return ret;
}
ret_code ip_config_set_chk(uint source,uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
ip_config_t *ip_conf;
ip_conf = (ip_config_t *)input;
if(input_len < sizeof(ip_config_t)
|| strlen(ip_conf->ifname) == 0)
{
ret = RET_INPUTERR;
}
if (ipv4_martian(&ip_conf->prefix))
{
ret = RET_IPINVALID;
}
ASSERT_RET(ret);
if(ip_conf->prefixlen == 0 || ip_conf->prefixlen > IPV4_MAX_PREFIXLEN)
{
ip_conf->prefixlen = IPV4_DEFAULT_PREFIXLEN;
}
return RET_OK;
}
ret_code ip_config_get_chk(uint source,uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
ip_config_t *ip_conf;
ip_conf = (ip_config_t *)input;
if(input_len < sizeof(ip_config_t)
|| strlen(ip_conf->ifname) == 0 )
{
ret = RET_INPUTERR;
}
return ret;
}
ret_code ip_config_getall_chk(uint source,uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
if(*output_len < MAX_IF_NUM * sizeof(ip_config_t))
{
ret = RET_INPUTERR;
}
return ret;
}
ret_code ip_config_chk(uint source,uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
int code = 0;
switch (config_type)
{
case CM_CONFIG_SET:
case CM_CONFIG_DEL:
ret = ip_config_set_chk(source, config_type,
input, input_len,
output, output_len);
break;
case CM_CONFIG_GET:
ret = ip_config_get_chk(source, config_type,
input, input_len,
output, output_len);
break;
case CM_CONFIG_GET_ALL:
ret = ip_config_getall_chk(source, config_type,
input, input_len,
output, output_len);
break;
default:
ret = RET_NOTSUPPORT;
}
RET_ERR_FORMART(ret, code, output, *output_len);
return ret;
}
ret_code ip_config_proc(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
ip_config_t *ip_conf;
ret_code ret = RET_OK;
int code;
ip_conf = (ip_config_t *)input;
if(config_type == CM_CONFIG_DEL)
{
ip_conf->prefix.s_addr = 0;
ip_conf->prefixlen = IPV4_DEFAULT_PREFIXLEN;
}
rpc_log_info("config type is %d, if %s ip %s prefixlen %d\n",
config_type, ip_conf->ifname,
inet_ntoa(ip_conf->prefix),
ip_conf->prefixlen);
ret = if_set_prefix(ip_conf, &code);
RET_ERR_FORMART(ret, code, output, *output_len);
ASSERT_RET(ret);
ip_save_file(ip_conf, config_type);
return RET_OK;
}
ret_code ip_config_get(uint source,
pointer input, int input_len,
pointer output, int *output_len)
{
ip_config_t *ip_conf;
ret_code ret = RET_OK;
int code;
ip_conf = (ip_config_t *)input;
ret = if_get_prefix(ip_conf, &code);
RET_ERR_FORMART(ret, code, output, *output_len);
ASSERT_RET(ret);
memcpy(output, ip_conf, sizeof(ip_config_t));
*output_len = sizeof(ip_config_t);
return ret;
}
ret_code ip_config_get_all(uint source, uint64 config_id,
pointer output, short *single_len,
int *output_len)
{
ip_config_t ip_conf;
ret_code ret;
int count = 0;
int code;
rpc_log_info("ip_config_get_all\r\n");
ret = if_get_prefix_all((ip_config_t *)output, &count, &code);
RET_ERR_FORMART(ret, code, output, *output_len);
ASSERT_RET(ret);
*single_len = sizeof(ip_config_t);
*output_len = count * sizeof(ip_config_t);
return RET_OK;
}

View File

@ -1,452 +1,452 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "parsefile.h"
#if 0
/*
*
*1 2 3
*==
*/
void read_config(char *conf_path,char *conf_name,char *config_buff)
{
char config_linebuf[256];
char line_name[40];
char exchange_buf[256];
char *config_sign = "=";
char *leave_line;
FILE *f;
f = fopen(conf_path,"r");
if(f == NULL)
{
printf("OPEN CONFIG FALID/n");
return 0;
}
fseek(f,0,SEEK_SET);
while(fgets(config_linebuf,256,f) != NULL)
{
if(strlen(config_linebuf) < 3) //判断是否是空行
{
continue;
}
if (config_linebuf[strlen(config_linebuf)-1] == 10) //去除最后一位是/n的情况
{
memset(exchange_buf,0,sizeof(exchange_buf));
strncpy(exchange_buf,config_linebuf,strlen(config_linebuf)-1);
memset(config_linebuf,0,sizeof(config_linebuf));
strcpy(config_linebuf,exchange_buf);
}
memset(line_name,0,sizeof(line_name));
leave_line = strstr(config_linebuf,config_sign);
if(leave_line == NULL) //去除无"="的情况
{
continue;
}
int leave_num = leave_line - config_linebuf;
strncpy(line_name,config_linebuf,leave_num);
if(strcmp(line_name,conf_name) ==0)
{
strncpy(config_buff,config_linebuf+(leave_num+1),strlen(config_linebuf)-leave_num-1);
break;
}
if(fgetc(f)==EOF)
{
break;
}
fseek(f,-1,SEEK_CUR);
memset(config_linebuf,0,sizeof(config_linebuf));
}
fclose(f);
}
/*
*
*
*1 2 3
*
*/
void add_set_config(char *conf_path,char *conf_name,char *config_buff)
{
char config_linebuf[256];
char line_name[40];
char *config_sign = "=";
char *leave_line;
int alter_sign = 0;
FILE *f;
f = fopen(conf_path,"r+");
if(f == NULL)
{
printf("OPEN CONFIG FALID/n");
return 0;
}
fseek(f,0,SEEK_END);
long congig_lenth = ftell(f);
int configbuf_lenth = strlen(config_buff);
configbuf_lenth = configbuf_lenth + 5;
char sum_buf[congig_lenth+configbuf_lenth];
memset(sum_buf,0,sizeof(sum_buf));
fseek(f,0,SEEK_SET);
while(fgets(config_linebuf,256,f) != NULL)
{
if(strlen(config_linebuf) < 3) //判断是否是空行
{
strcat(sum_buf,config_linebuf);
continue;
}
leave_line = NULL;
leave_line = strstr(config_linebuf,config_sign);
if(leave_line == NULL) //去除无"="的情况
{
strcat(sum_buf,config_linebuf);
continue;
}
int leave_num = leave_line - config_linebuf;
memset(line_name,0,sizeof(line_name));
strncpy(line_name,config_linebuf,leave_num);
if(strcmp(line_name,conf_name) ==0)
{
strcat(sum_buf,config_buff);
strcat(sum_buf,"/n");
alter_sign = 1;
}
else
{
strcat(sum_buf,config_linebuf);
}
if(fgetc(f)==EOF)
{
break;
}
fseek(f,-1,SEEK_CUR);
memset(config_linebuf,0,sizeof(config_linebuf));
}
if(alter_sign == 0)
{
strcat(sum_buf,config_buff);
strcat(sum_buf,"/n");
}
printf("---sum_buf---->%s<----------/n",sum_buf);
remove(conf_path);
fclose(f);
FILE *fp;
fp = fopen(conf_path,"w+");
if(fp == NULL)
{
printf("OPEN CONFIG FALID/n");
return 2;
}
fseek(fp,0,SEEK_SET);
fputs(sum_buf,fp);
fclose(fp);
}
/*
*
*
*1
*
*/
void del_if_config(char *conf_name)
{
char *conf_path = "/etc/network/interface";
char config_linebuf[256];
char line_name[40];
char *config_sign = "=";
char *leave_line;
FILE *f;
f = fopen(conf_path,"r+");
if(f == NULL)
{
printf("OPEN CONFIG FALID/n");
return 0;
}
fseek(f,0,SEEK_END);
long congig_lenth = ftell(f);
char sum_buf[congig_lenth+2];
memset(sum_buf,0,sizeof(sum_buf));
fseek(f,0,SEEK_SET);
while(fgets(config_linebuf,256,f) != NULL)
{
if(strlen(config_linebuf) < 3) //判断是否是空行
{
strcat(sum_buf,config_linebuf);
continue;
}
leave_line = NULL;
leave_line = strstr(config_linebuf,config_sign);
if(leave_line == NULL) //去除无"="的情况
{
strcat(sum_buf,config_linebuf);
continue;
}
int leave_num = leave_line - config_linebuf;
memset(line_name,0,sizeof(line_name));
strncpy(line_name,config_linebuf,leave_num);
if(strcmp(line_name,conf_name) !=0)
{
strcat(sum_buf,config_linebuf);
}
if(fgetc(f)==EOF)
{
break;
}
fseek(f,-1,SEEK_CUR);
memset(config_linebuf,0,sizeof(config_linebuf));
}
printf("---sum_buf---->%s<----------/n",sum_buf);
remove(conf_path);
fclose(f);
FILE *fp;
fp = fopen(conf_path,"w+");
if(fp == NULL)
{
printf("OPEN CONFIG FALID/n");
return 2;
}
fseek(fp,0,SEEK_SET);
fputs(sum_buf,fp);
fclose(fp);
}
#endif
/*
*
*
*1 2 3
*
*/
void set_if_config(char *if_name, char *conf_name, char *conf_buff)
{
char *conf_path = IFCONFIG_PATH;
char config_linebuf[IF_BUFF_LEN];
char static_name[IF_BUFF_LEN] = {0};
char iface_str[IF_BUFF_LEN] = {0};
char iface_str2[IF_BUFF_LEN] = {0};
char auto_str[IF_BUFF_LEN] = {0};
char *config_sign = "iface";
char *leave_line;
char *leave_line2;
int alter_sign = 0;
FILE *f;
f = fopen(conf_path,"r+");
if(f == NULL)
{
printf("OPEN CONFIG FALID\n");
return;
}
fseek(f,0,SEEK_END);
long congig_lenth = ftell(f);
int configbuf_lenth = strlen(conf_buff);
configbuf_lenth = configbuf_lenth + 5;
char sum_buf[congig_lenth+configbuf_lenth];
memset(sum_buf,0,sizeof(sum_buf));
fseek(f,0,SEEK_SET);
sprintf(iface_str, "%s %s", config_sign, if_name);
sprintf(iface_str2, "auto %s", if_name);
sprintf(static_name, "iface %s inet static\n", if_name);
leave_line = NULL;
leave_line2 = NULL;
while(fgets(config_linebuf,IF_BUFF_LEN,f) != NULL)
{
if(strlen(config_linebuf) < 3 || leave_line2) //判断是否是空行
{
strcat(sum_buf,config_linebuf);
continue;
}
if(leave_line == NULL)
{
leave_line = strstr(config_linebuf, iface_str);
if(leave_line)
{
strcat(sum_buf,static_name);
}
else
{
strcat(sum_buf,config_linebuf);
}
}
/*leave_line != NULL && leave_line2 !=NULL*/
else if((leave_line2 = strstr(config_linebuf,iface_str))
|| (leave_line2 = strstr(config_linebuf,iface_str2)))
{
if(alter_sign == 0)
{
strcat(sum_buf,conf_buff);
alter_sign = 1;
}
strcat(sum_buf,config_linebuf);
}
/*leave_line != NULL && leave_line2 == NULL*/
else
{
if(strstr(config_linebuf,conf_name) != NULL)
{
strcat(sum_buf,conf_buff);
alter_sign = 1;
}
else
{
strcat(sum_buf,config_linebuf);
}
}
if(fgetc(f)==EOF)
{
break;
}
fseek(f,-1,SEEK_CUR);
memset(config_linebuf,0,sizeof(config_linebuf));
}
if(leave_line == NULL)
{
sprintf(auto_str, "auto %s\n", if_name);
sprintf(auto_str, "%s", static_name);
strcat(sum_buf,auto_str);
}
if(alter_sign == 0)
{
//strcat(sum_buf,"\n");
strcat(sum_buf, conf_buff);
}
printf("---sum_buf---->%s<----------/n",sum_buf);
remove(conf_path);
fclose(f);
FILE *fp;
fp = fopen(conf_path,"w+");
if(fp == NULL)
{
printf("OPEN CONFIG FALID/n");
return;
}
fseek(fp,0,SEEK_SET);
fputs(sum_buf,fp);
fclose(fp);
return;
}
/*
*
*
*1
*
*/
void del_if_config(char *if_name, char *conf_buff)
{
char *conf_path = IFCONFIG_PATH;
char config_linebuf[IF_BUFF_LEN];
char iface_str[IF_BUFF_LEN] = {0};
char iface_str2[IF_BUFF_LEN] = {0};
char auto_str[IF_BUFF_LEN] = {0};
char *config_sign = "iface";
char *leave_line;
char *leave_line2;
int alter_sign = 0;
FILE *f;
f = fopen(conf_path,"r+");
if(f == NULL)
{
printf("OPEN CONFIG FALID\n");
return;
}
fseek(f,0,SEEK_END);
long congig_lenth = ftell(f);
int configbuf_lenth = strlen(conf_buff);
configbuf_lenth = configbuf_lenth + 5;
char sum_buf[congig_lenth+configbuf_lenth];
memset(sum_buf,0,sizeof(sum_buf));
fseek(f,0,SEEK_SET);
sprintf(iface_str, "%s %s", config_sign, if_name);
sprintf(iface_str2, "auto %s", if_name);
leave_line = NULL;
leave_line2 = NULL;
while(fgets(config_linebuf,256,f) != NULL)
{
if(strlen(config_linebuf) < 3 || leave_line2) //判断是否是空行
{
strcat(sum_buf,config_linebuf);
continue;
}
if(leave_line == NULL)
{
leave_line = strstr(config_linebuf, iface_str);
strcat(sum_buf,config_linebuf);
}
/*leave_line != NULL && leave_line2 !=NULL*/
else if((leave_line2 = strstr(config_linebuf,iface_str))
|| (leave_line2 = strstr(config_linebuf,iface_str2)))
{
strcat(sum_buf,config_linebuf);
}
/*leave_line != NULL && leave_line2 == NULL*/
else
{
if(strstr(config_linebuf,conf_buff) == NULL)
{
strcat(sum_buf,config_linebuf);
}
}
if(fgetc(f)==EOF)
{
break;
}
fseek(f,-1,SEEK_CUR);
memset(config_linebuf,0,sizeof(config_linebuf));
}
printf("---sum_buf---->%s<----------/n",sum_buf);
remove(conf_path);
fclose(f);
FILE *fp;
fp = fopen(conf_path,"w+");
if(fp == NULL)
{
printf("OPEN CONFIG FALID/n");
return;
}
fseek(fp,0,SEEK_SET);
fputs(sum_buf,fp);
fclose(fp);
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "parsefile.h"
#if 0
/*
*
*1 2 3
*==
*/
void read_config(char *conf_path,char *conf_name,char *config_buff)
{
char config_linebuf[256];
char line_name[40];
char exchange_buf[256];
char *config_sign = "=";
char *leave_line;
FILE *f;
f = fopen(conf_path,"r");
if(f == NULL)
{
printf("OPEN CONFIG FALID/n");
return 0;
}
fseek(f,0,SEEK_SET);
while(fgets(config_linebuf,256,f) != NULL)
{
if(strlen(config_linebuf) < 3) //判断是否是空行
{
continue;
}
if (config_linebuf[strlen(config_linebuf)-1] == 10) //去除最后一位是/n的情况
{
memset(exchange_buf,0,sizeof(exchange_buf));
strncpy(exchange_buf,config_linebuf,strlen(config_linebuf)-1);
memset(config_linebuf,0,sizeof(config_linebuf));
strcpy(config_linebuf,exchange_buf);
}
memset(line_name,0,sizeof(line_name));
leave_line = strstr(config_linebuf,config_sign);
if(leave_line == NULL) //去除无"="的情况
{
continue;
}
int leave_num = leave_line - config_linebuf;
strncpy(line_name,config_linebuf,leave_num);
if(strcmp(line_name,conf_name) ==0)
{
strncpy(config_buff,config_linebuf+(leave_num+1),strlen(config_linebuf)-leave_num-1);
break;
}
if(fgetc(f)==EOF)
{
break;
}
fseek(f,-1,SEEK_CUR);
memset(config_linebuf,0,sizeof(config_linebuf));
}
fclose(f);
}
/*
*
*
*1 2 3
*
*/
void add_set_config(char *conf_path,char *conf_name,char *config_buff)
{
char config_linebuf[256];
char line_name[40];
char *config_sign = "=";
char *leave_line;
int alter_sign = 0;
FILE *f;
f = fopen(conf_path,"r+");
if(f == NULL)
{
printf("OPEN CONFIG FALID/n");
return 0;
}
fseek(f,0,SEEK_END);
long congig_lenth = ftell(f);
int configbuf_lenth = strlen(config_buff);
configbuf_lenth = configbuf_lenth + 5;
char sum_buf[congig_lenth+configbuf_lenth];
memset(sum_buf,0,sizeof(sum_buf));
fseek(f,0,SEEK_SET);
while(fgets(config_linebuf,256,f) != NULL)
{
if(strlen(config_linebuf) < 3) //判断是否是空行
{
strcat(sum_buf,config_linebuf);
continue;
}
leave_line = NULL;
leave_line = strstr(config_linebuf,config_sign);
if(leave_line == NULL) //去除无"="的情况
{
strcat(sum_buf,config_linebuf);
continue;
}
int leave_num = leave_line - config_linebuf;
memset(line_name,0,sizeof(line_name));
strncpy(line_name,config_linebuf,leave_num);
if(strcmp(line_name,conf_name) ==0)
{
strcat(sum_buf,config_buff);
strcat(sum_buf,"/n");
alter_sign = 1;
}
else
{
strcat(sum_buf,config_linebuf);
}
if(fgetc(f)==EOF)
{
break;
}
fseek(f,-1,SEEK_CUR);
memset(config_linebuf,0,sizeof(config_linebuf));
}
if(alter_sign == 0)
{
strcat(sum_buf,config_buff);
strcat(sum_buf,"/n");
}
printf("---sum_buf---->%s<----------/n",sum_buf);
remove(conf_path);
fclose(f);
FILE *fp;
fp = fopen(conf_path,"w+");
if(fp == NULL)
{
printf("OPEN CONFIG FALID/n");
return 2;
}
fseek(fp,0,SEEK_SET);
fputs(sum_buf,fp);
fclose(fp);
}
/*
*
*
*1
*
*/
void del_if_config(char *conf_name)
{
char *conf_path = "/etc/network/interface";
char config_linebuf[256];
char line_name[40];
char *config_sign = "=";
char *leave_line;
FILE *f;
f = fopen(conf_path,"r+");
if(f == NULL)
{
printf("OPEN CONFIG FALID/n");
return 0;
}
fseek(f,0,SEEK_END);
long congig_lenth = ftell(f);
char sum_buf[congig_lenth+2];
memset(sum_buf,0,sizeof(sum_buf));
fseek(f,0,SEEK_SET);
while(fgets(config_linebuf,256,f) != NULL)
{
if(strlen(config_linebuf) < 3) //判断是否是空行
{
strcat(sum_buf,config_linebuf);
continue;
}
leave_line = NULL;
leave_line = strstr(config_linebuf,config_sign);
if(leave_line == NULL) //去除无"="的情况
{
strcat(sum_buf,config_linebuf);
continue;
}
int leave_num = leave_line - config_linebuf;
memset(line_name,0,sizeof(line_name));
strncpy(line_name,config_linebuf,leave_num);
if(strcmp(line_name,conf_name) !=0)
{
strcat(sum_buf,config_linebuf);
}
if(fgetc(f)==EOF)
{
break;
}
fseek(f,-1,SEEK_CUR);
memset(config_linebuf,0,sizeof(config_linebuf));
}
printf("---sum_buf---->%s<----------/n",sum_buf);
remove(conf_path);
fclose(f);
FILE *fp;
fp = fopen(conf_path,"w+");
if(fp == NULL)
{
printf("OPEN CONFIG FALID/n");
return 2;
}
fseek(fp,0,SEEK_SET);
fputs(sum_buf,fp);
fclose(fp);
}
#endif
/*
*
*
*1 2 3
*
*/
void set_if_config(char *if_name, char *conf_name, char *conf_buff)
{
char *conf_path = IFCONFIG_PATH;
char config_linebuf[IF_BUFF_LEN];
char static_name[IF_BUFF_LEN] = {0};
char iface_str[IF_BUFF_LEN] = {0};
char iface_str2[IF_BUFF_LEN] = {0};
char auto_str[IF_BUFF_LEN] = {0};
char *config_sign = "iface";
char *leave_line;
char *leave_line2;
int alter_sign = 0;
FILE *f;
f = fopen(conf_path,"r+");
if(f == NULL)
{
printf("OPEN CONFIG FALID\n");
return;
}
fseek(f,0,SEEK_END);
long congig_lenth = ftell(f);
int configbuf_lenth = strlen(conf_buff);
configbuf_lenth = configbuf_lenth + 5;
char sum_buf[congig_lenth+configbuf_lenth];
memset(sum_buf,0,sizeof(sum_buf));
fseek(f,0,SEEK_SET);
sprintf(iface_str, "%s %s", config_sign, if_name);
sprintf(iface_str2, "auto %s", if_name);
sprintf(static_name, "iface %s inet static\n", if_name);
leave_line = NULL;
leave_line2 = NULL;
while(fgets(config_linebuf,IF_BUFF_LEN,f) != NULL)
{
if(strlen(config_linebuf) < 3 || leave_line2) //判断是否是空行
{
strcat(sum_buf,config_linebuf);
continue;
}
if(leave_line == NULL)
{
leave_line = strstr(config_linebuf, iface_str);
if(leave_line)
{
strcat(sum_buf,static_name);
}
else
{
strcat(sum_buf,config_linebuf);
}
}
/*leave_line != NULL && leave_line2 !=NULL*/
else if((leave_line2 = strstr(config_linebuf,iface_str))
|| (leave_line2 = strstr(config_linebuf,iface_str2)))
{
if(alter_sign == 0)
{
strcat(sum_buf,conf_buff);
alter_sign = 1;
}
strcat(sum_buf,config_linebuf);
}
/*leave_line != NULL && leave_line2 == NULL*/
else
{
if(strstr(config_linebuf,conf_name) != NULL)
{
strcat(sum_buf,conf_buff);
alter_sign = 1;
}
else
{
strcat(sum_buf,config_linebuf);
}
}
if(fgetc(f)==EOF)
{
break;
}
fseek(f,-1,SEEK_CUR);
memset(config_linebuf,0,sizeof(config_linebuf));
}
if(leave_line == NULL)
{
sprintf(auto_str, "auto %s\n", if_name);
sprintf(auto_str, "%s", static_name);
strcat(sum_buf,auto_str);
}
if(alter_sign == 0)
{
//strcat(sum_buf,"\n");
strcat(sum_buf, conf_buff);
}
printf("---sum_buf---->%s<----------/n",sum_buf);
remove(conf_path);
fclose(f);
FILE *fp;
fp = fopen(conf_path,"w+");
if(fp == NULL)
{
printf("OPEN CONFIG FALID/n");
return;
}
fseek(fp,0,SEEK_SET);
fputs(sum_buf,fp);
fclose(fp);
return;
}
/*
*
*
*1
*
*/
void del_if_config(char *if_name, char *conf_buff)
{
char *conf_path = IFCONFIG_PATH;
char config_linebuf[IF_BUFF_LEN];
char iface_str[IF_BUFF_LEN] = {0};
char iface_str2[IF_BUFF_LEN] = {0};
char auto_str[IF_BUFF_LEN] = {0};
char *config_sign = "iface";
char *leave_line;
char *leave_line2;
int alter_sign = 0;
FILE *f;
f = fopen(conf_path,"r+");
if(f == NULL)
{
printf("OPEN CONFIG FALID\n");
return;
}
fseek(f,0,SEEK_END);
long congig_lenth = ftell(f);
int configbuf_lenth = strlen(conf_buff);
configbuf_lenth = configbuf_lenth + 5;
char sum_buf[congig_lenth+configbuf_lenth];
memset(sum_buf,0,sizeof(sum_buf));
fseek(f,0,SEEK_SET);
sprintf(iface_str, "%s %s", config_sign, if_name);
sprintf(iface_str2, "auto %s", if_name);
leave_line = NULL;
leave_line2 = NULL;
while(fgets(config_linebuf,256,f) != NULL)
{
if(strlen(config_linebuf) < 3 || leave_line2) //判断是否是空行
{
strcat(sum_buf,config_linebuf);
continue;
}
if(leave_line == NULL)
{
leave_line = strstr(config_linebuf, iface_str);
strcat(sum_buf,config_linebuf);
}
/*leave_line != NULL && leave_line2 !=NULL*/
else if((leave_line2 = strstr(config_linebuf,iface_str))
|| (leave_line2 = strstr(config_linebuf,iface_str2)))
{
strcat(sum_buf,config_linebuf);
}
/*leave_line != NULL && leave_line2 == NULL*/
else
{
if(strstr(config_linebuf,conf_buff) == NULL)
{
strcat(sum_buf,config_linebuf);
}
}
if(fgetc(f)==EOF)
{
break;
}
fseek(f,-1,SEEK_CUR);
memset(config_linebuf,0,sizeof(config_linebuf));
}
printf("---sum_buf---->%s<----------/n",sum_buf);
remove(conf_path);
fclose(f);
FILE *fp;
fp = fopen(conf_path,"w+");
if(fp == NULL)
{
printf("OPEN CONFIG FALID/n");
return;
}
fseek(fp,0,SEEK_SET);
fputs(sum_buf,fp);
fclose(fp);
}

View File

@ -1,257 +1,146 @@
#include <stdlib.h>
#include <stdio.h>
#include "rpc.h"
#include "configm.h"
#include "ipconfig.h"
rpc_client *config_client = NULL;
rpc_client *config_client_get()
{
if(config_client == NULL)
{
config_client = rpc_client_connect_ex("ConfigManger#0");
if(config_client == NULL)
{
rpc_log_error("connect ConfigManger#0 error\n");
return NULL;
}
}
return config_client;
}
ret_code config_construct_msg(uint config_type, uint64 config_id,
char* config_data, int config_len,
config_msg_t **config_msg, int *msg_len)
{
config_msg_t *pconfig_msg;
if(config_data == NULL)
{
return RET_NULLP;
}
*msg_len = sizeof(config_msg_t) + config_len;
pconfig_msg= (config_msg_t *) malloc(*msg_len);
if(pconfig_msg == NULL)
{
return RET_NOMEM;
}
pconfig_msg->source = CONFIG_FROM_WEB;
pconfig_msg->config_type = config_type;
pconfig_msg->config_id = config_id;
memcpy(pconfig_msg->config_buff, config_data, config_len);
*config_msg = pconfig_msg;
return RET_OK;
}
ret_code config_destroy_msg(config_msg_t *config_msg, int msg_len)
{
if(config_msg)
{
memset(config_msg, 0, msg_len);
free(config_msg);
}
}
ret_code web_config_exec_sync(uint config_type, uint64 config_id,
char* config_data, int config_len,
char**output, int *output_len)
{
rpc_client * client = config_client_get();
ret_code code = RET_OK ;
config_msg_t *config_msg;
int msg_len = 0;
if(client == NULL)
{
return RET_ERR;
}
code = config_construct_msg(config_type, config_id, config_data,
config_len, &config_msg, &msg_len);
ASSERT_RET(code);
code = rpc_client_call(client, "ConfigManger#0", "cm_config_process",
config_msg, msg_len, (pointer)output, output_len);
ASSERT_RET_NO(code);
config_destroy_msg(config_msg, msg_len);
return code;
}
ret_code web_config_exec_async(uint config_type, uint64 config_id,
char* config_data, int config_len,
rpc_callback callback, pointer data)
{
rpc_client * client = config_client_get();
config_msg_t *config_msg;
int msg_len = 0;
ret_code ret = RET_OK ;
if(client == NULL)
{
return RET_ERR;
}
ret = config_construct_msg(config_type, config_id, config_data,
config_len, &config_msg, &msg_len);
ASSERT_RET(ret);
ret = rpc_client_call_async(client, "ConfigManger#0", "cm_config_process",
config_msg, msg_len, callback, data);
config_destroy_msg(config_msg, msg_len);
return ret;
}
//big data test
//async
//sync io
static char* test_data = "给李彦宏先生的一封信 (2011-03-26 04:33:37)转载"
"标签: 杂谈 "
"您好,李彦宏先生。"
"上周我和出版社的朋友沈浩波先生去山东的纸厂销毁已经印刷完毕的一百多万册《独唱团》第二期,三百多吨的纸和工业垃圾一起进了化浆炉。"
"几百万的损失对您来说可能是个小数目,但是对一个出版公司来说几乎等于一年白干了,那还得是国内数得上数的大出版公司。"
"这个行业就是这么可怜的,一个一百多人的企业一年的利润还不如在上海炒一套公寓,而且分分钟要背上“黑心书商”的骂名。"
"但是沈浩波一直很高兴,因为他说和百度的谈判终于有眉目了,百度答应派人来商量百度文库的事情,李承鹏,慕容雪村,路金波,彭浩翔,"
"都是文化行业里数一数二的畅销书作家,导演和出版商,大家都很激动,准备了好几个晚上各种资料。"
"于是昨天开始谈判了,您派来几个高傲的中层,始终不承认百度文库有任何的侵权行为。"
"你们不认为那包含了几乎全中国所有最新最旧图书的279万份文档是侵权而是网民自己上传给大家共享的。"
"你这里只是一个平台。我觉得其实我们不用讨论平台不平台,侵权不侵权这个问题了,您其实什么都心知肚明。"
"您在美国有那么长时间的生活经历,现在您的妻子和女儿也都在美国,您一定知道如果百度开了一个叫百度美国的搜索引擎,"
"然后把全美国所有的作家的书和所有音乐人的音乐都放在百度美国上面免费共享会是什么样的一个结果。"
"您不会这么做,您也不会和美国人去谈什么这只是一个平台,和我没关系,都是网民自己干的,互联网的精神是共享。"
"因为您知道这事儿只有在现在的中国才能成立。而且您也知道谁能欺负,谁不能欺负,您看,您就没有做一个百度影剧院,让大家共享共享最新的电影电视剧。"
"您也许不太了解出版行业我可以简单的给您介绍一下。1999年十二年前我的书卖18元一本2011年卖25元一本很多读者还都嫌贵。"
"您知道这十二年间,纸张,人工,物流都涨了多少倍,但出版商一直不敢提太多价,因为怕被骂,文化人脸皮都薄。"
"一本25元的书一般作者的版税是百分之8可以赚2块钱其中还要交三毛钱左右的税也就是可以赚一块七。"
"一本书如果卖两万本,已经算是畅销,一个作家两年能写一本,一本可以赚三万四,一年赚一万七,如果他光写书,"
"他得不吃不喝写一百年才够在大城市的城郊买套像样的两居室。假设一本书卖10元里面的构成是这样的作家赚1元印刷成本2元多"
"出版社赚1元多书店赚5元。有点名气的作家出去签售做宣传住的都是三星的酒店来回能坐上飞机已经算不错了。"
"出行标准一定还不如你们的低级别员工。最近几年我已经不出席任何宣传签售活动了但是在2004年前"
"我至少做过几十场各个城市的宣传活动而在那个时候我已经是行业里的畅销书作家我从没住到过一次300以上的酒店"
"有的时候和出版社陪同的几个人得在机场等好几个小时,因为打折的那班飞机得傍晚起飞,而多住半天酒店得加钱。"
"这个行业就是这么窘迫的。这个行业里最顶尖的企业家,年收入就几百万。出版业和互联网业,本是两个级别相当的行业,"
"你们是用几百亿身价和私人飞机豪华游艇来算企业家身价的,我们这个行业里的企业家们,我几乎没见过一个出行坐头等舱的。"
"我们倒不是眼红你们有钱,我们只是觉得,你们都那么富有了,为何还要一分钱都不肯花从我们这个行业里强行获得免费的知识版权。"
"音乐人还可以靠商演赚钱,而你让作家和出版行业如何生存。也许你说,传统出版会始终消亡,但那不代表出版行业就该如此的不体面。"
"而且文艺作品和出版行业是不会消亡的,只是换了一个介质,一开始它们被画在墙上,后来刻在竹子上,现在有书,未来也许有别的科技,"
"但版权是永远存在的。我写这些并不是代表这个行业向你们哭穷,"
"但这的确中国唯一一个拥有很多的资源与生活息息相关却没有什么财富可言的行业。尤其在盗版和侵权的伤害之下。"
"我们也不是要求你们把百度文库关了,我们只是希望百度文库可以主动对版权进行保护,等未来数字阅读成熟以后,"
"说不定百度文库还能成为中国作家生活保障的来源,而不是现在这样,成为行业公敌众矢之的。因为没有永远的敌人,也没有永远的利益。"
"我在2006年还和磨铁图书的沈浩波先生打过笔仗为了现代诗互相骂的不可开交而现在却是朋友和合作伙伴。"
"百度文库完全可以成为造福作家的基地,而不是埋葬作家的墓地。"
"在我们这个行业里,我算是生活得好的。李彦宏先生,也许我们一样,虽不畏惧,但并不喜欢这些是非恩怨,我喜欢晒晒太阳玩泥巴,"
"你喜欢晒晒太阳种种花。无论你怎么共享我的知识版权,至少咱俩还能一起晒晒太阳,毕竟我赛车还能养活自己和家庭,"
"但对于大部分作家来说,他们理应靠着传统的出版和数字出版过着体面的生活。也许他们未必能够有自己的院子晒太阳。"
"您的产品会把他们赶回阴暗的小屋里为了生活不停的写,而您头上的太阳也并不会因此大一些。"
"中国那么多的写作者被迫为百度无偿的提供了无数的知识版权和流量,他们不光没有来找过百度麻烦或者要求百度分点红,"
"甚至还要承受百度拥趸们的侮辱以及百度员工谈判时的蔑视。您现在是中国排名第一的企业家,作为企业家的表率,"
"您必须对百度文库给出版行业带来的伤害有所表态。倘若百度文库始终不肯退一步,那我可以多走几步,也许在不远的某天,"
"在您北京的办公室里往楼下望去,您可以看见我。"
" 祝 您的女儿为她的父亲感到骄傲"
" 韩寒"
"2011年 3月26日"
"end";
void ip_set_callback(ret_code code, pointer output,
int output_len, pointer data)
{
int i;
//rpc_log_info("call %s i is %d len is %d", rpc_code_format(code), *(int *)data, output_len);
if(code != RET_OK)
{
rpc_log_info("ERROR: %s", (char *)output);
}
}
int main(int argc, char **argv)
{
rpc_client *client = rpc_client_connect_ex("ConfigManger#0");
ip_config_t ip_conf;
ip_config_t *pip_conf;
int i = 0, result;
ret_code code;
char* output = NULL;
int output_len;
strcpy(ip_conf.ifname, "ens39");
ip_conf.prefix.s_addr = inet_addr("192.168.80.1");
ip_conf.family=AF_INET;
ip_conf.prefixlen = 24;
code = rpc_client_call(client, "ConfigManger#0", "test_big_data", test_data,
strlen(test_data), NULL, NULL);
ASSERT_RET_NO(code);
/*code = web_config_exec_sync(CM_CONFIG_ADD, IPCONFIG_V4,
(pointer)&ip_conf, sizeof(ip_conf), &output, &output_len);
rpc_log_info("call CM_CONFIG_ADD %s: %s\n", rpc_code_format(code), output);*/
code = web_config_exec_sync(CM_CONFIG_DEL, IPCONFIG_V4,
(pointer)&ip_conf, sizeof(ip_conf), &output, &output_len);
rpc_log_info("call CM_CONFIG_DEL %s: %s\n", rpc_code_format(code), output);
/*code = web_config_exec_sync(CM_CONFIG_SET, IPCONFIG_V4,
(pointer)&ip_conf, sizeof(ip_conf), &output, &output_len);
rpc_log_info("call CM_CONFIG_SET %s: %s\n", rpc_code_format(code), output);*/
code = web_config_exec_sync(CM_CONFIG_GET_ALL, IPCONFIG_V4,
(pointer)&ip_conf, sizeof(ip_conf), &output, &output_len);
rpc_log_info("call CM_CONFIG_GET_ALL %s: %s\n", rpc_code_format(code), output);
for(i = 0; i < output_len / sizeof(ip_config_t); i++)
{
pip_conf = (ip_config_t *)output;
printf("ifname is %s\n",pip_conf[i].ifname);
printf("family is %d\n", pip_conf[i].family);
printf("ip is %s\n", inet_ntoa(pip_conf[i].prefix));
printf("prefix len is %d\n", pip_conf[i].prefixlen);
}
code = web_config_exec_sync(CM_CONFIG_GET, IPCONFIG_V4,
(pointer)&ip_conf, sizeof(ip_conf), &output, &output_len);
rpc_log_info("call %s: %s\n", rpc_code_format(code), output);
/* code = web_config_exec_async(CM_CONFIG_ADD, IPCONFIG_V4, (pointer)&ip_conf, sizeof(ip_conf), ip_set_callback, &i);
rpc_log_info("call CM_CONFIG_ADD: %s\n", rpc_code_format(code));
code = web_config_exec_async(CM_CONFIG_DEL, IPCONFIG_V4, (pointer)&ip_conf, sizeof(ip_conf), ip_set_callback, &i);
rpc_log_info("call CM_CONFIG_DEL: %s\n", rpc_code_format(code));
code = web_config_exec_async(CM_CONFIG_SET, IPCONFIG_V4, (pointer)&ip_conf, sizeof(ip_conf), ip_set_callback, &i);
rpc_log_info("call CM_CONFIG_SET: %s\n", rpc_code_format(code));
code = web_config_exec_async(CM_CONFIG_GET, IPCONFIG_V4, (pointer)&ip_conf, sizeof(ip_conf), ip_set_callback, &i);
rpc_log_info("call CM_CONFIG_GET: %s\n", rpc_code_format(code));
code = web_config_exec_async(CM_CONFIG_GET_ALL, IPCONFIG_V4, (pointer)&ip_conf, sizeof(ip_conf), ip_set_callback, &i);
rpc_log_info("call CM_CONFIG_GET_ALL: %s\n", rpc_code_format(code));*/
printf("test ok\n");
for (;;) {
rpc_sleep(1000);
}
return EXIT_SUCCESS;
}
#include <stdlib.h>
#include <stdio.h>
#include "rpc.h"
#include "configm.h"
#include "ipconfig.h"
//big data test
//async
//sync io
static char* test_data = "给李彦宏先生的一封信 (2011-03-26 04:33:37)转载"
"标签: 杂谈 "
"您好,李彦宏先生。"
"上周我和出版社的朋友沈浩波先生去山东的纸厂销毁已经印刷完毕的一百多万册《独唱团》第二期,三百多吨的纸和工业垃圾一起进了化浆炉。"
"几百万的损失对您来说可能是个小数目,但是对一个出版公司来说几乎等于一年白干了,那还得是国内数得上数的大出版公司。"
"这个行业就是这么可怜的,一个一百多人的企业一年的利润还不如在上海炒一套公寓,而且分分钟要背上“黑心书商”的骂名。"
"但是沈浩波一直很高兴,因为他说和百度的谈判终于有眉目了,百度答应派人来商量百度文库的事情,李承鹏,慕容雪村,路金波,彭浩翔,"
"都是文化行业里数一数二的畅销书作家,导演和出版商,大家都很激动,准备了好几个晚上各种资料。"
"于是昨天开始谈判了,您派来几个高傲的中层,始终不承认百度文库有任何的侵权行为。"
"你们不认为那包含了几乎全中国所有最新最旧图书的279万份文档是侵权而是网民自己上传给大家共享的。"
"你这里只是一个平台。我觉得其实我们不用讨论平台不平台,侵权不侵权这个问题了,您其实什么都心知肚明。"
"您在美国有那么长时间的生活经历,现在您的妻子和女儿也都在美国,您一定知道如果百度开了一个叫百度美国的搜索引擎,"
"然后把全美国所有的作家的书和所有音乐人的音乐都放在百度美国上面免费共享会是什么样的一个结果。"
"您不会这么做,您也不会和美国人去谈什么这只是一个平台,和我没关系,都是网民自己干的,互联网的精神是共享。"
"因为您知道这事儿只有在现在的中国才能成立。而且您也知道谁能欺负,谁不能欺负,您看,您就没有做一个百度影剧院,让大家共享共享最新的电影电视剧。"
"您也许不太了解出版行业我可以简单的给您介绍一下。1999年十二年前我的书卖18元一本2011年卖25元一本很多读者还都嫌贵。"
"您知道这十二年间,纸张,人工,物流都涨了多少倍,但出版商一直不敢提太多价,因为怕被骂,文化人脸皮都薄。"
"一本25元的书一般作者的版税是百分之8可以赚2块钱其中还要交三毛钱左右的税也就是可以赚一块七。"
"一本书如果卖两万本,已经算是畅销,一个作家两年能写一本,一本可以赚三万四,一年赚一万七,如果他光写书,"
"他得不吃不喝写一百年才够在大城市的城郊买套像样的两居室。假设一本书卖10元里面的构成是这样的作家赚1元印刷成本2元多"
"出版社赚1元多书店赚5元。有点名气的作家出去签售做宣传住的都是三星的酒店来回能坐上飞机已经算不错了。"
"出行标准一定还不如你们的低级别员工。最近几年我已经不出席任何宣传签售活动了但是在2004年前"
"我至少做过几十场各个城市的宣传活动而在那个时候我已经是行业里的畅销书作家我从没住到过一次300以上的酒店"
"有的时候和出版社陪同的几个人得在机场等好几个小时,因为打折的那班飞机得傍晚起飞,而多住半天酒店得加钱。"
"这个行业就是这么窘迫的。这个行业里最顶尖的企业家,年收入就几百万。出版业和互联网业,本是两个级别相当的行业,"
"你们是用几百亿身价和私人飞机豪华游艇来算企业家身价的,我们这个行业里的企业家们,我几乎没见过一个出行坐头等舱的。"
"我们倒不是眼红你们有钱,我们只是觉得,你们都那么富有了,为何还要一分钱都不肯花从我们这个行业里强行获得免费的知识版权。"
"音乐人还可以靠商演赚钱,而你让作家和出版行业如何生存。也许你说,传统出版会始终消亡,但那不代表出版行业就该如此的不体面。"
"而且文艺作品和出版行业是不会消亡的,只是换了一个介质,一开始它们被画在墙上,后来刻在竹子上,现在有书,未来也许有别的科技,"
"但版权是永远存在的。我写这些并不是代表这个行业向你们哭穷,"
"但这的确中国唯一一个拥有很多的资源与生活息息相关却没有什么财富可言的行业。尤其在盗版和侵权的伤害之下。"
"我们也不是要求你们把百度文库关了,我们只是希望百度文库可以主动对版权进行保护,等未来数字阅读成熟以后,"
"说不定百度文库还能成为中国作家生活保障的来源,而不是现在这样,成为行业公敌众矢之的。因为没有永远的敌人,也没有永远的利益。"
"我在2006年还和磨铁图书的沈浩波先生打过笔仗为了现代诗互相骂的不可开交而现在却是朋友和合作伙伴。"
"百度文库完全可以成为造福作家的基地,而不是埋葬作家的墓地。"
"在我们这个行业里,我算是生活得好的。李彦宏先生,也许我们一样,虽不畏惧,但并不喜欢这些是非恩怨,我喜欢晒晒太阳玩泥巴,"
"你喜欢晒晒太阳种种花。无论你怎么共享我的知识版权,至少咱俩还能一起晒晒太阳,毕竟我赛车还能养活自己和家庭,"
"但对于大部分作家来说,他们理应靠着传统的出版和数字出版过着体面的生活。也许他们未必能够有自己的院子晒太阳。"
"您的产品会把他们赶回阴暗的小屋里为了生活不停的写,而您头上的太阳也并不会因此大一些。"
"中国那么多的写作者被迫为百度无偿的提供了无数的知识版权和流量,他们不光没有来找过百度麻烦或者要求百度分点红,"
"甚至还要承受百度拥趸们的侮辱以及百度员工谈判时的蔑视。您现在是中国排名第一的企业家,作为企业家的表率,"
"您必须对百度文库给出版行业带来的伤害有所表态。倘若百度文库始终不肯退一步,那我可以多走几步,也许在不远的某天,"
"在您北京的办公室里往楼下望去,您可以看见我。"
" 祝 您的女儿为她的父亲感到骄傲"
" 韩寒"
"2011年 3月26日"
"end";
void ip_set_callback(ret_code code, pointer output,
int output_len, pointer data)
{
int i;
//rpc_log_info("call %s i is %d len is %d", rpc_code_format(code), *(int *)data, output_len);
if(code != RET_OK)
{
rpc_log_info("ERROR: %s", (char *)output);
}
}
int main(int argc, char **argv)
{
rpc_client *client = rpc_client_connect_ex("ConfigManger#0");
ip_config_t ip_conf;
ip_config_t *pip_conf;
int i = 0, result;
ret_code code;
char* output = NULL;
int output_len;
strcpy(ip_conf.ifname, "ens39");
ip_conf.prefix.s_addr = inet_addr("192.168.80.1");
ip_conf.family=AF_INET;
ip_conf.prefixlen = 24;
code = rpc_client_call(client, "ConfigManger#0", "test_big_data", test_data,
strlen(test_data), NULL, NULL);
ASSERT_RET_NO(code);
/*code = web_config_exec_sync(CM_CONFIG_ADD, IPCONFIG_V4,
(pointer)&ip_conf, sizeof(ip_conf), &output, &output_len);
rpc_log_info("call CM_CONFIG_ADD %s: %s\n", rpc_code_format(code), output);*/
code = web_config_exec_sync(CM_CONFIG_DEL, IPCONFIG_V4,
(pointer)&ip_conf, sizeof(ip_conf), &output, &output_len);
rpc_log_info("call CM_CONFIG_DEL %s: %s\n", rpc_code_format(code), output);
/*code = web_config_exec_sync(CM_CONFIG_SET, IPCONFIG_V4,
(pointer)&ip_conf, sizeof(ip_conf), &output, &output_len);
rpc_log_info("call CM_CONFIG_SET %s: %s\n", rpc_code_format(code), output);*/
code = web_config_exec_sync(CM_CONFIG_GET_ALL, IPCONFIG_V4,
(pointer)&ip_conf, sizeof(ip_conf), &output, &output_len);
rpc_log_info("call CM_CONFIG_GET_ALL %s: %s\n", rpc_code_format(code), output);
for(i = 0; i < output_len / sizeof(ip_config_t); i++)
{
pip_conf = (ip_config_t *)output;
printf("ifname is %s\n",pip_conf[i].ifname);
printf("family is %d\n", pip_conf[i].family);
printf("ip is %s\n", inet_ntoa(pip_conf[i].prefix));
printf("prefix len is %d\n", pip_conf[i].prefixlen);
}
code = web_config_exec_sync(CM_CONFIG_GET, IPCONFIG_V4,
(pointer)&ip_conf, sizeof(ip_conf), &output, &output_len);
rpc_log_info("call %s: %s\n", rpc_code_format(code), output);
/* code = web_config_exec_async(CM_CONFIG_ADD, IPCONFIG_V4, (pointer)&ip_conf, sizeof(ip_conf), ip_set_callback, &i);
rpc_log_info("call CM_CONFIG_ADD: %s\n", rpc_code_format(code));
code = web_config_exec_async(CM_CONFIG_DEL, IPCONFIG_V4, (pointer)&ip_conf, sizeof(ip_conf), ip_set_callback, &i);
rpc_log_info("call CM_CONFIG_DEL: %s\n", rpc_code_format(code));
code = web_config_exec_async(CM_CONFIG_SET, IPCONFIG_V4, (pointer)&ip_conf, sizeof(ip_conf), ip_set_callback, &i);
rpc_log_info("call CM_CONFIG_SET: %s\n", rpc_code_format(code));
code = web_config_exec_async(CM_CONFIG_GET, IPCONFIG_V4, (pointer)&ip_conf, sizeof(ip_conf), ip_set_callback, &i);
rpc_log_info("call CM_CONFIG_GET: %s\n", rpc_code_format(code));
code = web_config_exec_async(CM_CONFIG_GET_ALL, IPCONFIG_V4, (pointer)&ip_conf, sizeof(ip_conf), ip_set_callback, &i);
rpc_log_info("call CM_CONFIG_GET_ALL: %s\n", rpc_code_format(code));*/
printf("test ok\n");
for (;;) {
rpc_sleep(1000);
}
return EXIT_SUCCESS;
}