1 /*
2 ** Copyright 2000-2004 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 */
5
6 #if HAVE_CONFIG_H
7 #include "config.h"
8 #endif
9
10 #include <sys/types.h>
11 #if HAVE_DIRENT_H
12 #include <dirent.h>
13 #define NAMLEN(dirent) strlen((dirent)->d_name)
14 #else
15 #define dirent direct
16 #define NAMLEN(dirent) (dirent)->d_namlen
17 #if HAVE_SYS_NDIR_H
18 #include <sys/ndir.h>
19 #endif
20 #if HAVE_SYS_DIR_H
21 #include <sys/dir.h>
22 #endif
23 #if HAVE_NDIR_H
24 #include <ndir.h>
25 #endif
26 #endif
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <time.h>
33 #include <errno.h>
34 #if HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #include "maildirmisc.h"
39
40
41 static void do_maildir_getnew(const char *, const char *,
42 void (*)(const char *, void *),
43 void *);
44
maildir_getnew(const char * maildir,const char * folder,void (* callback_func)(const char *,void *),void * callback_arg)45 void maildir_getnew(const char *maildir, const char *folder,
46 void (*callback_func)(const char *, void *),
47 void *callback_arg)
48 {
49 char *dir=maildir_folderdir(maildir, folder);
50 char *newd, *curd;
51
52 if (!dir) return;
53
54 newd=malloc(strlen(dir)+sizeof("/new"));
55 curd=malloc(strlen(dir)+sizeof("/cur"));
56
57 if (newd && curd)
58 {
59 strcat(strcpy(newd, dir), "/new");
60 strcat(strcpy(curd, dir), "/cur");
61 do_maildir_getnew(newd, curd, callback_func, callback_arg);
62 }
63
64 if (newd) free(newd);
65 if (curd) free(curd);
66 free(dir);
67 }
68
do_maildir_getnew(const char * newd,const char * curd,void (* callback_func)(const char *,void *),void * callback_arg)69 static void do_maildir_getnew(const char *newd, const char *curd,
70 void (*callback_func)(const char *, void *),
71 void *callback_arg)
72 {
73 DIR *dirp;
74 struct dirent *de;
75 int keepgoing;
76 int n;
77 char *new_buf[20];
78 char *cur_buf[20];
79
80 do
81 {
82 keepgoing=0;
83 n=0;
84
85 dirp=opendir(newd);
86 while (dirp && (de=readdir(dirp)) != 0)
87 {
88 char *np, *cp;
89
90 if (de->d_name[0] == '.') continue;
91
92 if ((np=malloc(strlen(newd)+strlen(de->d_name)+2))
93 != 0)
94 {
95 if ((cp=malloc(strlen(curd)+strlen(de->d_name)
96 + sizeof("/" MDIRSEP "2,")))
97 != 0)
98 {
99 char *a;
100
101 strcat(strcat(strcpy(np, newd), "/"),
102 de->d_name);
103 strcat(strcat(strcpy(cp, curd), "/"),
104 de->d_name);
105 a=strchr(cp+strlen(curd), MDIRSEP[0]);
106 if (a && strncmp(a, MDIRSEP "2,", 3))
107 {
108 *a=0;
109 a=0;
110 }
111 if (!a) strcat(cp, MDIRSEP "2,");
112 new_buf[n]=np;
113 cur_buf[n]=cp;
114
115 if (++n >= sizeof(cur_buf)/
116 sizeof(cur_buf[0]))
117 {
118 keepgoing=1;
119 break;
120 }
121 }
122 else
123 free(np);
124 }
125 }
126 if (dirp) closedir(dirp);
127
128 while (n)
129 {
130 char *np, *cp;
131
132 --n;
133
134 np=new_buf[n];
135 cp=cur_buf[n];
136
137 if (rename(np, cp))
138 {
139 fprintf(stderr,
140 "ERR: rename(%s,%s) failed:"
141 " %s\n", np, cp, strerror(errno));
142 keepgoing=0;
143 /* otherwise we could have infinite loop */
144 }
145
146 if (callback_func)
147 (*callback_func)(strrchr(cp, '/')+1,
148 callback_arg);
149 free(np);
150 free(cp);
151 }
152 } while (keepgoing);
153 }
154