class Connection : Object {
public Lm.Connection cn;
public string jid;
public string password;
public string resource;
public string server;
public int port;
public bool ssl;
public enum State {
DISCONNECTED,
CONNECTING,
AUTHENTICATING,
CONNECTED
}
protected State _state;
public State state {
get { return _state; }
}
public Gee.ArrayList<Module> modules;
public signal void state_changed(State old_state, State new_state, string description);
public signal void check_time();
protected void _change_state(State new_state, string description) {
var old_state = this._state;
if (old_state != new_state) {
this._state = new_state;
stderr.printf("State changed %s -> %s : %s\n",old_state.to_string(), new_state.to_string(), description);
state_changed(old_state, new_state, description);
} else
stderr.printf("State not changed %s : %s\n",old_state.to_string(), description);
}
public Connection(Config cfg) {
this.modules = new Gee.ArrayList<Module>();
this.jid = cfg["server","jid"];
this.password = cfg["server","password"];
this.server = cfg.get_default("server", "server", this.jid.split("@",2)[1]);
if (cfg.has_key("server", "port"))
this.port = cfg["server", "port"].to_int();
else
this.port = Lm.Connection.DEFAULT_PORT;
this.ssl = (cfg.get_default("server", "ssl", "yes")=="yes");
this.resource = cfg.get_default("server", "resource", "iswydt");
cn = new Lm.Connection(this.server);
cn.set_disconnect_function((connection, reason) => {
stderr.printf("Disconnected: %s\n",reason.to_string());
_change_state(State.DISCONNECTED,reason.to_string());
}, null);
var msg_handler = new Lm.MessageHandler((handler, connection, message) => {
stdout.printf("Got msg\n");
var node = message.get_node();
var body = node.find_child("body");
if (body!=null) {
stdout.printf("MSG %s to %s: %s\n", node.get_attribute("from"), node.get_attribute("to"), body.get_value());
}
return Lm.HandlerResult.ALLOW_MORE_HANDLERS;
}, null);
cn.register_message_handler(msg_handler, Lm.MessageType.MESSAGE, Lm.HandlerPriority.NORMAL);
/*var muc_handler = new Lm.MessageHandler((handler, connection, message) => {
var node = message.node;
var from = node.get_attribute("from");
if (from != null) {
var froms = from.split("/",2);
//stdout.printf("From: %s %s\n",node.to_string(),message.get_type().to_string());
if (rooms.has_key(froms[0])) {
return rooms[froms[0]].muc_handler(handler, connection, message);
}
}
return Lm.HandlerResult.ALLOW_MORE_HANDLERS;
}, null);
cn.register_message_handler(muc_handler, Lm.MessageType.MESSAGE, Lm.HandlerPriority.NORMAL);
cn.register_message_handler(muc_handler, Lm.MessageType.PRESENCE, Lm.HandlerPriority.NORMAL);
cn.register_message_handler(muc_handler, Lm.MessageType.IQ, Lm.HandlerPriority.NORMAL);*/
state_changed.connect( (olds, news, desc) => {
if (news == Connection.State.CONNECTED) {
cn.send_raw("<message to='stiletto@stiletto.name'><body>ТХБ</body></message>");
/*var room = new Conference(this, "говнохост@conference.blasux.ru", "Ζαλυπα");
room.join("Oh hai");
this.rooms[room.jid] = room;*/
}
});
check_time.connect( () => {
if (_state == State.DISCONNECTED)
open();
});
}
public void add_module(Module module) {
modules.add(module);
}
public void open() {
stderr.printf("Connecting to %s:%d as %s\n",server,port,jid);
cn.set_port(port);
cn.set_jid(jid);
_change_state(State.CONNECTING,"");
try {
var result = cn.open((connection, consuc) => {
stderr.printf("Connection success: %s\n",consuc.to_string());
if (consuc) {
_change_state(State.AUTHENTICATING,"");
stderr.printf("Authing\n");
cn.authenticate(jid.split("@",2)[0],password, resource, (connection, authsuc) => {
stderr.printf("Auth success: %s\n",authsuc.to_string());
if (authsuc) {
_change_state(State.CONNECTED,"");
} else
cn.close();
}, null);
} else {
_change_state(State.DISCONNECTED, "Connection not successful");
}
}, null);
if (!result)
_change_state(State.DISCONNECTED, "Open failed");
} catch (Error e) {
stderr.printf("Error: %s\n", e.message);
_change_state(State.DISCONNECTED, e.message);
}
}
public void close(string reason) {
if ((state==State.CONNECTED)&&(reason != null)) {
var prs = new Lm.Message(null, Lm.MessageType.PRESENCE);
prs.node.set_attribute("type","unavailable");
prs.node.add_child("status",reason);
cn.send(prs);
}
cn.close();
}
}
static Connection account;
static MainLoop loop;
int main(string[] args) {
if (args.length<2) {
stderr.printf("Usage: %s <config file>\n",args[0]);
return 1;
}
Log.set_handler("Muc", (LogLevelFlags)65535, (domain, levels, message) => {
stderr.printf("--- %s\n", message);
});
Log.set_handler("muc_log", (LogLevelFlags)65535, (domain, levels, message) => {
stderr.printf("--- %s\n", message);
});
log("LM", LogLevelFlags.LEVEL_DEBUG, "HATE HATE");
var cfg = new Config.from_file(args[1]);
loop = new MainLoop();
account = new Connection(cfg);
//account.open();
stdout.printf("Fuck yeah\n");
var checktimer = new TimeoutSource(2000);
checktimer.set_callback(() => {
account.check_time();
//stderr.printf("TimeoutSource OLOLO\n");
return true;
});
checktimer.attach(loop.get_context());
account.add_module(new ModuleIq(cfg, account));
account.add_module(new ModuleMuc(cfg, account));
account.add_module(new ModuleMucCommands(cfg, account));
account.add_module(new ModuleMucLog(cfg, account));
Posix.sigaction_t action = Posix.sigaction_t();
action.sa_handler = ((i) => {
if (account.state != Connection.State.CONNECTED)
loop.quit();
else {
account.state_changed.connect( (olds, news, desc) => {
if (news == Connection.State.DISCONNECTED)
loop.quit();
});
account.close("Received SIGINT");
}
});
Posix.sigaction(Posix.SIGINT, action, null);
loop.run();
return 0;
}