// programma om  met behulp van de CD
// 							telefoonboek van Nederland op CD-ROM (*)
// gegevens te kunnen opzoeken.
// Author: RTZ
// Date:	 Jan. 1995
// Dit is een aangepaste versie om te prompten voor de gegevens
// als er geen parameters zijn opgegeven.
// Geen copyrights, dus copieer, modificeer enz. naar eigen inzicht.
// Dit programma werk waarschijnlijk alleen met de sep- en/of dec94
// versie van de CDFOON. Gebruik van andere versies
// van * op eigen risico (na het programma te hebben aangepast)
// Gebruikte compile switches (BORLAND C++ 4.02): Zie de bijbehorende
// foon.mak file
// gebruik in ieder geval de optie: treat char as unsigned char !!


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <dir.h>
#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <mem.h>
#include <limits.h>
#include <sys/stat.h>
#include "myincl.h"
#include "foon.h"
#include "xorbloks.h"

// ---------------------------------------------------------
//    HOOFDPROGRAMMA
// ---------------------------------------------------------
void main( int argc, char ** argv )
{
	commandparms 	myparms;
	HEADER 				WPLheader;
	WPL 					woonplaats,
								vorigeWpl;
	char 					wpldatfile[] = "wpl.dat";
	int 					gelezenItems;
	FILE 				* wpldatfp;
	long					matches,
								totaalTotNuToe;

	initMyparms( &myparms );
	readcommandparms( argc, argv, &myparms );

	if ( myparms.maxhits == 1 && myparms.environment )
		setEnvironment( NULL, "" ); // reset settel.bat

	readPTT_INI( &myparms );

	if ( ! checkCDversion(&myparms) ) // er is iets mis met de versie of de cd in de speler
		errorExit( "FOON: niet de goede versie of geen CDFOON in de CDROM", "" );

	wpldatfp = fopen( wpldatfile, "rb" );
	if ( ! wpldatfp )
		errorExit( "Kan file %s niet vinden\n", wpldatfile );

	gelezenItems = fread ( &WPLheader, 1, sizeof(HEADER), wpldatfp );
	if ( gelezenItems != sizeof(HEADER) )
		errorExit( "problemen bij lezen HEADER uit %s\n", wpldatfile );

	aanmelding( &myparms );


	totaalTotNuToe = 0L;
	vorigeWpl.directorynaam[0] = '\0';
	gelezenItems = fread( &woonplaats, sizeof(WPL), 1, wpldatfp );
	while ( gelezenItems  &&
					! ( totaalTotNuToe && woonplaats.codeWpl > 10000 ) ) {
		matches = 0;
		if ( memcmp (&vorigeWpl.directorynaam, &woonplaats.directorynaam,
				 sizeof( woonplaats.directorynaam )) || ! totaalTotNuToe ) {
			memcpy( &vorigeWpl, &woonplaats, sizeof(WPL) );
			// nu kijken of er een woonplaats èn een netnummer is opgegeven,
			// dan moeten beiden matchen
			if ( 	strlen ( myparms.woonplaats ) && strlen ( myparms.netnummer ) ) {
				if ( !strncmp( woonplaats.woonplaats, myparms.woonplaats,
											 strlen( myparms.woonplaats ) )
					&& !strncmp( myparms.netnummer, woonplaats.netnummer, 5 ) )
					 matches = processWoonplaats(&woonplaats, &myparms, totaalTotNuToe );
			}
			else  // probeer dan of de opgegeven woonplaats matched
			if ( 	strlen(  myparms.woonplaats ) ) {
				if ( !strncmp( woonplaats.woonplaats, myparms.woonplaats,
											 strlen(myparms.woonplaats) ) )
					matches = processWoonplaats(&woonplaats, &myparms, totaalTotNuToe );
			}
			else // anders het opgegeven netnummer
			if ( 	strlen(  myparms.netnummer ) ) {
				if ( !strncmp( myparms.netnummer, woonplaats.netnummer, 5 ) )
					 matches = processWoonplaats(&woonplaats, &myparms, totaalTotNuToe );
			}
			else // doorloop dan alle entries
					 matches = processWoonplaats( &woonplaats, &myparms, totaalTotNuToe );
			if ( matches < 0L ) { // oeps, foutje
				fprintf ( stderr, "Een kritieke fout opgetreden bij processen %-40.40s\n",
									woonplaats.woonplaats );
				char foutcode[20];
				errorExit( "FOON: Kritieke fout: <%s>\n", ltoa(matches,foutcode, 10) );
			}
			totaalTotNuToe += matches;
			if ( totaalTotNuToe >= myparms.maxhits) break;
		}
		gelezenItems = fread( &woonplaats, 1, sizeof(WPL), wpldatfp );
		// lees nu door tot er tenminste een andere plaatsnaam wordt gevonden
		while ( gelezenItems &&
					 !strcmp(woonplaats.woonplaats, vorigeWpl.woonplaats ) )
			gelezenItems = fread( &woonplaats, 1, sizeof(WPL), wpldatfp );
	}
	fclose( wpldatfp );
	if ( myparms.stdoutRedirected )
		resetStdout ( myparms.stdoutRedirected );
	if ( ! myparms.quiet )
		fprintf( stderr, "Totaal aantal records gevonden: %lu\n", totaalTotNuToe );
	return;
}

