/* ANSI */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>


/* Amiga */
#include <exec/types.h>

#include "protocol.h"
#include "hard.h"
#include "packet.h"

#include "list.h"
#include "config.h"



/*#define TI89_MAXTYPES 48
const char *TI89_TYPES[TI89_MAXTYPES]=
{
"EXPR", "UNKNOWN", "UNKNOWN", "UNKNOWN", "LIST", "UNKNOWN", "MAT", "UNKNOWN",
"UNKNOW", "UNKNOWN", "DATA", "TEXT", "STR", "GDB", "FIG", "UNKNOWN",
"PIC", "UNKNOWN", "PRGM", "FUNC", "MAC", "UNKNOWN", "UNKNOWN", "UNKNOWN",
"UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "BACKUP", "UNKNOWN", "DIR",
"ASM", "UNKNOWN", "IDLIST", "UNKNOWN", "FLASH", "UNKNOWN", "LOCKED", "ARCHIVED",
"UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"
};
*/


struct List_Content
{
  ULONG file_offset;
  char name[MAX_NAMELENGTH+1];
  char foldername[MAX_NAMELENGTH+1];
  char type;
};



char filetypes[] = "e---l-m---ctsda-i-pfx---h----b-g-z---------------r";


int ti_analysedir(Packet *packet, ti_variable *vars, char filter);

int ti_sendvardata(FILE *fptr, char *folder, char *name, char type);
void ti_writefileheader(FILE *fptr, char *defaultfolder, char *comment, int nb_vars);
void ti_writevarheader(FILE *fptr, char *name, int type, long int offset);
int ti_downloadvar(char *complete_varpath, Packet *data_packet, ti_variable *var);


/// int ti_ping(int nb)
int ti_ping(int nb)
{
  UBYTE hello[]={0x08,0x68,0x00,0x00};
  Packet packet;
  int cpt;

  ti_initpacket(&packet);

  for ( cpt=1; cpt<=nb;cpt++ )
  {
#ifdef DEBUG
		printf(HERE"ping %d\n",cpt);
#endif
		if ( ti_sendbytes(hello,sizeof(hello)) == 0 )
      if ( ti_getpacket(&packet) == 0 )
        return(TI_OK);

  }

  ti_freepacket(&packet);
  return(TI_TIMEOUT);
}
///

/// int ti_analysedir(Packet *packet, ti_variable *vars, char filter)
int ti_analysedir(Packet *packet, ti_variable *vars, char filter)
/*
if filter == 'v', remove any non-variable entry
if filter == 'f', remove any non-folder entry
*/
{
  int cpt, nbvar=0;
  unsigned int index=0;

  if ( packet->command != COMMAND_DATA )
    return(TI_PROTOCOL);

  for ( cpt=0; cpt<4; cpt++ )
  {
    if ( packet->bytes[index++] != 0 )
      return(TI_PROTOCOL);
  }

  while ( index < packet->nb )
  {

    for ( cpt=0; cpt<MAX_NAMELENGTH; cpt++ )
      vars[nbvar].name[cpt] = packet->bytes[index++];

    vars[nbvar].name[MAX_NAMELENGTH] = 0;

#ifdef DEBUG
		printf(HERE"Var %d\n",nbvar);
		printf(HERE" * Name : %s\n",vars[nbvar].name);
#endif

    vars[nbvar].type = packet->bytes[index++];
#ifdef DEBUG
		printf(HERE" * Type : %d \n",vars[nbvar].type);
#endif
		vars[nbvar].state= packet->bytes[index++];
    vars[nbvar].size = 0;

    for ( cpt=0; cpt<3; cpt++ )
    { /* Get size on 3 bytes */
      vars[nbvar].size += ( (packet->bytes[index++] ) << (8*cpt) );
    }
		index++; /* Skip one byte, unknown use */


		switch ( filter )
		{
			case 'v':
			case 'V':
				if ( ti_isvariable(vars[nbvar].type ) )
		      nbvar++;
				break;
			case 'f':
			case 'F':
				if ( vars[nbvar].type == TI_TYPE_FOLDER )
		      nbvar++;
				break;
			default:
				nbvar++;
		}
  }

  return(nbvar);
}
///

