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