/*
	$Id: DSMailUser.cpp,v 1.1 2003/04/20 23:34:11 dasenbro Exp $

	File:		DSMailUser.cpp

	Contains:	implementation of DSMailUser object

	Version:	Apple Mail Server - Mac OS X :  $Revision: 1.1 $

	Written by:	Michael Dasenbroc

	Copyright:	© 1996-2001 by Apple Computer, Inc., all rights reserved.

 	NOT_FOR_OPEN_SOURCE <to be reevaluated at a later time>

	Change History:

		$Log: DSMailUser.cpp,v $
		Revision 1.1  2003/04/20 23:34:11  dasenbro
		Initial check-in.
		
		Revision 1.25  2002/05/09 16:58:56  dasenbro
		Changed all str... calls to CUtils::Str... to be NULL safe.
		
		Revision 1.24  2002/04/18 18:09:10  dasenbro
		Changed bool to Bool for word alignment.
		
		Revision 1.23  2002/03/21 16:38:52  dasenbro
		Addes network transition support.
		
		Revision 1.22  2002/02/20 21:12:11  dasenbro
		Added disk quota member functions.
		
		Revision 1.21  2002/01/14 17:30:58  dasenbro
		Initial S4 updates.
		
		Revision 1.20  2001/06/21 20:50:55  dasenbro
		Updated file header info.
		
		Revision 1.19  2001/06/21 17:15:20  dasenbro
		Added protection for log user names and passwords.
		
		Revision 1.18  2001/05/23 22:27:05  dasenbro
		Added GetGroups() for ACL support.
		

	To Do:
*/

#include "DSMailUser.h"

#include <stdlib.h>

#include "DSMgr.h"
#include "CUtils.h"


// --------------------------------------------------------------------------------
//	* DSMailUser ()
//
// --------------------------------------------------------------------------------

DSMailUser::DSMailUser ( void )
{
	fDataRef		= nil;
	fPlistRef		= nil;
	fDictRef		= nil;

	fUserID			= 0;
	fGroupID		= 0;
	fDiskQuota		= 0;
	fName 			= nil;
	fRealName		= nil;
	fUserLocation 	= nil;
	fAcctState		= eUnknownAcctState;
	fNotifyState	= eUnknownNotifyState;
	fAPOPRequired	= false;
	fOneInbox		= true;
	fShowPOPInIMAP	= false;
	fAutoFwdAddr	= nil;
	fIMAPLogin		= false;
	fUNIXInbox		= false;
	fPOP3Login		= false;
	fAccountLoc		= nil;
	fMailLocation	= nil;
	fNotifyIPAddr	= nil;
} // DSMailUser


// --------------------------------------------------------------------------------
//	* DSMailUser ()
//
//		 - copy constructor
// --------------------------------------------------------------------------------

DSMailUser::DSMailUser ( DSMailUser *inMailUser )
{
	fDataRef		= nil;
	fPlistRef		= nil;
	fDictRef		= nil;

	if ( inMailUser == NULL )
	{
		fUserID			= 0;
		fGroupID		= 0;
		fDiskQuota		= 0;
		fName 			= nil;
		fRealName		= nil;
		fUserLocation 	= nil;
		fAcctState		= eUnknownAcctState;
		fNotifyState	= eUnknownNotifyState;
		fAPOPRequired	= false;
		fOneInbox		= true;
		fShowPOPInIMAP	= false;
		fAutoFwdAddr	= nil;
		fIMAPLogin		= false;
		fUNIXInbox		= false;
		fPOP3Login		= false;
		fAccountLoc		= nil;
		fMailLocation	= nil;
		fNotifyIPAddr	= nil;
	}
	else
	{
		fUserID			= inMailUser->fUserID;
		fGroupID		= inMailUser->fGroupID;
		fDiskQuota		= inMailUser->fDiskQuota;
		fAcctState		= inMailUser->fAcctState;
		fNotifyState	= inMailUser->fNotifyState;
		fAPOPRequired	= inMailUser->fAPOPRequired;
		fOneInbox		= inMailUser->fOneInbox;
		fShowPOPInIMAP	= inMailUser->fShowPOPInIMAP;
		fIMAPLogin		= inMailUser->fIMAPLogin;
		fUNIXInbox		= inMailUser->fUNIXInbox;
		fPOP3Login		= inMailUser->fPOP3Login;

		CopyString( &fName,			inMailUser->fName );
		CopyString( &fRealName,		inMailUser->fRealName );
		CopyString( &fUserLocation,	inMailUser->fUserLocation );
		CopyString( &fAutoFwdAddr,	inMailUser->fAutoFwdAddr );
		CopyString( &fAccountLoc,	inMailUser->fAccountLoc );
		CopyString( &fMailLocation,	inMailUser->fMailLocation );
		CopyString( &fNotifyIPAddr,	inMailUser->fNotifyIPAddr );
	}
} // DSMailUser


