]> jfr.im git - irc/thales.git/commitdiff
Replace sql interface with TSV output on stdout.
authorDmitry Bogatov <redacted>
Wed, 27 Mar 2013 15:57:03 +0000 (19:57 +0400)
committerDmitry Bogatov <redacted>
Wed, 27 Mar 2013 17:16:15 +0000 (21:16 +0400)
24 files changed:
Makefile.am
bootstrap.conf
configure.ac
src/Makefile.am
src/cmd.c
src/cmd.h
src/defaults.c [deleted file]
src/defaults.h [deleted file]
src/error.h
src/format.def [new file with mode: 0644]
src/format.tpl [new file with mode: 0644]
src/init_query.def [deleted file]
src/init_query.tpl [deleted file]
src/irc.c
src/irc.h
src/ircclient_set.h [new file with mode: 0644]
src/main.c
src/query.def [deleted file]
src/query.tpl [deleted file]
src/sentry.c [deleted file]
src/sentry.h [deleted file]
src/utility.h [deleted file]
src/writer.c [new file with mode: 0644]
src/writer.h [new file with mode: 0644]

index 4e5c6e09f19e301309dee22784de53dedc00eb13..f14900e85ce3d42fcdba43c3137ce2b1debe49d0 100644 (file)
@@ -1,5 +1,5 @@
 SUBDIRS = lib src doc
 prepare:
        $(MAKE) -C src $@
-all: prepare
+%: prepare
 .PHONY: prepare
index 0deda3d10382293e718439b42488b32ad943a20e..84c29e046285dfa52ad3f09c224978997d4cb586 100644 (file)
@@ -18,7 +18,7 @@
 
 # gnulib modules used by this package.
 gnulib_name=libgnu
-gnulib_modules="list xlist xstrndup"
+gnulib_modules="xoset rbtree-oset"
 
 # Additional xgettext options to use.  Use "\\\newline" to break lines.
 XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
index 0a14ae651974d05676b3f98747803587e5feece4..d4edb40bb65084205f24b5dfb56fe03801c7f2a9 100644 (file)
@@ -6,7 +6,7 @@ AM_INIT_AUTOMAKE
 # Checks for programs.
 AC_PROG_CC_C99
 AC_CHECK_PROGS([AUTOGEN], [autogen],
-                          [AC_MSG_ERROR([GNU Autogen required, but not found])])
+                          [AC_MSG_WARN([GNU Autogen required for developer build])])
 gl_EARLY
 gl_INIT
 AC_GNU_SOURCE
@@ -15,9 +15,9 @@ AC_CHECK_HEADER([libircclient/libircclient.h],[],
         [AC_MSG_ERROR([libircclient header not found])])
 AC_CHECK_LIB([ircclient],[irc_create_session],[],
         [AC_MSG_ERROR([libircclient library not found])])
-AC_CHECK_HEADER([dbi/dbi.h],[],
+AC_CHECK_HEADER([mysql/mysql.h],[],
         [AC_MSG_ERROR([Libdbi headers not found])])
-AC_CHECK_LIB([dbi],[dbi_conn_new],[],
+AC_CHECK_LIB([mysqlclient],[mysql_real_connect],[],
         [AC_MSG_ERROR([Libdbi library not found])])
 
 # Checks for typedefs, structures, and compiler characteristics.
index b270d5263357a0340f0f38d0b1b0341d0b5c41ca..d6df2bef603cf33549aaa24b3a4e5569bbcff570 100644 (file)
@@ -1,18 +1,17 @@
-AM_CFLAGS = -I$(top_srcdir)/lib
-.DEFAULT_GOAL = maintainer_all
+AM_CPPFLAGS = -I$(top_srcdir)/lib
+AM_CFLAGS= -Wno-unused-parameter
 bin_PROGRAMS = thales
 thales_SOURCES = main.c cmd.h cmd.c  \
-       error.h  irc.h irc.c defaults.c defaults.h \
-       sentry.h  sentry.c init_query.h init_query.c \
-       function_query.h function_query.c query.h query.c
+       error.h  irc.h irc.c writer.c writer.h
 
 thales_LDADD = $(top_builddir)/lib/libgnu.a
 
 %.c %.h: %.def %.tpl
        cd $(srcdir) && $(AUTOGEN) $<
 
-prepare: init_query.c query.c
-check-syntax:
+prepare:
+check-syntax: prepare
        $(COMPILE) -o /dev/null -S ${CHK_SOURCES}
-
-.PHONY: prepare
+GTAGS: prepare
+       gtags -I .
+.PHONY: prepare GTAGS check-syntax
index 16acd6dbf4b54372ecee2c1bda8a0c8a1fb69789..a45b3024348f903357c54d0734f01f1c532abd18 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -20,8 +20,11 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <envz.h>
-#include "utility.h"
+#include "error.h"
+
+static const char *default_server = "irc.freenode.net";
+static const unsigned short default_port = 6667;
+static const char *default_nickname ="__GNU_Thales__";
 
 static void
 printf_option (const char *option, const char *description)
@@ -36,7 +39,7 @@ print_help (void)
   printf_option ("--help, -h", "Display this information");
   printf_option ("--version, -v", "Display thales version");
   printf_option ("--debug, -d", "Enable output of debug information");
-  printf_option ("--config, -C", "Override default configuration file");
+  printf_option ("--config, -C", "Override default work_options file");
   printf_option ("--server, -s", "Irc server to connect");
   printf_option ("--port, -p", "Port to connect");
   printf_option ("--nick, -n", "Nickname to login with");
@@ -53,19 +56,25 @@ print_version (void)
        "or FITNESS FOR A PARTICULAR PURPOSE.");
 }
 
