Index: icb.c
===================================================================
--- icb.c	(revision 9c04f2a610774a04913d70b62f72b0c1e32de735)
+++ icb.c	(revision 82d3c1fc7b55d61d602c1cdc8cb2baf5e5bb0eca)
@@ -551,4 +551,5 @@
 	extern int modtabcnt;
 
+	icbd_modupdate();
 	if ((enforce ? 0 : modtabcnt == 0) ||
 	    bsearch(is->nick, modtab, modtabcnt, ICB_MAXNICKLEN,
Index: icb.h
===================================================================
--- icb.h	(revision 9c04f2a610774a04913d70b62f72b0c1e32de735)
+++ icb.h	(revision 82d3c1fc7b55d61d602c1cdc8cb2baf5e5bb0eca)
@@ -129,23 +129,24 @@
 
 /* icb.c */
-struct icb_group *icb_addgroup(struct icb_session *, char *, char *);
-void		 icb_cmdout(struct icb_session *, int, char *);
-void		 icb_delgroup(struct icb_group *);
-void		 icb_error(struct icb_session *, const char *, ...);
-void		 icb_init(struct icbd_callbacks *);
-void		 icb_input(struct icb_session *);
-inline int	 icb_ismod(struct icb_group *, struct icb_session *);
-int		 icb_modpermit(struct icb_session *, int);
-int		 icb_pass(struct icb_group *, struct icb_session *,
-		     struct icb_session *);
-void		 icb_privmsg(struct icb_session *, char *, char *);
-void		 icb_remove(struct icb_session *, char *);
-void		 icb_sendfmt(struct icb_session *, const char *, ...);
-void		 icb_start(struct icb_session *);
-void		 icb_status(struct icb_session *, int, const char *, ...);
-void		 icb_status_group(struct icb_group *, struct icb_session *,
+struct icb_group *
+		icb_addgroup(struct icb_session *, char *, char *);
+void		icb_cmdout(struct icb_session *, int, char *);
+void		icb_delgroup(struct icb_group *);
+void		icb_error(struct icb_session *, const char *, ...);
+void		icb_init(struct icbd_callbacks *);
+void		icb_input(struct icb_session *);
+inline int	icb_ismod(struct icb_group *, struct icb_session *);
+int		icb_modpermit(struct icb_session *, int);
+int		icb_pass(struct icb_group *, struct icb_session *,
+		    struct icb_session *);
+void		icb_privmsg(struct icb_session *, char *, char *);
+void		icb_remove(struct icb_session *, char *);
+void		icb_sendfmt(struct icb_session *, const char *, ...);
+void		icb_start(struct icb_session *);
+void		icb_status(struct icb_session *, int, const char *, ...);
+void		icb_status_group(struct icb_group *, struct icb_session *,
 		    int, const char *, ...);
-void		 icb_who(struct icb_session *, struct icb_group *);
-int		 icb_vis(char *, const char *, size_t, int);
+void		icb_who(struct icb_session *, struct icb_group *);
+int		icb_vis(char *, const char *, size_t, int);
 
 /* callbacks from icbd.c */
Index: icbd.c
===================================================================
--- icbd.c	(revision 9c04f2a610774a04913d70b62f72b0c1e32de735)
+++ icbd.c	(revision 82d3c1fc7b55d61d602c1cdc8cb2baf5e5bb0eca)
@@ -44,4 +44,5 @@
 
 uint64_t sessionid;
+struct stat modtabst;
 char modtabpath[MAXPATHLEN];
 char modtab[ICB_MTABLEN][ICB_MAXNICKLEN];
@@ -64,8 +65,6 @@
 void icbd_log(struct icb_session *, int, const char *, ...);
 void icbd_grplist(char *);
-void icbd_modtab(char *);
 void icbd_restrict(void);
 void icbd_write(struct icb_session *, char *, ssize_t);
-void icbd_signal(int);
 
 static inline int icbd_session_cmp(struct icb_session *, struct icb_session *);
@@ -82,5 +81,4 @@
 main(int argc, char *argv[])
 {
-	struct event ev_sig;
 	struct icbd_callbacks ic = { icbd_drop, icbd_log, icbd_write };
 	const char *cause = NULL;
@@ -239,11 +237,7 @@
 		icbd_restrict();
 
+	icbd_modupdate();
+
 	(void)signal(SIGPIPE, SIG_IGN);
-	if (strlen(modtabpath) > 0) {
-		icbd_modtab(modtabpath);
-		signal_set(&ev_sig, SIGHUP,
-		    (void (*)(int, short, void *))icbd_signal, NULL);
-		signal_add(&ev_sig, NULL);
-	}
 
 	(void)event_dispatch();
@@ -549,12 +543,24 @@
 
 void
-icbd_modtab(char *mtab)
-{
+icbd_modupdate(void)
+{
+	struct stat st;
 	FILE *fp;
 	char *buf, *lbuf;
 	size_t len;
 
-	if ((fp = fopen(mtab, "r")) == NULL)
-		err(EX_NOINPUT, "%s", mtab);
+	if (strlen(modtabpath) == 0)
+		return;
+	if (stat(modtabpath, &st)) {
+		syslog(LOG_ERR, "stat %s", modtabpath);
+		return;
+	}
+	/* see if there are any changes */
+	if (timespeccmp(&st.st_mtim, &modtabst.st_mtim, ==) ||
+	    st.st_size == 0)
+		return;
+
+	if ((fp = fopen(modtabpath, "r")) == NULL)
+		err(EX_NOINPUT, "open %s", modtabpath);
 
 	modtabcnt = 0;
@@ -577,4 +583,5 @@
 			continue;
 		strlcpy(modtab[modtabcnt++], buf, ICB_MAXNICKLEN);
+		fprintf(stderr, "%s\n", buf);
 	}
 	free(lbuf);
@@ -584,18 +591,4 @@
 
 	fclose(fp);
-}
-
-void
-icbd_signal(int sig)
-{
-	switch (sig) {
-	case SIGHUP:
-		if (strlen(modtabpath) > 0)
-			icbd_modtab(modtabpath);
-		break;
-	default:
-		syslog(LOG_WARNING, "unexpected signal %d", sig);
-		break;
-	}
 }
 
Index: icbd.h
===================================================================
--- icbd.h	(revision 9c04f2a610774a04913d70b62f72b0c1e32de735)
+++ icbd.h	(revision 82d3c1fc7b55d61d602c1cdc8cb2baf5e5bb0eca)
@@ -24,13 +24,15 @@
 
 /* icbd.c */
-inline struct icb_session *icbd_session_lookup(uint64_t);
-time_t	getmonotime(void);
+inline struct icb_session *
+		icbd_session_lookup(uint64_t);
+void		icbd_modupdate(void);
+time_t		getmonotime(void);
 
 /* dns.c */
 struct sockaddr_storage;
-int	dns_init(void);
-void	dns_rresolv(struct icb_session *, struct sockaddr_storage *);
+int		dns_init(void);
+void		dns_rresolv(struct icb_session *, struct sockaddr_storage *);
 
 /* logger.c */
-int	logger_init(void);
-void	logger(char *, char *, char *);
+int		logger_init(void);
+void		logger(char *, char *, char *);
