i got ircsrv to automatically authenticate via PASS and/or NickServ
through factotum and added a joinlist option.  i haven't written much
C in years so comments/criticism welcome :)

apologies for the sloppy patch + the 60 second sleep (might lower it i
guess).  i also should've split it into multiple commits but thought
yall would like to see it.  it connects well and i can chat so far.
haven't used it for a while to uncover any hidden bugs

thank u

--
noodle

---
diff ef4697c47cda464feb2fb57fcedf9453eb0bfddc 
37e5da47095c2e3d7ab843988decc0c6cd32fc83
--- 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]
@@ -79,6 +79,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-M4bd75d514a2b0a715a99c9de
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription

Reply via email to