[Cluster-devel] conga/ricci common/ClientSocket.cpp common/Mak ...

rmccabe at sourceware.org rmccabe at sourceware.org
Thu Aug 9 21:29:45 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	conga
Branch: 	RHEL4
Changes by:	rmccabe at sourceware.org	2007-08-09 21:29:43

Modified files:
	ricci/common   : ClientSocket.cpp Makefile Module.cpp 
	                 executils.cpp 
	ricci/init.d   : ricci 
	ricci/modules/cluster: ClusterModule.cpp Makefile Virt.cpp 
	                       Virt.h 
	ricci/modules/storage: VG.cpp parted_wrapper.cpp 
	ricci/ricci    : SSLInstance.cpp 
Added files:
	ricci/common   : base64.c base64.h 
	ricci/test_suite/cluster: delete_xvm_key.xml 
	                          generate_xvm_key.xml get_xvm_key.xml 
	                          set_xvm_key.xml 

Log message:
	Merge in fixes from the RHEL5 branch, pass 2

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/base64.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.1.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/base64.h.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.1.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/ClientSocket.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.4.4.1&r2=1.4.4.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/Makefile.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.7.2.1&r2=1.7.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/Module.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.5&r2=1.5.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/executils.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.7.4.1&r2=1.7.4.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/init.d/ricci.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.10&r2=1.10.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/ClusterModule.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.6.2.1&r2=1.6.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/Makefile.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.15&r2=1.15.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/Virt.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1&r2=1.1.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/Virt.h.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1&r2=1.1.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/VG.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.9.2.3&r2=1.9.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/parted_wrapper.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.8.4.2&r2=1.8.4.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/ricci/SSLInstance.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.7&r2=1.7.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/test_suite/cluster/delete_xvm_key.xml.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.1.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/test_suite/cluster/generate_xvm_key.xml.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.2.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/test_suite/cluster/get_xvm_key.xml.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.1.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/test_suite/cluster/set_xvm_key.xml.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.1.4.1

