MySVC
an open source UNIX framework for shell script based web services provider
»Home
»Tools
»Man Page
»User Guide
»ChangeLog
»Installation
»Source Code
»Downloads
»FAQ
»Support
»License

»My Apps

apt.cc

// $Id$

//  myspl - My Service Protocol Library - Version 1.0 (www.mysvc.it)
//  Copyright (C) 2009 Davide Cucciniello <davide6169@gmail.com>
//
//  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 3 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, see <http://www.gnu.org/licenses/>.

/* **********************************************************************
 *
 *  ***   **        *** **  **  ****
 *   **  **        *  *  *  ** **  *
 *   *** **  **  * ***   *  *  *
 *   * ** *   * **   **   * *  *
 *   * *  *   * *  *  *   **   **
 *  ***  ***   **  ***     *    ****
 *             *
 *            *
 *
 *  My Service
 *
 * ***********************************************************************
 *
 *  ***   **        *** ****  ***
 *   **  **        *  *  *  *  *
 *   *** **  **  * ***   *  *  *
 *   * ** *   * **   **  ***   *
 *   * *  *   * *  *  *  *     *  *
 *  ***  ***   **  ***  ***   *****
 *             *
 *            *
 *
 *  My Service Protocol Library Example Client
 *  (Ascii Protocol Tester)
 *
 *  File: apt.cc
 *
 *  Usage:
 *    apt [-a <addr>]
 *        [-p <port>]
 *        [-f <inputfile>]
 *        [-o <outputfile>]
 *        [-d <delay>]
 *
 *   (default input: stdin,
 *    default output: stdout)
 *
 *  Input:
 *      <request_line>
 *      <request_line>
 *      ...
 *      <request_line>
 *      %<substring_of_last_response_line>%
 *      <request_line>
 *      <request_line>
 *      ...
 *      <request_line>
 *      %<substring_of_last_response_line>%
 *
 *  Description:
 *    Simple Tester Client for ASCII Protocols
 *    (send to server request lines from input stream and
 *     write to output stream server response lines)
 *    as usage example for MySPL library
 *    (used to test many provisioning protocols on Network Elements
 *     in BLU mobile telephone operator)
 *
 *  Input Example:
 *
 *  AS4
 *  00
 *  SAS_ACTION LOGIN
 *  LOGIN blu2
 *  PASSWORD online
 *  $END$
 *  %$END$%
 *  SAS4
 *  00
 *  SAS_ACTION LOGOUT
 *  $END$
 *  %$END$%
 *
 * ***********************************************************************
 *
 *  History:
 *    1.0               first version
 *
 * *********************************************************************** */

#include "protocol.hh"
#include <fstream>

// Error codes

#define APT_INTERNAL_ERROR   1
#define APT_CONNECTION_ERROR 2
#define APT_INPUTFILE_ERROR  3
#define APT_OUTPUTFILE_ERROR 4
#define APT_SEND_ERROR       5
#define APT_RECV_ERROR       6

// Error messages

#define APT_SEND_MSGERROR     "error sending request"
#define APT_RECV_MSGERROR     "error receiving response"

// Constants

#define APT_MAXLINESIZE    1024

using namespace std;

//
// Main
//