+static void
+cmd_set_defaults (struct work_options *opts)
+{
+  opts->nickname = opts->nickname ? opts->nickname : default_nickname;
+  opts->server = opts->server ? opts->server : default_server;
+  opts->port = opts->port ? opts->port : default_port;
+}
+
 void
-parse_cmd_options (struct irc_options *opts, struct config_options *config_opts,
-               int argc, char **argv)
+parse_cmd_options (struct work_options *opts,  int argc, char **argv)
 {
-  const char *optstr = "hdvs:p:C:n:";
+  const char *optstr = "hvs:p:C:n:";
   const struct option longopts[] = {
     {"help", no_argument, NULL, 'h'},
     {"server", required_argument, NULL, 's'},
     {"port", required_argument, NULL, 'p'},
-    {"debug", no_argument, NULL, 'd'},
     {"version", no_argument, NULL, 'v'},
     {"nick", required_argument, NULL, 'n'},
-    {"config", required_argument, NULL, 'C'},
+    {NULL, 0, NULL, 0}
   };
   int val;
   while ((val = getopt_long (argc, argv, optstr, longopts, NULL)) != EOF)
@@ -74,71 +83,31 @@ parse_cmd_options (struct irc_options *opts, struct config_options *config_opts,
       case 'h':
        print_help ();
        exit (EXIT_SUCCESS);
+        break;
       case 'v':
        print_version ();
        exit (EXIT_SUCCESS);
-      case 'C':
-       config_opts->conf_filename = optarg;
        break;
       case 's':
        opts->server = optarg;
        break;
       case 'p':
-       opts->port = (unsigned short int) atoi (optarg); // Port in two byte integral.
+       opts->port = (unsigned short int) atoi (optarg);        // Port in two byte integral.
        break;
       case 'n':
-       opts->nick = optarg;
+       opts->nickname = optarg;
        break;
-      case 'd':
-        config_opts->debug = true;
       case '?':
+      default:
+       print_help ();
        exit (EXIT_FAILURE);
       }
+  cmd_set_defaults (opts);
   opts->channels = argv + optind;
-}
-
-
-FILE*
-default_config_file(void)
-{
-  /* Have to replace hardcoded pathes to
-     Automake generated */
-  const char *filenames[] ={
-    getenv("THALES_CONFIG"),
-    "~/.thales",
-    "/etc/thales"
-  };
-  FILE *config_file;
-
-  for (int index = 0; index != countof(filenames); ++index)
-    if (filenames[index] && (config_file = fopen(filenames[index], "r")))
-      return config_file;
-  return NULL;
-}
-
-static inline void
-fill_envz(char **envz, size_t *envz_len, FILE *stream)
-{
-  char *line = NULL;
-  size_t line_len;
-
-  while (getline(&line, &line_len, stream) > 0)
-    argz_add(envz, envz_len, line);
-  free(line);
-}
-
-void
-parse_mysql_options(struct mysql_options *opts, FILE *stream)
-{
-  char *envz = NULL;
-  size_t envz_len = 0;
-
-  fill_envz(&envz, &envz_len, stream);
-
-  opts->database = xstrdup_safe(envz_get(envz, envz_len, "database"));
-  opts->host = xstrdup_safe(envz_get(envz, envz_len, "host"));
-  opts->password = xstrdup_safe(envz_get(envz, envz_len, "password"));
-  opts->port = xstrdup_safe(envz_get(envz, envz_len, "port"));
-  opts->username = xstrdup_safe(envz_get(envz, envz_len, "username"));
 
+  if (!*opts->channels)
+    {                          /* No channels specified */
+      print_help ();
+      exit (EXIT_FAILURE);
+    }
 }
