/************************************************************************
** MODULE INFORMATION*
**********************
**     FILE     NAME:       str.c
**     SYSTEM   NAME:       SNMP String Module
**     ORIGINAL AUTHOR(S):  Dirk Wisse
**     VERSION  NUMBER:     1
**     CREATION DATE:       1990/11/28
**
** DESCRIPTION: SNMP String Module
**              
*************************************************************************
** CHANGES INFORMATION **
*************************
** REVISION:    $Revision$
** WORKFILE:    $Workfile$
** LOGINFO:     $Log$
*************************************************************************/
#if ! defined(PRD)
static char _pvcs_hdr[] =
"$Header$";
#endif
#include "snmp.h"

typedef struct
{
    int     Tag;
    char    TagStr [31];
}
    str_tag;

typedef struct
{
    int     Err;
    char    ErrStr [31];
}
    str_err;

typedef struct
{
    int     Trp;
    char    TrpStr [31];
}
    str_trp;

static str_tag
    StrTag [] =
{
    {PKT_NULL,             "NULL"}, 
    {PKT_INTEGER,          "INTEGER"}, 
    {PKT_OCTETSTRING,      "OCTETSTRING"}, 
    {PKT_OBJECTIDENTIFIER, "OBJECTIDENTIFIER"}, 
    {PKT_IPADDRESS,        "ADDRESS"}, 
    {PKT_COUNTER,          "COUNTER"}, 
    {PKT_GAUGE,            "GAUGE"}, 
    {PKT_TIMETICKS,        "TIMETICKS"}, 
    {PKT_OPAQUE,           "OPAQUE"}, 
    {-1,                    ""}                   
};

static str_err
    StrErr [] =
{
    {PKT_NOERROR,    "NOERROR"}, 
    {PKT_TOOBIG,     "TOOBIG"}, 
    {PKT_NOSUCHNAME, "NOSUCHNAME"}, 
    {PKT_BADVALUE,   "BADVALUE"}, 
    {PKT_READONLY,   "READONLY"}, 
    {PKT_GENERR,     "GENERR"}, 
    {-1,             ""}                   
};

static str_trp
    StrTrp [] =
{
    {PKT_COLDSTART,       "COLDSTART"},
    {PKT_WARMSTART,       "WARMSTART"},
    {PKT_LINKDOWN,        "LINKDOWN"},
    {PKT_LINKUP,          "LINKUP"},
    {PKT_AUTFAILURE,      "AUTHENTICATIONFAILURE"},
    {PKT_EGPNEIGHBORLOSS, "NEIGHBORLOSS"},
    {PKT_ENTSPECIFIC,     "SPECIFIC"},
    {-1,                  ""}
};

int StrEncOid (Str,Oid,OidLen)
char        *Str;
unsigned    *Oid;
unsigned    OidLen;
{
    int
        Ind,
        Len;

    sprintf (Str, "%u%n", Oid [0], &Len);
    Str += Len;
    for (Ind = 1; Ind < (int) OidLen; Ind++)
    {
        sprintf (Str, ".%u%n", Oid [Ind], &Len);
        Str += Len;
    }
    return (0);
}        

int StrDecOid (Str,Oid,OidLen)
char        *Str;
unsigned    *Oid;
unsigned    *OidLen;
{
    int
        Ind,
        Len;

    if (sscanf (Str, "%u%n", &(Oid [0]), &Len) != 1)
        return (-1);
    Ind = 1;
    Str += Len;
    while (sscanf (Str, ".%u%n", &(Oid [Ind]), &Len) == 1)
    {
        Ind++;
        Str += Len;
    }
    *OidLen = Ind;
    return (0);
}

/**************************************************************
** NAME:        StrEncOji     
** SYNOPSIS:    int
**                  StrEncOji
**                  (
**                      char        *Str,
**                      pkt_obj     *Obj
**                  )
** DESCRIPTION: Encodes an Object Identifier in a string.
**              Parameters:
**              Str: String.
**              Obj: Object with Object Identifier.
** RETURNS:     0 -->   no error
**              else    error code
**************************************************************/
int StrEncOji (Str,Obj)
char        *Str;
pkt_obj     *Obj;
{
    int
        Ind,
        Len;

    sprintf (Str, "%u%n", Obj->ObjOji [0], &Len);
    Str += Len;
    for (Ind = 1; Ind < (int) Obj->ObjOjiLen; Ind++)
    {
        sprintf (Str, ".%u%n", Obj->ObjOji [Ind], &Len);
        Str += Len;
    }
    return (0);
}        

