Watch utility for local maildir.
git clone git://git.skec.site/pub/mailstatus.git
log | files | refs | readme | license

commit 0f3877d4c6ca07e205215ae38e90e67c0c3d2e44
parent db5fdecd77253a9d745413975c672793bc89e49a
Author: Michael Skec
Date:   Mon, 25 Dec 2023 17:50:11 +1100

Watch $XDG_RUNTIME_DIR/mailstatus-fetch for fetch status indication.

If the file $XDG_RUNTIME_DIR/mailstatus-fetch exists, the program shows
a transitory "Fetching mail..." message.  When this file is removed, the
program returns to normal behaviour, displaying the current unread
message count.

This functionality is intended to be used in a script for fetching mail,
such as in the following example:

  touch $XDG_RUNTIME_DIR/mailstatus-fetch
  fdm fetch # command to fetch mail
  rm $XDG_RUNTIME_DIR/mailstatus-fetch

Diffstat:
Mmailstatus.c | 56+++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 53 insertions(+), 3 deletions(-)

diff --git a/mailstatus.c b/mailstatus.c @@ -22,9 +22,13 @@ static int _buffer_len = 0; /* Current mail info */ static int _unread_count = 0; -static int _inotify = -1, _watch = -1; +static int _inotify = -1, _watch = -1, _watch2 = -1; static volatile sig_atomic_t _sigint = 0; +/* Path of "fetching" indication file to watch */ +static int _fetch = 0; +static char _f_indicator[FILENAME_MAX]; + static void sigint_handler(int param) { @@ -39,6 +43,13 @@ update_status(void) DIR *d; struct dirent *de; + if (_fetch) + { + _buffer_len = snprintf(_buffer, sizeof(_buffer), + "Fetching mail..."); + return; + } + d = opendir(_maildir_inbox_new); if (d == NULL) { @@ -86,6 +97,7 @@ int main(int argc, char **argv) { int rc = 0; + char *runtime_dir; /* Get maildir from command line */ if (argc < 2) @@ -101,6 +113,17 @@ main(int argc, char **argv) //fprintf(stdout, "Watch directory: %s\n", _maildir_inbox_new); + /* Get fetch indicator path */ + runtime_dir = getenv("XDG_RUNTIME_DIR"); + if (!runtime_dir && !*runtime_dir) + { + fprintf(stderr, "$XDG_RUNTIME_DIR is not set\n"); + rc = -1; + goto exit; + } + snprintf(_f_indicator, sizeof(_f_indicator), + "%s/mailstatus-fetch", runtime_dir); + _inotify = inotify_init1(IN_NONBLOCK); if (_inotify == -1) { @@ -122,6 +145,18 @@ main(int argc, char **argv) goto exit; } + /* Register inotify watch on the fetch indicator file */ + _watch2 = inotify_add_watch(_inotify, + runtime_dir, + IN_CREATE | IN_DELETE); + if (_watch2 == -1) + { + fprintf(stderr, "failed to add inotify watch (%d): %s\n", + errno, strerror(errno)); + rc = -1; + goto exit; + } + struct sigaction sigact = { sigint_handler }; sigaction(SIGINT, &sigact, NULL); @@ -148,6 +183,7 @@ main(int argc, char **argv) char *p; const struct inotify_event *e; int count = 0; + int fetch = -1; for (p = buf; p < buf + n; @@ -155,12 +191,26 @@ main(int argc, char **argv) { e = (const struct inotify_event *)p; - if (e->mask & (IN_CREATE | IN_DELETE | IN_MOVE)) + if ((e->wd == _watch) && + (e->mask & (IN_CREATE | IN_DELETE | IN_MOVE))) + { ++count; + } + else if ((e->wd == _watch2) && + (strcmp(e->name, "mailstatus-fetch") == 0)) + { + if (e->mask & IN_CREATE) + fetch = 1; + else if (e->mask & IN_DELETE) + fetch = 0; + } } - if (count > 0) + if (fetch != -1 || count > 0) { + if (fetch != -1) + _fetch = fetch; + /* Update mail status */ update_status(); print_status();