index 275c0604661f41ae5e93c0f3fe9253c511eb6e62..f7aabe0949e42cdc9a7f8a3233ecd36220edcade 100644 (file)
--- a/src/cmd.h
+++ b/src/cmd.h
@@ -19,28 +19,15 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <stdbool.h>
 #include <stdio.h>
 
-struct irc_options {
+struct work_options
+{
   const char *server;
-  const char *nick;
+  const char *nickname;
   unsigned short port;
   char **channels;
 };
-struct mysql_options {
-  const char *host;
-  const char *username;
-  const char *password;
-  const char *database;
-  unsigned short int port;
-};
-
-struct config_options {
-  bool debug;
-  const char *conf_filename;
-};
 
-FILE* default_config_file(void);
-void parse_cmd_options(struct irc_options *irc_opts, struct config_options *config_opts,
-                       int argc, char **argv);
-void parse_mysql_options(struct mysql_options *opts, FILE *stream);
+FILE *default_config_file (void);
+void parse_cmd_options (struct work_options *opts, int argc, char **argv);
 
 #endif
diff --git a/src/defaults.c b/src/defaults.c
deleted file mode 100644 (file)
index cc7c39f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "defaults.h"
-
-const char *default_server = "irc.freenode.net";
-const unsigned short default_port = 6667;
-const char *default_nick="thales";
diff --git a/src/defaults.h b/src/defaults.h
deleted file mode 100644 (file)
index 9510675..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef DEFAULTS_H
-#define DEFAULTS_H
-
-extern const char *default_server;
-extern const unsigned short default_port;
-extern const char *default_nick;
-
-#endif
index 08689696bac3a8b2497e955a243e65b70381da73..571dda367ed9edf664562673f9754bf342cf797e 100644 (file)
@@ -13,4 +13,8 @@
   exit(EXIT_FAILURE); \
   } while (0)
 
+#define debug(...) do {                         \
+  fprintf(stderr, __VA_ARGS__);                 \
+} while (0)
+
 #endif
diff --git a/src/format.def b/src/format.def
new file mode 100644 (file)
index 0000000..542665d
--- /dev/null
@@ -0,0 +1,7 @@
+/* -*- conf-unix-*- */
+autogen definitions query.tpl;
+
+query = {
+      action = "nick_quit";
+      format = "foobar %s";
+};
diff --git a/src/format.tpl b/src/format.tpl
new file mode 100644 (file)
index 0000000..be13816
--- /dev/null
@@ -0,0 +1,13 @@
+[+ autogen5 template h +]
+/*
+[+ (gpl "GNU Thales" " * " ) +]
+*/
+/*
+[+ (dne " * ") +]
+*/
+[+ (make-header-guard "") +]
+
+[+ FOR query "" +]
+#define WRITER_[+ (string-upcase (get "action")) +] "{[+ (get "action") +]}(%s)[+ (get "format") +]"
+[+ ENDFOR query +]
+#endif /* [+ (. header-guard) +] */
diff --git a/src/init_query.def b/src/init_query.def
deleted file mode 100644 (file)
index bf15d85..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-# -*- conf-unix-*-
-autogen definitions init_query;
-query = {
-  value = "CREATE TABLE IF NOT EXISTS channel ("
-    "chanid int unsigned NOT NULL auto_increment,"
-    "channel varchar(33) binary NOT NULL default '',"
-    "topic text,"
-    "topicauthor varchar(31) default NULL,"
-    "topictime datetime default NULL,"
-    "PRIMARY KEY  (chanid),"
-    "UNIQUE KEY channel (channel))";
-
-  error_msg = "Failed to create channel table.";
-};
-
-query = {
-  value = "CREATE TABLE IF NOT EXISTS user ("
-    "nickid int unsigned NOT NULL auto_increment,"
-    "nick varchar(31) NOT NULL default '',"
-    "realname varchar(51) NOT NULL default '',"
-    "hostname varchar(64) NOT NULL default '',"
-    "hiddenhostname varchar(64) NOT NULL default '',"
-    "username varchar(11) NOT NULL default '',"
-    "swhois varchar(32) NOT NULL default '',"
-    "connecttime datetime NOT NULL default '0000-00-00 00:00:00',"
-    "servid int unsigned NOT NULL default '0',"
-    "away enum('Y','N') NOT NULL default 'N',"
-    "awaymsg text,"
-    "online enum('Y','N') NOT NULL DEFAULT 'Y',"
-    "lastquit datetime default NULL,"
-    "PRIMARY KEY  (nickid),"
-    "UNIQUE KEY nick (nick),"
-    "KEY servid (servid))";
-
-  error_msg = "Failed to create user table.";
-};
-
-query = {
-  value = "CREATE TABLE IF NOT EXISTS server ("
-    "servid int unsigned NOT NULL auto_increment,"
-    "server varchar(64) NOT NULL default '',"
-    "connecttime datetime default NULL,"
-    "PRIMARY KEY  (servid),"
-    "UNIQUE KEY server (server))";
-
-  error_msg = "Failed to create server table.";
-};
-
-query = {
-  value = "CREATE TABLE IF NOT EXISTS presence ("
-    "nickid int unsigned NOT NULL default '0',"
-    "chanid int unsigned NOT NULL default '0',"
-    "servid int unsigned NOT NULL default '0',"
-    "PRIMARY KEY  (nickid,chanid,servid),"
-    "KEY nickid (nickid),"
-    "KEY chanid (chanid))";
-
-  error_msg = "Failed to create presence table.";
-};
diff --git a/src/init_query.tpl b/src/init_query.tpl
deleted file mode 100644 (file)
index bae598a..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-[+autogen5 template h c +][+DEFINE
-GPL +]/*
-[+ (gpl "GNU Thales" " * " ) +]
- */
-[+ENDDEF +][+DEFINE
-DO_NOT_EDIT +]/*
-[+(dne " * ") +]
-*/
-[+ENDDEF +][+
-CASE (suffix) +][+
-==  h  +][+ DO_NOT_EDIT +]
-[+GPL+]
-[+ (make-header-guard "") +]
-
-#define INIT_QUERIES_COUNT [+ (count "query") +]
-extern char const *init_queries[ INIT_QUERIES_COUNT ];
-extern char const *init_queries_error_messages[ INIT_QUERIES_COUNT];
-#endif /* [+ (. header-guard) +] */ [+
-==  c  +][+ DO_NOT_EDIT +]
-[+ GPL +]
-
-#include "[+ (. header-file)  +]"
-
-char const *init_queries[] = { [+
-FOR query "," +]
-  "[+ value +]"[+
-ENDFOR query +]
-};
-
-char const *init_queries_error_messages[] = { [+
-FOR query "," +]
-  "[+ error_msg +]"[+
-ENDFOR query +]
-};
-
-[+ESAC +]
index 6f392acc1ccf3076687853094c54158677c93383..715aeafaaf585507ac6bfa30c66e4bde8537c778 100644 (file)
--- a/src/irc.c
+++ b/src/irc.c
 #include "irc.h"
+#include <stdlib.h>
 #include <libircclient/libircclient.h>
 #include <libircclient/libirc_rfcnumeric.h>
 #include <stdlib.h>
 #include <string.h>
-#include "defaults.h"
+#include <assert.h>
+#include <signal.h>
+#include <cmd.h>
 #include "error.h"
-#include "utility.h"
-#include "sentry.h"
+#include "writer.h"
+
+static volatile sig_atomic_t exit_flag;
+
+
+static inline void
+check_disconnect (irc_session_t * session)
+{
+  if (exit_flag)
+    irc_disconnect (session);
+}
+
+static inline const char *
+purge_nick (const char *nick)
+{
+  enum
+  { nickname_max_length = 256, max_simultaneous_calls = 8 };
+  static char buffer[max_simultaneous_calls][nickname_max_length];
+  static int call_index = 0;
+  call_index = (call_index + 1) % max_simultaneous_calls;
+  irc_target_get_nick (nick, buffer[call_index], nickname_max_length);
+  return buffer[call_index];
+}
 
-#define EVENT_CALLBACK(function_name) void                              \
+#define EVENT_CALLBACK(function_name)  void                             \
   function_name (irc_session_t * session, const char *event,            \
                  const char *origin, const char **params, unsigned int count)
 
-struct context {
-  SENTRY *sentry;
-  const struct irc_options *opts;
-};
+EVENT_CALLBACK (event_part)
+{
+  const struct work_options *context = irc_get_ctx (session);
+  const char *nickname = purge_nick (origin);
+  const char *channel = *params;
+  const char *reason = params[1];
+
+  writer_channel_presence_remove (context, channel, nickname);
+  check_disconnect (session);
+}
+
+EVENT_CALLBACK (event_topic)
+{
+  const struct work_options *context = irc_get_ctx (session);
+  const char *nickname = purge_nick (origin);
+  const char *channel = *params;
+  const char *new_topic = params[1];
+
+  writer_channel_topic_update (context, channel, nickname, new_topic);
+}
+
+EVENT_CALLBACK (event_kick)
+{
+  const struct work_options *context = irc_get_ctx (session);
+  const char *kicker = purge_nick (origin);
+  const char *channel = *params;
+  const char *victim = purge_nick (params[1]);
+  const char *reason = params[2];
+
+  writer_channel_presence_remove (context, channel, victim);
+}
+
+EVENT_CALLBACK (event_nick)
+{
+  const struct work_options *context = irc_get_ctx (session);
+  const char *oldnick = purge_nick (origin);
+  const char *newnick = purge_nick (*params);
+
+
+  writer_nick_change (context, oldnick, newnick);
+}
 
-EVENT_CALLBACK(event_nick)
+static
+EVENT_CALLBACK (event_quit)
 {
+  const struct work_options *context = irc_get_ctx (session);
+  const char *nickname = purge_nick (origin);
 
+  writer_nick_quit (context, nickname);
 }
 
 
 static
 EVENT_CALLBACK (event_join)
 {
-  const char *nickname =  origin;
+  const struct work_options *context = irc_get_ctx (session);
+  const char *nickname = purge_nick (origin);
   const char *channel = *params;
-  const struct context *ctx = irc_get_ctx(session);
+  const char *own_nickname = context->nickname;
 
-  printf ("%s joined %s\n", nickname, channel);
-  fflush(stdout);
-  sentry_channel_presence_clear(ctx, channel);
-  irc_cmd_names(session, channel);
+  if (!strcmp (own_nickname, nickname))
+    writer_channel_presence_clear (context, channel);
+  else
+    writer_channel_presence_add (context, channel, nickname);
 }
 
 static
 EVENT_CALLBACK (event_channel)
 {
+  const struct work_options *context = irc_get_ctx (session);
+  const char *nickname = purge_nick (origin);
+  const char *channel = *params;
+  const char *text = params[1];
 
+  debug ("%s", text);
 }
 
 static inline void
-event_numeric_namreply(struct context *context, const char *channel,
-                       const char *nicknames)
+event_numeric_namreply (irc_session_t * session, const char *channel,
+                       const char *nicknames)
 {
-  char *nicknames_buf = strdup(nicknames);
+  struct work_options *context = irc_get_ctx (session);
+  char *nicknames_buf = strdup (nicknames);
 
-  for (const char *nickname = strtok(nicknames_buf, " ");
-       nickname;
-       nickname = strtok(NULL, " "))
+  for (const char *nickname = strtok (nicknames_buf, " ");
+       nickname; nickname = strtok (NULL, " "))
     {
-      sentry_channel_presence_add(context->sentry, channel, nickname);
+      writer_channel_presence_add (context, channel, purge_nick (nickname));
+      irc_cmd_whois (session, nickname);
     }
 
-  free(nicknames_buf);
+  free (nicknames_buf);
+}
+
+static inline void
+event_numeric_whoisuser (const char *nickname,
+                        const char *hostname, const char *server)
+{
+
 }
 
+#define NUMERIC_OUTPUT_ARGS() \
+  fprintf(stderr, "*** Origin: %s ***\n", origin);                   \
+  fprintf(stderr, "*** Parameters: ***\n");         \
+  for (int ne_index = 0; ne_index != count;  ne_index++) \
+    fprintf(stderr, "%s\n", params[ne_index]);            \
+  fprintf(stderr, "*********\n");
+
 static void
 event_numeric (irc_session_t * session, unsigned int
               event, const char *origin, const char **params,
               unsigned int count)
 {
-  struct context *context = irc_get_ctx(session);
-
-  switch (event) {
-  case LIBIRC_RFC_RPL_NAMREPLY:
-    assert(count >= 4);
-    const char *channel = params[2];
-    const char *nicknames = params[3];
-    event_numeric_namreply(context, channel, nicknames);
-    break;
-  }
+  switch (event)
+    {
+    case LIBIRC_RFC_RPL_NAMREPLY:
+      assert (count >= 4);
+      const char *channel = params[2];
+      const char *nicknames = params[3];
+      event_numeric_namreply (session, channel, nicknames);
+      break;
+    case LIBIRC_RFC_RPL_WHOISUSER:
+      assert (count == 6);
+      const char *server = origin;
+      const char *nickname = params[1];
+      const char *hostname = params[3];
+      const char *realname = params[5];
+      event_numeric_whoisuser (nickname, hostname, server);
+      NUMERIC_OUTPUT_ARGS ();
+      break;
+    }
 }
 
 static
 EVENT_CALLBACK (event_connect)
 {
-  const struct context *ctx =  irc_get_ctx (session);
-  printf("Connected!");
-  for (char **chan = ctx->opts->channels; *chan; ++chan) {
-    printf("sending connect request for %s\n", *chan);
+  const struct work_options *context = irc_get_ctx (session);
+  debug ("Connected!");
+  for (char **chan = context->channels; *chan; ++chan)
     irc_cmd_join (session, *chan, NULL);
-  }
-  fflush(stdout);
 }
 
 /* Question to libircclient. Why not const? */
@@ -93,32 +184,36 @@ static irc_callbacks_t callbacks = {
   .event_join = event_join,
   .event_connect = event_connect,
   .event_numeric = event_numeric,
-  .event_nick =  event_nick
+  .event_nick = event_nick
 };
 
+#define check_irc_error(session, err) if (err) {fatal ("error = %d, %s", err, irc_strerror (irc_errno (session))); }
 bool
-start_listen_irc (const struct irc_options *opts,
-                 SENTRY *sentry)
+client_start_listen (const struct work_options *opts)
 {
   irc_session_t *session = irc_create_session (&callbacks);
-  struct context context = {
-    .sentry = sentry,
-    .opts = opts
-  };
 
   if (!session)
     fatal ("Failed to create session");
-  irc_set_ctx (session, &context);
-  int error = irc_connect (session,
-                           opts->server ? opts->server : default_server,
-                           opts->port ? opts->port : default_port, NULL,       /* Password*/
-                          opts->nick ? opts->nick : default_nick, NULL,
-                          NULL);
-  if (error)
-    fatal ("error = %d, %s", error, irc_strerror (irc_errno (session)));
-  error = irc_run (session);
-  if (error)
-    fatal ("error = %d, %s", error, irc_strerror (irc_errno (session)));
+
+  irc_set_ctx (session, opts);
+
+  int err = irc_connect (session,
+                        opts->server, opts->port, NULL,        /* Password */
+                        opts->nickname, NULL, NULL);
+  check_irc_error (session, err);
+
+  err = irc_run (session);
+  check_irc_error (session, err);
+
   irc_destroy_session (session);
   return true;
 }
+
+#undef check_irc_error
+
+void
+client_stop_listen (void)
+{
+  exit_flag = 1;
+}
index 292f53219ef17c05e0c652206806e1ace034e209..f653937127263b862814d3fe0e7c7bc345b423df 100644 (file)
--- a/src/irc.h
+++ b/src/irc.h
@@ -1,15 +1,18 @@
 #ifndef IRC_H
 #define IRC_H
 #include <stdbool.h>
