r=mkaply, sr=blizzard (platform specific), a=mkaply (OS/2 only)
Patch from Peter Weilbacher - Add protocols to ExternalProtocolHandlerExists/Add GetApplicationDescription for OS/2
This commit is contained in:
mkaply%us.ibm.com 2004-11-22 19:28:24 +00:00
Родитель eb21150598
Коммит d33b2e33c8
2 изменённых файлов: 289 добавлений и 136 удалений

Просмотреть файл

@ -23,6 +23,7 @@
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
* Boris Zbarsky <bzbarsky@mit.edu> (Added mailcap and mime.types support)
* Peter Weilbacher <mozilla@Weilbacher.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -70,6 +71,8 @@ static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID); // XXX need to conver
#define INCL_WINSHELLDATA
#include <os2.h>
#define MAXINIPARAMLENGTH 1024 // max length of OS/2 INI key for application parameters
#define LOG(args) PR_LOG(mLog, PR_LOG_DEBUG, args)
#define LOG_ENABLED() PR_LOG_TEST(mLog, PR_LOG_DEBUG)
@ -1138,10 +1141,111 @@ nsOSHelperAppService::GetHandlerAndDescriptionFromMailcapFile(const nsAString& a
return rv;
}
// Check OS/2 INI for application and parameters for the protocol
// return NS_OK, if application exists for protocol in INI and is not empty
nsresult
nsOSHelperAppService::GetApplicationAndParametersFromINI(const nsACString& aProtocol,
char * app, ULONG appLength,
char * param, ULONG paramLength)
{
/* initialize app to '\0' for later check */
*app = '\0';
/* http or https */
if ((aProtocol == NS_LITERAL_CSTRING("http")) ||
(aProtocol == NS_LITERAL_CSTRING("https"))) {
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultBrowserExe",
"",
app,
appLength);
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultParameters",
"",
param,
paramLength);
}
/* mailto: */
else if (aProtocol == NS_LITERAL_CSTRING("mailto")) {
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultMailExe",
"",
app,
appLength);
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultMailParameters",
"",
param,
paramLength);
}
/* ftp */
else if (aProtocol == NS_LITERAL_CSTRING("ftp")) {
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultFTPExe",
"",
app,
appLength);
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultFTPParameters",
"",
param,
paramLength);
}
/* news: or snews: */
else if ((aProtocol == NS_LITERAL_CSTRING("news")) ||
(aProtocol == NS_LITERAL_CSTRING("snews"))) {
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultNewsExe",
"",
app,
appLength);
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultNewsParameters",
"",
param,
paramLength);
}
/* irc: */
else if (aProtocol == NS_LITERAL_CSTRING("irc")) {
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultIRCExe",
"",
app,
appLength);
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultIRCParameters",
"",
param,
paramLength);
}
else {
NS_WARNING("GetApplicationAndParametersFromINI(): unsupported protocol scheme");
return NS_ERROR_FAILURE;
}
/* application string in INI was empty */
if (app[0] == '\0')
return NS_ERROR_FAILURE;
return NS_OK;
}
NS_IMETHODIMP nsOSHelperAppService::ExternalProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists)
{
LOG(("-- nsOSHelperAppService::ExternalProtocolHandlerExists for '%s'\n",
aProtocolScheme));
*aHandlerExists = PR_FALSE;
/* if applications.protocol is in prefs, then we have an external protocol handler */
nsresult rv;
nsCAutoString prefName;
@ -1152,15 +1256,27 @@ NS_IMETHODIMP nsOSHelperAppService::ExternalProtocolHandlerExists(const char * a
nsXPIDLCString prefString;
rv = thePrefsService->CopyCharPref(prefName.get(), getter_Copies(prefString));
*aHandlerExists = NS_SUCCEEDED(rv) && !prefString.IsEmpty();
if (*aHandlerExists) {
return NS_OK;
}
}
/* Check the OS/2 INI for the protocol */
char szAppFromINI[CCHMAXPATH];
char szParamsFromINI[MAXINIPARAMLENGTH];
rv = GetApplicationAndParametersFromINI(nsDependentCString(aProtocolScheme),
szAppFromINI, sizeof(szAppFromINI),
szParamsFromINI, sizeof(szParamsFromINI));
if (NS_SUCCEEDED(rv)) {
*aHandlerExists = PR_TRUE;
return NS_OK;
}
*aHandlerExists = PR_FALSE;
return NS_OK;
return NS_ERROR_FAILURE;
}
nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
{
LOG(("-- nsOSHelperAppService::LoadUrl\n"));
LOG(("-- nsOSHelperAppService::LoadUriInternal\n"));
nsCOMPtr<nsIPref> thePrefsService(do_GetService(NS_PREF_CONTRACTID));
if (!thePrefsService) {
return NS_ERROR_FAILURE;
@ -1184,128 +1300,67 @@ nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
prefName = NS_LITERAL_CSTRING("applications.") + uProtocol;
nsXPIDLCString prefString;
nsCAutoString parameters;
nsCAutoString applicationName;
nsCAutoString parameters;
rv = thePrefsService->CopyCharPref(prefName.get(), getter_Copies(prefString));
if (NS_FAILED(rv) || prefString.IsEmpty()) {
char szAppFromINI[CCHMAXPATH] = "\0";
char szParamsFromINI[CCHMAXPATH];
/* Special case http, https, and ftp - if we get here, pass them to the shell */
if ((uProtocol.EqualsLiteral("http")) ||
(uProtocol.EqualsLiteral("https")) ||
(uProtocol.EqualsLiteral("ftp"))) {
if (uProtocol.EqualsLiteral("ftp")) {
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultFTPExe",
"",
szAppFromINI,
sizeof(szAppFromINI)) ;
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultFTPParameters",
"",
szParamsFromINI,
sizeof(szParamsFromINI)) ;
}
/* If we didn't get a default ftp or it's http or https */
if ((uProtocol.EqualsLiteral("http")) ||
(uProtocol.EqualsLiteral("https")) ||
(szAppFromINI[0] == '\0')) {
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultBrowserExe",
"",
szAppFromINI,
sizeof(szAppFromINI));
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultParameters",
"",
szParamsFromINI,
sizeof(szParamsFromINI));
// DefaultParameters is the correct OS/2 way.
// In the configapps application, it writes
// DefaultBrowserParameters as well, so let's
// support it
if (szParamsFromINI[0] = '\0') {
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultBrowserParameters",
"",
szParamsFromINI,
sizeof(szParamsFromINI));
}
}
} else if ((uProtocol.EqualsLiteral("mailto")) ||
(uProtocol.EqualsLiteral("news"))) {
if (uProtocol.EqualsLiteral("news")) {
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultNewsExe",
"",
szAppFromINI,
sizeof(szAppFromINI)) ;
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultNewsParameters",
"",
szParamsFromINI,
sizeof(szParamsFromINI)) ;
}
/* If we didn't get a default news or it's mailto */
if ((uProtocol.EqualsLiteral("mailto")) ||
(szAppFromINI[0] == '\0')) {
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultMailExe",
"",
szAppFromINI,
sizeof(szAppFromINI));
PrfQueryProfileString(HINI_USER,
"WPURLDEFAULTSETTINGS",
"DefaultMailParameters",
"",
szParamsFromINI,
sizeof(szParamsFromINI));
}
} else {
return NS_ERROR_FAILURE;
}
if (szAppFromINI[0]) {
char szAppFromINI[CCHMAXPATH];
char szParamsFromINI[MAXINIPARAMLENGTH];
/* did OS2.INI contain application? */
rv = GetApplicationAndParametersFromINI(uProtocol,
szAppFromINI, sizeof(szAppFromINI),
szParamsFromINI, sizeof(szParamsFromINI));
if (NS_SUCCEEDED(rv)) {
applicationName = szAppFromINI;
parameters = szParamsFromINI;
parameters += " ";
parameters += urlSpec;
} else {
return NS_ERROR_FAILURE;
}
}
// Dissect the URI
nsCAutoString uURL, uUsername, uPassword, uHost, uPort, uPath;
nsCAutoString uEmail, uGroup;
PRInt32 iPort;
// when passing to OS/2 apps later, we need ASCII URLs,
// UTF-8 would probably not get handled correctly
aURL->GetAsciiSpec(uURL);
uri->GetAsciiHost(uHost);
uri->GetUsername(uUsername);
NS_UnescapeURL(uUsername);
uri->GetPassword(uPassword);
NS_UnescapeURL(uPassword);
uri->GetPort(&iPort);
/* GetPort returns -1 if there is no port in the URI */
if (iPort != -1)
uPort.AppendInt(iPort);
uri->GetPath(uPath);
NS_UnescapeURL(uPath);
// One could use nsIMailtoUrl to get email and newsgroup,
// but it is probably easier to do that quickly by hand here
// uEmail is both email address and message id for news
uEmail = uUsername + NS_LITERAL_CSTRING("@") + uHost;
// uPath can almost be used as newsgroup and as channel for IRC
// but strip leading "/"
uGroup = Substring(uPath, 1, uPath.Length());
NS_NAMED_LITERAL_CSTRING(url, "%url%");
NS_NAMED_LITERAL_CSTRING(username, "%username%");
NS_NAMED_LITERAL_CSTRING(password, "%password%");
NS_NAMED_LITERAL_CSTRING(host, "%host%");
NS_NAMED_LITERAL_CSTRING(port, "%port%");
NS_NAMED_LITERAL_CSTRING(email, "%email%");
NS_NAMED_LITERAL_CSTRING(group, "%group%");
NS_NAMED_LITERAL_CSTRING(msgid, "%msgid%");
NS_NAMED_LITERAL_CSTRING(channel, "%channel%");
if (applicationName.IsEmpty() && parameters.IsEmpty()) {
/* Put application name in parameters */
applicationName.Append(prefString);
nsCAutoString uPort;
PRInt32 iPort;
uri->GetPort(&iPort);
/* GetPort returns -1 if there is no port in the URI */
if (iPort != -1)
uPort.AppendInt(iPort);
nsCAutoString uUsername;
uri->GetUsername(uUsername);
NS_UnescapeURL(uUsername);
nsCAutoString uPassword;
uri->GetPassword(uPassword);
NS_UnescapeURL(uPassword);
nsCAutoString uHost;
uri->GetAsciiHost(uHost);
prefName.Append(".");
nsCOMPtr<nsIPrefBranch> prefBranch;
rv = thePrefsService->GetBranch(prefName.get(), getter_AddRefs(prefBranch));
@ -1316,8 +1371,6 @@ nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
parameters.Append(" ");
parameters.Append(prefString);
NS_NAMED_LITERAL_CSTRING(url, "%url%");
PRInt32 pos = parameters.Find(url.get());
if (pos != kNotFound) {
nsCAutoString uURL;
@ -1361,34 +1414,79 @@ nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
}
}
}
}
#ifdef DEBUG_peter
printf("uURL=%s\n", uURL.get());
printf("uUsername=%s\n", uUsername.get());
printf("uPassword=%s\n", uPassword.get());
printf("uHost=%s\n", uHost.get());
printf("uPort=%s\n", uPort.get());
printf("uPath=%s\n", uPath.get());
printf("uEmail=%s\n", uEmail.get());
printf("uGroup=%s\n", uGroup.get());
#endif
PRInt32 pos;
NS_NAMED_LITERAL_CSTRING(port, "%port%");
NS_NAMED_LITERAL_CSTRING(username, "%username%");
NS_NAMED_LITERAL_CSTRING(password, "%password%");
NS_NAMED_LITERAL_CSTRING(host, "%host%");
pos = parameters.Find(port.get());
if (pos != kNotFound) {
parameters.Replace(pos, port.Length(), uPort);
}
pos = parameters.Find(username.get());
if (pos != kNotFound) {
parameters.Replace(pos, username.Length(), uUsername);
}
pos = parameters.Find(password.get());
if (pos != kNotFound) {
parameters.Replace(pos, password.Length(), uPassword);
}
pos = parameters.Find(host.get());
if (pos != kNotFound) {
parameters.Replace(pos, host.Length(), uHost);
}
PRInt32 pos;
PRBool replaced = PR_FALSE;
pos = parameters.Find(url.get());
if (pos != kNotFound) {
replaced = PR_TRUE;
parameters.Replace(pos, url.Length(), uURL);
}
pos = parameters.Find(username.get());
if (pos != kNotFound) {
replaced = PR_TRUE;
parameters.Replace(pos, username.Length(), uUsername);
}
pos = parameters.Find(password.get());
if (pos != kNotFound) {
replaced = PR_TRUE;
parameters.Replace(pos, password.Length(), uPassword);
}
pos = parameters.Find(host.get());
if (pos != kNotFound) {
replaced = PR_TRUE;
parameters.Replace(pos, host.Length(), uHost);
}
pos = parameters.Find(port.get());
if (pos != kNotFound) {
replaced = PR_TRUE;
parameters.Replace(pos, port.Length(), uPort);
}
pos = parameters.Find(email.get());
if (pos != kNotFound) {
replaced = PR_TRUE;
parameters.Replace(pos, email.Length(), uEmail);
}
pos = parameters.Find(group.get());
if (pos != kNotFound) {
replaced = PR_TRUE;
parameters.Replace(pos, group.Length(), uGroup);
}
pos = parameters.Find(msgid.get());
if (pos != kNotFound) {
replaced = PR_TRUE;
parameters.Replace(pos, msgid.Length(), uEmail);
}
pos = parameters.Find(channel.get());
if (pos != kNotFound) {
replaced = PR_TRUE;
parameters.Replace(pos, channel.Length(), uGroup);
}
// If no replacement variable was used, the user most likely uses the WPS URL
// object and does not know about the replacement variables.
// Just append the full URL.
if (!replaced) {
parameters.Append(" ");
parameters.Append(uURL);
}
const char *params[3];
params[0] = parameters.get();
#ifdef DEBUG_peter
printf("params[0]=%s\n", params[0]);
#endif
PRInt32 numParams = 1;
nsCOMPtr<nsILocalFile> application;
@ -1414,7 +1512,6 @@ nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
params[2] = parameters.get();
numParams = 3;
}
}
nsCOMPtr<nsIProcess> process = do_CreateInstance(NS_PROCESS_CONTRACTID);
@ -1657,3 +1754,55 @@ nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aType,
return retval;
}
NS_IMETHODIMP
nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval)
{
nsCOMPtr<nsIPref> thePrefsService(do_GetService(NS_PREF_CONTRACTID));
if (!thePrefsService) {
return NS_ERROR_FAILURE;
}
nsCAutoString prefName = NS_LITERAL_CSTRING("applications.") + aScheme;
nsXPIDLCString prefString;
nsCAutoString applicationName;
nsresult rv = thePrefsService->CopyCharPref(prefName.get(), getter_Copies(prefString));
if (NS_FAILED(rv) || prefString.IsEmpty()) {
char szAppFromINI[CCHMAXPATH];
char szParamsFromINI[MAXINIPARAMLENGTH];
/* did OS2.INI contain application? */
rv = GetApplicationAndParametersFromINI(aScheme,
szAppFromINI, sizeof(szAppFromINI),
szParamsFromINI, sizeof(szParamsFromINI));
if (NS_SUCCEEDED(rv)) {
applicationName = szAppFromINI;
} else {
return NS_ERROR_NOT_AVAILABLE;
}
} else {
applicationName.Append(prefString);
}
nsCOMPtr<nsILocalFile> application;
rv = NS_NewNativeLocalFile(nsDependentCString(applicationName.get()),
PR_FALSE,
getter_AddRefs(application));
if (NS_FAILED(rv)) {
char szAppPath[CCHMAXPATH];
APIRET rc = DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT,
"PATH",
applicationName.get(),
szAppPath,
sizeof(szAppPath));
/* if that worked, we can use the full pathname */
if (rc == NO_ERROR) {
_retval.Assign(NS_ConvertUTF8toUTF16(nsDependentCString(szAppPath)));
return NS_OK;
}
}
/* if the full path is given or not, use what we have */
_retval.Assign(NS_ConvertUTF8toUTF16(applicationName));
return NS_OK;
}

Просмотреть файл

@ -66,12 +66,16 @@ public:
// override nsIExternalProtocolService methods
NS_IMETHOD ExternalProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
nsresult LoadUriInternal(nsIURI * aURL);
NS_IMETHODIMP GetApplicationDescription(const nsACString& aScheme, nsAString& _retval);
protected:
already_AddRefed<nsMIMEInfoOS2> GetFromType(const nsCString& aMimeType);
already_AddRefed<nsMIMEInfoOS2> GetFromExtension(const nsCString& aFileExt);
private:
nsresult GetApplicationAndParametersFromINI(const nsACString& aProtocol,
char * app, ULONG appLength,
char * param, ULONG paramLength);
// Helper methods which have to access static members
static nsresult UnescapeCommand(const nsAString& aEscapedCommand,
const nsAString& aMajorType,