1 #if	HAVE_CONFIG_H
2 #include	"config.h"
3 #endif
4 #include	<stdio.h>
5 #include	<string.h>
6 #include	<stdlib.h>
7 #if	HAVE_FCNTL_H
8 #include	<fcntl.h>
9 #endif
10 #if	HAVE_UNISTD_H
11 #include	<unistd.h>
12 #endif
13 #include	<sys/types.h>
14 #if	HAVE_SYS_STAT_H
15 #include	<sys/stat.h>
16 #endif
17 #include	<ctype.h>
18 #include	<errno.h>
19 
20 #include	"maildirmisc.h"
21 
22 #if HAVE_DIRENT_H
23 #include <dirent.h>
24 #define NAMLEN(dirent) strlen((dirent)->d_name)
25 #else
26 #define dirent direct
27 #define NAMLEN(dirent) (dirent)->d_namlen
28 #if HAVE_SYS_NDIR_H
29 #include <sys/ndir.h>
30 #endif
31 #if HAVE_SYS_DIR_H
32 #include <sys/dir.h>
33 #endif
34 #if HAVE_NDIR_H
35 #include <ndir.h>
36 #endif
37 #endif
38 
maildir_make(const char * maildir,int perm,int subdirperm,int folder)39 int maildir_make(const char *maildir, int perm, int subdirperm, int folder)
40 {
41 	char *q=malloc(strlen(maildir)+sizeof("/maildirfolder"));
42 	int fd= -1;
43 
44 	if (!q)
45 		return -1;
46 
47 	if (mkdir(maildir, perm) < 0 ||
48 	    chmod(maildir, perm) < 0 ||
49 	    mkdir(strcat(strcpy(q, maildir), "/tmp"), subdirperm) < 0 ||
50 	    chmod(q, subdirperm) < 0 ||
51 	    mkdir(strcat(strcpy(q, maildir), "/new"), subdirperm) < 0 ||
52 	    chmod(q, subdirperm) < 0 ||
53 	    mkdir(strcat(strcpy(q, maildir), "/cur"), subdirperm) < 0 ||
54 	    chmod(q, subdirperm) < 0 ||
55 	    (folder && (fd=open(strcat(strcpy(q, maildir), "/maildirfolder"),
56 				O_CREAT|O_WRONLY, 0600)) < 0))
57 	{
58 		free(q);
59 		return -1;
60 	}
61 	if (fd >= 0)
62 		close(fd);
63 	free(q);
64 	return 0;
65 }
66 
maildir_del_content(const char * maildir)67 int maildir_del_content(const char *maildir)
68 {
69 	char *filenamebuf[100];
70 	int n, i;
71 	DIR *dirp;
72 	struct dirent *de;
73 
74 	do
75 	{
76 		dirp=opendir(maildir);
77 		n=0;
78 		while (dirp && (de=readdir(dirp)) != 0)
79 		{
80 			if (strcmp(de->d_name, ".") == 0 ||
81 			    strcmp(de->d_name, "..") == 0)
82 				continue;
83 
84 			if ((filenamebuf[n]=malloc(strlen(maildir)+
85 						   strlen(de->d_name)+2))
86 			    == NULL)
87 			{
88 				closedir(dirp);
89 				while (n)
90 					free(filenamebuf[--n]);
91 				return -1;
92 			}
93 			strcat(strcat(strcpy(filenamebuf[n], maildir),
94 				      "/"), de->d_name);
95 			if (++n >= sizeof(filenamebuf)/sizeof(filenamebuf[0]))
96 				break;
97 		}
98 		if (dirp)
99 			closedir(dirp);
100 
101 		for (i=0; i<n; i++)
102 		{
103 			struct stat s_buf;
104 
105 			if (lstat(filenamebuf[i], &s_buf) < 0)
106 				continue;
107 
108 			if (S_ISDIR(s_buf.st_mode))
109 			{
110 				if (maildir_del(filenamebuf[i]) < 0)
111 				{
112 					while (n)
113 						free(filenamebuf[--n]);
114 					return -1;
115 				}
116 			}
117 			else if (unlink(filenamebuf[i]) < 0)
118 			{
119 				if (errno != ENOENT)
120 				{
121 					while (n)
122 						free(filenamebuf[--n]);
123 					return -1;
124 
125 				}
126 			}
127 		}
128 
129 		for (i=0; i<n; i++)
130 			free(filenamebuf[i]);
131 	} while (n);
132 	return 0;
133 }
134 
maildir_del(const char * maildir)135 int maildir_del(const char *maildir)
136 {
137 	int rc;
138 	if ((rc=maildir_del_content(maildir)) == -1)
139 	    return rc;
140 	return rmdir(maildir) < 0 && errno != ENOENT ? -1:0;
141 }
142