src/client_resource.c | 57 +++++++++++++++++++---
tests/res_string.c | 80 --------------------------------
tests/sanlk_string.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 173 insertions(+), 89 deletions(-)
New commits:
commit f672df006a80335c0bcc29983273613c7c732801
Author: David Teigland <teigland(a)redhat.com>
Date: Wed Jul 27 12:04:54 2011 -0500
sanlock: handle colon escaping in path strings
diff --git a/src/client_resource.c b/src/client_resource.c
index ef334b9..fd3228a 100644
--- a/src/client_resource.c
+++ b/src/client_resource.c
@@ -31,6 +31,32 @@
#include "client_msg.h"
#include "sanlock_resource.h"
+/* src has colons unescaped, dst should have them escaped with backslash */
+
+static void copy_path_out(char *dst, char *src)
+{
+ int i, j = 0;
+
+ for (i = 0; i < strlen(src); i++) {
+ if (src[i] == ':')
+ dst[j++] = '\\';
+ dst[j++] = src[i];
+ }
+}
+
+/* src has colons escaped with backslash, dst should have backslash removed */
+
+static void copy_path_in(char *dst, char *src)
+{
+ int i, j = 0;
+
+ for (i = 0; i < strlen(src); i++) {
+ if (src[i] == '\\')
+ continue;
+ dst[j++] = src[i];
+ }
+}
+
int sanlock_register(void)
{
int sock, rv;
@@ -305,6 +331,7 @@ int sanlock_release(int sock, int pid, uint32_t flags, int res_count,
int sanlock_res_to_str(struct sanlk_resource *res, char **str_ret)
{
+ char path[SANLK_PATH_LEN + 1];
char *str;
int ret, len, pos, d;
@@ -324,8 +351,10 @@ int sanlock_res_to_str(struct sanlk_resource *res, char **str_ret)
pos += ret;
for (d = 0; d < res->num_disks; d++) {
- ret = snprintf(str + pos, len - pos, ":%s:%llu",
- res->disks[d].path,
+ memset(path, 0, sizeof(path));
+ copy_path_out(path, res->disks[d].path);
+
+ ret = snprintf(str + pos, len - pos, ":%s:%llu", path,
(unsigned long long)res->disks[d].offset);
if (ret >= len - pos)
@@ -585,13 +614,23 @@ int sanlock_str_to_lockspace(char *str, struct sanlk_lockspace *ls)
char *host_id = NULL;
char *path = NULL;
char *offset = NULL;
+ int i;
- if (str)
- host_id = strstr(str, ":");
- if (host_id)
- path = strstr(host_id+1, ":");
- if (host_id && path)
- offset = strstr(path+1, ":");
+ for (i = 0; i < strlen(str); i++) {
+ if (str[i] == '\\') {
+ i++;
+ continue;
+ }
+
+ if (str[i] == ':') {
+ if (!host_id)
+ host_id = &str[i];
+ else if (!path)
+ path = &str[i];
+ else if (!offset)
+ offset = &str[i];
+ }
+ }
if (host_id) {
*host_id = '\0';
@@ -611,7 +650,7 @@ int sanlock_str_to_lockspace(char *str, struct sanlk_lockspace *ls)
if (host_id)
ls->host_id = atoll(host_id);
if (path)
- strncpy(ls->host_id_disk.path, path, SANLK_PATH_LEN-1);
+ copy_path_in(ls->host_id_disk.path, path);
if (offset)
ls->host_id_disk.offset = atoll(offset);
diff --git a/tests/res_string.c b/tests/res_string.c
deleted file mode 100644
index d1508c8..0000000
--- a/tests/res_string.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <inttypes.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <string.h>
-
-#include "sanlock.h"
-#include "sanlock_resource.h"
-
-void print_res(struct sanlk_resource *res)
-{
- int i;
-
- printf("\"%s:%s", res->lockspace_name, res->name);
-
- for (i = 0; i < res->num_disks; i++) {
- printf(":%s:%llu", res->disks[i].path,
- (unsigned long long)res->disks[i].offset);
- }
- printf(":%llu\"\n", (unsigned long long)res->lver);
-}
-
-int main(int argc, char *argv[])
-{
- struct sanlk_resource *res;
- struct sanlk_resource **res_args = NULL;
- char *state;
- int res_count;
- int rv, i;
-
- state = malloc(1024 * 1024);
- memset(state, 0, 1024 * 1024);
-
- printf("\n");
- printf("sanlock_str_to_res\n", rv);
- printf("--------------------------------------------------------------------------------\n");
-
- for (i = 1; i < argc; i++) {
- rv = sanlock_str_to_res(argv[i], &res);
-
- print_res(res);
-
- free(res);
- res = NULL;
-
- if (i > 1)
- strcat(state, " ");
- strcat(state, argv[i]);
- }
-
- printf("\n");
- printf("combined state\n");
- printf("--------------------------------------------------------------------------------\n");
- printf("\"%s\"\n", state);
-
- rv = sanlock_state_to_args(state, &res_count, &res_args);
-
- printf("\n");
- printf("sanlock_state_to_args %d res_count %d\n", rv, res_count);
- printf("--------------------------------------------------------------------------------\n");
- for (i = 0; i < res_count; i++) {
- res = res_args[i];
- print_res(res);
- }
-
- free(state);
- state = NULL;
-
- rv = sanlock_args_to_state(res_count, res_args, &state);
-
- printf("\n");
- printf("sanlock_args_to_state %d\n", rv);
- printf("--------------------------------------------------------------------------------\n");
- printf("\"%s\"\n", state);
-
- return 0;
-}
-
diff --git a/tests/sanlk_string.c b/tests/sanlk_string.c
new file mode 100644
index 0000000..88d050d
--- /dev/null
+++ b/tests/sanlk_string.c
@@ -0,0 +1,125 @@
+#include <inttypes.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "sanlock.h"
+#include "sanlock_resource.h"
+
+void print_res(struct sanlk_resource *res)
+{
+ int i;
+
+ printf("struct fields: \"%s\" \"%s\"", res->lockspace_name, res->name);
+
+ for (i = 0; i < res->num_disks; i++) {
+ printf(" \"%s\" %llu", res->disks[i].path,
+ (unsigned long long)res->disks[i].offset);
+ }
+ printf(" %llu\n", (unsigned long long)res->lver);
+}
+
+int main(int argc, char *argv[])
+{
+ struct sanlk_lockspace ls;
+ struct sanlk_resource *res;
+ struct sanlk_resource **res_args = NULL;
+ char *state;
+ int res_count;
+ int rv, i;
+
+ if (argc < 2) {
+ printf("%s RESOURCE RESOURCE ...\n", argv[0]);
+ printf("%s -s LOCKSPACE\n", argv[0]);
+ return 0;
+ }
+
+ if (!strcmp(argv[1], "-s")) {
+ memset(&ls, 0, sizeof(ls));
+
+ rv = sanlock_str_to_lockspace(argv[2], &ls);
+
+ printf("struct fields: \"%s\" %llu %u \"%s\" %llu\n",
+ ls.name,
+ (unsigned long long)ls.host_id,
+ ls.flags,
+ ls.host_id_disk.path,
+ (unsigned long long)ls.host_id_disk.offset);
+ return rv;
+ }
+
+ state = malloc(1024 * 1024);
+ memset(state, 0, 1024 * 1024);
+
+ printf("\n");
+ printf("sanlock_str_to_res for each argv\n", rv);
+ printf("--------------------------------------------------------------------------------\n");
+
+ for (i = 1; i < argc; i++) {
+ rv = sanlock_str_to_res(argv[i], &res);
+
+ print_res(res);
+
+ free(res);
+ res = NULL;
+
+ if (i > 1)
+ strcat(state, " ");
+ strcat(state, argv[i]);
+ }
+
+ printf("\n");
+ printf("combined argv input for state_to_args\n");
+ printf("--------------------------------------------------------------------------------\n");
+ printf("\"%s\"\n", state);
+
+ rv = sanlock_state_to_args(state, &res_count, &res_args);
+
+ printf("\n");
+ printf("sanlock_state_to_args %d res_count %d\n", rv, res_count);
+ printf("--------------------------------------------------------------------------------\n");
+ for (i = 0; i < res_count; i++) {
+ res = res_args[i];
+ print_res(res);
+ }
+
+ free(state);
+ state = NULL;
+
+ rv = sanlock_args_to_state(res_count, res_args, &state);
+
+ printf("\n");
+ printf("sanlock_args_to_state %d\n", rv);
+ printf("--------------------------------------------------------------------------------\n");
+ printf("\"%s\"\n", state);
+
+ return 0;
+}
+
+#if 0
+
+[root@bull-02 tests]# ./res_string 'LA:R1:/dev/foo1\:xx:0:/dev/foo2\:yy:0' 'LB:R2:/dev/bar:11'
+
+sanlock_str_to_res for each argv
+--------------------------------------------------------------------------------
+struct fields: "LA" "R1" "/dev/foo1:xx" 0 "/dev/foo2:yy" 0 0
+struct fields: "LB" "R2" "/dev/bar" 11 0
+
+combined argv input for state_to_args
+--------------------------------------------------------------------------------
+"LA:R1:/dev/foo1\:xx:0:/dev/foo2\:yy:0 LB:R2:/dev/bar:11"
+
+sanlock_state_to_args 0 res_count 2
+--------------------------------------------------------------------------------
+struct fields: "LA" "R1" "/dev/foo1:xx" 0 "/dev/foo2:yy" 0 0
+struct fields: "LB" "R2" "/dev/bar" 11 0
+
+sanlock_args_to_state 0
+--------------------------------------------------------------------------------
+"LA:R1:/dev/foo1\:xx:0:/dev/foo2\:yy:0:0 LB:R2:/dev/bar:11:0"
+
+#endif
+