byte2lba.c 3.24 KB
/*
 * lba <-> byte conversion program
 *
 *     Author: has@rd3
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

extern	int tab[][4292];

#define	BYTE2LBA	0
#define LBA2BYTE	1

int byte2LBA(int type, int startLBA, int nbytes)
{
  int totalbytes = 0;
  int lba = startLBA;
  
  while(totalbytes < nbytes)
  {
    totalbytes += tab[type][lba];
    lba ++;
  }

  return(lba - startLBA);
  
}

int lba2Byte(int type, int startLBA, int nlbas)
{
  int result = 0;
  
  nlbas += startLBA;
  while(startLBA < nlbas)
    result += tab[type][startLBA++];

  return result;
  
}

#ifndef OBJECTONLY
int main(int argc, char **argv)
{
  int 	type;
  int 	startLBA;
  int 	num;
  int 	dir;
  char	*cmdName;
#ifndef MSDOS
#ifdef __sgi__
  char	*rindex(char *, int);
#endif
#endif
  int	remain;
  
  /*
   * Get the command name
   */
#if MSDOS /* { */
  cmdName=(char *)cut_dir_fname(argv[0]);
#else /* }{ */
  if ((cmdName = rindex(argv[0], '/')) != NULL)
    cmdName++;
  else
    cmdName = argv[0];
  
#endif /* } */

  /*
   * The command name is either "byte2lba" or "lba2byte"
   */
#ifndef MSDOS
  if (strcmp(cmdName, "byte2lba") == 0)
    dir = BYTE2LBA;
  else if (strcmp(cmdName, "lba2byte") == 0)
    dir = LBA2BYTE;
  
#else /* MSDOS */
  if (strnicmp(cmdName, "byte2lba" , sizeof("byte2lba")-1 ) == 0)
    dir = BYTE2LBA;
  else if (strnicmp(cmdName, "lba2byte" , sizeof("lba2byte")-1 ) == 0)
    dir = LBA2BYTE;
  
#endif

  /*
   * it's legal only when the number of the arguments is 3.
   */
  if(argc != 4)
  {
    if (dir == BYTE2LBA)
    {
      fprintf(stderr, "Usage: byte2lba type startLBA nbytes\n");
      fprintf(stderr, "Calculate how many LBAs are equivalent to <nbytes> from <startLBA>\n");
    }
    else
    {
      fprintf(stderr, "Usage: lba2byte type startLBA nlbas\n");
      fprintf(stderr, "Calculate how many bytes are equivalent to <nlbas> from <startLBA>\n");
    }      
    return -1;
  }
  
  /*
   * Check whether argument "type" is legal
   */
  type = strtol(argv[1], (char **)NULL, 0);
  if ((type < 0) || (type > 6))
  {
    fprintf(stderr, "%s: type is illegal. It must be in [0-6]\n",
	    cmdName);
    return -1;
  }
  
  /*
   * Check whether argument "startLBA" is legal
   */
  startLBA = strtol(argv[2], (char **)NULL, 0);
  if ((startLBA < 0) || (startLBA >= 4292))
  {
    fprintf(stderr, "%s: startLBA is illegal. It must be in [0-4291]\n",
	    cmdName);
    return -1;
  }
  
  num = strtol(argv[3], (char **)NULL, 0);
  if (dir == BYTE2LBA)
  {
    /*
     * Check whether argument "nbytes" is legal.
     */
    remain = lba2Byte(type, startLBA, 4292 - startLBA);
    if (remain < num)
    {
      fprintf(stderr, "%s: There are only %d bytes from LBA%d to 4291\n",
	      cmdName, remain, startLBA);
      return -1;
    }

    /*
     * do the conversion
     */
    printf("%d\n", byte2LBA(type, startLBA, num));
  }
  else /* lba2byte */
  {
    /*
     * Check whether argument "nlbas" is legal
     */
    if (startLBA + num - 1 >= 4292)
    {
      fprintf(stderr, "%s: End LBA(%d) is illegal. It must be in [0-4291]\n",
	      cmdName, startLBA + num - 1);
      return -1;
    }

    /*
     * do the conversion
     */
    printf("%d\n", lba2Byte(type, startLBA, num));

  } /* if (dir == BYTE2LBA) */
  
  return 0;
  
} /* main */

#endif