Logo Search packages:      
Sourcecode: dbtcp version File versions  Download package

dbftp.c

/*****************************************************************************
DBTCP
(C) 2000 Giussani Cristian
Released under GPL v2
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>

#include <define.h>
#include <dbug/dbug.h>
#include <socket.h>
#include <my_error.h>
#include <my_string.h>
#include <my_array.h>
#include <protocol.h>

#include <readline/readline.h>
#include <readline/history.h>

static int escape_chars=0;
static char *host;
static char *dsn;
static char *dsn2=NULL;
static int port=DBTCP_DEFAULT_PORT;
static char *linea=NULL;
static char hseparator=',';
/******************************************************************************
void print_escaped_string ( char *string )
Print a string delimited by ' and escaping special chars.
 *****************************************************************************/
void print_escaped_string ( char *string )
{
  DBUG_ENTER ( "print_escaped_string" );

  printf ("'");
  while ( *string )
    {
      /* Escape special chars */
      switch ( *string )
      {
      case 0x09:
        printf ( "\\t" );
        break;
        
      case 0x0a:
        printf ( "\\n" );
        break;
        
      case 0x0d:
        printf ( "\\r" );
        break;
        
      case '\'':
        printf ( "\\'" );
        break;
        
      default:
        printf ( "%c", *string );
        break;
      }
      
      string++;
    }
  
  printf ( "'");
  
  DBUG_VOID_RETURN;
  return;
}

/******************************************************************************
void print_escaped_string ( char *string )
Print a string delimited by ';
*****************************************************************************/
void print_string ( char *string )
{
  DBUG_ENTER ( "print_escaped_string" );

  printf ("'");
  while ( *string )
    {
      if ( *string=='\'' )
        printf ( "\\'" );
      else
        {
        printf ( "%c", *string );
      }
      string++;
    }
  
  printf ( "'");
  DBUG_VOID_RETURN;
}

/******************************************************************************
int print_field ( char *string, char type )
 *****************************************************************************/
int print_field ( char *string, char type )
{
  DBUG_ENTER ("print_field" );

  switch ( type )
    {
    case 'N': /* Number */
      printf ( "%s", string );
      break;

    case 'D': /* Date YYYY-MM-GG */
    case 'd': /* Datetime YYYY-MM-GG HH:MM:SS */
      printf ( "'%s'", string );
      break;

    case 'C':
    default:
      if ( escape_chars==1 )
      print_escaped_string ( string );
      else
      print_string ( string );
      break;
    }

  DBUG_RETURN ( OK );
  return ( OK );
}

char *batch_gets ( void )
{
  int strmax=256,idx=0,c;

  if ( linea )
    {
      free ( linea );
      linea=NULL;
    }

  linea=(char *)malloc(strmax+1);
  if ( linea == NULL )
    return ( NULL );

  while ( 1 )
    {
      c = getchar();
      if ( ( c == EOF ) ||
         ( c == CHR_CR ) ||
           ( c == CHR_LF ) )
      {
        if ( idx == 0 )
          {
            return ( NULL );
          }

        linea[idx]=0x00;
        return ( linea );
      }

      linea[idx++]=c;
      if ( idx == strmax )
      {
        char *new;
        strmax += 256;
        new = (char *)malloc (strmax+1);
        if ( new == NULL )
          return ( NULL );
        memcpy ( new, linea, idx );
        free ( linea );
        linea = new;
      }
    }

  return ( linea );
}

/******************************************************************************
int read_defaults ( char **host, char **dsn, int *port )
Read DSN and HOST from ~.dbtcprc
*****************************************************************************/
int read_defaults ( char **host, char **dsn, int *port )
{
  FILE *stream;
  char buffer[256];
  struct passwd *pwd_ptr;
  DBUG_ENTER ( "read_defaults" );

  pwd_ptr = getpwuid( getuid() );
  sprintf ( buffer, "%s/.dbtcprc", pwd_ptr->pw_dir );

  stream=fopen ( buffer,"rb" );
  if ( stream != NULL )
    {
      /* Works only on glibc %as */
      fscanf ( stream, "%as %as %d", host, dsn, port );

      DBUG_RETURN ( OK );
      return ( OK );
    }

  DBUG_RETURN ( ERR );
  return ( ERR );
}

/******************************************************************************
int write_defaults ( char *host, char *dsn, int port )
Write DSN and HOST to ~.dbtcprc
 *****************************************************************************/
