/
irc_orb/
;var p, new; if(!(| valid($irc_connection) |)) { new = $connection.spawn(); new.set_objname('irc_connection);}
@chmanage $irc_connection to $irc_connection
;as $irc_connection<$root>;.set_quota_exempt(1);

@program $irc_connection.connect +access=driver
arg taskid;

// called by the driver when a connection is made
$scheduler.resume(taskid, 'success);
.

@program $irc_connection.failed +access=driver
arg taskid, reason;

// called by the driver when a connection fails
$scheduler.resume(taskid, reason);
.

@program $irc_connection.uninit_irc_connection +access=root
  $user_neale.debug();
  (| .interface().connection_going_away() |);
  
  // $#Edited: 01 Apr 97 19:41 $user_neale
.

@program $irc_connection.disconnect +access=driver
arg @args;
// called by the driver when a connection has been lost
(> .close() <);
.

@av $irc_connection,connection_nick
@program $irc_connection.set_connection_nick
arg nick;

(> .perms(sender()) <);
connection_nick = nick;
.
@program $irc_connection.connection_nick
(> .perms(sender()) <);
return connection_nick;
.

@program $irc_connection.write +access=pub
arg args, @text;
var buf, t, spaceok;

(| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);

// Might want to add some code to prevent server flooding.
// By using semaphores, we could down, sleep, up.  Real simple.
switch (type(args)) {
  case 'buffer:
    buf = args;
  case 'string:
    buf = args.to_buffer();
  case 'list:
    buf = (args.join()).to_buffer();
  default:
    throw(~type, "args must be a buffer, string, or list.");
}
if (text) {
  // " :" == `[32, 58]
  buf += `[32, 58];
  for t in (text) {
    if (spaceok)
      buf += `[32];
    else
      spaceok = 1;
    switch (type(t)) {
      case 'buffer:
	buf += t;
      case 'string:
	buf += t.to_buffer();
      case 'integer:
	buf += (t.to_string()).to_buffer();
      case 'list:
	buf += (t.join()).to_buffer();
      default:
	throw(~type, "invalid type for text.");
    }
  }
}
buf += `[13, 10];
if (!cwrite(buf)) {
  .close();
  return 0;
}

// $#Edited: 01 Apr 97 19:41 $user_neale
.

@av $irc_connection,line_buffer
@av $irc_connection,buffer
@program $irc_connection.parse() +access=driver
arg incoming;
var lines, line, index;

// called by the driver when a connection receives data
lines = (buffer + incoming + `[10]).break_lines();
index = lines.length();
buffer = lines[index];
lines = lines.delete(index);
line_buffer += lines;
while (line_buffer) {
  line = line_buffer[1];
  line_buffer = line_buffer.delete(1);
  (| .parse_line(line) |);
}
.

@av $irc_connection,nick
@program $irc_connection.nick
(> .perms(sender()) <);
return nick;
.
@program $irc_connection.set_nick
arg nickname;
(> .perms(sender()) <);
nick = nickname;
.

@program $irc_connection.init_irc_connection +access=root
buffer = `[];
line_buffer = [];
.

@av $irc_connection,server_port
@program $irc_connection.set_server_port +access=prot
arg server, port;

if (server_port) {
  throw(~assigned, "Already assigned.");
}
server_port = [server, port];
.
@program $irc_connection.server_port
return server_port;
.

@program $irc_connection.new
var child;

(| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
child = .spawn();

// do perms stuff
child.add_writer(sender());
child.add_writer(this());
child.new_interface(sender());

return child;
.

@av $irc_connection,timeout
@program $connection.set_timeout() +access=pub
arg seconds;

(> .perms(sender(), interface, this()) <);
timeout = seconds;
.

@program $connection.timeout() +access=pub
return (timeout || 30);
.

@program $irc_connection.open_connection() +access=pub
arg host, port;
var code;

(| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
(> .perms(sender()) <);

 (> .set_server_port(host, port) <);
 catch any {
   (> pass($network.ip(host), port) <);
   if (.timeout()) {
     $scheduler.add_task(.timeout(), 'do_timeout, task_id());
   }
   if ((code = $scheduler.suspend(this())) != 'success) {
     throw(~connection, "Couldn't connect: " + code);
   }
 } with {
   throw(~connect, "Can't connect to IRC server: " + traceback()[1][2]);
 }
 .write(["NICK", $motd.server_name()]);
 .write(["USER", $motd.server_name(), "unused1", "unused2"],
        $motd.server_title());
.

@program $irc_connection.do_timeout() +access=public
arg tid;

(| $scheduler.resume(tid, 'timeout) |);
// if it returns an error, that means we connected after all
.

@program $irc_connection.parse_line +access=priv
arg line;

(> .perms(sender()) <);
//$user_neale.debug(line.to_string());
if (.interface().parse_line(line) == 'disconnect) {
  (> .close() <);
}
.