#include "str.h"
#include "file.h"
-#include "../lib/debug.h"
-
#ifndef O_NOFOLLOW
# define O_NOFOLLOW 0
#endif
if (lstat (path, &osb) < 0 || fstat(fd, &nsb) < 0
|| compare_stat(&osb, &nsb) == -1)
{
- debug_print(1, ("%s is a symlink!\n", path));
close(fd);
return -1;
}
return r;
}
+/* If rfc1524_expand_command() is used on a recv'd message, then
+ * the filename doesn't exist yet, but if its used while sending a message,
+ * then we need to rename the existing file.
+ *
+ * This function returns 0 on successful move, 1 on old file doesn't exist,
+ * 2 on new file already exists, and 3 on other failure.
+ */
+
+/* note on access(2) use: No dangling symlink problems here due to
+ * safe_fopen().
+ */
+int mutt_rename_file(char *oldfile, char *newfile)
+{
+ FILE *ofp, *nfp;
+
+ if (access(oldfile, F_OK) != 0)
+ return 1;
+ if (access(newfile, F_OK) == 0)
+ return 2;
+
+ ofp = fopen(oldfile, "r");
+ if (!ofp)
+ return 3;
+
+ nfp = safe_fopen(newfile, "w");
+ if (!nfp) {
+ fclose (ofp);
+ return 3;
+ }
+
+ mutt_copy_stream(ofp, nfp);
+ fclose(nfp);
+ fclose(ofp);
+ mutt_unlink(oldfile);
+ return 0;
+}
+
/* Read a line from ``fp'' into the dynamically allocated ``s'',
* increasing ``s'' if necessary. The ending "\n" or "\r\n" is removed.
* If a line ends with "\", this char and the linefeed is removed,
* and the next line is read too.
*/
-char *mutt_read_line(char *s, size_t *size, FILE * fp, int *line)
+char *mutt_read_line(char *s, ssize_t *size, FILE * fp, int *line)
{
- size_t offset = 0;
+ ssize_t offset = 0;
char *ch;
if (!s) {
char buf[BUFSIZ];
size_t l;
- while ((l = fread(buf, 1, sizeof (buf), fin)) > 0) {
+ while ((l = fread(buf, 1, sizeof(buf), fin)) > 0) {
if (fwrite(buf, 1, l, fout) != l)
return -1;
}
return 0;
}
-int mutt_copy_bytes(FILE *in, FILE *out, size_t size)
+int mutt_copy_bytes(FILE *in, FILE *out, ssize_t size)
{
char buf[BUFSIZ];
while (size > 0) {
- size_t chunk = MIN(size, sizeof(buf));
+ size_t chunk = MIN(size, ssizeof(buf));
if ((chunk = fread(buf, 1, chunk, in)) < 1)
break;
if (fwrite(buf, 1, chunk, out) != chunk) {
- debug_print(1, ("fwrite() returned short byte count\n"));
return -1;
}
size -= chunk;