int write_defaults ( char *host, char *dsn, int port )
{
  FILE *stream;
  char buffer[256];
  struct passwd *pwd_ptr;
  DBUG_ENTER ( "write_defaults" );

  pwd_ptr = getpwuid( getuid() );
  sprintf ( buffer, "%s/.dbtcprc", pwd_ptr->pw_dir );
 
  stream=fopen( buffer,"w+b" );
  if ( stream != NULL )
    {
      fprintf ( stream, "%s %s %d", host, dsn, port );
      fclose ( stream );
      
      DBUG_RETURN ( OK );
      return ( OK );
    }

  DBUG_RETURN ( ERR );
  return ( ERR );
}

#ifdef USE_READLINE
/******************************************************************************
int my_write_history ( void )
Write history to ~.dbtcp_history
*****************************************************************************/
void my_write_history ( void )
{
  char buffer[256];
  struct passwd *pwd_ptr;
  DBUG_ENTER ( "write_history" );

  pwd_ptr = getpwuid( getuid() );
  sprintf ( buffer, "%s/.dbtcp_history", pwd_ptr->pw_dir );
  write_history ( buffer );

  DBUG_VOID_RETURN;
}

/******************************************************************************
int my_read_history ( void )
Read history from ~.dbtcp_history
******************************************************************************/
void my_read_history ( void )
{
  char buffer[256];
  struct passwd *pwd_ptr;
  DBUG_ENTER ( "write_history" );

  pwd_ptr = getpwuid( getuid() );
  sprintf ( buffer, "%s/.dbtcp_history", pwd_ptr->pw_dir );
  read_history ( buffer );

  DBUG_VOID_RETURN;
}
#else
#define my_write_history()
#define my_read_history()
#endif /* USE_READLINE */

void usage ( void )
{
  printf ( "DBTCP Client\nUsage: dbtcp [OPTION] remote_dsn host [port]\n" );
  printf ( "Options:\n" );
  printf ( "-e\t--escape-chars\tEscape control chars when writing strings.\n" );
  printf ( "-2\t--2dsn=...\tSecond DSN to connect\n" );
  printf ( "-p\t--port=...\tPort number to use for connection.\n" );
  printf ( "-\t--separator=...\tChar separator between columns.\n" );
  printf ( "-h\t--help\tUsage\n" );

  exit ( 2 );
}

#ifdef USE_GETOPTS

#define _GNU_SOURCE
#include <getopt.h>
void parse_args ( int argc, char *argv[] )
{
  int opt,option_index;
  static struct option options[]=
  {
    { "port", 1, 0, 0 },
    { "escape-chars", 0, 0, 0 },
    { "2dsn", 1, 0, 0 },
    { "separator", 1, 0, 0 },
    { "help", 0, 0, 0 },
    { 0,0,0,0 } 
  };

  while ( 1 )
    {
      opt=getopt_long (argc, argv, "e2:hp:s:", options, &option_index);

      if ( opt == -1 )
      break;

      if ( ( opt==':' ) || ( opt=='?' ) )
      usage();

      switch ( opt )
      {
      case 0:
        switch ( option_index )
          {
          case 0: // port
            port=atoi(optarg);
            break;

          case 1: // escape-chars
            escape_chars=1;
            break;

          case 2: // 2 connection
            dsn2=malloc(strlen(optarg)+1);
            if ( dsn2 != NULL )
            strcpy ( dsn2, optarg );
            break;

          case 3:
            hseparator=optarg[0];
            break;

          case 4:
            usage();
          }
        break;

      case '2':
        dsn2=malloc(strlen(optarg)+1);
        if ( dsn2 != NULL )
          strcpy ( dsn2, optarg );
        break;

      case 'e':
        escape_chars=1;
        break;

      case 'h':
        usage();

      case 'p':
        port=atoi(optarg);
        break;

      case 's':
        hseparator=optarg[0];
        break;
      }
    }

  if ( argc == optind )
    {
      /* No arguments */
      if ( read_defaults ( &host, &dsn, &port ) != OK )
        {
          usage();
        }
    }
  else
    {
      if ( ( (argc-optind) != 2 ) && ( (argc-optind) != 3 ) )
      {
        usage();
      }

      dsn=argv[optind];
      host=argv[optind+1];
      if ( (argc-optind) == 3 )
      port=atoi( argv[optind+2] );
    }
}
#endif /* USE_GETOPTS */

/******************************************************************************
MAIN
 *****************************************************************************/