/**************************************************************
** NAME:        StrDecOji     
** SYNOPSIS:    int
**                  StrDecOji
**                  (
**                      char        *Str,
**                      pkt_obj     *Obj
**                  )
** DESCRIPTION: Decodes an Object Identifier from a string.
**              Parameters:
**              Str: String.
**              Obj: Object with Object Identifier.
** RETURNS:     0 -->   no error
**              else    error code
**************************************************************/
int StrDecOji (Str,Obj)
char        *Str;
pkt_obj     *Obj;
{
    int
        Ind,
        Len;

    if (sscanf (Str, "%u%n", &(Obj->ObjOji [0]), &Len) != 1)
        return (-1);
    Ind = 1;
    Str += Len;
    while (sscanf (Str, ".%u%n", &(Obj->ObjOji [Ind]), &Len) == 1)
    {
        Ind++;
        Str += Len;
    }
    Obj->ObjOjiLen = Ind;
    return (0);
}        

/**************************************************************
** NAME:        StrEncTag     
** SYNOPSIS:    char
**                  *StrEncTag
**                  (
**                      int     Tag
**                  )
** DESCRIPTION: Encodes a Tag in a string.
**              Parameters:
**              Tag: Tag.
** RETURNS:     NULL --> error
**              else     pointer to string
**************************************************************/
char *StrEncTag (Tag)
int     Tag;
{
    str_tag
        *Ptr;

    Ptr = StrTag;
    while (Ptr->Tag != -1)
    {
        if (Ptr->Tag == Tag)
            return (Ptr->TagStr);
        Ptr++;
    }
    return (NULL);
}

/**************************************************************
** NAME:        StrDecTag     
** SYNOPSIS:    int
**                  StrDecTag
**                  (
**                      char    *Str
**                  )
** DESCRIPTION: Decodes a Tag from a string.
**              Parameters:
**              Str: String with Tag.
** RETURNS:     NULL --> error
**              else     pointer to string
**************************************************************/
int StrDecTag (Str)
char    *Str;
{
    str_tag
        *Ptr;

    Ptr = StrTag;
    while (Ptr->Tag != -1)
    {
        if (strcmp (Ptr->TagStr, Str) == 0)
            return (Ptr->Tag);
        Ptr++;
    }
    return (-1);
}

/**************************************************************
** NAME:        StrEncSyn     
** SYNOPSIS:    int
**                  StrEncSyn
**                  (
**                      char        *Str,
**                      pkt_obj     *Obj
**                  )
** DESCRIPTION: Encodes a Syntax in a string.
**              Parameters:
**              Str: String.
**              Obj: Object with Syntax.
** RETURNS:     0 -->   no error
**              else    error code
**************************************************************/
int StrEncSyn (Str,Obj)
char        *Str;
pkt_obj     *Obj;
{
    pkt_syn
        *Syn;
    int
        Ind,
        Len;

    Syn = &Obj->ObjSyn;
    switch (Obj->ObjTag)
    {
        case PKT_NULL:
	    strcpy (Str, "NULL");
	    break;
        case PKT_INTEGER:
            sprintf (Str, "%ld", Syn->SynLngInt);
            break;
        case PKT_OCTETSTRING:
            Syn->SynBufChr [Obj->ObjSynLen] = '\0';
            sprintf (Str, "%s", Syn->SynBufChr);
            break;
       case PKT_OBJECTIDENTIFIER:
            sprintf (Str, "%u%n", Syn->SynBufInt [0], &Len); 
            Str += Len;
            for (Ind = 1; Ind < (int) Obj->ObjSynLen; Ind++)
            {
                sprintf (Str, ".%u%n", Syn->SynBufInt [Ind], &Len);
                Str += Len;
            }
            break;
        case PKT_IPADDRESS:
            strcpy (Str, inet_ntoa (&(Syn->SynLngInt)));
            break;
        case PKT_COUNTER:
        case PKT_GAUGE:
        case PKT_TIMETICKS:
            sprintf (Str, "%lu", Syn->SynLngInt);
            break;
        case PKT_OPAQUE:
            break;
    }
    return (0);
}

