PERFORCE change 123088 for review

Andrew Turner andrew at FreeBSD.org
Sun Jul 8 06:03:23 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=123088

Change 123088 by andrew at andrew_hermies on 2007/07/08 06:03:12

	When processing a call allow any children to set the response when they find bad data.
	Handle incorrect attributes in the call processing code
	Don't use a fixed size string when the element is unknown

Affected files ...

.. //depot/projects/soc2007/andrew-update/lib/facund_private.h#6 edit
.. //depot/projects/soc2007/andrew-update/lib/facund_server.c#10 edit

Differences ...

==== //depot/projects/soc2007/andrew-update/lib/facund_private.h#6 (text+ko) ====

@@ -68,6 +68,7 @@
 	char		 current_call[32];
 	char		 call_id[8];
 	struct facund_object *call_arg;
+	struct facund_response *resp;
 };
 
 #endif /* FACUND_PRIVATE_H */

==== //depot/projects/soc2007/andrew-update/lib/facund_server.c#10 (text+ko) ====

@@ -42,7 +42,7 @@
 
 #define BUF_SIZE	128
 
-static void facund_server_call(struct facund_conn *, const char *,const char *,
+static struct facund_response *facund_server_call(const char *, const char *,
     struct facund_object *);
 static void facund_server_start_tag(void *, const XML_Char *, const XML_Char**);
 static void facund_server_end_tag(void *, const XML_Char *);
@@ -124,11 +124,9 @@
 /*
  * Calls the correct function for the given call
  */
-static void
-facund_server_call(struct facund_conn *conn, const char *name, const char *id,
-    struct facund_object *arg)
+static struct facund_response *
+facund_server_call(const char *name, const char *id, struct facund_object *arg)
 {
-	const char *msg;
 	struct facund_response *resp;
 	facund_call_cb *cb;
 	DBT key, data;
@@ -145,15 +143,17 @@
 		cb = *(facund_call_cb **)data.data;
 		assert(cb != NULL);
 		resp = cb(id, arg);
-
+		if (resp == NULL) {
+			/* TODO: Remove Magic Number */
+			resp = facund_response_new(id, 1,
+			    "Method returned an invalid response", NULL);
+		}
 	} else {
-		/* TODO: send a bad request response */
+		/* TODO: Remove Magic Number */
+		resp = facund_response_new(id, 1, "Invalid request", NULL);
 	}
 
-	msg = facund_response_string(resp);
-	if (msg != NULL) {
-		facund_send(conn, msg, strlen(msg));
-	}
+	return resp;
 }
 
 /*
@@ -187,7 +187,7 @@
     const XML_Char **attrs)
 {
 	struct facund_conn *conn;
-	char str[1024];
+	char *str;
 
 	printf("> %s\n", name);
 	conn = data;
@@ -195,37 +195,58 @@
 	if (conn->current_call[0] == '\0' && strcmp(name, "call") == 0) {
 		unsigned int i;
 		const char *call_name, *id;
+
+		assert(conn->resp == NULL);
+
 		if (attrs == NULL) {
-			/* TODO: Return an error */
+			conn->resp = facund_response_new(NULL,
+			    RESP_NO_ATTRIBUTE,
+			    "No call attributes were sent", NULL);
 			return;
 		}
 		call_name = id = NULL;
 		for (i = 0; attrs[i] != NULL && attrs[i+1] != NULL; i += 2) {
 			if (strcmp(attrs[i], "name") == 0) {
-				if (call_name != NULL) {
-					/* TODO: Return an error */
-					return;
+				if (call_name != NULL && conn->resp == NULL) {
+					conn->resp = facund_response_new(NULL,
+					    RESP_REPEATED_ATTRIBUTE,
+					    "Call name was set multiple times",
+					    NULL);
 				}
 				call_name = attrs[i + 1];
 			} else if (strcmp(attrs[i], "id") == 0) {
-				if (id != NULL) {
-					/* TODO: Return an error */
-					return;
+				if (id != NULL && conn->resp == NULL) {
+					/* TODO: Don't use a magic number */
+					conn->resp = facund_response_new(NULL,
+					    RESP_REPEATED_ATTRIBUTE,
+					    "Call ID was set multiple times",
+					    NULL);
 				}
 				id = attrs[i + 1];
-			} else {
-				/* TODO: Return an error */
-				return;
+			} else if (conn->resp == NULL) {
+				/*
+				 * This is entered when there is
+				 * an unknown attribute sent and
+				 * no other errors have occured.
+				 */
+				conn->resp = facund_response_new(NULL,
+				    RESP_UNKNOWN_ATTRIBUTE,
+				    "Unknown attribute was sent", NULL);
 			}
 		}
 		strlcpy(conn->current_call, call_name,
 		    sizeof(conn->current_call));
 		strlcpy(conn->call_id, id, sizeof(conn->call_id));
+
+		/* Attempt to set the ID if it can be */
+		facund_response_set_id(conn->resp, id);
 	} else if (strcmp(name, "data") == 0) {
 		struct facund_object *obj;
 
 		if (attrs == NULL) {
-			/* TODO: Return an error */
+			conn->resp = facund_response_new(NULL,
+			    RESP_NO_ATTRIBUTE,
+			    "No data attributes were sent", NULL);
 			return;
 		}
 		obj = NULL;
@@ -247,8 +268,11 @@
 	} else if (strcmp(name, "facund-client") == 0) {
 		/* Pass */
 	} else {
-		snprintf(str, 1024, "<unknown element=\"%s\"/>", name);
+		asprintf(&str, "<unknown element=\"%s\"/>", name);
+		if (str == NULL)
+			return;
 		facund_send(conn, str, strlen(str));
+		free(str);
 	}
 }
 
@@ -261,8 +285,24 @@
 	conn = data;
 
 	if (strcmp(name, "call") == 0) {
-		facund_server_call(conn, conn->current_call, conn->call_id,
-		    conn->call_arg);
+		const char *msg;
+		struct facund_response *resp;
+
+		if (conn->resp != NULL) {
+			resp = conn->resp;
+			conn->resp = NULL;
+		} else {
+			resp = facund_server_call(conn->current_call,
+			    conn->call_id, conn->call_arg);
+		}
+
+		/* Get the response string and send it to the client */
+		msg = facund_response_string(resp);
+		if (msg != NULL) {
+			facund_send(conn, msg, strlen(msg));
+		}
+		facund_response_free(resp);
+
 		conn->current_call[0] = '\0';
 		conn->call_id[0] = '\0';
 		facund_object_free(conn->call_arg);


More information about the p4-projects mailing list