4
* Author: Jia Ming Pan <jmltc@cn.ibm.com>
5
* Copyright (c) 2005 International Business Machines
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
#include <lha_internal.h>
30
#include <sys/types.h>
34
#include <heartbeat.h>
35
#include "cluster_info.h"
40
static char * pathname_encode(const char *);
43
cim_init_logger(const char * entity)
45
char * inherit_debuglevel;
48
inherit_debuglevel = getenv(HADEBUGVAL);
49
if (inherit_debuglevel != NULL) {
50
debug_level = atoi(inherit_debuglevel);
51
if (debug_level > 2) {
56
cl_log_set_entity(entity);
57
cl_log_enable_stderr(debug_level?TRUE:FALSE);
58
cl_log_set_facility(HA_LOG_FACILITY);
63
run_shell_cmnd(const char *cmnd, int *ret, char ***out, char ***err)
64
/* err not used currently */
66
FILE * fstream = NULL;
71
if ( (fstream = popen(cmnd, "r")) == NULL ){
72
cl_log(LOG_ERR, "run_shell_cmnd: popen error: %s",
77
if ( (*out = cim_malloc(sizeof(char*)) ) == NULL ) {
78
cl_log(LOG_ERR, "run_shell_cmnd: failed malloc.");
85
while (!feof(fstream)) {
86
if ( fgets(buffer, 4096, fstream) != NULL ){
87
/** add buffer to out **/
88
*out = cim_realloc(*out, (i+2) * sizeof(char*));
93
(*out)[i] = cim_strdup(buffer);
103
if ( (cmnd_rc = pclose(fstream)) == -1 ){
104
/*** WARNING log ***/
105
cl_log(LOG_WARNING, "failed to close pipe.");
114
regex_search(const char * reg, const char * str, int * len)
117
const int maxmatch = 16;
119
int i, ret, nmatch = 0;
125
ret = regcomp(®exp, reg, REG_EXTENDED);
127
cl_log(LOG_ERR, "regex_search: error regcomp regex %s.", reg);
131
ret = regexec(®exp, str, nmatch, pm, 0);
132
if ( ret == REG_NOMATCH ){
134
cl_log(LOG_ERR, "regex_search: no match.");
137
cl_log(LOG_ERR, "regex_search: error regexec.\n");
142
for(nmatch=0; pm[nmatch].rm_so != -1 && nmatch < maxmatch; nmatch++);
144
if ( (match = cim_malloc(nmatch*sizeof(char *))) == NULL ) {
145
cl_log(LOG_ERR, "regex_search: alloc_failed.");
151
for(i = 0; i < maxmatch && i < nmatch; i++){
152
int str_len = pm[i].rm_eo - pm[i].rm_so;
153
if ((match[i] = cim_malloc(str_len + 1))) {
154
strncpy( match[i], str + pm[i].rm_so, str_len);
155
match[i][str_len] = EOS;
164
free_2d_zarray(void *zarray, cim_free_t free)
166
void ** z = (void **)zarray;
177
free_2d_array(void * a, int len, cim_free_t free)
180
void ** array = (void **)a;
182
for (i=0; i<len; i++){
191
uuid_to_str(const cl_uuid_t * uuid){
193
char * str = cim_malloc(256);
201
for ( i = 0; i < sizeof(cl_uuid_t); i++){
202
len += snprintf(str + len, 2, "%.2X", uuid->uuid[i]);
208
cim_assert(const char * assertion, int line, const char * file)
210
cl_log(LOG_ERR, "Assertion \"%s\" failed on line %d in file \"%s\""
211
, assertion, line, file);
217
split_string(const char* string, int *len, const char *delim)
219
char **strings = NULL;
225
/* eat up delim chars */
226
while (*string && strchr(delim, *string)) {
234
/* reach a delim char */
236
while ( *p && !strchr(delim, *p) ) {
241
/* copy string~(p-1) to token */
242
token = cim_malloc(p-string+1);
243
if ( token == NULL ) {
246
memcpy(token, string, p - string);
247
token[p-string] = EOS;
249
strings = cim_realloc(strings, (*len+1) * sizeof(char *));
250
if ( strings == NULL ) {
253
strings[*len] = token;
261
cim_msg2disk(const char *objpathname, struct ha_msg *msg)
265
char pathname[MAXLEN], *buf;
268
if ( stat(HA_CIM_VARDIR, &st) < 0 ) {
269
if ( errno == ENOENT ) { /* not exist, create */
270
if ( mkdir(HA_CIM_VARDIR, 0660) < 0){
271
cl_log(LOG_ERR,"msg2disk: mkdir failed.");
272
cl_log(LOG_ERR,"reason:%s",strerror(errno));
277
cl_log(LOG_ERR, "msg2disk: stat faild.");
278
cl_log(LOG_ERR,"reason:%d(%s)",errno,strerror(errno));
286
if((buf = pathname_encode(objpathname))== NULL ) {
289
snprintf(pathname, MAXLEN, "%s/%s", HA_CIM_VARDIR, buf);
292
if ( ( fobj = fopen(pathname, "w") ) == NULL ) {
293
cl_log(LOG_WARNING, "msg2disk: can't open file.");
294
cl_log(LOG_WARNING, "reason:%d(%s)", errno, strerror(errno));
297
if ( msg->nfields == 0 ) {
302
if ((msgstr = msg2string(msg)) == NULL ) {
303
cl_log(LOG_ERR, "cim_msg2disk: msgstr NULL.");
307
fprintf(fobj, "%s", msgstr);
313
cim_disk2msg(const char *objpathname)
315
char pathname[MAXLEN], *buf;
320
struct ha_msg *msg = NULL;
322
if((buf = pathname_encode(objpathname))== NULL ) {
325
snprintf(pathname, MAXLEN, "%s/%s", HA_CIM_VARDIR, buf);
328
if ( ( ret = stat(pathname, &st)) < 0 ) {
329
cl_log(LOG_WARNING, "disk2msg: stat faild for %s.", pathname);
330
cl_log(LOG_WARNING,"reason:%d(%s)",errno,strerror(errno));
334
if (st.st_size == 0 ) {
335
cl_log(LOG_WARNING, "disk2msg: size of %s is zero.", objpathname);
339
if ((buf = cim_malloc(st.st_size)) == NULL ) {
340
cl_log(LOG_ERR, "disk2msg: alloc msg failed for %s.", objpathname);
344
if ( (fobj = fopen(pathname, "r")) == NULL ) {
345
cl_log(LOG_WARNING, "msg2disk: can't open file %s.", pathname);
346
cl_log(LOG_WARNING, "reason:%d(%s)", errno, strerror(errno));
350
while ( (ret = fread(buf, st.st_size, 1, fobj))){
351
bytes += ret*st.st_size;
355
cl_log(LOG_ERR, "msg2disk: read error for %s.", objpathname);
356
cl_log(LOG_ERR, "reason: %d(%s).", errno, strerror(errno));
361
if ( bytes != st.st_size ) {
362
cl_log(LOG_ERR, "msg2disk: incompete read:");
363
cl_log(LOG_ERR, "read: %d vs size: %d.", bytes, (int)st.st_size);
367
msg = string2msg(buf, bytes);
375
cim_disk_msg_del(const char *objpathname)
377
char fullpathname[MAXLEN];
378
char * pathname = pathname_encode(objpathname);
379
snprintf(fullpathname, MAXLEN, "%s/%s", HA_CIM_VARDIR, pathname);
380
cim_debug2(LOG_INFO, "%s: unlink %s", __FUNCTION__, fullpathname);
381
unlink(fullpathname);
388
cim_dbget(const char *pathname, const char*key)
390
struct ha_msg *db = cim_disk2msg(pathname);
397
value = cl_get_string(db, key);
398
if ( value == NULL || strncmp(value, "null", MAXLEN) == 0) {
401
return cim_strdup(value);
405
cim_dbput(const char *pathname, const char*key, const char*value)
408
struct ha_msg* db = cim_disk2msg(pathname);
410
if ( (db = ha_msg_new(1)) == NULL ) {
411
cl_log(LOG_ERR, "cim_dbput: alloc db failed.");
416
if ((cl_msg_modstring(db, key, value?value:"null")) != HA_OK ) {
418
cl_log(LOG_ERR, "cim_dbput: put value failed.");
422
ret = cim_msg2disk(pathname, db);
428
cim_dbdel(const char *pathname, const char*key)
431
struct ha_msg* db = cim_disk2msg(pathname);
433
cl_log(LOG_ERR, "cim_dbdel: get db failed.");
437
if ((cl_msg_remove(db, key)) != HA_OK ) {
439
cl_log(LOG_ERR, "cim_dbdel: remove failed.");
443
ret = cim_msg2disk(pathname, db);
449
cim_dbkeys(const char *pathname)
451
struct ha_msg * db = cim_disk2msg(pathname);
452
struct ha_msg * list;
456
cl_log(LOG_ERR, "cim_dbkeys: get db failed.");
460
if ( (list = ha_msg_new(1)) == NULL ) {
462
cl_log(LOG_ERR, "cim_dbkeys: alloc list failed.");
466
for (i = 0; i < db->nfields; i++) {
467
cim_list_add(list, db->names[i]);
475
pathname_encode(const char *pathname)
477
char *new_pathname = NULL;
479
if ((new_pathname = cim_malloc(strlen(pathname)+1)) == NULL ) {
480
cl_log(LOG_ERR, "pathname_enocde: alloc pathname failed.");
484
while( (ch = *(pathname++)) ) {
485
if (ch == '\\' || ch == '/') {
496
/****************************************************
498
****************************************************/
500
cim_msg_children_count(struct ha_msg *parent)
503
for (i = 0; i < parent->nfields; i++) {
504
if ( parent->types[i] == FT_STRUCT ) {
513
cim_msg_child_name(struct ha_msg *parent, int index)
516
for (i = 0; i < parent->nfields; i++) {
517
if ( parent->types[i] == FT_STRUCT ) {
518
if ( index == current) {
519
return parent->names[i];
529
cim_msg_child_index(struct ha_msg *parent, int index)
532
for (i = 0; i < parent->nfields; i++) {
533
if ( parent->types[i] == FT_STRUCT ) {
534
if ( index == current) {
535
return parent->values[i];
545
cim_list_find(struct ha_msg *list, const char *value)
547
int len = cim_list_length(list);
549
for (i = 0; i<len; i++) {
550
char * v = cim_list_index(list, i);
551
if ( v && (strncmp(v, value, MAXLEN) == 0)) {