Author: bdonlan
Date: 2004-12-30 22:00:30 -0500 (Thu, 30 Dec 2004)
New Revision: 485

Added:
   trunk/clients/havercurs/
   trunk/clients/havercurs/Makefile.am
   trunk/clients/havercurs/TODO
   trunk/clients/havercurs/autogen.sh
   trunk/clients/havercurs/configure.ac
   trunk/clients/havercurs/display.c
   trunk/clients/havercurs/display.h
   trunk/clients/havercurs/entry.c
   trunk/clients/havercurs/entry.h
   trunk/clients/havercurs/event.c
   trunk/clients/havercurs/event.h
   trunk/clients/havercurs/lineio.c
   trunk/clients/havercurs/lineio.h
   trunk/clients/havercurs/main.c
   trunk/clients/havercurs/mymalloc.c
   trunk/clients/havercurs/mymalloc.h
   trunk/clients/havercurs/net.c
   trunk/clients/havercurs/net.h
Removed:
   trunk/clients/ncurses/
Modified:
   trunk/
Log:
 [EMAIL PROTECTED]:  bdonlan | 2004-12-31T02:59:11.945246Z
 Renamed to havercurs
 



Property changes on: trunk
___________________________________________________________________
Name: svk:merge
   - 1f59643a-e6e5-0310-bc24-f7d4c744f460:/haver/local/trunk:10236
27e50396-46e3-0310-8b22-ae223a1f35ce:/local:212
edfcd8bd-4ce7-0310-a97e-bb1efd40edf3:/local:238
   + 1f59643a-e6e5-0310-bc24-f7d4c744f460:/haver/local/trunk:10237
27e50396-46e3-0310-8b22-ae223a1f35ce:/local:212
edfcd8bd-4ce7-0310-a97e-bb1efd40edf3:/local:238


Property changes on: trunk/clients/havercurs
___________________________________________________________________
Name: svn:ignore
   + configure
Makefile.in
config.log
depcomp
config.guess
config.h
config.sub
ltmain.sh
.libs
.deps
Makefile
mkinstalldirs
config.status
stamp-h1
config.h.in
havercurs
autom4te.cache
libtool
missing
aclocal.m4
install-sh


Added: trunk/clients/havercurs/Makefile.am
===================================================================
--- trunk/clients/havercurs/Makefile.am 2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/Makefile.am 2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,11 @@
+## Process this file with automake to produce Makefile.in
+## vim: set ts=4 sw=4 si ai sta tw=104:
+
+bin_PROGRAMS = havercurs
+havercurs_SOURCES = main.c main.h \
+                                       display.c display.h \
+                                       event.c event.h \
+                                       entry.c entry.h \
+                                       mymalloc.c mymalloc.h \
+                                       net.c net.h \
+                                       lineio.c lineio.h


Property changes on: trunk/clients/havercurs/Makefile.am
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/TODO
===================================================================
--- trunk/clients/havercurs/TODO        2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/TODO        2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,22 @@
+Done:
+* input line
+* basic display
+* event loop (fd polling, timers)
+
+Debugging:
+* Synchronous connection
+
+Partial implementation:
+* Line-oriented buffered I/O
+
+TODO:
+* Hash table
+* /-command parser
+* Haver protocol parser
+* Authentication
+* Chat
+* Asynchronous connection and DNS
+* Input history
+* Scrollback
+* Preferences save
+* Colors

Added: trunk/clients/havercurs/autogen.sh
===================================================================
--- trunk/clients/havercurs/autogen.sh  2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/autogen.sh  2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,9 @@
+#!/bin/bash
+# vim: set ts=4 sw=4 expandtab si ai sta tw=104:
+export WANT_AUTOMAKE=1.7
+export WANT_AUTOCONF=1.5
+set -x
+aclocal &&
+autoheader &&
+automake --foreign --add-missing &&
+autoconf


Property changes on: trunk/clients/havercurs/autogen.sh
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/configure.ac
===================================================================
--- trunk/clients/havercurs/configure.ac        2004-12-31 03:00:15 UTC (rev 
484)
+++ trunk/clients/havercurs/configure.ac        2004-12-31 03:00:30 UTC (rev 
485)
@@ -0,0 +1,27 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl vim: set ts=4 sw=4 expandtab si ai sta tw=104:
+
+AC_INIT(havercurs, 0.0.1)
+AM_INIT_AUTOMAKE
+AM_CONFIG_HEADER(config.h)
+
+dnl Checks for programs.
+AC_PROG_CC
+
+dnl Checks for libraries.
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(sys/time.h assert.h ncurses.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+
+dnl Checks for library functions.
+AC_TYPE_SIGNAL
+AC_CHECK_FUNCS(gettimeofday select)
+AC_CHECK_LIB(ncurses, initscr)
+
+AC_OUTPUT(Makefile)


Property changes on: trunk/clients/havercurs/configure.ac
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/display.c
===================================================================
--- trunk/clients/havercurs/display.c   2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/display.c   2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,24 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104: */
+#include "display.h"
+#include <ncurses.h>
+
+static WINDOW *dwin = NULL;
+
+void display_init(int lines) {
+       dwin = newwin(lines, COLS, 0, 0);
+       idlok(dwin, TRUE);
+       scrollok(dwin, TRUE);
+}
+
+void display_free(void) {
+       delwin(dwin);
+       dwin = NULL;
+}
+
+void display_print(const char *fmt, ...) {
+       va_list ap;
+       va_start(ap, fmt);
+       vw_printw(dwin, fmt, ap);
+       va_end(ap);
+       wnoutrefresh(dwin);
+}


Property changes on: trunk/clients/havercurs/display.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/display.h
===================================================================
--- trunk/clients/havercurs/display.h   2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/display.h   2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,10 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104: */
+#ifndef DISPLAY_H
+#define DISPLAY_H 1
+
+void display_init(int lines);
+void display_free(void);
+
+void display_print(const char *fmt, ...);
+
+#endif


Property changes on: trunk/clients/havercurs/display.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/entry.c
===================================================================
--- trunk/clients/havercurs/entry.c     2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/entry.c     2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,109 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104: */
+#include "mymalloc.h"
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ncurses.h>
+
+static char *buffer = NULL;
+int pos, len, blen, win;
+
+void entry_init(void) {
+       pos = len = win = 0;
+       blen = 32;
+       buffer = mymalloc(blen);
+}
+
+void entry_free(void) {
+       free(buffer);
+       buffer = NULL;
+}
+
+int entry_get_pos(void) {
+       return pos;
+}
+
+int entry_get_len(void) {
+       return len;
+}
+
+static void checkpos(void) {
+       if (pos < 0)
+               pos = 0;
+       if (pos > len)
+               pos = len;
+}
+
+char entry_remove_ch(int offset) {
+       char c;
+       if (offset >= len || offset < 0)
+               return 0;
+       c = buffer[offset];
+       memmove(&buffer[offset], &buffer[offset + 1], len - offset - 1);
+       len--;
+       checkpos();
+       return c;
+}
+
+static void expand_buf(void) {
+       blen = (blen * 3) / 2;
+       buffer = myrealloc(buffer, blen);
+}
+
+void entry_insert_ch(int offset, char c) {
+       if (offset < 0 || offset > len) {
+               assert(0);
+               abort();
+       }
+       if (len + 1 > blen)
+               expand_buf();
+       memmove(&buffer[offset + 1], &buffer[offset], len - offset);
+       buffer[offset] = c;
+       len++;
+}
+
+int entry_move_abs(int offset) {
+       pos = offset;
+       checkpos();
+       return pos;
+}
+
+int entry_move_rel(int offset) {
+       pos += offset;
+       checkpos();
+       return pos;
+}
+
+const char *entry_get(void) {
+       if (len + 1 > blen)
+               expand_buf();
+       buffer[len] = '\0'; /* null-terminate it for the caller */
+       return buffer;
+}
+
+void entry_clear(void) {
+       len = pos = win = 0;
+}
+
+void entry_refresh(WINDOW *w, int yoff, int cols) {
+       int i, lim;
+       wmove(w, yoff, 0);
+       wclrtoeol(w);
+
+       /* Is the window sane? */
+       if (pos < win ||
+               pos > win + cols
+          )
+       {
+               win = pos - (cols / 2);
+               if (win < 0)
+                       win = 0;
+       }
+
+       lim = win + cols;
+       for (i = win; i < lim && i < len; i++) {
+               addch(buffer[i]);
+       }
+       wmove(w, yoff, pos - win);
+       wnoutrefresh(w);
+}


Property changes on: trunk/clients/havercurs/entry.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/entry.h
===================================================================
--- trunk/clients/havercurs/entry.h     2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/entry.h     2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,22 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104: */
+#ifndef ENTRY_H
+#define ENTRY_H 1
+
+void entry_init(void);
+void entry_free(void);
+
+int entry_get_pos(void);
+int entry_get_len(void);
+
+char entry_remove_ch(int offset);
+void entry_insert_ch(int offset, char c);
+
+int entry_move_abs(int offset);
+int entry_move_rel(int offset);
+
+const char *entry_get(void);
+void entry_clear(void);
+
+void entry_refresh(WINDOW *w, int yoff, int cols);
+
+#endif


Property changes on: trunk/clients/havercurs/entry.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/event.c
===================================================================
--- trunk/clients/havercurs/event.c     2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/event.c     2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,266 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104: */
+#include "mymalloc.h"
+#include "event.h"
+#include <sys/time.h>
+#include <sys/select.h>
+
+typedef struct event_timer_struct {
+       struct event_timer_struct *next;
+       struct timeval when;
+       event_timer_callback *cb;
+       void *baton;
+} event_timer_t;
+
+typedef struct event_fd_struct {
+       struct event_fd_struct *next;
+       int fd;
+       int mode;
+       event_fd_callback *cb;
+       void *baton;
+} event_fd_t;  
+
+static event_timer_t *t_head = NULL;
+static event_fd_t *fd_head = NULL;
+
+static fd_set cache_r, cache_w, cache_e;
+static int fd_max = 0;
+
+void event_init(void) {
+       FD_ZERO(&cache_r);
+       FD_ZERO(&cache_w);
+       FD_ZERO(&cache_e);
+}
+
+void event_free(void) {
+       event_timer_t *t_cur = t_head;
+       event_fd_t *io_cur = fd_head;
+       while (t_cur) {
+               event_timer_t *next = t_cur;
+               free(t_cur);
+               t_cur = next;
+       }
+       t_head = NULL;
+       while (io_cur) {
+               event_fd_t *next = io_cur;
+               free(io_cur);
+               io_cur = next;
+       }
+       fd_head = NULL; 
+}
+
+void event_timer_abs(
+               const struct timeval *when,
+               event_timer_callback *cb,
+               void *baton
+               ) {
+       event_timer_t *new = mymalloc(sizeof *new);
+       event_timer_t *cur, *prev;
+       new->when = *when;
+       new->cb = cb;
+       new->baton = baton;
+       prev = NULL;
+       cur = t_head;
+       while (cur) {
+               if (cur->when.tv_sec < new->when.tv_sec ||
+                       cur->when.tv_usec < new->when.tv_usec
+                  )
+               {
+                       break;
+               }
+               cur = cur->next;
+       }
+       if (prev)
+               prev->next = new;
+       else
+               t_head = new;
+       new->next = cur;                
+}
+
+void event_timer_rel(
+               const struct timeval *when,
+               event_timer_callback *cb,
+               void *baton
+               )
+{
+       struct timeval absolute;
+       gettimeofday(&absolute, NULL);
+       absolute.tv_sec += when->tv_sec;
+       absolute.tv_usec += when->tv_usec;
+       if (absolute.tv_usec > 1000000) {
+               absolute.tv_sec += absolute.tv_usec / 1000000;
+               absolute.tv_usec %= 1000000;
+       }
+       event_timer_abs(&absolute, cb, baton);
+}
+
+static int check_timers(
+               const struct timeval *now,
+               const struct timeval **next
+               )
+{
+       int counter = 0;
+       const struct timeval *dummy;
+       if (!next)
+               next = &dummy;
+       while (t_head) {
+               if (t_head->when.tv_sec < now->tv_sec ||
+                               (t_head->when.tv_sec == now->tv_sec &&
+                                t_head->when.tv_usec < now->tv_usec
+                               ))
+               {
+                       event_timer_t *cur = t_head;
+                       counter++;
+                       t_head = cur->next;
+                       cur->cb(&cur->when, cur->baton);
+                       free(cur);
+               } else break;
+       }
+       if (t_head)
+               *next = &t_head->when;
+       else
+               *next = NULL;
+       return counter;
+}
+
+static void recache_fd(event_fd_t *what, int add) {
+       if (what->mode & EVENT_FD_READABLE)
+               FD_SET(what->fd, &cache_r);
+       else
+               FD_CLR(what->fd, &cache_r);
+       if (what->mode & EVENT_FD_WRITABLE)
+               FD_SET(what->fd, &cache_w);
+       else
+               FD_CLR(what->fd, &cache_w);
+       if (what->mode & EVENT_FD_ERROR)
+               FD_SET(what->fd, &cache_e);
+       else
+               FD_CLR(what->fd, &cache_e);
+
+       if (add) {
+               if (what->fd + 1 > fd_max)
+                       fd_max = what->fd + 1;
+       } else {
+               if (what->fd + 1 == fd_max) {
+                       event_fd_t *cur = fd_head;
+                       fd_max = 0;
+                       while (cur) {
+                               if (cur->fd + 1 > fd_max)
+                                       fd_max = cur->fd + 1;
+                               cur = cur->next;
+                       }
+               }
+       }
+}
+
+static event_fd_t *search(int fd, event_fd_t **prev) {
+       event_fd_t *dummy, *cur;
+       if (!prev)
+               prev = &dummy;
+       cur = fd_head;
+       while (cur) {
+               if (cur->fd == fd)
+                       return cur;
+               *prev = cur;
+               cur = cur->next;
+       }
+       return NULL;
+}
+
+void event_addfd(
+               int fd,
+               int mode,
+               event_fd_callback *cb,
+               void *baton
+               ) {
+       static event_fd_t *prev, *cur;
+       cur = search(fd, &prev);
+       if (!cur) {
+               cur = mymalloc(sizeof *cur);
+               cur->fd = fd;
+               if (prev) {
+                       cur->next = prev->next;
+                       prev->next = cur;
+               } else {
+                       cur->next = fd_head;
+                       fd_head = cur;
+               }
+       }
+       cur->cb = cb;
+       cur->mode = mode;
+       cur->baton = baton;
+       recache_fd(cur, 1);
+}
+
+void event_delfd(int fd) {
+       static event_fd_t *prev, *cur;
+       cur = search(fd, &prev);
+       if (!cur)
+               return;
+       if (prev)
+               prev->next = cur->next;
+       else
+               fd_head = cur->next;
+       recache_fd(cur, 0);
+}
+
+static int io_poll(struct timeval *timeout) {
+       fd_set r, w, e;
+       int count = 0;
+       int remain = 0;
+       event_fd_t *cur = fd_head;
+       r = cache_r;
+       w = cache_w;
+       e = cache_e;
+       remain = select(fd_max, &r, &w, &e, timeout);
+       while (remain > 0 && cur) {
+               int mode = 0;
+               int fd = cur->fd;
+               if (FD_ISSET(fd, &r)) {
+                       remain--;
+                       mode |= EVENT_FD_READABLE;
+               }
+               if (FD_ISSET(fd, &w)) {
+                       remain--;
+                       mode |= EVENT_FD_WRITABLE;
+               }
+               if (FD_ISSET(fd, &e)) {
+                       remain--;
+                       mode |= EVENT_FD_ERROR;
+               }
+               if (mode & ~cur->mode)
+                       recache_fd(cur, 1);
+               mode &= cur->mode;
+               if (mode) {
+                       count++;
+                       cur->cb(fd, mode, cur->baton);
+               }
+               cur = cur->next;
+       }
+       return count;
+}
+
+int event_poll(int block) {
+       int counter = 0;
+       struct timeval now;
+       const struct timeval *next;
+       struct timeval tv, *p_tv = NULL;
+       gettimeofday(&now, NULL);
+       counter += check_timers(&now, &next);
+       if (block && next) {
+               tv.tv_sec = next->tv_sec - now.tv_sec;
+               tv.tv_usec = next->tv_usec - now.tv_usec;
+               if (tv.tv_usec < 0) {
+                       tv.tv_sec--;
+                       tv.tv_usec += 1000000;
+               }
+               p_tv = &tv;
+       }
+       if (!block) {
+               tv.tv_sec = tv.tv_usec = 0;
+               p_tv = &tv;
+       }
+       counter += io_poll(p_tv);
+       gettimeofday(&now, NULL);
+       counter += check_timers(&now, NULL);
+       return counter;
+}


Property changes on: trunk/clients/havercurs/event.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/event.h
===================================================================
--- trunk/clients/havercurs/event.h     2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/event.h     2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,38 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104: */
+#ifndef EVENT_H
+#define EVENT_H 1
+
+#define EVENT_FD_READABLE      1
+#define EVENT_FD_WRITABLE      2
+#define EVENT_FD_ERROR         4
+
+typedef void event_fd_callback(int fd, int mode, void *baton);
+typedef void event_timer_callback(const struct timeval *when, void *baton);
+
+void event_init(void);
+void event_free(void);
+
+void event_timer_abs(
+               const struct timeval *when,
+               event_timer_callback *cb,
+               void *baton
+               );
+
+void event_timer_rel(
+               const struct timeval *when,
+               event_timer_callback *cb,
+               void *baton
+               );
+
+void event_addfd(
+               int fd,
+               int mode,
+               event_fd_callback *cb,
+               void *baton
+               );
+
+void event_delfd(int fd);
+
+int event_poll(int block);
+
+#endif


Property changes on: trunk/clients/havercurs/event.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/lineio.c
===================================================================
--- trunk/clients/havercurs/lineio.c    2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/lineio.c    2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,108 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104: */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <assert.h>
+#include "lineio.h"
+#include "mymalloc.h"
+#include "event.h"
+
+struct lineio_conn {
+       char *outbuf;
+       size_t outbuf_used, outbuf_len;
+       char *inbuf;
+       size_t inbuf_used, inbuf_len;
+
+       lineio_callback *cb;
+       void *baton;
+
+       int fd;
+};
+       
+
+static void lineio_evcallback(int fd, int mode, void *baton);
+
+lineio_conn *lineio_attach(
+               int fd, lineio_callback *cb, void *baton
+               )
+{
+       lineio_conn *conn = mymalloc(sizeof *conn);
+       conn->outbuf_used = conn->inbuf_used = 0;
+       conn->inbuf_len = conn->outbuf_len = 32;
+       conn->inbuf = mymalloc(conn->inbuf_len);
+       conn->outbuf = mymalloc(conn->outbuf_len);
+       
+       conn->cb = cb;
+       conn->baton = baton;
+       conn->fd = fd;
+
+       event_addfd(
+                       fd,
+                       EVENT_FD_READABLE | EVENT_FD_ERROR,
+                       lineio_evcallback,
+                       conn
+                       );
+}
+
+static void lineio_evcallback(int fd, int mode, void *baton) {
+       lineio_conn *conn = baton;
+       assert(conn->fd == fd);
+       if (mode & EVENT_FD_READABLE) {
+               /* FIXME: Line buffering. This is a test hack */
+               ssize_t dlen = read(fd, conn->inbuf, conn->inbuf_len - 1);
+               if (dlen <= 0) {
+                       /* badness */
+                       abort();
+               }
+               conn->inbuf[dlen] = 0;
+               conn->cb(conn, fd, conn->baton, LINEIO_GOTLINE, conn->inbuf);
+       }
+       if (mode & EVENT_FD_WRITABLE) {
+               if (conn->outbuf_used) {
+                       ssize_t dlen = write(fd, conn->outbuf, 
conn->outbuf_used);
+                       if (dlen <= 0) {
+                               /* badness */
+                               abort();
+                       }
+                       assert(dlen <= conn->outbuf_used);
+                       if (conn->outbuf_used > dlen) {
+                               memmove(conn->outbuf, conn->outbuf + dlen,
+                                               conn->outbuf_used - dlen);
+                       }
+                       conn->outbuf_used -= dlen;
+               } else {
+                       event_addfd(
+                                       fd, EVENT_FD_READABLE | EVENT_FD_ERROR,
+                                       lineio_evcallback, conn);
+               }
+       }
+       if (mode & EVENT_FD_ERROR) {
+               /* badness */
+               abort();
+       }
+}
+
+int lineio_printf(lineio_conn *conn, char *fmt, ...) {
+       int elen;
+       va_list ap;
+
+       va_start(ap, fmt);
+       elen = vsnprintf(NULL, 0, fmt, ap);
+       if (conn->outbuf_len < conn->outbuf_used + elen) {
+               conn->outbuf_len = elen + conn->outbuf_used;
+               conn->outbuf = myrealloc(conn->outbuf, conn->outbuf_len);
+       }
+       elen = vsnprintf(
+                       conn->outbuf + conn->outbuf_used,
+                       conn->outbuf_len - conn->outbuf_used,
+                       fmt, ap
+                       );
+       conn->outbuf_used += elen;
+
+       event_addfd(
+                       conn->fd,
+                       EVENT_FD_READABLE | EVENT_FD_WRITABLE | EVENT_FD_ERROR,
+                       lineio_evcallback,
+                       conn);
+       return elen;
+}


Property changes on: trunk/clients/havercurs/lineio.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/lineio.h
===================================================================
--- trunk/clients/havercurs/lineio.h    2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/lineio.h    2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,23 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104: */
+#ifndef LINEIO_H
+#define LINEIO_H 1
+
+enum lineio_events {
+       LINEIO_GOTLINE,
+       LINEIO_FLUSHED,
+       LINEIO_DISCON,
+       LINEIO_ERROR
+};
+
+struct lineio_conn;
+typedef struct lineio_conn lineio_conn;
+typedef void lineio_callback(
+               struct lineio_conn *conn, int fd, void *baton,
+               enum lineio_events ev, void *data
+               );
+
+lineio_conn *lineio_attach(int fd, lineio_callback *cb, void *baton);
+void lineio_detatch(lineio_conn *conn);
+int lineio_printf(lineio_conn *conn, char *fmt, ...);
+
+#endif


Property changes on: trunk/clients/havercurs/lineio.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/main.c
===================================================================
--- trunk/clients/havercurs/main.c      2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/main.c      2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,165 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104: */
+#include <ncurses.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "mymalloc.h"
+#include "entry.h"
+#include "display.h"
+/*#include "io.h"*/
+#include "event.h"
+#include "net.h"
+#include "lineio.h"
+
+void finish(int);
+void handle_input(int fd, int mode, void *baton);
+void heartbeat(const struct timeval *when, void *baton);
+void heartbeat_start(int delay);
+
+lineio_conn *conn = NULL;
+
+void connected_cb(
+        void *baton, int fd, int ecode, const char *error
+);
+
+void lio_cb(
+               struct lineio_conn *conn, int fd, void *baton,
+               enum lineio_events ev, void *data);
+
+int main(void) {
+       int i;
+       signal(SIGINT, finish);      /* arrange interrupts to terminate */
+    signal(SIGIO, SIG_IGN);      /* we select() for async I/O       */
+       initscr();
+       nonl();
+       cbreak();
+       noecho();
+       idlok(stdscr, TRUE);
+       keypad(stdscr, TRUE);
+
+       move(LINES - 2, 0);
+       for (i = 0; i < COLS; i++)
+               addch('-');
+       move(LINES - 1, 0);
+       
+       entry_init();
+       event_init();
+       display_init(LINES - 2);
+
+    heartbeat_start(30);
+
+       refresh();
+
+       event_addfd(0, EVENT_FD_READABLE | EVENT_FD_ERROR, handle_input, NULL);
+       
+       for (;;) {
+               int c = event_poll(1);
+               entry_refresh(stdscr, LINES - 1, COLS);
+               refresh();
+       }
+}
+
+void finish(int sig) {
+       endwin();
+       exit(0);
+}
+
+void connected_cb(
+        void *baton, int fd, int ecode, const char *error
+)
+{
+    if (fd == -1) {
+        display_print("connect error: %s\n", error);
+        return;
+    }
+    conn = lineio_attach(fd, lio_cb, NULL);
+}
+
+void lio_cb(
+               struct lineio_conn *conn, int fd, void *baton,
+               enum lineio_events ev, void *data)
+{
+    if (ev == LINEIO_GOTLINE) {
+        display_print("INPUT:\n|%s|\n", (char *)data);
+    }
+}
+
+void handle_input(int fd, int mode, void *baton) {
+       int c;
+       size_t pos, len;
+       
+       mode = mode & (EVENT_FD_READABLE | EVENT_FD_ERROR);
+       if (!mode)
+               return; /* We're willing to block on stdout. */
+       
+       if (mode & EVENT_FD_ERROR) {
+               endwin();
+               exit(0);
+       }
+       pos = entry_get_pos();
+       len = entry_get_len();
+       
+       switch (c = getch()) {
+               case KEY_UP:
+                       break;
+               case KEY_DOWN:
+                       break;
+               case KEY_BACKSPACE:
+                       if (pos > 0)
+                               entry_remove_ch(pos - 1);
+                       entry_move_abs(pos - 1);
+                       break;
+               case KEY_DC:
+                       if (len && pos < len)
+                               entry_remove_ch(pos);
+                       entry_move_abs(pos);
+                       break;
+               case KEY_ENTER:
+               case '\n':
+               case '\r':
+                       if (conn) {
+                display_print("OUT: %s\n", entry_get());
+                lineio_printf(conn, "%s\n", entry_get());
+            } else {
+                display_print("Not connected.\n");
+                break;
+            }
+                       /* fallthru */
+               case KEY_DL:
+                       entry_clear();
+                       break;
+               case KEY_LEFT:
+                       entry_move_rel(-1);
+                       break;
+               case KEY_RIGHT:
+                       entry_move_rel(1);
+                       break;
+               default:
+                       if (!isprint(c)) {
+                               display_print("%d\n", (int)c);  
+                               break;
+                       }
+                       entry_insert_ch(pos, c);
+                       entry_move_rel(1);
+       };
+}
+
+void heartbeat_start(int delay) {
+    struct timeval next = {delay, 0};
+    event_timer_rel(&next, heartbeat, NULL);
+}
+
+void heartbeat(const struct timeval *when, void *baton) {
+       const char *message = baton;
+       struct timeval next;
+    if (!message) {
+        net_async_connect(connected_cb, NULL, "localhost", 12564);
+        baton = message = "Heartbeat 1";
+    }
+       display_print("%s\n", message);
+       next.tv_sec = 1;
+       next.tv_usec = 0;
+       event_timer_rel(&next, heartbeat, baton);
+}


Property changes on: trunk/clients/havercurs/main.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/mymalloc.c
===================================================================
--- trunk/clients/havercurs/mymalloc.c  2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/mymalloc.c  2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,22 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104: */
+#include <stdlib.h>
+#include <ncurses.h>
+#include "mymalloc.h"
+
+void *mymalloc(size_t s) {
+       void *p = malloc(s);
+       if (!p) {
+               endwin();
+               abort();
+       }
+       return p;
+}
+
+void *myrealloc(void *oldp, size_t s) {
+       void *p = realloc(oldp, s);
+       if (!p) {
+               endwin();
+               abort();
+       }
+       return p;
+}


Property changes on: trunk/clients/havercurs/mymalloc.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/mymalloc.h
===================================================================
--- trunk/clients/havercurs/mymalloc.h  2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/mymalloc.h  2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,10 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104: */
+#ifndef MYMALLOC_H
+#define MYMALLOC_H 1
+
+#include <stdlib.h>
+
+void *mymalloc(size_t s);
+void *myrealloc(void *oldp, size_t s);
+
+#endif


Property changes on: trunk/clients/havercurs/mymalloc.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/net.c
===================================================================
--- trunk/clients/havercurs/net.c       2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/net.c       2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,46 @@
+#include "net.h"
+#include <sys/socket.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <netdb.h>
+extern int h_errno;
+
+/* FIXME: not actually async */
+void net_async_connect(
+               net_conn_callback *cb, void *baton,
+               const char *host, unsigned long port
+               )
+{
+       struct hostent *h;
+       int fd;
+       int pf;
+       int ret;
+       h = gethostbyname(host);
+       if (!h) {
+               cb(baton, -1, h_errno, hstrerror(h_errno));
+               return;
+       }
+       if (h->h_addrtype == AF_INET) {
+               pf = PF_INET;
+       } else {
+               pf = PF_INET6;
+       }
+       fd = socket(pf, SOCK_STREAM, 0);
+       if (fd < 0) {
+               cb(baton, -1, errno, strerror(errno));
+               return;
+       }
+       ret = connect(fd, (const struct sockaddr *)h->h_addr_list[0], 
h->h_length);
+       if (ret != 0) {
+               int err = errno;
+               close(fd);
+               cb(baton, -1, err, strerror(err));
+               return;
+       }
+       fcntl(fd, F_SETFL, O_NONBLOCK);
+       cb(baton, fd, 0, NULL);
+}


Property changes on: trunk/clients/havercurs/net.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/net.h
===================================================================
--- trunk/clients/havercurs/net.h       2004-12-31 03:00:15 UTC (rev 484)
+++ trunk/clients/havercurs/net.h       2004-12-31 03:00:30 UTC (rev 485)
@@ -0,0 +1,18 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104: */
+#ifndef NET_H
+#define NET_H 1
+
+/* This is mostly a placeholder right now. Sometime in the future
+ * this should become truly asynchronous.
+ */
+
+typedef void net_conn_callback(
+        void *baton, int fd, int ecode, const char *error
+        );
+
+void net_async_connect(
+        net_conn_callback *cb, void *baton,
+        const char *host, unsigned long port
+        );
+
+#endif


Property changes on: trunk/clients/havercurs/net.h
___________________________________________________________________
Name: svn:eol-style
   + native


Reply via email to