{\rtf0\ansi{\fonttbl\f0\fmodern Courier;}
\paperw11760
\paperh7800
\margl120
\margr120
{\colortbl;\red0\green0\blue0;}
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\ulnone\fs24\fc1\cf1 #import "NetrcEntry.h"\
\
#import <appkit/appkit.h>\
\

\b0\i // NetrcEntry class list of entries for current user
\b\i0 \
static ObjectList *userEntries;\
static BOOL needToSaveEntries = NO;\
\
@implementation NetrcEntry\
\

\b0\i\fs28 /*\\ ------ Class Methods ------ \\*/
\b\i0\fs24 \
+ initialize\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker254 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  This class method allocates and fills the class\
		userEntries list of NetrcEntry objects.  It first looks to\
		the user's .netrc and then to ~/.AppInfo/Archie.netrc.;
\fc0\cf0 \
	
\i0\ul Args:
\i\ulnone \
		sender: The ªHosts...º button in the FTP menu;\
*/
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 char path[MAXPATHLEN], appInfo[MAXPATHLEN];\
FILE *netrcFile;\
int encryptTag;\
\
	if( userEntries != 0 )\
		return self;\
\
	// Allocate the class's list of NetrcEntrys\
	userEntries = [[ObjectList alloc] initCount: 0 sortAlgorithm: eShellSort\
		typeID: eStringType keyMethod: @selector(hostname)];\
\
	// Look for ~/.netrc file\
	sprintf(path, "%s/.netrc", NXHomeDirectory());\
	netrcFile = fopen(path, "r");\
	if( netrcFile != 0 )\
		[self parseNetrcFile: netrcFile fromDotFile: YES];\
\
	// Look for ~/.AppInfo/Archie.netrc file\
	sprintf(appInfo, "%s/.AppInfo", NXHomeDirectory());\
	sprintf(path, "%s/.AppInfo/Archie.netrc", NXHomeDirectory());\
#ifdef USE_WSM_CRYPT\
	// Decrypt the file\
	encryptTag = [[Application workspace] performFileOperation:\
		WSM_DECRYPT_OPERATION source: appInfo destination: "/tmp"\
		files: "Archie.netrc" options: 0];\
	if( encryptTag < 0 )\
	\{\
		[self debug: LOW_DEBUG method:_cmd, "Failed to decrypt Archie.netrc"];\
		return self;\
	\}\
#endif\
	netrcFile = fopen(path, "r");\
	if( netrcFile != 0 )\
		[self parseNetrcFile: netrcFile fromDotFile: NO];\
\
	return self;\
\} 
\b0\i // End initialize
\b\i0 \
\
+ parseNetrcFile:(FILE *) netrcFile fromDotFile:(BOOL) flag\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker1699 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  This class method parses the .netrc formatted file\
		for these fields:\

\i0 			machine name\
			login name\
			password string\

\i 		For each successful set of entries it creates a NetrcEntry object\
		and addes it to userEntries list using the addEntry method.;
\fc0\cf0 \
	
\i0\ul Args:
\i\ulnone \
		netrcFile: The .netrc formatted file stream to parse;\
		flag: A flag indicating if this is the ~/.netrc file;\
*/
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 NetrcEntry *netrcEntry;\
char password[32], machine[MAXHOSTNAMELEN+1], login[64];\
int success;\
\
	do\
	\{	
\b0\i // Parse the .netrc formatted file for all machine entries
\b\i0 \
		success = fscanf(netrcFile, "%*[^m]machine %s", machine);\
		if( success != 1 )\
			continue;\
		success = fscanf(netrcFile, "%*[^l]login %s", login);\
		if( success != 1 )\
			continue;\
		success = fscanf(netrcFile, "%*[^p]password %s", password);\
		if( success != 1 )\
			continue;\
		netrcEntry = [[NetrcEntry alloc] init: machine login: login\
			passwd: password setDotEntry: flag];\
		[self addEntry: netrcEntry];\
	\} while( !feof(netrcFile) );\
\
	return self;\
\} 
\b0\i // End parseNetrcFile:fromDotFile:
\b\i0 \
\
+ saveNetrcEntries\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker2810 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self if successful, Nil on failure;\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  This class method saves the userEntries list to the\
		file ~/.AppInfo/Archie.netrc.  If this file cannot be opened or\
		created Nil is returned to indicate the failure. Only those\
		NetrcEntrys that were not created from the user's ~/.netrc entry\
		are saved by this method.;