/cvs/cluster/conga/ricci/common/base64.c,v  -->  standard output
revision 1.1.4.1
--- conga/ricci/common/base64.c
+++ -	2007-08-09 21:29:43.564631000 +0000
@@ -0,0 +1,421 @@
+/* base64.c -- Encode binary data using printable characters.
+   Copyright (C) 1999, 2000, 2001, 2004, 2005, 2006 Free Software
+   Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* Written by Simon Josefsson.  Partially adapted from GNU MailUtils
+ * (mailbox/filter_trans.c, as of 2004-11-28).  Improved by review
+ * from Paul Eggert, Bruno Haible, and Stepan Kasal.
+ *
+ * See also RFC 3548 <http://www.ietf.org/rfc/rfc3548.txt>.
+ *
+ * Be careful with error checking.  Here is how you would typically
+ * use these functions:
+ *
+ * bool ok = base64_decode_alloc (in, inlen, &out, &outlen);
+ * if (!ok)
+ *   FAIL: input was not valid base64
+ * if (out == NULL)
+ *   FAIL: memory allocation error
+ * OK: data in OUT/OUTLEN
+ *
+ * size_t outlen = base64_encode_alloc (in, inlen, &out);
+ * if (out == NULL && outlen == 0 && inlen != 0)
+ *   FAIL: input too long
+ * if (out == NULL)
+ *   FAIL: memory allocation error
+ * OK: data in OUT/OUTLEN.
+ *
+ */
+
+/* Get prototype. */
+#include "base64.h"
+
+/* Get malloc. */
+#include <stdlib.h>
+
+/* Get UCHAR_MAX. */
+#include <limits.h>
+
+/* C89 compliant way to cast 'char' to 'unsigned char'. */
+static inline unsigned char
+to_uchar (char ch)
+{
+  return ch;
+}
+
+/* Base64 encode IN array of size INLEN into OUT array of size OUTLEN.
+   If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as
+   possible.  If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero
+   terminate the output buffer. */
+void
+base64_encode (const char *in, size_t inlen,
+	       char *out, size_t outlen)
+{
+  static const char b64str[64] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+  while (inlen && outlen)
+    {
+      *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f];
+      if (!--outlen)
+	break;
+      *out++ = b64str[((to_uchar (in[0]) << 4)
+		       + (--inlen ? to_uchar (in[1]) >> 4 : 0))
+		      & 0x3f];
+      if (!--outlen)
+	break;
+      *out++ =
+	(inlen
+	 ? b64str[((to_uchar (in[1]) << 2)
+		   + (--inlen ? to_uchar (in[2]) >> 6 : 0))
+		  & 0x3f]
+	 : '=');
+      if (!--outlen)
+	break;
+      *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '=';
+      if (!--outlen)
+	break;
+      if (inlen)
+	inlen--;
+      if (inlen)
+	in += 3;
+    }
+
+  if (outlen)
+    *out = '\0';
+}
+
+/* Allocate a buffer and store zero terminated base64 encoded data
+   from array IN of size INLEN, returning BASE64_LENGTH(INLEN), i.e.,
+   the length of the encoded data, excluding the terminating zero.  On
+   return, the OUT variable will hold a pointer to newly allocated
+   memory that must be deallocated by the caller.  If output string
+   length would overflow, 0 is returned and OUT is set to NULL.  If
+   memory allocation failed, OUT is set to NULL, and the return value
+   indicates length of the requested memory block, i.e.,
+   BASE64_LENGTH(inlen) + 1. */
+size_t
+base64_encode_alloc (const char *in, size_t inlen, char **out)
+{
+  size_t outlen = 1 + BASE64_LENGTH (inlen);
+
+  /* Check for overflow in outlen computation.
+   *
+   * If there is no overflow, outlen >= inlen.
+   *
+   * If the operation (inlen + 2) overflows then it yields at most +1, so
+   * outlen is 0.
+   *
+   * If the multiplication overflows, we lose at least half of the
+   * correct value, so the result is < ((inlen + 2) / 3) * 2, which is
+   * less than (inlen + 2) * 0.66667, which is less than inlen as soon as
+   * (inlen > 4).
+   */
+  if (inlen > outlen)
+    {
+      *out = NULL;
+      return 0;
+    }
+
+  *out = malloc (outlen);
+  if (!*out)
+    return outlen;
+
+  base64_encode (in, inlen, *out, outlen);
+
+  return outlen - 1;
+}
+
+/* With this approach this file works independent of the charset used
+   (think EBCDIC).  However, it does assume that the characters in the
+   Base64 alphabet (A-Za-z0-9+/) are encoded in 0..255.  POSIX
+   1003.1-2001 require that char and unsigned char are 8-bit
+   quantities, though, taking care of that problem.  But this may be a
+   potential problem on non-POSIX C99 platforms.
+
+   IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_"
+   as the formal parameter rather than "x".  */
+#define B64(_)					\
+  ((_) == 'A' ? 0				\
+   : (_) == 'B' ? 1				\
+   : (_) == 'C' ? 2				\
+   : (_) == 'D' ? 3				\
+   : (_) == 'E' ? 4				\
+   : (_) == 'F' ? 5				\
+   : (_) == 'G' ? 6				\
+   : (_) == 'H' ? 7				\
+   : (_) == 'I' ? 8				\
+   : (_) == 'J' ? 9				\
+   : (_) == 'K' ? 10				\
+   : (_) == 'L' ? 11				\
+   : (_) == 'M' ? 12				\
+   : (_) == 'N' ? 13				\
+   : (_) == 'O' ? 14				\
+   : (_) == 'P' ? 15				\
+   : (_) == 'Q' ? 16				\
+   : (_) == 'R' ? 17				\
+   : (_) == 'S' ? 18				\
+   : (_) == 'T' ? 19				\
+   : (_) == 'U' ? 20				\
+   : (_) == 'V' ? 21				\
+   : (_) == 'W' ? 22				\
+   : (_) == 'X' ? 23				\
+   : (_) == 'Y' ? 24				\
+   : (_) == 'Z' ? 25				\
+   : (_) == 'a' ? 26				\
+   : (_) == 'b' ? 27				\
+   : (_) == 'c' ? 28				\
+   : (_) == 'd' ? 29				\
+   : (_) == 'e' ? 30				\
+   : (_) == 'f' ? 31				\
+   : (_) == 'g' ? 32				\
+   : (_) == 'h' ? 33				\
+   : (_) == 'i' ? 34				\
+   : (_) == 'j' ? 35				\
+   : (_) == 'k' ? 36				\
+   : (_) == 'l' ? 37				\
+   : (_) == 'm' ? 38				\
+   : (_) == 'n' ? 39				\
+   : (_) == 'o' ? 40				\
+   : (_) == 'p' ? 41				\
+   : (_) == 'q' ? 42				\
+   : (_) == 'r' ? 43				\
+   : (_) == 's' ? 44				\
+   : (_) == 't' ? 45				\
+   : (_) == 'u' ? 46				\
+   : (_) == 'v' ? 47				\
+   : (_) == 'w' ? 48				\
+   : (_) == 'x' ? 49				\
+   : (_) == 'y' ? 50				\
+   : (_) == 'z' ? 51				\
+   : (_) == '0' ? 52				\
+   : (_) == '1' ? 53				\
+   : (_) == '2' ? 54				\
+   : (_) == '3' ? 55				\
+   : (_) == '4' ? 56				\
+   : (_) == '5' ? 57				\
+   : (_) == '6' ? 58				\
+   : (_) == '7' ? 59				\
+   : (_) == '8' ? 60				\
+   : (_) == '9' ? 61				\
+   : (_) == '+' ? 62				\
+   : (_) == '/' ? 63				\
+   : -1)
+
+static const signed char b64[0x100] = {
+  B64 (0), B64 (1), B64 (2), B64 (3),
+  B64 (4), B64 (5), B64 (6), B64 (7),
+  B64 (8), B64 (9), B64 (10), B64 (11),
+  B64 (12), B64 (13), B64 (14), B64 (15),
+  B64 (16), B64 (17), B64 (18), B64 (19),
+  B64 (20), B64 (21), B64 (22), B64 (23),
+  B64 (24), B64 (25), B64 (26), B64 (27),
+  B64 (28), B64 (29), B64 (30), B64 (31),
+  B64 (32), B64 (33), B64 (34), B64 (35),
+  B64 (36), B64 (37), B64 (38), B64 (39),
+  B64 (40), B64 (41), B64 (42), B64 (43),
+  B64 (44), B64 (45), B64 (46), B64 (47),
+  B64 (48), B64 (49), B64 (50), B64 (51),
+  B64 (52), B64 (53), B64 (54), B64 (55),
+  B64 (56), B64 (57), B64 (58), B64 (59),
+  B64 (60), B64 (61), B64 (62), B64 (63),
+  B64 (64), B64 (65), B64 (66), B64 (67),
+  B64 (68), B64 (69), B64 (70), B64 (71),
+  B64 (72), B64 (73), B64 (74), B64 (75),
+  B64 (76), B64 (77), B64 (78), B64 (79),
+  B64 (80), B64 (81), B64 (82), B64 (83),
+  B64 (84), B64 (85), B64 (86), B64 (87),
+  B64 (88), B64 (89), B64 (90), B64 (91),
+  B64 (92), B64 (93), B64 (94), B64 (95),
+  B64 (96), B64 (97), B64 (98), B64 (99),
+  B64 (100), B64 (101), B64 (102), B64 (103),
+  B64 (104), B64 (105), B64 (106), B64 (107),
+  B64 (108), B64 (109), B64 (110), B64 (111),
+  B64 (112), B64 (113), B64 (114), B64 (115),
+  B64 (116), B64 (117), B64 (118), B64 (119),
+  B64 (120), B64 (121), B64 (122), B64 (123),
+  B64 (124), B64 (125), B64 (126), B64 (127),
+  B64 (128), B64 (129), B64 (130), B64 (131),
+  B64 (132), B64 (133), B64 (134), B64 (135),
+  B64 (136), B64 (137), B64 (138), B64 (139),
+  B64 (140), B64 (141), B64 (142), B64 (143),
+  B64 (144), B64 (145), B64 (146), B64 (147),
+  B64 (148), B64 (149), B64 (150), B64 (151),
+  B64 (152), B64 (153), B64 (154), B64 (155),
+  B64 (156), B64 (157), B64 (158), B64 (159),
+  B64 (160), B64 (161), B64 (162), B64 (163),
+  B64 (164), B64 (165), B64 (166), B64 (167),
+  B64 (168), B64 (169), B64 (170), B64 (171),
+  B64 (172), B64 (173), B64 (174), B64 (175),
+  B64 (176), B64 (177), B64 (178), B64 (179),
+  B64 (180), B64 (181), B64 (182), B64 (183),
+  B64 (184), B64 (185), B64 (186), B64 (187),
+  B64 (188), B64 (189), B64 (190), B64 (191),
+  B64 (192), B64 (193), B64 (194), B64 (195),
+  B64 (196), B64 (197), B64 (198), B64 (199),
+  B64 (200), B64 (201), B64 (202), B64 (203),
+  B64 (204), B64 (205), B64 (206), B64 (207),
+  B64 (208), B64 (209), B64 (210), B64 (211),
+  B64 (212), B64 (213), B64 (214), B64 (215),
+  B64 (216), B64 (217), B64 (218), B64 (219),
+  B64 (220), B64 (221), B64 (222), B64 (223),
+  B64 (224), B64 (225), B64 (226), B64 (227),
+  B64 (228), B64 (229), B64 (230), B64 (231),
+  B64 (232), B64 (233), B64 (234), B64 (235),
+  B64 (236), B64 (237), B64 (238), B64 (239),
+  B64 (240), B64 (241), B64 (242), B64 (243),
+  B64 (244), B64 (245), B64 (246), B64 (247),
+  B64 (248), B64 (249), B64 (250), B64 (251),
+  B64 (252), B64 (253), B64 (254), B64 (255)
+};
+
+#if UCHAR_MAX == 255
+# define uchar_in_range(c) true
+#else
+# define uchar_in_range(c) ((c) <= 255)
+#endif
+
+/* Return true if CH is a character from the Base64 alphabet, and
+   false otherwise.  Note that '=' is padding and not considered to be
+   part of the alphabet.  */
+bool
+isbase64 (char ch)
+{
+  return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)];
+}
+
+/* Decode base64 encoded input array IN of length INLEN to output
+   array OUT that can hold *OUTLEN bytes.  Return true if decoding was
+   successful, i.e. if the input was valid base64 data, false
+   otherwise.  If *OUTLEN is too small, as many bytes as possible will
+   be written to OUT.  On return, *OUTLEN holds the length of decoded
+   bytes in OUT.  Note that as soon as any non-alphabet characters are
+   encountered, decoding is stopped and false is returned.  This means
+   that, when applicable, you must remove any line terminators that is
+   part of the data stream before calling this function.  */
+bool
+base64_decode (const char *in, size_t inlen, char *out, size_t *outlen) {
+  size_t outleft = *outlen;
+
+  while (inlen >= 2)
+    {
+      if (!isbase64 (in[0]) || !isbase64 (in[1]))
+	break;
+
+      if (outleft)
+	{
+	  *out++ = ((b64[to_uchar (in[0])] << 2)
+		    | (b64[to_uchar (in[1])] >> 4));
+	  outleft--;
+	}
+
+      if (inlen == 2)
+	break;
+
+      if (in[2] == '=')
+	{
+	  if (inlen != 4)
+	    break;
+
+	  if (in[3] != '=')
+	    break;
+
+	}
+      else
+	{
+	  if (!isbase64 (in[2]))
+	    break;
+
+	  if (outleft)
+	    {
+	      *out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0)
+			| (b64[to_uchar (in[2])] >> 2));
+	      outleft--;
+	    }
+
+	  if (inlen == 3)
+	    break;
+
+	  if (in[3] == '=')
+	    {
+	      if (inlen != 4)
+		break;
+	    }
+	  else
+	    {
+	      if (!isbase64 (in[3]))
+		break;
+
+	      if (outleft)
+		{
+		  *out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0)
+			    | b64[to_uchar (in[3])]);
+		  outleft--;
+		}
+	    }
+	}
+
+      in += 4;
+      inlen -= 4;
+    }
+
+  *outlen -= outleft;
+
+  if (inlen != 0)
+    return false;
+
+  return true;
+}
+
+/* Allocate an output buffer in *OUT, and decode the base64 encoded
+   data stored in IN of size INLEN to the *OUT buffer.  On return, the
+   size of the decoded data is stored in *OUTLEN.  OUTLEN may be NULL,
+   if the caller is not interested in the decoded length.  *OUT may be
+   NULL to indicate an out of memory error, in which case *OUTLEN
+   contains the size of the memory block needed.  The function returns
+   true on successful decoding and memory allocation errors.  (Use the
+   *OUT and *OUTLEN parameters to differentiate between successful
+   decoding and memory error.)  The function returns false if the
+   input was invalid, in which case *OUT is NULL and *OUTLEN is
+   undefined. */
+bool
+base64_decode_alloc (const char *in, size_t inlen, char **out,
+		     size_t *outlen)
+{
+  /* This may allocate a few bytes too much, depending on input,
+     but it's not worth the extra CPU time to compute the exact amount.
+     The exact amount is 3 * inlen / 4, minus 1 if the input ends
+     with "=" and minus another 1 if the input ends with "==".
+     Dividing before multiplying avoids the possibility of overflow.  */
+  size_t needlen = 3 * (inlen / 4) + 2;
+
+  *out = malloc (needlen);
+  if (!*out)
+    return true;
+
+  if (!base64_decode (in, inlen, *out, &needlen))
+    {
+      free (*out);
+      *out = NULL;
+      return false;
+    }
+
+  if (outlen)
+    *outlen = needlen;
+
+  return true;
+}
/cvs/cluster/conga/ricci/common/base64.h,v  -->  standard output
revision 1.1.4.1
--- conga/ricci/common/base64.h
+++ -	2007-08-09 21:29:43.652464000 +0000
@@ -0,0 +1,45 @@
+/* base64.h -- Encode binary data using printable characters.
+   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+   Written by Simon Josefsson.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef BASE64_H
+# define BASE64_H
+
+/* Get size_t. */
+# include <stddef.h>
+
+/* Get bool. */
+# include <stdbool.h>
+
+/* This uses that the expression (n+(k-1))/k means the smallest
+   integer >= n/k, i.e., the ceiling of n/k.  */
+# define BASE64_LENGTH(inlen) ((((inlen) + 2) / 3) * 4)
+
+extern bool isbase64 (char ch);
+
+extern void base64_encode (const char *in, size_t inlen,
+			   char *out, size_t outlen);
+
+extern size_t base64_encode_alloc (const char *in, size_t inlen, char **out);
+
+extern bool base64_decode (const char *in, size_t inlen,
+			   char *out, size_t *outlen);
+
+extern bool base64_decode_alloc (const char *in, size_t inlen,
+				 char **out, size_t *outlen);
+
+#endif /* BASE64_H */
--- conga/ricci/common/ClientSocket.cpp	2007/03/27 02:06:26	1.4.4.1
+++ conga/ricci/common/ClientSocket.cpp	2007/08/09 21:29:42	1.4.4.2
@@ -27,6 +27,7 @@
 
 #include <unistd.h>
 #include <errno.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -159,14 +160,14 @@
     throw String("ClientSocket::recv(): socket already closed");
   
   while (true) {
-    char buffer[1024];
+    char buffer[4096];
     int ret = ::recv(_sock, buffer, sizeof(buffer), 0);
     if (ret == -1) {
       if (errno == EINTR)
 	continue;
       else if (errno == EAGAIN)
 	return "";
-      throw String("ClientSocket::recv(): recv error");
+      throw String("ClientSocket::recv(): recv error: ") + String(strerror(errno));
     }
     
     if (ret == 0) {
@@ -204,10 +205,9 @@
     if (ret == -1) {
       if (errno == EINTR)
 	continue;
-      else if (errno == EAGAIN ||
-	       errno == EWOULDBLOCK)
+      else if (errno == EAGAIN || errno == EWOULDBLOCK)
 	return msg;
-      throw String("ClientSocket::send(): socket error");
+      throw String("ClientSocket::send(): socket error: ") + String(strerror(errno));
     }
     
     //    log(String("sent ") + ret + " bytes thru socket " + _sock, 
--- conga/ricci/common/Makefile	2007/03/27 02:06:26	1.7.2.1
+++ conga/ricci/common/Makefile	2007/08/09 21:29:42	1.7.2.2
@@ -32,6 +32,7 @@
 	Variable.o \
 	Random.o \
 	daemon_init.o \
+	base64.o \
 	Module.o
 
 
--- conga/ricci/common/Module.cpp	2006/08/15 04:15:52	1.5
+++ conga/ricci/common/Module.cpp	2007/08/09 21:29:42	1.5.4.1
@@ -1,5 +1,5 @@
 /*
-  Copyright Red Hat, Inc. 2006
+  Copyright Red Hat, Inc. 2006-2007
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
@@ -253,56 +253,74 @@
 int
 __stdin_out_module_driver(Module& module)
 {
-  unsigned int time_beg = time_mil();
-  String data;
+	unsigned int time_beg = time_mil();
+	String data;
   
-  while (time_mil() < time_beg + timeout) {
-    poll_fd poll_data;
-    poll_data.fd = 0;
-    poll_data.events = POLLIN;
-    poll_data.revents = 0;
+	while (time_mil() < time_beg + timeout) {
+		poll_fd poll_data;
+		poll_data.fd = 0;
+		poll_data.events = POLLIN;
+		poll_data.revents = 0;
     
-    // wait for events
-    int ret = poll(&poll_data, 1, 500);
-    if (ret == 0) {
-      // continue waiting
-      continue;
-    } else if (ret == -1) {
-      if (errno == EINTR)
-        continue;
-      else
-        throw String("poll() error");
-    }
-    
-    // process event
-    if (poll_data.revents & POLLIN) {
-      char buff[1024];
-      int ret = read(poll_data.fd, buff, sizeof(buff));
-      if (ret == -1) {
-	if (errno == EINTR)
-	  continue;
-	throw String("error reading stdin");
-      }
-      try {
-	data.append(buff, ret);
-	shred(buff, sizeof(buff));
-	XMLObject request = parseXML(data);
-	XMLObject response = module.process(request);
-	cout << generateXML(response) << endl;
-	return 0;
-      } catch ( ... ) {
-	shred(buff, sizeof(buff));
-      }
-      continue;
-    }
-    if (poll_data.revents & (POLLERR | POLLHUP | POLLNVAL))
-      throw String("stdin error???");
+		// wait for events
+		int ret = poll(&poll_data, 1, 500);
+
+		if (ret == 0) {
+			/*
+			** We may be done if the total input length is a multiple of
+			** the buffer size.
+			*/
+			if (data.length() > 0) {
+				try {
+					XMLObject request = parseXML(data);
+					XMLObject response = module.process(request);
+					cout << generateXML(response) << endl;
+					return 0;
+				} catch ( ... ) { }
+			}
+			// continue waiting
+			continue;
+		} else if (ret == -1) {
+			if (errno == EINTR)
+				continue;
+			else
+				throw String("poll() error: ") + String(strerror(errno));
+		}
     
-  } // while
+		// process event
+		if (poll_data.revents & POLLIN) {
+			char buff[4096];
+			int ret;
+
+			ret = read(poll_data.fd, buff, sizeof(buff));
+			if (ret == -1) {
+				if (errno == EINTR)
+					continue;
+				throw String("error reading stdin: ") + String(strerror(errno));
+			}
+
+			if (ret > 0) {
+				data.append(buff, ret);
+				shred(buff, sizeof(buff));
+			}
+
+			if ((size_t) ret < sizeof(buff)) {
+				try {
+					XMLObject request = parseXML(data);
+					XMLObject response = module.process(request);
+					cout << generateXML(response) << endl;
+					return 0;
+				} catch ( ... ) { }
+			}
+			continue;
+		}
+
+		if (poll_data.revents & (POLLERR | POLLHUP | POLLNVAL))
+			throw String("stdin error: ") + String(strerror(errno));
+	} // while
   
   //  cout << data << endl;
-  
-  throw String("invalid input");
+	throw String("invalid input");
 }
 
 
--- conga/ricci/common/executils.cpp	2007/03/05 20:07:33	1.7.4.1
+++ conga/ricci/common/executils.cpp	2007/08/09 21:29:42	1.7.4.2
@@ -218,7 +218,7 @@
   
   if (poll_info.revents & POLLIN) {
     try {
-      char data_in[1024];
+      char data_in[4096];
       int ret = read(fd, data_in, sizeof(data_in));
       if (ret < 0)
 	return;
--- conga/ricci/init.d/ricci	2007/01/18 03:02:38	1.10
+++ conga/ricci/init.d/ricci	2007/08/09 21:29:42	1.10.2.1
@@ -1,10 +1,9 @@
 #!/bin/sh
 #
-# Copyright (C) 2005 Red Hat, Inc.
+# Copyright (C) 2005-2007 Red Hat, Inc.
 #
 # This program is Free Software.  You may modify and/or redistribute it under
-# the terms of the GNU General Public License version 2, or (at your option)
-# any later version.
+# the terms of the GNU General Public License version 2.
 #
 # description:  Starts and stops Red Hat Cluster and Storage Remote \
 #               Configuration Interface (ricci)
@@ -32,127 +31,125 @@
 #
 # Only root wants to run this...
 #
-[ `id -u` = 0 ] || exit 0
+[ `id -u` = 0 ] || exit 4
 
 #
 # If we're not configured, then don't start anything.
 #
-[ "${NETWORKING}" = "yes" ] || exit 0
-
-
-
+[ "${NETWORKING}" = "yes" ] || exit 1
 
 ssl_certs_ok()
 {
-    if [ ! -e $SSL_PRIVKEY ] ; then
-	return 1
-    fi
-    if [ ! -e $SSL_PUBKEY ] ; then
-	return 2
-    fi
-    return 0
+	if [ ! -f "$SSL_PRIVKEY" ] ; then
+		return 1
+	fi
+	if [ ! -f "$SSL_PUBKEY" ] ; then
+		return 2
+	fi
+	return 0
 }
 
 generate_ssl_certs()
 {
-    rm -f $SSL_PUBKEY $SSL_PRIVKEY
-    echo -n "generating SSL certificates...  "
-    /usr/bin/openssl genrsa -out $SSL_PRIVKEY 2048 > /dev/null 2>&1
-    /usr/bin/openssl req -new -x509 -key $SSL_PRIVKEY -out $SSL_PUBKEY -days 1825 -config /var/lib/ricci/certs/cacert.config
-    /bin/chown $RUNASUSER:$RUNASUSER $SSL_PRIVKEY $SSL_PUBKEY
-    /bin/chmod 644 $SSL_PUBKEY
-    /bin/chmod 600 $SSL_PRIVKEY
-    echo "done"
-    return $?
+	rm -f "$SSL_PUBKEY" "$SSL_PRIVKEY"
+	echo -n "generating SSL certificates...  "
+	/usr/bin/openssl genrsa -out "$SSL_PRIVKEY" 2048 >&/dev/null
+	/usr/bin/openssl req -new -x509 -key "$SSL_PRIVKEY" -out "$SSL_PUBKEY" -days 1825 -config /var/lib/ricci/certs/cacert.config
+	/bin/chown $RUNASUSER:$RUNASUSER "$SSL_PRIVKEY" "$SSL_PUBKEY"
+	/bin/chmod 644 "$SSL_PUBKEY"
+	/bin/chmod 600 "$SSL_PRIVKEY"
+	ret=$?
+	echo "done"
+	return $ret
 }
 
 
 case $1 in
 	start)
-	        service messagebus status > /dev/null 2>&1
+		service messagebus status >&/dev/null
 		if [ $? -ne 0 ]; then
-		    service messagebus start
-		    service messagebus status > /dev/null 2>&1
-		    if [ $? -ne 0 ]; then
-			echo "not starting ricci..."
-			/usr/bin/logger -t $RICCID "startup failed"
-			exit 1
-		    fi
+			service messagebus start
+			service messagebus status >&/dev/null
+			if [ $? -ne 0 ]; then
+				echo "not starting ricci..."
+				/usr/bin/logger -t $RICCID "startup failed"
+				exit 1
+			fi
 		fi
-	        service oddjobd status > /dev/null 2>&1
+		service oddjobd status >&/dev/null
 		if [ $? -ne 0 ]; then
-		    service oddjobd start
-		    service oddjobd status > /dev/null 2>&1
-		    if [ $? -ne 0 ]; then
-			echo "not starting ricci..."
-			/usr/bin/logger -t $RICCID "startup failed"
-			exit 1
-		    fi
+			service oddjobd start
+			service oddjobd status >&/dev/null
+			if [ $? -ne 0 ]; then
+				echo "not starting ricci..."
+				/usr/bin/logger -t $RICCID "startup failed"
+				exit 1
+			fi
 		fi
 		
-		service saslauthd start > /dev/null 2>&1
-		
+		service saslauthd start >&/dev/null
 		ssl_certs_ok
 		if [ "1$?" != "10" ] ; then
-		    generate_ssl_certs
+			generate_ssl_certs
 		fi
 		
-		NewUID=`cat /etc/passwd | grep "^$RUNASUSER:" | sed -e 's/^[^:]*:[^:]*://' -e 's/:.*//'`
+		NewUID=`grep "^$RUNASUSER:" /etc/passwd | sed -e 's/^[^:]*:[^:]*://' -e 's/:.*//'`
 		echo -n $"Starting $ID: "
 		daemon $RICCID -u $NewUID
 		rtrn=$?
 		echo 
+
 		if [ $rtrn -eq 0 ]; then
-		    touch $LOCKFILE
-		    /usr/bin/logger -t $RICCID "startup succeeded"
+			touch "$LOCKFILE"
+			/usr/bin/logger -t $RICCID "startup succeeded"
 		else
-		    /usr/bin/logger -t $RICCID "startup failed"
+			/usr/bin/logger -t $RICCID "startup failed"
 		fi
-		;;
+	;;
 
-        restart)
+	restart)
 		$0 stop
 		$0 start 
 		rtrn=$?