// --------------------------------------------------------------------------------
//	* ~DSMailUser ()
//
// --------------------------------------------------------------------------------

DSMailUser::~DSMailUser ( void )
{
	if ( fName != nil )
	{
		delete( fName );
		fName = nil;
	}
	if ( fRealName != nil )
	{
		delete( fRealName );
		fRealName = nil;
	}
	if ( fUserLocation != nil )
	{
		delete( fUserLocation );
		fUserLocation = nil;
	}

	if ( fAccountLoc != nil )
	{
		delete( fAccountLoc );
		fAccountLoc = nil;
	}

	if ( fMailLocation != nil )
	{
		delete( fMailLocation );
		fMailLocation = nil;
	}

	if ( fNotifyIPAddr != nil )
	{
		delete( fNotifyIPAddr );
		fNotifyIPAddr = nil;
	}

	if ( fAutoFwdAddr != nil )
	{
		delete( fAutoFwdAddr );
		fAutoFwdAddr = nil;
	}

} // ~DSMailUser


// --------------------------------------------------------------------------------
//	* SetUserName ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::SetUserName ( const char *inUserName )
{
	eMailUserErr	siResult 	= eMailUserNoErr;

	if ( inUserName != nil )
	{
		if ( fName != nil )
		{
			delete( fName );
			fName = nil;
		}

		fName = new char[ CUtils::Strlen( inUserName ) + 1 ];
		if ( fName != nil )
		{
			CUtils::Strcpy( fName, inUserName );
		}
		else
		{
			siResult = eMemoryError;
		}
	}
	else
	{
		siResult = eNullUserName;
	}

	return( siResult );

} // SetUserName


// --------------------------------------------------------------------------------
//	* SetRealName ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::SetRealName ( const char *inRealName )
{
	eMailUserErr	siResult 	= eMailUserNoErr;

	if ( inRealName != nil )
	{
		if ( fRealName != nil )
		{
			delete( fRealName );
			fRealName = nil;
		}

		fRealName = new char[ CUtils::Strlen( inRealName ) + 1 ];
		if ( fRealName != nil )
		{
			CUtils::Strcpy( fRealName, inRealName );
		}
		else
		{
			siResult = eMemoryError;
		}
	}
	else
	{
		siResult = eNullUserName;
	}

	return( siResult );

} // SetRealName


// --------------------------------------------------------------------------------
//	* SetUserLocation ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::SetUserLocation ( const char *inUserLocation )
{
	eMailUserErr	siResult 	= eMailUserNoErr;

	if ( inUserLocation != nil )
	{
		if ( fUserLocation != nil )
		{
			delete( fUserLocation );
			fUserLocation = nil;
		}

		fUserLocation = new char[ CUtils::Strlen( inUserLocation ) + 1 ];
		if ( fUserLocation != nil )
		{
			CUtils::Strcpy( fUserLocation, inUserLocation );
		}
		else
		{
			siResult = eMemoryError;
		}
	}
	else
	{
		siResult = eNullUserName;
	}

	return( siResult );

} // SetUserLocation


// --------------------------------------------------------------------------------
//	* SetGroupID ()
//
// --------------------------------------------------------------------------------

void DSMailUser::SetGroupID ( const uInt32 inGroupID )
{
	fGroupID = inGroupID;
} // SetGroupID


// --------------------------------------------------------------------------------
//	* SetAutoFwd ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::SetAutoFwd ( const char *inEmailAddress )
{
	eMailUserErr	siResult 	= eMailUserNoErr;
	
	if ( inEmailAddress != nil)
	{
		fAcctState = eAcctForwarded;
		fPOP3Login = false;
		fIMAPLogin = false;
		if ( fAutoFwdAddr != nil )
		{
			delete( fAutoFwdAddr );
			fAutoFwdAddr = nil;
		}
		if ( ::strncmp( inEmailAddress, "mailto:", 7) == 0 )
		{
			inEmailAddress += 7; // advance past mailto: part
		}
		fAutoFwdAddr = (char*)::malloc( (CUtils::Strlen(inEmailAddress) + 1) * sizeof(char) );
		if ( fAutoFwdAddr != nil )
		{
			CUtils::Strcpy( fAutoFwdAddr, inEmailAddress );
			siResult = eMailUserNoErr;
		}
		else
		{
			siResult = eMemoryError;
		}
	}
	else
	{
		siResult = eEmptyString;
	}
	
	return( siResult );
}
	
