/*
* Copyright (c) 1998,1999,2000
* Traakan, Inc., Los Altos, CA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Project: NDMJOB
* Ident: $Id: $
*
* Description:
*
*/
#include "ndmlib.h"
xdrproc_t
ndmnmb_find_xdrproc (struct ndmp_msg_buf *nmb)
{
struct ndmp_xdr_message_table * xmte;
xmte = ndmp_xmt_lookup (nmb->protocol_version, nmb->header.message);
if (!xmte) {
return 0;
}
if (nmb->header.message_type == NDMP0_MESSAGE_REQUEST) {
return (xdrproc_t) xmte->xdr_request;
}
if (nmb->header.message_type == NDMP0_MESSAGE_REPLY) {
return (xdrproc_t) xmte->xdr_reply;
}
return 0;
}
void
ndmnmb_free (struct ndmp_msg_buf *nmb)
{
xdrproc_t xdr_body = ndmnmb_find_xdrproc (nmb);
if (nmb->flags & NDMNMB_FLAG_NO_FREE)
return;
if (xdr_body) {
xdr_free (xdr_body, (void*) &nmb->body);
}
}
void
ndmnmb_snoop (
struct ndmlog *log,
char *tag,
int level,
struct ndmp_msg_buf *nmb,
char *whence)
{
int rc, nl, i;
char buf[2048];
int (*ndmpp)();
int level5 = 5;
int level6 = 6;
if (level < 6 && nmb->protocol_version == 4) {
ndmp4_header *header = (ndmp4_header *)&nmb->header;
if ((header->message_code == NDMP4_NOTIFY_DATA_HALTED &&
header->error_code == NDMP4_DATA_HALT_SUCCESSFUL) ||
(header->message_code == NDMP4_NOTIFY_MOVER_HALTED &&
header->error_code == NDMP4_MOVER_HALT_CONNECT_CLOSED)) {
level = 6;
level5 = 0;
level6 = 0;
}
}
if (!log || level < 5) {
return;
}
rc = ndmp_pp_header (nmb->protocol_version, &nmb->header, buf);
#if 0
ndmlogf (log, tag, level5, "%s %s", buf, whence);
#else
{
char combo[3];
if (*whence == 'R') {
combo[0] = '>';
combo[1] = buf[0];
} else {
combo[0] = buf[0];
combo[1] = '>';
}
combo[2] = 0;
ndmlogf (log, tag, level5, "%s %s", combo, buf+2);
}
#endif
if (level < 6) {
return;
}
if (rc <= 0) { /* no body */
return;
}
if (nmb->header.message_type == NDMP0_MESSAGE_REQUEST) {
ndmpp = ndmp_pp_request;
} else if (nmb->header.message_type == NDMP0_MESSAGE_REPLY) {
ndmpp = ndmp_pp_reply;
} else {
return; /* should not happen */
}
nl = 1;
for (i = 0; i < nl; i++) {
nl = (*ndmpp)(nmb->protocol_version,
nmb->header.message, &nmb->body, i, buf);
if (nl == 0)
break; /* no printable body (void) */
ndmlogf (log, tag, level6, " %s", buf);
}
}
unsigned
ndmnmb_get_reply_error_raw (struct ndmp_msg_buf *nmb)
{
unsigned protocol_version = nmb->protocol_version;
unsigned msg = nmb->header.message;
unsigned raw_error;
if (NDMNMB_IS_UNFORTUNATE_REPLY_TYPE(protocol_version, msg)) {
raw_error = nmb->body.unf3_error.error;
} else {
raw_error = nmb->body.error;
}
return raw_error;
}
ndmp9_error
ndmnmb_get_reply_error (struct ndmp_msg_buf *nmb)
{
unsigned protocol_version = nmb->protocol_version;
unsigned raw_error = ndmnmb_get_reply_error_raw (nmb);
ndmp9_error error;
switch (protocol_version) {
default:
/* best effort */
error = (ndmp9_error) raw_error;
break;
#ifndef NDMOS_OPTION_NO_NDMP2
case NDMP2VER:
{
ndmp2_error error2 = raw_error;
ndmp_2to9_error (&error2, &error);
}
break;
#endif /* !NDMOS_OPTION_NO_NDMP2 */
#ifndef NDMOS_OPTION_NO_NDMP3
case NDMP3VER:
{
ndmp3_error error3 = raw_error;
ndmp_3to9_error (&error3, &error);
}
break;
#endif /* !NDMOS_OPTION_NO_NDMP3 */
#ifndef NDMOS_OPTION_NO_NDMP4
case NDMP4VER:
{
ndmp4_error error4 = raw_error;
ndmp_4to9_error (&error4, &error);
}
break;
#endif /* !NDMOS_OPTION_NO_NDMP4 */
}
return error;
}
int
ndmnmb_set_reply_error_raw (struct ndmp_msg_buf *nmb, unsigned raw_error)
{
unsigned protocol_version = nmb->protocol_version;
unsigned msg = nmb->header.message;
if (NDMNMB_IS_UNFORTUNATE_REPLY_TYPE(protocol_version, msg)) {
nmb->body.unf3_error.error = raw_error;
} else {
nmb->body.error = raw_error;
}
return 0;
}
int
ndmnmb_set_reply_error (struct ndmp_msg_buf *nmb, ndmp9_error error)
{
unsigned protocol_version = nmb->protocol_version;
unsigned raw_error;
switch (protocol_version) {
default:
/* best effort */
raw_error = (unsigned) error;
break;
#ifndef NDMOS_OPTION_NO_NDMP2
case NDMP2VER:
{
ndmp2_error error2;
ndmp_9to2_error (&error, &error2);
raw_error = (unsigned) error2;
}
break;
#endif /* !NDMOS_OPTION_NO_NDMP2 */
#ifndef NDMOS_OPTION_NO_NDMP3
case NDMP3VER:
{
ndmp3_error error3;
ndmp_9to3_error (&error, &error3);
raw_error = (unsigned) error3;
}
break;
#endif /* !NDMOS_OPTION_NO_NDMP3 */
#ifndef NDMOS_OPTION_NO_NDMP4
case NDMP4VER:
{
ndmp4_error error4;
ndmp_9to4_error (&error, &error4);
raw_error = (unsigned) error4;
}
break;
#endif /* !NDMOS_OPTION_NO_NDMP4 */
}
return ndmnmb_set_reply_error_raw (nmb, raw_error);
}