/*

  ssh-probe2.c

  Authors:
        Timo J. Rinne <tri@ssh.com>

  Copyright (C) 1999-2000 SSH Communications Security Corp, Helsinki, Finland
  All rights reserved.

*/

#include "ssh2includes.h"
#include "ssheloop.h"
#include "sshtimeouts.h"
#include "sshtcp.h"
#include "sshudp.h"
#include "sshbuffer.h"
#include "sshserver.h"
#include "sshencode.h"
#include "sshgetopt.h"
#include "sshserverprobe.h"

#define SSH_DEBUG_MODULE "SshProbe"


const char *av0;

typedef struct SshProbeRec *SshProbe;

struct SshProbeRec {
  Boolean readable;
  Boolean silent;
  int responses;
};

void probe_reply_callback(const char *address,
                          const char *port,
                          const char *version,
                          void *context)
{
  SshProbe probe = (SshProbe)context;

  if (address == NULL)
    {
      ssh_event_loop_abort();
      return;
    }
  if (! probe->silent)
    {
      if (probe->readable)
        {
          printf("Server address = \"%s\"\n", address);
          printf("Server port = \"%s\"\n", port);
          printf("Server version = \"%s\"\n", version);
        }
      else
        {
          printf("%s:%s:%s\n", address, port, version);
        }
    }
  probe->responses++;
  return;
}

int main(int argc, char **argv)
{
  SshProbe probe;
  int opt, i, timeout;

  /* Save program name. */
  if (strchr(argv[0], '/'))
    av0 = strrchr(argv[0], '/') + 1;
  else
    av0 = argv[0];

  ssh_event_loop_initialize();

  probe = ssh_xcalloc(1, sizeof (*probe));
  timeout = 1;

  while ((opt = ssh_getopt(argc, argv, "t:rsd:", NULL)) != -1)
    {
      switch (opt)
        {
        case 't':
          if (ssh_optargnum && (ssh_optargval > 0))
            timeout = ssh_optargval;
          else
            ssh_warning("illegal timeout value ignored");
          break;

        case 'r':
          probe->readable = TRUE;
          break;

        case 's':
          probe->silent = TRUE;
          break;

        case 'd':
          ssh_debug_set_level_string(ssh_optarg);
          break;

        default:
          fprintf(stderr, "%s: unknown option '%c'.\n", av0, ssh_optopt);
          exit(-1);
        }
    }

  if (ssh_optind >= argc)
    {
      fprintf(stderr, "%s: No broadcast addresses given.\n", av0);
      exit(-1);
    }
  for (i = ssh_optind; i < argc; i++)
    {
      ssh_server_probe(argv[i],
                       (long)timeout,
                       0L,
                       probe_reply_callback,
                       probe);

    }
  ssh_event_loop_run();
  SSH_DEBUG(5, ("event loop aborts."));
  ssh_event_loop_uninitialize();
  if ((! probe->silent) && probe->readable)
    {
      switch (probe->responses)
        {
        case 0:
          printf("No servers detected.\n");
          break;
          
        case 1:
          printf("One server detected.\n");
          break;
          
        default:
          printf("%d servers detected.\n", probe->responses);
          break;
        }
    }
  exit((probe->responses > 0) ? 0 : 1);
}

/* eof (sshprobe.c) */