-#include "cmd.h"
-#include "sentry.h"
-struct irc_user {
+struct work_options;
+struct ircclient
+{
   char *nickname;
   char *realname;
+  char *server;
+  char ipv4[8];                        /* 8 hex digits */
+  bool ready;
 };
 
-bool start_listen_irc(const struct irc_options *opts, SENTRY *sentry);
-
+bool client_start_listen (const struct work_options *opts);
+void client_stop_listen (void);
 
 
 #endif
diff --git a/src/ircclient_set.h b/src/ircclient_set.h
new file mode 100644 (file)
index 0000000..73f929e
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef CLIENTSET_H
+#define CLIENTSET_H
+#include "irc.h"
+
+
+typedef struct ircclient_set ircclient_set;
+ircclient_set *ircclient_set_new();
+struct irc_client* ircclient_set_find(ircclient_set *set, const char *nickname);
+void ircclient_set_remove(ircclient_set *set, const char *nickname);
+void ircclient_set_dispose(ircclient_set *set);
+
+#endif
index cc130f59364acd41f04fffffbff0def93c8d783c..afb3d2f45c90a740c7ec27b925125a54f11f72cd 100644 (file)
@@ -1,18 +1,20 @@
-/*  Main program of GNU Thales.  Copyright (C)
-2012 Free Software Foundation, Inc.  This file is part of GNU Thales.
-
-GNU Thales is free software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the Free Software
-Foundation; either version 3 of the License, or (at your option) any later
-version.
-
-GNU Thales is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program.  If not, see <http://www.gnu.org/licenses/>.  */
+/*
+ * Main program of GNU Thales.  Copyright (C)
+ * 2012 Free Software Foundation, Inc.  This file is part of GNU Thales.
+ *
+ * GNU Thales is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * GNU Thales is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
 #include <config.h>
 #include <stdio.h>
@@ -21,30 +23,14 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "cmd.h"
 #include "error.h"
 #include "irc.h"
-#include "sentry.h"
 
 int
 main (int argc, char **argv)
 {
-  struct irc_options irc_opts = { 0 };
-  struct mysql_options mysql_opts = { 0 };
-  struct config_options config_opts = { 0 };
-
-
-  parse_cmd_options (&irc_opts, &config_opts, argc, argv);
-  FILE *config_file = config_opts.conf_filename ? fopen (config_opts.conf_filename, "r")
-    : default_config_file ();
-
-  if (!config_file)
-    fatal ("failed to open config file");
-
-  parse_mysql_options(&mysql_opts, config_file);
-
-SENTRY *sentry = sentry_initialize(&mysql_opts, irc_opts.server);
-#warning "mysql is not used"
-/* if (!sentry) */
-/*   fatal("failed to connect to database"); */
+  struct work_options work_opts = { 0 };
+  parse_cmd_options (&work_opts, argc, argv);
 
-  start_listen_irc(&irc_opts, sentry);
+  setbuf(stdout, NULL); /* Just in case. */
+  client_start_listen (&work_opts);
   return 0;
 }
