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