From 3fd1c5a3592d6395d2ee890ccdbf2d2e151a9255 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 10 Nov 2017 21:38:43 +0000 Subject: [PATCH] irc: because every platform needs an irc client --- Applications/netd/Makefile.z80 | 9 +- Applications/netd/linein.c | 169 ++++++++ Applications/netd/tinyirc.c | 743 +++++++++++++++++++++++++++++++++ 3 files changed, 918 insertions(+), 3 deletions(-) create mode 100644 Applications/netd/linein.c create mode 100644 Applications/netd/tinyirc.c diff --git a/Applications/netd/Makefile.z80 b/Applications/netd/Makefile.z80 index 7a9f87f0..480f97fb 100644 --- a/Applications/netd/Makefile.z80 +++ b/Applications/netd/Makefile.z80 @@ -2,12 +2,13 @@ SRCS = netd.c uip.c uiplib.c timer.c clock-arch.c uip_arp.c telnet.c slip.c SRCS += echoping.c dig.c gethostbyname.c httpd.c ping.c ntpdate.c +SRCS += linein.c tinyirc.c OBJS = $(SRCS:.c=.rel) -APPS = netd-slip telnet echoping dig httpd ping ntpdate +APPS = netd-slip telnet echoping dig httpd ping ntpdate irc -OPTS = -O2 -DNETD_LITTLE_ENDIAN +OPTS = -DNETD_LITTLE_ENDIAN all: $(APPS) @@ -38,6 +39,8 @@ ping: ping.rel gethostbyname.rel ntpdate: ntpdate.rel gethostbyname.rel fcc -o $@ $^ +irc: tinyirc.rel linein.rel gethostbyname.rel + fcc -o $@ $^ clean: - rm -f *.rel *.lst *.asm *.noi *.map *.lk *.sym *~ *.ihx *.bin + rm -f *.rel *.lst *.asm *.noi *.map *.lk *.sym *~ *.ihx *.bin $(APPS) diff --git a/Applications/netd/linein.c b/Applications/netd/linein.c new file mode 100644 index 00000000..5999e160 --- /dev/null +++ b/Applications/netd/linein.c @@ -0,0 +1,169 @@ +/* + * Simple implementation of canonical style line input with redraw + * and timeout. + * + * At the moment we only deal with the very simplest elements of the + * tty - no word delete, quoting etc just typing and deleting and + * going beep + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "linein.h" + +static char *buffer, *bufstart, *bufpos, *bufend; + +static void undraw(int len) +{ + int i; + for (i = 0; i < len; i++) + fputs("\010 \010", stdout); + fflush(stdout); +} + +static void redraw(void) +{ + if (bufpos != bufstart) + fwrite(buffer, bufpos-bufstart, 1, stdout); + fflush(stdout); +} + +static uint8_t tty_do(char c) +{ + switch(c) { + case 8: + case 127: + if (bufpos > bufstart) + undraw(1); + bufpos--; + return 1; + case '\n': + case '\r': + if (bufpos == bufstart) + return 1; + *bufpos++ = 0; + putchar('\n'); + bufpos = bufstart; + return 2; + case 3: + kill(getpid(), SIGINT); + return 1; + case ('\'' & 31): + kill(getpid(), SIGQUIT); + return 1; + case 4: + if (bufpos == bufstart) + return 2; + return 1; + case 'U' - 64: + undraw(bufpos - bufstart); + bufpos = bufstart; + return 1; + case 'R' - 64: + undraw(bufpos - buffer); + redraw(); + return 1; + case 9: + c = ' '; + default: + if (c < 32 || c > 126) + return 1; + if (bufpos == bufend - 1) { + putchar(7); + fflush(stdout); + return 1; + } + *bufpos++ = c; + putchar(c); + fflush(stdout); + return 1; + } +} + +int tty_event(void) +{ + char c; + int n; + + do { + n = read(0, &c, 1); + if (n == -1 && errno != EAGAIN) + return -1; + if (n) + n = tty_do(c); + } while(n == 1); + return n; +} + +void tty_hide(void) +{ + undraw(bufpos - buffer); +} + +void tty_show(void) +{ + redraw(); +} + +static struct termios term, save; +static uint8_t tty_saved; + +int tty_width = 80; + +int tty_begin(void) +{ + struct winsize sz; + const char *p; + int n; + + if (!isatty(0)) + return 0; + if (tcgetattr(0, &save) == -1) { + perror("tcgetattr"); + return -1; + } + tty_saved = 1; + memcpy(&term, &save, sizeof(struct termios)); + term.c_lflag &= ~(ICANON|ECHO|ISIG); + term.c_cc[VMIN] = 0; + term.c_cc[VTIME] = 10; + if (tcsetattr(0, TCSADRAIN, &term) == -1) { + perror("tcsetattr"); + return -1; + } + if (ioctl(0, TIOCGWINSZ, &sz) == 0) + tty_width = sz.ws_col; + p = getenv("COLS"); + if (p) { + n = atoi(p); + if (n >= 20) + tty_width = n; + } + return 0; +} + +int tty_restore(void) +{ + return tcsetattr(0, TCSADRAIN, &save); +} + +int tty_resume(void) +{ + return tcsetattr(0, TCSADRAIN, &term); +} + +void tty_set_buffer(char *base, int promptlen, int totalsize) +{ + buffer = base; + bufstart = base + promptlen; + bufpos = bufstart; + bufend = base + totalsize - 1; +} diff --git a/Applications/netd/tinyirc.c b/Applications/netd/tinyirc.c new file mode 100644 index 00000000..f3c0a07c --- /dev/null +++ b/Applications/netd/tinyirc.c @@ -0,0 +1,743 @@ +/* + NanoIRC 0.1 + + Based heavily upon + + TinyIRC 1.1 + Copyright (C) 1991-1996 Nathan I. Laredo + + This program is modifiable/redistributable under the terms + of the GNU General Public Licence. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Send your comments and all your spare pocket change to + laredo@gnu.ai.mit.edu (Nathan Laredo) or to PSC1, BOX 709, + Lackland AFB, TX, 78236-5128 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "linein.h" + +#define COMMANDCHAR '/' +#define ASCIIHEXCHAR '@' +#define HEXASCIICHAR '#' +#define RELEASE "NanoIRC 0.1" +/* most bytes to try to read from server at one time */ +#define IB_SIZE 256 + +static unsigned short irc_port = 6667; + +struct dlist { + char name[64]; + char mode[64]; + struct dlist *next; +}; + +#define ischan(x) (*x == '#' || *x == '&' || *x == '+') + +static struct dlist *obj = NULL, *olist = NULL, *newobj; +static int my_tcp; +static int sok = 1; +static int column; +static char *tmp, *fromhost; +static char *tok[20]; +static char ircname[32]; +static char *irclogin; +static char *gecos; +static char ib[IB_SIZE]; +static char serverdata[512]; +static char ch; +static char lineout[512] = { +"NanoIRC 0.1 based upon TinyIRC\n\ +(C) 1991-1996 Nathan Laredo\n\ +This is free software with ABSOLUTELY NO WARRANTY.\n\ +For details please see the file COPYING." +}; + +static int cursd = 0; +static int noinput = 0; +static int reconnect = 1; +static time_t idletimer, tmptime; +static struct passwd *userinfo; + +static char inbuf[256]; + +static struct dlist *additem(char *item, struct dlist *p) +{ + newobj = (struct dlist *) malloc(sizeof(struct dlist)); + strlcpy(newobj->name, item, 64); + newobj->mode[0] = '\0'; + newobj->next = p; + return newobj; +} + +static struct dlist *finditem(char *item, struct dlist *p) +{ + while (p != NULL) + if (strcasecmp(item, p->name) == 0) + break; + else + p = p->next; + return p; +} + +static struct dlist *delitem(char *item, struct dlist *p) +{ + struct dlist *prev = NULL, *start = p; + while (p != NULL) + if (strcasecmp(item, p->name) == 0) { + newobj = p->next; + if (obj == p) + obj = NULL; + free(p); + if (prev == NULL) + return newobj; + else { + prev->next = newobj; + return start; + } + } else { + prev = p; + p = p->next; + } + return start; +} + +static char encoded[513]; + +static void hexascii(const char *s) +{ + uint8_t byte; + uint8_t k = 0; + char *p = encoded; + + while(*s && p < encoded + 400) { + ch = toupper(*s); + s++; + if (ch >= '0' && ch <= '9') + byte = (byte << 4) | (ch - '0'); + else if (ch >= 'A' && ch <= 'F') + byte = (byte << 4) | (ch - 'A' + 10); + else + continue; + if (k++ & 1) + *p++ = byte; + } + *p = 0; +} + +static void asciihex(const char *s) +{ + char *p = encoded; + static char hex[] = "0123456789ABCDEF"; + + while(*s && p != encoded + sizeof(encoded) - 1) { + uint8_t c = *s++; + *p++ = hex[c >> 4]; + *p++ = hex[c & 15]; + } + *p = 0; +} + +/* FIXME: turn off ndelay for the write */ +static int sendline(void) +{ + if (write(my_tcp, lineout, strlen(lineout)) < 1) + return 0; + return 1; +} + +static int nop(void) +{ + return 1; +} + +static int doerror(void) +{ + column = printf("*** ERROR:"); + return 2; +} + +static int doinvite(void) +{ + printf("*** %s (%s) invites you to join %s.", tok[0], fromhost, tok[3]); + return 0; +} + +static int dojoin(void) +{ + if (strcmp(tok[0], ircname) == 0) { + obj = olist = additem(tok[2], olist); + sprintf(lineout, "MODE :%s\n", obj->name); + sendline(); + printf("*** Now talking in %s", obj->name); + } else + printf("*** %s (%s) joined %s", tok[0], fromhost, tok[2]); + return 0; +} + +static int dokick(void) +{ + printf("*** %s was kicked from %s by %s (%s)", tok[3], tok[2], tok[0], tok[4]); + if (strcmp(tok[3], ircname) == 0) { + olist = delitem(tok[2], olist); + if (obj == NULL) + obj = olist; + if (obj != NULL) + printf("\n\r*** Now talking in %s", obj->name); + } + return 0; +} + +static int dokill(void) +{ + printf("*** %s killed by %s: ", tok[3], tok[0]); + if (strcmp(tok[3], ircname) == 0) + reconnect = 0; /* don't reconnect if killed */ + return 4; +} + +static int domode(void) +{ + char *t = tok[3], op = *tok[3]; + printf("*** %s changed %s to:", tok[0], tok[2]); + if ((newobj = finditem(tok[2], olist)) != NULL) { + while ((t = strpbrk(t, "-+psitnml")) != NULL) { + if (*t == '-' || *t == '+') + op = *t; + else if (op == '-') + for (tmp = strchr(newobj->mode, *t); *tmp != '\0'; tmp++) + *tmp = *(tmp + 1); + else + strncat(newobj->mode, t, 1); + t++; + } + } + return 3; +} + +static int donick(void) +{ + if (strcmp(tok[0], ircname) == 0) + strlcpy(ircname, tok[2], 32); + printf("*** %s is now known as %s", tok[0], tok[2]); + return 0; +} + +static int donotice(void) +{ + if (!ischan(tok[2])) + column = printf("-%s-", tok[0]); + else + column = printf("-%s:%s-", tok[0], tok[2]); + return 3; +} + +static int dopart(void) +{ + printf("*** %s (%s) left %s", tok[0], fromhost, tok[2]); + if (strcmp(tok[0], ircname) == 0) { + olist = delitem(tok[2], olist); + if (obj == NULL) + obj = olist; + if (obj != NULL) + printf("\n\r*** Now talking in %s", obj->name); + } + return 0; +} + +static int dopong(void) +{ + column = printf("*** Got PONG from %s:", tok[0]); + return 3; +} + +static int doprivmsg(void) +{ +#ifdef DO_CTCP + if (strncmp(tok[3], "\01PING", 5) == 0) { /* lame ctcp ping hack */ + sprintf(lineout, "NOTICE %s :%s\n", tok[0], tok[3]); + column = printf("*** CTCP PING from %s", tok[0]); + sendline(); + return 0; + } else if (strncmp(tok[3], "\01VERSION", 8) == 0) { /* lame ctcp */ + sprintf(lineout, "NOTICE %s :\01VERSION " RELEASE " :*ix\01\n", tok[0]); + column = printf("*** CTCP VERSION from %s", tok[0]); + sendline(); + return 0; + } +#endif + if (!ischan(tok[2])) { + column = printf("*%s*", tok[0]); + } else if (obj != NULL && strcasecmp(obj->name, tok[2])) + column = printf("<%s:%s>", tok[0], tok[2]); + else + column = printf("<%s>", tok[0]); + return 3; +} + +static int doquit(void) +{ + printf("*** %s (%s) Quit (%s)", tok[0], fromhost, tok[2]); + return 0; +} + +static int dosquit(void) +{ + return 1; +} + +static int dotime(void) +{ + return 1; +} + +static int dotopic(void) +{ + printf("*** %s set %s topic to \"%s\"", tok[0], tok[2], tok[3]); + return 0; +} + +int donumeric(int num) +{ + switch (num) { + case 352: + column = printf("%-14s %-10s %-3s %s@%s :", tok[3], tok[7], tok[8], tok[4], tok[5]); + return 9; + case 311: + column = printf("*** %s is %s@%s", tok[3], tok[4], tok[5]); + return 6; + case 324: + if ((newobj = finditem(tok[3], olist)) != NULL) + strlcpy(newobj->mode, tok[4], 64); + break; + case 329: + tmptime = atoi(tok[4]); + strcpy(lineout, ctime(&tmptime)); + tmp = strchr(lineout, '\n'); + if (tmp != NULL) + *tmp = '\0'; + column = printf("*** %s formed %s", tok[3], lineout); + return 0; + case 333: + tmptime = atoi(tok[5]); + strcpy(lineout, ctime(&tmptime)); + tmp = strchr(lineout, '\n'); + if (tmp != NULL) + *tmp = '\0'; + column = printf("*** %s topic set by %s on %s", tok[3], tok[4], lineout); + return 0; + case 317: + tmptime = atoi(tok[5]); + strcpy(lineout, ctime(&tmptime)); + tmp = strchr(lineout, '\n'); + if (tmp != NULL) + *tmp = '\0'; + column = printf("*** %s idle %s second(s), on since %s", tok[3], tok[4], lineout); + return 0; + case 432: + case 433: + printf("*** You've chosen an invalid nick. Choose again."); + tmp = ircname; + tty_restore(); + printf("New Nick? "); + fgets(ircname, 32, stdin); + tmp = strchr(ircname, '\n'); + if (tmp) + *tmp = '\0'; + tty_resume(); + sprintf(lineout, "NICK :%s\n", ircname); + sendline(); + return 0; + default: + break; + } + column = 0;//printf("%s", tok[1]); + return 3; +} + +#define LISTSIZE 49 +static char *clist[LISTSIZE] = { "ADMIN", "AWAY", "CLOSE", "CONNECT", "DIE", "DNS", "ERROR", "HASH", + "HELP", "INFO", "INVITE", "ISON", "JOIN", "KICK", "KILL", "LINKS", "LIST", + "LUSERS", "MODE", "MOTD", "MSG", "NAMES", "NICK", "NOTE", "NOTICE", "OPER", + "PART", "PASS", "PING", "PONG", "PRIVMSG", "QUIT", "REHASH", "RESTART", + "SERVER", "SQUIT", "STATS", "SUMMON", "TIME", "TOPIC", "TRACE", "USER", + "USERHOST", "USERS", "VERSION", "WALLOPS", "WHO", "WHOIS", "WHOWAS" +}; + +#define DO_JOIN 12 +#define DO_MSG 20 +#define DO_PART 26 +#define DO_PRIVMSG 30 +#define DO_QUIT 31 +static int numargs[LISTSIZE] = { + 15, 1, 15, 3, 15, 15, 15, 1, 15, 15, 15, 15, 15, 3, 2, 15, 15, 15, + 15, 15, 2, 1, 1, 2, 2, 15, 15, 1, 1, 1, 2, 1, 15, 15, 15, 2, 15, + 15, 15, 2, 15, 4, 15, 15, 15, 1, 15, 15, 15 +}; + +static int (*docommand[LISTSIZE]) (void) = { +nop, nop, nop, nop, nop, nop, doerror, nop, nop, nop, doinvite, + nop, dojoin, dokick, dokill, nop, nop, nop, domode, nop, nop, nop, donick, nop, donotice, nop, dopart, nop, nop, dopong, doprivmsg, doquit, nop, nop, nop, dosquit, nop, nop, dotime, dotopic, nop, nop, nop, nop, nop, nop, nop, nop, nop}; + +static int wordwrapout(char *p, int count) +{ + while (p != NULL) { + if ((tmp = strchr(p, ' ')) != NULL) + *(tmp++) = '\0'; + if (strlen(p) < tty_width - count) { + if (count == 0) + count += printf("%s", p); + else + count += printf(" %s", p); + } else + count = printf("\n\r %s", p); + p = tmp; + } + return count; +} + +static int parsedata(void) +{ + int i, found = 0; + + if (serverdata[0] == 'P') { + sprintf(lineout, "PONG :%s\n", ircname); + return sendline(); + } + tok[i = 0] = serverdata; + tok[i]++; + while (tok[i] != NULL && i < 15) + if (*tok[i] == ':') + break; + else { + if ((tmp = strchr(tok[i], ' ')) != NULL) { + tok[++i] = &tmp[1]; + *tmp = '\0'; + } else + tok[++i] = NULL; + } + if (tok[i] != NULL && *tok[i] == ':') + tok[i]++; + tok[++i] = NULL; + if ((tmp = strchr(tok[0], '!')) != NULL) { + fromhost = &tmp[1]; + *tmp = '\0'; + } else + fromhost = NULL; + column = 0; + if ((i = atoi(tok[1])) != 0) + i = donumeric(i); + else { + for (i = 0; i < LISTSIZE && !found; i++) + found = (strcmp(clist[i], tok[1]) == 0); + if (found) + i = (*docommand[i - 1]) (); + else + i = nop(); + } + if (i) { + if (*tok[i] == ASCIIHEXCHAR && tok[i + 1] == NULL) { + hexascii(&tok[i][1]); + wordwrapout(encoded, column); + } else { + while (tok[i]) + column = wordwrapout(tok[i++], column); + } + } + putchar('\n'); + if (strncmp(tok[1], "Closing", 7) == 0) + return (reconnect = 0); + return 1; +} + +static int serverinput(void) +{ + int count, i; + int hidden = 0; + + while ((count = read(my_tcp, ib, IB_SIZE)) >= 1) { + for (i = 0; i < count; i++) { + if (ib[i] == '\n') { + serverdata[cursd] = '\0'; + cursd = 0; + if (!hidden) { + tty_hide(); + hidden = 1; + } + if (!parsedata()) + return 0; + } else if (ib[i] != '\r') { + if (cursd < 512) + serverdata[cursd++] = ib[i]; + } + } + } + if (count == 0) + count = -1; /* EOF */ + else if (errno == EWOULDBLOCK || errno == EAGAIN) + count = 0; + if (hidden) + tty_show(); + return count; +} + +static void parseinput(void) +{ + int i, j, outcol, c, found = 0; + if (*inbuf == '\0') + return; + /* Do we really need this copy FIXME */ + tok[i = 0] = inbuf; + while (tok[i] != NULL && i < 5) + if ((tmp = strchr(tok[i], ' ')) != NULL) { + tok[++i] = &tmp[1]; + *tmp = '\0'; + } else + tok[++i] = NULL; + tok[++i] = NULL; + if (*tok[0] == COMMANDCHAR) { + tok[0]++; + for (i = 0; i < strlen(tok[0]) && isalpha(tok[0][i]); i++) + tok[0][i] = toupper(tok[0][i]); + for (i = 0; i < LISTSIZE && !found; i++) + found = (strncmp(clist[i], tok[0], strlen(tok[0])) == 0); + i--; + if (!found) { + printf("*** Invalid command"); + return; + } + if (i == DO_JOIN) { + if ((newobj = finditem(tok[1], olist)) != NULL) { + obj = newobj; + printf("*** Now talking in %s", obj->name); + return; + } else if (!ischan(tok[1])) { + obj = olist = additem(tok[1], olist); + printf("*** Now talking to %s", obj->name); + return; + } + } + if (i == DO_PART && !ischan(tok[1])) + if ((newobj = finditem(tok[1], olist)) != NULL) { + olist = delitem(tok[1], olist); + if (obj == NULL) + obj = olist; + printf("*** No longer talking to %s", tok[1]); + if (obj != NULL) + printf(", now %s", obj->name); + return; + } + if (i == DO_MSG) + i = DO_PRIVMSG; + if (i == DO_PRIVMSG && (tok[1] == NULL || tok[2] == NULL)) { + printf("*** Unable to parse message"); + return; + } + strcpy(lineout, clist[i]); + if (i == DO_QUIT) + reconnect = 0; + if (i == DO_QUIT && tok[1] == NULL) + strcat(lineout, " :" RELEASE); + j = 0; +#if 0 + if (i != DO_PRIVMSG || tok[1] == NULL) + outcol = printf("= %s", lineout); + else if (ischan(tok[1])) + outcol = printf(">%s>", tok[1]); + else { + outcol = printf("-> *%s*", tok[1]); + } +#else + outcol = 0; +#endif + while (tok[++j]) { + c = strlen(lineout); + sprintf(&lineout[c], "%s%s", ((j == numargs[i] && tok[j + 1] != NULL) ? " :" : " "), tok[j]); +#if 0 + if (j > 1 || i != DO_PRIVMSG) + outcol = wordwrapout(tok[j], outcol); +#endif + } + strcat(lineout, "\n"); + } else { + if (obj == NULL) { + printf("*** Nowhere to send"); + return; + } + if (*tok[0] == ASCIIHEXCHAR) { + asciihex(&inbuf[1]); + strcpy(&inbuf[1], encoded); + } else if (*tok[0] == HEXASCIICHAR) { + /* display decoded line */ + hexascii(&inbuf[1]); + outcol = wordwrapout(encoded, outcol); + return; + } + sprintf(lineout, "PRIVMSG %s :%s\n", obj->name, inbuf); + outcol = printf("> %s", tok[j = 0]); + while (tok[++j]) + outcol = wordwrapout(tok[j], outcol); + } + sendline(); + idletimer = time(NULL); +} + +static int userinput(void) +{ + int err = tty_event(); + if (err < 0) + return err; + if (err == 2) { + parseinput(); + } + return err; +} + +static void cleanup(int sig) +{ + tty_restore(); + fflush(stdout); +#ifndef __hpux +// psignal(sig, "tinyirc"); +#endif + if (sig != SIGTSTP) + exit(128 + sig); + raise(SIGSTOP); +} + +static void stopin(int sig) +{ + signal(SIGTTIN, stopin); + noinput = 1; +} + +static void redraw(int sig) +{ + signal(SIGCONT, redraw); + signal(SIGTSTP, cleanup); + noinput = 0; +} + +static int makeconnect(char *hostname) +{ + struct sockaddr_in sa; + struct hostent *hp; + int s, t; + if ((hp = gethostbyname(hostname)) == NULL) + return -1; + for (t = 0, s = -1; s < 0 && hp->h_addr_list[t] != NULL; t++) { + memset(&sa, 0, sizeof(sa)); + bcopy(hp->h_addr_list[t], (char *) &sa.sin_addr, hp->h_length); + sa.sin_family = hp->h_addrtype; + sa.sin_port = htons((unsigned short) irc_port); + s = socket(hp->h_addrtype, SOCK_STREAM, 0); + if (s > 0) { + if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) { + close(s); + s = -1; + } else { + fcntl(s, F_SETFL, O_NDELAY); + my_tcp = s; + sprintf(lineout, "USER %s * * :%s\n", irclogin, gecos); + sendline(); + sprintf(lineout, "NICK :%s\n", ircname); + sendline(); + for (obj = olist; obj != NULL; obj = olist->next) { + sprintf(lineout, "JOIN %s\n", obj->name); + sendline(); + } /* error checking will be done later */ + } + } + } + return s; +} + +static void parsehost(char *p) +{ + char *tmp = strchr(p, ':'); + if (tmp) { + *tmp++ = 0; + irc_port = (unsigned short) atoi(tmp); + } +} + +int main(int argc, char *argv[]) +{ + char *hostname; + int i = 0; + printf(lineout); + + if (argc < 2) { + fprintf(stderr, "%s: server:port [name]\n", argv[0]); + exit(1); + } + hostname = argv[1]; + parsehost(hostname); + + userinfo = getpwuid(getuid()); + if (userinfo == NULL) { + fprintf(stderr, "User not found\n"); + exit(1); + } + if (argv[2]) + strlcpy(ircname, argv[i], sizeof(ircname)); + else + strlcpy(ircname, userinfo->pw_name, sizeof(ircname)); + irclogin = userinfo->pw_name; + gecos = userinfo->pw_gecos; + + printf("*** trying port %d of %s\n\n", irc_port, hostname); + if (makeconnect(hostname) < 0) { + fprintf(stderr, "*** %s refused connection, aborting\n", hostname); + exit(0); + } + tty_begin(); + + idletimer = time(NULL); + + redraw(0); + signal(SIGINT, cleanup); + signal(SIGHUP, cleanup); + signal(SIGTERM, cleanup); + signal(SIGSEGV, cleanup); + signal(SIGTTIN, stopin); + + tty_set_buffer(inbuf, 0, sizeof(inbuf)); + + while (sok >= 0) { + if (userinput() == -1) + break; + sok = serverinput(); + if (sok < 0 && reconnect) { + close(my_tcp); /* dead socket */ + printf("*** trying port %d of %s\n\n", irc_port, hostname); + if (makeconnect(hostname) < 0) { + fprintf(stderr, "*** %s refused connection\n", hostname); + break; + } + } + fflush(stdout); + } + tty_restore(); + exit(0); +} + +/* EOF */ -- 2.34.1