/*
 * Raw upload program for use with minicom
 * Add this to minicom's list of file transfer protocols:
 *   bin-xfr
 */

#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <termios.h>

struct baud_info {
  speed_t speed;
  int baudrate;
  int interval;
} baud_info[] = {
  B300,		300,	30,
  B600,		600,	60,
  B1200,	1200,	100,
  B1800,	1800,	200,
  B2400,	2400,	250,
  B4800,	4800,	500,
  B9600,	9600,	1000,
  B19200,	19200,	2000,
  B38400,	38400,	4000,
  B57600,	57600,	5000,
  B115200,	115200,	10000,
  B230400,	230400,	200000,
  B0,		0,	1000,
};

int find_interval(int fd)
{
  int i;
  speed_t speed;
  struct termios tstate;

  (void)tcgetattr(fd, &tstate);
  speed = cfgetospeed(&tstate);
  i = 0;
  while (baud_info[i].speed != B0) {
    if (baud_info[i].speed == speed)
      break;
    i++;
  }
  return(baud_info[i].interval);
}

extern unsigned int get_centisecs();
main(int argc, char *argv[])
{
  int i;
  int c;
  char *filename;
  //  unsigned int baud;
  unsigned int size;
  int outfd;
  unsigned int interval;
  unsigned int starttime, duration;
  
  FILE *fp, *outfp;
  // filename = argv[4];
  filename = argv[1];
  //fprintf(stderr, "Line: %s FD: %s Baud: %s File: %s\n",
  //	  argv[1], argv[2], argv[3], argv[4] );

  //  outfd = atoi(argv[2]);
  outfd = 1;
  //  baud = atoi(argv[3]);
  //  interval = baud / 10;
  interval = find_interval(outfd);

  fp = fopen(filename, "r");
  if (fp == NULL) {
    fprintf(stderr, "Can't open %s\n", filename);
    exit (1);
  }
  outfp = fdopen(outfd, "w");
  if (outfp == NULL) {
    fprintf(stderr, "Can't attach to device %d\n", outfd);
    exit (1);
  }

  (void) fseek(fp, 0, SEEK_END);
  size = ftell(fp);
  (void) fseek(fp, 0, SEEK_SET);

  fprintf(stderr, "File: %s \nSize: %7d\n", filename, size);

  starttime = get_centisecs();

  i = 0;
  while ( (c = getc(fp)) >= 0 ) {
    i++;
    if (i%interval == 0) { fprintf(stderr,"\r      %7d",i); fflush(stderr); }
    fputc (c, outfp);
  }
  fclose(fp);
  fflush(outfp);
  tcdrain(outfd);

  duration = get_centisecs() - starttime;
  duration = (duration + 5) / 10; // tenths of seconds

  fprintf(stderr, "\rSent: %7d bytes in %d.%d seconds\n",
	  i, duration/10, duration%10);
}  

unsigned int get_centisecs() {
  struct timeval tv;
  struct timezone tz;
  gettimeofday (&tv, &tz);
  return ( (tv.tv_sec * 100) + (tv.tv_usec / 10000) );
}
