1 /*
2 ** Copyright 2003 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 */
5 
6 #include	"maildiraclt.h"
7 #include	"maildirmisc.h"
8 #include	"maildircreate.h"
9 #include	"maildirnewshared.h"
10 #include	"numlib/numlib.h"
11 #include	<time.h>
12 #if	HAVE_UNISTD_H
13 #include	<unistd.h>
14 #endif
15 #include	<string.h>
16 #include	<errno.h>
17 #include	<stdio.h>
18 #include	<stdlib.h>
19 
20 
21 int maildir_newshared_disabled=0;
22 
maildir_newshared_open(const char * indexfile,struct maildir_newshared_enum_cb * info)23 int maildir_newshared_open(const char *indexfile,
24 			   struct maildir_newshared_enum_cb *info)
25 {
26 	info->indexfile=indexfile;
27 	if ((info->fp=fopen(maildir_newshared_disabled ?
28 			    "/dev/null":indexfile, "r")) == NULL)
29 		return -1;
30 	info->startingpos=0;
31 	info->linenum=0;
32 	return 0;
33 }
34 
maildir_newshared_close(struct maildir_newshared_enum_cb * info)35 void maildir_newshared_close(struct maildir_newshared_enum_cb *info)
36 {
37 	if (info->fp)
38 		fclose(info->fp);
39 	info->fp=NULL;
40 }
41 
maildir_newshared_nextAt(struct maildir_newshared_enum_cb * info,int * eof,int (* cb_func)(struct maildir_newshared_enum_cb *),void * cb_arg)42 int maildir_newshared_nextAt(struct maildir_newshared_enum_cb *info,
43 			     int *eof,
44 			     int (*cb_func)(struct maildir_newshared_enum_cb*),
45 			     void *cb_arg)
46 {
47 	if (fseek(info->fp, info->startingpos, SEEK_SET) < 0)
48 		return -1;
49 	info->linenum= -1;
50 	return maildir_newshared_next(info, eof, cb_func, cb_arg);
51 }
52 
maildir_newshared_next(struct maildir_newshared_enum_cb * info,int * eof,int (* cb_func)(struct maildir_newshared_enum_cb *),void * cb_arg)53 int maildir_newshared_next(struct maildir_newshared_enum_cb *info,
54 			   int *eof,
55 			   int (*cb_func)(struct maildir_newshared_enum_cb *),
56 			   void *cb_arg)
57 {
58 	char linebuf[BUFSIZ];
59 	int rc;
60 	char *p;
61 	const char *name;
62 	const char *homedir;
63 	const char *maildir;
64 	uid_t uid;
65 	gid_t gid;
66 	off_t nbytes;
67 
68 #define CB_INIT(name_,homedir_,maildir_,uid_,gid_) \
69 	info->name=name_; info->homedir=homedir_; info->maildir=maildir_; \
70 	info->uid=uid_; info->gid=gid_; info->cb_arg=cb_arg;
71 
72 	*eof=0;
73 
74 	while (fgets(linebuf, sizeof(linebuf), info->fp) != NULL)
75 	{
76 		nbytes=strlen(linebuf);
77 
78 		if (nbytes && linebuf[nbytes-1] == '\n')
79 			linebuf[nbytes-1]=0;
80 
81 		p=strchr(linebuf, '#');
82 		if (p) *p=0;
83 
84 		p=strchr(linebuf, '\t');
85 		++info->linenum;
86 		if (p)
87 		{
88 			name=linebuf;
89 			*p++=0;
90 
91 			if (*p == '*')
92 			{
93 				p=strchr(p, '\t');
94 				if (p)
95 				{
96 					const char *q;
97 					size_t n;
98 
99 					*p++=0;
100 					maildir=p;
101 					p=strchr(p, '\t');
102 					if (p) *p=0;
103 
104 					q=strrchr(info->indexfile, '/');
105 					if (q)
106 						++q;
107 					else q=info->indexfile;
108 
109 					n=strlen(info->indexfile)-strlen(q);
110 
111 					p=malloc(n+strlen(maildir)+1);
112 					if (!p)
113 						return -1;
114 
115 					if (n)
116 						memcpy(p, info->indexfile, n);
117 					strcpy(p+n, maildir);
118 
119 
120 					CB_INIT(name, NULL, p, 0, 0);
121 
122 					info->cb_arg=cb_arg;
123 					rc= (*cb_func)(info);
124 
125 					free(p);
126 					info->startingpos += nbytes;
127 					return rc;
128 				}
129 			}
130 			else
131 			{
132 				uid=libmail_atouid_t(p);
133 				p=strchr(p, '\t');
134 				if (uid && p)
135 				{
136 					*p++=0;
137 					gid=libmail_atogid_t(p);
138 					p=strchr(p, '\t');
139 					if (gid && p)
140 					{
141 						*p++=0;
142 						homedir=p;
143 						p=strchr(p, '\t');
144 						maildir="./Maildir";
145 
146 						if (p)
147 						{
148 							*p++=0;
149 							if (*p && *p != '\t')
150 								maildir=p;
151 							p=strchr(p, '\t');
152 							if (p) *p=0;
153 						}
154 
155 						CB_INIT(name, homedir,
156 							maildir,
157 							uid,
158 							gid);
159 
160 						info->cb_arg=cb_arg;
161 						rc=(*cb_func)(info);
162 						info->startingpos += nbytes;
163 						return rc;
164 					}
165 				}
166 			}
167 		}
168 
169 		if (linebuf[0])
170 		{
171 			fprintf(stderr, "ERR: %s(%d): syntax error.\n",
172 				info->indexfile, (int)info->linenum);
173 		}
174 		info->startingpos += nbytes;
175 	}
176 	*eof=1;
177 	return 0;
178 }
179 
maildir_newshared_enum(const char * indexfile,int (* cb_func)(struct maildir_newshared_enum_cb *),void * cb_arg)180 int maildir_newshared_enum(const char *indexfile,
181 			   int (*cb_func)(struct maildir_newshared_enum_cb *),
182 			   void *cb_arg)
183 {
184 	struct maildir_newshared_enum_cb cb;
185 	int eof;
186 	int rc;
187 
188 	if (maildir_newshared_open(indexfile, &cb) < 0)
189 		return -1;
190 
191 	while ((rc=maildir_newshared_next(&cb, &eof, cb_func, cb_arg)) == 0)
192 	{
193 		if (eof)
194 		{
195 			maildir_newshared_close(&cb);
196 			return 0;
197 		}
198 	}
199 
200 	maildir_newshared_close(&cb);
201 	return rc;
202 }
203