summaryrefslogtreecommitdiffstats
path: root/maildir/maildirwatch.h
blob: 330baace69015e63d0af58118183f5f60341d5fa (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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#ifndef maildirwatch_h
#define maildirwatch_h
/*
** Copyright 2002 Double Precision, Inc.
** See COPYING for distribution information.
*/


#ifdef  __cplusplus
extern "C" {
#endif

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

/*
** These function leverage libfam.a to watch for maildir changes.
**
** If libfam.a is not available, these functions are compiled to no-ops
*/

#if HAVE_FAM
#include <fam.h>
#endif


#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

#if HAVE_FAM
struct maildirwatch_fam {
	FAMConnection fc;
	int broken;
	unsigned refcnt;
};

#endif

struct maildirwatch {
	char *maildir;

#if HAVE_FAM
	struct maildirwatch_fam *fam;
#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_FAM
	FAMRequest new_req;
	FAMRequest cur_req;
	FAMRequest courierimapkeywords_req;

	unsigned short endexists_received;
	unsigned short ack_received;

	unsigned short cancelled;

#endif

};

/*
** maildirwatch_start() initiates the process of monitoring the maildir.
** The monitoring process does not get started right away, since FAM needs
** to acknowledge th monitoring requests first.
**
** Returns: 0 - monitoring request sent.
**          1 - FAM is not available, will fall back to 60 second polls.
**         -1 - Fatal error.
*/

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

/*
** Check if FAM started monitoring yet.
**
** Returns: 1 - Monitoring has started, or we're in fallback mode.
**          0 - Not yet, *fdret is initialized to file descriptor to wait on.
**         -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.
*/

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