diff --git a/src/query.def b/src/query.def
deleted file mode 100644 (file)
index 8826bef..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# -*- conf-unix-*-
-autogen definitions query;
-query = {
-  def = "CHANNEL_PRESENCE_CLEAR";
-  value = "clear?!";
-  error_msg = "Failed to clear?!";
-  comment = "Optional";
-};
-query = {
-  def = "CHANNEL_PRESENCE_ADD";
-  value = "add?!";
-  error_msg = "Failed to add?!";
-};
\ No newline at end of file
diff --git a/src/query.tpl b/src/query.tpl
deleted file mode 100644 (file)
index fc8727e..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-[+autogen5 template h c +][+DEFINE
-GPL +]/*
-[+ (gpl "GNU Thales" " * " ) +]
- */
-[+ENDDEF +][+DEFINE
-DO_NOT_EDIT +]/*
-[+(dne " * ") +]
-*/
-[+ENDDEF +][+
-CASE (suffix) +][+
-==  h  +][+ DO_NOT_EDIT +]
-[+GPL+]
-[+ (make-header-guard "") +]
-
-[+FOR query "" +]
-/* [+ comment +] */
-#define QUERY_[+def+] [+ (for-index) +]
-[+ENDFOR query +]
-
-#define QUERIES_COUNT [+ (count "query") +]
-extern char const *queries[ QUERIES_COUNT ];
-extern char const *queries_error_messages[ QUERIES_COUNT];
-#endif /* [+ (. header-guard) +] */ [+
-==  c  +][+ DO_NOT_EDIT +]
-[+ GPL +]
-
-#include "[+ (. header-file)  +]"
-
-char const *queries[] = { [+
-FOR query "," +]
-  "[+ value +]"[+
-ENDFOR query +]
-};
-
-char const *queries_error_messages[] = { [+
-FOR query "," +]
-  "[+ error_msg +]"[+
-ENDFOR query +]
-};
-
-[+ESAC +]
diff --git a/src/sentry.c b/src/sentry.c
deleted file mode 100644 (file)
index 79c738f..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#include "sentry.h"
-#include <xalloc.h>
-#include <stdbool.h>
-#include <dbi/dbi.h>
-#include "cmd.h"
-#include "init_query.h"
-
-struct sentry
-{
-  char *unused;
-};
-
-static inline bool
-initialize_tables(MYSQL *db_handle)
-{
-  for (const char *query = *init_queries; *query; ++query)
-    if (!mysql_query(db_handle, query))
-      return false;
-  return true;
-}
-
-SENTRY *
-sentry_initialize (const struct mysql_options *opts, const char *server)
-{
-  MYSQL db_handle;
-  mysql_init (&db_handle);
-  if (!mysql_real_connect (&db_handle, opts->host, opts->username,
-                          opts->password, opts->database, opts->port,
-                          NULL, 0))
-    {
-      fprintf(stderr, "Failed to connect to database: Error: %s\n",
-              mysql_error(&db_handle));
-      goto connect;
-  }
-  if (!initialize_tables(&db_handle)) {
-    fprintf(stderr, "Failed to connect to database: Error: %s\n",
-            mysql_error(&db_handle));
-    goto tables;
-  }
-
-  struct sentry *new = xmalloc (sizeof *new);
-
-  new->db_handle = db_handle;
-  new->server = xstrdup(server);
-  return new;
-
- tables:
-  mysql_close(&db_handle);
- connect:
-  return NULL;
-}
-
-void
-sentry_channel_presence_clear(SENTRY *sentry, const char *channel)
-{
-  static const char *query =
-}
-
-void
-sentry_channel_presence_add(SENTRY *sentry, const char *channel,
-                            const char *nickname)
-{
-  const char *query = "INSERT INTO presence VALUES (nickid, chanid, servid) where"
-
-}
diff --git a/src/sentry.h b/src/sentry.h
deleted file mode 100644 (file)
index 6a79ac8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef SENTRY_H
-#define SENTRY_H
-#include <stdbool.h>
-struct db_options;
-struct sentry;
-typedef struct sentry SENTRY;
-
-SENTRY *sentry_initialize(const struct db_options *opts, const char *server);
-void sentry_channel_presence_clear(SENTRY *sentry, const char *channel);
-void sentry_channel_presence_add(SENTRY *sentry,  const char *channel,
-                                 const char *nickname);
-#endif
diff --git a/src/utility.h b/src/utility.h
deleted file mode 100644 (file)
index 9b5ae7e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef UTILITY_H
-#define UTILITY_H
-#include <xalloc.h>
-#include <xstrndup.h>
-
-#define countof(x) sizeof(x)/sizeof(0[x])
-static inline void *
-xrangedup (const void *begin, const void *end)
-{
-  return xstrndup (begin, (char *) end - (char *) begin);
-}
-static inline char*
-xstrdup_safe(const char *ptr)
-{
-  return ptr ? xstrdup(ptr) : NULL;
-}
-
-#endif
diff --git a/src/writer.c b/src/writer.c
new file mode 100644 (file)
index 0000000..b2d1322
--- /dev/null
@@ -0,0 +1,42 @@
+#include <xalloc.h>
+#include <stdbool.h>
+#include "cmd.h"
+
+#define writer_printf(context, fmt, ...) printf("%s/%s:%d\t" fmt, \
+                                                __func__+7, /* Remove `writer_` prefix */ \
+                                                context->server, context->port, __VA_ARGS__)
+void
+writer_channel_presence_clear(struct work_options *context, const char *channel)
+{
+  writer_printf(context, "%s\n", channel);
+}
+
+void
+writer_channel_presence_add(struct work_options *context, const char *channel,
+                            const char *nickname)
+{
+  writer_printf(context, "%s\t%s\n", channel, nickname);
+}
+
+void
+writer_channel_presence_remove(struct work_options *context, const char *channel,
+                                    const char *nickname)
+{
+  writer_printf(context, "%s\t%s\n", channel, nickname);
+}
+void
+writer_channel_topic_update(struct work_options *context, const char *channel,
+                                 const char *nickname, const char *new_topic)
+{
+  writer_printf(context, "%s\t%s\t%s\n", channel, nickname, new_topic);
+}
+void
+writer_nick_change(struct work_options *context, const char *oldnick, const char *newnick)
+{
+  writer_printf(context, "%s\t%s\n", oldnick, newnick);
+}
+void
+writer_nick_quit(struct work_options *context, const char *nickname)
+{
+  writer_printf(context, "%s\n", nickname);
+}
diff --git a/src/writer.h b/src/writer.h
new file mode 100644 (file)
index 0000000..7d3080e
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef WRITER_H
+#define WRITER_H
+#include <stdbool.h>
+struct work_options;
+
+void writer_channel_presence_clear(const struct work_options *context, const char *channel);
+void writer_channel_presence_add(const struct work_options *context,  const char *channel,
+                                 const char *nickname);
+void writer_channel_presence_remove(const struct work_options *context, const char *channel,
+                                    const char *nickname);
+void writer_channel_topic_update(const struct work_options *context, const char *channel,
+                                 const char *nickname, const char *new_topic);
+void writer_nick_change(const struct work_options *context, const char *oldnick, const char *newnick);
+void writer_nick_quit(const struct work_options *context, const char *nickname);
+
+#endif