static unsigned int telnet_open_listen(unsigned int i) { char *vhost = NULL; char *msg; unsigned int rc; ir_sockaddr_union_t listenaddr; updatecontext(); vhost = irlist_get_nth(&gdata.telnet_vhost, i); if (vhost == NULL) return 1; rc = open_listen(0, &listenaddr, &(telnet_listen[i]), gdata.telnet_port, 1, 0, vhost); if (rc != 0) return 1; telnet_family[i] = listenaddr.sa.sa_family; msg = mymalloc(maxtextlength); my_getnameinfo(msg, maxtextlength -1, &listenaddr.sa); ioutput(OUT_S|OUT_L|OUT_D, COLOR_MAGENTA, "Telnet SERVER waiting for connection on %s", msg); mydelete(msg); return 0; }
/* find a free port and open a new socket for an incoming connection */ unsigned int irc_open_listen(ir_connection_t *con) { unsigned int rc; rc = open_listen(con->family, &(con->local), &(con->listensocket), gdata.tcprangestart, 0, 1, get_local_vhost()); if (rc != 0) return rc; con->connecttime = gdata.curtime; con->lastcontact = gdata.curtime; con->localport = get_port(&(con->local)); return 0; }
/* Create a new listening port (or destroy one) * * listen <port> bots/all/users [mask] * listen <port> script <proc> [flag] * listen <port> off */ static int tcl_listen(ClientData cd, Tcl_Interp *irp, int argc, char *argv[]) { int i, j, idx = -1, port, realport; char s[11], msg[256]; struct portmap *pmap = NULL, *pold = NULL; BADARGS(3, 5, " port type ?mask?/?proc ?flag??"); port = realport = atoi(argv[1]); for (pmap = root; pmap; pold = pmap, pmap = pmap->next) if (pmap->realport == port) { port = pmap->mappedto; break; } for (i = 0; i < dcc_total; i++) if ((dcc[i].type == &DCC_TELNET) && (dcc[i].port == port)) idx = i; if (!egg_strcasecmp(argv[2], "off")) { if (pmap) { if (pold) pold->next = pmap->next; else root = pmap->next; nfree(pmap); } /* Remove */ if (idx < 0) { Tcl_AppendResult(irp, "no such listen port is open", NULL); return TCL_ERROR; } killsock(dcc[idx].sock); lostdcc(idx); return TCL_OK; } if (idx < 0) { /* Make new one */ if (dcc_total >= max_dcc) { Tcl_AppendResult(irp, "No more DCC slots available.", NULL); return TCL_ERROR; } /* Try to grab port */ j = port + 20; i = -1; while (port < j && i < 0) { i = open_listen(&port); if (i == -1) port++; else if (i == -2) break; } if (i == -1) { egg_snprintf(msg, sizeof msg, "Couldn't listen on port '%d' on the " "given address. Please make sure 'my-ip' is set correctly, " "or try a different port.", realport); Tcl_AppendResult(irp, msg, NULL); return TCL_ERROR; } else if (i == -2) { Tcl_AppendResult(irp, "Couldn't assign the requested IP. Please make " "sure 'my-ip' is set properly.", NULL); return TCL_ERROR; } idx = new_dcc(&DCC_TELNET, 0); dcc[idx].addr = iptolong(getmyip()); dcc[idx].port = port; dcc[idx].sock = i; dcc[idx].timeval = now; } /* script? */ if (!strcmp(argv[2], "script")) { strcpy(dcc[idx].nick, "(script)"); if (argc < 4) { Tcl_AppendResult(irp, "a proc name must be specified for a script listen", NULL); killsock(dcc[idx].sock); lostdcc(idx); return TCL_ERROR; } if (argc == 5) { if (strcmp(argv[4], "pub")) { Tcl_AppendResult(irp, "unknown flag: ", argv[4], ". allowed flags: pub", NULL); killsock(dcc[idx].sock); lostdcc(idx); return TCL_ERROR; } dcc[idx].status = LSTN_PUBLIC; } strncpyz(dcc[idx].host, argv[3], UHOSTMAX); egg_snprintf(s, sizeof s, "%d", port); Tcl_AppendResult(irp, s, NULL); return TCL_OK; } /* bots/users/all */ if (!strcmp(argv[2], "bots")) strcpy(dcc[idx].nick, "(bots)"); else if (!strcmp(argv[2], "users")) strcpy(dcc[idx].nick, "(users)"); else if (!strcmp(argv[2], "all")) strcpy(dcc[idx].nick, "(telnet)"); if (!dcc[idx].nick[0]) { Tcl_AppendResult(irp, "invalid listen type: must be one of ", "bots, users, all, off, script", NULL); killsock(dcc[idx].sock); dcc_total--; return TCL_ERROR; } if (argc == 4) strncpyz(dcc[idx].host, argv[3], UHOSTMAX); else strcpy(dcc[idx].host, "*"); egg_snprintf(s, sizeof s, "%d", port); Tcl_AppendResult(irp, s, NULL); if (!pmap) { pmap = nmalloc(sizeof(struct portmap)); pmap->next = root; root = pmap; } pmap->realport = realport; pmap->mappedto = port; putlog(LOG_MISC, "*", "Listening at telnet port %d (%s).", port, argv[2]); return TCL_OK; }