/// int ti_listdir(char *foldname, ti_variable *vars)
int ti_listdir(char *foldname, ti_variable *vars)
{
  UBYTE ldir_sfx[]={0x00,0x00,0x00,0x1B,0x1A};
  Packet packet;
  UBYTE *ldir;
  UBYTE ok[]={0x08,0x56,0x00,0x00};
  UBYTE waiting[]={0x08,0x09,0x00,0x00};

  unsigned int cpt;
  int nb;

  /*printf(HERE"listing %s\n",foldname);*/

  ldir = calloc(sizeof(ldir_sfx)+strlen(foldname)+1,sizeof(UBYTE));

  for ( cpt=0; cpt<sizeof(ldir_sfx); cpt++)
    ldir[cpt] = ldir_sfx[cpt];


  ldir[sizeof(ldir_sfx)] = strlen(foldname);

  for ( cpt=0; cpt<strlen(foldname); cpt++)
    ldir[sizeof(ldir_sfx)+cpt+1]=foldname[cpt];


  ti_initpacket(&packet);
  packet.command = 0xA2;
  ti_cp2packet(&packet,sizeof(ldir_sfx)+strlen(foldname)+1,ldir);


  if ( ti_sendpacket(&packet) )
  {
    ti_freepacket(&packet);
    return(TI_TIMEOUT);
  }


  if (
    ti_getpacket(&packet) ||
    ti_getpacket(&packet) ||
    ti_sendbytes(ok,sizeof(ok)) ||
    ti_sendbytes(waiting,sizeof(waiting)) ||
    ti_getpacket(&packet) ||
    ti_getpacket(&packet) )
  {
      ti_freepacket(&packet);
      return(TI_TIMEOUT);
  }


	nb = ti_analysedir(&packet,vars,'v');

  ti_sendbytes(ok,sizeof(ok));
  ti_getpacket(&packet);
  ti_sendbytes(ok,sizeof(ok));

  free(ldir);

  ti_freepacket(&packet);
  return(nb);
}
///

/// int ti_folderlist(ti_variable *vars)
int ti_folderlist(ti_variable *vars)
{
  Packet packet;
  UBYTE dir[]={0x00,0x00,0x00,0x1F,0x1A,0x00};
  UBYTE ok[]={0x08,0x56,0x00,0x00};
  UBYTE waiting[]={0x08,0x09,0x00,0x00};
  int nb;

  if ( ti_ping(3) != TI_OK )
    return(TI_PING);

  ti_initpacket(&packet);
  packet.command = 0xA2;
  ti_cp2packet(&packet,sizeof(dir),dir);

  if (  ti_sendpacket(&packet)||
        ti_getpacket(&packet) || /* Skip OK */
        ti_getpacket(&packet) || /* Skip ??? */
        ti_sendbytes(ok,sizeof(ok)) || /* OK... */
        ti_sendbytes(waiting,sizeof(waiting)) || /* ... waiting for data */
        ti_getpacket(&packet) || /* Skip OK */
        ti_getpacket(&packet) ) /* Get listing */
  {
    ti_freepacket(&packet);
    return(TI_TIMEOUT);
  }

	nb = ti_analysedir(&packet,vars,'f'); /* Analyse it */

  if (  nb < 0 ||
        ti_sendbytes(ok,sizeof(ok)) || /* OK for data  */
        ti_getpacket(&packet) ||  /* Skip EOT */
        ti_sendbytes(ok,sizeof(ok)) ) /* OK */
  {
    ti_freepacket(&packet);
    if ( nb < 0 )  return(nb);
    return(TI_TIMEOUT);
  }

  ti_freepacket(&packet);

  return(nb);

}
///

