/*
* Amanda, The Advanced Maryland Automatic Network Disk Archiver
* Copyright (c) 1991-1999 University of Maryland at College Park
* Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved.
* Copyright (c) 2013-2016 Carbonite, Inc. All Rights Reserved.
* All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of U.M. not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. U.M. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Authors: the Amanda Development Team. Its members are listed in a
* file named AUTHORS, in the root directory of this distribution.
*/
/*
* $Id: packet.c,v 1.8 2006/05/25 01:47:12 johnfranks Exp $
*
* Routines for modifying the amanda protocol packet type
*/
#include "amanda.h"
#include "packet.h"
/*
* Table of packet types and their printable forms
*/
static const struct {
const char name[5];
pktype_t type;
} pktypes[] = {
{ "REQ", P_REQ },
{ "REP", P_REP },
{ "PREP", P_PREP },
{ "ACK", P_ACK },
{ "NAK", P_NAK }
};
#define NPKTYPES G_N_ELEMENTS(pktypes)
/*
* Initialize a packet
*/
void pkt_init_empty(
pkt_t *pkt,
pktype_t type)
{
assert(pkt != NULL);
assert(!g_str_equal(pkt_type2str(type), "BOGUS"));
pkt->type = type;
pkt->packet_size = 1000;
pkt->body = g_malloc(pkt->packet_size);
pkt->body[0] = '\0';
pkt->size = strlen(pkt->body);
}
void pkt_init(pkt_t *pkt, pktype_t type, const char *fmt, ...)
{
va_list argp;
int len;
assert(pkt != NULL);
assert(!g_str_equal(pkt_type2str(type), "BOGUS"));
if(fmt == NULL)
fmt = "";
pkt->type = type;
pkt->packet_size = 1000;
pkt->body = g_malloc(pkt->packet_size);
while(1) {
arglist_start(argp, fmt);
len = g_vsnprintf(pkt->body, pkt->packet_size, fmt, argp);
arglist_end(argp);
if (len > -1 && len < (int)(pkt->packet_size - 1))
break;
pkt->packet_size *= 2;
amfree(pkt->body);
pkt->body = g_malloc(pkt->packet_size);
}
pkt->size = strlen(pkt->body);
}
/*
* Append data to a packet
*/
void pkt_cat(pkt_t *pkt, const char *fmt, ...)
{
size_t len;
int lenX;
va_list argp;
char * pktbody;
assert(pkt != NULL);
assert(fmt != NULL);
len = strlen(pkt->body);
while(1) {
arglist_start(argp, fmt);
lenX = g_vsnprintf(pkt->body + len, pkt->packet_size - len, fmt,argp);
arglist_end(argp);
if (lenX > -1 && lenX < (int)(pkt->packet_size - len - 1))
break;
pkt->packet_size *= 2;
pktbody = g_malloc(pkt->packet_size);
strncpy(pktbody, pkt->body, len);
pktbody[len] = '\0';
amfree(pkt->body);
pkt->body = pktbody;
}
pkt->size = strlen(pkt->body);
}
/*
* Converts a string into a packet type
*/
pktype_t
pkt_str2type(
const char *typestr)
{
guint i;
assert(typestr != NULL);
for (i = 0; i < NPKTYPES; i++)
if (g_str_equal(typestr, pktypes[i].name))
return (pktypes[i].type);
return ((pktype_t)-1);
}
/*
* Converts a packet type into a string
*/
const char *
pkt_type2str(
pktype_t type)
{
guint i;
for (i = 0; i < NPKTYPES; i++)
if (pktypes[i].type == type)
return (pktypes[i].name);
return ("BOGUS");
}