-		;;
+	;;
 
 	status)
 		status $RICCID
 		rtrn=$?
-		;;
+	;;
 
 	stop)
 		echo -n "Shutting down $ID: "
 		killproc $RICCID SIGTERM
 		rtrn=$?
 		if [ $rtrn -eq 0 ]; then
-		    sleep 8
-		    rm -f $PIDFILE
-		    rm -f $LOCKFILE
-		    /usr/bin/logger -t $RICCID "shutdown succeeded"
+			sleep 8
+			rm -f $PIDFILE
+			rm -f $LOCKFILE
+			/usr/bin/logger -t $RICCID "shutdown succeeded"
+			rtrn=0
 		else
-		    /usr/bin/logger -t $RICCID "shutdown failed"
+			/usr/bin/logger -t $RICCID "shutdown failed"
+			rtrn=1
 		fi
-		rtrn=0
 		echo 
-		;;
+	;;
 
-        condrestart)
-               if [ -f ${PIDFILE} ] ; then
-		   $0 restart
-		   rtrn=$?
-	       fi
-	       ;;
-
-        reload)
-               rtrn=0
-	       ;;
+	condrestart)
+		if [ -f ${PIDFILE} ] ; then
+			$0 restart
+			rtrn=$?
+		fi
+	;;
+
+	reload)
+		rtrn=3
+	;;
 
 	*)
 		echo "Usage: $0 {start|stop|status|restart|condrestart|reload}"
-		rtrn=1
-		;;
-
+		rtrn=3
+	;;
 esac
 
 exit $rtrn
--- conga/ricci/modules/cluster/ClusterModule.cpp	2007/03/09 22:50:08	1.6.2.1
+++ conga/ricci/modules/cluster/ClusterModule.cpp	2007/08/09 21:29:42	1.6.2.2
@@ -1,5 +1,5 @@
 /*
-  Copyright Red Hat, Inc. 2006
+  Copyright Red Hat, Inc. 2006-2007
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
@@ -13,11 +13,12 @@
 
   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING.  If not, write to the
-  Free Software Foundation, Inc.,  675 Mass Ave, Cambridge, 
+  Free Software Foundation, Inc.,  675 Mass Ave, Cambridge,
   MA 02139, USA.
 */
 /*
  * Author: Stanko Kupcevic <kupcevic at redhat.com>
+ * Author: Ryan McCabe <rmccabe at redhat.com>
  */
 
 
@@ -27,6 +28,7 @@
 #include "Clusvcadm.h"
 #include "Fence.h"
 #include "Virt.h"
+#include "base64.h"
 
 
 using namespace std;
@@ -42,13 +44,18 @@
 static VarMap fence_node(const VarMap& args);
 static VarMap start_node(const VarMap& args);
 static VarMap stop_node(const VarMap& args);
+
 static VarMap virt_guest(const VarMap& args);
+static VarMap delete_xvm_key(const VarMap& args);
+static VarMap set_xvm_key(const VarMap& args);
+static VarMap get_xvm_key(const VarMap& args);
+static VarMap generate_xvm_key(const VarMap& args);
 
 static ApiFcnMap build_fcn_map();
 
 
 ClusterModule::ClusterModule() :
-  Module(build_fcn_map())
+	Module(build_fcn_map())
 {}
 
 ClusterModule::~ClusterModule()
@@ -58,157 +65,161 @@
 ApiFcnMap
 build_fcn_map()
 {
-  FcnMap   api_1_0;
-  api_1_0["get_cluster.conf"]                     = get_cluster_conf;
-  api_1_0["set_cluster.conf"]                     = set_cluster_conf;
-  
-  api_1_0["status"]                               = cluster_status;
-  
-  api_1_0["start_service"]                        = service_start;
-  api_1_0["stop_service"]                         = service_stop;
-  api_1_0["restart_service"]                      = service_restart;
-  api_1_0["migrate_service"]                      = service_migrate;
-  
-  api_1_0["start_node"]                           = start_node;
-  api_1_0["stop_node"]                            = stop_node;
-  api_1_0["fence_node"]                           = fence_node;
-  api_1_0["virt_guest"]                           = virt_guest;
-  
-  
-  ApiFcnMap   api_fcn_map;
-  api_fcn_map["1.0"] = api_1_0;
-  
-  return api_fcn_map;
-}
+	FcnMap	api_1_0;
+
+	api_1_0["get_cluster.conf"]		= get_cluster_conf;
+	api_1_0["set_cluster.conf"]		= set_cluster_conf;
+
+	api_1_0["status"]				= cluster_status;
+
+	api_1_0["start_service"]		= service_start;
+	api_1_0["stop_service"]			= service_stop;
+	api_1_0["restart_service"]		= service_restart;
+	api_1_0["migrate_service"]		= service_migrate;
+
+	api_1_0["start_node"]			= start_node;
+	api_1_0["stop_node"]			= stop_node;
+	api_1_0["fence_node"]			= fence_node;
 
 
-VarMap 
+	api_1_0["delete_xvm_key"]		= delete_xvm_key;
+	api_1_0["set_xvm_key"]			= set_xvm_key;
+	api_1_0["get_xvm_key"]			= get_xvm_key;
+	api_1_0["generate_xvm_key"]		= generate_xvm_key;
+	api_1_0["virt_guest"]			= virt_guest;
+
+
+	ApiFcnMap api_fcn_map;
+	api_fcn_map["1.0"] = api_1_0;
+
+	return api_fcn_map;
+}
+
+VarMap
 cluster_status(const VarMap& args)
 {
-  Variable var("status", Cluster::status());
-  
-  VarMap ret;
-  ret.insert(pair<String, Variable>(var.name(), var));
-  return ret;
+	Variable var("status", Cluster::status());
+
+	VarMap ret;
+	ret.insert(pair<String, Variable>(var.name(), var));
+	return ret;
 }
 