long
processWoonplaats(	WPL * woonplaats, commandparms * myparms,
										Ulong totaalTotNuToe )
{
	AMrecord 		*	AMblok;
	char				*	uitgepakt,
							*	DMblok;
	abonnee			*	entries;
	Ulong					AMfileLengte,
								gelezenRecords;
	int						aantalEntries;
	Uint					aantalDMbloks,
								DMlengte,
								gelezenItems,
								matched,
								totaalWoonplaats,
								uitpakGrootte;
	int						i, j;
	char					AMfilename[64],
								DMfilename[64];
	FILE 				*	inputfile;


	sprintf(	AMfilename, "%s/%c/%.6s/%.6s.AM",
						myparms->CDdriveChar,
						woonplaats->directorynaam[0],
						woonplaats->directorynaam,
						woonplaats->directorynaam );

	sprintf(	DMfilename, "%s/%c/%.6s/%.6s.DM",
						myparms->CDdriveChar,
						woonplaats->directorynaam[0],
						woonplaats->directorynaam,
						woonplaats->directorynaam );

	inputfile = fopen( AMfilename, "rb" );
	if ( ! inputfile ) 											return 0;

	// de nodige blokken alloceren
	uitgepakt = new char[MAXUIT];
	if ( ! uitgepakt ) 											return -10L;

	entries = new abonnee[200];
	if ( ! entries ) 												return -30L;

	if ( fseek(inputfile, 0, SEEK_END) )		return -40L;

	AMfileLengte = ftell(inputfile);
	aantalDMbloks = (Uint) AMfileLengte / 6;

	// alloceer nu genoeg ruimte voor de hele AM file
	AMblok = new AMrecord[aantalDMbloks];
	if ( ! AMblok )													return -50L;

	if ( fseek( inputfile, 0L, SEEK_SET ) ) return -60L;

	// lees nu hele AM file binnen
	gelezenItems = fread( AMblok, sizeof(AMrecord), aantalDMbloks, inputfile );
	if ( gelezenItems != aantalDMbloks ) 		return -70L;
	fclose(inputfile);

	inputfile = fopen(DMfilename, "rb" );
	if ( ! inputfile )											return -80L;

	totaalWoonplaats = 0;
	gelezenRecords	 = 0;
	if ( ! myparms->quiet )
		fprintf ( stderr, "Bezig met: %-.30s %-5.5s (%d blokken)\n",
							woonplaats->woonplaats, woonplaats->netnummer, aantalDMbloks );

	for ( i = 0; i < aantalDMbloks &&
				totaalWoonplaats + totaalTotNuToe < myparms->maxhits; i++ ) {
		if ( fseek( inputfile, AMblok[i].DMoffset, SEEK_SET ) )
																					return -90L;
		DMblok = new char[AMblok[i].DMlengte];
		if ( ! DMblok )												return -100L;

		DMlengte = fread( DMblok, 1, AMblok[i].DMlengte, inputfile );
		if ( DMlengte != AMblok[i].DMlengte ) return -110L;

		uitpakGrootte =
		 pakBlokUit( DMblok, DMlengte, uitgepakt );
		if ( ! uitpakGrootte )								return -120L;

		aantalEntries = fillAligned( uitgepakt, uitpakGrootte, entries, myparms );
		if ( aantalEntries < 0 ) 							return aantalEntries;
		else
		if ( ! aantalEntries ) 								return -130L;
		gelezenRecords += aantalEntries;

		matched = selectEntries( entries, aantalEntries, myparms,
							totaalTotNuToe + totaalWoonplaats, woonplaats );
		totaalWoonplaats += matched;
		if ( matched  && ! myparms->quiet )
			displayData( entries, aantalEntries, myparms, woonplaats );
		if ( 	matched 				 == 1 &&
					myparms->maxhits == 1 &&
					myparms->environment     ) {
			j = -1;
			while ( ! entries[++j].selected ); // zoek de enig geselecteerde entry
			setEnvironment( &entries[j], woonplaats->woonplaats );
		}
		delete DMblok;
	}
	fclose( inputfile );

	delete AMblok;
	delete entries;
	delete uitgepakt;
	if ( ! myparms->quiet )
		if ( totaalWoonplaats == 1 )
			fprintf ( stderr,
"Er is 1 record gevonden in %s\nop een totaal van %lu doorzochte records\n",
			woonplaats->woonplaats, gelezenRecords );
		else
		if ( totaalWoonplaats )
			fprintf( 	stderr,
"Er zijn %u records gevonden in %s\nop een totaal van %lu doorzochte records\n",
			totaalWoonplaats, woonplaats->woonplaats, gelezenRecords );
	return totaalWoonplaats;
}


Uint
pakBlokUit( char * DMblok, Uint DMlengte, char * uitgepakt )
{
	Uint 	  i, j, k,
					tempOffset,
					uitgepaktWijzer,
					compressedWijzer,
					copyblokWijzer,
					bitWijzer,
					offsetCopyBlok,
					aantalCopy;
	char		currentByte,
				*	copyBlok;

// eerst het gelezen blok xorren
	for ( i = 0, j = 1, k = 1; i < DMlengte; i++, j++, k++ ) {
		DMblok[i] ^= xorblok1[j];
		DMblok[i] ^= xorblok2[k];
		j %= 999;
		k %= 1001;
	}

// nu het gelezen blok 'uitpakken'
// maak een copyblok aan tbv compressed data
	copyBlok = new char[4096];
	if ( ! copyBlok ) return 0;

	uitgepaktWijzer = 0;
	compressedWijzer = 0;
	copyblokWijzer = 0xFEE;
	setmem(uitgepakt, MAXUIT, ' ' );
	setmem(copyBlok, 4096, 0x00 );
	setmem(copyBlok, 0xFEE, ' ' );

	bitWijzer = DMblok[0] | 0xFF00;

	while ( compressedWijzer < DMlengte ) {
		currentByte = DMblok[++compressedWijzer];
		uitgepakt[uitgepaktWijzer++] = currentByte;
		copyBlok[copyblokWijzer++] = currentByte;
		copyblokWijzer &= 0x0FFF;
loop0:
		bitWijzer >>= 1;
		if ( (bitWijzer & 0x0100) && (bitWijzer & 0x0001) ) continue;
		if ( ! (bitWijzer & 0x0100) )
			bitWijzer = DMblok[++compressedWijzer] | 0xFF00;
		if ( ! (bitWijzer & 0x0001) ) {
			offsetCopyBlok = DMblok[++compressedWijzer];
			// nu ook weer kijken of je klaar bent
			if ( compressedWijzer >= DMlengte ) break;
			aantalCopy = DMblok[++compressedWijzer];
			offsetCopyBlok |= (aantalCopy & 0x00F0) << 4;
			aantalCopy &= 0x000F;
			aantalCopy += 3;
			// nu uit copyblok met offsetCopyBlok aantalCopy bytes copiëren.
			for ( i = 0; i < aantalCopy; i++ ) {
				tempOffset = offsetCopyBlok + i;
				tempOffset &= 0x0FFF;
				currentByte = copyBlok[tempOffset];
				uitgepakt[uitgepaktWijzer++] = currentByte;
				copyBlok[copyblokWijzer++] = currentByte;
				copyblokWijzer &= 0x0FFF;
			}
			goto loop0;
		}
	} // end while
	delete copyBlok;
	return uitgepaktWijzer;
}

