/* BDEIN: import IBM Basic Data Exchange data-sets to RSX files */

#include	<stdio.h>
#include "ascii.h"
#include <cx.h>
#include <qiofun.h>
#include <spcio.h>
#include <algol68.h>
#define LUN 6
#define EFN 6
int	prl[6];		/* QIO parameter block */
int	isb[2];		/* directive status block (QIO) */
char d1index[26][128];	/* image (in EBCDIC) of diskette-1 index track */
int  apcrlf;		/* true to append \r\n to every record on output */
char *ap;		/* points into argument */
char	*dp;		/* points to string defining device name */
		 int boeblk;	/* beginning of extent */
		 int eodblk;	/* just after last data block */
		 int cpb;	/* (data) characters per block */
		 int records;	/* number of records in file */
/*		 int d1block();	*/
/*		 int g_ed();	*/
		 char block[128];/* image of 1 IBM diskette block */
		 int blk;	/* particular block sniffing now */
		 char cpmfn[12];/* "12345678.nn" */
		 char string[3];/* convert chars to string */
/*junk*/	int ibmdrive;
	 char *dslp;	/* point to dataset label that matched */
/* junk */ int iobuf;
int j,m,k;
#define CPMEOF 21

help()
{puts("BDEIN is a RSX program to import data from IBM Basic Data Exchange Diskettes\n");
 puts(" i.e. 8\" soft-sectored single-sided single-density IBM diskette-1 type.\n");
 puts("Program is invoked by the following, where \">\" is the RSX prompt:\n");
 puts("A>BDEIN                 or:     A>BDEIN filename\n");
 puts("With no filename the diskette directory is displayed.\n");
 puts("Witè á filename (8 or less characters, no spaces)\n");
 puts("  the named dataset is copied from the IBM diskette to a CPM file (same name).\n");
 puts("The RSX file-extension is the IBM dataset volume sequence number (if any).\n");
 puts("The RSX file is output in ASCII to the standard output\n");
 puts("The IBM dataset must be in EBCDIC, and is assumed to be in drive DY0: .\n");
/*
 puts("To tell BDEIN the IBM diskette is in a different drive,\n");
 puts("  use the drive name (with :) before the filename. E.g.:\n");
 puts(">BDEIN DX1:      gives a directory of an IBM diskette in drive DX1:\n");
*/
 puts(">BDEIN FRED  copys FRED (IBM) to standard output\n");
 puts("BDEIN forces your command to UPPER-CASE: so you can't use lower-case names\n");
 puts("Normally RSX files have a Carriage-return-Line-feed inserted after each IBM\n");
 puts(" record, but this feature is canceled by adding \" -n\" to the command\n");
 puts("Type \"BDEIN -?\" for more help\n");
}
helps()
{puts("\n\n\nThe command line to BDEIN is of the form:\n");
 puts(">BDEIN a1 a2 a3\n");
 puts("where \">\" is the RSX prompt, \"BDEIN\" is the program name,\n");
 puts("and \"a1 a2 a3\" represent details of the command.\n");
 puts("No details is OK, but often at least one detail is needed.\n");
 puts("Details are seperated from the command name \"BDEIN\" and from\n");
 puts("other details by at least one space (or tab).\n");
 puts("There are two types of details: those that begin with \"-\" and\n");
 puts("those that don\'t.\n");
 puts("Details that begin with \"-\" are allowed anywhere.\n");
 puts("Currently only two are recognised: \"-n\" turns off automatic appending\n");
 puts("of new-lines to each output record; \"-?\" displays this text.\n");
 puts("Only one (or no) detail is permitted to not begin with \"-\".\n");
 puts("Such a detail is the destination (output) RSX filename if a file is\n");
 puts("being transferred.\n");
 puts("If the filename is \"?\" then help is given rather than a file transferred.\n");
}
main(argc,argv)
int argc; char **argv;
{
#define ARGSIZ 50
 char arg[ARGSIZ];
 int	dsw;
 int	devnam;
 int	devunt;
 devnam = 'DY';
 devunt = 0;
 dsw = alun(LUN,devnam,devunt);
 IF	(dsw!=IS_SUC)
 THEN	error("Can't use lun: dsw=%oo devnam=%oo devunt=%oo",dsw,devnam,devunt);
 FI;
 dsw = qiow(IO_ATT,LUN,EFN,isb,0,prl);
 IF	(dsw!=IS_SUC||(isb[0]&0xFF)!=IS_SUC)
 THEN	error("dsw=%oo isb[0]=%oo isb[1]=%oo \7IO_ATT",dsw,isb[0],isb[1]);
 FI;
#ifdef SMD
 prl[0] = 0;	/* RX01 density: 3740 standard */
 dsw = qiow(IO_SMD,LUN,EFN,isb,0,prl);
 IF	(dsw!=IS_SUC||(isb[0]&0xFF)!=IS_SUC)
 THEN	error("dsw=%oo isb[0]=%oo isb[1]=%oo IO_SMD\7",dsw,isb[0],isb[1]);
 FI;
#endif
 arg[0]=0;
 apcrlf=1;	/* default: append cr-lf to each record */
 while	(--argc)
	{if	(*argv[argc]=='-')
		{if	(strcmp(argv[argc],"-?")==0)
			{
			 helps();
			 exit();
			}
		 else
			{if	(  toupper(argv[argc][1])=='N'
				&& argv[argc][2]==0
				)
				{
				 apcrlf=0;
				}
			 else
				{puts("\7Ignoring unknown switch:");
				 puts(argv[argc]);
				 puts("\n");
				}
			 ;
			}
		 ;
		}
	else
		/* have a non-switch argument */
		{if	(*arg)
			{puts("\7You may only type 1 argument excluding switches, but you typed:\n");
			 printf("%s\n%s\nSo I QUIT in utter confusion!\n",arg,argv[argc]);
			 exit();
			}
		 ;
		 /* is first arg */
		 if	(strlen(argv[argc])>=ARGSIZ)
			{puts("\7command argument too long!\n");
			 help();
			 exit();
			}
		 else
			{strcpy(arg,argv[argc]);
			}
		 ;
		}
	 ;
	}
 ;
 /* here with argument in arg[] */
 if	(strcmp(arg,"?")==0)
	{help();
	 exit();
	}
 ;
 ap = arg;
 if	(  isalpha(*ap++)
	&& isalpha(*ap++)
	&& isdigit(*ap++)
	&& *ap++==':'
	)
	{dp = arg;
	 ap[-1] = 0;
	}
 else
	{dp = "DY0";
	 ap = arg;
	}
 ;
 /* ibmdrive known */
 /* ap points to dataset name */
 d1getind(d1index,ibmdrive);	/* !!!!!!!!!!!!!!!!!!!!!!!!!! */
 /* d1index known */
 if	(*ap)
	{
/*	 int ddsif();	*/
	 if	(ddsif(d1index[7],128,19,ap,&dslp,ascii))
		{/* dslp points to matching dataset label in index */
		 cpb=g_ed(&dslp[22],5);
		 boeblk=d1block(g_ed(&dslp[28],2),g_ed(&dslp[31],2));
		 eodblk=d1block(g_ed(&dslp[74],2),g_ed(&dslp[77],2));
		 records = eodblk-boeblk;
		 strcpy(cpmfn,ap);	/* filename = datasetname */
		 strcat(cpmfn,".");
		 string[0] = ascii[dslp[45]];
		 string[1] = ascii[dslp[46]];
		 string[2] = 0;
		 strcat(cpmfn,string);
/*		 printf("%c:%s ",dfltdrv+'A',cpmfn);	*/
		 printf("%d records each %d characters wide\n",records,cpb);
		 if (apcrlf) puts("Each record having Carriage-return-Line-feed appended\n");
		 fcreat(cpmfn,iobuf);
		 for	(blk=boeblk;blk<eodblk;blk++)
			{d1get128(block,ibmdrive,blk);
			 for	(m=0;m<cpb;m++)
				{
				 putc(ascii[block[m]],iobuf);
				 printf("%c",ascii[block[m]]);
				}
			 ;
			 if	(apcrlf)
				{putc('\r',iobuf);
				 putc('\n',iobuf);
				}
			 ;
			 puts("\n");
			}
		 ;
		 putc(CPMEOF,iobuf);
		 fflush(iobuf);
		 fclose(iobuf);
		}
	 else
		{printf("\7Can\'t find dataset label: \"%s\"\n",ap);
		 exit();
		}
	 ;
	}
 else
	{
	 for	(k=6;k<26;k++)
		{
		 for	(j=0;j<79;j++)
		 	printf("%c",ascii[d1index[k][j]])
		 ;
		 puts("\n");
		}
	 ;
	}
 ;
}

setmem(base,len,byt)
char	*base;
unsigned	len;
char	byt;
{while	(len--)	*base++=byt;
}

d1get128(data,where)
char	*data;
unsigned where;	/* 0-org sector number */
{
 int	dsw;
 prl[0] = data;
 prl[1] = 128;
 prl[4] = where;
 dsw = qiow(IO_RPB,LUN,EFN,isb,0,prl);
 if	(dsw!=IS_SUC||(isb[0]&0xFF)!=IS_SUC)	error("dsw=%oo isb[0]=%oo isb[1]=%oo \7IO_RPB",dsw,isb[0],isb[1]);
}

/* end: BDEIN */