-VarMap 
+VarMap
 get_cluster_conf(const VarMap& args)
 {
-  Variable var("cluster.conf", ClusterConf::get());
-  
-  VarMap ret;
-  ret.insert(pair<String, Variable>(var.name(), var));
-  return ret;
+	Variable var("cluster.conf", ClusterConf::get());
+
+	VarMap ret;
+	ret.insert(pair<String, Variable>(var.name(), var));
+	return ret;
 }
 
-VarMap 
+VarMap
 set_cluster_conf(const VarMap& args)
 {
-  XMLObject conf;
-  bool propagate;
-  try {
-    VarMap::const_iterator iter = args.find("cluster.conf");
-    if (iter == args.end())
-      throw APIerror("missing cluster.conf variable");
-    conf = iter->second.get_XML();
-    
-    propagate = false;
-    iter = args.find("propagate");
-    if (iter != args.end())
-      propagate = iter->second.get_bool();
-  } catch ( String e ) {
-    throw APIerror(e);
-  }
-  
-  ClusterConf::set(conf, propagate);
-  
-  VarMap ret;
-  return ret;
+	XMLObject conf;
+	bool propagate;
+
+	try {
+		VarMap::const_iterator iter = args.find("cluster.conf");
+		if (iter == args.end())
+			throw APIerror("missing cluster.conf variable");
+		conf = iter->second.get_XML();
+
+		propagate = false;
+		iter = args.find("propagate");
+		if (iter != args.end())
+			propagate = iter->second.get_bool();
+	} catch ( String e ) {
+		throw APIerror(e);
+	}
+
+	ClusterConf::set(conf, propagate);
+	VarMap ret;
+	return ret;
 }
 
-VarMap 
+VarMap
 service_stop(const VarMap& args)
 {
-  String name;
-  try {
-    VarMap::const_iterator iter = args.find("servicename");
-    if (iter == args.end())
-      throw APIerror("missing servicename variable");
-    name = iter->second.get_string();
-  } catch ( String e ) {
-    throw APIerror(e);
-  }
-  
-  Clusvcadm::stop(name);
-  
-  VarMap ret;
-  return ret;
+	String name;
+
+	try {
+		VarMap::const_iterator iter = args.find("servicename");
+		if (iter == args.end())
+			throw APIerror("missing servicename variable");
+		name = iter->second.get_string();
+	} catch ( String e ) {
+		throw APIerror(e);
+	}
+
+	Clusvcadm::stop(name);
+	VarMap ret;
+	return ret;
 }
 
-VarMap 
+VarMap
 service_start(const VarMap& args)
 {
-  String service_name, node_name;
-  try {
-    VarMap::const_iterator iter = args.find("servicename");
-    if (iter == args.end())
-      throw APIerror("missing servicename variable");
-    service_name = iter->second.get_string();
-    
-    iter = args.find("nodename");
-    if (iter != args.end())
-      node_name = iter->second.get_string();
-  } catch ( String e ) {
-    throw APIerror(e);
-  }
-  
-  Clusvcadm::start(service_name, node_name);
-  
-  VarMap ret;
-  return ret;
+	String service_name, node_name;
+
+	try {
+		VarMap::const_iterator iter = args.find("servicename");
+		if (iter == args.end())
+			throw APIerror("missing servicename variable");
+		service_name = iter->second.get_string();
+
+		iter = args.find("nodename");
+		if (iter != args.end())
+			node_name = iter->second.get_string();
+	} catch ( String e ) {
+		throw APIerror(e);
+	}
+
+	Clusvcadm::start(service_name, node_name);
+	VarMap ret;
+	return ret;
 }
 
-VarMap 
+VarMap
 service_migrate(const VarMap& args)
 {
-  String service_name, node_name;
-  try {
-    VarMap::const_iterator iter = args.find("servicename");
-    if (iter == args.end())
-      throw APIerror("missing servicename variable");
-    service_name = iter->second.get_string();
-    
-    iter = args.find("nodename");
-    if (iter != args.end())
-      node_name = iter->second.get_string();
-  } catch ( String e ) {
-    throw APIerror(e);
-  }
-  
-  Clusvcadm::migrate(service_name, node_name);
-  
-  VarMap ret;
-  return ret;
+	String service_name, node_name;
+	try {
+		VarMap::const_iterator iter = args.find("servicename");
+		if (iter == args.end())
+			throw APIerror("missing servicename variable");
+		service_name = iter->second.get_string();
+
+		iter = args.find("nodename");
+		if (iter != args.end())
+			node_name = iter->second.get_string();
+	} catch ( String e ) {
+		throw APIerror(e);
+	}
+
+	Clusvcadm::migrate(service_name, node_name);
+	VarMap ret;
+	return ret;
 }
 
-VarMap 
+VarMap
 service_restart(const VarMap& args)
 {
-  String name;
-  try {
-    VarMap::const_iterator iter = args.find("servicename");
-    if (iter == args.end())
-      throw APIerror("missing servicename variable");
-    name = iter->second.get_string();
-  } catch ( String e ) {
-    throw APIerror(e);
-  }
-  
-  Clusvcadm::restart(name);
-  
-  VarMap ret;
-  return ret;
+	String name;
+	try {
+		VarMap::const_iterator iter = args.find("servicename");
+		if (iter == args.end())
+			throw APIerror("missing servicename variable");
+		name = iter->second.get_string();
+	} catch ( String e ) {
+		throw APIerror(e);
+	}
+
+	Clusvcadm::restart(name);
+	VarMap ret;
+	return ret;
 }
 
 VarMap
@@ -221,62 +232,141 @@
 	return ret;
 }
 
-VarMap 
+VarMap
+delete_xvm_key(const VarMap& args) {
+	Virt::delete_xvm_key();
+	VarMap ret;
+	return ret;
+}
+
+VarMap
+set_xvm_key(const VarMap& args) {
+	String key_base64;
+
+	try {
+		VarMap::const_iterator iter = args.find("key_base64");
+
+		if (iter != args.end()) {
+			key_base64 = iter->second.get_string();
+		} else {
+			throw String("missing key_base64 variable");
+		}
+	} catch ( String e ) {
+		throw APIerror(e);
+	}
+
+	Virt::set_xvm_key(key_base64.c_str());
+	VarMap ret;
+	return ret;
+}
+
+VarMap
+get_xvm_key(const VarMap& args) {
+	char *key_base64 = NULL;
+
+	key_base64 = Virt::get_xvm_key();
+	Variable var("key_base64", String(key_base64));
+	memset(key_base64, 0, strlen(key_base64));
+	free(key_base64);
+
+	VarMap ret;
+	ret.insert(pair<String, Variable>(var.name(), var));
+	return ret;
+}
+
+VarMap
+generate_xvm_key(const VarMap& args) {
+	size_t key_bytes = XVM_KEY_DEFAULT_SIZE;
+
+	try {
+		VarMap::const_iterator iter = args.find("size");
+
+		if (iter != args.end()) {
+			int bytes = iter->second.get_int();
+
+			if (bytes < XVM_KEY_MIN_SIZE) {
+				char err[64];
+				snprintf(err, sizeof(err),
+					"The minimum fence_xvm key size is %u bytes",
+					XVM_KEY_MIN_SIZE);
+				throw String(err);
+			}
+
+			if (bytes > XVM_KEY_MAX_SIZE) {
+				char err[64];
+				snprintf(err, sizeof(err),
+					"The maximum fence_xvm key size is %u bytes",
+					XVM_KEY_MAX_SIZE);
+				throw String(err);
+			}
+			key_bytes = (size_t) bytes;
+		}
+	} catch ( String e ) {
+		throw APIerror(e);
+	}
+
+	Virt::generate_xvm_key(key_bytes);
+	VarMap ret;
+	return ret;
+}
+
+VarMap
 fence_node(const VarMap& args)
 {
-  String name;
-  try {
-    VarMap::const_iterator iter = args.find("nodename");
-    if (iter == args.end())
-      throw APIerror("missing nodename variable");
-    name = iter->second.get_string();
-  } catch ( String e ) {
-    throw APIerror(e);
-  }
-  
-  Fence::fence_node(name);
-  
-  VarMap ret;
-  return ret;
+	String name;
+
+	try {
+		VarMap::const_iterator iter = args.find("nodename");
+		if (iter == args.end())
+			throw APIerror("missing nodename variable");
+		name = iter->second.get_string();
+	} catch ( String e ) {
+		throw APIerror(e);
+	}
+
+	Fence::fence_node(name);
+	VarMap ret;
+	return ret;
 }
 