\fc0\cf0 \
	
\i0\ul Args:
\i\ulnone \
*/
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 char path[MAXPATHLEN], appInfo[MAXPATHLEN];\
FILE *netrcFile;\
NetrcEntry *netrcEntry;\
int index, encryptTag;\
\
	if( userEntries == 0 || [self needToSaveEntries] == NO )\
		return Nil;\
\
	
\b0\i // Open ~/.AppInfo/Archie.netrc file
\b\i0 \
	sprintf(appInfo, "%s/.AppInfo", NXHomeDirectory());\
	sprintf(path, "%s/.AppInfo/Archie.netrc", NXHomeDirectory());\
	netrcFile = fopen(path, "w");\
	if( netrcFile == 0 )\
	\{	
\b0\i // Create the file and .AppInfo directory
\b\i0 \
		if( access(appInfo, F_OK) == -1 )\
		\{	
\b0\i // The .AppInfo directory does not exist
\b\i0 \
			if( mkdir(appInfo, 0777) == -1 )\
			\{\
				[self systemErr: "Failed to create ~/.AppInfo dir" method:_cmd];\
				return Nil;\
			\}\
		\}\
		else if( access(appInfo, W_OK) == -1 )\
		\{	
\b0\i // Cannot write into .AppInfo
\b\i0 \
			[self systemErr: "Cannot write FTP host info to ~/.AppInfo dir"\
				method:_cmd];\
			return Nil;\
		\}\
		else if( chmod(path, 0600) == -1 )\
		\{	
\b0\i // File must exist but cannot make it writable
\b\i0 \
			[self systemErr: "Cannot write FTP host info to ~/.AppInfo dir"\
				method:_cmd];\
			return Nil;\
		\}\
		
\b0\i // Try one more time to open the file
\b\i0 \
		netrcFile = fopen(path, "w");\
		if( netrcFile == 0 )\
		\{\
			[self systemErr: "Cannot open FTP host file Archie.netrc"\
				method:_cmd];\
			return Nil;\
		\}\
	\}\
\
	
\b0\i /* Traverse the list of NetrcEntrys and write those not in the\
		user's ~/.netrc file to the Archie netrc file */
\b\i0 \
	index = 0;\
	while( (netrcEntry = [userEntries objectAt: index]) != nil )\
	\{\
		index ++;\
		if( [netrcEntry isDotEntry] == YES )\
			continue;\
		fprintf(netrcFile, "machine %s\\n", [netrcEntry hostname]);\
		fprintf(netrcFile, "login %s\\n", [netrcEntry username]);\
		fprintf(netrcFile, "password %s\\n\\n", [netrcEntry passwd]);\
	\}\
	fclose(netrcFile);\
	chmod(path, 0600);\
	[self setNeedToSaveEntries: NO];\
\
#ifdef USE_WSM_CRYPT\
	// Encrypt the file\
	encryptTag = [[Application workspace] performFileOperation:\
		WSM_ENCRYPT_OPERATION source: appInfo destination: "/tmp"\
		files: "Archie.netrc" options: 0];\
	if( encryptTag < 0 )\
		[self debug: LOW_DEBUG method:_cmd, "Failed to encrypt Archie.netrc"];\
#endif\
\
	return self;\
\} 
\b0\i // End saveNetrcEntries
\b\i0 \
\
+ (BOOL) needToSaveEntries\
\{\
	return needToSaveEntries;\
\}\
\
+ setNeedToSaveEntries:(BOOL) flag\
\{\
	needToSaveEntries = flag;\
	return self;\
\}\
\
+ (ObjectList *) userNetrcEntries\
\{\
	return userEntries;\
\}\
\
+ (NetrcEntry *) findNetrcInfo:(const char *) machine\
\{\

\b0\i /* --- 
\ul MethodDescription
\ulnone \
	
\ul ReturnValue:
\ulnone  A pointer to a NetrcEntry if successful, nil otherwise;\
	
\ul Description:
\ulnone  This method searches the class NetrcInfo list for\
		for an entry matching the argument machine hostname.;\
	
\ul Args:
\ulnone \
		hostname: the hostname to find a 'machine' entry for;\
*/
\b\i0 \
NetrcEntry *theEntry;\
\
	theEntry = [userEntries findObjectWithData:(void *) machine];\
\
	return theEntry;\
\}\
\
+ (BOOL) addEntry:(NetrcEntry *) entry\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker5954 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  YES if entry is added, NO if not;\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  This class method adds the entry to the class\
		NetrcEntry list if it is not already there and returns YES. If\
		the entry already exists nothing is added and NO is returned.;
