/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ // InternetConfig.cp // // Created by Tim Craycroft, 2/9/96 // #include "InternetConfig.h" #include #include #include #include #include "xp_core.h" #include "xp_str.h" #include "uprefd.h" #include "prefapi.h" // ns/modules/libpref #include "ufilemgr.h" #include "resgui.h" // // InternetConfig class. // // Checks the IC seed on resume events // class CInternetConfig { public: static void Connect(); static void Disconnect(); static ICError GetInternetConfigString(ConstStr255Param icKey, Str255 s, long *port = nil); static ICError GetInternetConfigFileMapping( OSType fileType, OSType creator, ConstStr255Param fileName, ICMapEntry *ent); static ICError MapFileName( ConstStr255Param filename, ICMapEntry *ent ); static ICError GetFileSpec( ConstStr255Param icKey , FSSpec & ioSpec ); static ICError LaunchInternetConfigApplication(ConstStr255Param key); #ifndef MOZ_MAIL_NEWS static ICError SendInternetConfigURL(char *address); #endif static int UseICPrefCallback(const char *prefString, void *); static void ResumeEvent(); static Boolean CurrentlyUsingIC(); static Boolean HaveICInstance(); private: CInternetConfig(); ~CInternetConfig(); void SynchIf(); // iff the seed has changed void SynchFromIC(); ICError SynchStringFromIC( ConstStr255Param icKey, CPrefs::PrefEnum netscapePref, Boolean stripPort = false, const char *xpPortPrefName = nil, int32 defaultPort = 0); ICError SynchSplitStringFromIC( ConstStr255Param icKey, char divider, CPrefs::PrefEnum firstString, CPrefs::PrefEnum secondString, Boolean stripPort = false); ICError SyncFileSpec ( ConstStr255Param icKey, CPrefs::PrefEnum netscapePref ); ICError GetICString( ConstStr255Param icKey, Str255 s, int32 *port = nil); ICError GetFSSpec( ConstStr255Param icKey , FSSpec & ioSpec ); ICError GetICFileMapping( OSType fileType, OSType creator, ConstStr255Param fileName, ICMapEntry *ent); ICError MapICFileName( ConstStr255Param filename, ICMapEntry *ent ); ICError LaunchICApplication(ConstStr255Param key); #ifndef MOZ_MAIL_NEWS ICError SendICURL(char *address); #endif ICInstance fInstance; SInt32 fSeed; static CInternetConfig* sInternetConfigConnection; }; void CInternetConfigInterface::ResumeEvent() { CInternetConfig::ResumeEvent(); } // // ConnectToInternetConfig // // Only public entrypoint to this InternetConfig module. // // gets the folder from CPrefs::GetFilePrototype(prefSpec(, MainFolder) // void CInternetConfigInterface::ConnectToInternetConfig() { // I assume that this is only called once, at startup. const char *useICPrefName = "browser.mac.use_internet_config"; PREF_RegisterCallback(useICPrefName, CInternetConfig::UseICPrefCallback, nil); try { if (CInternetConfig::CurrentlyUsingIC()) { CInternetConfig::Connect(); } } catch(ICError err) { // do something ? a dialog perhaps ? // only if there is a real problem, not if // IC just isn't installed. } } void CInternetConfigInterface::DisconnectFromInternetConfig() { CInternetConfig::Disconnect(); } Boolean CInternetConfigInterface::CurrentlyUsingIC(void) { Boolean returnValue = TRUE; returnValue = returnValue && CInternetConfig::CurrentlyUsingIC(); returnValue = returnValue && CInternetConfig::HaveICInstance(); return returnValue; } void CInternetConfigInterface::GetInternetConfigString( ConstStr255Param icKey, Str255 s, long *port) { if (CInternetConfig::GetInternetConfigString(icKey, s, port)) { s[0] = 0; } } ICError CInternetConfigInterface::GetInternetConfigFileMapping( OSType fileType, OSType creator, ConstStr255Param fileName, ICMapEntry *ent) { return CInternetConfig::GetInternetConfigFileMapping(fileType, creator, fileName, ent); } ICError CInternetConfigInterface::MapFileName( ConstStr255Param filename, ICMapEntry *ent ) { return CInternetConfig::MapFileName( filename , ent ); } #ifndef MOZ_MAIL_NEWS ICError CInternetConfigInterface::SendInternetConfigURL(char *address) { return CInternetConfig::SendInternetConfigURL(address); } #endif ICError CInternetConfigInterface::LaunchInternetConfigApplication(ConstStr255Param key) { return CInternetConfig::LaunchInternetConfigApplication(key); } ICError CInternetConfigInterface::GetFileSpec( ConstStr255Param icKey , FSSpec & ioSpec ) { return CInternetConfig::GetFileSpec( icKey, ioSpec); } CInternetConfig* CInternetConfig::sInternetConfigConnection = nil; Boolean CInternetConfig::CurrentlyUsingIC() { XP_Bool result; const char *useICPrefName = "browser.mac.use_internet_config"; if (PREF_NOERROR != PREF_GetBoolPref(useICPrefName, &result)) { result = false; } return (Boolean)result; } // // CInternetConfig::Connect // // Call once to hook up with IC. // void CInternetConfig::Connect() { if (!sInternetConfigConnection) { sInternetConfigConnection = new CInternetConfig(); } } // // Bail // void CInternetConfig::Disconnect() { if (sInternetConfigConnection != nil) { delete sInternetConfigConnection; sInternetConfigConnection = nil; } } Boolean CInternetConfig::HaveICInstance(void) { Boolean returnValue = FALSE; Connect(); if (sInternetConfigConnection != nil) { returnValue = (sInternetConfigConnection->fInstance != NULL); } return returnValue; } // // CInternetConfig::CInternetConfig // CInternetConfig::CInternetConfig(): fInstance(NULL) { ICError err; // Detect IC, if present StValueChanger okayToFail(gDebugThrow, debugAction_Nothing); err = ::ICStart(&fInstance, emSignature); //ThrowIfOSErr_(err); if (!err) { try { ICDirSpec prefDir[1]; ICDirSpecArrayPtr prefDirArray; UInt32 dirCount = 0; // what a wonderful api... // // Give IC the directory that contains the pref file we're using // so it can look there for an IC config file. prefDirArray = (ICDirSpecArrayPtr) &prefDir; FSSpec prefSpec = CPrefs::GetFilePrototype(CPrefs::MainFolder); prefDir[0].vRefNum = prefSpec.vRefNum; prefDir[0].dirID = prefSpec.parID; dirCount = 1; err = ::ICFindConfigFile(fInstance, dirCount, prefDirArray); ThrowIfOSErr_(err); // Remember initial seed err = ::ICGetSeed(fInstance, &fSeed); ThrowIfOSErr_(err); // Read prefs from IC if (CurrentlyUsingIC()) { SynchFromIC(); } } catch(ICError err) { // Close IC connection and pass the error along ::ICStop(fInstance); fInstance = NULL; // throw(err); // we probably out to delete "this" as well } } } int CInternetConfig::UseICPrefCallback(const char *, void *) { if (CInternetConfig::CurrentlyUsingIC()) { Connect(); sInternetConfigConnection->SynchFromIC(); } return 0; // You don't even want to know my opinion of this! } // // CInternetConfig::~CInternetConfig // CInternetConfig::~CInternetConfig() { if (fInstance != NULL) { ::ICStop(fInstance); // close IC connection } } // // CInternetConfig::SynchFromIC // // Reads IC settings and converts them to Netscape prefs // void CInternetConfig::SynchFromIC() { ICError err; err = ::ICBegin(fInstance, icReadOnlyPerm); ThrowIfOSErr_(err); // Again, this is lame. // // We should have a table of some sort // SynchStringFromIC(kICRealName, CPrefs::UserName); SynchStringFromIC(kICEmail, CPrefs::UserEmail); SynchStringFromIC(kICEmail, CPrefs::ReplyTo); // IC has no reply-to SynchSplitStringFromIC(kICMailAccount, '@', CPrefs::PopID, CPrefs::PopHost, true); SynchStringFromIC(kICSMTPHost, CPrefs::SMTPHost, true); SynchStringFromIC(kICWWWHomePage, CPrefs::HomePage); SynchStringFromIC(kICOrganization, CPrefs::Organization); SynchStringFromIC(kICNNTPHost, CPrefs::NewsHost, true, "news.server_port", 119); SyncFileSpec( kICDownloadFolder, CPrefs::DownloadFolder ); ::ICEnd(fInstance); } void CInternetConfig::SynchIf() { SInt32 seed; if (::ICGetSeed(fInstance, &seed)) { return; } if (seed != fSeed) { try { SynchFromIC(); } catch(ICError err) { } fSeed = seed; } } // // CInternetConfig::ResumeEvent // // void CInternetConfig::ResumeEvent() { if (CurrentlyUsingIC()) { Connect(); sInternetConfigConnection->SynchIf(); } } // // CInternetConfig::SynchStringFromIC // // Set a netscape string from an IC string ICError CInternetConfig::SynchStringFromIC( ConstStr255Param icKey, CPrefs::PrefEnum netscapePref, Boolean stripPort, const char *xpPortPrefName, int32 defaultPort) { char s[256]; ICError err; int32 *portPtr = stripPort ? &defaultPort : nil; err = GetICString(icKey, (unsigned char*) s, portPtr); if (err == 0) { p2cstr((StringPtr)s); CPrefs::SetString(s, netscapePref); if (xpPortPrefName) { PREF_SetIntPref(xpPortPrefName, defaultPort); } } return err; } // // CInternetConfig::SynchSplitStringFromIC // // Takes a single IC string and splits it into two Netscape strings. // Useful for machine@host.domain.com, or proxy.address:port type stuff // // If the divider can't be found, the entire string is put into the // first netscape string and the second netscape string is set to '\0' // ICError CInternetConfig::SynchSplitStringFromIC( ConstStr255Param icKey, char divider, CPrefs::PrefEnum firstString, CPrefs::PrefEnum secondString, Boolean stripPort) { char buffer[256]; char *s; char *split; ICError err; s = buffer; err = GetICString(icKey, (unsigned char *) s); if (err != 0) return err; p2cstr((StringPtr)s); split = strchr(s, divider); if (split != NULL) { *split = '\0'; if (stripPort) { char *colon = strchr(split+1, ':'); if (colon) { *colon = '\0'; } } CPrefs::SetString(split+1, secondString); } else { CPrefs::SetString('\0', secondString); } CPrefs::SetString(s, firstString); return 0; } // // CInternetConfig::GetICString // // Gets an IC string pref // ICError CInternetConfig::GetInternetConfigString( ConstStr255Param icKey, Str255 s, long *port) { Connect(); return sInternetConfigConnection->GetICString(icKey, s, port); } // // CInternetConfig::GetICString // // Gets an IC string pref // ICError CInternetConfig::GetICString( ConstStr255Param icKey, Str255 s, int32 *port) { ICAttr attr; long size = 256; ICError result; result = ::ICGetPref(fInstance, icKey, &attr, (Ptr)s, &size); if (!result) { if (port) { char cString[256]; BlockMoveData(&s[1], cString, s[0]); cString[s[0]] = '\0'; char *colon = strchr(cString, ':'); if (colon) { *colon = '\0'; s[0] = colon - cString; ++colon; // IC supposedly supports notations like: // news.netscape.com:nntp // The protocol services don't seem to work in IC (or I'm to stupid // to make them work), so we just check for this one value ("nntp") // because that is the only protocol for which we support port numbers. if (!XP_STRCASECMP("nntp", colon)) { *port = 119; } else { // Add more protocols here if/when we suppor them. long portFromICString; int numargs = sscanf(colon, "%ld", &portFromICString); if (1 == numargs) { if (portFromICString >= 0) // negative port numbers are not valid { *port = portFromICString; } } // else we just use the default port } } } } return result; } #ifndef MOZ_MAIL_NEWS ICError CInternetConfig::SendInternetConfigURL(char *address) { Connect(); return sInternetConfigConnection->SendICURL(address); } ICError CInternetConfig::SendICURL(char *address) { if (address == NULL) return icNoURLErr; long selStart = 0; long selEnd = strlen(address); if( CInternetConfig::HaveICInstance() ) return ::ICLaunchURL(fInstance, "\p", address, selEnd, &selStart, &selEnd); else return icPrefNotFoundErr; } #endif ICError CInternetConfig::GetInternetConfigFileMapping( OSType fileType, OSType creator, ConstStr255Param filename, ICMapEntry *ent) { Connect(); return sInternetConfigConnection->GetICFileMapping(fileType, creator, filename, ent); } ICError CInternetConfig::GetICFileMapping( OSType fileType, OSType creator, ConstStr255Param filename, ICMapEntry *ent) { if( CInternetConfig::HaveICInstance() ) return ::ICMapTypeCreator(fInstance, fileType, creator, filename, ent); else return icPrefNotFoundErr; } ICError CInternetConfig::LaunchInternetConfigApplication(ConstStr255Param key) { Connect(); return sInternetConfigConnection->LaunchICApplication(key); } ICError CInternetConfig::LaunchICApplication(ConstStr255Param key) { if (CInternetConfig::HaveICInstance()) return ::ICEditPreferences(fInstance, key); else return icPrefNotFoundErr; } ICError CInternetConfig::MapFileName( ConstStr255Param filename, ICMapEntry *ent) { Connect(); return sInternetConfigConnection->MapICFileName(filename, ent); } ICError CInternetConfig::MapICFileName( ConstStr255Param filename, ICMapEntry *ent ) { if( CInternetConfig::HaveICInstance() ) return ::ICMapFilename(fInstance, filename, ent); else return icPrefNotFoundErr; } ICError CInternetConfig::GetFileSpec( ConstStr255Param icKey , FSSpec & ioSpec ) { Connect(); return sInternetConfigConnection->GetFSSpec(icKey, ioSpec); } ICError CInternetConfig::GetFSSpec( ConstStr255Param icKey , FSSpec & ioSpec ) { ICFileSpec* spec; ICAttr attr; char buffer[512]; long size = 512; ICError result; result = ::ICGetPref(fInstance, icKey, &attr, buffer, &size); if (!result) { spec = (ICFileSpec *) buffer; CFileMgr::CopyFSSpec( spec->fss, ioSpec ); } return result; } ICError CInternetConfig::SyncFileSpec ( ConstStr255Param icKey, CPrefs::PrefEnum netscapePref ) { FSSpec icSpec; ICError result = GetFSSpec( icKey, icSpec ); if( !result ) { CPrefs::SetFolderSpec( icSpec , netscapePref ); } return result; }