/// int ti_sendfile(char *filename, char *userfolder)
int ti_sendfile(char *filename, char *userfolder)
{
  char folder[MAX_NAMELENGTH+1];
  int nb_entries;

  FILE *fptr;

  if ( ti_ping(3) != TI_OK )
    return(TI_PING);

  if ((fptr = fopen (filename, "rb")) == NULL )
    return(TI_FILE);

#ifdef DEBUG
	printf(HERE"Sending %s\n",filename);
#endif

  {
    char header[9];
    if ( fread(header,1,8,fptr) != 8 ) /* Read header */
      return(TI_BADFORMAT);
  }


  fgetc(fptr); /* Skip 01 */
  fgetc(fptr); /* Skip 00 */

  if ( fread(folder,1,MAX_NAMELENGTH,fptr) != 8 )
  {
#ifdef DEBUG
    printf(HERE"Cannot read foldername ! \n");
#endif
		return(TI_BADFORMAT);
  }
  folder[MAX_NAMELENGTH]=0;


  {
    char comment[41];
    if ( fread(comment,1,sizeof(comment)-1,fptr) != sizeof(comment)-1 )
      return(TI_BADFORMAT);
  }


  nb_entries  = fgetc(fptr);
  nb_entries += (fgetc(fptr)<<8);

  /*if ( feof(fptr) )
    return(TI_BADFORMAT);*/

  if ( userfolder[0] ) /* Override default folder with user defined folder */
    strncpy(folder,userfolder,MAX_NAMELENGTH);




  { /* Get variables informations */
    int entry;
    ULONG offset;
    char name[MAX_NAMELENGTH+1];
    char type;


    for ( entry=1; entry <= nb_entries ; entry++ )
    {
      int temp;

      offset = fgetc(fptr);
      offset += fgetc(fptr)<<8;
      offset += fgetc(fptr)<<16;
      offset += fgetc(fptr)<<24;

      if ( (temp=fread(name,1,MAX_NAMELENGTH,fptr)) != MAX_NAMELENGTH )
      {
#ifdef DEBUG
				printf(HERE"Unable to read name (%d/%d) %d\n",temp,MAX_NAMELENGTH,feof(fptr));
#endif
				return(TI_BADFORMAT);
      }

      name[MAX_NAMELENGTH] = 0;

      type = fgetc(fptr);
			//printf(HERE"name(%d) : >%s<\n",entry,name);
      //printf(HERE"offset   : %x\n",offset);
      //printf(HERE"type     : %x\n",type);
      fgetc(fptr);

      fgetc(fptr); /* Skip 0's */
      fgetc(fptr);

      if ( type != 0x1F )
      {
        long backup_offset = ftell(fptr);
				//printf(HERE" Jumping to %x\n",(unsigned int)offset);
        if ( fseek(fptr,offset, SEEK_SET) )
          return(TI_BADFORMAT);

        {
          int ret;
					//printf("sending %s\n",name);
          if ( (ret=ti_sendvardata(fptr,folder,name, type)) )
					{
						fclose(fptr);
            return(ret);
					}
        }

        //printf(HERE"back to %x\n",backup_offset);
        if ( fseek(fptr,backup_offset, SEEK_SET) )
          return(TI_BADFORMAT);
      }
      else /* folder info */
      if ( userfolder[0] == '\0' )
      {
        //printf(HERE"information supp : folder = <%s>\n",name);
        strncpy(folder,name,MAX_NAMELENGTH);
        folder[MAX_NAMELENGTH] = 0;
      }


    }
  }

  /*system("date");*/
  fclose(fptr);

  return(TI_OK);
}
///

/// int ti_sendvardata(FILE *fptr, char *folder, char *name, char type)
int ti_sendvardata(FILE *fptr, char *folder, char *name, char type)
{

  unsigned short int size;
  UBYTE *buffer;
  UBYTE ok[]={0x08,0x56,0x00,0x00};
  UBYTE eot[]={0x08,0x92,0x00,0x00};
  char fullname[200];
  UBYTE dummy;

  if ( fgetc(fptr)||fgetc(fptr)||fgetc(fptr)||fgetc(fptr) )
  {
    /*printf(HERE"pas à 0 ! \n");
    return(1);*/
  }

  size = (fgetc(fptr)<<8) + fgetc(fptr);

  if ( feof(fptr) || size == 0 )
  {
#ifdef DEBUG
		printf(HERE"Error : EOF size=%d\n",size);
#endif
    return(TI_BADFORMAT);
  }


  buffer = calloc (size,sizeof(UBYTE));

  if ( fread (buffer,sizeof(UBYTE),size,fptr) != size )
  {
#ifdef DEBUG
    printf(HERE"Could not read %d(%x) bytes in file.\n",size,size);
#endif
		free(buffer);
    return(TI_BADFORMAT);
  }

	sprintf(fullname,"%s\\%s",folder,name);



  {
    UBYTE *varhead;
    int index=0;
    unsigned int cpt;
    Packet packet;


    if ( ! ( varhead = calloc(7+strlen(fullname),sizeof(UBYTE)) ) )
      return(TI_MEMORY);

    varhead[index++] = (size+2) & 0xFF;
    varhead[index++] = (size+2) >> 8;
    varhead[index++] = 0;
    varhead[index++] = 0;

    varhead[index++] = type;
    varhead[index++] = strlen(fullname);

    for ( cpt=0; cpt<strlen(fullname); cpt++ )
      varhead[index++] = fullname[cpt];

    varhead[index++] = 0;

    ti_initpacket(&packet);
    packet.command = 0x06;
    ti_cp2packet(&packet,index,varhead);

    if ( ti_sendpacket(&packet) )
    {
      ti_freepacket(&packet);
      return(TI_TIMEOUT);
    }

    if ( ti_getpacket(&packet) ||   /* Skip OK */
         ti_getpacket(&packet) || /* Skip Wait */
         ti_sendbytes(ok,sizeof(ok)) )
    {
      ti_freepacket(&packet);
      return(TI_TIMEOUT);
    }

    ti_freepacket(&packet);
    free(varhead);
  }

  {
    UBYTE *data;
    int cpt,index=0;
    Packet packet;

    if ( ! ( data = calloc(6+size,sizeof(UBYTE)) ) )
      return(TI_MEMORY);

    for ( cpt=0; cpt<4; cpt++ )
      data[index++] = 0;

    data[index++] = size>>8;
    data[index++] = size&0xFF;

    for ( cpt=0; cpt<size; cpt++ )
      data[index++] = buffer[cpt];

    ti_initpacket(&packet);
    packet.command = 0x15;
    ti_cp2packet(&packet,6+size,data);

    ti_sendpacket(&packet);
    ti_freepacket(&packet);

    {
      if (
        ti_recvbyte(&dummy) ||
        ti_recvbyte(&dummy) ||
        ti_recvbyte(&dummy) ||
        ti_recvbyte(&dummy) ) /* Skip OK */
          return(TI_TIMEOUT);
    }

    if ( ti_sendbytes(eot,sizeof(eot)) )
      return(TI_TIMEOUT);

    {
      if (
        ti_recvbyte(&dummy) || /* Skip OK */
        ti_recvbyte(&dummy) || /* Skip OK */
        ti_recvbyte(&dummy) || /* Skip OK */
        ti_recvbyte(&dummy) ) /* Skip OK */
          return(TI_TIMEOUT);
		}

    free(data);
  }

  free(buffer);

  return(TI_OK);
}
///

/// void ti_writefileheader(FILE *fptr, char *defaultfolder, char *comment, int nb_vars)
void ti_writefileheader(FILE *fptr, char *defaultfolder, char *comment, int nb_vars)
{
	char header[]={'*','*','T','I','9','2','P','*','\1','\0'};

  unsigned int cpt;

  for ( cpt=0; cpt<sizeof(header); cpt++) /* Write header */
    fputc(header[cpt],fptr);

  { /* Write folder */
    int flag=0;
    for ( cpt=0; cpt<8; cpt++ ) /* TODO : remove explicit constants */
    {
      if ( ! flag )
        if ( defaultfolder[cpt] == '\0' )
          flag = 1;

      if ( flag )
        fputc('\0' ,fptr);
      else
        fputc(defaultfolder[cpt],fptr);
    }
  }

  { /* Write comment */
    int flag=0;
    for ( cpt=0; cpt<40; cpt++ ) /* TODO : remove explicit constants */
    {
      if ( ! flag )
        if ( comment[cpt] == '\0' )
          flag = 1;

      if ( flag )
        fputc(' ',fptr);
      else
        fputc(comment[cpt],fptr);
    }
  }

  fputc(nb_vars & 0xFF, fptr); /* write nb of vars */
  fputc((nb_vars >> 8)&0xFF, fptr);
}
///

