From 3dece5987680e6604ca8fde020fe28fd37bbcf49 Mon Sep 17 00:00:00 2001
From: Danny Auble <da@llnl.gov>
Date: Mon, 19 May 2008 19:18:19 +0000
Subject: [PATCH] fix for handling qoutes around ints and such in a load file
 for sacctmgr

---
 src/sacctmgr/common.c   | 46 ++++++++++++++++++++++++---
 src/sacctmgr/sacctmgr.c | 70 ++++++++++++++++++++++++++++-------------
 src/sacctmgr/sacctmgr.h |  1 +
 3 files changed, 91 insertions(+), 26 deletions(-)

diff --git a/src/sacctmgr/common.c b/src/sacctmgr/common.c
index ea94663cc63..95c6ff654dc 100644
--- a/src/sacctmgr/common.c
+++ b/src/sacctmgr/common.c
@@ -90,6 +90,38 @@ extern int parse_option_end(char *option)
 	return end;
 }
 
+/* you need to xfree whatever is sent from here */
+extern char *strip_quotes(char *option, int *increased)
+{
+	int end = 0;
+	int i=0, start=0;
+	char *meat = NULL;
+
+	if(!option)
+		return NULL;
+
+	/* first strip off the ("|')'s */
+	if (option[i] == '\"' || option[i] == '\'')
+		i++;
+	start = i;
+
+	while(option[i]) {
+		if(option[i] == '\"' || option[i] == '\'') {
+			end++;
+			break;
+		}
+		i++;
+	}
+	end += i;
+
+	meat = xmalloc((i-start)+1);
+	memcpy(meat, option+start, (i-start));
+
+	(*increased) += end;
+
+	return meat;
+}
+
 extern void addto_char_list(List char_list, char *names)
 {
 	int i=0, start=0;
@@ -547,15 +579,21 @@ extern acct_cluster_rec_t *sacctmgr_find_cluster_from_list(
 
 extern int get_uint(char *in_value, uint32_t *out_value, char *type)
 {
-	char *ptr = NULL;
+	char *ptr = NULL, *meat = NULL;
 	long num;
+	int i=0;
+
+	if(!(meat = strip_quotes(in_value, &i)))
+		return SLURM_ERROR;
 
-	num = strtol(in_value, &ptr, 10);
+	num = strtol(meat, &ptr, 10);
 	if ((num == 0) && ptr && ptr[0]) {
-		error("Invalid value for %s", type);
+		error("Invalid value for %s (%s)", type, meat);
+		xfree(meat);
 		return SLURM_ERROR;
 	}
-
+	xfree(meat);
+	
 	if (num < 0)
 		*out_value = INFINITE;		/* flag to clear */
 	else
diff --git a/src/sacctmgr/sacctmgr.c b/src/sacctmgr/sacctmgr.c
index 8f8a5799836..9c6056ffc70 100644
--- a/src/sacctmgr/sacctmgr.c
+++ b/src/sacctmgr/sacctmgr.c
@@ -671,9 +671,11 @@ static void _destroy_sacctmgr_file_opts(void *object)
 
 static sacctmgr_file_opts_t *_parse_options(char *options)
 {
-	int start=0, i=0, end=0, mins;
-	char *sub = NULL;
+	int start=0, i=0, end=0, mins, quote = 0;
+ 	char *sub = NULL;
 	sacctmgr_file_opts_t *file_opts = xmalloc(sizeof(sacctmgr_file_opts_t));
+	char *option = NULL;
+
 	file_opts->fairshare = NO_VAL;
 	file_opts->max_cpu_secs_per_job = NO_VAL;
 	file_opts->max_jobs = NO_VAL;
@@ -681,13 +683,31 @@ static sacctmgr_file_opts_t *_parse_options(char *options)
 	file_opts->max_wall_duration_per_job = NO_VAL;
 
 	while(options[i]) {
+		quote = 0;
 		start=i;
-
-		while(options[i] != ':' && options[i] != '\n' && options[i])
+		
+		while(options[i] && options[i] != ':' && options[i] != '\n') {
+			if(options[i] == '"') {
+				if(quote)
+					quote = 0;
+				else
+					quote = 1;
+			}
 			i++;
-
+		}
+		if(quote) {
+			while(options[i] && options[i] != '"') 
+				i++;
+			if(!options[i])
+				fatal("There is a problem with option "
+				      "%s with quotes.", option);
+			i++;
+		}
 		sub = xstrndup(options+start, i-start);
 		end = parse_option_end(sub);
+		
+		option = strip_quotes(sub+end, &quote);
+		
 		if(!end) {
 			if(file_opts->name) {
 				printf(" Bad format on %s: "
@@ -696,75 +716,81 @@ static sacctmgr_file_opts_t *_parse_options(char *options)
 				_destroy_sacctmgr_file_opts(file_opts);
 				break;
 			}
-			file_opts->name = xstrdup(sub+end);
+			file_opts->name = xstrdup(option);
 		} else if (strncasecmp (sub, "AdminLevel", 2) == 0) {
-			file_opts->admin = str_2_acct_admin_level(sub+end);
+			file_opts->admin = str_2_acct_admin_level(option);
 		} else if (strncasecmp (sub, "DefaultAccount", 3) == 0) {
-			file_opts->def_acct = xstrdup(sub+end);
+			file_opts->def_acct = xstrdup(option);
 		} else if (strncasecmp (sub, "Description", 3) == 0) {
-			file_opts->desc = xstrdup(sub+end);
+			file_opts->desc = xstrdup(option);
 		} else if (strncasecmp (sub, "FairShare", 1) == 0) {
-			if (get_uint(sub+end, &file_opts->fairshare, 
+			if (get_uint(option, &file_opts->fairshare, 
 			    "FairShare") != SLURM_SUCCESS) {
-				printf(" Bad FairShare value: %s\n", sub+end);
+				printf(" Bad FairShare value: %s\n", option);
 				_destroy_sacctmgr_file_opts(file_opts);
 				break;
 			}
 		} else if (strncasecmp (sub, "MaxCPUSec", 4) == 0) {
-			if (get_uint(sub+end, &file_opts->max_cpu_secs_per_job,
+			if (get_uint(option, &file_opts->max_cpu_secs_per_job,
 			    "MaxCPUSec") != SLURM_SUCCESS) {
-				printf(" Bad MaxCPUSec value: %s\n", sub+end);
+				printf(" Bad MaxCPUSec value: %s\n", option);
 				_destroy_sacctmgr_file_opts(file_opts);
 				break;
 			}
 		} else if (strncasecmp (sub, "MaxJobs", 4) == 0) {
-			if (get_uint(sub+end, &file_opts->max_jobs,
+			if (get_uint(option, &file_opts->max_jobs,
 			    "MaxJobs") != SLURM_SUCCESS) {
-				printf(" Bad MaxJobs value: %s\n", sub+end);
+				printf(" Bad MaxJobs value: %s\n", option);
 				_destroy_sacctmgr_file_opts(file_opts);
 				break;
 			}
 		} else if (strncasecmp (sub, "MaxNodes", 4) == 0) {
-			if (get_uint(sub+end, &file_opts->max_nodes_per_job,
+			if (get_uint(option, &file_opts->max_nodes_per_job,
 			    "MaxNodes") != SLURM_SUCCESS) {
-				printf(" Bad MaxNodes value: %s\n", sub+end);
+				printf(" Bad MaxNodes value: %s\n", option);
 				_destroy_sacctmgr_file_opts(file_opts);
 				break;
 			}
 		} else if (strncasecmp (sub, "MaxWall", 4) == 0) {
-			mins = time_str2mins(sub+end);
+			mins = time_str2mins(option);
 			if (mins >= 0) {
 				file_opts->max_wall_duration_per_job 
 					= (uint32_t) mins;
-			} else if (strcmp(sub+end, "-1") == 0) {
+			} else if (strcmp(option, "-1") == 0) {
 				file_opts->max_wall_duration_per_job = -1;
 			} else {
 				printf(" Bad MaxWall time format: %s\n", 
-					sub+end);
+					option);
 				_destroy_sacctmgr_file_opts(file_opts);
 				break;
 			}
 		} else if (strncasecmp (sub, "Organization", 1) == 0) {
-			file_opts->org = xstrdup(sub+end);
+			file_opts->org = xstrdup(option);
 		} else if (strncasecmp (sub, "QosLevel", 1) == 0) {
-			file_opts->qos = str_2_acct_qos(sub+end);
+			file_opts->qos = str_2_acct_qos(option);
 		} else {
 			printf(" Unknown option: %s\n", sub);
 		}
 
 		xfree(sub);
+		xfree(option);
 
 		if(options[i] == ':')
 			i++;
 		else
 			break;
 	}
+	
+	xfree(sub);
+	xfree(option);
+
 	if(!file_opts->name) {
 		printf(" error: No name given\n");
 		_destroy_sacctmgr_file_opts(file_opts);
 	}
 	return file_opts;
 }
+
 static void _load_file (int argc, char *argv[])
 {
 	DEF_TIMERS;
diff --git a/src/sacctmgr/sacctmgr.h b/src/sacctmgr/sacctmgr.h
index bb7eedf85a2..00b665f568c 100644
--- a/src/sacctmgr/sacctmgr.h
+++ b/src/sacctmgr/sacctmgr.h
@@ -145,6 +145,7 @@ extern int sacctmgr_delete_cluster(int argc, char *argv[]);
 
 /* common.c */
 extern int parse_option_end(char *option);
+extern char *strip_quotes(char *option, int *increased);
 extern void addto_char_list(List char_list, char *names);
 extern void destroy_sacctmgr_action(void *object);
 extern int notice_thread_init();
-- 
GitLab