int main(int argc,char* argv[])
{
  // Default values

  string inputfile = "";
  string outputfile = "";
  int delay = 0;
  string addr = "";
  int port = 0;

  bool delay_option_is_specified = false;

  // Parsing command line options

  int option;

  while((option = getopt(argc,argv,":ha:p:f:o:d:")) != EOF)
  {
    switch(option)
    {
      case 'h':
        cerr << "usage: apt [-a <addr>]" << endl;
        cerr << "           [-p <port>]" << endl;
        cerr << "           [-f <inputfile>]" << endl;
        cerr << "           [-o <outputfile>]" << endl;
        cerr << "           [-d <delay>]" << endl;
        cerr << endl;

        return APT_INTERNAL_ERROR;
        break;
      case 'a':
        addr = optarg;
        break;
      case 'p':
        port = atoi(optarg);
        break;
      case 'f':
        inputfile = optarg;
        break;
      case 'o':
        outputfile = optarg;
        break;
      case 'd':
        delay = atoi(optarg);
        delay_option_is_specified = true;
        break;
    }
  }

  // If ip address or port is not specified try environment variables ...

  if(addr.empty() && getenv("APT_ADDR"))
    addr = getenv("APT_ADDR");

  if(port == 0 && getenv("APT_PORT"))
    port = atoi(getenv("APT_PORT"));

  // If APT_DELAY environment variable is defined use it ...

  if(!delay_option_is_specified && getenv("APT_DELAY"))
    delay = atoi(getenv("APT_DELAY"));

  if(addr.empty() || port == 0)
  {
    // error ...

    cerr << "apt - Ascii Protocol Tester - Ver 1.0" << endl;
    cerr << endl;
    cerr << "usage: apt [-a <addr>]" << endl;
    cerr << "           [-p <port>]" << endl;
    cerr << "           [-f <inputfile>]" << endl;
    cerr << "           [-o <outputfile>]" << endl;
    cerr << "           [-d <delay>]" << endl;
    cerr << endl;
    cerr << "  input:" << endl;
    cerr << "    <request_line>" << endl;
    cerr << "    <request_line>" << endl;
    cerr << "    ..." << endl;
    cerr << "    <request_line>" << endl;
    cerr << "    %<substring_of_last_response_line>%" << endl;
    cerr << "    <request_line>" << endl;
    cerr << "    <request_line>" << endl;
    cerr << "    ..." << endl;
    cerr << "    <request_line>" << endl;
    cerr << "    %<substring_of_last_response_line>%" << endl;
    cerr << "    ..." << endl;

    return APT_INTERNAL_ERROR;
  }

  // if inputfile and outputfile are not specified
  // use standard input and standard output

  istream* inputstream;
  ostream* outputstream;

  if(inputfile.empty())
    inputstream = &cin;
  else
  {
    inputstream = new ifstream(inputfile.c_str());

    if(!(*inputstream))
    {
      cerr << "error: cannot open input file " << inputfile << endl;

      delete inputstream;

      return APT_INPUTFILE_ERROR;
    }
  }

  if(outputfile.empty())
    outputstream = &cout;
  else
  {
    outputstream = new ofstream(outputfile.c_str());

    if(!(*outputstream))
    {
      cerr << "error: cannot open output file " << outputfile << endl;

      delete outputstream;

      return APT_OUTPUTFILE_ERROR;
    }
  }

  try
  {
    // Connect to server (ascii mode) ...

    SocketClient client(addr,port,false);

    client.connect();

    StringField request;
    StringField response(APT_MAXLINESIZE);

    string requeststr;
    string responsestr;

    // input is a sequence of <request_block>;
    // each <request_block> has the following syntax:
    //
    // <request_line>
    // <request_line>
    // ...
    // <request_line>
    // %<substring_of_last_response_line>%
    //
    // Send request lines of input stream to server
    // and write response lines from server to output stream ...

    while(getline(*inputstream,requeststr))
    {
      if ((requeststr.length() >= 2) &&
          (requeststr[0] == '%') &&
          (requeststr[requeststr.length()-1] == '%'))
      {
        string last;

        if(requeststr.length() > 2)
          last = requeststr.substr(1,requeststr.length()-2);

        while(1)
        {
          try
          {
            // Reading response ...
            client >> response;

            responsestr = response.value();
          }
          catch(...)
          {
            cerr << APT_RECV_MSGERROR << endl;

            try
            {
              client.close();
            }
            catch(...)
            {
            }

            return APT_RECV_ERROR;
          }

          (*outputstream) << responsestr << endl;

          if(responsestr.find(last) != string::npos)
            break;
        }

        continue;
      }

      request = requeststr;

      try
      {
        // Sending request ...
        client << request;
      }
      catch(...)
      {
        cerr << APT_SEND_MSGERROR << endl;

        try
        {
          client.close();
        }
        catch(...)
        {
        }

        return APT_SEND_ERROR;
      }
    }

    client.close();
  }
  catch(SocketException e)
  {
    cerr << e << endl;

    return APT_CONNECTION_ERROR;
  }
  catch(Exception e)
  {
    cerr << e << endl;

    return APT_INTERNAL_ERROR;
  }
  catch(exception e)
  {
    cerr << "System exception" << endl;
    cerr << e.what() << endl;

    return APT_INTERNAL_ERROR;
  }

  if(inputstream != &cin)
  {
    ((ifstream*)inputstream)->close();
    delete inputstream;
  }

  if(outputstream != &cout)
  {
    ((ofstream*)outputstream)->close();
    delete outputstream;
  }

  return 0;
}

/* end of file */