\fc0\cf0 \
	
\i0\ul Args:\

\i\ulnone\fc1\cf1 		entry: The NetrcEntry instance to add;
\fc0\cf0 \
*/
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 BOOL added;\
\
	if( [userEntries findObject: entry] != nil )\
		return NO;\
	added = ([userEntries insertObject: entry] != NX_NOT_IN_LIST ? YES : NO);\
	if( added == YES && [entry isDotEntry] == NO )\
		[NetrcEntry setNeedToSaveEntries: YES];\
\
	return added;\
\} 
\b0\i // End addEntry:
\b\i0 \
\
+ (BOOL) removeEntry:(NetrcEntry *) entry\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker6586 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  YES if entry is removed, NO if not;\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  This class method removes the entry from the class\
		NetrcEntry list if it is there and returns YES. If the\
		entry is not found NO is returned.;
\fc0\cf0 \
	
\i0\ul Args:\

\i\ulnone\fc1\cf1 		entry: The NetrcEntry instance to remove;
\fc0\cf0 \
*/
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 	if( [userEntries removeObject: entry] == nil )\
		return NO;\
\
	return YES;\
\} 
\b0\i // End removeEntry:
\b\i0 \
\
/*\\ ------ Initialization Methods ------ \\*/\
- init:(const char *) machine login:(const char *) login\
	passwd:(const char *) password setDotEntry:(BOOL) flag\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker7134 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  Initializes an instance from the machine, login,\
		password components of a .netrc style entry. The setDotEntry\
		flag is YES if the components come from the user's ~/.netrc\
		file.;
\fc0\cf0 \
	
\i0\ul Args:\

\i\ulnone\fc1\cf1 		machine: The hostname;\
		login: The username;\
		password: The login password;\
		flag: A flag indicating if this entry is from ~/.netrc;
\fc0\cf0 \
*/
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 	[super init];\
\
	hostname = NXCopyStringBuffer(machine);\
	username = NXCopyStringBuffer(login);\
	if( password != 0 )\
		passwd = NXCopyStringBuffer(password);\
	isDotEntry = flag;\
\
	return self;\
\}	
\b0\i // End init:login:passwd:setDotEntry:
\b\i0 \
\
- update:(const char *) machine login:(const char *) login\
	passwd:(const char *) password\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker7852 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  Updates the NetrcEntry fields and resorts the class\
		NetrcEntry list.;
\fc0\cf0 \
	
\i0\ul Args:\

\i\ulnone\fc1\cf1 		machine: The new hostname;\
		login: The new username;\
		password: The new login password;\

\fc0\cf0 */
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 	if( hostname )\
		free(hostname);\
	hostname = NXCopyStringBuffer(machine);\
	if( username )\
		free(username);\
	username = NXCopyStringBuffer(login);\
	if( passwd )\
		free(passwd);\
	if( password )\
		passwd = NXCopyStringBuffer(password);\
	[userEntries sort];\
\
	return self;\
\}	
\b0\i // End update:login:passwd:
\b\i0 \
\
- setHostname:(const char *) machine\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker8427 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self if machine updates the hostname, nil if not;\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  Updates the NetrcEntry hostname instance variable\
		from machine it is non-null and distinct from hostname. If\
		hostname is updated the class NetrcEntry list is resorted.;
\fc0\cf0 \
	
\i0\ul Args:\

\i\ulnone\fc1\cf1 		machine: The new hostname;\

\fc0\cf0 */
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 	if( machine == 0 || strcmp(hostname, machine) == 0 )\
		return nil;\
	if( hostname )\
		free(hostname);\
	hostname = NXCopyStringBuffer(machine);\
	[userEntries sort];\
\
	return self;\
\}	
\b0\i // End setHostname:
\b\i0 \

\b0\i \

