-
/*
- * folder_addmsg.c -- Link message into folder
- *
- * $Id$
- *
- * This code is Copyright (c) 2002, by the authors of nmh. See the
- * COPYRIGHT file in the root directory of the nmh distribution for
- * complete copyright information.
- */
+** folder_addmsg.c -- Link message into folder
+**
+** This code is Copyright (c) 2002, by the authors of nmh. See the
+** COPYRIGHT file in the root directory of the nmh distribution for
+** complete copyright information.
+*/
#include <h/mh.h>
#include <fcntl.h>
#include <errno.h>
/*
- * Link message into a folder. Return the new number
- * of the message. If an error occurs, return -1.
- */
+** Link message into a folder. Return the new number
+** of the message. If an error occurs, return -1.
+*/
int
-folder_addmsg (struct msgs **mpp, char *msgfile, int selected,
- int unseen, int preserve)
+folder_addmsg(struct msgs **mpp, char *msgfile, int selected,
+ int unseen, int preserve, int deleting, char *from_dir)
{
- int infd, outfd, linkerr, first_time, msgnum;
- char *nmsg, newmsg[BUFSIZ];
- struct msgs *mp;
- struct stat st1, st2;
-
- first_time = 1; /* this is first attempt */
- mp = *mpp;
-
- /*
- * We might need to make several attempts
- * in order to add the message to the folder.
- */
- for (;;) {
- /*
- * Get the message number we will attempt to add.
- */
- if (first_time) {
- /* should we preserve the numbering of the message? */
- if (preserve && (msgnum = m_atoi (msgfile)) > 0) {
+ int infd, outfd, linkerr, msgnum;
+ char *nmsg, newmsg[BUFSIZ];
+ char oldmsg[BUFSIZ];
+ struct msgs *mp;
+ struct stat st1, st2;
+
+ mp = *mpp;
+
+ /* should we preserve the numbering of the message? */
+ if (preserve && (msgnum = m_atoi(msgfile)) > 0) {
;
- } else if (mp->nummsg == 0) {
+ } else if (mp->nummsg == 0) {
/* check if we are adding to empty folder */
msgnum = 1;
- } else {
+ } else {
/* else use highest message number + 1 */
msgnum = mp->hghmsg + 1;
- }
- first_time = 0;
- } else {
- /* another attempt, so try next higher message number */
- msgnum++;
}
/*
- * See if we need more space. If we need space at the
- * end, then we allocate space for an addition 100 messages.
- * If we need space at the beginning of the range, then just
- * extend message status range to cover this message number.
- */
- if (msgnum > mp->hghoff) {
- if ((mp = folder_realloc (mp, mp->lowoff, msgnum + 100)))
- *mpp = mp;
- else {
- advise (NULL, "unable to allocate folder storage");
- return -1;
- }
- } else if (msgnum < mp->lowoff) {
- if ((mp = folder_realloc (mp, msgnum, mp->hghoff)))
- *mpp = mp;
- else {
- advise (NULL, "unable to allocate folder storage");
- return -1;
- }
- }
+ ** We might need to make several attempts
+ ** in order to add the message to the folder.
+ */
+ for (;; msgnum++) {
+
+ /*
+ ** See if we need more space. If we need space at the
+ ** end, then we allocate space for an addition 100 messages.
+ ** If we need space at the beginning of the range, then just
+ ** extend message status range to cover this message number.
+ */
+ if (msgnum > mp->hghoff) {
+ if ((mp = folder_realloc(mp, mp->lowoff, msgnum + 100)))
+ *mpp = mp;
+ else {
+ advise(NULL, "unable to allocate folder storage");
+ return -1;
+ }
+ } else if (msgnum < mp->lowoff) {
+ if ((mp = folder_realloc(mp, msgnum, mp->hghoff)))
+ *mpp = mp;
+ else {
+ advise(NULL, "unable to allocate folder storage");
+ return -1;
+ }
+ }
- /*
- * If a message is already in that slot,
- * then loop to next available slot.
- */
- if (does_exist (mp, msgnum))
- continue;
-
- /* setup the bit flags for this message */
- clear_msg_flags (mp, msgnum);
- set_exists (mp, msgnum);
-
- /* should we set the SELECT_UNSEEN bit? */
- if (unseen) {
- set_unseen (mp, msgnum);
- }
+ /*
+ ** If a message is already in that slot,
+ ** then loop to next available slot.
+ */
+ if (does_exist(mp, msgnum))
+ continue;
- /* should we set the SELECTED bit? */
- if (selected) {
- set_selected (mp, msgnum);
-
- /* check if highest or lowest selected */
- if (mp->numsel == 0) {
- mp->lowsel = msgnum;
- mp->hghsel = msgnum;
- } else {
- if (msgnum < mp->lowsel)
- mp->lowsel = msgnum;
- if (msgnum > mp->hghsel)
- mp->hghsel = msgnum;
- }
-
- /* increment number selected */
- mp->numsel++;
- }
+ /* setup the bit flags for this message */
+ clear_msg_flags(mp, msgnum);
+ set_exists(mp, msgnum);
- /*
- * check if this is highest or lowest message
- */
- if (mp->nummsg == 0) {
- mp->lowmsg = msgnum;
- mp->hghmsg = msgnum;
- } else {
- if (msgnum < mp->lowmsg)
- mp->lowmsg = msgnum;
- if (msgnum > mp->hghmsg)
- mp->hghmsg = msgnum;
- }
-
- /* increment message count */
- mp->nummsg++;
+ /* should we set the SELECT_UNSEEN bit? */
+ if (unseen) {
+ set_unseen(mp, msgnum);
+ }
- nmsg = m_name (msgnum);
- snprintf (newmsg, sizeof(newmsg), "%s/%s", mp->foldpath, nmsg);
+ /* should we set the SELECTED bit? */
+ if (selected) {
+ set_selected(mp, msgnum);
+
+ /* check if highest or lowest selected */
+ if (mp->numsel == 0) {
+ mp->lowsel = msgnum;
+ mp->hghsel = msgnum;
+ } else {
+ if (msgnum < mp->lowsel)
+ mp->lowsel = msgnum;
+ if (msgnum > mp->hghsel)
+ mp->hghsel = msgnum;
+ }
+
+ /* increment number selected */
+ mp->numsel++;
+ }
- /*
- * Now try to link message into folder
- */
- if (link (msgfile, newmsg) != -1) {
- return msgnum;
- } else {
- linkerr = errno;
-
-#ifdef EISREMOTE
- if (linkerr == EISREMOTE)
- linkerr = EXDEV;
-#endif /* EISREMOTE */
-
- /*
- * Check if the file in our desired location is the same
- * as the source file. If so, then just leave it alone
- * and return. Otherwise, we will continue the main loop
- * and try again at another slot (hghmsg+1).
- */
- if (linkerr == EEXIST) {
- if (stat (msgfile, &st2) == 0 && stat (newmsg, &st1) == 0
- && st2.st_ino == st1.st_ino) {
- return msgnum;
+ /*
+ ** check if this is highest or lowest message
+ */
+ if (mp->nummsg == 0) {
+ mp->lowmsg = msgnum;
+ mp->hghmsg = msgnum;
} else {
- continue;
+ if (msgnum < mp->lowmsg)
+ mp->lowmsg = msgnum;
+ if (msgnum > mp->hghmsg)
+ mp->hghmsg = msgnum;
}
- }
-
- /*
- * If link failed because we are trying to link
- * across devices, then check if there is a message
- * already in the desired location. If so, then return
- * error, else just copy the message.
- */
- if (linkerr == EXDEV) {
- if (stat (newmsg, &st1) == 0) {
- advise (NULL, "message %s:%s already exists", newmsg);
- return -1;
+
+ /* increment message count */
+ mp->nummsg++;
+
+ nmsg = m_name(msgnum);
+ snprintf(newmsg, sizeof(newmsg), "%s/%s", mp->foldpath, nmsg);
+
+ /*
+ ** Now try to link message into folder. Then run the
+ ** external hook on the message if one was specified in
+ ** the context. Run the refile hook if we're moving the
+ ** message from one place to another. We have to construct
+ ** the from path name for this because it's not there.
+ ** Run the add hook if the message is getting copied or
+ ** linked somewhere else.
+ */
+ if (link(msgfile, newmsg) != -1) {
+
+ if (deleting) {
+ snprintf(oldmsg, sizeof (oldmsg), "%s/%s",
+ from_dir, msgfile);
+ ext_hook("ref-hook", oldmsg, newmsg);
+ } else
+ ext_hook("add-hook", newmsg, NULL);
+
+ return msgnum;
} else {
- if ((infd = open (msgfile, O_RDONLY)) == -1) {
- advise (msgfile, "unable to open message %s");
- return -1;
- }
- fstat (infd, &st1);
- if ((outfd = creat (newmsg, (int) st1.st_mode & 0777)) == -1) {
- advise (newmsg, "unable to create");
- close (infd);
+ linkerr = errno;
+
+ /*
+ ** Check if the file in our desired location is
+ ** the same as the source file. If so, then just
+ ** leave it alone and return. Otherwise, we will
+ ** continue the main loop and try again at another
+ ** slot (hghmsg+1).
+ */
+ if (linkerr == EEXIST) {
+ if (stat(msgfile, &st2) == 0 && stat(newmsg, &st1) == 0
+ && st2.st_ino == st1.st_ino) {
+ return msgnum;
+ } else {
+ continue;
+ }
+ }
+
+ /*
+ ** If link failed because we are trying to link
+ ** across devices, then check if there is a message
+ ** already in the desired location. If so, then return
+ ** error, else just copy the message.
+ */
+ if (linkerr == EXDEV) {
+ if (stat(newmsg, &st1) == 0) {
+ advise(NULL, "message %s:%s already exists", mp->foldpath, newmsg);
+ return -1;
+ } else {
+ if ((infd = open(msgfile, O_RDONLY)) == -1) {
+ advise(msgfile, "unable to open message %s", msgfile);
+ return -1;
+ }
+ fstat(infd, &st1);
+ if ((outfd = creat(newmsg, (int) st1.st_mode & 0777)) == -1) {
+ advise(newmsg, "unable to create");
+ close(infd);
+ return -1;
+ }
+ cpydata(infd, outfd, msgfile, newmsg);
+ close(infd);
+ close(outfd);
+
+ if (deleting) {
+ snprintf(oldmsg, sizeof oldmsg,
+ "%s/%s",
+ from_dir,
+ msgfile);
+ ext_hook("ref-hook", oldmsg, newmsg);
+ } else
+ ext_hook("add-hook", newmsg, NULL);
+
+ return msgnum;
+ }
+ }
+
+ /*
+ ** Else, some other type of link error,
+ ** so just return error.
+ */
+ advise(newmsg, "error linking %s to", msgfile);
return -1;
- }
- cpydata (infd, outfd, msgfile, newmsg);
- close (infd);
- close (outfd);
- return msgnum;
}
- }
-
- /*
- * Else, some other type of link error,
- * so just return error.
- */
- advise (newmsg, "error linking %s to", msgfile);
- return -1;
}
- }
}