-VarMap 
+VarMap
 start_node(const VarMap& args)
 {
-  bool cluster_startup = false;
-  try {
-    VarMap::const_iterator iter = args.find("cluster_startup");
-    if (iter != args.end())
-      cluster_startup = iter->second.get_bool();
-  } catch ( String e ) {
-    throw APIerror(e);
-  }
-  
-  Cluster::start_node(cluster_startup);
-  
-  VarMap ret;
-  return ret;
+	bool cluster_startup = false;
+
+	try {
+		VarMap::const_iterator iter = args.find("cluster_startup");
+		if (iter != args.end())
+			cluster_startup = iter->second.get_bool();
+		} catch ( String e ) {
+			throw APIerror(e);
+	}
+
+	Cluster::start_node(cluster_startup);
+
+	VarMap ret;
+	return ret;
 }
 
-VarMap 
+VarMap
 stop_node(const VarMap& args)
 {
-  bool cluster_shutdown = false;
-  bool purge_conf = false;
-  try {
-    VarMap::const_iterator iter = args.find("cluster_shutdown");
-    if (iter != args.end())
-      cluster_shutdown = iter->second.get_bool();
-    iter = args.find("purge_conf");
-    if (iter != args.end())
-      purge_conf = iter->second.get_bool();
-  } catch ( String e ) {
-    throw APIerror(e);
-  }
-  
-  Cluster::stop_node(cluster_shutdown,
-		     purge_conf);
-  
-  VarMap ret;
-  return ret;
+	bool cluster_shutdown = false;
+	bool purge_conf = false;
+
+	try {
+		VarMap::const_iterator iter = args.find("cluster_shutdown");
+		if (iter != args.end())
+			cluster_shutdown = iter->second.get_bool();
+
+		iter = args.find("purge_conf");
+		if (iter != args.end())
+			purge_conf = iter->second.get_bool();
+	} catch ( String e ) {
+		throw APIerror(e);
+	}
+
+	Cluster::stop_node(cluster_shutdown, purge_conf);
+	VarMap ret;
+	return ret;
 }
--- conga/ricci/modules/cluster/Makefile	2006/11/20 23:10:58	1.15
+++ conga/ricci/modules/cluster/Makefile	2007/08/09 21:29:42	1.15.2.1
@@ -25,8 +25,8 @@
 	Virt.o
 
 
-INCLUDE    += 
-CXXFLAGS   += 
+INCLUDE    += -I${top_srcdir}/common/
+CXXFLAGS   +=
 LDFLAGS    += 
 
 
--- conga/ricci/modules/cluster/Virt.cpp	2006/11/20 23:10:58	1.1
+++ conga/ricci/modules/cluster/Virt.cpp	2007/08/09 21:29:42	1.1.4.1
@@ -1,5 +1,5 @@
 /*
-  Copyright Red Hat, Inc. 2006
+  Copyright Red Hat, Inc. 2006-2007
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
@@ -17,6 +17,14 @@
   MA 02139, USA.
 */
 
+extern "C" {
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include "base64.h"
+}
+
 #include "Virt.h"
 #include "utils.h"
 
@@ -36,5 +44,128 @@
         if (out.find("Manufacturer: Xen") != out.npos)
             return true;
     } catch ( ... ) {}
+
     return false;
 }
+
+bool Virt::delete_xvm_key(void) {
+	return unlink(XVM_KEY_PATH) == 0;
+}
+
+bool Virt::set_xvm_key(const char *key_base64) {
+	char *buf = NULL;
+	size_t keylen;
+	size_t keylen_dec = 0;
+	ssize_t ret;
+	bool decoded = false;
+	int fd;
+	mode_t old_mask;
+	char tmpname[] = "/etc/cluster/.fence_xvm.keyXXXXXX";
+
+	if (key_base64 == NULL)
+		throw String("no key was given");
+	
+	keylen = strlen(key_base64);
+	if (keylen < 1)
+		throw String("no key was given");
+
+	decoded = base64_decode_alloc(key_base64, keylen, &buf, &keylen_dec);
+	if (!decoded || buf == NULL)
+		throw String("an invalid key was given");
+
+	old_mask = umask(077);
+
+	fd = mkstemp(tmpname);
+	umask(old_mask);
+	if (fd < 0) {
+		memset(buf, 0, keylen_dec);
+		free(buf);
+		throw String("error setting new key");
+	}
+
+	fchmod(fd, 0600);
+	ret = write(fd, buf, keylen_dec);
+	if (ret < 0 || (size_t) ret != keylen_dec) {
+		unlink(tmpname);
+		close(fd);
+		memset(buf, 0, keylen_dec);
+		free(buf);
+		throw String("error setting new key");
+	}
+
+	close(fd);
+	memset(buf, 0, keylen_dec);
+	free(buf);
+
+	if (rename(tmpname, XVM_KEY_PATH) != 0) {
+		unlink(tmpname);
+		throw String("error setting new key");
+	}
+
+	return (true);
+}
+
+bool Virt::generate_xvm_key(size_t keylen) {
+	int fd;
+	size_t ret;
+	char buf[XVM_KEY_MAX_SIZE];
+	struct stat stat;
+
+	if (keylen < XVM_KEY_MIN_SIZE || keylen > XVM_KEY_MAX_SIZE)
+		throw String("invalid key length");
+
+	fd = open("/dev/urandom", O_RDONLY);
+	if (fd < 0)
+		throw String("error generating key");
+
+	ret = read(fd, buf, keylen);
+	close(fd);
+	if ((size_t) ret != keylen)
+		throw String("error generating key");
+		
+
+	fd = open(XVM_KEY_PATH, O_WRONLY | O_EXCL | O_CREAT, 0600);
+	if (fd < 0)
+		throw String("error generating key");
+
+	ret = write(fd, buf, keylen);
+	close(fd);
+	if ((size_t) ret != keylen) {
+		unlink(XVM_KEY_PATH);
+		throw String("error generating key");
+	}
+	return (true);
+}
+
+char *Virt::get_xvm_key(void) {
+	int fd;
+	ssize_t ret;
+	size_t keylen_bin = 0;
+	size_t keylen_base64 = 0;
+	char buf[XVM_KEY_MAX_SIZE];
+	struct stat st;
+	char *key_out = NULL;
+
+	fd = open(XVM_KEY_PATH, O_RDONLY);
+	if (fd < 0)
+		throw String("error retrieving key");
+
+	if (fstat(fd, &st) != 0) {
+		close(fd);
+		throw String("error retrieving key");
+	}
+
+	ret = read(fd, buf, sizeof(buf));
+	close(fd);
+	if (ret < 0 || (off_t) ret != st.st_size) {
+		memset(buf, 0, sizeof(buf));
+		throw String("error retrieving key");
+	}
+	keylen_bin = (size_t) ret;
+
+	keylen_base64 = base64_encode_alloc(buf, keylen_bin, &key_out);
+	memset(buf, 0, sizeof(buf));
+	if (keylen_base64 < 1 || key_out == NULL)
+		throw String("error retrieving key");
+	return (key_out);
+}
--- conga/ricci/modules/cluster/Virt.h	2006/11/20 23:10:58	1.1
+++ conga/ricci/modules/cluster/Virt.h	2007/08/09 21:29:42	1.1.4.1
@@ -22,11 +22,20 @@
 
 #include "String.h"
 
-#define DMIDECODE_PATH	"/usr/sbin/dmidecode"
+#define XVM_KEY_PATH			"/etc/cluster/fence_xvm.key"
+#define XVM_KEY_MAX_SIZE		4096
+#define XVM_KEY_MIN_SIZE		128
+#define XVM_KEY_DEFAULT_SIZE	4096
+
+#define DMIDECODE_PATH			"/usr/sbin/dmidecode"
 
 class Virt {
  public:
 	static bool virt_guest(void);
+	static bool delete_xvm_key(void);
+	static bool set_xvm_key(const char *key_base64);
+	static char *get_xvm_key(void);
+	static bool generate_xvm_key(size_t key_bytes);
 };
 
 #endif
