sorry i forgot to specify that i'm patching on top of
https://github.com/pete/irc7 so the patch won't apply on the 9p.io or
https://code.9front.org/hg/irc7 versions.  i sent another diff below
that applies on top of https://code.9front.org/hg/irc7 commit
6c4572b47d06d30b86d2aab66c8ef5d666608929 without trouble.
(code.9front.org looks offline right now; bad timing :b).  the 9p.io
version seems to not have TLS support so adding authentication to it
is counterintuitive

after some use, i can confirm it automatically authenticates to
liberachat and oftc without trouble.  (a friend says it has trouble
connecting to ircnow but we haven't figured it out yet.  seems their
nickserv has a quirk).  the joinlist works well too.

it's still rough around the edges with it forgetting to reconnect from
time to time and having to monitor all dms to not miss messages (the
latter problem seems to be solved by the pete version but i haven't
tested their patches much.  i posted the last patch then after i
realized i sent an unapply-able patch i reverted pete's diffs on my
version for tha time.  i should test the more).

ircs seems to handle dms and reconnection well (except when
reconnecting to oftc for some reason) but it's code is complex to hack
on.

--
noodle

---
diff 4e3135c90cc6de1bb782fce03d17d1d1a9dd5876 
7106744269a9b3af0fba432ae8de47cbcd9f8ead
--- a/irc.man
+++ b/irc.man
@@ -4,7 +4,7 @@
 .SH SYNOPSIS
 .B ircsrv
 [
-.I -e
+.I -eip
 ]
 [
 .I -s service
@@ -13,7 +13,7 @@
 .I -f file
 ]
 [
-.I -p pass
+.I -j joinlist
 ]
 .I nickname
 .I [net!]irc.server.org[!port]
@@ -75,6 +75,18 @@
 The
 .I -e
 flag enables SSL, the
+.I -f
+flag sets the pathname of the log file, the
+.I -j
+flag sets a list of channels to join (ex: -j '#aaa,#bbb,#ccc'), the
+.I -s
+flag sets the filename of the service file under /srv,
+.I -i
+flag sends a password to NickServ (from factotum service=ircsrv) after 
connecting to server and enables SSL, the
+.I -p
+flag is like the
+.I -i
+flag but sends the password to the server on connection instead (both can be 
combined), the
 .I -c
 flag sets character set conversion using
 .IR tcs (1),
--- a/ircsrv.c
+++ b/ircsrv.c
@@ -3,6 +3,8 @@
 #include <auth.h>
 #include <libsec.h>
 
+enum { ReconDelay = 60 };      /* time in seconds to sleep before reconnecting 
to server */
+
 char *post;
 char *file;
 int ircfd = -1;        // the irc server
@@ -10,23 +12,27 @@
 int enctls = 0; // ssl/tls
 QLock lck;
 
+UserPasswd *pass = nil;
+UserPasswd *nickpass = nil;
+char *chans = nil;
+char *host;
 char *server;
-char *passwd;
 char *nickname;
-char *realname;
-char *username;
-char *mode = "foo";
-char *unused = "bar";
+char *realname = nil;
+char *username = nil;
+char *port = "6667";
 
 void ircsrv(void);
 void logger(void);
 void die(void*, char*);
 void reconnect(void);
