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