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@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 +
sanlock-devel@lists.fedorahosted.org