From owner-p4-projects@FreeBSD.ORG Sun Jul 8 06:03:23 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C833616A46B; Sun, 8 Jul 2007 06:03:22 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 5F79716A421 for ; Sun, 8 Jul 2007 06:03:22 +0000 (UTC) (envelope-from andrew@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 4C60C13C458 for ; Sun, 8 Jul 2007 06:03:22 +0000 (UTC) (envelope-from andrew@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l6863Mux039264 for ; Sun, 8 Jul 2007 06:03:22 GMT (envelope-from andrew@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l6863LIc039261 for perforce@freebsd.org; Sun, 8 Jul 2007 06:03:21 GMT (envelope-from andrew@freebsd.org) Date: Sun, 8 Jul 2007 06:03:21 GMT Message-Id: <200707080603.l6863LIc039261@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to andrew@freebsd.org using -f From: Andrew Turner To: Perforce Change Reviews Cc: Subject: PERFORCE change 123088 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 08 Jul 2007 06:03:23 -0000 http://perforce.freebsd.org/chv.cgi?CH=123088 Change 123088 by andrew@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, "", name); + asprintf(&str, "", 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);