1 /*	$Id: proto_push_dump_debug.c 20800 2012-01-19 05:13:45Z m-oki $	*/
2 
3 /*
4  * Copyright (c) 2012, Internet Initiative Japan, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "config.h"
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <inttypes.h>
35 #include <string.h>
36 #include <sys/time.h>
37 #include <sys/types.h>
38 #include <unistd.h>
39 
40 #include <libarms.h>
41 #include <libarms_resource.h>
42 #include <axp_extern.h>
43 
44 #include <arms_xml_tag.h>
45 #include <module_db_mi.h>
46 
47 #include <libarms_log.h>
48 #include <libarms/base64.h>
49 #include <libarms/malloc.h>
50 #include <transaction/transaction.h>
51 #include <protocol/arms_methods.h>
52 
53 #include "compat.h"
54 
55 /*
56  * Callback Functions
57  */
58 /* context alloc */
59 static void *dump_debug_context(tr_ctx_t *);
60 static int dump_debug_response(transaction *, char *, int, int *);
61 static void dump_debug_release(tr_ctx_t *);
62 
63 
64 /*
65  * XML Schema: dump-debug-request
66  */
67 static struct axp_schema dump_debug_request = {
68 	ARMS_TAG_DUMP_DEBUG_REQ, "dump-debug-request", AXP_TYPE_CHILD,
69 		NULL, push_default_hook, NULL
70 };
71 
72 /*
73  * Method defineition
74  */
75 arms_method_t dump_debug_methods = {
76 	ARMS_TR_DUMP_DEBUG,	/* pm_type */
77 	"dump-debug",		/* type string */
78 	&dump_debug_request,	/* schema */
79 	0,			/* pm_flags */
80 	dump_debug_response,	/* pm_response */
81 	NULL,			/* pm_done */
82 	NULL,			/* pm_exec */
83 	NULL,			/* pm_copyarg */
84 	NULL,			/* pm_rollback */
85 	dump_debug_context,	/* pm_context */
86 	dump_debug_release,	/* pm_release */
87 };
88 
89 /*
90  * Method implementations
91  */
92 
93 #define BEGIN  1
94 #define RESULT 2
95 #define DONE   3
96 struct dump_debug_args {
97 	int state;
98 	int encoding;
99 	char result[1024];
100 	int resultlen;
101 };
102 
103 /*
104  * Context Alloc
105  */
106 static void *
dump_debug_context(tr_ctx_t * tr_ctx)107 dump_debug_context(tr_ctx_t *tr_ctx)
108 {
109 	struct dump_debug_args *arg;
110 
111 	arg = CALLOC(1, sizeof(*arg));
112 	if (arg != NULL) {
113 		arg->state = BEGIN;
114 	}
115 	return arg;
116 }
117 
118 /*
119  * Context Free
120  */
121 static void
dump_debug_release(tr_ctx_t * tr_ctx)122 dump_debug_release(tr_ctx_t *tr_ctx)
123 {
124 	struct dump_debug_args *arg;
125 
126 	if (tr_ctx->arg) {
127 		arg = tr_ctx->arg;
128 		FREE(arg);
129 	}
130 }
131 
132 /*
133  * Generate md-command-response mesage.
134  */
135 static int
dump_debug_response(transaction * tr,char * buf,int len,int * wrote)136 dump_debug_response(transaction *tr, char *buf, int len, int *wrote)
137 {
138 	tr_ctx_t *tr_ctx = &tr->tr_ctx;
139 	arms_context_t *res = arms_get_context();
140 	struct dump_debug_args *arg = tr_ctx->arg;
141 	int size, rv;
142 
143 	libarms_log(ARMS_LOG_DEBUG, "Generate response to RS");
144 
145 	switch (arg->state) {
146 	case BEGIN:
147 		if (res->callbacks.command_cb == NULL) {
148 			tr_ctx->result = 505;/*Not Support*/
149 			*wrote = arms_write_empty_message(tr, buf, len);
150 			return TR_WRITE_DONE;
151 		}
152 		rv = res->callbacks.command_cb(
153 			0,
154 			ARMS_PUSH_DUMP_DEBUG,
155 			NULL, 0,
156 			arg->result, sizeof(arg->result),
157 			NULL,
158 			res->udata);
159 		if (ARMS_RESULT_IS_ERROR(rv)) {
160 			tr_ctx->result = 402;/*SA Failure*/
161 			*wrote = arms_write_empty_message(tr, buf, len);
162 			return TR_WRITE_DONE;
163 		}
164 		size = arms_write_begin_message(tr, buf, len);
165 		buf += size;
166 		len -= size;
167 		if (ARMS_RESULT_IS_BYTES(rv)) {
168 			if (ARMS_RV_DATA_MASK(rv) > sizeof(arg->result)) {
169 				/* too big bytes.  no md-result */
170 				tr_ctx->result = 402;/*SA Failure*/
171 				size += arms_write_end_message(tr, buf, len);
172 				*wrote = size;
173 				return TR_WRITE_DONE;
174 			}
175 			arg->resultlen = ARMS_RV_DATA_MASK(rv);
176 			arg->encoding = ARMS_DATA_BINARY;
177 			size += snprintf(buf, len,
178 				 "<md-result id=\"0\" encoding=\"base64\">");
179 		} else {
180 			arg->encoding = ARMS_DATA_TEXT;
181 			size += snprintf(buf, len,
182 				 "<md-result id=\"0\">");
183 		}
184 		arg->state = RESULT;
185 		*wrote = size;
186 		return TR_WANT_WRITE;
187 	case RESULT:
188 		if (arg->encoding == ARMS_DATA_BINARY) {
189 			/* binary */
190 			*wrote = arms_base64_encode(buf, len,
191 						    arg->result,
192 						    arg->resultlen);
193 		} else {
194 			/* text */
195 			*wrote = strlcpy(buf, arms_escape(arg->result), len);
196 		}
197 		arg->state = DONE;
198 		return TR_WANT_WRITE;
199 	case DONE:
200 		size = snprintf(buf, len, "</md-result>");
201 		buf += size;
202 		len -= size;
203 		size += arms_write_end_message(tr, buf, len);
204 		*wrote = size;
205 		return TR_WRITE_DONE;
206 	default:
207 		break;
208 	}
209 	return TR_FATAL_ERROR;
210 }
211