Commit c5e486a3 authored by Daniel Henninger's avatar Daniel Henninger Committed by dhenninger

[JM-761] [JM-770] Base code tweaks and beginnings of MSN support.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@4587 b35dd754-fafc-0310-a699-88a17e54d16e
parent 458964a8
Name | Version
---------------------------------------------
joscar.jar | 0.9.3 (patched)
jmml.jar | cvs-2006-07-19
picocontainer | 1.2.0
ymsg_network.jar | 0.61
ymsg_support.jar | 0.6
......@@ -47,14 +47,25 @@ IM Gateway Readme
<p>
The IM (instant messaging) gateway plugin allows users to log in to and
communicate through other instant messaging services via their Jabber
accounts.
accounts. The gateway itself provides a number of "transports" to other
protocols (AIM, ICQ, MSN, Yahoo, etc).
</p>
<h2>Terminology</h2>
<p>
To help identify the differences between the plugin as a whole and the
underlying interfaces to external protocols (AIM, ICQ, etc), we refer
to the plugin itself as the "gateway" while we refer to the protocol
handlers as "transports".
</p>
<h2>Installation</h2>
<p>
Copy the gateway.jar into the plugins directory of your Wildfire
installation. The plugin will then be automatically deployed. To upgrade to a
new version, copy the new gateway.jar file over the existing file.
new version, copy the new gateway.jar file over the existing file. Please
be aware that an upgrade will cause all of the users on your server who are
making use of the plugin to be disconnected from their external IM accounts.
</p>
<h2>Configuration</h2>
......@@ -66,7 +77,37 @@ This plugin is configured via the "IM Gateway" sidebar item located under the
<h2>Using the plugin</h2>
<p>
Need to write this, need to explain about registering and such.
Before going into specifics, there are some important things you need to
know first. A user must be registered with a transport in order to make
use of it. Registration is the process wherein a user tells a transport
what username and password will be used with the external service. This
process also places the transport JID in their roster to that the
transport itself can "hear" them come online, and act appropriately (logging
them in and such). In this case, we interact with the user's roster directly,
so there is no need for a flood of subscription requests to the client itself.
A side effect of this is that only users of the local Wildfire server will
be able to make use of any transport on the gateway.
</p>
<h3>For admins:</h3>
<p>
The web interface of the gateway plugin provides a mechanism for setting
up registrations on a user's behalf, as well as editing and deleting them.
It also provides tools for monitoring who is using the gateway, their status,
etc. In a typical setup, a user will be allowed to register an account
themselves. See the next section for details on this. You can also
set who has access to the specific transports and even enforce manual
registrations only. If a specific transport has any options, they will
be made available from the web interface.
</p>
<h3>For end users:</h3>
<p>
Typically, users will use Service Discovery (aka disco) to find out what
services are available on a server, and then will be provided with a way
to register with whatever transports are made available. Some clients
do not have the functionality to interact with transports. In this case,
a server admin will need to register the user on their behalf. (see above)
</p>
<h2>Trouble shooting</h2>
......
......@@ -257,13 +257,10 @@ public abstract class BaseTransport implements Component {
else {
Log.debug("Presence to user at gateway");
// This packet is to a user at the transport.
try {
TransportSession session = sessionManager.getSession(from);
if (session == null) {
// We don't have a session, so stop here.
// TODO: maybe return an error?
Log.error("No session for incoming packet: " + packet.toString());
}
else if (packet.getType() == Presence.Type.probe) {
if (packet.getType() == Presence.Type.probe) {
// Presence probe, lets try to tell them.
session.retrieveContactStatus(packet.getTo());
}
......@@ -279,8 +276,12 @@ public abstract class BaseTransport implements Component {
// Anything else we will ignore for now.
}
}
}
catch (NotFoundException e) {
// Well we just don't care then.
}
}
}
catch (Exception e) {
Log.error("Exception while processing packet: " + e.toString());
}
......@@ -656,7 +657,7 @@ public abstract class BaseTransport implements Component {
try {
Roster roster = rosterManager.getRoster(userjid.getNode());
for (RosterItem ri : roster.getRosterItems()) {
if (ri.getJid() == contactjid) {
if (ri.getJid().toBareJID().equals(contactjid.toBareJID())) {
try {
roster.deleteRosterItem(ri.getJid(), false);
}
......
......@@ -69,6 +69,10 @@ public class GatewayPlugin implements Plugin {
/* Set up Yahoo transport. */
transports.put("yahoo", new TransportInstance(TransportType.yahoo, "Yahoo! Transport", "org.jivesoftware.wildfire.gateway.protocols.yahoo.YahooTransport", componentManager));
maybeStartService("yahoo");
/* Set up MSN transport. */
transports.put("msn", new TransportInstance(TransportType.msn, "MSN Transport", "org.jivesoftware.wildfire.gateway.protocols.msn.MSNTransport", componentManager));
maybeStartService("msn");
}
public void destroyPlugin() {
......
/**
* $Revision$
* $Date$
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.gateway.protocols.msn;
import java.util.ArrayList;
import java.util.HashMap;
import org.hn.sleek.jmml.IncomingMessageEvent;
import org.hn.sleek.jmml.MessengerClientAdapter;
import org.jivesoftware.util.Log;
import org.xmpp.packet.Message;
/**
* MSN Listener Interface.
*
* This handles real interaction with MSN, but mostly is a listener for
* incoming events from MSN.
*
* @author Daniel Henninger
*/
public class MSNListener extends MessengerClientAdapter {
/**
* Creates the MSN Listener instance.
*
* @param session Session this listener is associated with.
*/
public MSNListener(MSNSession session) {
this.msnSession = session;
}
/**
* The session this listener is associated with.
*/
public MSNSession msnSession = null;
/**
* Handles incoming messages from MSN.
*/
public void incomingMessage(IncomingMessageEvent event) {
Message m = new Message();
m.setType(Message.Type.chat);
m.setTo(msnSession.getJID());
m.setFrom(msnSession.getTransport().convertIDToJID(event.getUserName()));
m.setBody(event.getMessage());
msnSession.getTransport().sendPacket(m);
}
/**
* Deals with a server disconnection.
*/
public void serverDisconnected() {
msnSession.logOut();
}
}
/**
* $Revision$
* $Date$
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.gateway.protocols.msn;
import org.hn.sleek.jmml.ContactStatus;
import org.hn.sleek.jmml.MessengerServerManager;
import org.hn.sleek.jmml.MSNException;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.gateway.Registration;
import org.jivesoftware.wildfire.gateway.TransportSession;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
/**
* Represents a MSN session.
*
* This is the interface with which the base transport functionality will
* communicate with MSN.
*
* @author Daniel Henninger
*/
public class MSNSession extends TransportSession {
/**
* Create a MSN Session instance.
*
* @param registration Registration informationed used for logging in.
*/
public MSNSession(Registration registration, JID jid, MSNTransport transport) {
super(registration, jid, transport);
msnManager = MessengerServerManager.getInstance();
msnManager.addMessengerClientListener(new MSNListener(this));
}
/**
* MSN session
*/
private MessengerServerManager msnManager = null;
/**
* Log in to MSN.
*/
public void logIn() {
try {
msnManager.signIn(registration.getUsername(), registration.getPassword(), ContactStatus.ONLINE);
Presence p = new Presence();
p.setTo(getJID());
p.setFrom(getTransport().getJID());
getTransport().sendPacket(p);
msnManager.setStatus(ContactStatus.ONLINE);
}
catch (MSNException e) {
Log.error("MSN exception thrown while logging in: " + e.toString());
}
}
/**
* Log out of MSN.
*/
public void logOut() {
try {
msnManager.signOut();
Presence p = new Presence(Presence.Type.unavailable);
p.setTo(getJID());
p.setFrom(getTransport().getJID());
getTransport().sendPacket(p);
}
catch (MSNException e) {
Log.error("MSN exception thrown while logging out: " + e.toString());
}
}
/**
* Have we successfully logged in to MSN?
*/
public Boolean isLoggedIn() {
return msnManager.isConnected();
}
/**
* Adds a contact to the user's MSN contact list.
*
* @param jid JID of contact to be added.
*/
public void addContact(JID jid) {
// TODO: check jabber group and use it
}
/**
* Removes a contact from the user's MSN contact list.
*
* @param jid JID of contact to be added.
*/
public void removeContact(JID jid) {
// TODO: check jabber group and use it
}
/**
* Sends a message from the jabber user to a MSN contact.
*
* @param jid JID of contact to send message to.
* @param message Message to send to yahoo contact.
*/
public void sendMessage(JID jid, String message) {
try {
msnManager.sendMessage(jid.getNode(), message);
}
catch (MSNException e) {
Log.error("MSN exception while sending message: " + e.toString());
}
}
/**
* Asks for transport to send information about a contact if possible.
*
* @param jid JID of contact to be probed.
*/
public void retrieveContactStatus(JID jid) {
// TODO: yeah
}
}
/**
* $Revision$
* $Date$
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.gateway.protocols.msn;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.gateway.BaseTransport;
import org.jivesoftware.wildfire.gateway.Registration;
import org.jivesoftware.wildfire.gateway.TransportSession;
import org.xmpp.packet.JID;
/**
* MSN Transport Interface.
*
* This handles the bulk of the XMPP work via BaseTransport and provides
* some gateway specific interactions.
*
* @author Daniel Henninger
*/
public class MSNTransport extends BaseTransport {
/**
* Handles creating a MSN session and triggering a login.
*
* @param registration Registration information to be used to log in.
*/
public TransportSession registrationLoggedIn(Registration registration, JID jid) {
Log.debug("Logging in to MSN gateway.");
TransportSession session = new MSNSession(registration, jid, this);
session.logIn();
return session;
}
/**
* Handles logging out of a MSN session.
*
* @param session The session to be disconnected.
*/
public void registrationLoggedOut(TransportSession session) {
Log.debug("Logging out of MSN gateway.");
session.logOut();
}
}
......@@ -44,9 +44,9 @@ public class BOSConnection extends BasicFlapConnection {
}
protected void handleStateChange(ClientConnEvent e) {
Log.debug("main connection state changed from "
+ e.getOldState() + " to " + e.getNewState() + ": "
+ e.getReason());
//Log.debug("main connection state changed from "
// + e.getOldState() + " to " + e.getNewState() + ": "
// + e.getReason());
}
protected void handleFlapPacket(FlapPacketEvent e) {
......@@ -92,20 +92,20 @@ public class BOSConnection extends BasicFlapConnection {
FullUserInfo info = yic.getUserInfo();
Log.debug("got my user info: " + info);
//Log.debug("got my user info: " + info);
} else if (cmd instanceof UserInfoCmd) {
UserInfoCmd uic = (UserInfoCmd) cmd;
String sn = uic.getUserInfo().getScreenname();
Log.debug("user info for " + sn + ": "
+ uic.getInfoData());
//Log.debug("user info for " + sn + ": "
// + uic.getInfoData());
} else if (cmd instanceof ServiceRedirect) {
ServiceRedirect sr = (ServiceRedirect) cmd;
Log.debug("connecting to " + sr.getRedirectHost()
+ " for 0x" + Integer.toHexString(sr.getSnacFamily()));
//Log.debug("connecting to " + sr.getRedirectHost()
// + " for 0x" + Integer.toHexString(sr.getSnacFamily()));
oscarSession.connectToService(sr.getSnacFamily(), sr.getRedirectHost(),
sr.getCookie());
......@@ -122,12 +122,12 @@ public class BOSConnection extends BasicFlapConnection {
else if (obj instanceof GroupItem) {
oscarSession.gotGroup((GroupItem)obj);
}
Log.debug("- " + (obj == null ? (Object) items[i]
: (Object) obj));
//Log.debug("- " + (obj == null ? (Object) items[i]
// : (Object) obj));
}
if (sdc.getLastModDate() != 0) {
Log.debug("done with SSI");
//Log.debug("done with SSI");
request(new ActivateSsiCmd());
clientReady();
oscarSession.gotCompleteSSI();
......
......@@ -61,7 +61,7 @@ public abstract class BasicFlapConnection extends BaseFlapConnection {
protected RvProcessor rvProcessor = new RvProcessor(sp);
protected RvProcessorListener rvListener = new RvProcessorListener() {
public void handleNewSession(NewRvSessionEvent event) {
Log.debug("new RV session: " + event.getSession());
//Log.debug("new RV session: " + event.getSession());
event.getSession().addListener(rvSessionListener);
}
......@@ -75,13 +75,13 @@ public abstract class BasicFlapConnection extends BaseFlapConnection {
SnacCommand snaccmd = event.getSnacCommand();
if (!(snaccmd instanceof RecvRvIcbm)) return;
RecvRvIcbm icbm = (RecvRvIcbm) snaccmd;
Log.debug("got rendezvous on session <" + session + ">");
Log.debug("- command: " + cmd);
//Log.debug("got rendezvous on session <" + session + ">");
//Log.debug("- command: " + cmd);
}
public void handleSnacResponse(RvSnacResponseEvent event) {
Log.debug("got SNAC response for <"
+ event.getRvSession() + ">: "
+ event.getSnacCommand());
//Log.debug("got SNAC response for <"
// + event.getRvSession() + ">: "
// + event.getSnacCommand());
}
};
......@@ -117,18 +117,18 @@ public abstract class BasicFlapConnection extends BaseFlapConnection {
if (cmd instanceof LoginFlapCmd) {
getFlapProcessor().sendFlap(new LoginFlapCmd(cookie));
} else {
Log.debug("got FLAP command on channel 0x"
+ Integer.toHexString(e.getFlapPacket().getChannel())
+ ": " + cmd);
//Log.debug("got FLAP command on channel 0x"
// + Integer.toHexString(e.getFlapPacket().getChannel())
// + ": " + cmd);
}
}
protected void handleSnacPacket(SnacPacketEvent e) {
SnacPacket packet = e.getSnacPacket();
Log.debug("got snac packet type "
+ Integer.toHexString(packet.getFamily()) + "/"
+ Integer.toHexString(packet.getCommand()) + ": "
+ e.getSnacCommand());
//Log.debug("got snac packet type "
// + Integer.toHexString(packet.getFamily()) + "/"
// + Integer.toHexString(packet.getCommand()) + ": "
// + e.getSnacCommand());
SnacCommand cmd = e.getSnacCommand();
if (cmd instanceof ServerReadyCmd) {
......@@ -223,17 +223,17 @@ public abstract class BasicFlapConnection extends BaseFlapConnection {
} else if (cmd instanceof RateChange) {
RateChange rc = (RateChange) cmd;
Log.debug("rate change: current avg is "
+ rc.getRateInfo().getCurrentAvg());
//Log.debug("rate change: current avg is "
// + rc.getRateInfo().getCurrentAvg());
}
}
protected void handleSnacResponse(SnacResponseEvent e) {
SnacPacket packet = e.getSnacPacket();
Log.debug("got snac response type "
+ Integer.toHexString(packet.getFamily()) + "/"
+ Integer.toHexString(packet.getCommand()) + ": "
+ e.getSnacCommand());
//Log.debug("got snac response type "
// + Integer.toHexString(packet.getFamily()) + "/"
// + Integer.toHexString(packet.getCommand()) + ": "
// + e.getSnacCommand());
SnacCommand cmd = e.getSnacCommand();
......
......@@ -39,19 +39,19 @@ public class LoginConnection extends BaseFlapConnection {
}
protected void handleStateChange(ClientConnEvent e) {
Log.debug("state changed to: " + e.getNewState() + " (" + e.getReason() + ")");
//Log.debug("state changed to: " + e.getNewState() + " (" + e.getReason() + ")");
if (e.getNewState() == ClientFlapConn.STATE_CONNECTED) {
Log.debug("connected, sending flap version and key request");
//Log.debug("connected, sending flap version and key request");
getFlapProcessor().sendFlap(new LoginFlapCmd());
request(new KeyRequest(oscarSession.getRegistration().getUsername()));
}
else if (e.getNewState() == ClientFlapConn.STATE_FAILED) {
Log.info("connection failed: " + e.getReason());
//Log.info("connection failed: " + e.getReason());
}
else if (e.getNewState() == ClientFlapConn.STATE_NOT_CONNECTED) {
if (!loggedin) {
Log.info("connection lost: " + e.getReason());
//Log.info("connection lost: " + e.getReason());
}
}
}
......@@ -62,9 +62,9 @@ public class LoginConnection extends BaseFlapConnection {
protected void handleSnacResponse(SnacResponseEvent e) {
SnacCommand cmd = e.getSnacCommand();
Log.debug("snac response: "
+ Integer.toHexString(cmd.getFamily()) + "/"
+ Integer.toHexString(cmd.getCommand()) + ": " + cmd);
//Log.debug("snac response: "
// + Integer.toHexString(cmd.getFamily()) + "/"
// + Integer.toHexString(cmd.getCommand()) + ": " + cmd);
if (cmd instanceof KeyResponse) {
KeyResponse kr = (KeyResponse) cmd;
......@@ -89,7 +89,7 @@ public class LoginConnection extends BaseFlapConnection {
} else {
loggedin = true;
oscarSession.startBosConn(ar.getServer(), ar.getPort(), ar.getCookie());
Log.info("connecting to " + ar.getServer() + ":"
Log.info("OSCAR connection to " + ar.getServer() + ":"
+ ar.getPort());
}
......
......@@ -78,7 +78,6 @@ public class OSCARSession extends TransportSession {
public void logIn() {
if (!isLoggedIn()) {
Log.debug("Connecting...");
loginConn = new LoginConnection("login.oscar.aol.com", 5190, this);
loginConn.connect();
......@@ -87,7 +86,6 @@ public class OSCARSession extends TransportSession {
Presence p = new Presence();
p.setTo(getJID());
p.setFrom(getTransport().getJID());
Log.debug("Logged in, sending: " + p.toString());
getTransport().sendPacket(p);
} else {
Log.warn(this.jid + " is already logged in");
......@@ -127,7 +125,6 @@ public class OSCARSession extends TransportSession {
}
public void removeContact(JID jid) {
Log.debug("removeContact called");
for (BuddyItem i : buddies.values()) {
if (i.getScreenname().equals(jid.getNode())) {
request(new DeleteItemsCmd(new SsiItem[] { i.toSsiItem() }));
......@@ -137,7 +134,6 @@ public class OSCARSession extends TransportSession {
}
public void sendMessage(JID jid, String message) {
Log.debug("sendPacket called:"+jid.toString()+","+message);
request(new SendImIcbm(jid.getNode(), message));
}
......@@ -152,7 +148,7 @@ public class OSCARSession extends TransportSession {
protected SnacManager snacMgr = new SnacManager(new PendingSnacListener() {
public void dequeueSnacs(SnacRequest[] pending) {
Log.debug("dequeuing " + pending.length + " snacs");
//Log.debug("dequeuing " + pending.length + " snacs");
for (int i = 0; i < pending.length; i++) {
handleRequest(pending[i]);
}
......@@ -172,8 +168,8 @@ public class OSCARSession extends TransportSession {
} else {
// it's time to request a service
if (!(request.getCommand() instanceof ServiceRequest)) {
Log.debug("requesting " + Integer.toHexString(family)
+ " service.");
//Log.debug("requesting " + Integer.toHexString(family)
// + " service.");
snacMgr.setPending(family, true);
snacMgr.addRequest(request);
request(new ServiceRequest(family));
......@@ -222,7 +218,7 @@ public class OSCARSession extends TransportSession {
* @param buddy The buddy we've been told about.
*/
void gotBuddy(BuddyItem buddy) {
Log.debug("Found buddy item: " + buddy.toString());
//Log.debug("Found buddy item: " + buddy.toString());
buddies.put(buddy.getId(), buddy);
if (buddy.getId() > highestBuddyId) {
highestBuddyId = buddy.getId();
......@@ -235,7 +231,7 @@ public class OSCARSession extends TransportSession {
* @param group The group we've been told about.
*/
void gotGroup(GroupItem group) {
Log.debug("Found group item: " + group.toString());
//Log.debug("Found group item: " + group.toString());
groups.put(group.getId(), group);
if (group.getId() > highestGroupId) {
highestGroupId = group.getId();
......@@ -248,7 +244,7 @@ public class OSCARSession extends TransportSession {
void gotCompleteSSI() {
List<TransportBuddy> legacyusers = new ArrayList<TransportBuddy>();
for (BuddyItem buddy : buddies.values()) {
Log.debug("CompleteSSI: adding "+buddy.getScreenname());
//Log.debug("CompleteSSI: adding "+buddy.getScreenname());
String nickname = buddy.getAlias();
if (nickname == null) {
nickname = buddy.getScreenname();
......
......@@ -58,9 +58,9 @@ public class ServiceConnection extends BasicFlapConnection {
}
protected void handleStateChange(ClientConnEvent e) {
Log.debug("0x" + Integer.toHexString(serviceFamily)
+ " service connection state changed to " + e.getNewState()
+ ": " + e.getReason());
//Log.debug("0x" + Integer.toHexString(serviceFamily)
// + " service connection state changed to " + e.getNewState()
// + ": " + e.getReason());
if (e.getNewState() == ClientFlapConn.STATE_FAILED) {
oscarSession.serviceFailed(this);
......@@ -115,12 +115,12 @@ public class ServiceConnection extends BasicFlapConnection {
Integer id = new Integer(infos[i].getParentId());
List interests = (List) children.get(id);
Log.debug("- " + infos[i].getName());
//Log.debug("- " + infos[i].getName());
if (interests != null) {
for (Iterator it = interests.iterator();
it.hasNext();) {
InterestInfo info = (InterestInfo) it.next();
Log.debug(" - " + info.getName());
//Log.debug(" - " + info.getName());
}
}
}
......@@ -128,8 +128,8 @@ public class ServiceConnection extends BasicFlapConnection {
List toplevels = (List) children.get(new Integer(0));
if (toplevels != null) {
for (Iterator it = toplevels.iterator(); it.hasNext();) {
Log.debug(" "
+ ((InterestInfo) it.next()).getName());
//Log.debug(" "
// + ((InterestInfo) it.next()).getName());
}
}
}
......@@ -140,7 +140,7 @@ public class ServiceConnection extends BasicFlapConnection {
DirInfo[] results = src.getResults();
for (int i = 0; i < results.length; i++) {
Log.debug("result " + (i + 1) + ": " + results[i]);
//Log.debug("result " + (i + 1) + ": " + results[i]);
}
} else if (cmd instanceof IconDataCmd) {
......
......@@ -14,6 +14,7 @@
boolean aimEnabled = ParamUtils.getBooleanParameter(request, "aimEnabled");
boolean icqEnabled = ParamUtils.getBooleanParameter(request, "icqEnabled");
boolean yahooEnabled = ParamUtils.getBooleanParameter(request, "yahooEnabled");
boolean msnEnabled = ParamUtils.getBooleanParameter(request, "msnEnabled");
String serverName = XMPPServer.getInstance().getServerInfo().getName();
GatewayPlugin plugin = (GatewayPlugin)XMPPServer.getInstance().getPluginManager().getPlugin("gateway");
......@@ -39,6 +40,12 @@
else {
plugin.disableService("yahoo");
}
if (msnEnabled) {
plugin.enableService("msn");
}
else {
plugin.disableService("msn");
}
response.sendRedirect("gateway-service.jsp?success=true");
return;
}
......@@ -46,6 +53,7 @@
aimEnabled = plugin.serviceEnabled("aim");
icqEnabled = plugin.serviceEnabled("icq");
yahooEnabled = plugin.serviceEnabled("yahoo");
msnEnabled = plugin.serviceEnabled("msn");
%>
<html>
......@@ -188,6 +196,43 @@ JID provided in each corresponding section.
<br><br>
<fieldset>
<legend>MSN Gateway</legend>
<div>
<p>
This gateway provides a mechanism for users to access the MSN network.
Users will be able to register with the JID specified below, specifying
their MSN username and password.<br />
<br />
JID: msn.<%= serverName %>
</p>
<table cellpadding="3" cellspacing="0" border="0" width="100%">
<tbody>
<tr>
<td width="1%">
<input type="radio" name="msnEnabled" value="true" id="rb03"
<%= ((msnEnabled) ? "checked" : "") %>>
</td>
<td width="99%">
<label for="rb01"><b>Enabled</b> - MSN gateway is available.</label>
</td>
</tr>
<tr>
<td width="1%">
<input type="radio" name="msnEnabled" value="false" id="rb04"
<%= ((!msnEnabled) ? "checked" : "") %>>
</td>
<td width="99%">
<label for="rb01"><b>Disabled</b> - MSN gateway is not available.</label>
</td>
</tr>
</tbody>
</table>
</div>
</fieldset>
<br><br>
<input type="submit" value="Save Settings">
</form>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment