/*

NAME
	idx2dat - Convert a simibm.idx file format to a data format
		   compatible with autoftp or batchftp for downloading
SYNOPSIS
	idx2dat fname1 [fname2]

DESCRIPTION
	idx2dat converts a file in the format of simibm.idx into
	a data file for the autoftp or batchftp program.  It will 
	extract the directory and file name from each line of the
	fname1 file and convert them into a format acceptable to the
	common background ftp programs.  
	
	The simibm.idx file format is a comma delimited record with
	each ASCII field in the record enclosed in quotes.  The
	order of fields is:
	"<vol name>","<dir name>","<fname>","x","<size>,"<type>",...
	where <vol name> is the disk volume (e.g. PD1: or PD2:), 
	<dir name> is the directory name (e.g. <MSDOS.DSKUTL>), 
	<fname> is the name of the file in upper case letters,
	<x> is ignored, <size> is the size in bytes (ignored) and
	<type> is the type of the file ("7" = ASCII, "8" = binary).  
	The fields after <type> are ignored by this program.

	Each record is converted to the following format:
	-d <vol_name><dir name>
	-t	<lc_fname>

	for binary files or:

	-d <vol_name><dir name>
	-a	<lc_fname>

	for ASCII files, where lc_fname is a lowercase version of 
	the <fname> field.  Simtel does not care about the case of
	the file name and this will cause batchftp and autoftp to
	create the local file using lowercase.  The -d line with 
	the directory name is only printed once for a group of files 
	from the same directory.  Note that there are slight 
	differences between the data file format between autoftp and 
	batchftp.  However, the forms used above are accepted by 
	both programs.

	The first command line parameter is taken to be the input
	file name.  The second parameter (if present) is the output
	file name.  If the second file name is not given then stdout
	is used.

	To set up the program, simply compile idx2dat:
		cc -o idx2dat idx2dat.c
	and place the executable in your bin directory.  You can
	rename the executable to anything you like.

USAGE:	I have found this program a valuable timesaver.  I use a 
	simple shell script which extracts the simibm.idx file from
	a newly downloaded simibm.arc file and runs diff against the 
	previous simibm.idx.  I then use an editor to read the diff 
	file and save off lines of the file for new programs I want 
	to download.  Then I use idx2dat to convert that file into a
	format for autoftp or batchftp.  Now I run autoftp to start
	downloading the files I selected in the background.  The
	whole process takes me just five minutes with most of the
	time spent browsing through the diff file for interesting
	new programs.

AUTHOR
	John Sauter, Industrial Technology Institute

DISTRIBUTION
        This is a freeware, meaning that it can be copied and used 
	freely. But the programs must NOT be sold for profit.

        Problems, improvements, comments and suggestions can be sent 
	to the author at:

        E-mail:				Postal Mail:

	john@iti.org			John A. Sauter
					Industrial Technology Institute
					PO Box 1485
					Ann Arbor, MI 48106

HISTORY:
  	Version 1.0 by John Sauter, March 1, 1991
        -------------------------------------------
	After a year of internal use I decided to clean up the
	program, make it compatible with both autoftp and batchftp 
	and release it.  This version also includes some nominal
	error checking to verify that it was given a valid
	simibm.idx file.  Its not elegant.  I just used simple brute
	force methods to parse the files, but all I wanted was
	something quick and dirty.  It does what it says it does and
	nothing more.
BUGS
	The program does not protect itself very well from 
	overrunning array bounds.  It makes sure that the first 
	three characters of a line are '"PD' and ignores the line 
	if it isn't.  This will be a problem if simibm.idx ever
	references volumes that don't start with "PD" (currently it
	doesn't).  If this test passes, but the rest of the line 
	is not in correct simibm.idx format then the program will 
	probably bomb in a spectacular fashion!

*/

#include <stdio.h>
#include <strings.h>
#include <ctype.h>

#define MAXLINE	150
#define lowercase(c) (isupper((c)) ? tolower((c)) : (c))


