From: jhelberg@nl.oracle.com (Joost Helberg)
Newsgroups: comp.os.linux
Subject: fdio reposted, compressed multi flopyy
Date: 12 Oct 92 15:08:04 GMT
Organization: Oracle Europe
X-Newsreader: Tin 1.1 PL3

X-Disclaimer: This message was written by an unauthenticated user
              at Oracle Corporation.  The opinions expressed are those
              of the user and not necessarily those of Oracle.

This is a repost of the command 'fdio', originally not posted by
me.
It provides a continuous flow of bytes from several floppies, or
makes several floppies from one contiguous stream of bytes.
I post this because several people asked me to, there is a 
discussion going on, on how to make multiple volumes using
compressed tar.

---- snip ---- snip ----


Hi,

this is my solution. the code is a mess, as i hadn't planned on
releasing it. i use it to transfer stuff from my Sparcstation at work
to my Linux box at home.

to backup, you do something like:

tar cvf - . | compress | fdio w /dev/fd1 1440

to read:

fdio r /dev/fd1 1440 | uncompress | tar xvf -
 
when compiled with LINUX defined, it tries to autodetect the size of
the floppy if you omit it on the command line. this allows you to mix
floppy types with the fd0 or fd1 devices. this feature used to work
with 0.96a but i haven't tested it since, because i use disks of the
same type and specify the size on the command line...

the defines are:
LINUX: adds floppy size autodetect
EJECT: adds autoeject floppy (sparcstation)
BUFFERK: size of internal buffer in K

I hope this is useful to somebody... If you don't find any bugs,
perhaps somebody might want to put it on a FTP site somewhere.

=================================================================
=  Massimo Fasciano       E-MAIL: fasciano@IRO.UMontreal.CA     =
=================================================================

/*                               -*- Mode: C -*- 
 * fdio.c --- 
 * Author          : Massimo Fasciano
 * Created On      : Mon Jun 15 13:21:31 1992
 * Last Modified By: Massimo Fasciano
 * Last Modified On: Tue Jun 16 14:49:56 1992
 * Update Count    : 59
 */

#define LINUX
/* #define EJECT */

#define BUFFERK 90

#include <stdio.h>

#ifdef LINUX
#include <fcntl.h>
#include <linux/fd.h>
#endif

FILE *diskf,*ttyinf,*ttyoutf;
int diskn,autodisksize,disksize,nread,nwrite;
int writing,buffercount,count,remain;
char buffer[BUFFERK*1024],dummy[82],*device;

#ifdef EJECT
void DiskEject (void)
{
  system("eject");
}
#endif

void DiskProgress (char *device)
{
  sync();
  fprintf(ttyoutf,"\r");
  fprintf(ttyoutf,"%s disk %d on %s %dK.",
	  (writing ? "Writing" : "Reading"),diskn,device,count >> 10);
  fflush(ttyoutf);
}

int GetDiskSize (char *device)
{
#ifdef LINUX
  int ctrl;
  struct floppy_struct param;

  if (autodisksize) {
    if ((ctrl = open(device,3)) < 0) {
      fprintf(ttyoutf,"Could not open %s for ioctl.\n",device);
      fflush(ttyoutf);
      exit(1);
    }
    if (ioctl(ctrl,FDGETPRM,(int) &param) < 0) {
      fprintf(ttyoutf,"Could not ioctl(FDGETPRM) on %s\n.",device);
      fflush(ttyoutf);
      exit(1);
    }
    if (close(ctrl) < 0) {
      fprintf(ttyoutf,"Could not close %s after ioctl\n.",device);
      fflush(ttyoutf);
      exit(1);
    }
    return param.size << 9;
  }
#endif
  return disksize;
}

