Automatic refresh for local Maildir's mail counts -- an attempt based on named pipes
Linux-Fan <Ma_Sys.ma-S0/[email protected]> Sun, 25 Mar 2018 21:21:29 +0200
| Newsgroups | gmane.mail.cone |
|---|---|
| Message-ID | <cone.1522005689.867125.28794.1000@masysma-3> |
This is a MIME GnuPG-signed message. If you see this text, it means that
your E-mail or Usenet software does not support MIME signed messages.
The Internet standard for MIME PGP messages, RFC 2015, was published in 1996.
To open this message correctly you will need to install E-mail or Usenet
software that supports modern Internet standards.
--===============4446096351122265123==
Content-Type: multipart/signed;
boundary="=_masysma-3-28794-1522005689-0001";
micalg=pgp-sha1; protocol="application/pgp-signature"
This is a MIME GnuPG-signed message. If you see this text, it means that
your E-mail or Usenet software does not support MIME signed messages.
The Internet standard for MIME PGP messages, RFC 2015, was published in 1996.
To open this message correctly you will need to install E-mail or Usenet
software that supports modern Internet standards.
--=_masysma-3-28794-1522005689-0001
Content-Type: multipart/mixed; boundary="=_masysma-3-1522005689-0000"
This is a MIME-formatted message. If you see this text it means that your
E-mail software does not support MIME-formatted messages.
--=_masysma-3-1522005689-0000
Content-Type: text/plain; format=flowed; delsp=yes; charset="UTF-8"
Content-Disposition: inline
Content-Transfer-Encoding: 7bit
Dear Mr. Varshavchik, dear other Cone users,
it has been more than a year since I wrote about means to automatically
refresh Maildir's displayed mail counts
(https://sourceforge.net/p/courier/mailman/message/35577227/).
I have been running the patch proposed there ever since and it worked.
Still, during a discussion with a friend, I got convinced that signals
and multithreaded programs should really be avoided as much as possible.
As a result, I have thought of another way to interact with Cone for
triggering a refresh of mail counts and ended up with an approach based
on named pipes.
Unlike before, a write to the named pipe does not interrupt Cone and
is thus much safer.
However, I did not manage to have the named pipe polled at the same
location as other poll calls in Cone happen, because this always
resulted in either my file descriptor being ignored (when calling
`fds.push_back(myServer::pollFDForRefreshMessageCount)` in
myserver.C:192 only) or in an endless loop (when calling `push_back`
also in line 239 in the same file).
The attached patch thus implements polling in an own location which
means it only happens every `mailCheckInterval` (worst case: 300)
seconds.
My questions are now as follows:
* Is the idea implemented by the attached patch safe enough to be
included in Cone?
* What can I do to have the polling mechanism which is already in
use in Cone also poll my named pipe file descriptor such that mail
counts are immediately updated?
Thanks in advance and Yours Sincerely
Linux-Fan
--=_masysma-3-1522005689-0000
Content-Disposition: attachment;
FILENAME="patch_cone_refresh_with_named_pipe.diff"
Content-Type: text/x-diff; charset="UTF-8"
Content-Transfer-Encoding: 7bit
--- cone-beforechg/cone/cone.C 2018-03-25 16:10:45.317386165 +0200
+++ cone-0.96.2.20180216/cone/cone.C 2018-03-25 17:41:34.671972832 +0200
@@ -429,6 +429,7 @@
myServer **selectedServer)
{
CursesHierarchy hierarchy_screen( &myServer::hierarchy, mainScreen);
+ myServer::setCursesHierarchyPointerForRefreshing(&hierarchy_screen);
titleBar->setTitles(_("FOLDERS"), "");
@@ -474,6 +475,8 @@
*selectedFolder=hierarchy_screen.folderSelected;
if (selectedServer)
*selectedServer=hierarchy_screen.serverSelected;
+
+ myServer::setCursesHierarchyPointerForRefreshing(NULL);
}
void hierarchyScreen(void *dummy)
@@ -1025,6 +1028,8 @@
delete myServer::remoteConfigAccount;
myServer::remoteConfigAccount=NULL;
}
+
+ myServer::closePollFDForRefreshMessageCount();
}
//
@@ -1142,7 +1147,7 @@
int recover=0;
Macros macroBuffer;
- while ((optc=getopt(argc, argv, "vrCc:")) != -1)
+ while ((optc=getopt(argc, argv, "vrCc:m:")) != -1)
{
switch (optc) {
case 'v':
@@ -1151,6 +1156,22 @@
case 'r':
recover=1;
break;
+ case 'm':
+ // try to delete if existent, ignore fail
+ unlink(optarg);
+ if(mkfifo(optarg, 0644) < 0)
+ {
+ perror("Failed to create FIFO");
+ exit(1);
+ }
+ int pipe;
+ if((pipe = open(optarg, O_RDONLY | O_NONBLOCK)) < 0)
+ {
+ perror("Failed to open FIFO for reading");
+ exit(1);
+ }
+ myServer::setPollFDForRefreshMessageCount(pipe);
+ break;
case 'c':
myServer::configDir=optarg;
diff -x config.status -x '*.log' -x .deps -x Makefile -x Makefile.in -Nrau cone-beforechg/cone/curseshierarchy.C cone-0.96.2.20180216/cone/curseshierarchy.C
--- cone-beforechg/cone/curseshierarchy.C 2018-03-25 16:10:45.301386438 +0200
+++ cone-0.96.2.20180216/cone/curseshierarchy.C 2018-03-25 17:08:13.627911893 +0200
@@ -985,6 +985,26 @@
me->processDeletedFolder(parent, deleted, updatedFolder);
}
+bool CursesHierarchy::RefreshIterator::visit(Hierarchy::Folder* f)
+{
+ if(f != NULL && this->cs != NULL)
+ f->updateInfo(this->cs, true);
+ return true;
+}
+
+bool CursesHierarchy::RefreshIterator::visit(Hierarchy::Server* s)
+{
+ if(s != NULL)
+ this->cs = s->getServer();
+ return true;
+}
+
+void CursesHierarchy::refreshAllFolders()
+{
+ RefreshIterator iterator;
+ getHierarchy()->root.prefixIterate(iterator);
+}
+
///////////
bool CursesHierarchy::processKey(const Curses::Key &key)
{
diff -x config.status -x '*.log' -x .deps -x Makefile -x Makefile.in -Nrau cone-beforechg/cone/curseshierarchy.H cone-0.96.2.20180216/cone/curseshierarchy.H
--- cone-beforechg/cone/curseshierarchy.H 2018-03-25 16:10:45.321386096 +0200
+++ cone-0.96.2.20180216/cone/curseshierarchy.H 2018-03-25 17:10:14.744631348 +0200
@@ -61,6 +61,14 @@
};
+ class RefreshIterator: public Hierarchy::EntryIterator {
+ private:
+ myServer* cs = NULL;
+ public:
+ bool visit(Hierarchy::Folder* f);
+ bool visit(Hierarchy::Server* s);
+ };
+
public:
friend class DrawIterator;
@@ -84,6 +92,7 @@
bool drawErase(Hierarchy::Server *server, bool doErase);
void visible(Hierarchy::Entry *e);
+ void refreshAllFolders();
private:
bool drawErase(std::string str1, int col1,
diff -x config.status -x '*.log' -x .deps -x Makefile -x Makefile.in -Nrau cone-beforechg/cone/myserver.C cone-0.96.2.20180216/cone/myserver.C
--- cone-beforechg/cone/myserver.C 2018-03-25 16:10:45.313386233 +0200
+++ cone-0.96.2.20180216/cone/myserver.C 2018-03-25 19:51:51.585481655 +0200
@@ -23,6 +23,7 @@
#include <fcntl.h>
#include <pwd.h>
#include <unistd.h>
+#include <poll.h>
#include <iostream>
@@ -42,6 +43,9 @@
extern void folderIndexScreen(void *);
extern void hierarchyScreen(void *);
+struct pollfd myServer::pollFDForRefreshMessageCount = { -1, POLLIN, 0 };
+CursesHierarchy* myServer::cursesHierarchyForRefreshing = NULL;
+
myServer::myServer(string name, string urlArg)
: serverName(name), url(urlArg), mailCheckInterval(300), server(NULL),
currentFolder(NULL), hierarchyEntry(NULL)
@@ -281,6 +285,18 @@
break;
}
}
+
+ // TODO Code works but may refresh only every 300sec.
+ // Could the polling happen within the other poll calls?
+ char buf[128];
+ if(myServer::pollFDForRefreshMessageCount.fd != -1 &&
+ poll(&myServer::pollFDForRefreshMessageCount,
+ 1, 0) > 0 &&
+ read(myServer::pollFDForRefreshMessageCount.fd,
+ buf, sizeof(buf)) > 0 &&
+ myServer::cursesHierarchyForRefreshing != NULL)
+ myServer::cursesHierarchyForRefreshing->
+ refreshAllFolders();
}
statusBar->notbusy();
@@ -1032,3 +1048,24 @@
finishCheckingNewMail();
}
+
+void myServer::setPollFDForRefreshMessageCount(int fd)
+{
+ myServer::pollFDForRefreshMessageCount.fd = fd;
+}
+
+void myServer::closePollFDForRefreshMessageCount()
+{
+ if(myServer::pollFDForRefreshMessageCount.fd != -1)
+ {
+ if(!close(myServer::pollFDForRefreshMessageCount.fd))
+ perror("Failed to close message count update file "
+ "descriptor");
+ myServer::pollFDForRefreshMessageCount.fd = -1;
+ }
+}
+
+void myServer::setCursesHierarchyPointerForRefreshing(CursesHierarchy* h)
+{
+ myServer::cursesHierarchyForRefreshing = h;
+}
diff -x config.status -x '*.log' -x .deps -x Makefile -x Makefile.in -Nrau cone-beforechg/cone/myserver.H cone-0.96.2.20180216/cone/myserver.H
--- cone-beforechg/cone/myserver.H 2018-03-25 16:10:45.313386233 +0200
+++ cone-0.96.2.20180216/cone/myserver.H 2018-03-25 17:11:03.572938075 +0200
@@ -14,6 +14,7 @@
#include "curses/timer.H"
#include "myreadfolders.H"
#include "certificates.H"
+#include "curseshierarchy.H"
#include <string>
#include <vector>
@@ -86,6 +87,9 @@
std::map<std::string, std::map<std::string, std::string>
> folder_configuration;
+ static struct pollfd pollFDForRefreshMessageCount;
+ static CursesHierarchy* cursesHierarchyForRefreshing;
+
public:
bool updateServerConfiguration(std::string name, std::string value);
std::string getServerConfiguration(std::string name);
@@ -220,6 +224,10 @@
void addHierarchy(bool assignRows);
void showHierarchy();
void updateHierarchy();
+
+ static void setPollFDForRefreshMessageCount(int fd);
+ static void closePollFDForRefreshMessageCount();
+ static void setCursesHierarchyPointerForRefreshing(CursesHierarchy* h);
private:
void addTopLevelFolders();
void addTopLevelFolder(std::string);
--=_masysma-3-1522005689-0000--
--=_masysma-3-28794-1522005689-0001
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEkKMBOo1F/f2B6jfK+Elw7bKeCLUFAlq39rkACgkQ+Elw7bKe
CLV8cQ/+OyTNEfH+VPWVgQsWJMUQZq7nyQLhsu7paMZo1Epk/xWVFlEg0fV3wP50
XeBYjbf/l7C7wta9wAt/9lIFiW8ULiNHkLrbRie5+5jMZRuxiMgjnULv4XD8MKXe
8376NB2OsfHVCTpXG5o13uaJFw9UVrY9WrbnLWEeVipexRLf80pecXSu7RA+fBNz
kFuXTE8/n6qB1sfEKzqFokg4Y1XvUGFl+WOz9BmJJvohyhKvJgxNYw2+607i7UFy
x/BHUWcX8mZoDEhfKSKsJuIXZJE7CZxOmb8dhDpZyM5V2pRMYtD+u2dyP+iFmAKu
e4yJ/6BPE7CDMXd4LFZ/6GqZ0qTklB011m3Pqdm4x/Gcqb8UGh4my9WJwFVDT2c7
NeHImF+//fCPJpPEUd5csomcavCrB8dNiB3DrqsF8WnOHofz5Z7U1d4uIb3zo2on
cdxau/gvsMzGd/6xcRejVAt43KqrC4PyCsf4gZocMzgXOVHIJJ/eAuFd6b4Q8N1C
R50IU2eTQMnfVG14bs4NtZxI8s17/9fB60f//2MfWO1Sdr9/kyI2n7gXYIO0Z0/8
PayzGHGntxBIhUflGDpHyRIrunidYsgoeJY7JtgkhRD7X4dJXJlknFDJV2YCJhru
wCXilA7mfQ7Y5Vp6gaMPJGTvhqHsaJvGlPk7112gF949YXBy/rs=
=u6vo
-----END PGP SIGNATURE-----
--=_masysma-3-28794-1522005689-0001--
--===============4446096351122265123==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
--===============4446096351122265123==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
Courier-cone mailing list
[email protected]
Unsubscribe: https://lists.sourceforge.net/lists/listinfo/courier-cone
--===============4446096351122265123==--