int
fillAligned(	char * uitgepakt, Uint uitpakGrootte,
							abonnee * entries, commandparms * myparms )
{
	// nu blok 'netjes' opmaken
	// iedere entry (waarvan het aantal vooralsnog niet bekend is, maar
	// nooit meer dan 200 is) ziet er als volgt uit:
	// 4 bytes long, pointer naar *.DS file
	// 1 byte char onbekend, altijd 0x00 ?
	// 1 byte soort nummer, ' ' gewoon, F Fax, A autotelefoon en T telex
	// 2 bytes int een soort van index die ook voorkomt in wpl.dat, maar
	// die niet gebruikt wordt.
	// 4 bytes netnummer
	// 6 bytes postcode
	// tot '@' naam in vorm: optioneel#achternaam, i.n.i.t.a.l.s.,restant
	// tot '@' straat (maximum is 17)
	// tot '@' huisnr
	// tot '@' telnr
	// dan de volgende entry

	Uint 	i, count;
	char	initialen[64],
				naam[128],
				achternaam[45],
				vander[45],
				rest[45],
				*	ptr,
				* tempPtr,
				* achternaamPtr;

	i = 0;
	ptr = uitgepakt;

	while ( ptr < &uitgepakt[uitpakGrootte] ) {
		// eerst de voorloop 'rotzooi' copiëren
		memcpy(&entries[i].DSentry, ptr, 8 );
		ptr += 8;
		memcpy(entries[i].netnummer, ptr, 4 );
		entries[i].netnummer[4] = '\0';
		ptr += 4;
		memcpy(entries[i].postcode, ptr, 6 );
		entries[i].postcode[6] = '\0';
		ptr += 6;
		count = sscanf( ptr, "%[^@]@%[^@]@%[^@]@%[^@]@",
										naam, entries[i].straat,
										entries[i].zoekhuisnr, entries[i].telnr );
		if ( count <= 0 ) return -140;
		ptr += strlen(naam);
		ptr += strlen(entries[i].straat);
		ptr += strlen(entries[i].zoekhuisnr);
		ptr += strlen(entries[i].telnr);
		ptr += 4; // de 4 '@'jes

		// nu de naam strippen van stuk voor '#', dit is niet echt interessant
		tempPtr = strchr(naam, '#' );
		achternaamPtr = tempPtr ? ++tempPtr : naam;

		// nu de naam opmaken en een zoekversie maken
		// deze heeft alleen de achternaam en kan gebruikt
		// worden om exact te matchen om het aantal gevonden
		// entries te berperken

		initialen[0] 	= '\0';
		vander[0] 		= '\0';
		rest[0]		 		= '\0';
		sscanf( achternaamPtr, "%[^,],%[^.].%[^,],%[^@]s",
						achternaam, initialen, vander, rest );

		strcpy(entries[i].naam, initialen );
		if ( initialen[0] )
			strcat(entries[i].naam, " " );
		strcat(entries[i].naam, vander );
		if ( vander[0] )
			strcat(entries[i].naam, " " );
		strcat(entries[i].naam, achternaam );
		if ( rest[0] ) {
			strcat(entries[i].naam, " " );
			strcat(entries[i].naam, rest );
		}
		myparms->output == 'D' ? PC8strlwr( entries[i].naam  ):
														 ANSIstrlwr( entries[i].naam );
		strcpy(	entries[i].zoeknaam, zoekstrlwr( achternaam ));
		strlwr( entries[i].straat );
		strlwr( entries[i].zoekhuisnr );
		alignhuisnummer( entries[i].sorthuisnr, entries[i].zoekhuisnr );
		entries[i++].selected = 1;
		if ( i > 200 ) return -150;
	}
	return i;
}

char *
alignhuisnummer( char * sorthuisnr, const char * huisnr )
{
// Routine om huisnummer zodanig op te maken dat er op gesorteerd
// kan worden.
// De volgende aanname wordt gedaan: huisnummer is altijd <= 9999
// als er nog wat op volgt (zoals hs, k123) wordt dit erachter
// gezet voorafgegaan door een '/'. Zo staat het ook in het
// telefoonboek. Voorbeeld: 123  hs\0 -> __123/hs\0 of
// 45   a\0 ->___45/a\0
// als deze routine wordt aangeroepen staat het huisnummer als
// volgt: 123   hs\0 of 118\0
// Helaas is dit niet altijd het geval: soms ziet het huisnummer
// er als volgt uit: 12345eli (dit is blijkbaar de naam van een
// woonboot). Dus als het huisnummer uit maar
// 1 woord bestaat de lengte bepalen, en als groter 5
// juiste formattering uitvoeren.

	char  nr[16],
				rest[16];
	unsigned short i;

	i = sscanf( huisnr, "%s %s", nr, rest );
	switch ( i ) {
		case 1 :
			if ( strlen(nr) > 5 )
				strcpy( sorthuisnr, nr );
			else
				sprintf( sorthuisnr, "%5.5s", nr );
			break;
		case 2 :
			sprintf(sorthuisnr, "%5.5s/%s", nr, rest );
			break;
		default : // er is geen huisnummer
			sorthuisnr[0] = '\0';
			break;
	}
	return sorthuisnr;
}

Uint
selectEntries( abonnee * entries, Uint aantalEntries,
							 commandparms * myparms, Ulong totaalTotNuToe,
							 WPL * woonplaats )
{
// Routine om die entries af te vinken die niet gewenst zijn.
// De selectie criteria staan in myparms.
// Als er meerdere selectie criteria zijn opgegeven, worden deze
// allemaal afgedwongen. Bovendien worden de entries waarvan de
// postcode aangeeft dat ze niet in de range: woonplaats->pcdfrom
// woonplaats->pcdto vallen, ook uitgeschakeld. Dit bovenop de eventueel
// meegegeven postcode in myparms->postcode. Dus het heeft geen zin
// om postcodes te vragen die niet in die plaats horen!

	Uint 	i, matched;

	matched = aantalEntries;
	if ( myparms->soort ) // selecteer alleen fax, telex of mobiele nummers
		for ( i = 0; 	i < aantalEntries; i++ )
			if ( myparms->soort != entries[i].soort ) {
				entries[i].selected = '\0';
				matched--;
			}

	if ( strlen(myparms->straat) )
		for ( i = 0; 	i < aantalEntries; i++ ) {
			if ( ! entries[i].selected ) continue;
			if ( strncmp(myparms->straat, entries[i].straat,
					 strlen(myparms->straat))) {
				entries[i].selected = '\0';
				matched--;
			}
		}

	if ( strlen(myparms->huisnr) )
		for ( i = 0; 	i < aantalEntries; i++ ) {
			if ( ! entries[i].selected ) continue;
			if ( strncmp(myparms->huisnr, entries[i].zoekhuisnr,
					 strlen(myparms->huisnr))) {
				entries[i].selected = '\0';
				matched--;
			}
		}

	if ( strlen(myparms->telnr) )
		for ( i = 0; 	i < aantalEntries; i++ ) {
			if ( ! entries[i].selected ) continue;
			if ( strncmp(myparms->telnr, entries[i].telnr,
					 strlen(myparms->telnr))) {
				entries[i].selected = '\0';
				matched--;
			}
		}

	if ( strlen(myparms->postcode) )
		for ( i = 0; 	i < aantalEntries; i++ ) {
			if ( ! entries[i].selected ) continue;
			if ( strncmp(myparms->postcode, entries[i].postcode,
					 strlen(myparms->postcode))) {
				entries[i].selected = '\0';
				matched--;
			}
		}

// nu kijken of de postcode in entries[i].postcode in de
// range valt in woonplaats->pcdfrom en woonplaats->pcdto

	for ( i = 0; 	i < aantalEntries; i++ ) {
		if ( ! entries[i].selected ) continue;
		if ( strncmp(entries[i].postcode, woonplaats->pcdfrom, 4 ) < 0 ||
				 strncmp(entries[i].postcode, woonplaats->pcdto,   4 ) > 0 ) {
			// dan is de entries door de abonnee ook opgenomen
			// onder deze plaatsnaam en wordt door dit programma
			// niet meegenomen.
			entries[i].selected = '\0';
			matched--;
		}
	}

// Nu de naam. Als er een selectie is opgegeven wordt er gekeken
// of de opgegeven string voorkomt in de volledige naam
// dus je kunt zoeken op gedeeltes in een naam, die daar niet mee
// hoeven te beginnen. Tenzij exact matching is opgegeven, dan
// moet de string exact matchen op de naam. Let er daarbij op dat
// entries[i].zoeknaam alleen de achternaam bevat.

	if ( strlen(myparms->naam) )
		if ( ! myparms->naamExact )
			for ( i = 0; 	i < aantalEntries; i++ ) {
				if ( ! entries[i].selected ) continue;
				if ( ! strstr(entries[i].zoeknaam, myparms->naam )) {
					entries[i].selected = '\0';
					matched--;
				}
			}
		else // dus moet de naam exact matchen
			for ( i = 0; 	i < aantalEntries; i++ ) {
				if ( ! entries[i].selected ) continue;
				if ( strcmp(entries[i].zoeknaam, myparms->naam )) {
					entries[i].selected = '\0';
					matched--;
				}
			}


// Nu nog maxhits controleren en indien nodig teveel geselecteerde
// entries deselecteren.
	i = aantalEntries - 1;
	while ( matched + totaalTotNuToe > myparms->maxhits ) {
		if ( entries[i].selected ) {
			entries[i].selected = '\0';
			matched--;
		}
		i--;
	}
	return matched;
}


void
displayData( abonnee * entries, Uint aantalEntries,
						 commandparms * myparms, WPL * woonplaats )
{
	Uint 	i;
	char	soort[10],
				netnummer[6],
				format[64];
	char	plaatsnaam[40];
	static char header = 0;

	switch ( myparms->format ) {
		case ';' :
			strcpy(format, "\"%s-%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n" );
			break;
		default  :
			strcpy(format, "%s-%-8.8s %s %s %s %s %s %s\n" );
	}

	if ( ! header ) {
		switch ( myparms->format ) {
			case ';' :
				fprintf ( stdout,
				"\"telnummer\",\"naam\",\"straat\",\"nr\",\"postcode\",\"plaats\",\"soort\",\"sorteernaam\"\n" );
				fprintf ( stdout,
				"\"00000-00000\",\"verwijder\",\"dit\",\"record\",\"als\",\"u\",\"blieft\",\"x\"\n" );
				break;
			default :
				fprintf ( stdout, "Gevonden data in volgende volgorde:\n" );
				fprintf ( stdout, "Telnummer,Naam,Straat,Nr,Postcode,Plaats,Soort\n" );
		}
		header = 1;
	}

	for ( i = 0; 	i < aantalEntries; i++ )
		if ( entries[i].selected ) {
			if ( entries[i].netnummer[0] != ' ' )
				sprintf(netnummer, "0%4.4s", entries[i].netnummer);
			else
				sprintf(netnummer, "%5s", entries[i].netnummer);

// nu controleren of de postcode valt in de range in woonplaats->pcdfrom/
// woonplaats->pcdto. Als dit niet het geval is, dan de juiste plaatsnaam
// opzoeken in wpl.dat door serieel de file even af te lopen en de
// eerste entry pakken, waarbij de postcode wel in de range zit.
// De dan gevonden woonplaats wordt dan gebruikt, in plaats van
// woonplaats->woonplaats.
// TIJDELIJK INACTIEF, de entries worden niet geselecteerd in
// selectEntries !!!!! om performance redenen, en omdat het
// programma ptt(w).exe ook NIET de juiste plaatsnaam laat zien!
/*
		if ( strncmp(entries[i].postcode, woonplaats->pcdfrom, 4 ) >= 0 &&
				 strncmp(entries[i].postcode, woonplaats->pcdto,   4 ) <= 0 )
			// dan is het goed, anders...
			strcpy(plaatsnaam, woonplaats->woonplaats);
		else
			haalWoonplaats(entries[i].postcode, plaatsnaam );
*/
			strcpy(plaatsnaam, woonplaats->woonplaats);
			switch ( entries[i].soort ) {
				case 'T' :
					strcpy(soort, "telex" );
					break;
				case 'F' :
					strcpy(soort, "fax" );
					break;
				case 'N' :
					strcpy(soort, "speciaal" );
					break;
				case 'A' :
					strcpy(soort, "mobiel" );
					break;
				default :
					strcpy(soort, " " );
			}
			if ( myparms->format == ' ' )
				fprintf(	stdout, format, netnummer, entries[i].telnr,
					entries[i].naam,	entries[i].straat, entries[i].sorthuisnr,
					entries[i].postcode, plaatsnaam, soort );
			else
			fprintf(	stdout, format, netnummer, entries[i].telnr,
				entries[i].naam,	entries[i].straat, entries[i].sorthuisnr,
				entries[i].postcode, plaatsnaam, soort, entries[i].zoeknaam );
		}
}

void
haalWoonplaats( const char * postcode, char * plaatsnaam )
{
// nu de file wpl.dat openen en doorlopen totdat een entry wordt
// gevonden waarbij de eerste 4 postities van de meegegeven postcode
// valt in de range: woonplaats.pcdfrom en woonplaats.pcdto.
// De eerst gevonden entry zal hoogstwaarschijnlijk de juiste, door de
// PTT aanbevolen plaatsnaam bevatten. Of dit zo is, kan ik niet
// garanderen. gevonden plaatsnaam wordt teruggegeven in plaatsnaam.

	FILE * wpldatfp;
	WPL woonplaats;
	Uint	gelezenItems;

	fprintf ( stderr, "haalWoonplaats voor: %s\n", postcode );
	*plaatsnaam = '\0'; // voor het geval er niets gevonden wordt.
	wpldatfp = fopen( "wpl.dat", "rb" );
	if ( ! wpldatfp ) return;
	// eerst een fseek doen om de header over te slaan

	if ( fseek(wpldatfp, (long)sizeof(HEADER), SEEK_SET ) ) {
		fclose(wpldatfp);
		return;
	}
	gelezenItems = fread( &woonplaats, sizeof(WPL), 1, wpldatfp );
	while ( gelezenItems && woonplaats.codeWpl < 10000 ) {
		if ( strncmp(postcode, woonplaats.pcdfrom, 4 ) >= 0 &&
				 strncmp(postcode, woonplaats.pcdto,   4 ) <= 0 ) {
			strcpy( plaatsnaam, woonplaats.woonplaats );
			break;
		}
		gelezenItems = fread( &woonplaats, 1, sizeof(WPL), wpldatfp );
	}
	fclose( wpldatfp );
	return;
}

