2 * Copyright (c) 1998 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 __RCSID("$Heimdal: maildir.c 10678 2001-09-10 11:56:53Z joda $"
40 make_path(POP
*p
, MsgInfoList
*mp
, int new, char *buf
, size_t len
)
42 snprintf(buf
, len
, "%s/%s%s%s", p
->drop_name
,
43 new ? "new" : "cur", mp
? "/" : "", mp
? mp
->name
: "");
47 scan_file(POP
*p
, MsgInfoList
*mp
)
49 char path
[MAXPATHLEN
];
54 make_path(p
, mp
, mp
->flags
& NEW_FLAG
, path
, sizeof(path
));
61 "Failed to open message file `%s': %s",
62 path
, strerror(errno
));
64 return pop_msg (p
, POP_FAILURE
,
65 "Failed to open message file `%s'", path
);
67 while(fgets(buf
, sizeof(buf
), f
)) {
68 if(buf
[strlen(buf
) - 1] == '\n')
70 mp
->length
+= strlen(buf
);
73 if(strcmp(buf
, "\n") == 0)
75 parse_header(mp
, buf
);
78 return add_missing_headers(p
, mp
);
82 scan_dir(POP
*p
, int new)
87 MsgInfoList
*mp
= p
->mlp
;
88 int n_mp
= p
->msg_count
;
91 make_path(p
, NULL
, new, tmp
, sizeof(tmp
));
94 while((dent
= readdir(dir
)) != NULL
) {
95 if(strcmp(dent
->d_name
, ".") == 0 || strcmp(dent
->d_name
, "..") == 0)
97 mp
= realloc(mp
, (n_mp
+ 1) * sizeof(*mp
));
100 return pop_msg (p
, POP_FAILURE
,
101 "Can't build message list for '%s': Out of memory",
104 memset(mp
+ n_mp
, 0, sizeof(*mp
));
105 mp
[n_mp
].name
= strdup(dent
->d_name
);
106 if(mp
[n_mp
].name
== NULL
) {
108 return pop_msg (p
, POP_FAILURE
,
109 "Can't build message list for '%s': Out of memory",
112 mp
[n_mp
].number
= n_mp
+ 1;
115 mp
[n_mp
].flags
|= NEW_FLAG
;
116 e
= scan_file(p
, &mp
[n_mp
]);
119 p
->drop_size
+= mp
[n_mp
].length
;
129 pop_maildir_info(POP
*p
)
133 p
->temp_drop
[0] = '\0';
138 if(e
!= POP_SUCCESS
) return e
;
141 if(e
!= POP_SUCCESS
) return e
;
146 pop_maildir_update(POP
*p
)
149 char tmp1
[MAXPATHLEN
], tmp2
[MAXPATHLEN
];
150 for(i
= 0; i
< p
->msg_count
; i
++) {
151 make_path(p
, &p
->mlp
[i
], p
->mlp
[i
].flags
& NEW_FLAG
,
153 if(p
->mlp
[i
].flags
& DEL_FLAG
) {
156 pop_log(p
, POP_DEBUG
, "Removing `%s'", tmp1
);
158 if(unlink(tmp1
) < 0) {
161 pop_log(p
, POP_DEBUG
, "Failed to remove `%s': %s",
162 tmp1
, strerror(errno
));
164 /* return failure? */
166 } else if((p
->mlp
[i
].flags
& NEW_FLAG
) &&
167 (p
->mlp
[i
].flags
& RETR_FLAG
)) {
168 make_path(p
, &p
->mlp
[i
], 0, tmp2
, sizeof(tmp2
));
171 pop_log(p
, POP_DEBUG
, "Linking `%s' to `%s'", tmp1
, tmp2
);
173 if(link(tmp1
, tmp2
) == 0) {
176 pop_log(p
, POP_DEBUG
, "Removing `%s'", tmp1
);
178 if(unlink(tmp1
) < 0) {
181 pop_log(p
, POP_DEBUG
, "Failed to remove `%s'", tmp1
);
183 /* return failure? */
189 pop_log(p
, POP_DEBUG
, "Trying to rename `%s' to `%s'",
192 if(rename(tmp1
, tmp2
) < 0) {
195 pop_log(p
, POP_DEBUG
, "Failed to rename `%s' to `%s'",
207 pop_maildir_open(POP
*p
, MsgInfoList
*mp
)
209 char tmp
[MAXPATHLEN
];
210 make_path(p
, mp
, mp
->flags
& NEW_FLAG
, tmp
, sizeof(tmp
));
213 p
->drop
= fopen(tmp
, "r");
215 return pop_msg(p
, POP_FAILURE
, "Failed to open message file");