static int maildir_sync_message (CONTEXT *ctx, int msgno) { HEADER *h = ctx->hdrs[msgno]; if (h->attach_del) { /* when doing attachment deletion, fall back to the MH case. */ if (mh_rewrite_message (ctx, msgno) != 0) return (-1); } else { /* we just have to rename the file. */ char newpath[_POSIX_PATH_MAX]; char partpath[_POSIX_PATH_MAX]; char fullpath[_POSIX_PATH_MAX]; char oldpath[_POSIX_PATH_MAX]; char suffix[16]; char *p; if ((p = strrchr (h->path, '/')) == NULL) { dprint (1, (debugfile, "maildir_sync_message: %s: unable to find subdir!\n", h->path)); return (-1); } p++; strfcpy (newpath, p, sizeof (newpath)); /* kill the previous flags */ if ((p = strchr (newpath, ':')) != NULL) *p = 0; maildir_flags (suffix, sizeof (suffix), h); snprintf (partpath, sizeof (partpath), "%s/%s%s", (h->read || h->old) ? "cur" : "new", newpath, suffix); snprintf (fullpath, sizeof (fullpath), "%s/%s", ctx->path, partpath); snprintf (oldpath, sizeof (oldpath), "%s/%s", ctx->path, h->path); if (mutt_strcmp (fullpath, oldpath) == 0) { /* message hasn't really changed */ return 0; } /* record that the message is possibly marked as trashed on disk */ h->trash = h->deleted; if (rename (oldpath, fullpath) != 0) { mutt_perror ("rename"); return (-1); } mutt_str_replace (&h->path, partpath); } return (0); }
int maildir_open_new_message (MESSAGE *msg, CONTEXT *dest, HEADER *hdr) { int fd; char path[_POSIX_PATH_MAX]; char suffix[16]; char subdir[16]; if (hdr) { short deleted = hdr->deleted; hdr->deleted = 0; maildir_flags (suffix, sizeof (suffix), hdr); hdr->deleted = deleted; } else *suffix = '\0'; if (hdr && (hdr->read || hdr->old)) strfcpy (subdir, "cur", sizeof (subdir)); else strfcpy (subdir, "new", sizeof (subdir)); FOREVER { snprintf (path, _POSIX_PATH_MAX, "%s/tmp/%s.%ld.%d_%d.%s%s", dest->path, subdir, time (NULL), getpid (), Counter++, NONULL (Hostname), suffix); dprint (2, (debugfile, "maildir_open_new_message (): Trying %s.\n", path)); if ((fd = open (path, O_WRONLY | O_EXCL | O_CREAT, 0600)) == -1) { if (errno != EEXIST) { mutt_perror (path); return -1; } } else { dprint (2, (debugfile, "maildir_open_new_message (): Success.\n")); msg->path = safe_strdup (path); break; } } if ((msg->fp = fdopen (fd, "w")) == NULL) { FREE (&msg->path); close (fd); unlink (path); return (-1); } return 0; }
static int rename_maildir_filename(const char *old, char *newpath, size_t newsz, HEADER *h) { char filename[_POSIX_PATH_MAX]; char suffix[_POSIX_PATH_MAX]; char folder[_POSIX_PATH_MAX]; char *p; strfcpy(folder, old, sizeof(folder)); p = strrchr(folder, '/'); if (p) *p = '\0'; p++; strfcpy(filename, p, sizeof(filename)); /* remove (new,cur,...) from folder path */ p = strrchr(folder, '/'); if (p) *p = '\0'; /* remove old flags from filename */ if ((p = strchr(filename, ':'))) *p = '\0'; /* compose new flags */ maildir_flags(suffix, sizeof(suffix), h); snprintf(newpath, newsz, "%s/%s/%s%s", folder, (h->read || h->old) ? "cur" : "new", filename, suffix); if (strcmp(old, newpath) == 0) return 1; if (rename(old, newpath) != 0) { dprint(1, (debugfile, "nm: rename(2) failed %s -> %s\n", old, newpath)); return -1; } return 0; }