/*-GNU-GPL-BEGIN-*
nepim - network pipemeter
Copyright (C) 2005 Everton da Silva Marques

nepim 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, or (at your option)
any later version.

nepim 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 nepim; see the file COPYING.  If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*-GNU-GPL-END-*/


/* $Id: greet.c,v 1.8 2005/10/13 19:57:39 evertonm Exp $ */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "conf.h"
#include "greet.h"
#include "common.h"

const char *GREET_SERVER_SEND       = "server_send=";
const char *GREET_BIT_RATE          = "bit_rate=";
const char *GREET_PKT_RATE          = "pkt_rate=";
const char *GREET_STAT_INTERVAL     = "stat_interval=";
const char *GREET_TEST_DURATION     = "test_duration=";
const char *GREET_WRITE_DELAY       = "write_delay=";
const char *GREET_SERVER_KA_SEND    = "server_ka_send=";
const char *GREET_SERVER_KA_REQUIRE = "server_ka_req=";
const char *GREET_PASSWORD          = "password=";

#define NEPIM_GREET_PARSE_OK     (0)
#define NEPIM_GREET_PARSE_FTOKEN (-1)
#define NEPIM_GREET_PARSE_HELLO  (-2)

#define NEPIM_GREET_WRITE_OK       (0)
#define NEPIM_GREET_WRITE_IO       (-1)
#define NEPIM_GREET_WRITE_OVERFLOW (-2)

int nepim_write_greetings(const nepim_greet_t *opt, char *buf, int buf_size)
{
  int pr;

  assert(opt->password_buf);
  assert(opt->password_buf_size > 0);
  assert(memchr(opt->password_buf, '\0', opt->password_buf_size));
  assert(strlen(opt->password_buf) >= 0);
  assert(strlen(opt->password_buf) < opt->password_buf_size);

  pr = snprintf(buf, buf_size,
		"hello %s%d %s%lld "
		"%s%d %s%d %s%d "
		"%s%ld %s%d %s%d %s%s\n", 
		GREET_SERVER_SEND,       opt->must_send,
		GREET_BIT_RATE,          opt->bit_rate,
		GREET_PKT_RATE,          opt->pkt_rate,
		GREET_STAT_INTERVAL,     opt->stat_interval,
		GREET_TEST_DURATION,     opt->test_duration,
		GREET_WRITE_DELAY,       opt->write_delay,
		GREET_SERVER_KA_SEND,    opt->udp_keepalive_send,
		GREET_SERVER_KA_REQUIRE, opt->udp_keepalive_require,
		GREET_PASSWORD,          opt->password_buf);

  if (pr < 1)
    return NEPIM_GREET_WRITE_IO;
  if (pr >= buf_size)
    return NEPIM_GREET_WRITE_OVERFLOW;

  assert(pr > 0);
  assert(pr < buf_size);

  return pr;
}