--- conga/ricci/modules/storage/VG.cpp	2007/03/30 14:42:12	1.9.2.3
+++ conga/ricci/modules/storage/VG.cpp	2007/08/09 21:29:42	1.9.2.4
@@ -354,10 +354,15 @@
   props.set(Variable("extent_size", 
 		     4 * 1024 * 1024 /* 4 MB */,
 		     ext_sizes));
-  
+
   // clustered
-  props.set(Variable("clustered", false, true));
-  
+  bool use_clustered = false;
+  try {
+    LVM::check_locking();
+    use_clustered = true;
+  } catch ( ... ) { }
+  props.set(Variable("clustered", use_clustered, true));
+
   // new sources
   VG unused(VG_PREFIX);
   for (list<counting_auto_ptr<BD> >::iterator iter = unused.sources.begin();
--- conga/ricci/modules/storage/parted_wrapper.cpp	2007/03/20 15:48:29	1.8.4.2
+++ conga/ricci/modules/storage/parted_wrapper.cpp	2007/08/09 21:29:42	1.8.4.3
@@ -678,7 +678,7 @@
     else if (s[s.size()-2] == 'g')
       multiplier = 1000 * 1000 * 1000;
     else if (s[s.size()-2] == 't')
-      multiplier = 1000 * 1000 * 1000 * 1000;
+      multiplier = (long long) 1000 * 1000 * 1000 * 1000;
   }
   
   return (long long) utils::to_float(s) * multiplier;