// --------------------------------------------------------------------------------
//	* SetAttrsFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::SetAttrsFromXML ( char *inXMLData )
{
	eMailUserErr	siResult 	= eMailUserNoErr;
	uInt32			uiDataLen	= 0;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;

	if ( inXMLData != nil )
	{
		uiDataLen = CUtils::Strlen( inXMLData );
		fDataRef = ::CFDataCreate( nil, (const uInt8 *)inXMLData, uiDataLen );
		if ( fDataRef != nil )
		{
			fPlistRef = ::CFPropertyListCreateFromXMLData( kCFAllocatorDefault, fDataRef, kCFPropertyListImmutable, nil );
			if ( fPlistRef != nil )
			{
				if ( ::CFDictionaryGetTypeID() == ::CFGetTypeID( fPlistRef ) )
				{
					fDictRef = (CFDictionaryRef)fPlistRef;

					siResult = VerifyMailAttrVers();
					if ( siResult == eMailUserNoErr )
					{
						siResult = GetAcctStateFromXML();
						if ( siResult == eMailUserNoErr )
						{
							siResult = GetIMAPLoginFromXML();
							if ( siResult == eMailUserNoErr )
							{
								siResult = GetPOP3LoginFromXML();
								if ( siResult == eMailUserNoErr )
								{
									siResult = SetAcctLocFromXML();
									if ( siResult == eMailUserNoErr )
									{
										(void)GetAPOPFromXML();
										(void)GetNotifyFromXML();
										(void)GetDiskQuotaFromXML();
										(void)GetSeparateInboxFromXML();
										(void)GetShowPopInImapFromXML();
										(void)GetLocalDeliveryFromXML();
									}
								}
							}
						}
					}
				}
				::CFRelease(fPlistRef);
			}
			::CFRelease(fDataRef);
		}
	}

	return( siResult );

} // SetAttrsFromXML


// --------------------------------------------------------------------------------
//	* VerifyMailAttrVers ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::VerifyMailAttrVers ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeyAttrVersion ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeyAttrVersion ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char *)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( pValue != nil )
				{
					siResult = eWrongVersion;

					if ( CUtils::Strcmp( pValue, kXMLValueVersion ) == 0 )
					{
						siResult = eMailUserNoErr;
					}
				}
			}
		}
	}

	return( siResult );

} // VerifyMailAttrVers


// --------------------------------------------------------------------------------
//	* GetAPOPFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::GetAPOPFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	// Default value
	fAPOPRequired = false;

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeyAPOPRequired ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeyAPOPRequired ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char *)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( pValue != nil )
				{
					siResult = eMalformedAttr;

					if ( CUtils::Strcmp( pValue, kXMLValueYesAPOP ) == 0 )
					{
						fAPOPRequired = true;
						siResult = eMailUserNoErr;
					}
					if ( CUtils::Strcmp( pValue, kXMLValueNoAPOP ) == 0 )
					{
						fAPOPRequired = false;
						siResult = eMailUserNoErr;
					}
				}
			}
		}
	}

	return( siResult );

} // GetAPOPFromXML


// --------------------------------------------------------------------------------
//	* GetIMAPLoginFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::GetIMAPLoginFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	// Default
	fIMAPLogin = false;

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeykIMAPLoginState ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeykIMAPLoginState ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char *)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( pValue != nil )
				{
					siResult = eMalformedAttr;

					if ( CUtils::Strcmp( pValue, kXMLValueIMAPLoginOK ) == 0 )
					{
						fIMAPLogin = true;
						siResult = eMailUserNoErr;
					}
					else if ( CUtils::Strcmp( pValue, kXMLValueIMAPLogInNotOK ) == 0 )
					{
						fIMAPLogin = false;
						siResult = eMailUserNoErr;
					}
				}
			}
		}
	}

	return( siResult );

} // GetIMAPLoginFromXML