int main ( int argc, char *argv[] )
{
  int connected=0,connected2=0,batch=0;
  dbftp_result *risultati,*res2=NULL;
  char *cptrdmy;

  if (getenv ("DEBUG") != NULL)
    {
      setbuf (stdout, NULL);
      setbuf (stderr, NULL);
      DBUG_PUSH (getenv ("DEBUG"));
    }

#ifdef USE_GETOPTS
  parse_args ( argc, argv );
#else
  if ( argc == 4 )
    {
      dsn=argv[1];
      host=argv[2];
      port = atoi ( argv[3] );
    }
  else
    {
      if ( argc == 3 )
        {
        dsn=argv[1];
        host=argv[2];
          port = DBTCP_DEFAULT_PORT;
        }
      else
        {
        if ( read_defaults ( &host, &dsn, &port ) != OK )
          {
            usage();
          }
        }
    }
#endif


  /* TTY ? */
  if ( isatty( fileno(stdin) ) )
    {
      batch=0;
      my_read_history();
      printf ( "DSN='%s' host=%s:%d\n", dsn, host, port );
    }
  else
    {
      batch=1;
    }

  write_defaults ( host, dsn, port );
  risultati=init_dbftp_result();

  if ( risultati != NULL )
    {
      if ( dbftp_connect ( risultati, host, port, dsn ) == OK )
      {
        if ( dsn2 != NULL )
          {
            res2=init_dbftp_result();

            if ( res2 != NULL )
            {
              if ( dbftp_connect ( res2, host, port, dsn2 ) == OK )
                {
                  connected2=1;
                }
            }
          }
                
        connected=1;
        if ( batch == 0 )
          {
            if ( connected2 != 0 )
            {
              printf ( "Secondary connection to %s done\n", dsn2 );
            }

            printf ( "Connected to %s\nUse CTRL-D to exit\n", dsn );
          }
      }
      else
      {
        fprintf ( stderr, "CONNECT ERROR: %s\n", dbftp_error_string ( risultati ) );
        exit ( 2 );
      }
      
      while ( connected==1 )
        {
        if ( batch == 0 )
          {
#ifdef USE_READLINE
            linea = readline ( "dbtcp>" );
            if ( linea == NULL )
            {
              connected=0;
              break;
            }
            else
            {
              /* Salva nella history solo se non e' vuota */
              if ( *linea )
                add_history( linea );
            }
#else
              printf ( "dbtcp>" );
              if ( batch_gets() == NULL )
                {
                  connected=0;
                  break;
                }
#endif
          }
        else
          {
            if ( batch_gets() == NULL )
            {
              connected=0;
              break;
            }
          }

        /* --------------------------------------------------------- Query */
        if ( dbftp_sql ( risultati, linea ) == OK )
          {
            int idmy,rec_num=0;
           /* 
            for ( idmy=0; idmy<dbftp_num_field(risultati); idmy++ )
            {
              printf ( "COL %d: '%s' (length %d - type %c)\n",idmy , dbftp_field_name(risultati,idmy)
                     , dbftp_field_len(risultati,idmy)
                     , dbftp_field_type(risultati,idmy) );
                     }
            */
            /* ----------------------- Riceve tutti i dati della query */
            while ( 1 )
            {
              if ( dbftp_fetch_row ( risultati ) != OK )
                break;
              
              for ( idmy=0; idmy < dbftp_num_field(risultati); idmy++ )
                {
                  cptrdmy=dbftp_fetch_value ( risultati, idmy );
                  if ( cptrdmy != NULL )
                  {
                    print_field ( dbftp_fetch_value(risultati, idmy), dbftp_field_type(risultati, idmy ) );
                  }
                  else
                  {
                    printf ( "NULL" );
                  }

                  if ( idmy == ( dbftp_num_field(risultati)-1 ) )
                            printf( "\n" );
                          else
                            printf( "%c",hseparator );
 
                }
              rec_num++;
            }

            if ( batch == 0 )
            printf ( "Rows: %d\n", rec_num );
            
          }
        else
          {
            fprintf ( stderr, "ERROR: %s\n", dbftp_error_string ( risultati ) );
          }
        free ( linea );
        linea = NULL;
      }
      
      dbftp_close ( risultati );
      if ( res2 != NULL )
      dbftp_close ( res2 );

    }

  my_write_history();
  exit ( 0 );
}

Generated by  Doxygen 1.6.0   Back to index