home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Encyclopedia 96-1
/
novell-nsepro-1996-1-cd2.iso
/
download
/
netware
/
partvw.exe
/
PARTVIEW.C
next >
Wrap
Text File
|
1994-11-29
|
24KB
|
1,021 lines
/****************************************************************************
** File: PARTVIEW.C
**
** Desc: This program discovers all of the File Servers in a tree, lists the
** partitions (replicas) on each and connects to each server to read
** the current Synchronized Up To value.
**
**
**
** DISCLAIMER
**
** Novell, Inc. makes no representations or warranties with respect to
** any NetWare software, and specifically disclaims any express or
** implied warranties of merchantability, title, or fitness for a
** particular purpose.
**
** Distribution of any NetWare software is forbidden without the
** express written consent of Novell, Inc. Further, Novell reserves
** the right to discontinue distribution of any NetWare software.
**
** Novell is not responsible for lost profits or revenue, loss of use
** of the software, loss of data, costs of re-creating lost data, the
** cost of any substitute equipment or program, or claims by any party
** other than you. Novell strongly recommends a backup be made before
** any software is installed. Technical support for this software
** may be provided at the discretion of Novell.
**
** Programmers:
**
** Ini Who Firm
** -----------------------------------------------------------------------
** KLB Karl Bunnell Novell Developer Support.
**
** History:
**
** When Who What
** -----------------------------------------------------------------------
** 10-28-94 klb First code.
*/
/****************************************************************************
** Include headers, macros, function prototypes, etc.
*/
/*------------------------------------------------------------------------
** MACROS
*/
#define NWDOS
/*------------------------------------------------------------------------
** ANSI
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <time.h>
/*------------------------------------------------------------------------
** NetWare
*/
#include <nwnet.h>
#include <nwcalls.h>
#include <nwlocale.h>
#include "partview.h"
/*------------------------------------------------------------------------
** Prototypes
*/
int ActOnData(NWDS_BUFFER NWFAR *buffer);
int SearchForObjects(void);
ReadPartInfo(char *serverName);
ReadSyncTimes(char *serverName, char *partName, struct PartRecord *ptrthis);
DisplayRetrievedInfo(void);
GetReplicaDescription(NWREPLICA_TYPE replicaType, char *replicaDesc);
FreeUpList(void);
/*------------------------------------------------------------------------
** Globals
*/
NWDSContextHandle dContext;
NWCOUNT objectCount;
struct ServerRecord *pfirst=NULL, *pthis=NULL, *pnew=NULL;
/****************************************************************************
** Function: Main (void)
*/
void main(void)
{
NWDSCCODE cCode;
LCONV lconvInfo;
DWORD flags;
char far *countryPtr;
cCode = NWCallsInit(NULL, NULL);
if (cCode)
{
printf("\nCall to NWCallsInit returned: %04X", cCode);
exit(1);
}
countryPtr = NWLsetlocale(LC_ALL, "");
NWLlocaleconv(&lconvInfo);
cCode = NWInitUnicodeTables(lconvInfo.country_id, lconvInfo.code_page);
if(cCode)
{
printf("NWInitUnicodeTables() returned: %04X\n", cCode);
goto _FreeUnicodeTables;
}
dContext = NWDSCreateContext();
if (dContext == ERR_CONTEXT_CREATION)
{
printf("NWDSCreateContext returned: %04X\n", cCode);
goto _FreeContext;
}
/*-------------------------------------------------------------------
** Get the current directory context flags so we can modify them.
*/
cCode = NWDSGetContext(
/* Contxt Handle */ dContext,
/* Key */ DCK_FLAGS,
/* Context Flags */ &flags
);
if (cCode < 0)
{
printf("NWDSGetContext returned: %04X\n", cCode);
goto _FreeContext;
}
/*-------------------------------------------------------------------
** Turn typeless naming on.
** Turn canonicalize names off. This means we will get full names.
*/
flags |= DCV_TYPELESS_NAMES;
flags &= ~DCV_CANONICALIZE_NAMES;
/*-------------------------------------------------------------------
** Set the directory context flags so they take effect.
*/
cCode = NWDSSetContext(
/* Context Handle */ dContext,
/* Key */ DCK_FLAGS,
/* Set Flag Value */ &flags
);
if (cCode < 0)
{
printf("NWDSSetContext returned: %04X\n", cCode);
goto _FreeContext;
}
SearchForObjects();
DisplayRetrievedInfo();
FreeUpList();
_FreeContext:
NWDSFreeContext(dContext);
_FreeUnicodeTables:
NWFreeUnicodeTables();
}
/****************************************************************************
** Function: int SearchForObjects(void)
** This function initializes the search filter and issues the request to
** return all attributes that meet the search criteria and the time stamp
** criteria.
*/
int SearchForObjects(void)
{
NWFLAGS searchAliases = FALSE,
allAttrs = FALSE;
NWDS_TYPE infoType = 0;
NWDS_ITERATION iterHandle = (NWDS_ITERATION)-1;
NWDS_BUFFER NWFAR *searchFilter = NULL,
NWFAR *attrNames = NULL,
NWFAR *retBuf = NULL;
NWDSCCODE cCode;
NWDS_NUM_OBJ cntObjectsToSearch,
cntObjectsSearched;
int i,
iterCnt = 0,
err=0;
void NWFAR *val;
NWSYNTAX_ID syntaxID;
NWDS_FILTER_CURSOR NWFAR *cur = NULL;
/*------------------------------------------------------------
** Allocate a buffer to contain the search expression
*/
cCode = NWDSAllocBuf(
/* Buffer Size */ DEFAULT_MESSAGE_LEN,
/* Buff. Point.*/ &searchFilter
);
if (cCode < 0)
{
printf("NWDSAllocBuf returned: %04X\n", cCode);
goto Out;
}
/*------------------------------------------------------------
** Initialize the searchFilter buffer
*/
cCode = NWDSInitBuf(
/* Context */ dContext,
/* Operation*/ DSV_SEARCH_FILTER,
/* buffer */ searchFilter
);
if (cCode < 0)
{
printf("NWDSInitBuf returned: %04X\n", cCode);
goto Out;
}
/*------------------------------------------------------------
** Allocate a filter cursor to put the search expression
*/
cCode = NWDSAllocFilter(
/* Cursor */ &cur
);
if (cCode < 0)
{
printf("NWDSAllocFilter returned: %04X\n", cCode);
goto Out;
}
/*------------------------------------------------------------
** Now we can build the expression tree.
** Filter on Object Class of "User".
*/
cCode = NWDSAddFilterToken(
/* Cursor (exp tree) */ cur,
/* TOKEN */ FTOK_ANAME,
/* Name or Value */ "Object Class",
/* Syntax ID */ SYN_CLASS_NAME
);
if (cCode < 0)
{
printf("NWDSAddFilterToken returned: %04X\n", cCode);
goto Out;
}
cCode = NWDSAddFilterToken(
/* Cursor (exp tree) */ cur,
/* TOKEN */ FTOK_EQ,
/* Name or Value */ NULL,
/* Syntax ID */ 0
);
if (cCode < 0)
{
printf("NWDSAddFilterToken returned: %04X\n", cCode);
goto Out;
}
cCode = NWDSAddFilterToken(
/* Cursor (exp tree) */ cur,
/* TOKEN */ FTOK_AVAL,
/* Name or Value */ "NCP Server",
/* Syntax ID */ SYN_CLASS_NAME
);
if (cCode < 0)
{
printf("NWDSAddFilterToken returned: %04X\n", cCode);
goto Out;
}
cCode = NWDSAddFilterToken(
/* Cursor (exp tree) */ cur,
/* TOKEN */ FTOK_AND,
/* Name or Value */ NULL,
/* Syntax ID */ 0
);
if (cCode < 0)
{
printf("NWDSAddFilterToken returned: %04X\n", cCode);
goto Out;
}
cCode = NWDSAddFilterToken(
/* Cursor (exp tree) */ cur,
/* TOKEN */ FTOK_ANAME,
/* Name or Value */ "Version",
/* Syntax ID */ SYN_CI_STRING
);
if (cCode < 0)
{
printf("NWDSAddFilterToken returned: %04X\n", cCode);
goto Out;
}
cCode = NWDSAddFilterToken(
/* Cursor (exp tree) */ cur,
/* TOKEN */ FTOK_EQ,
/* Name or Value */ NULL,
/* Syntax ID */ 0
);
if (cCode < 0)
{
printf("NWDSAddFilterToken returned: %04X\n", cCode);
goto Out;
}
cCode = NWDSAddFilterToken(
/* Cursor (exp tree) */ cur,
/* TOKEN */ FTOK_AVAL,
/* Name or Value */ "Novell Netware 4*",
/* Syntax ID */ SYN_CI_STRING
);
if (cCode < 0)
{
printf("NWDSAddFilterToken returned: %04X\n", cCode);
goto Out;
}
cCode = NWDSAddFilterToken(
/* Cursor (exp tree) */ cur,
/* TOKEN */ FTOK_END,
/* Name or Value */ NULL,
/* Syntax ID */ 0
);
if (cCode < 0)
{
printf("NWDSAddFilterToken returned: %04X\n", cCode);
goto Out;
}
/*-------------------------------------------------------------
** The expression is complete! Put the filter expression
** into the filter buffer. The freeVal function pointer
** would free the attribute values, but we allocated the
** values on the stack, so pass NULL.
*/
cCode = NWDSPutFilter(
/* Context Handle */ dContext,
/* Input Buffer */ searchFilter,
/* Cursor Pointer */ cur,
/* Free val. func */ NULL
);
if (cCode < 0)
{
printf("NWDSAddFilterToken returned: %04X\n", cCode);
goto Out;
}
else
cur = NULL; /* so we know at the bottom of this routine to free or not */
/*-------------------------------------------------------------
** Allocate a buffer to receive the results.
*/
cCode = NWDSAllocBuf(
/* Buffer Size */ DEFAULT_MESSAGE_LEN,
/* Buff. Point.*/ &retBuf
);
if (cCode < 0)
{
printf("NWDSAllocBuf returned: %04X\n", cCode);
goto Out;
}
do
{
/*---------------------------------------------------------
** Finally! we have everything we need to search. Note that
** the base object specified here is "[Root]". The base
** object could be an OU. This will initiate the search from
** that OU on down the tree.
*/
cCode = NWDSSearch(
/* Context handle */ dContext,
/* Base Obj Name */ "[Root]",
/* Scope */ DS_SEARCH_SUBTREE,
/* Search Alias? */ searchAliases,
/* Search Filter */ searchFilter,
/* Info Type */ infoType,
/* All Attrib's ? */ allAttrs,
/* Attrib. names */ attrNames,
/* Iter. Handle */ &iterHandle,
/* cnt Obj's 2 sch*/ cntObjectsToSearch,
/* cnt obj's schd */ &cntObjectsSearched,
/* Object returned*/ retBuf
);
if (cCode < 0)
{
printf("NWDSExtSyncSearch returned: %04X\n", cCode);
goto Out;
}
iterCnt++;
err = ActOnData(retBuf);
}
while (iterHandle != (NWDS_ITERATION)-1);
// printf("\n\n%d iterations of search\n", iterCnt);
Out:
if (retBuf)
NWDSFreeBuf(retBuf);
if (cur)
NWDSFreeFilter(cur, NULL);
if (searchFilter)
NWDSFreeBuf(searchFilter);
if (attrNames)
NWDSFreeBuf(attrNames);
return(0);
}
/****************************************************************************
** Function: int ActOnData(NWDS_BUFFER NWFAR *buffer)
** The buffer returned from NWDSSearch() is passed to this function. This
** buffer contains all of the object/attribute information that met the
** criteria of the search. This function reads this information from the
** buffer.
*/
int ActOnData(NWDS_BUFFER NWFAR *buffer)
{
NWDSCCODE dscCode;
NWCCODE cCode;
NWCOUNT attrCount,
attrValCount;
NWOBJECT_INFO objectInfo;
static char objectName[MAX_DN_CHARS + 1];
char shortName[48];
int err=1,
i;
NWNUMBER maxConnections;
dscCode = NWDSGetObjectCount(
/* Req. Context */ dContext,
/* P. to read buf.*/ buffer,
/* Num. of OBJs */ &objectCount
);
if (dscCode < 0)
{
printf("\nNWDSGetObjectCount returned : %04X\n", dscCode);
return(err);
}
NWGetMaximumConnections(
/* max connections */ &maxConnections
);
printf("\nMax connections: %d", maxConnections);
if(objectCount > maxConnections)
{
printf("\nInsufficient connection slots to run this program!\n");
printf("Add CONNECTIONS = 50 in the NET.CFG under the \n");
printf("NetWare DOS Requester header!\n");
return(err);
}
for (i = 0; i < objectCount; i++)
{
dscCode = NWDSGetObjectName(
/* Req. Context */ dContext,
/* P. to result buf */ buffer,
/* object name */ objectName,
/* Attribute count */ &attrCount,
/* object Info */ &objectInfo
);
if (dscCode < 0)
{
printf("\nNWDSGetObjectName returned: %04X\n", dscCode);
return(dscCode);
}
ReadPartInfo(objectName);
} /* end of objects loop */
return(0);
}
ReadPartInfo(char *serverName)
{
NWDSCCODE dscCode;
NWDS_ITERATION iterHandle = (NWDS_ITERATION)-1;
NWDS_BUFFER NWFAR *retBuf = NULL;
NWCOUNT partCount;
char partName[256];
char tempName[256];
NWREPLICA_TYPE replicaType;
struct PartRecord *ptrthis=NULL, *ptrnew=NULL, *ptrfirst=NULL;
int i;
/*----------------------------------------------------------------
** Allocate a buffer to receive the results.
*/
dscCode = NWDSAllocBuf(
/* Buffer Size */ DEFAULT_MESSAGE_LEN,
/* Buff. Point.*/ &retBuf
);
if (dscCode < 0)
{
printf("NWDSAllocBuf returned: %04X\n", dscCode);
goto Out;
}
pnew = (struct ServerRecord *) malloc( sizeof(struct ServerRecord));
if(pfirst == (struct ServerRecord *)NULL)
pfirst = pthis = pnew;
else
{
pthis = pfirst;
while ( pthis->pnext != (struct ServerRecord *)NULL)
pthis = pthis->pnext;
pthis->pnext=pnew;
pthis = pnew;
}
strcpy(pthis->serverName, serverName);
pthis->pnext = (struct ServerRecord *) NULL;
do
{
dscCode = NWDSListPartitions(
/* Context handle */ dContext,
/* Interation hndl*/ &iterHandle,
/* Server Name */ serverName,
/* Result Buffer */ retBuf
);
if (dscCode < 0)
{
printf("NWDSListPartitions returned: %04X\n", dscCode);
goto Out;
}
}
while (iterHandle != (NWDS_ITERATION)-1);
dscCode = NWDSGetServerName(
/* Context hndl */ dContext,
/* result Buffer*/ retBuf,
/* OUT server DN*/ tempName,
/* part. Count */ &partCount
);
if (dscCode < 0)
{
printf("NWDSGetServerName returned: %04X\n", dscCode);
goto Out;
}
for(i=0; i < partCount; ++i)
{
dscCode = NWDSGetPartitionInfo(
/* Context Handle */ dContext,
/* Result buffer */ retBuf,
/* partition name */ partName,
/* replica Type */ &replicaType
);
if (dscCode < 0)
{
printf("NWDSGetPartitionInfo returned: %04X\n", dscCode);
goto Out;
}
ptrnew = (struct PartRecord *) malloc( sizeof(struct PartRecord));
if(ptrfirst == (struct PartRecord *)NULL)
ptrfirst = ptrthis = ptrnew;
else
{
ptrthis = ptrfirst;
while ( ptrthis->pnext != (struct PartRecord *)NULL)
ptrthis = ptrthis->pnext;
ptrthis->pnext=ptrnew;
ptrthis = ptrnew;
}
strcpy(ptrthis->partRoot, partName);
ptrthis->replicaType = replicaType;
ptrthis->connectFail = 0;
ptrthis->pnext = (struct PartRecord *) NULL;
ReadSyncTimes(tempName, partName, ptrthis);
}
pthis->headlst = ptrfirst;
Out:
if (retBuf)
NWDSFreeBuf(retBuf);
return(0);
}
ReadSyncTimes(char *serverName, char *partName, struct PartRecord *ptrthis)
{
NWCCODE cCode, cCode2;
NWDSCCODE dscCode;
NWCONN_HANDLE connHandle;
NWCONN_HANDLE oldConnHandle;
char shortServerName[256];
char *ptr;
NWDS_BUFFER *outBuf, *inBuf;
NWDS_ITERATION iterHandle = -1L;
NWSYNTAX_ID syntax;
NWSIZE attrValSize;
NWCOUNT attrCount;
NWCOUNT valCount;
char attrName[MAX_DN_CHARS + 1];
void *attrVal;
int h, i, j, k, cnt;
char *attrList[] =
{
"Synchronized Up To"
};
if (ptrthis->replicaType > 2)
{
strcpy(shortServerName, serverName);
ptr = strchr(shortServerName, '.');
if (ptr)
shortServerName[ptr-shortServerName] = '\0';
cCode = NWGetDefaultConnectionID(
/* connection handle */ &oldConnHandle
);
cCode = NWGetConnectionHandle(
/* Server Name */ shortServerName,
/* reserved */ 0,
/* Connection hand */ &connHandle,
/* reserved */ NULL
);
if ( cCode == INVALID_CONNECTION )
{
cCode2 = NWAttachToFileServer(
/* Server Name */ shortServerName,
/* scope */ 0,
/* new conn handle */ &connHandle
);
if (cCode2)
{
printf("NWAttachToFileServer returned: %04X\n", cCode2);
ptrthis->connectFail = 1;
goto cleanUp;
}
}
/*-------------------------------------------------------------------
** The followin NWDSSetContext() is used to ensure that the read call
** is issued to the server that actually contains the replica.
*/
dscCode = NWDSSetContext(
/* context handle */ dContext,
/* Key (command) */ DCK_LAST_CONNECTION,
/* connection hand*/ &connHandle
);
if (dscCode < 0)
{
printf("NWDSSetContext returned: %04X\n", dscCode);
goto cleanUp;
}
}
/*-------------------------------------------------------------------
** Read the object info.
*/
dscCode = NWDSAllocBuf(
/* Buffer Size */ DEFAULT_MESSAGE_LEN,
/* Buff. Point.*/ &inBuf
);
if (dscCode < 0)
{
printf("NWDSAllocBuf returned: %04X\n", dscCode);
return(1);
}
dscCode = NWDSInitBuf(
/* Context */ dContext,
/* Operation*/ DSV_READ,
/* buffer */ inBuf
);
if (dscCode < 0)
{
printf("NWDSInitBuf returned: %04X\n", dscCode);
NWDSFreeBuf(inBuf);
return(1);
}
dscCode = NWDSAllocBuf(
/* Buffer Size */ DEFAULT_MESSAGE_LEN,
/* Buff. Point.*/ &outBuf
);
if (dscCode < 0)
{
printf("NWDSAllocBuf returned: %04X\n", dscCode);
NWDSFreeBuf(inBuf);
return(1);
}
for(h = 0; h < 1; ++h)
{
dscCode = NWDSPutAttrName(
/* context */ dContext,
/* in buffer */ inBuf,
/* attr. name*/ (char NWFAR*)attrList[h]
);
if (dscCode < 0)
{
printf("NWDSPutAttrName returned: %04X\n", dscCode);
NWDSFreeBuf(inBuf);
NWDSFreeBuf(outBuf);
return(1);
}
}
do
{
dscCode = NWDSRead(
/* Context */ dContext,
/* Object name */ partName,
/* Info. Type */ DS_ATTRIBUTE_VALUES,
/* All Attrib ?*/ FALSE,
/* Attri. names*/ inBuf,
/* Iter. Handle*/ &iterHandle,
/* Object info */ outBuf
);
if (dscCode < 0)
{
printf("\nNWDSRead returned: %04X\n", dscCode);
NWDSFreeBuf(inBuf);
NWDSFreeBuf(outBuf);
return(1);
}
}
while (iterHandle != (NWDS_ITERATION)-1);
/*----------------------------------------------------------------
** Read Received Up to value
*/
dscCode = NWDSGetAttrCount(
/* Context */ dContext,
/* attr. buff */ outBuf,
/* num of attr*/ &attrCount
);
if (dscCode < 0)
{
printf("\nNWDSGetAttrCount returned: %04X\n", dscCode);
return(1);
}
for (i = 0; i < attrCount; i++)
{
dscCode = NWDSGetAttrName(
/* Context */ dContext,
/* attrib. buf */ outBuf,
/* attrib name */ attrName,
/* attr. val. cnt */ &valCount,
/* Syntax ID */ &syntax
);
if (dscCode < 0)
{
printf("\nNWDSGetAttrName returned: %04X\n", dscCode);
return(1);
}
/*--------------------------------------------------------------
** Get Received up to value.
*/
for (j = 0; j < valCount; j++)
{
dscCode = NWDSComputeAttrValSize(
/* Context handle */ dContext,
/* Result Buffer */ outBuf,
/* Syntax ID */ syntax,
/* Size of attrib.*/ &attrValSize
);
attrVal = (void NWFAR *)malloc(attrValSize);
dscCode = NWDSGetAttrVal(
/* Context */ dContext,
/* read buf */ outBuf,
/* syntax id*/ syntax,
/* attr. val*/ attrVal
);
if (dscCode < 0)
{
printf("\nNWDSGetAttrVal returned: %04X\n", dscCode);
return(1);
}
if (j == 2)
{
memcpy(&ptrthis->synchronizedUpTo, attrVal, attrValSize);
}
free(attrVal);
}
}
cleanUp:
if (ptrthis->replicaType > 2)
{
dscCode = NWDSSetContext(
/* context handle */ dContext,
/* Key (command) */ DCK_LAST_CONNECTION,
/* connection hand*/ &oldConnHandle
);
if (dscCode < 0)
printf("NWDSSetContext returned: %04X\n", dscCode);
}
return(0);
}
DisplayRetrievedInfo(void)
{
struct tm *reptm;
struct PartRecord *ptrthis=NULL;
char replicaDescription[30];
pthis = pfirst;
putenv("TZ=MST7MDT");
tzset();
do
{
printf("\nServer Name : %s", pthis->serverName);
printf("\n\n\tPartitions : ");
ptrthis = (struct PartRecord *)pthis->headlst;
if (ptrthis == (struct PartRecord *)NULL)
{
printf("\nNone...");
}
while (ptrthis != (struct PartRecord *)NULL)
{
printf("\n\tPartition Name : %s", ptrthis->partRoot);
GetReplicaDescription(ptrthis->replicaType, replicaDescription);
printf("\n\tPartition Type : %s", replicaDescription);
if (ptrthis->connectFail)
{
printf("\n\tUnable to connect to server %s .", pthis->serverName);
printf("\n\tSynchronized Up To time stamp unverified for this server!");
}
else
{
if(ptrthis->replicaType <= 2)
{
reptm = localtime(&ptrthis->synchronizedUpTo.wholeSeconds);
printf("\n\tSynchronized Up To Time : %s", asctime(reptm));
}
else
{
printf("\n\tSync Time N/A for this replica type\n");
}
}
ptrthis = ptrthis->pnext;
}
pthis = pthis->pnext;
}
while ( pthis != (struct ServerRecord *)NULL);
return(0);
}
GetReplicaDescription(NWREPLICA_TYPE replicaType, char *replicaDesc)
{
switch(replicaType)
{
case 0x00:
strcpy(replicaDesc, "Master");
break;
case 0x01:
strcpy(replicaDesc, "Read/Write");
break;
case 0x02:
strcpy(replicaDesc, "Read Only");
break;
case 0x03:
strcpy(replicaDesc, "Subordinate Reference");
break;
}
}
FreeUpList(void)
{
struct PartRecord *ptrthis, *ptrfirst;
while (pfirst != (struct ServerRecord *)NULL)
{
pthis=pfirst->pnext;
ptrfirst = (struct PartRecord *)pfirst->headlst;
while (ptrfirst != (struct PartRecord *)NULL)
{
ptrthis = ptrfirst->pnext;
free(ptrfirst);
ptrfirst=ptrthis;
}
free(pfirst);
pfirst=pthis;
}
return(0);
}