// --------------------------------------------------------------------------------
//	* GetPOP3LoginFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::GetPOP3LoginFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	// Default value
	fPOP3Login = true;

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeyPOP3LoginState ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeyPOP3LoginState ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char *)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( pValue != nil )
				{
					siResult = eMalformedAttr;

					if ( CUtils::Strcmp( pValue, kXMLValuePOP3LoginOK ) == 0 )
					{
						fPOP3Login = true;
						siResult = eMailUserNoErr;
					}
					else if ( CUtils::Strcmp( pValue, kXMLValuePOP3LoginNotOK ) == 0 )
					{
						fPOP3Login = false;
						siResult = eMailUserNoErr;
					}
				}
			}
		}
	}

	return( siResult );

} // GetPOP3LoginFromXML


// --------------------------------------------------------------------------------
//	* SetAcctLocFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::SetAcctLocFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	// Default to nil
	if ( fAccountLoc != nil )
	{
		delete( fAccountLoc );
		fAccountLoc = nil;
	}

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeyAcctLoc ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeyAcctLoc ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char*)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( fAccountLoc != nil )
				{
					delete( fAccountLoc );
					fAccountLoc = nil;
				}

				if ( pValue != nil )
				{
					fAccountLoc = new char[ CUtils::Strlen( pValue ) + 1 ];
					if ( fAccountLoc != nil )
					{
						CUtils::Strcpy( fAccountLoc, pValue );
						siResult = eMailUserNoErr;
					}
					else
					{
						siResult = eMemoryError;
					}
				}
			}
		}
	}

	return( siResult );

} // SetAcctLocFromXML


// --------------------------------------------------------------------------------
//	* GetAcctStateFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::GetAcctStateFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	// Default value
	fAcctState = eUnknownAcctState;

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeyAcctState ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeyAcctState ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char *)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( pValue != nil )
				{
					siResult = eMalformedAttr;

					if ( CUtils::Strcmp( pValue, kXMLValueAcctEnabled ) == 0 )
					{
						fAcctState = eAcctEnabled;
						siResult = eMailUserNoErr;
					}
					else if ( CUtils::Strcmp( pValue, kXMLValueAcctDisabled ) == 0 )
					{
						fAcctState = eAcctDisabled;
						siResult = eMailUserNoErr;
					}
					else if ( CUtils::Strcmp( pValue, kXMLValueAcctFwd ) == 0 )
					{
						siResult = GetAutoFwdFromXML();
						if ( siResult == eMailUserNoErr )
						{
							fAcctState = eAcctForwarded;
						}
					}
				}
			}
		}
	}

	return( siResult );

} // GetAcctStateFromXML


// --------------------------------------------------------------------------------
//	* GetAutoFwdFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::GetAutoFwdFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
        char*		pValue = nil;

	// Default to nil
	if ( fAutoFwdAddr != nil )
	{
		delete( fAutoFwdAddr );
		fAutoFwdAddr = nil;
	}

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeyAutoFwd ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeyAutoFwd ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;
                                
				pValue = (char *)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );

				if ( pValue != nil )
				{
					siResult = SetAutoFwd( pValue );
				}
			}
		}
	}

	return( siResult );

} // GetAutoFwdFromXML


// --------------------------------------------------------------------------------
//	* GetNotifyFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::GetNotifyFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	// Default value
	fNotifyState = eUnknownNotifyState;

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeyNotifyState ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeyNotifyState ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char *)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( pValue != nil )
				{
					siResult = eMalformedAttr;

					if ( CUtils::Strcmp( pValue, kXMLValueNotifyOff ) == 0 )
					{
						fNotifyState = eNotifyDisabled;
						siResult = eMailUserNoErr;
					}
					else if ( CUtils::Strcmp( pValue, kXMLValueNotifyLastIP ) == 0 )
					{
						fNotifyState = eNotifyUseLastIP;
						siResult = eMailUserNoErr;
					}
					else if ( CUtils::Strcmp( pValue, kXMLValueNotifyStaticIP ) == 0 )
					{
						siResult = SetNotifyIPAddrFromXML();
						if ( siResult == eMailUserNoErr )
						{
							fNotifyState = eNotifyUseStaticIP;
						}
					}
				}
			}
		}
	}

	return( siResult );

} // GetNotifyFromXML