\b\i0 - setLogin:(const char *) login;\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker8980 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self if machine updates the hostname, nil if not;\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  Updates the NetrcEntry username instance variable\
		from login it is non-null and distinct from username. If\
		username is updated the class NetrcEntry list is resorted.;
\fc0\cf0 \
	
\i0\ul Args:\

\i\ulnone\fc1\cf1 		login: The new username;\

\fc0\cf0 */
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 	if( login == 0 || strcmp(username, login) == 0 )\
		return nil;\
	if( username )\
		free(username);\
	username = NXCopyStringBuffer(login);\
	[userEntries sort];\
\
	return self;\
\}	
\b0\i // End setLogin:
\b\i0 \

\b0\i \

\b\i0 - setPasswd:(const char *) password;\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker9524 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self if password updates the passwd, nil if not;\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  Updates the NetrcEntry passwd instance variable\
		from password it is non-null and distinct from passwd;
\fc0\cf0 \
	
\i0\ul Args:\

\i\ulnone\fc1\cf1 		password: The new passwd;\

\fc0\cf0 */
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 	if( password == 0 || strcmp(passwd, password) == 0 )\
		return nil;\
	if( passwd )\
		free(passwd);\
	passwd = NXCopyStringBuffer(password);\
\
	return self;\
\}	
\b0\i // End setPasswd:
\b\i0 \
\
- free\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker9953 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  [super free];\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  Frees the hostname, username, and passwd strings;
\fc0\cf0 \
	
\i0\ul Args:\

\i\ulnone */
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 	if( hostname )\
		free(hostname);\
	if( username )\
		free(username);\
	if( passwd )\
		free(passwd);\
	return [super free];\
\}	
\b0\i // End free
\b\i0 \
\

\b0\i /*\\ ------ Information Methods ------ \\*/
\b\i0 \
- (const char *) hostname\
\{\
	return hostname;\
\}\
- (const char *) username;\
\{\
	return username;\
\}\
- (const char *) passwd;\
\{\
	return passwd;\
\}\
- (const char *) displayName;\
\{	
\b0\i // Form a name of the form hostname:user
\b\i0 \

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker10473 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  A pointer to a string of the form hostname:username;\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  The displayName is the concatination of the hostname\
		and username seperated by a colon. The pointer returned is only\
		valid until the next invocation of this method.;
\fc0\cf0 \
	
\i0\ul Args:\

\i\ulnone */
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 static char displayName[MAXHOSTNAMELEN];\
	sprintf(displayName, "%s:%s", hostname, username);\
	return displayName;\
\}\
- (BOOL) isDotEntry\
\{\
	return isDotEntry;\
\}\
\
- (int) compare: anObject typeID:(int) typeID\
	size:(int) size keyMethod:(SEL) keyMethod;\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker11013 \markername doLogin:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  0, -1, or 1 to indicate a value equal to, less than,\
		or greater than anObject respectively;\
	
\i0\ul Description:
\i\ulnone\fc1\cf1  An override of the SortableObject compare method.\
		Comparison of NetrcEntries is based first on hostname, then\
		username using strcmp().;
\fc0\cf0 \
	
\i0\ul Args:\

\i\ulnone\fc1\cf1 		anObject: The NetrcEntry instance to compare against;\
		typeID: The type of anObject's keyMethod. Ignored here.;\
		size: The size of anObject's keyMethod type. Ignored here.;\
		keyMethod: The method that returns anObject's key value. Ignored here.;\

\fc0\cf0 */
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b\i0\fc1\cf1 \
int test;\
\
	
\b0\i // If anObject is not a NetrcEntry type defer to SortableObject method
\b\i0 \
	if( [anObject isKindOf:[NetrcEntry class]] == NO )\
		return [super compare: anObject typeID: typeID\
			size: size keyMethod: keyMethod];\
\
	
\b0\i // Major key is hostname, minor key is username
\b\i0 \
	test = strcmp(hostname, [anObject hostname]);\
	if( test == 0 )\
		test = strcmp(username, [anObject username]);\
	if( test < 0 )\
		test = -1;\
	else if( test > 0 )\
		test = 1;\
\
	return test;\
\}	
\b0\i // End compare:typeID:size:keyMethod:
\b\i0 \
\
@end\

}