void
readPTT_INI( commandparms * myparms )
{
	FILE * inifp;
	char iniLine[128];
	char * notEOF;

	inifp = fopen("PTT.INI", "r" );
	if ( ! inifp ) { 	// try the windows version of pttw.ini, should be in
										// c:\windows
		inifp = fopen("C:/WINDOWS/PTTW.INI", "r" );
		if ( ! inifp ) {
			fprintf ( stderr,
			"Programma kan PTT.INI of C:/WINDOWS/PTTW.INI niet vinden\n" );
			fprintf ( stderr,
			"Maak anders 1 van genoemde files zelf aan met regel: drive=x:\n");
			fprintf ( stderr, "Programma probeert nu drive G: als CDROM Drive\n" );
			return;
		}
	}
	notEOF = fgets( iniLine, 127, inifp );
	while ( notEOF ) {
		iniLine[strlen(iniLine)-1] = '\0'; // get rid of \n
		if ( ! strncmp(strupr(iniLine), "DRIVE=", strlen("DRIVE=") ) ) {
			strncpy( myparms->CDdriveChar, iniLine+strlen("DRIVE="),1 );
			myparms->CDdriveInt = myparms->CDdriveChar[0] - 'A';
			break;
		}
		notEOF = fgets( iniLine, 127, inifp );
	}
	fclose(inifp);
}

void
setEnvironment( abonnee * entry, char * wpl )
// schrijf nu gevonden telefoonnummer in een .BAT file
// deze .BAT file kan dan worden aangeroepen
// en de environment variabele wordt gezet met
// het (enig) gevonden telefoon nummer
// werkt alleen als de switch -m1 en -i
// en eventueel -q zijn opgegeven
// Ook wordt een file resettel.bat aangemaakt om ze
// te verwijderen uit de environment space
{
	FILE * envbat;
	char * telnr;

	envbat = fopen("settel.bat", "w" );
	if ( ! envbat ) {
		fprintf ( stderr, "Error met openen van file settel.bat voor schrijven\n" );
		exit(0);
	}
	if ( ! entry ) {
		fprintf ( envbat, "@echo off\n"   );
		fprintf ( envbat, "SET TELNR=\n"  );
		fprintf ( envbat, "SET NAAM=\n"   );
		fprintf ( envbat, "SET STRAAT=\n" );
		fprintf ( envbat, "SET NR=\n"     );
		fprintf ( envbat, "SET POSTCDE=\n");
		fprintf ( envbat, "SET WPL=\n"    );
		fprintf ( envbat, "SET SRT=\n" 		);
	}
	else {
		telnr = entry->telnr;
		while ( *telnr && *telnr == ' ') telnr++; // skip leading spaces
		fprintf ( envbat, "@echo off\n" );
		fprintf ( envbat, "SET TELNR=%s\n", 	telnr );
		fprintf ( envbat, "SET NAAM=%s\n",  	entry->zoeknaam );
		fprintf ( envbat, "SET STRAAT=%s\n", 	entry->straat );
		fprintf ( envbat, "SET NR=%s\n",      entry->zoekhuisnr );
		fprintf ( envbat, "SET POSTCDE=%s\n", entry->postcode );
		fprintf ( envbat, "SET WPL=%s\n",			wpl );
		switch ( entry->soort ) {
			case 'F' : // fax
				fprintf ( envbat, "SET SRT=FAX\n" );
				break;
			case 'T' : // telex
				fprintf ( envbat, "SET SRT=TELEX\n" );
				break;
			case 'N' : // 'speciaal'
				fprintf ( envbat, "SET SRT=SPECIAAL\n" );
				break;
			default :
				fprintf ( envbat, "SET SRT=NORMAAL\n" );
				break;
		}
	}
	fclose ( envbat );
	if ( entry ) {
		envbat = fopen("resettel.bat", "w" );
		if ( ! envbat ) {
			fprintf ( stderr, "Error met openen van file resettel.bat voor schrijven\n" );
			exit(0);
		}
		fprintf ( envbat, "@echo off\n"   );
		fprintf ( envbat, "SET TELNR=\n"  );
		fprintf ( envbat, "SET NAAM=\n"   );
		fprintf ( envbat, "SET STRAAT=\n" );
		fprintf ( envbat, "SET NR=\n"     );
		fprintf ( envbat, "SET POSTCDE=\n");
		fprintf ( envbat, "SET WPL=\n"    );
		fprintf ( envbat, "SET SRT=\n" 		);
		fclose  ( envbat );
	}
}

char *
PC8strlwr( char * string )
// deze functie zet een string met 'vreemde' (Ä, Ö, Ü enz.) characters
// om in een lowercase equivalent. Behalve voor de o met
// een streep erdoorheen zoals in sørensen, daar DOS dit character niet
// kent. Hiervoor is character 0xED gebruikt van de DOS set. Dit is
// het meest er op lijkende character.
// De characters zijn al gebaseerd op de Windows (ANSI) set en moeten
// voor DOS apart worden omgezet. Dit louter ter verfraaiing en ten
// behoeve van import in een spreadsheet of database pakket.
// Deze functie maakt gebruik van de globale array PC8LowerChar
{
	char * ptr;
	ptr = string;
	while ( *ptr ) *ptr = PC8LowerChar[*ptr++];
return string;
}

char *
zoekstrlwr( char * string )
// deze functie zet een string met 'vreemde' (Ä, Ö, Ü enz.) characters
// om in een lowercase 'normale' character ten behoeve van het kunnen
// zoeken op namen waarin deze 'vreemde' character zitten.
// zoekLowerChar is gedefinieerd in foon.h
{
	char * ptr;
	ptr = string;
	while ( *ptr ) *ptr = zoekLowerChar[*ptr++];
return string;
}

char *
ANSIstrlwr( char * string )
// deze functie zet een (ANSI) string met 'vreemde (Ä, Ö, Ü enz.)
// characters om in een lowercase equivalent.
// Dit ten behoeve van import in spreadsheet of database en ter
// verfraaiing. ANSILowerChar is gedefinieerd in foon.h
{
	char * ptr;
	ptr = string;
	while ( *ptr ) *ptr = ANSILowerChar[*ptr++];
return string;
}

void
changeString( char * string, const char nieuw, const char oud )
// deze functie vervangt in string character oud door character nieuw
{
	while ( *string ) {
		*string = *string == oud ? nieuw : *string ;
		string++;
	}
}