/// void ti_writevarheader(FILE *fptr, char *name, int type, long int offset)
void ti_writevarheader(FILE *fptr, char *name, int type, long int offset)
{

  fputc(offset&0xFF,fptr);
  fputc((offset>>8)&0xFF,fptr);
  fputc((offset>>16)&0xFF,fptr);
  fputc((offset>>24)&0xFF,fptr);


  { /* Write name */
    int flag=0;
    int  cpt;

    for ( cpt=0; cpt<8; cpt++ ) /* TODO : remove explicit constants */
    {
      if ( ! flag )
        if ( name[cpt] == '\0' )
          flag = 1;

      if ( flag )
        fputc('\0' ,fptr);
      else
        fputc(name[cpt],fptr);
    }
  }

  fputc(type&0xFF,fptr);
  fputc((type>>8)&0xFF,fptr);

  fputc(0,fptr);
  fputc(0,fptr);
}
///

/// int ti_getvar(char *foldername, char *varname, char *filename)
int ti_getvar(char *foldername, char *varname, char *filename)
{
  Packet packet;
  //UBYTE ok[]={0x08,0x56,0x00,0x00};
  FILE *fptr;
  unsigned int cpt;

  char complete_varpath[17];

  if ( ti_ping(3) != TI_OK )
    return(TI_PING);

  if ( foldername[0] == '\0' ) // no folder specified
    foldername = "main";


  if ((fptr = fopen (filename, "wb")) == NULL )
  {
#ifdef DEBUG
    printf(HERE"error opening %s\n",filename);
#endif
		return(TI_FILE);
  }

  if ( foldername[0] )
		sprintf(complete_varpath,"%s\\%s",foldername,varname);

  //printf(HERE"getting %s\n",complete_varpath);



  ti_initpacket(&packet);
  {
    int ret;
    if ( (ret=ti_downloadvar(complete_varpath, &packet, NULL) ) )
    {
      ti_freepacket(&packet);
			fclose(fptr);
      return(ret);
    }
  }

  ti_writefileheader(fptr,"main","",1);
  ti_writevarheader(fptr,varname,0x12,0x52);


  /*sprintf(HEREfilename,"%s.89%c",varname,filetypes[*//**/

  {
    int index;
    for ( index = 0; index < 4 ; index ++ )
    {
      fputc(((0x52+2+packet.nb)>>(index*8))&0xFF,fptr);;
      /*printf(HERE"%x ",head.length[index]);*/
    }
  }

  fputc(0xA5,fptr);
  fputc(0x5A,fptr);
  fputc(0x00,fptr);
  fputc(0x00,fptr);
  fputc(0x00,fptr);
  fputc(0x00,fptr);


  fputc((packet.nb-6)>>8,fptr);
  fputc((packet.nb-6)&0xFF,fptr);



  for ( cpt = 6; cpt < packet.nb ; cpt ++ )
    fputc(packet.bytes[cpt],fptr);

  fputc(0x00,fptr); /* should be checksum */
  fputc(0x00,fptr);

  fclose(fptr);

  ti_freepacket(&packet);

  return(TI_OK);
}
///