// --------------------------------------------------------------------------------
//	* GetDiskQuotaFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::GetDiskQuotaFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeyDiskQuota ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeyDiskQuota ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char *)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( pValue != nil )
				{
					fDiskQuota = atol( pValue );
					siResult = eMailUserNoErr;
				}
			}
		}
	}

	return( siResult );

} // GetDiskQuotaFromXML


// --------------------------------------------------------------------------------
//	* SetNotifyIPAddrFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::SetNotifyIPAddrFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeykNotifyStaticIP ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeykNotifyStaticIP ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char *)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( fNotifyIPAddr != nil )
				{
					delete( fNotifyIPAddr );
					fNotifyIPAddr = nil;
				}

				if ( pValue != nil )
				{
					fNotifyIPAddr = new char[ CUtils::Strlen( pValue ) + 1 ];
					if ( fNotifyIPAddr != nil )
					{
						CUtils::Strcpy( fNotifyIPAddr, pValue );
						siResult = eMailUserNoErr;
					}
					else
					{
						siResult = eMemoryError;
					}
				}
			}
		}
	}

	return( siResult );

} // SetNotifyIPAddrFromXML


// --------------------------------------------------------------------------------
//	* GetSeparateInboxFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::GetSeparateInboxFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	// Default value
	fOneInbox = true;

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeySeparateInbox ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeySeparateInbox ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char *)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( pValue != nil )
				{
					siResult = eMalformedAttr;

					if ( CUtils::Strcmp( pValue, kXMLValueSharedInbox ) == 0 )
					{
						fOneInbox = true;
						siResult = eMailUserNoErr;
					}
					else if ( CUtils::Strcmp( pValue, kXMLValueSeparateInbox ) == 0 )
					{
						fOneInbox = false;
						siResult = eMailUserNoErr;
					}
				}
			}
		}
	}

	return( siResult );

} // GetSeparateInboxFromXML


// --------------------------------------------------------------------------------
//	* GetShowPopInImapFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::GetShowPopInImapFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	// Default value
	fShowPOPInIMAP = false;

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeyShowPOP3InIMAP ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeyShowPOP3InIMAP ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char *)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( pValue != nil )
				{
					siResult = eMalformedAttr;

					if ( CUtils::Strcmp( pValue, kXMLValueShowPOP ) == 0 )
					{
						fShowPOPInIMAP = true;
						siResult = eMailUserNoErr;
					}
					else if ( CUtils::Strcmp( pValue, kXMLValueDontShowPOP ) == 0 )
					{
						fShowPOPInIMAP = false;
						siResult = eMailUserNoErr;
					}
				}
			}
		}
	}

	return( siResult );

} // GetShowPopInImapFromXML


// --------------------------------------------------------------------------------
//	* GetLocalDeliveryFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::GetLocalDeliveryFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	// Default value
	fUNIXInbox = false;

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeyDeliveToUNIXInbox ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeyDeliveToUNIXInbox ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char *)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( pValue != nil )
				{
					siResult = eMalformedAttr;

					if ( CUtils::Strcmp( pValue, kXMLValueDeliverToUNIX ) == 0 )
					{
						fUNIXInbox = true;
						siResult = eMailUserNoErr;
					}
					else if ( CUtils::Strcmp( pValue, kXMLValueDontDeliverToUNIX ) == 0 )
					{
						fUNIXInbox = false;
						siResult = eMailUserNoErr;
					}
				}
			}
		}
	}

	return( siResult );

} // GetLocalDeliveryFromXML


// -------------------------------------------------------------------------------------
#pragma mark * Get Attributes *
// -------------------------------------------------------------------------------------

// --------------------------------------------------------------------------------
//	* GetUserID ()
//	
// --------------------------------------------------------------------------------

uInt32 DSMailUser::GetUserID ( void )
{
	return( fUserID );
} // GetUserID


// --------------------------------------------------------------------------------
//	* SetUserID ()
//
// --------------------------------------------------------------------------------

void DSMailUser::SetUserID ( const uInt32 inUserID )
{
	fUserID = inUserID;
} // SetUserID


// --------------------------------------------------------------------------------
//	* GetDiskQuota ()
//	
// --------------------------------------------------------------------------------

uInt32 DSMailUser::GetDiskQuota ( void )
{
	return( fDiskQuota );
} // GetDiskQuota


// --------------------------------------------------------------------------------
//	* SetDiskQuota ()
//
// --------------------------------------------------------------------------------