--- conga/ricci/ricci/SSLInstance.cpp	2006/12/06 22:34:08	1.7
+++ conga/ricci/ricci/SSLInstance.cpp	2007/08/09 21:29:43	1.7.2.1
@@ -1,5 +1,5 @@
 /*
-  Copyright Red Hat, Inc. 2005
+  Copyright Red Hat, Inc. 2005-2007
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
@@ -279,7 +279,7 @@
   if (!_accepted)
     throw String("cannot receive, yet: SSL connection not accepted");
   
-  char buff[1024];
+  char buff[4096];
   
   unsigned int beg = time_mil();
   while (time_mil() < beg + timeout) {
/cvs/cluster/conga/ricci/test_suite/cluster/delete_xvm_key.xml,v  -->  standard output
revision 1.1.4.1
--- conga/ricci/test_suite/cluster/delete_xvm_key.xml
+++ -	2007-08-09 21:29:45.080895000 +0000
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<ricci version="1.0" function="process_batch" async="false">
+<batch>
+
+<module name="cluster">
+<request sequence="1254" API_version="1.0">
+<function_call name="delete_xvm_key" />
+</request>
+</module>
+
+</batch>
+</ricci>
+
/cvs/cluster/conga/ricci/test_suite/cluster/generate_xvm_key.xml,v  -->  standard output
revision 1.2.4.1
--- conga/ricci/test_suite/cluster/generate_xvm_key.xml
+++ -	2007-08-09 21:29:45.183050000 +0000
@@ -0,0 +1,15 @@
+<?xml version="1.0" ?>
+<ricci version="1.0" function="process_batch" async="false">
+<batch>
+
+<module name="cluster">
+<request sequence="1254" API_version="1.0">
+<function_call name="generate_xvm_key">
+	<var mutable="false" name="size" type="int" value="4096" />
+</function_call>
+</request>
+</module>
+
+</batch>
+</ricci>
+
/cvs/cluster/conga/ricci/test_suite/cluster/get_xvm_key.xml,v  -->  standard output
revision 1.1.4.1
--- conga/ricci/test_suite/cluster/get_xvm_key.xml
+++ -	2007-08-09 21:29:45.352982000 +0000
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<ricci version="1.0" function="process_batch" async="false">
+<batch>
+
+<module name="cluster">
+<request sequence="1254" API_version="1.0">
+<function_call name="get_xvm_key" />
+</request>
+</module>
+
+</batch>
+</ricci>
+
/cvs/cluster/conga/ricci/test_suite/cluster/set_xvm_key.xml,v  -->  standard output
revision 1.1.4.1
--- conga/ricci/test_suite/cluster/set_xvm_key.xml
+++ -	2007-08-09 21:29:45.482916000 +0000
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<ricci version="1.0" function="process_batch" async="false">
+<batch>
+
+<module name="cluster">
+<request sequence="1254" API_version="1.0">
+<function_call name="set_xvm_key">
+	<var mutable="false" name="key_base64" type="string" value="33+Yc2b3UfmAGuvknYE2oW3r26fI/jLZYrVnmEQcnG9ANTlKBd2kFrjstZiDzWENBoOAHGCIX4p5SanuysqHZBrEmgh06FY9ZFz5Ss1unGVNzq39EQDkCIKd+rMOF8ncQTDK3RmGmNImic9Ur13w4AXgSodJJp4m3ycxh3cZDT34G1Q2ZI804FLjSSIE3UNpbtmrxLfIm5jZqquVjtQc/xRWr7MyFgu9t0a40gSVHcojYUml7PTtDkcxE6ka274qQoGLwt77Z/kR2RghuPFAoBa3quyA9V8hFtxlG8sSzTS39R82j5Y2/SNKyMJyRsSeSjNPCXlAEuTPItoCYdZghvR1F9lqXHc51nEhd+MaTCFQ5kdJZ6x1CDniCHteiA7f6a4FLMnT6R+HM7b8/MBUqd9x7iwt9aIwgppoWfTvIV+pJ8N4QrpVliUqt8ZxQ02z7D1QlIKYBGrhnsglMHv6BlZMe4ogX4YkXtV8kjSHBxYHSXvOb+LSHYT8qpQDlmAfONsj+UWsN75Af9HDTUuUcjDl05dEjxrEa/E5OAmpBixjuWrsxVjQfi/qZvETX68k1XC93YEDBwMMEej/uxfomf1BzSxlBSWX/3iXWjvxiOWXoENYLM9IYR/XmZUvq5L45bJ4KLjj178EBRyOWXHdhbD5QJLPyxRg+ePHksFsgsTp3jSqru2i1K+EFLpNGObinTNqzCtGyb0vKjuFlD2/C/IQyOGMg7mIEizJSaJvlRFtLVEJRsPN1Pi9sKXpMgaV4lzkzzGgrooz4zRXJ3cDqEKx2uqRikEakPS0jIgL41NAGlOKNQdFee4RKrB5tefVVuRdfRf8WD0XJ3Fub7YAeKosPMMP6g6aeU32HV2l7SBpxbKoeBUcNyHJ5hGn94U8LLYMJ5j0cY73o0c3AvU/vfFukzU8cLq!
 Xo8ZQ/hrmc51Evk3e5QDhaiv0huR3JbcrmAVEOnrcgXXYUiezE/mDTD+IR44xrCSqO6mWOTYMh0ZGb2roZS4rRy5kykzmbVT/D4TqFHGgpn8aIyP8qVRDhH/UOZZOCdc6um+ipi+otzVQcK9yOYD4pk0rRnJ0DBzDuebLWEvcoHuBiZFzanaEGK7R7FXy3iR9eE7O/6UVbZSsr6DhmdseAKGKQ2HQ0KJ38X1zf+6vOcV/PUvYimNKmpta2qn9pkNyWTdBRVOrS3VLRNRGtHl2uE/oW9QMpL/mY5+YsPyBR8iEcD1Ra3vknGQ0hDK+6KxPeJx1f/QGaVj7oxQze5RWoVKRuhgeWcKaomxoJ+36O5rgakNduOCIUcrGKxWHb1C3YNsDxIzYLLGHhxLVbciXGzxY5EL12GsELFnK+cdv++qkX1HsiKayBt88O0YlYK1DxFK7wMvuK7stOtfzWFI67j/LGoxBYAkXuMcaRiSzDJm5ADEUrug7L9zCp9A+LYPylPu7t2qdEG57bauEosPy48g+3+/fln//JflUOQemnRbAXLfIQxWJwG4JMYDBegJcVtOvoY+kemTP0rPlDwNgijqBwaU/JW0APCZfOUzmLSbt0jV7m46IwUMkvv9Tf2npi8rKABAY7GwuZUKU1IaDYtsEx4njgodHgRQmLvrAaNLA/7L51jI35PxJ2fsj95Iia7jUmOEIe45IpOfEBxPAHGeBUryt9hohfddBocazucGz3b+14grJ68TXJsAGcTeAe66rw/W+cXksG1W5Ih8gQ+v3xUEBoXTTgqD+336C5Lf0APqBMCCF6om0n3NBIVJ4XvqTHjx6Wbj99bTooDcDKsIJVGY3sf1FZdwdsAs85s1CY3k/j6L732jwKdtV+kdqc5VTAkOG4nqST2UFI5Qtc2umjwxDrDe8GJvQLxtMXPGZcxVW3jgsLOAasYdf6VBN79HMd0FrjfG7t2lQ+BjwEmsOS/E!
 gvWV2MjPsyX85901P0M8WSdB7nR5ETvYhQhizFLVjc4ZDY/GBEyCwg20ywEMGU!
 7Fr0r8wg
NUWWi/+gBMsXw6DS6c4Dnwj1U6rExffMOJoXum8Gcdi2N3B1vGAH99KGOFtei3E2DJNpd+EgyuJiuO8fz7EWqbokoJba9U2XMEF+9w7YrtZUOF3tmEMlabNDff/GdBFiEPC4bD7GfBE+1jhuYito7fOMXR4e16q1WDspXhD6MGmqe0xSHXqRLtAO9EErZ9RDm0ass7Uwc3gNtgKtx3Oms4kV/+P/6WTslMmQttKpVAmU1Nhw/5cuaHwuRNNDZvNuSdj4tsykkIGsrfSdiWuE/0Ts+PI17rrgxtHBZWTF10Xg/xaAvytspNHbJylSfwN4a4aBf7U7G3DYg95onD4A4KitWA18VCcP4u8M4TDj/Tyz7Tr37/DAfyLek0+NPKFLgcSuMicBovvHrziuZ+QHCquCTAWxvLC965WKpo7jQzqNZVI195b+CocV+YgV2jKeEoaTdMDjeIVGmxElBYVCKU3+y6BVQpARJ+OSqudqPNuukXR8oBCaZQlsCVkugJ+AqPObsDLTda2mjcCREopIzXhYEYGEUwU8AIMzYlw1F15ZzHzgDOG2b3tXW7TairT2KJA0ZtigVAvHGxBh7H7Z3w0s9sInNvH/bZvjWsvB7fXu9qVZxYh9QYFew7zliyvNXUH3NIJseu3njaKluHhYzPokr2RzTHKdNVeeYcFwIWEJFGnk0AYTxb7mW2ATyWJ7CQHUwAWW0n4DyUdkiOU/081x2wPn/+SuH+YvKc1bzdszoSO2zBaAZjbz7GeZJMYAZfAmigYrjSmtMAClk8BgQy0Ecmt9y/vkoPXNq7iiu7O3dNNX2zd1QXbWkYIYhbvl+Z9zWysuVqZ/sVAavUMjm8cnpWh2Rl13siarO57TL/QysyyGYzKEJw55n+Xhjral6c7NhSi4WbuTaMwpw5pSIw38YA/3XTKLI3FXvV5ZQvNKONsKW4WwHgBDkx0QiGWayLtBU8VLEsYWHWU5jIUc3JJA7QgcV!
 Swii22vlXCcmfqUJuBtV2AkVTOjUluvk9VOqR8Av3hS/iGBHHoEb8oiJUAjL2P1AqdKrmomZpfYtrVRmHOB0dbNUIq0I6sXY0v0kYzKMfu930NrJEjW1kyPJKnbTfifLlOMUYX+6HBqeSa5ml/04qYwajsG/HfgOqtlIBwOU/OilrK4wqjEIZrDR3eO6wIi2Dmeoqc5euFIfkSu2WR2AO+gxhx80lE4Kny97nykVkgK3I79hpfa7A1h0MGp6ZHKOMesGDJMtDRkCCw7ByHI/+or7ysCHfVmTVJ2nX0dpOUoK6eG+YtidtsI/8i++YLXHyZIl8y+LJHwIpLQOzbVAWoLDihrCR0INL3Z/1NCsp1UlbQwe6Ko+7YHzYGHvaVal1CKeTUmNRaX4ydwL1G57PnlYCNF9+YzLuuAKQavRd/o/LVxojlwj2LaUycfGVcXidLZmNfLulKRX7cyly0bxCuf6RNRnRdLGxnPCRu5SJJrhO9AJXKfTzWaPfIn1vUJaNfEQnhA4D1PwKRTpLlPoF/RgIlzzLY47y1o0pEQ/iRH+9W+EObka5l9Re/1K3ZKmrIJaBftpw8ynvq9sjsnR6mr4GgWGPaVkk32ywNB8MFAS0ZgDgoP2l3cKGZyKH7DifPQsO27EjulMmZHwsBdk4yrPv0Ngmz5Mg35UzkIDEqE7m/l5u27CJ5Jo5jdvio57p0DTI1Rkbr/UpsjlnWwrsq7k/bhRWbES9qXxrsI5rD3wsd1EXH4eoxyDNb4X0IkR8oD4UdGQ6JK/IZfY9hK7D0OpGatK150ftvnqabIkExve4+qdZXVIRIVYikSfbb0+2cAj4sOqr2A/TuSLwlDFLIHj1INFB4gM7qCnPQYJ4SwH86HFiBtM7tRNzT6HUNWm/qhe4tqQRYtJSH1w0kOyMXLP5yNLX57AvVzdcvURvY41DV2BgDwM8NKzSO4qNFwGs5sfyvj6uRQW21xGT7C3EHlE1QQK!
 f9sRdRnRmaVHyMOLnRK0aaPsDWhwerO6Wsz2Vm3UJ4Vvgaf9ysA08UvSzcU7mO!
 wbPTRciB
MNrx6q5+XIN7xTOYKPsPHkMRrDlyEPojIgnAUNISAhfSPNZuPwhAC5+OiKQV674GntSTOQ1X+VRRX5DtOEd8I/Z4FzPr+vLl8pgoEEJQlNi7UAeaz0Cn5YH8NlCvk62AjVJ/og9dk1SNr0tXMgQjkETxkTsGFamOx8YdENKqTXXVcE6yZurvnyMdTKDmYnLsPeQgeq2Ngfik/vshyLvssewA3sBm9a8iEYwErXWbu/9ccFXDA7KNS76IJfLSYqPKb68M78/ip6v4z8195MyXrx6Nzpalw3KUeXA/YNcx/jMouX8J2F1nN4V0pvHi1Lwi5bl1kCvbQKQNQtpQyZ0MGjTkxzKHxzzIMtd6a3BR+N8UvSUCxq66mLVPsXRgXuB2oyKE/Q5QnQhrotHCEAwF7Gd5yRQBne+7GzTBGc/JGLhni8iIaMg2lw8blQ4sTqWwNB2eJfyOZ1da4AI+YFubcj86O3XEihRwcsn8UZWu9hdsZuS/S6Al+Ocee1JqeHEM1uc07IAoVL6TW0X2Z6VrobCEB1Gkm9iS419EXLzG9vbjidpz5ORB8yRXDFuouv4hXFSGj4WGj9uew52bcyr+WbtlmBBL1/79E78twZsrVSZ9v/drLqq1Cxr/GIu386pdCfgl0AdZeqwXYuU+3dA5iYQDi1CLRZB9D8pMQovAJE4o/HG54lrmHQ1OckVQ6D9Bqr4Pb0yvCcVozXvDgvPcZnSZT3O1L2pIu0FVWbN5izTR3Yk0zWdGCiyGDjnbH7rs9A5PRsahpaoqjemLHePL12rsJnhcmFBx9sEeXkJQHEWBVot+GphFrMLmJ3LurVJgGi1nIIJ8yBqSno+wU5/kPcgneUZfei3QBuXClVVDS4K4CLs15LWjKgP7DFN88Ojdx3HXHjJyfm8tSyToQEEonw0O2O3Vr1fJHg5cEn8p7yCFY36AqjhqtsFPyZESnUsjW2sIcRhlOcvGP0LDqWko81qW7VUjA!
 AI4Yi2eDWqCsN4OnrJ8UtkYBC07oNiUNhrwV96KPXj8hM1pn7Err56wnGym0dQ1sEUXDSKZV9vMrMNv+TKCtmN1JN0wQplx0fHDl7sUmCQsWgilELEAtVmPH8U/7xe2CHTKaAwveCbu7ebWTqLE2tTd1mmgG+9V60ptZa3SZ9EU3dpMy83cF3QUhfWZiHUh8c/jpSxnw39o8FrDcXuHjjlLJGni/dDHeMH/TVa+SLx6t/uGwZpdXSmvE4ApXMtxabHNTZO8DGbwbfjeD9kL8LA9R9Td9QfMDbYPSpUXqX7Q0HHQAdyPZIftsZ/ZphDrLyveCHsTwPWo/sGKIfQgv35mAgocuobVZqHUJngNpxNppmVbwnbw/We4pla+UZFQvM7gpBkJRAtHFwu+Wlf8/Nk87ZtgPwiNgq1gaLQLORnsRJ5okyS5v223sw=="/>
+</function_call>
+</request>
+</module>
+
+</batch>
+</ricci>




More information about the Cluster-devel mailing list