summaryrefslogtreecommitdiffstats
path: root/maildir/maildirwatch.h
blob: 5f496236b38d906db3a4de99ac6fdb8001501819 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ifndef maildirwatch_h
#define maildirwatch_h
/*
** Copyright 2002-2021 Double Precision, Inc.
** See COPYING for distribution information.
*/


#ifdef  __cplusplus
extern "C" {
#endif

#if HAVE_CONFIG_H
#include "config.h"
#endif

/*
** These function use inotify to watch for maildir changes.
*/

#if TIME_WITH_SYS_TIME
#include	<sys/time.h>
#include	<time.h>
#else
#if HAVE_SYS_TIME_H
#include	<sys/time.h>
#else
#include	<time.h>
#endif
#endif

struct maildirwatch {
	char *maildir;

#if HAVE_INOTIFY_INIT
	int inotify_fd;
#endif
	time_t now;
	time_t timeout;

};

#define WATCHDOTLOCK	"tmp/courier.lock"

#define KEYWORDDIR "courierimapkeywords"

struct maildirwatch *maildirwatch_alloc(const char *maildir);

void maildirwatch_free(struct maildirwatch *w);
	/*
	** Wait for WATCHDOTLOCK to go away
	*/

void maildirwatch_cleanup();
	/* Final cleanup before prog terminates */

int maildirwatch_unlock(struct maildirwatch *w, int nseconds);

	/*********** Wait for changes to new and cur subdirs ************/

	/* Caller must allocate the follownig structure: */

struct maildirwatch_contents {
	struct maildirwatch *w;

#if HAVE_INOTIFY_INIT
	int handles[3];
#endif
};

/*
** maildirwatch_start() initiates the process of monitoring the maildir.
**
** Returns: 0 - monitoring started.
**          1 - inotify not available, will fall back to 60 second polls.
**         -1 - Fatal error.
*/

int maildirwatch_start(struct maildirwatch *p,
		       struct maildirwatch_contents *w);

/*
** Check the status of inotify monitoring.
**
** Returns: 1 - Monitoring has started, or we're in fallback mode.
**          0 - Not yet, *fdret is initialized to file descriptor to wait on.
**              (not used at this time).
**         -1 - A fatal error occured, fall back to polling mode.
**
** maildirwatch_started() returns right away, without blocking.
*/

int maildirwatch_started(struct maildirwatch_contents *w,
			 int *fdret);

/*
** Check if maildir's contents have changed.
**
** Returns: 0 - Monitoring in progress.  *changed set to non-zero if maildir
**              was changed.
**         -1 - Fatal error.
**
** *fdret and *timeout get initialized to the file descriptor to wait on,
** and the requested timeout.  *fdret may be negative in polling mode, this
** should be interpreted as: if *changed is not set, sleep for this period of
** time.
*/

int maildirwatch_check(struct maildirwatch_contents *w,
		       int *changed,
		       int *fdret,
		       int *timeout);

	/*
	** Clean everything up.
	*/
void maildirwatch_end(struct maildirwatch_contents *w);


	/*
	** Courier-IMAP compatible maildir lock.
	**
	** Returns a non-NULL filename on success.  To unlock:
	**
	** unlink(filename); free(filename);
	**
	** A NULL return with tryAnyway != 0 means that the lock failed
	** probably as a result of misconfigured FAM, or something.
	**
	*/
char *maildir_lock(const char *maildir,
		   struct maildirwatch *w, /* If NULL, we sleep() */
		   int *tryAnyway);

#ifdef  __cplusplus
}
#endif

#endif