📄 slist.m
字号:
/*****************************************************************************
EXHIBIT A
"The contents of this file are subject to the Novell Free Source Agreement
Version 1.0 (the "Agreement"); you may not use this file except in
compliance with the Agreement. You may obtain a copy of the Agreement at
http://developer.novell.com/.
Software distributed under the Agreement is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the Agreement
for the specific language governing rights and limitations under the
Agreement.
The Original Code is slist.m, released under the Novell Free Source License
Agreement 1.0 on 1999.
The Initial Developer of the Original Code is Novell. Portions created
by Novell are Copyright (C) 1988-93, Novell, Inc. All Rights Reserved.
*****************************************************************************/
#include "SList.H"
/****************************************************************************/
/*
Global variables
*/
int pause, /* Should we pause during output? */
doDomain, /* Domain option to output Domains on internet */
outputToFile, /* Is output going to a file? */
linesPerScreen; /* Number of lines to be printed per screen */
char targetServer[SERVER_NAME_SIZE]; /* Server name or pattern to match */
WORD numberConnInUse; /* Used to check for free conn to get Domain Names */
char *VERSION = "VeRsIoN=3.75";
char *COPYRIGHT = "CoPyRiGhT=(c) Copyright 1988-1993, Novell, Inc. All rights reserved.";
char *NNS_MSG = "NaMe SeRvIcE=A NetWare Name Service Utility";
/****************************************************************************/
/*
Description: Main routine for SList
Called by: Other worldly forces
*/
void main(argc, argv)
int argc; /* Number of command line arguments */
char *argv[]; /* Command line arguments */
{
int numServers, /* Number of servers found */
i; /* Loop counter */
char commandLine[256]; /* Command line arguments */
WORD ccode, /* Error code */
connection; /* Default connection */
/*
Assume that we are going to pause after each screen full
*/
pause = TRUE;
/*
If we are not sending output to the screen, don't pause
*/
SetScrollParms();
/*
Assume they want to list all servers
*/
strcpy(targetServer, "*");
/*
Put all the arguments into one command line buffer and convert
it to upper case
*/
strcpy(commandLine, "");
for ( i = 1 ; i < argc ; i++ )
{
if (i > 1)
strcat(commandLine, " ");
strcat(commandLine, strupr(argv[i]));
}
/*
Make sure there are no control characters in the command line
*/
for ( i = 0 ; commandLine[i] != '\0' ; i++ )
if (commandLine[i] < ' ' || commandLine[i] >= '\x7F')
Error(E_CONTROL_CHARACTERS_FOUND);
/*
Try to parse the command line
*/
DefineTokenTable(INITIALTOKENCOUNT, MAXTOKENCOUNT);
SetParseAddress(commandLine);
if (!Parse())
DisplayUsageLine();
/*
Get a connection number to work with
*/
ccode = NWGetDefaultConnectionID(&connection);
if (ccode)
Error(E_NO_DEFAULT_CONNECTION, ccode);
if(doDomain)
{
/* One free connection is necessary to attach to servers to
get Domain Names */
NWGetConnectionList (MY_SESSION, (WORD *)NULL, (WORD)NULL, &numberConnInUse);
if (numberConnInUse > 7)
Error(E_MAX_CONN_FOR_DOMAIN);
DisplayDomainNames(connection);
exit(0);
}
/*
Read in the server names
*/
numServers = ReadServerNames(serverList, connection);
/*
Sort the servers by name
*/
SortServerNames(serverList, numServers);
/*
Print out the server names
*/
PrintServerNames(serverList, numServers, connection);
/*
Now, wasn't that easy?
*/
exit(0);
}
/****************************************************************************/
/*
Description: Displays all Domain Names found on the internet.
Called by: Main
*/
void DisplayDomainNames(defaultConnectionID)
WORD defaultConnectionID;
{
long serverID;
LIST *l, *serverPtr, *listPtr;
WORD currConnectionID, ccode, attachCCODE, more;
char serverName[SERVER_NAME_SIZE];
BYTE serverDomain[PROPERTY_NAME_SIZE];
int i,next, numberFound = 0, advanceFlag = TRUE;
/* Let them know this may take a while */
fprintf(stderr, GetMessage(READING_DOMAIN_NAMES));
fprintf(stderr, "\n");
/* First build server list. */
InitList();
serverID = -1L; /* Set up for scan sequence */
for (i = 0; ;i++)
{
ccode = NWScanObject(defaultConnectionID, "*", OT_FILE_SERVER, &serverID,
serverName, (WORD far *)NULL, (BYTE far *)NULL,
(BYTE far *)NULL, (BYTE far *)NULL);
if (ccode != 0)
break;
l = AppendToList(serverName, (char *)NULL);
if (l == NULL)
{
Error(E_BUILDING_SERVER_LIST);
}
}
/* Attach to servers found in server list, check if in given domain. */
for(serverPtr = GetListHead(); serverPtr != NULL;serverPtr )
{
/* print out dots to show that something is still happening */
advanceFlag = TRUE; /* ART-this flag is used to determine when to */
/* advance in the list, and when not to. */
fprintf(stderr, GetMessage(CHECKING), serverPtr->text);
attachCCODE = NWAttachToFileServer(serverPtr->text, (WORD)0, &currConnectionID);
if((attachCCODE == 0) || (attachCCODE == ALREADY_ATTACHED))
{
/* See if server has DOMAIN_NAME property, if so it's value */
ccode = NWReadPropertyValue(currConnectionID, serverPtr->text,
OT_FILE_SERVER, "DOMAIN_NAME", 1, serverDomain,
NULL, NULL);
if (ccode == 0)
{
/* If there is a Domain is on current server */
/* Copy the Domain name into the table for sorting */
strcpy(serverList[numberFound].name, serverDomain);
/* Increment number of Domains found */
numberFound++;
/* Remove all servers in that Domain from the master server list */
more = next = 0;
while (more != NO_SUCH_SEGMENT)
{
next++;
more = GetServerName(currConnectionID, DOMAIN_OBJ_TYPE,
(char *)serverDomain, serverName, next);
if(more == 0) /* ART - No need to check the last entry again */
{
for(listPtr = GetListHead(); listPtr != NULL;
listPtr = listPtr->next)
{
if(!strcmp(listPtr->text, serverName))
{
if ( serverPtr == listPtr ) /* if name is at head of list */
{
serverPtr = serverPtr->next; /* advance the head now */
advanceFlag = FALSE; /* make sure the head of the list */
} /* is not advanced later */
DeleteFromList(listPtr); /* now you can delete the pointer */
break; /* stop the comparison */
}
}
}
}
}
}
if(attachCCODE != ALREADY_ATTACHED)
NWDetachFromFileServer(currConnectionID);
if ( advanceFlag == TRUE ) /* only advance the head pointer if the flag is set */
serverPtr = serverPtr->next;
}
DestroyList();
SortServerNames(serverList, numberFound);
/* Remove the Reading Domain Names message from the screen */
fprintf(stderr, GetMessage(ERASE_LINE));
/* If output is being sent to a file, tell user that we are doing so */
if (outputToFile)
fprintf(stderr, GetMessage(WRITING_TO_FILE));
/* Now print out all the Domains */
for ( i = 0 ; i <= numberFound-1 ; i++ )
Print("%-47.47s\n", serverList[i].name);
/* Tell how many Domains were found */
if (numberFound)
Print(GetMessage(NUMBER_OF_DOMAINS_FOUND), numberFound);
else
Print(GetMessage(NO_DOMAINS_FOUND));
/* If data was being written to a file, erase the line that
tells him we are writing to the file
*/
if (outputToFile)
fprintf(stderr, GetMessage(ERASE_LINE));
exit(0);
}
/* for use in putting out dots */
void CheckDot( void )
{
static time_t first_time=0;
static time_t next_time=0;
static int dots = 0;
time(&next_time);
if (next_time - first_time > 5)
{
first_time = next_time;
fprintf(stderr, ".");
dots++;
if (dots > 50)
fprintf(stderr, "\n");
}
}
/****************************************************************************/
/*
Description: Gets a server name from SERVERS property of a Domain object.
Called by: Display Domain Names
*/
WORD GetServerName(WORD connectID, WORD type, char *name,char *server,int next)
{
BYTE propValue[PROPERTY_NAME_SIZE];
BYTE moreSeg = 0;
WORD ccode = 0;
strset(propValue, 0);
ccode = NWReadPropertyValue(connectID, name, type, "SERVERS",
(BYTE)((next/2)+(next%2)), propValue, &moreSeg, NULL);
if (ccode != 0)
return(NO_SUCH_SEGMENT); /* if no more segments, return now */
if (next%2) /* first half */
memmove(server, propValue, 47);
else /* second half */
memmove(server, &propValue[48], 47);
if ((server[0]>32) && (strlen(server) != 0))
return(0); /* ok */
else
{
server[0] = NULL;
return(1); /* no name at that position */
}
}
/****************************************************************************/
/*
Description: Read in a list of all the servers and their addresses
Called by: Main
*/
int ReadServerNames(serverList, connection)
SERVER serverList[]; /* List of servers and their addresses */
WORD connection; /* Default connection */
{
WORD ccode1, /* Return code from ScanObject calls */
ccode2; /* Return code from ReadProperty calls */
int numberFound = 0, /* Number of servers found */
match; /* Should this server be included? */
long objectID = -1L; /* Object number for ScanObject */
char objectName[OBJECT_NAME_SIZE]; /* Object name from ScanObject */
NETADDRESS address; /* Address property read from bindery */
/*
Let the user know we are doing something
*/
fprintf(stderr, GetMessage(READING_SERVER_NAMES));
/*
Prime the pump with the first server
*/
ccode1 = NWScanObject(connection, "*", OT_FILE_SERVER, &objectID,
objectName, NULL, NULL, NULL, NULL);
while (ccode1 == 0)
{
/*
Does this server meet the qualifications?
*/
if (IsWild(targetServer))
match = WildMatch(targetServer, objectName);
else
match = strcmp(targetServer, objectName) == 0;
if (match)
{
/*
Make sure we haven't exceeded the maximum number of servers
*/
if (numberFound >= MAX)
Error(E_TOO_MANY_SERVERS, MAX);
/*
Copy the file server name into the table
*/
strcpy(serverList[numberFound].name, objectName);
/*
Now try to read the network address for the server
*/
ccode2 = NWReadPropertyValue(connection, objectName,
OT_FILE_SERVER, "NET_ADDRESS", 1,
(BYTE *)&address, NULL, NULL);
/*
If network address was read correctly, save it, otherwise
flag it as being unknown
*/
if (ccode2 == 0)
{
address.netAddress = NWLongSwap(address.netAddress);
address.highNode = NWWordSwap(address.highNode );
address.lowNode = NWLongSwap(address.lowNode );
if (address.highNode == 0)
sprintf(serverList[numberFound].addr,
GetMessage(FORMAT_ONE), address.netAddress,
address.lowNode);
else
sprintf(serverList[numberFound].addr,
GetMessage(FORMAT_TWO), address.netAddress,
address.highNode, address.lowNode);
}
else
sprintf(serverList[numberFound].addr,
GetMessage(CANT_READ_ADDRESS));
/*
Increment number of servers found
*/
numberFound++;
}
/*
Try to find another file server
*/
ccode1 = NWScanObject(connection, "*", OT_FILE_SERVER, &objectID,
objectName, NULL, NULL, NULL, NULL);
}
/*
Make sure we didn't get any bizarre error
*/
if (ccode1 != NO_SUCH_OBJECT)
Error(E_READING_SERVER_NAMES, ccode1);
return (numberFound);
}
/****************************************************************************/
/*
Description: Sort the list of the servers
Called by: Main
*/
void SortServerNames(serverList, numServers)
SERVER serverList[]; /* List of servers and their addresses */
int numServers; /* Number of servers found */
{
int i, /* Loop variable */
j; /* Loop variable */
char tempName[SERVER_NAME_SIZE], /* Used for copying server name */
tempAddr[26]; /* Used for copying server address */
/*
I'm a simple man with simple tastes, so a bubble sort will do
*/
for ( i = 0 ; i < numServers-1 ; i++ )
for ( j = 0 ; j < numServers-1 ; j++ )
if (strcmp(serverList[j].name, serverList[j+1].name) > 0)
{
/*
Switch the server names
*/
strcpy(tempName, serverList[j].name );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -