## root/socloc/sconnect.c

/* [<][>][^][v][top][bottom][index][help] */

## DEFINITIONS

This source file includes following definitions.

1. sconnect_parse
2. sconnect_build
3. sp_code_string

    /* sconnect - A 'socloc' connect string parsing/building API.
       Rick Smereka, Copyright (C) 2000-2004.

       This program is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published by
       the Free Software Foundation; either version 2 of the License, or
       (at your option) any later version.

       This program is distributed in the hope that it will be useful,
       but WITHOUT ANY WARRANTY; without even the implied warranty of
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       GNU General Public License for more details.

       You should have received a copy of the GNU General Public License
       along with this program; if not, get a copy via the Internet at
       http://gnu.org/copyleft/gpl.html or write to the Free Software
       Foundation, Inc., 59 Temple Place, Suite 330, Boston,
       MA 02111-1307 USA

       You can contact the author via email at rsmereka@future-lab.com

       Original Windows 32bit version Jan/2000, Rick Smereka

       Added include of header 'ip.h' after moving the function 'isip'.
       Jul/2000, Rick Smereka

       Ported to Debian Linux. Nov/2002, Rick Smereka

       Changed all logging calls from 'log_file_date' to 'logman'.
       Mar/2004, Rick Smereka */

    #include "stdhead.h"
    #include "flsocket.h"
    #include "sconnect.h"
    #include "ip.h"

    int sconnect_parse(char *comm, int sflag, char *sname, char *hname,
                       int *port, char *ip_ad)
    {
       /* Parse a 'connect' command. Command string is expected in 'comm'.
          Syntax is:

             service service_name host host_name port port_num ip ip_ad

          The flag 'sflag' controls whether the service name is allowed.
          At least one comand word/value pair are required.
          Upon successful completion, components will be loaded into
          their respective parameters.  All string components must be
          allocated by the caller to sufficident size. Function returns
          a code defined in 'sconnect.h'. */

       char mname[] = "sconnect_parse";
       char *port_char, *comwrd;
       int i, done, found, nwords;

       logman("%s:enter", mname);
       nwords = command_words(comm);

       /* reasonableness checks */

       if (comm == (char *)NULL || !strlen(comm))
          {
          logman("%s:'comm' null or empty", mname);
          return(SP_INVALID_PARAMETER);
          }

       if (sflag != 0 && sflag != 1)
          {
          logman("%s:'sflag' not 0 or 1", mname);
          return(SP_INVALID_PARAMETER);
          }

       if (sflag)
          if (sname == (char *)NULL)
             {
             logman("%s:'sname' is null", mname);
             return(SP_INVALID_PARAMETER);
             }

       if (hname == (char *)NULL)
          {
          logman("%s:'hname' is null", mname);
          return(SP_INVALID_PARAMETER);
          }

       if (port == (int *)NULL)
          {
          logman("%s:'port' is null", mname);
          return(SP_INVALID_PARAMETER);
          }

       /* alloc vars */

       if ((port_char = (char *)malloc(128)) == (char *)NULL)
          {
          logman("%s:alloc fail[port_char]", mname);
          free(hname);
          return(SP_MEMORY_FAIL);
          }

       if ((comwrd = (char *)malloc(128)) == (char *)NULL)
          {
          logman("%s:alloc fail[comwrd]", mname);

          free(port_char);
          return(SP_MEMORY_FAIL);
          }

       /* clear out returning components */

       if (sflag)
          sname[0] = EOS;

       if (ip_ad != (char *)NULL)
          ip_ad[0] = EOS;

       hname[0] = EOS;
       port_char[0] = EOS;
       *port = 0;
       i = 1;
       done = FALSE;

       /* go through each word pair which must consist of a keyword
          followed by its value, keywords are not case sensitive, the
          value is treated 'as is' and its case is not modified */

       while(!done)
          {
          found = FALSE;

          /* get keyword or command word */

          if (!command_word(comm, comwrd, i))
             {
             logman("%s:parse error[comwrd(%d)]", mname, i);
             free(port_char);
             free(comwrd);
             return(SP_INTERNAL_ERROR);
             }

          /* is it 'SERVICE'? */

          if (!stricmp(comwrd, "SERVICE"))
             {
             if (!sflag)
                {
                logman("%s:service name not allowed", mname);
                return(SP_SERVICE_NOT_ALLOWED);
                }

             if (!command_word(comm, sname, i + 1))
                {
                logman("%s:parse error[sname]", mname);
                free(port_char);
                free(comwrd);
                return(SP_INVALID_PARAMETER);
                }

             found = TRUE;
             }

          /* is it 'HOST'? */

          if (!found && !stricmp(comwrd, "HOST"))
             {
             if (!command_word(comm, hname, i + 1))
                {
                logman("%s:parse error[hname]", mname);
                free(port_char);
                free(comwrd);
                return(SP_INVALID_PARAMETER);
                }

             found = TRUE;
             }

          /* is it 'PORT'? */

          if (!found && !stricmp(comwrd, "PORT"))
             {
             if (!command_word(comm, port_char, i + 1))
                {
                logman("%s:parse error[hname]", mname);
                free(port_char);
                free(comwrd);
                return(SP_INVALID_PARAMETER);;
                }

             /* port must be a number */

             if (!qatoi(port_char, port))
                {
                logman("%s:non numeric port", mname);
                free(port_char);
                free(comwrd);
                return(SP_INVALID_PARAMETER);
                }

             /* a positive number */

             if (*port <= 0)
                {
                logman("%s:port out of range", mname);
                free(port_char);
                free(comwrd);
                return(SP_INVALID_PARAMETER);
                }

             found = TRUE;
             }

          /* is it 'IP' */

          if (!found && !stricmp(comwrd, "IP"))
             {
             if (!command_word(comm, ip_ad, i + 1))
                {
                logman("%s:parse error[ip_ad]", mname);
                free(port_char);
                free(comwrd);
                return(SP_INVALID_PARAMETER);
                }

             /* must be a valid IP address */

             if (!isip(ip_ad))
                {
                logman("%s:not a valid IP address", mname);
                free(port_char);
                free(comwrd);
                return(SP_INVALID_PARAMETER);
                }

             found = TRUE;
             }

          if (!found)
             {
             logman("%s:unknown comwrd[%s]", mname, comwrd);
             free(port_char);
             free(comwrd);
             return(SP_INVALID_PARAMETER);
             }

          i += 2;

          if (i > nwords)
             done = TRUE;
          }

       free(comwrd);
       free(port_char);

       /* if (sflag)
          if (!strlen(sname))
             {
             logman("%s:service name is required", mname);
             return(SP_SERVICE_MISSING);
             } */

       logman("%s:normal exit rc[0]", mname);
       return(SP_OK);
    }

    int sconnect_build(char *sname, char *hname, int *port, char *ip_ad,
                       char *scout)
    {
       /* Build a connect string in the form:

             [service service_name][ host host_name][ port port_num][ip ad_ad]

          String is built from input parameters. All parameters are optional.
          At least one input parameter must be present. Connect string is
          returned in 'scout' which must already be allocated by the caller
          to sufficient size. Function returns a code defined in
          'sconnect.h'. */

       char mname[] = "sconnect_build";
       char *wrd;

       logman("%s:enter", mname);
       scout[0] = EOS;

       if (scout == (char *)NULL)
          {
          logman("%s:parm null[scout]", mname);
          return(SP_INVALID_PARAMETER);
          }

       if ((wrd = (char *)malloc(SP_MAXCOMMAND)) == (char *)NULL)
          {
          logman("%s:alloc fail[wrd]", mname);
          return(SP_MEMORY_FAIL);
          }

       /* quote the service name if it contains spaces */

       if (sname != (char *)NULL && strlen(sname))
          if (words(sname) > 1)
             sprintf(scout, "service '%s'", sname);
          else
             sprintf(scout, "service %s", sname);

       /* add host name, if present */

       if (hname != (char *)NULL && strlen(hname))
          {
          if (words(hname) > 1)
             sprintf(wrd, "host '%s'", hname);
          else
             sprintf(wrd, "host %s", hname);

          if (strlen(scout))
             {
             strcat(scout, " ");
             strcat(scout, wrd);
             }
          else
             strcpy(scout, wrd);
          }

       /* add port if present */

       if (port != (int *)NULL && *port > 0)
          {
          sprintf(wrd, "port %d", *port);

          if (strlen(scout))
             {
             strcat(scout, " ");
             strcat(scout, wrd);
             }
          else
             strcpy(scout, wrd);
          }

       /* add IP address if present */

       if (ip_ad != (char *)NULL && strlen(ip_ad))
          {
          sprintf(wrd, "ip %s", ip_ad);

          if (strlen(scout))
             {
             strcat(scout, " ");
             strcat(scout, wrd);
             }
          else
             strcpy(scout, wrd);
          }

       free(wrd);

       /* if output string is empty, error */

       if (!strlen(scout))
          {
          logman("%s:no values given", mname);
          return(SP_INVALID_PARAMETER);
          }

       logman("%s:normal exit[0],scout=%s,l=%d", mname, scout,
                     strlen(scout));
       return(SP_OK);
    }

    void sp_code_string(int ret, char *mes)
    {
       /* Translate a 'sconnect' return code to English. 'mes' must
          already be allocated to sufficient size. */

       switch(ret)
          {
          case SP_OK:
             strcpy(mes, "ok");
             break;

          case SP_INVALID_PARAMETER:
             strcpy(mes, "invalid parameter");
             break;

          case SP_MEMORY_FAIL:
             strcpy(mes, "memory allocation error");
             break;

          case SP_INTERNAL_ERROR:
             strcpy(mes, "internal error");
             break;

          case SP_SERVICE_NOT_ALLOWED:
             strcpy(mes, "service name not allowed");
             break;

          case SP_SERVICE_MISSING:
             strcpy(mes, "service name is required");
             break;

          default:
             strcpy(mes, "unknown code");
          };
    }

/* [<][>][^][v][top][bottom][index][help] */