/**************************************************************
** NAME:        StrDecSyn     
** SYNOPSIS:    int
**                  StrDecSyn
**                  (
**                      char        *Str,
**                      pkt_obj     *Obj
**                  )
** DESCRIPTION: Decodes a Syntax from a string.
**              Parameters:
**              Str: String.
**              Obj: Object with Syntax.
** RETURNS:     0 -->   no error
**              else    error code
**************************************************************/
int StrDecSyn (Str,Obj)
char        *Str;
pkt_obj     *Obj;
{
    pkt_syn
        *Syn;
    int
        Ind,
        Len;

    Syn = &Obj->ObjSyn;
    switch (Obj->ObjTag)
    {
        case PKT_NULL:
            break;
        case PKT_INTEGER:
            sscanf (Str, "%ld", &Syn->SynLngInt);
            break;
        case PKT_OCTETSTRING:
            sscanf (Str, "%[^\n]", Syn->SynBufChr);
            Obj->ObjSynLen = strlen (Syn->SynBufChr);
            break;
       case PKT_OBJECTIDENTIFIER:
            if (sscanf (Str, "%u%n", &(Syn->SynBufInt [0]), &Len) != 1)
                return (-1);
            Ind = 1;
            Str += Len;
            while (sscanf (Str, ".%u%n", &(Syn->SynBufInt [Ind]), &Len) == 1)
            {
                Ind++;
                Str += Len;
            }
            Obj->ObjSynLen = Ind;
            break;
        case PKT_IPADDRESS:
            Syn->SynLngInt = inet_addr (Str);
            break;
        case PKT_COUNTER:
        case PKT_GAUGE:
        case PKT_TIMETICKS:
            sscanf (Str, "%lu", &Syn->SynLngInt);
            break;
        case PKT_OPAQUE:
            break;
    }
    return (0);
}


/**************************************************************
** NAME:        StrEncOji     
** SYNOPSIS:    int
**                  StrEncOji
**                  (
**                      char        *Str,
**                      pkt_obj     *Obj
**                  )
** DESCRIPTION: Encodes an Object in a string.
**              Parameters:
**              Str: String.
**              Obj: Object.
**              Format is <x.y.z> = <TYPE> <syntax>.
** RETURNS:     0 -->   no error
**              else    error code
**************************************************************/
int StrEncObj (Str,Obj)
char        *Str;
pkt_obj     *Obj;
{
    char
        Oji [63],
        *Tag,
        Syn [255];
    
    if (StrEncOji (Oji, Obj) < 0)
        return (-1);
    if ((Tag = StrEncTag (Obj->ObjTag)) == NULL)
        return (-1);
    if (StrEncSyn (Syn, Obj) < 0)
        return (-1);
    if (sprintf (Str, "%s = %s %s", Oji, Tag, Syn) == NULL)
        return (-1);
    return (0);
}

/**************************************************************
** NAME:        StrDecOji     
** SYNOPSIS:    int
**                  StrDecOji
**                  (
**                      char        *Str,
**                      pkt_obj     *Obj
**                  )
** DESCRIPTION: Decodes an Object from a string.
**              Parameters:
**              Str: String.
**              Obj: Object.
**              Format must be <x.y.z> = <TYPE> <syntax>.
** RETURNS:     0 -->   no error
**              else    error code
**************************************************************/
int StrDecObj (Str,Obj)
char        *Str;
pkt_obj     *Obj;
{
    char
        Oji [63],
        Tag [31],
        Syn [255];

    if (sscanf (Str, "%s = %s %[^\0]", Oji, Tag, Syn) != 3)
        return (-1);
    if (StrDecOji (Oji, Obj) < 0)
        return (-1);
    if ((Obj->ObjTag = StrDecTag (Tag)) < 0)
        return (-1);
    if (StrDecSyn (Syn, Obj) < 0)
        return (-1);
    return (0);
}

/**************************************************************
** NAME:        StrEncErr     
** SYNOPSIS:    char
**                  *StrEncErr
**                  (
**                      int     Err
**                  )
** DESCRIPTION: Encodes an Error Status in a string.
**              Parameters:
**              Err: Error Status.
** RETURNS:     NULL --> error
**              else     pointer to string
**************************************************************/
char *StrEncErr (Err)
int     Err;
{
    str_err
        *Ptr;

    Ptr = StrErr;
    while (Ptr->Err != -1)
    {
        if (Ptr->Err == Err)
            return (Ptr->ErrStr);
        Ptr++;
    }
    return (NULL);
}

/**************************************************************
** NAME:        StrEncTrp     
** SYNOPSIS:    char
**                  *StrEncTrp
**                  (
**                      int     Trp
**                  )
** DESCRIPTION: Encodes a General Trap in a string.
**              Parameters:
**              Trp: General Trap.
** RETURNS:     NULL --> error
**              else     pointer to string
**************************************************************/
char *StrEncTrp (Trp)
int     Trp;
{
    str_trp
        *Ptr;

    Ptr = StrTrp;
    while (Ptr->Trp != -1)
    {
        if (Ptr->Trp == Trp)
            return (Ptr->TrpStr);
        Ptr++;
    }
    return (NULL);
}