main(argc,argv)
  int argc;
  char **argv;
  {
     char *cname ;		/* pointer to command name */
     FILE *infile; 		/* input file ptr */
     FILE *outfile; 		/* output file ptr */
     char *res;			/* fgets result */
     char *iptr, *fptr, *dptr;	/* string parsing ptrs */
     int i ;
     char c;
     char inline[MAXLINE];	/* current record from input file */
     char dname[100];		/* current directory name */
     char last_dname[100];	/* last directory name */
     char fname[100];		/* current file name */
     char type;			/* file type (ASCII, Binary) */
     
     cname = argv[0] ;		/* cname = comand name from argv */
     if (argc < 2)
     {
       fprintf(stderr, "%s: Missing input file name\n", cname) ;
       fprintf(stderr, "Usage: %s input_fname [output_fname]\n", cname) ;
       return(-1);
     }
     if (argc > 3)
     {
       fprintf(stderr, "%s: Too many parameters\n", cname) ;
       fprintf(stderr, "Usage: %s input_fname [output_fname]\n", cname) ;
       return(-1);
     }


#ifdef DEBUG
	fprintf(stderr, "Opening %s\n", argv[1]);
#endif

     if ((infile = fopen(argv[1], "r")) == NULL)
     {
  	printf("unable to access %s\n", argv[1]) ;
	return(-1);
     }
     if (argc == 3)		/* open second file name for writing */
     {
#ifdef DEBUG
	fprintf(stderr, "Opening %s\n", argv[2]);
#endif
        if ((outfile = fopen(argv[2], "w")) == NULL)
        {
  	   printf("unable to access %s\n", argv[2]) ;
	   return(-1);
        }
     }
     else 
	outfile = stdout;	/* use stdout if no fname given */

     last_dname[0] = '\0';
     /* Read a line from the file */

     while((res = fgets(inline, MAXLINE, infile)) != NULL) 
     {
#ifdef DEBUG
	fprintf(stderr, "Input line = %s\n", inline);
#endif
	/* get the directory name */
	iptr = inline;
	if (strncmp(iptr, "\"PD", 3) != 0)	/* Check for simibm.idx format */
	{  
	   fprintf(stderr, "Error in input line:\n%s\n", inline);
	   fprintf(stderr, "Input line not in simibm.idx format.  Line ignored.\n");
	} 
	else 
	{
	   while (*iptr++ != '"'); 		/* find 1st " for vol name */
	   dptr = dname;
	   while ((*dptr++ = *iptr++) != '"');	/* find 2nd qoute */
	   dptr--;				/* ignore the quote */
	   while (*iptr++ != '"');		/* find 1st " for dir name */
	   while ((*dptr++ = *iptr++) != '"');	/* find 2nd qoute */
	   *(--dptr) = '\0';			/* end directory name */
#ifdef DEBUG
	   fprintf(stderr, "Directory name = %s\n", dname);
#endif

	/* get file name */
	   while (*iptr++ != '"');		/* find 1st " for filename */
	   fptr = fname;
	   while ((c = *iptr++) != '"')		/* find 2nd qoute */
	      *fptr++ = lowercase(c);
	   *fptr = '\0';			/* end file name */

#ifdef DEBUG
   	   fprintf(stderr, "File name = %s\n", fname);
#endif

	/* Get the file type (after third comma) */
	   i = 0;
	   while (i < 3)
	      if (*iptr++ == ',')
	         i++;
           type = *iptr;			/* get type character */

#ifdef DEBUG
	   fprintf(stderr, "File type = %c\n", type);
#endif
	/* print output line */
	   if (strcmp(last_dname, dname) != 0)
	   {
	      fprintf(outfile, "-d %s\n", dname);
	      strcpy(last_dname, dname);
	   }
	   if (type == '7')
	      fprintf(outfile, "-a\t%s\n", fname);
           else
	      fprintf(outfile, "-t\t%s\n", fname);
       }	/* end if */
    } 		/* end while */
    return(0) ;
}

