summaryrefslogtreecommitdiff
path: root/degesch.c
diff options
context:
space:
mode:
Diffstat (limited to 'degesch.c')
-rw-r--r--degesch.c67
1 files changed, 59 insertions, 8 deletions
diff --git a/degesch.c b/degesch.c
index 0dee7ac..05b22ba 100644
--- a/degesch.c
+++ b/degesch.c
@@ -48,6 +48,7 @@
#include <langinfo.h>
#include <locale.h>
#include <pwd.h>
+#include <sys/utsname.h>
#include <curses.h>
#include <term.h>
@@ -125,6 +126,12 @@ toupper_ascii (int c)
return false; \
BLOCK_END
+// A few other debugging shorthands
+#define LOG_FUNC_FAILURE(name, desc) \
+ print_debug ("%s: %s: %s", __func__, (name), (desc))
+#define LOG_LIBC_FAILURE(name) \
+ print_debug ("%s: %s: %s", __func__, (name), strerror (errno))
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// We need a few reference countable objects with support
@@ -1841,14 +1848,14 @@ irc_send (struct app_context *ctx, const char *format, ...)
// TODO: call SSL_get_error() to detect if a clean shutdown has occured
if (SSL_write (ctx->ssl, str.str, str.len) != (int) str.len)
{
- print_debug ("%s: %s: %s", __func__, "SSL_write",
+ LOG_FUNC_FAILURE ("SSL_write",
ERR_error_string (ERR_get_error (), NULL));
result = false;
}
}
else if (write (ctx->irc_fd, str.str, str.len) != (ssize_t) str.len)
{
- print_debug ("%s: %s: %s", __func__, "write", strerror (errno));
+ LOG_LIBC_FAILURE ("write");
result = false;
}
@@ -2017,7 +2024,7 @@ irc_establish_connection (struct app_context *ctx,
err = getnameinfo (gai_iter->ai_addr, gai_iter->ai_addrlen,
buf, sizeof buf, NULL, 0, NI_NUMERICHOST);
if (err)
- print_debug ("%s: %s", "getnameinfo", gai_strerror (err));
+ LOG_FUNC_FAILURE ("getnameinfo", gai_strerror (err));
else
real_host = buf;
@@ -2636,21 +2643,65 @@ irc_handle_ping (struct app_context *ctx, const struct irc_message *msg)
irc_send (ctx, "PONG");
}
+static char *
+ctime_now (char buf[26])
+{
+ struct tm tm_;
+ time_t now = time (NULL);
+ if (!asctime_r (localtime_r (&now, &tm_), buf))
+ return NULL;
+
+ // Annoying thing
+ *strchr (buf, '\n') = '\0';
+ return buf;
+}
+
static void
irc_handle_ctcp_request (struct app_context *ctx,
const struct irc_message *msg, struct ctcp_chunk *chunk)
{
char *nickname = irc_cut_nickname (msg->prefix);
char *nickname_utf8 = irc_to_utf8 (ctx, nickname);
- free (nickname);
char *tag_utf8 = irc_to_utf8 (ctx, chunk->tag.str);
buffer_send_status (ctx, ctx->server_buffer,
"CTCP requested by %s: %s", nickname_utf8, tag_utf8);
- // TODO: reply to other CTCPs;
- // see http://www.irchelp.org/irchelp/rfc/ctcpspec.html
+ const char *target = msg->params.vector[0];
+ const char *recipient = nickname;
+ if (irc_is_channel (ctx, target))
+ recipient = target;
+
+ // TODO: log a "CTCP reply to <recipient>: <whatever>
+ // Probably abstract the irc_send call to something like
+ // irc_send_ctcp_reply (ctx, recipient, fmt, ...)
+
+ if (!strcmp (chunk->tag.str, "CLIENTINFO"))
+ irc_send (ctx, "NOTICE %s :\x01" "CLIENTINFO %s %s %s %s\x01",
+ recipient, "PING", "VERSION", "TIME", "CLIENTINFO");
+ else if (!strcmp (chunk->tag.str, "PING"))
+ irc_send (ctx, "NOTICE %s :\x01" "PING %s\x01",
+ recipient, chunk->text.str);
+ else if (!strcmp (chunk->tag.str, "VERSION"))
+ {
+ struct utsname info;
+ if (uname (&info))
+ LOG_LIBC_FAILURE ("uname");
+ else
+ irc_send (ctx, "NOTICE %s :\x01" "VERSION %s %s on %s %s\x01",
+ recipient, PROGRAM_NAME, PROGRAM_VERSION,
+ info.sysname, info.machine);
+ }
+ else if (!strcmp (chunk->tag.str, "TIME"))
+ {
+ char buf[26];
+ if (!ctime_now (buf))
+ LOG_LIBC_FAILURE ("asctime_r");
+ else
+ irc_send (ctx, "NOTICE %s :\x01" "TIME %s\x01", recipient, buf);
+ }
+ free (nickname);
free (nickname_utf8);
free (tag_utf8);
}
@@ -3718,7 +3769,7 @@ start:
case XSSL_ERROR_TRY_AGAIN:
goto start;
default:
- print_debug ("%s: %s: %s", __func__, "SSL_read", error_info);
+ LOG_FUNC_FAILURE ("SSL_read", error_info);
return IRC_READ_ERROR;
}
}
@@ -3744,7 +3795,7 @@ start:
if (errno == EINTR)
goto start;
- print_debug ("%s: %s: %s", __func__, "recv", strerror (errno));
+ LOG_LIBC_FAILURE ("recv");
return IRC_READ_ERROR;
}