int nepim_parse_greetings(nepim_greet_t *opt, 
			  const char *buf, const char *past_end)
{
  char tmp[past_end - buf + 1];
  const char *SEP = " ";
  const char *tok;
  char *ptr;

  const int GREET_SERVER_SEND_LEN       = strlen(GREET_SERVER_SEND);
  const int GREET_BIT_RATE_LEN          = strlen(GREET_BIT_RATE);
  const int GREET_PKT_RATE_LEN          = strlen(GREET_PKT_RATE);
  const int GREET_STAT_INTERVAL_LEN     = strlen(GREET_STAT_INTERVAL);
  const int GREET_TEST_DURATION_LEN     = strlen(GREET_TEST_DURATION);
  const int GREET_WRITE_DELAY_LEN       = strlen(GREET_WRITE_DELAY);
  const int GREET_SERVER_KA_SEND_LEN    = strlen(GREET_SERVER_KA_SEND);
  const int GREET_SERVER_KA_REQUIRE_LEN = strlen(GREET_SERVER_KA_REQUIRE);
  const int GREET_PASSWORD_LEN          = strlen(GREET_PASSWORD);

  int server_send       = -2;
  long long bit_rate    = -2;
  int pkt_rate          = -2;
  int stat_interval     = -2;
  int test_duration     = -2;
  long write_delay      = -2;
  int server_ka_send    = -2;
  int server_ka_require = -2;

  assert(opt->password_buf);
  assert(opt->password_buf_size > 0);
  *opt->password_buf = '\0';

  memcpy(tmp, buf, past_end - buf + 1);

  tok = strtok_r(tmp, SEP, &ptr);

  if (!tok)
    return NEPIM_GREET_PARSE_FTOKEN;

  if (strncmp(tok, "hello", 5))
    return NEPIM_GREET_PARSE_HELLO;

  for (;;) {
    tok = strtok_r(0, SEP, &ptr);
    if (!tok)
      break;

    if (!strncmp(tok, GREET_SERVER_SEND, GREET_SERVER_SEND_LEN)) {
      server_send = atoi(tok + GREET_SERVER_SEND_LEN);
      continue;
    }

    if (!strncmp(tok, GREET_BIT_RATE, GREET_BIT_RATE_LEN)) {
      bit_rate = strtoll(tok + GREET_BIT_RATE_LEN, 0, 10);
      continue;
    }

    if (!strncmp(tok, GREET_PKT_RATE, GREET_PKT_RATE_LEN)) {
      pkt_rate = strtoll(tok + GREET_PKT_RATE_LEN, 0, 10);
      continue;
    }

    if (!strncmp(tok, GREET_STAT_INTERVAL, GREET_STAT_INTERVAL_LEN)) {
      stat_interval = atoi(tok + GREET_STAT_INTERVAL_LEN);
      continue;
    }

    if (!strncmp(tok, GREET_TEST_DURATION, GREET_TEST_DURATION_LEN)) {
      test_duration = atoi(tok + GREET_TEST_DURATION_LEN);
      continue;
    }

    if (!strncmp(tok, GREET_WRITE_DELAY, GREET_WRITE_DELAY_LEN)) {
      write_delay = atoi(tok + GREET_WRITE_DELAY_LEN);
      continue;
    }

    if (!strncmp(tok, GREET_SERVER_KA_SEND, GREET_SERVER_KA_SEND_LEN)) {
      server_ka_send = atoi(tok + GREET_SERVER_KA_SEND_LEN);
      continue;
    }

    if (!strncmp(tok, GREET_SERVER_KA_REQUIRE, GREET_SERVER_KA_REQUIRE_LEN)) {
      server_ka_require = atoi(tok + GREET_SERVER_KA_REQUIRE_LEN);
      continue;
    }

    if (!strncmp(tok, GREET_PASSWORD, GREET_PASSWORD_LEN)) {
      const char *tmp_past_end = tmp + sizeof(tmp);
      const char *pass;
      const char *end;
      int pass_len;
      int rem;

      pass = tok + GREET_PASSWORD_LEN;
      rem = tmp_past_end - pass;
      end = memchr(pass, ' ', rem);
      if (!end)
	end = memchr(pass, '\0', rem);
      if (!end)
	end = tmp_past_end;
      
      pass_len = NEPIM_MIN(opt->password_buf_size - 1, end - pass);

      assert(pass_len >= 0);
      assert(pass_len < opt->password_buf_size);

      memcpy(opt->password_buf, pass, pass_len);
      opt->password_buf[pass_len] = '\0';

      assert(memchr(opt->password_buf, '\0', opt->password_buf_size));
      assert(strlen(opt->password_buf) >= 0);
      assert(strlen(opt->password_buf) < opt->password_buf_size);
      assert(strlen(opt->password_buf) == pass_len);

      continue;
    }

    fprintf(stderr, "%s %s: unknown greeting parameter: '%s'\n",
	    __FILE__, __PRETTY_FUNCTION__, tok);
  }

  assert(memchr(opt->password_buf, '\0', opt->password_buf_size));
  assert(strlen(opt->password_buf) >= 0);
  assert(strlen(opt->password_buf) < opt->password_buf_size);

  if (write_delay < 0)
    write_delay = nepim_global.write_delay;

  opt->must_send             = server_send;
  opt->bit_rate              = bit_rate;
  opt->pkt_rate              = pkt_rate;
  opt->stat_interval         = stat_interval;
  opt->test_duration         = test_duration;
  opt->write_delay           = write_delay;
  opt->udp_keepalive_send    = server_ka_send;
  opt->udp_keepalive_require = server_ka_require;

  return NEPIM_GREET_PARSE_OK;
}


syntax highlighted by Code2HTML, v. 0.9.1