+void authnick(void);
+void joinchans(void);
 
 void
 usage(void)
 {
-       fprint(2, "usage: %s [-e] [-s service] [-f file] [-p pass] nickname 
[net!]ircserver[!port]\n", argv0);
+       fprint(2, "usage: %s [-eip] [-f file] [-j join] [-s service] [ -r 
realname ] [ -u username ] nickname [net!]ircserver[!port]\n", argv0);
        exits("usage");
 }
 
@@ -50,13 +56,17 @@
 void
 main(int argc, char *argv[])
 {
-       char *tmp;
-       int p[2], fd;
+       char *netaddr[3];
+       int getpass = 0, getnickpass = 0;
+       int nf, p[2], fd;
 
        ARGBEGIN{
        case 'f':
                file = EARGF(usage());
                break;
+       case 'j':
+               chans = EARGF(usage());
+               break;
        case 's':
                post = EARGF(usage());
                break;
@@ -63,19 +73,20 @@
        case 'r':
                realname = EARGF(usage());
                break;
+       case 'u':
+               username = EARGF(usage());
+               break;
        case 'e':
                enctls = 1;
                break;
        case 'p':
-               passwd = EARGF(usage());        
-               /* try to obfuscate the password so ps -a won't see it */
-               tmp = passwd;
-               passwd = smprint("%s", tmp);
-               if(passwd) 
-                       memset(tmp, '\0', strlen(tmp));
-               else
-                       passwd = tmp;
+               getpass = 1;
+               enctls = 1;
                break;
+       case 'i':
+               getnickpass = 1;
+               enctls = 1;
+               break;
        default:
                usage();
        }ARGEND;
@@ -82,16 +93,34 @@
 
        if(argc < 2)
                usage();
+       if(enctls)
+               port = "6697";
 
-
        nickname = argv[0];
        server = argv[1];
 
-       username = getuser();
+       nf = getfields(server, netaddr, 3, 0, "!");
+       host = nf == 3 ? netaddr[1] : server;
+       if(getpass){
+               pass = auth_getuserpasswd(auth_getkey,
+                       "proto=pass service=irc server=%q user=%q", host, 
nickname);
+               if(pass == nil)
+                       sysfatal("auth_getuserpasswd");
+       }
+       if(getnickpass){
+               nickpass = auth_getuserpasswd(auth_getkey,
+                       "proto=pass service=ircsrv server=%q user=%q", host, 
nickname);
+               if(nickpass == nil)
+                       sysfatal("auth_getuserpasswd");
+       }
 
+       if(!username)
+               username = getuser();
        if(strlen(username) > 4)
                username[4] = '\0';
 
+       if (!realname)
+               realname = "<nil>";
 
        if(post == nil)
                post = smprint("/srv/%sirc", username);
@@ -188,22 +217,51 @@
        TLSconn *conn;
        if(ircfd >= 0)
                close(ircfd);
-       if((ircfd = dial(netmkaddr(server, "tcp", "6667"), nil, nil, nil)) < 0)
+       if((ircfd = dial(netmkaddr(server, "tcp", port), nil, nil, nil)) < 0)
                sysfatal("dial %r");
-       if(enctls > 0) {
+       if(enctls > 0){
                conn = (TLSconn *)mallocz(sizeof *conn, 1);
-               ircfd = tlsClient(ircfd, conn);
+        ircfd = tlsClient(ircfd, conn);
                if (ircfd < 0) { sysfatal ("tls: %r"); }
        }
-       if(passwd && strcmp(passwd, ""))
-               fprint(ircfd, "PASS %s\r\n", passwd);
-       fprint(ircfd, "USER %s %s %s :%s\r\n",
-               nickname, mode, unused, realname);
+       if(pass && pass->passwd && strcmp(pass->passwd, ""))
+               fprint(ircfd, "PASS %s\r\n", pass->passwd);
+       fprint(ircfd, "USER %s * * :%s\r\n", username, realname);
        fprint(ircfd, "NICK %s\r\n", nickname);
+       authnick();
+       joinchans();
 }
 
+void
+joinchans(void)
+{
+       char *s, *e;
+       if(!chans)
+               return;
+       for(s = e = chans; *e; e++)
+               if (*e == ',' && e - s > 0) {
+                       fprint(ircfd, "JOIN %.*s\r\n", (int) (e - s), s);
+                       s = e + 1;
+               }
+       if(e - s > 0)
+               fprint(ircfd, "JOIN %.*s\r\n", (int) (e - s), s);
+}
 
 void
+authnick(void){
+       char *labels[3];
+       int nf;
+
+       if(!nickpass || !nickpass->passwd || !strcmp(nickpass->passwd, ""))
+               return;
+       nf = getfields(host, labels, 3, 0, ".");
+       if(nf == 3 && !strcmp(labels[1], "oftc") && !strcmp(labels[2], "net"))
+               fprint(ircfd, "PRIVMSG NickServ :IDENTIFY %s %s\r\n", 
nickpass->passwd, nickname);
+       else
+               fprint(ircfd, "PRIVMSG NickServ :IDENTIFY %s %s\r\n", nickname, 
nickpass->passwd);
+}
+
+void
 logger(void)
 {
        char buf[513];
@@ -211,6 +269,7 @@
        long n;
 
        for(;;){
+               int doreauth = 0;
                while((n = readln(ircfd, buf, sizeof(buf)-1)) > 0){
                        fprint(logfd, "%ld ", time(0));
                        write(logfd, buf, n);
@@ -221,15 +280,21 @@
                                fprint(ircfd, "PONG %s\r\n", f[2]);
                                fprint(logfd, "%ld PONG %s\r\n", time(0), f[2]);
                                qunlock(&lck);
-                       } else if(n == 2 && !cistrcmp(f[0], "PING")){
+                       }else if(n == 2 && !cistrcmp(f[0], "PING")){
                                qlock(&lck);
                                fprint(ircfd, "PONG %s\r\n", f[1]);
                                fprint(logfd, "%ld PONG %s\r\n", time(0), f[1]);
                                qunlock(&lck);
-                       } else if(n == 3 && atoi(f[1]) == 433) {
+                       }else if(n == 3 && (atoi(f[1]) == 433 || atoi(f[1]) == 
437)){
                                reregister();
+                               doreauth = 1;
+                       }else if (doreauth && n == 3 && atoi(f[1]) == 001){
+                               authnick();
+                               fprint(ircfd, "PRIVMSG NickServ :REGAIN 
%s\r\n", nickname);
+                               joinchans();
                        }
                }
+               sleep(ReconDelay * 1000);
                reconnect();
        }
 }
@@ -251,5 +316,3 @@
        }
        killall();
 }
-
-
-- 
⑨


------------------------------------------
9fans: 9fans
Permalink: 
https://9fans.topicbox.com/groups/9fans/Tda2484b041420163-M836f7ba4f98bd81120bd567d
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription

Reply via email to