/// int ti_getfolder(char *foldername, char *filename)
int ti_getfolder(char *foldername, char *filename)
/*
Download one or all folders
*/
{
  //UBYTE ok[]={0x08,0x56,0x00,0x00};
  FILE *fptr;
	int var, nb_vars, folder,nb_folders;

  unsigned long int buffer_index=0,buffer_size=0;
  char *buffer;

	ti_variable folders[MAX_NBNAME];
	ti_variable vars[MAX_NBNAME];

	Packet packet;
	unsigned long int file_offset;


  char complete_varpath[17];

  if ( ti_ping(3) != TI_OK )
    return(TI_PING);

	/* Init. the "folders" array */
	if ( foldername == NULL||foldername[0] == '\0' ) // no folder specified
	{
		nb_folders =ti_folderlist(folders);
	}
	else
	{
		nb_folders = 1;
		strcpy(folders[0].name,foldername);
		//printf(HERE"  Getting folder %s\n",foldername);
	}



  if ((fptr = fopen (filename, "wb")) == NULL )
  {
#ifdef DEBUG
    printf(HERE"error opening %s\n",filename);
#endif
		return(TI_FILE);
  }



	buffer_size = 0;
	buffer  = NULL;

	nb_vars = 0;

	for ( folder = 0; folder<nb_folders; folder++ )
	{
		int nb_vars_this;


		//printf(HERE" Folder %s\n",folders[folder].name);

		
		if ( (nb_vars_this = ti_listdir(folders[folder].name, vars)) < 0 )
	  {
	    fclose(fptr);
	    return(TI_PROTOCOL);
		}
		//printf(HERE" nb vars of %s : %d\n",folders[folder].name,nb_vars_this);
		
		/* Get the nb of vars required by this folder :
			 one for the folder, nb_vars_this for its variables */

		
	for ( var=0 ; var<nb_vars_this ; var ++)
		buffer_size += (vars[var].size+8);
		
		nb_vars += ( 1 + nb_vars_this );
    /* In the data part of the file, we found, for each var :
        4     :  zeros
        2     :  length
        length:  variable data
        2     :  checksum
    */
	}

	//printf(HERE" buffer size : %ld\n",buffer_size);
	if ( (buffer = malloc(buffer_size)) == NULL )
	{
		fclose(fptr);
		return(TI_MEMORY );
	}

	ti_writefileheader(fptr,"","",nb_vars);

	ti_initpacket(&packet);

	file_offset=ftell(fptr)+2+16*nb_vars;


	for ( folder = 0; folder<nb_folders; folder ++)
	{
		int nb_vars_this;

		if ( ti_ping(3) == TI_TIMEOUT )
			return(TI_TIMEOUT);

		nb_vars_this = ti_listdir(folders[folder].name, vars);
		
		//printf(HERE" Downloading %s : %d vars\n",folders[folder].name,nb_vars_this);

		/* Write folder info */
		ti_writevarheader(fptr,folders[folder].name,TI_TYPE_FOLDER,file_offset);

		for ( var=0 ; var<nb_vars_this ; var ++)
    {
      int ret;
      unsigned long int cpt;

			sprintf(complete_varpath,"%s\\%s",folders[folder].name,vars[var].name);

			//printf(HERE"getting %s  type=%d...\n",complete_varpath,vars[var].type);

			if ( ! ti_isvariable(vars[var].type ) )
				continue; /* Not a variable, skip it */

      ti_writevarheader(fptr,vars[var].name,vars[var].type,file_offset);
      file_offset += (vars[var].size+6);


      if ( ti_ping(3) != TI_OK )
      {
        ti_freepacket(&packet);
        fclose(fptr);
        free(buffer);
        return(TI_PING);
      }

      if ( (ret=ti_downloadvar(complete_varpath, &packet,&(vars[var]) ) ) )
      {
#ifdef DEBUG
        printf(HERE"Error downloading var (%d)\n",ret);
#endif
				ti_freepacket(&packet);
        fclose(fptr);
        free(buffer);
        return(ret);
      }
      /* Copy data to buffer */
      for ( cpt = 1; cpt <= 4 ; cpt ++ ) /* Four 0 */
        buffer[buffer_index++] = 0;

      /* Length : */
      vars[var].size -= 2;
      buffer[buffer_index++] = (vars[var].size>>8)&0xFF;
      buffer[buffer_index++] = vars[var].size&0xFF;

			//printf(HERE"taille : %x\n",vars[var].size);

      {
        unsigned long int checksum=0;
        /* Data : */
        for ( cpt = 6; cpt < packet.nb ; cpt ++ )
        {
          buffer[buffer_index++] = packet.bytes[cpt];
          checksum += packet.bytes[cpt];
        }
        /* Checksum : */
        buffer[buffer_index++] = checksum&&0xFF;
        buffer[buffer_index++] = (checksum>>8)&&0xFF;
      }

      //printf(HERE"Copying data to buffer... ok !\n");
    }
  }

	ti_freepacket(&packet);

  fputc(0xA5,fptr);
  fputc(0x5A,fptr);


  {
    int cpt;
    for ( cpt = 0; cpt < buffer_index ; cpt ++ )
      fputc(buffer[cpt],fptr);
  }

  fputc(0x00,fptr); // should be checksum
  fputc(0x00,fptr);

  fclose(fptr);

  return(TI_OK);
}
///