void DSMailUser::SetDiskQuota ( const uInt32 inQuota )
{
	fDiskQuota = inQuota;
} // SetDiskQuota


// --------------------------------------------------------------------------------
//	* GetGroupID ()
//	
// --------------------------------------------------------------------------------

uInt32 DSMailUser::GetGroupID ( void )
{
	return( fGroupID );
} // GetGroupID

// --------------------------------------------------------------------------------
//	* GetUserName ()
//	
// --------------------------------------------------------------------------------

const char*	DSMailUser::GetUserName ( void )
{
	return( fName );
} // GetUserName


// --------------------------------------------------------------------------------
//	* GetRealName ()
//	
// --------------------------------------------------------------------------------

const char*	DSMailUser::GetRealName ( void )
{
	return( fRealName );
} // GetRealName


// --------------------------------------------------------------------------------
//	* GetUserLocation ()
//	
// --------------------------------------------------------------------------------

const char* DSMailUser::GetUserLocation ( void )
{
	return( fUserLocation );
} // GetUserLocation


// --------------------------------------------------------------------------------
//	* GetAcctLocation ()
//	
// --------------------------------------------------------------------------------

const char* DSMailUser::GetAcctLocation ( void )
{
	return( fAccountLoc );
} // GetAcctLocationv


// --------------------------------------------------------------------------------
//	* GetMailLocation ()
//	
// --------------------------------------------------------------------------------

const char* DSMailUser::GetMailLocation ( void )
{
	return( fMailLocation );
} // GetMailLocation


// --------------------------------------------------------------------------------
//	* SetMailLocFromXML ()
//
// --------------------------------------------------------------------------------

DSMailUser::eMailUserErr DSMailUser::SetMailLocFromXML ( void )
{
	eMailUserErr	siResult	= eItemNotFound;
	Bool			bFound		= false;
	CFStringRef		cfStringRef	= nil;
	char		   *pValue		= nil;

	// Default to nil
	if ( fMailLocation != nil )
	{
		delete( fMailLocation );
		fMailLocation = nil;
	}

	bFound = ::CFDictionaryContainsKey( fDictRef, CFSTR( kXMLKeyMailLoc ) );
	if ( bFound == true )
	{
		siResult = eInvalidDataType;

		cfStringRef = (CFStringRef)::CFDictionaryGetValue( fDictRef, CFSTR( kXMLKeyMailLoc ) );
		if ( cfStringRef != nil )
		{
			if ( ::CFGetTypeID( cfStringRef ) == ::CFStringGetTypeID() )
			{
				siResult = eItemNotFound;

				pValue = (char*)::CFStringGetCStringPtr( cfStringRef, kCFStringEncodingMacRoman );
				if ( fMailLocation != nil )
				{
					delete( fMailLocation );
					fMailLocation = nil;
				}

				if ( pValue != nil )
				{
					fMailLocation = new char[ CUtils::Strlen( pValue ) + 1 ];
					if ( fMailLocation != nil )
					{
						CUtils::Strcpy( fMailLocation, pValue );
						siResult = eMailUserNoErr;
					}
					else
					{
						siResult = eMemoryError;
					}
				}
			}
		}
	}
 
	return( siResult );

} // SetMailLocFromXML


// --------------------------------------------------------------------------------
//	* IsMailEnabled ()
//
// --------------------------------------------------------------------------------

Bool DSMailUser::IsMailEnabled ( void )
{
	return( ((fAcctState == eAcctEnabled) || (fAcctState == eAcctForwarded)) );
} // IsMailEnabled


// --------------------------------------------------------------------------------
//	* IsPOPLoginEnabled ()
//	
// --------------------------------------------------------------------------------

Bool DSMailUser::IsPOPLoginEnabled ( void )
{
	return( (fAcctState == eAcctEnabled) && fPOP3Login );
} // IsPOPLoginEnabled


// --------------------------------------------------------------------------------
//	* IsIMAPLoginEnabled ()
//	
// --------------------------------------------------------------------------------

Bool DSMailUser::IsIMAPLoginEnabled ( void )
{
	return( (fAcctState == eAcctEnabled) && fIMAPLogin );
} // IsIMAPLoginEnabled


// --------------------------------------------------------------------------------
//	* IsAPOPRequired ()
//	
// --------------------------------------------------------------------------------

Bool DSMailUser::IsAPOPRequired	( void )
{
	return( false ); // !!! change this back when APOP support arrives -- fAPOPRequired );
} // IsAPOPRequired


