+/*
+ * set up the various mode flags, NL endings and things
+ */
+void setmode(char *m)
+{
+ connsort = strlower(m);
+ if (eq(connsort, "telnet") || eq(connsort, "local") || eq(connsort, "nlonly")) {
+ nl = '\n';
+ echo = 1;
+ mode = eq(connsort, "nlonly") ? 2 : 1;
+ } else if (eq(connsort, "ax25")) {
+ nl = '\r';
+ echo = 0;
+ mode = 0;
+ } else if (eq(connsort, "connect")) {
+ nl = '\n';
+ echo = 0;
+ mode = 3;
+ } else {
+ die("Connection type must be \"telnet\", \"nlonly\", \"ax25\", \"login\" or \"local\"");
+ }
+}
+
+
+/*
+ * things to do with ongoing processing of inputs
+ */
+
+void process_stdin()
+{
+ cmsg_t *mp = cmsg_next(in->inq);
+ char *p, hasa, hasn, i;
+ char callsign[MAXCALLSIGN+1];
+
+ if (mp) {
+ dbg(DMSG, "MSG size: %d", mp->size);
+
+ switch (state) {
+ case CONNECTED:
+ if (mp->size > 0) {
+ send_msg(node, 'I', mp->data, mp->size);
+ }
+ break;
+ case WAITLOGIN:
+ for (i = 0; i < mp->size; ++i) {
+ UC ch = mp->data[i];
+ if (i < MAXCALLSIGN) {
+ if (isalpha(ch))
+ ++hasa;
+ if (isdigit(ch))
+ ++hasn;
+ if (isalnum(ch) || ch == '-')
+ callsign[i] = ch;
+ else
+ die("invalid callsign");
+ } else
+ die("invalid callsign");
+ }
+ callsign[i]= 0;
+ if (strlen(callsign) < 3)
+ die("invalid callsign");
+ if (hasa && hasn)
+ ;
+ else
+ die("invalid callsign");
+ call = strupper(callsign);
+
+ /* check the callsign against the regexes */
+ if (!iscallsign(call)) {
+ die("Sorry, %s isn't a valid callsign", call);
+ }
+
+ alarm(0);
+ signal(SIGALRM, SIG_IGN);
+
+ /* tell the cluster who I am */
+ send_msg(node, 'A', connsort, strlen(connsort));
+
+ chgstate(CONNECTED);
+ }
+
+ cmsg_callback(mp, 0);
+
+ }
+}
+
+void process_node()
+{
+ cmsg_t *mp = cmsg_next(node->inq);
+ if (mp) {
+ dbg(DMSG, "MSG size: %d", mp->size);
+
+ if (mp->size > 0 && mp->inp > mp->data) {
+ char *p = strchr(mp->data, '|');
+ if (p)
+ p++;
+ switch (mp->data[0]) {
+ case 'Z':
+ ending++;
+ return;
+ case 'E':
+ if (isdigit(*p))
+ in->echo = *p - '0';
+ break;
+ case 'B':
+ if (isdigit(*p))
+ in->buffer_it = *p - '0';
+ break;
+ case 'D':
+ if (p) {
+ int l = mp->inp - (UC *) p;
+ send_text(in, p, l, 1);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ cmsg_callback(mp, 0);
+ } else {
+ flush_text(in);
+ }
+}
+
+/*
+ * things to do with going away
+ */
+
+void term_timeout(int i)
+{
+ /* none of this is going to be reused so don't bother cleaning up properly */
+ if (in && in->t_set)
+ tcsetattr(0, TCSANOW, &in->t);
+ if (node) {
+ shutdown(node->cnum, 3);
+ close(node->cnum);
+ }
+ exit(i);
+}
+
+void terminate(int i)
+{
+ signal(SIGALRM, term_timeout);
+ alarm(10);
+
+ while ((in && !is_chain_empty(in->outq)) ||
+ (node && !is_chain_empty(node->outq))) {
+ sel_run();
+ }
+ if (in && in->t_set)
+ tcsetattr(0, TCSADRAIN, &in->t);
+ if (node) {
+ shutdown(node->cnum, 3);
+ close(node->cnum);
+ }
+ exit(i);
+}
+
+void login_timeout(int i)
+{
+ write(0, "Timed Out", 10);
+ write(0, &nl, 1);
+ sel_run(); /* force a coordination */
+ if (in && in->t_set)
+ tcsetattr(0, TCSANOW, &in->t);
+ exit(i);
+}
+