void WriteDisk (char *device)
{
  if ((diskf = fopen(device,"wb")) == NULL) {
    fprintf(ttyoutf,"Could not open %s for output.\n",device);
    fflush(ttyoutf);
    exit(1);
  }
  count = 0;
  DiskProgress(device);

  while (count < disksize) {
    remain = disksize - count;
    buffercount = (BUFFERK*1024 < remain ? BUFFERK*1024 : remain);
     
    nread = fread(buffer,1,buffercount,stdin);
    nwrite = fwrite(buffer,1,nread,diskf);
    count += nwrite;
    
    if (nread != nwrite) {
      DiskProgress(device);
      sync();
      fprintf(ttyoutf,"\n");
      fprintf(ttyoutf,"Write error at disk %d.\n",diskn);
      fflush(ttyoutf);
#ifdef EJECT
      DiskEject();
#endif
      exit(1);
    }
    if (nread < buffercount) {
      DiskProgress(device);
      sync();
      fprintf(ttyoutf,"\n");
      fprintf(ttyoutf,"No more input data. %d disk(s) written.\n",
	      diskn);
      fflush(ttyoutf);
#ifdef EJECT
      DiskEject();
#endif
      exit(0);
    }
    if ((!(count % (1024*BUFFERK)))) DiskProgress(device);
  }

  if (fclose(diskf)) {
    fprintf(ttyoutf,"Could not close %s\n.",device);
    fflush(ttyoutf);
    exit(1);
  }
#ifdef EJECT
  DiskEject();
#endif
  DiskProgress(device);
  fprintf(ttyoutf,"\n");
}

void ReadDisk (char *device)
{
  if ((diskf = fopen(device,"rb")) == NULL) {
    fprintf(ttyoutf,"Could not open %s for input.\n",device);
    fflush(ttyoutf);
    exit(1);
  }
  count = 0;
  DiskProgress(device);

  while (count < disksize) {
    remain = disksize - count;
    buffercount = (BUFFERK*1024 < remain ? BUFFERK*1024 : remain);
     
    nread = fread(buffer,1,buffercount,diskf);
    nwrite = fwrite(buffer,1,nread,stdout);
    count += nwrite;
    
    if (!(count % (1024*BUFFERK))) DiskProgress(device);
  }
  
  if (fclose(diskf)) {
    fprintf(ttyoutf,"Could not close %s\n.",device);
    fflush(ttyoutf);
    exit(1);
  }
#ifdef EJECT
  DiskEject();
#endif
  DiskProgress(device);
  fprintf(ttyoutf,"\n");
}

main(int argc, char *argv[])
{

#ifdef LINUX
  if (argc < 3) {
    fprintf(stderr,"Syntax: %s r|w device [blocks].\n",argv[0]);
#else
  if (argc < 4) {
    fprintf(stderr,"Syntax: %s r|w device blocks.\n",argv[0]);
#endif
    fflush(stderr);
    exit(1);
  }

  if ((ttyinf = fopen("/dev/tty","r")) == NULL) {
    fprintf(stderr,"Could not open tty for input.\n");
    fflush(stderr);
    exit(1);
  }
  if ((ttyoutf = fopen("/dev/tty","w")) == NULL) {
    fprintf(stderr,"Could not open tty for output.\n");
    fflush(stderr);
    exit(1);
  }

  if (argc < 4) {
    autodisksize=1;
  }
  else {
    autodisksize=0;
    disksize = atoi(argv[3])*1024;
  }
  
  diskn = 1;
  device = argv[2];

  if (argv[1][0] == 'w') writing = 1;
  else writing = 0;

  for(;;) {
    sync();
    fprintf(ttyoutf,"\07\n");
    fprintf(ttyoutf,"Insert disk %d in %s.\n",diskn,device);
    fprintf(ttyoutf,"Press return to continue... ");
    fflush(ttyoutf);
    fgets(dummy,80,ttyinf);
    if (*dummy == 'q') exit(0);

    disksize = GetDiskSize(device);
    fprintf(ttyoutf,"Disk size is %dK (%d bytes).\n",
	    disksize>>10,disksize);
    fflush(ttyoutf);

    if (writing) WriteDisk(device);
    else ReadDisk(device);

    diskn++;
  }
}


--  
   Joost Helberg                                Rijnzathe 6
   jhelberg@oracle.nl                           NL-3454 PV De Meern
   jhelberg@nl.oracle.com                       The Netherlands

   Oracle Europe BV                             Product Line Development	
   Phone: +31 3406 94211                        Fax:   +31 3406 65609
Newsgroups: comp.os.linux