//   ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
//   º                                                                    º
//   º module:      connopen.c                                            º
//   º abstract:    This module shows how to make 3.x system calls using  º
//   º              the F2 Shell Interface for the GetConnectionsOpen     º
//   º              Files API, obviously it requires the NetWare Shell.   º
//   º                                                                    º
//   º environment: NetWare 3.x v3.11                                     º
//   º              Borland C 3.0                                         º
//   º                                                                    º
//   º  This software is provided as is and carries no warranty           º
//   º  whatsoever.  Novell disclaims and excludes any and all implied    º
//   º  warranties of merchantability, title and fitness for a particular º
//   º  purpose.  Novell does not warrant that the software will satisfy  º
//   º  your requirements or that the software is without defect or error º
//   º  or that operation of the software will be uninterrupted.  You are º
//   º  using the software at your risk.  The software is not a product   º
//   º  of Novell, Inc. or any of subsidiaries.                           º
//   ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>

#include "nwsys.h"

//
//  First of all, we define the request and reply structures which are
//  needed for the GetConnectionsOpenFiles API call.  These structures are
//  layed out according to the System Call documentation.
//

struct  {
    WORD    sflen;          // length of the structure.  This is 6 + 'onlen'
    BYTE    sfcode;         // the subfunction code, in our case 53.
    WORD    connNumber;     // object type (hi-lo)
    WORD    lastRecordSeen; // length of name (below)
}Request;

struct fileStruct{
    WORD    taskNumber;     // task number within ws holding file open
    BYTE    lockType;       // lock type  ie sharable, logged, locked, TTS
    BYTE    accessControl;  // connectiosn access rights to file
    BYTE    lockFlag;       // lock flag
    BYTE    volumeNumber;   // volume number file resides upon
    BYTE    reserved[9];
    BYTE    nameSpace;      // name space identifier
    BYTE    fileName[14];   // name of file (null terminated)
} ;

struct 	fileStruct *fs[29];
int	numOpenFiles;
WORD    connectionNumber;

struct  {
    WORD    nextRequestRec; // next record to be requested.
    WORD    numberReturned; // numober of records returned
    BYTE    buffer[512];
}Reply;

void ProcessEntries(void);
void FreeEntries(void);
void DisplayData(void);
//  This routine allocates memory for the data returned for each file.
//  It also makes the GetConnectionOpenFiles call and parses the data
//  for each file.
//
void ProcessEntries(void)
{
	char *lookup;
	int i,j;

	lookup=(char *)&Reply.buffer;
	numOpenFiles=Reply.numberReturned;
	for(i=0;i < numOpenFiles; i++) {
		fs[i]=malloc(sizeof (struct fileStruct));
		memmove((char *)&fs[i]->taskNumber,(lookup),2);
		fs[i]->lockType=*(lookup+2);
		fs[i]->accessControl=*(lookup+3);
		fs[i]->lockFlag=*(lookup+4);
		fs[i]->volumeNumber=*(lookup+5);
		memmove(fs[i]->reserved,(lookup+6),9);
		fs[i]->nameSpace=*(lookup+15);
		for(j=0;j<*(lookup+16);j++)
			fs[i]->fileName[j]=*(lookup+17+j);
		fs[i]->fileName[j]='\0';
		lookup=(lookup+17+j);
	}
}

//
//  This routine frees memory allocated by ProcessEntries.
//
void FreeEntries( void )
{
	int i;

	for(i=0;i<numOpenFiles;i++)
		free(fs[i]);
}

//
//  Display the list of open files for the connection.
//
void DisplayData( void )
{
	int i;

	clrscr();
	printf("\n\nList Of %d Open Files For Connection %d\n\n",
				numOpenFiles,
				connectionNumber);
	for(i=0;i<numOpenFiles;i++)
		printf("%s\n",&fs[i]->fileName);
}
//
//  This is the main program.  The purpose is to make the GetBinderyObjectID
//  API call to illustrate making system calls using the F2 interface.
//


void main(int argc, char *argv[])
{
	int     cc;
	if(argc!=2){printf("usage: CONNOPEN connectionNumber\n");exit(1);}
	connectionNumber=atoi(argv[1]);
	//
	//  Build the request buffer
	//
	Request.sflen = (sizeof Request) ;
	Request.sfcode = 235;                       // subfunction code
	Request.connNumber = connectionNumber;
	Request.lastRecordSeen = 0;
	cc = NWSystemCall(23,&Request,sizeof Request,&Reply,sizeof Reply);
	printf("Function returned:    %03d--%#02x\n",cc,cc);
	if( cc == 0 ) {
		ProcessEntries();
		DisplayData();
		FreeEntries();
	}
}