/// int ti_downloadvar(char *complete_varpath, Packet *data_packet, ti_variable *var)
int ti_downloadvar(char *complete_varpath, Packet *data_packet, ti_variable *var)
{
  int index;
  Packet packet; /* temp. packet */
  UBYTE ok[]={0x08,0x56,0x00,0x00};
  unsigned int cpt;

  /* !!! */
  ti_variable temp;

  if ( ! var )
    var = &temp; /**/

  ti_initpacket(&packet);
  ti_allocpacket(&packet,6+strlen(complete_varpath));

  index =0;
  packet.command= 0xA2;

  packet.bytes[index++] = 0;
  packet.bytes[index++] = 0;
  packet.bytes[index++] = 0;
  packet.bytes[index++] = 0;

  packet.bytes[index++] = 0;
  packet.bytes[index++] = strlen(complete_varpath);

  for ( cpt=0; cpt<strlen(complete_varpath); cpt++ )
    packet.bytes[index++] = complete_varpath[cpt];

  packet.nb     = index;

  if (     ti_sendpacket(&packet)
        || ti_getpacket(&packet) /*ok */
        ||  packet.bytes[1] != 0x00 )
  {
#ifdef DEBUG
    printf(HERE"No such var\n");
#endif
		ti_freepacket(&packet);
    return(TI_NOTEXIST);
  }


  if (      ti_getpacket(&packet)        /* Local name */
        ||  ti_sendbytes(ok,sizeof(ok))) /* OK */
  {
    ti_freepacket(&packet);
    return(TI_PROTOCOL);
  }

  if ( var != NULL )
  { /* update var info */
    int cpt;
    int index=0;

		/*for ( cpt=0; cpt<packet.nb; cpt++)
			printf(HERE"%x ",packet.bytes[cpt]);
		printf(HERE"\n");*/

    var->size = 0;
    for ( cpt=0; cpt<4; cpt++)
      var->size += ( packet.bytes[index++] << (cpt*8));
    //var->size -= 2;

    var->type += packet.bytes[index++];

    for ( cpt=0; cpt<MAX_NAMELENGTH; cpt++)
      var->name[cpt] = packet.bytes[index++];
		
		//printf(HERE"info maj : %s %x %x\n",var->name,var->size,var->type);
  }

  packet.command= COMMAND_WAITING;
  packet.nb     = 0xFFFF;
	
	if (      ti_sendpacket(&packet) /* waiting */ )
	{
#ifdef DEBUG
		printf(HERE"Error 1 getting variable data\n");
#endif
		ti_freepacket(&packet);
		return(TI_PROTOCOL);
	}

	if (      ti_getpacket(&packet) /* OK */ )
	{
#ifdef DEBUG
		printf(HERE"Error 2 getting variable data\n");
#endif
		ti_freepacket(&packet);
		return(TI_PROTOCOL);
	}

	if ( ti_getpacket(data_packet) /* Data */ )
  {
#ifdef DEBUG
		printf(HERE"Error getting variable data\n");
#endif
		ti_freepacket(&packet);
    return(TI_PROTOCOL);
  }

  ti_sendbytes(ok,sizeof(ok));

  ti_getpacket(&packet); /* EOT */

  ti_freepacket(&packet);
  return(TI_OK);
}
///


int ti_isvariable(ti_type type)
{
	switch (type)
	{
		case TI_TYPE_EXPR    :
		case TI_TYPE_LIST  	 :
		case TI_TYPE_MATRIX  :
		case TI_TYPE_DATA    :
		case TI_TYPE_TEXT		 :
		case TI_TYPE_STRING	 :
		case TI_TYPE_GDB		 :
		case TI_TYPE_FIGURE	 :
		case TI_TYPE_PICTURE :
		case TI_TYPE_PRGM		 :
		case TI_TYPE_FUNC    :
		case TI_TYPE_MAC     :
		case TI_TYPE_ASM		 :
				return(1);
		case TI_TYPE_FOLDER		  :
		default:
			return(0);
	}
}
char *ti_code2string(int code)
{
  switch ( code )
  {
    case TI_OK:
      return("No error");
      break;
    case TI_PROTOCOL:
			return("Protocol error.\nPlease report to "CONFIG_EMAIL);
      break;
    case TI_PING:
      return("The TI did not respond to a ping.\nCheck cable and TI.");
      break;
    case TI_FILE:
      return("File access error.\nPlease check existence and/or rights.");
      break;
    case TI_BADFORMAT:
      return("Error : bad file format.");
      break;
    case TI_MEMORY:
      return("Error : could not allocate memory.");
      break;
    case TI_NOTEXIST:
      return("Error : no such variable.");
      break;
    default:
      return("Timeout.\nThere has been a problem with the transfer.");
      break;
  }
}