void
aanmelding( commandparms * myparms )
{
	char c, dag[3], maand[4], jaar[5], mydate[32];
	Uint i;

	i = sscanf(__DATE__, "%s %s %s", maand, dag, jaar );
	if ( i == 3 )
		sprintf ( mydate, "%s %s %s", dag, maand, jaar );
	else
		strcpy( mydate, "unknown date!!" );

	if ( ! myparms->quiet )
		fprintf ( stderr, "\nFOON, Laatst gecompileerd op %s om %s door RTZ\n",
							mydate, __TIME__ );

	if ( ! ( strlen(myparms->woonplaats) || strlen(myparms->netnummer) ) ) {
		fprintf ( stderr,
		"Je selecteerde geen plaats of netnummer, alle plaatsen zullen worden\n");
		fprintf ( stderr, "afgelopen. Dit kan behoorlijk lang duren. (1 uur of langer)\n" );
		fprintf ( stderr,
		"Druk op 'D' om Door te gaan, of een andere toets om te stoppen\n" );
		c = toupper(getch());
		if ( c != 'D' ) exit(0);
	}
	if ( ! myparms->quiet )
		fprintf ( stderr, "Je opdracht wordt uitgevoerd, even geduld...\n" );
}

void help( void )
{ // deze routine laat wat help info zien en exit daarna

	char dag[3], maand[4], jaar[5], mydate[32];
	Uint i;

	i = sscanf(__DATE__, "%s %s %s", maand, dag, jaar );
	if ( i == 3 )
		sprintf ( mydate, "%s %s %s", dag, maand, jaar );
	else
		strcpy( mydate, "01 Jan 1900" ); // ??????

	fprintf ( stderr, "FOON, Laatst gecompileerd op %s om %s door RTZ\n", mydate, __TIME__ );
	fprintf ( stderr, "Aanroep: FOON [-b -d -e -f -h -i -m -n -o -p -q -s -t -w -x -;]\n" );
	fprintf ( stderr, "Waarbij -b outputbestand\n" );
	fprintf ( stderr, "				 -d Alleen mobiele telefoonnummers (autotelefoon)\n" );
	fprintf ( stderr, "        -e alleen tElex nummers en -f alleen Faxnummers \n" );
	fprintf ( stderr, "        -hHuisnummer (beginnende met)\n" );
	fprintf ( stderr, "        -i cre%cert file settel.bat om environment var te setten\n", 0x89 );
	fprintf ( stderr, "           maakt TELNR, NAAM, STRAAT, NR, POSTCDE, WPL, SRT aan met\n" );
	fprintf ( stderr, "           eerst gevonden match (-m1 en -i (en -q) dan verplicht)\n" );
	fprintf ( stderr, "        -mMaximum hits (gebruik -m1 in combinatie met -i)\n" );
	fprintf ( stderr, "        -nNaam (matched op willekeurige positie binnen naam gedeelte)\n" );
	fprintf ( stderr, "        -o dan wordt er een exacte match gedaan van opgegeven naam\n" );
	fprintf ( stderr, "        -pPostcode (beginnende met)\n" );
	fprintf ( stderr, "        -q Quiet geeft geen output (tbv opties -i -m1)\n");
	fprintf ( stderr, "        -sStraatnaam (beginnende met, maximum is 17 posities)\n" );
	fprintf ( stderr, "        -t(netnummer-)Telefoonnummer (beginnende met telefoonnummer)\n" );
	fprintf ( stderr, "        -wWoonplaats (beginnende met)\n" );
	fprintf ( stderr, "        -x gebruik de Windows character set (default DOS PC8)\n" );
	fprintf ( stderr, "        -; \"tekst\",\"tekst\" gescheiden bestand tbv import in database\n" );
	fprintf ( stderr, "tussen de optie en de waarde mag GEEN spatie staan! Dus -nnaam en NIET -n naam.\n");
	fprintf ( stderr, "Gebruik '_' voor embedded spaties (bijv. de_els voor de els (in Didam)).\n" );
	fprintf ( stderr, "Als -d, -e, -f samen voorkomen, wordt alleen de laatst gevonden optie gebruikt.\n" );
	fprintf ( stderr, "Druk een toets om verder te gaan...\n" );
	getch();
	fprintf ( stderr, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                  DISCLAIMER\n\n" );
	fprintf ( stderr, "De maker van dit programma kan niet aansprakelijk worden gesteld voor\n" );
	fprintf ( stderr, "schade of andere (financi%cle) aanspraken voorvloeiende uit het gebruik\n", 0x89 );
	fprintf ( stderr, "of het bestaan van dit programma of aangepaste versies.\n" );
	fprintf ( stderr, "De juistheid van de gegevens is de verantwoordelijkheid van PTT Telecom.\n");
	fprintf ( stderr, "Dit programma laat alleen zien wat er op een CDFOON staat in leesbare vorm.\n" );
	exit(0);
}

int
checkCDversion( commandparms * myparms )
{
	int 		curDrive,
					stat;
	ffblk * myffblk;

	curDrive = getdisk();
	setdisk(myparms->CDdriveInt);
	// nu de current directory zetten op \0
	if ( chdir( "/0" ) ) {
		fprintf ( stderr, "Problemen met zetten van \\0 als de current directory op CDROM\n", "" );
		setdisk( curDrive );
		return 0;
	}

	// nu de eerste file ophalen die matched met mask cd???9?.lbl
	// programma werkt waarschijnlijk alleen met de cdsep94.lbl
	// en cddec94.lbl versies. (nog) Niet met andere versies
	// vanwege (mogelijke) andere codering van de *.DM files

	myffblk = new ffblk;
	*myffblk->ff_name = '\0';
	stat = findfirst( "CD???9?.LBL", myffblk, 0 );
	if ( stat ) {
		fprintf ( stderr,
		"FOON: Waarschijnlijk niet een goede versie van de CDFOON\n" );
		setdisk( curDrive );
		delete myffblk;
		return 0;
	}
	else
	if ( strcmp( myffblk->ff_name, "CDSEP94.LBL" ) &&
			 strcmp( myffblk->ff_name, "CDDEC94.LBL" ) ) {
		fprintf ( stderr,
		"FOON: Sorry, gevonden: <%s> niet een goede CDFOON versie\n",
		myffblk->ff_name );
		setdisk( curDrive );
		delete myffblk;
		return 0;
	}
	else
		delete myffblk;
	setdisk(curDrive);
	return 1; // alles lijkt okido
}

void
readcommandparms(int argc, char ** argv, commandparms * myparms)
{
	char 	*	arg = '\0',
				* temp,
					netnummer[6];
	Uint 		i;

	if ( argc < 2 ) {
		vraaggegevens ( myparms );
		return;
	}

	argv[argc] = '\0';
	arg = *++argv;
	while ( arg ) {
		if ( strchr( "-/", *arg ) ) {
			arg++;
			switch ( toupper(*arg) ) {
				case 'B' :
					if ( ! myparms->stdoutRedirected )
						myparms->stdoutRedirected = redirectStdout( *argv+2 );
					else
						fprintf ( stderr, 
						"-B switch mag maar 1 keer worden opgegeven: %s wordt niet gebruikt\n",
						*argv );
					break;
				case 'D' :
					myparms->soort = 'A';
					break;
				case 'E' :
					myparms->soort = 'T';
					break;
				case 'F' :
					myparms->soort = 'F';
					break;
				case 'H' :
					if ( ! strlen(myparms->huisnr) )
						strcpy( myparms->huisnr,	*argv+2 );
					else
						fprintf ( stderr,
						"-H switch mag maar 1 keer worden opgegeven: %s wordt niet gebruikt\n",
						*argv );
					break;
				case 'I' :
					myparms->environment = 1;
					break;
				case 'M' :
					if ( myparms->maxhits == ULONG_MAX )
						myparms->maxhits = strtoul(*argv+2, &temp, 10 );
					else
						fprintf ( stderr,
						"-M switch mag maar 1 keer worden opgegeven: %s wordt niet gebruikt\n",
						*argv );
					break;
				case 'N' :
					if ( ! strlen(myparms->naam) )
						strcpy( myparms->naam,			*argv+2 );
					else
						fprintf ( stderr,
						"-N switch mag maar 1 keer worden opgegeven: %s wordt niet gebruikt\n",
						*argv );
					break;
				case 'O' :
					myparms->naamExact = 1;
					break;
				case 'P' :
					if ( ! strlen(myparms->postcode) )
						strcpy( myparms->postcode,	*argv+2 );
					else
						fprintf ( stderr,
						"-P switch mag maar 1 keer worden opgegeven: %s wordt niet gebruikt\n",
						*argv );
					break;
				case 'Q' :
					myparms->quiet = 1;
					break;
				case 'S' :
					if ( ! strlen(myparms->straat) )
						strcpy( myparms->straat,		*argv+2 );
					else
						fprintf ( stderr,
						"-S switch mag maar 1 keer worden opgegeven: %s wordt niet gebruikt\n",
						*argv );
					break;
				case 'T' :
					if ( ! strlen(myparms->telnr) )
						strcpy( myparms->telnr,	*argv+2 );
					else
						fprintf ( stderr,
						"-T switch mag maar 1 keer worden opgegeven: %s wordt niet gebruikt\n",
						*argv );
					break;
				case 'W' :
					if ( ! strlen(myparms->woonplaats) )
						strcpy( myparms->woonplaats,*argv+2 );
					else
						fprintf ( stderr,
						"-W switch mag maar 1 keer worden opgegeven: %s wordt niet gebruikt\n",
						*argv );
					break;
				case 'X' :
					myparms->output = 'W'; // Windows character set
					break;
				case '?' : help();
				case ';' :
					myparms->format = ';';
					break;
				default :
					fprintf ( stderr,
					"Onbekende optie <%s>! Buiten beschouwing gelaten\n", *argv );
			}
		}
		else
			fprintf ( stderr,
			"Onbekende optie <%s>! Buiten beschouwing gelaten\n", *argv );
		arg = *++argv;
	}

	if ( myparms->maxhits == 0 ) {
		fprintf ( stderr,
		"Sorry -M moet worden gevolgd door een positief geheel getal\n" );
		exit(0);
	}

	if ( ! strlen(myparms->naam) && myparms->naamExact ) {
		fprintf ( stderr, "Optie -o kan alleen samen met optie -n worden gebruikt\n" );
		exit(0);
	}

	// haal nu de '_' uit de strings en zet alles op lowercase
	strlwr(myparms->straat);
	changeString(myparms->straat, ' ', '_' );

	strlwr(myparms->huisnr);
	changeString(myparms->huisnr, ' ', '_' );

	strlwr(myparms->naam);
	changeString(myparms->naam, ' ', '_' );

	strlwr(myparms->woonplaats);
	changeString(myparms->woonplaats, ' ', '_' );

	strupr(myparms->postcode);

	// nu het telefoon nummer. Dit mag uit alleen maar cijfers bestaan
	// en een '-' tussen netnummer-abonneenummer
	*netnummer = '\0';
	temp = strchr( myparms->telnr, '-' );
	if ( temp ) { // er was een netnummer opgegeven
		*temp = '\0';
		strcpy(netnummer, myparms->telnr);
		sprintf(myparms->netnummer, "%5.5s\0", netnummer );
		// kopieer nu overgebleven abonnee nummer in myparms->telnr
		strcpy( myparms->telnr, temp+1 );
	}

	for ( i = 0; i < strlen(netnummer); i++ ) {
		if ( ! isdigit(netnummer[i]) ) {
			fprintf ( stderr, "Netnummer mag alleen uit cijfers bestaan.\n" );
			fprintf ( stderr, "Je gaf op: netnummer <%s>\n", myparms->netnummer );
			fprintf ( stderr, "           telnummer <%s>\n", myparms->telnr );
			exit(0);
		}
	}

	for ( i = 0; i < strlen(myparms->telnr); i++ )
		if ( ! isdigit(myparms->telnr[i]) ) {
			fprintf ( stderr, "Telefoon nummer mag alleen uit cijfers bestaan.\n" );
			fprintf ( stderr, "Je gaf op: netnummer <%s>\n", myparms->netnummer );
			fprintf ( stderr, "           telnummer <%s>\n", myparms->telnr );
			exit(0);
		}

	// als er een telefoon nummer is opgegeven en geen plaatsnaam,
	//  moet er ook een netnummer aanwezig zijn, anders weet het
	// programma niet in welke plaats het moet zoeken.
	if (  strlen(myparms->telnr)   		 > 0 &&
				strlen(netnummer)  					== 0 &&
				strlen(myparms->woonplaats) == 0 ) {
		fprintf ( stderr, "Bij zoeken op telefoonnummer is %cf een plaatsnaam\n", 0x95 );
		fprintf ( stderr, "%cf een netnummer noodzakelijk\n", 0x95 );
		exit(0);
	}
}


void
vraaggegevens( commandparms * myparms )
{
	char 	* notEOF,
				* temp,
					netnummer[16],
					regel[128];
	int			i;

	fprintf ( stderr, "\nFOON: Geef de gewenste zoekgegevens, of laat leeg\n\n" );
	fprintf ( stderr, "Woonplaats:       " );
	notEOF = gets( regel );
	if ( notEOF )
		if ( strlen(regel) > 0 ) strcpy(myparms->woonplaats, regel );
	fprintf ( stderr, "Naam:             " );
	notEOF = gets( regel );
	if ( notEOF )
		if ( strlen(regel) > 0 ) {
			strcpy(myparms->naam, regel );
			fprintf ( stderr, "Naam exact [N/j]: " );
			notEOF = gets( regel );
			if ( notEOF )
				if ( toupper(*regel) == 'J' ) myparms->naamExact = 1;
		}
	fprintf ( stderr, "Straat:           " );
	notEOF = gets( regel );
	if ( notEOF )
		if ( strlen(regel) > 0 ) strcpy(myparms->straat, regel );
	fprintf ( stderr, "Huisnr:           " );
	notEOF = gets( regel );
	if ( notEOF )
		if ( strlen(regel) > 0 ) strcpy(myparms->huisnr, regel );
	fprintf ( stderr, "Telnr:            " );
	notEOF = gets( regel );
	if ( notEOF )
		if ( strlen(regel) > 0 ) strcpy(myparms->telnr, regel );
	fprintf ( stderr, "Postcode:         " );
	notEOF = gets( regel );
	if ( notEOF )
		if ( strlen(regel) > 0 ) strcpy(myparms->postcode, regel );
	fprintf ( stderr, "Maxhits:          " );
	notEOF = gets( regel );
	if ( notEOF )
		if ( strlen(regel) > 0 ) myparms->maxhits = strtoul(regel, &temp, 10 );
	fprintf ( stderr, "Soort (T=Telex, F=FAX, A=Autotelefoon):  " );
	notEOF = gets( regel );
	if ( notEOF )
		if ( strlen(regel) > 0 ) myparms->soort = regel[0];
	fprintf ( stderr, "Komma gescheiden bestand [N/j]:  " );
	notEOF = gets( regel );
	if ( notEOF )
		if ( strlen(regel) > 0 && toupper(regel[0]) == 'J' ) {
			myparms->format = ';';
			fprintf ( stderr, "Bestandsnaam:     " );
			notEOF = gets( regel );
			if ( notEOF )
				if ( strlen(regel) > 0 )
					myparms->stdoutRedirected = redirectStdout( regel );
		}
	fprintf ( stderr, "Soort output: W=Windows (ANSI) D=DOS PC8:  " );
	notEOF = gets( regel );
	if ( notEOF )
		if ( strlen(regel) > 0 && toupper(regel[0]) == 'W' )
			myparms->output = 'W';

	fprintf ( stderr, "Druk op <Enter> om gegevens te valideren en starten..." );
	notEOF = gets( regel );

	if ( myparms->maxhits == 0 ) {
		fprintf ( stderr,
		"Sorry Maxhits moet worden gevolgd door een positief geheel getal\n" );
		exit(0);
	}

	strlwr(myparms->straat);
	strlwr(myparms->huisnr);
	strlwr(myparms->naam);
	strlwr(myparms->woonplaats);
	strupr(myparms->postcode);

	// nu het telefoon nummer. Dit mag uit alleen maar cijfers bestaan
	// en een '-' tussen netnummer-abonneenummer
	*netnummer = '\0';
	temp = strchr( myparms->telnr, '-' );
	if ( temp ) { // er was een netnummer opgegeven
		*temp = '\0';
		strcpy(netnummer, myparms->telnr);
		sprintf(myparms->netnummer, "%5.5s\0", netnummer );
		// kopieer nu overgebleven abonnee nummer in myparms->telnr
		strcpy( myparms->telnr, temp+1 );
	}

	for ( i = 0; i < strlen(netnummer); i++ ) {
		if ( ! isdigit(netnummer[i]) ) {
			fprintf ( stderr, "Netnummer mag alleen uit cijfers bestaan.\n" );
			fprintf ( stderr, "Je gaf op: netnummer <%s>\n", netnummer );
			fprintf ( stderr, "           telnummer <%s>\n", myparms->telnr );
			exit(0);
		}
	}

	for ( i = 0; i < strlen(myparms->telnr); i++ )
		if ( ! isdigit(myparms->telnr[i]) ) {
			fprintf ( stderr, "Telefoon nummer mag alleen uit cijfers bestaan.\n" );
			fprintf ( stderr, "Je gaf op: netnummer <%s>\n", netnummer );
			fprintf ( stderr, "           telnummer <%s>\n", myparms->telnr );
			exit(0);
		}

	// als er een telefoon nummer is opgegeven en geen plaatsnaam,
	//  moet er ook een netnummer aanwezig zijn, anders weet het
	// programma niet in welke plaats het moet zoeken.
	if (  strlen(myparms->telnr)   		 > 0 &&
				strlen(netnummer)  					== 0 &&
				strlen(myparms->woonplaats) == 0 ) {
		fprintf ( stderr, "Bij zoeken op telefoonnummer is %cf een plaatsnaam\n", 0x95 );
		fprintf ( stderr, "%cf een netnummer noodzakelijk\n", 0x95 );
		exit(0);
	}
}

void
initMyparms ( commandparms * myparms )
{
	// initieer de velden
	strcpy(myparms->straat, 		 ""   )		;
	strcpy(myparms->huisnr,  		 ""   )		;
	strcpy(myparms->telnr, 	 		 ""   )		;
	strcpy(myparms->postcode, 	 ""   )		;
	strcpy(myparms->naam, 			 ""   )		;
	strcpy(myparms->woonplaats,	 ""   )		;
	strcpy(myparms->netnummer,	 ""   )		;
	strcpy(myparms->CDdriveChar, "G:" )		;		// default
	myparms->soort 				     = '\0'	 		;
	myparms->naamExact		     = '\0'	 		;
	myparms->CDdriveInt 	     = 6		 		; 	// default is G:
	myparms->quiet						 = '\0'	 		;
	myparms->environment			 = '\0' 		;
	myparms->format						 = ' '			;
	myparms->maxhits 			     = ULONG_MAX;
	myparms->output						 = 'D'			; 	// dos output
	myparms->stdoutRedirected	 = 0        ;
}

void
errorExit( char * format, char * parameter )
{
	fprintf ( stderr, "\n" );
	fprintf ( stderr, "Een kritieke fout opgetreden tijdens uitvoering.\n" );
	fprintf ( stderr, "Of niet de juiste CD versie van de CDFOON.\n" );
	fprintf ( stderr, format, parameter );
	exit(0);
}

int
redirectStdout( char * filename )
{
	int oldstdout;
	FILE * newStdout;

	newStdout = fopen(filename, "w" );
	if ( ! newStdout ) {
		fprintf ( stderr, "FOON: kan bestand %s niet openen om te schrijven\n",
							filename );
		exit(0);
	}

	 // create a duplicate handle for standard output
	 oldstdout = dup(STDOUT);

	 // redirect standard output to filename
	 // by duplicating the file handle onto
	 //	the file handle for standard output.
	 dup2(fileno(newStdout), STDOUT);

	 // close the handle for filename
	 fclose(newStdout);
	 return oldstdout; // tbv sluiten aan eind programma
}

void
resetStdout( int oldstdout )
{
// restore original standard output handle
	 dup2(oldstdout, STDOUT);
// close duplicate handle for STDOUT
	 close(oldstdout);
}