// --------------------------------------------------------------------------------
//	* IsInboxSeparate ()
//	
// --------------------------------------------------------------------------------

Bool DSMailUser::IsInboxShared ( void )
{
	return( fOneInbox );
} // IsInboxSeparate


// --------------------------------------------------------------------------------
//	* IsShowPOPInIMAP ()
//	
// --------------------------------------------------------------------------------

Bool DSMailUser::IsShowPOPInIMAP ( void )
{
	return( fShowPOPInIMAP );
} // IsShowPOPInIMAP


// --------------------------------------------------------------------------------
//	* DeliverToUNIXInbox ()
//	
// --------------------------------------------------------------------------------

Bool DSMailUser::DeliverToUNIXInbox ( void )
{
	return( fUNIXInbox );
} // DeliverToUNIXInbox


// --------------------------------------------------------------------------------
//	* IsNotificationOn ()
//	
// --------------------------------------------------------------------------------

Bool DSMailUser::IsNotificationOn ( void )
{
	return( ((fNotifyState == eNotifyUseLastIP) || (fNotifyState == eNotifyUseStaticIP)) );
} // IsNotificationOn


// --------------------------------------------------------------------------------
//	* UseLastIPAddress ()
//	
// --------------------------------------------------------------------------------

Bool DSMailUser::UseLastIPAddress ( void )
{
	return( (fNotifyState == eNotifyUseLastIP) );
} // UseLastIPAddress


// --------------------------------------------------------------------------------
//	* GetNotifyIPAddress ()
//	
// --------------------------------------------------------------------------------

const char* DSMailUser::GetNotifyIPAddress ( void )
{
	return( fNotifyIPAddr );
} // GetNotifyIPAddress


// --------------------------------------------------------------------------------
//	* IsSMTPForwardEnabled ()
//	
// --------------------------------------------------------------------------------

Bool DSMailUser::IsSMTPForwardEnabled ( void )
{
	return( (fAcctState == eAcctForwarded) );
} // IsSMTPForwardEnabled


// --------------------------------------------------------------------------------
//	* GetSMTPForward ()
//	
// --------------------------------------------------------------------------------

const char* DSMailUser::GetSMTPForward ( void )
{
	return( fAutoFwdAddr );
} // GetSMTPForward


// --------------------------------------------------------------------------------
//	* ValidateAPOPDigest ()
//	
// --------------------------------------------------------------------------------

/*
Bool DSMailUser::ValidateAPOPDigest ( const char* inTimestamp, const char *inAPOPDigest, OAMStatus& outErr )
{
	OAMStatus				err				= kNoErr;
	OAMObjectSpec 			object;
	OAMAuthenticateInfo	   * authInfo		= nil;
	OAMBufferDescriptor	   * input			= nil;
	OAMBufferDescriptor	   * output			= nil;
	char				   * input_buffer	= nil;
	char				   * output_buffer	= nil;

	// Allocate the memory needed
	authInfo		= NEW OAMAuthenticateInfo;
	input			= NEW OAMBufferDescriptor;
	output			= NEW OAMBufferDescriptor;
	output_buffer	= NEW char[ 16 ];

	// Clear the authentication info structure
	::memset( authInfo, 0, sizeof( OAMAuthenticateInfo ) );
	::memset( input, 0, sizeof( OAMBufferDescriptor ) );
	::memset( output, 0, sizeof( OAMBufferDescriptor ) );
	::memset( output_buffer, 0, 16 );

	// Set up the U&G Database Object Reference
	ConstructObjectSpec( &object, kOAMUser, this->GetShortID() );

	authInfo->objectSpec = &object;
	authInfo->stage = kOAMAuthLogin;
	::memcpy( authInfo->uam, "APOP", sizeof( "APOP") );

	// set up output buffer
	output->buffer = output_buffer;
	output->bufferLen = 16;

	long timestampLength	= CUtils::Strlen( inTimestamp );
	long apopdigestLength	= CUtils::Strlen( inAPOPDigest );

	// Allocate a large enough input buffer
	long inputLength = timestampLength + apopdigestLength + (2 * sizeof( short ) );

	if ( inputLength & 1 )				// if odd lengthed, add one
	{
		inputLength++;
	}

	input_buffer = NEW char[ inputLength ];
	::memset( input_buffer, 0, inputLength );		// make sure it's cleared

	((short*)input_buffer)[ 0 ] = timestampLength;		// first short contains length of timestamp
	((short*)input_buffer)[ 1 ] = apopdigestLength;		// second short contains length of digest

	char *insertionPoint = input_buffer + (2 * sizeof( short ));	// skip length shorts

	// Timestamp starts after two shorts
	::memcpy( insertionPoint, inTimestamp, timestampLength );
	insertionPoint += timestampLength;			// move forward by length of timestamp

	if ( (long)insertionPoint & 1 )				// if odd lengthed, pad to even byte
	{
		insertionPoint++;
	}

	// Digest starts after timestamp and possible pad byte
	::memcpy( insertionPoint, inAPOPDigest, apopdigestLength );
	insertionPoint += apopdigestLength;			// move forward by length of digest

	input->buffer = input_buffer;
	input->bufferLen = inputLength;
	input->actCount = inputLength;

	err = OAMAuthenticateObject( gASDMgr->GetSessionID(), authInfo, input, output, nil );

	outErr = authInfo->objStatus; 		// return the value from OAMAuthenticateObject

	delete( authInfo );
	delete( input );
	delete( output );
	delete( input_buffer );
	delete( output_buffer );

	if ( err == kNoErr )
	{
		return( true );
	}
	else
	{
		return( false );
	}
} // ValidateAPOPDigest

*/

