int VLU_File(FILE *f, struct vlu *l);
int VLU_Data(const void *ptr, int len, struct vlu *l);
void VLU_Destroy(struct vlu *l);
+void VLU_SetTelnet(struct vlu *l, int fd);
#endif
unsigned bufl;
unsigned bufp;
void *priv;
+ int telnet;
vlu_f *func;
};
FREE_OBJ(l);
l = NULL;
}
+ l->telnet = -1;
}
return (l);
}
+void
+VLU_SetTelnet(struct vlu *l, int fd)
+{
+ CHECK_OBJ_NOTNULL(l, LINEUP_MAGIC);
+ assert(fd >= 0);
+ l->telnet = fd;
+}
+
void
VLU_Destroy(struct vlu *l)
{
FREE_OBJ(l);
}
+static int
+vlu_dotelnet(struct vlu *l, char *p)
+{
+ char *e;
+ char tno[3];
+ int i;
+
+ e = l->buf + l->bufp;
+ assert(p >= l->buf && p < e);
+ assert(*p == (char)255);
+
+ /* We need at least two characters */
+ if (p == e - 1)
+ return (1);
+
+ /* And three for will/wont/do/dont */
+ if (p[1] >= (char)251 && p[1] <= (char)254 && p == e - 2)
+ return (1);
+
+ switch (p[1]) {
+ case (char)251: /* WILL */
+ case (char)252: /* WONT */
+ /* Ignore these */
+ i = 3;
+ break;
+ case (char)253: /* DO */
+ case (char)254: /* DONT */
+ /* Return WONT for these */
+ memcpy(tno, p, 3);
+ tno[1] = (char)252;
+ write(l->telnet, tno, 3);
+ i = 3;
+ break;
+ default:
+ /* Ignore the rest */
+ /* XXX: only p[1] >= 240 ? */
+ i = 2;
+ }
+
+ /* Remove telnet sequence from buffer */
+ memmove(p, p + i, 1 + e - (p + i));
+ l->bufp -= i;
+ return (0);
+}
+
static int
LineUpProcess(struct vlu *l)
{
l->buf[l->bufp] = '\0';
for (p = l->buf; *p != '\0'; p = q) {
/* Find first CR or NL */
- for (q = p; *q != '\0'; q++)
+ for (q = p; *q != '\0'; q++) {
+ while (l->telnet >= 0 && *q == (char)255)
+ if (vlu_dotelnet(l, q))
+ return (0);
if (*q == '\n' || *q == '\r')
break;
+ }
if (*q == '\0')
break;
*q++ = '\0';