// --------------------------------------------------------------------------------
//	* GetGroups ()
//
// --------------------------------------------------------------------------------

uInt32 DSMailUser::GetGroups ( uInt32 *outGroups )
{
	uInt32	uiResult	= 0;

	uiResult = gDSMgr->GetGroups ( this->GetUserName(), outGroups );

	return( uiResult );

} // GetGroups


// --------------------------------------------------------------------------------
//	* IsAccountLocal ()
//
//		- outFwdTo is expected to be a pointer to a buffer of
//			at least 256 bytes, or nil
// --------------------------------------------------------------------------------

Bool DSMailUser::IsAccountLocal ( char *outFwdTo )
{

	Bool			result		= false;
	const char	   *inetName	= nil;
	const char	   *srvrName	= nil;
	CString			csFullName( 512 );
//	UMailAddress	hostLookUp;

	if ( outFwdTo != nil )
	{
		*outFwdTo = nil;
	}

	inetName = this->GetUserName();
	if ( *inetName == nil )
	{
		inetName = this->GetRealName();
	}

	srvrName = this->GetAcctLocation();
	if ( (srvrName != nil) && (*srvrName != nil) )
	{
		csFullName.Sprintf( "%s@%s", inetName, srvrName );

//		hostLookUp.Initialize822( csFullName.GetData() );
//		if ( hostLookUp.IsLocalHost( nil, nil,
////									UMailAddress::kUseHostDestClassFlag,
//									UMailAddress::kIgnoreHostDestClassFlag,
//									UMailAddress::kDoNotCreateHostEntry,
//									UMailAddress::kUseLocalDNSCannonicalNameList,
//									CHostEntry::kFindResolveHostDNSCache ) == true )
//		{
			result = true;
//		}
//		else if ( outFwdTo != nil )
		{
			CUtils::Strncpy( outFwdTo, srvrName, 255 );
			// we are expecting a 256 byte buffer, so 255 is the max length
		}
	}
	return( result );

} // IsAccountLocal


// --------------------------------------------------------------------------------
//	* IsAdminEnabled ()
//
// --------------------------------------------------------------------------------

const char * const kAdminGroup = "admin";

Bool DSMailUser::IsAdminEnabled ( void )
{
	if ( gDSMgr != NULL )
	{
		return( gDSMgr->UserIsMemberOfGroup( fName, kAdminGroup ) );
	}
	else
	{
		return false;
	}
} // IsAdminEnabled


// --------------------------------------------------------------------------------
//	* CopyString ()
//
// --------------------------------------------------------------------------------

void DSMailUser::CopyString ( char** outDestStr, char* inSourceStr )
{
	if (outDestStr == NULL)
	{
		return;
	}
	if (inSourceStr == NULL)
	{
		*outDestStr = NULL;
	}
	else
	{
		*outDestStr = new char[ CUtils::Strlen( inSourceStr ) + 1 ];
		if ( outDestStr != nil )
		{
			CUtils::Strcpy( *outDestStr, inSourceStr );
		}
	}
} // CopyString

	
