]>
diplodocus.org Git - nmh/blob - sbr/folder_addmsg.c
f78df87c96cb79836d3342a032e6fd86da727d76
1 /* folder_addmsg.c -- Link message into folder
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
9 #include "folder_realloc.h"
10 #include "folder_addmsg.h"
15 * Link message into a folder. Return the new number
16 * of the message. If an error occurs, return -1.
20 folder_addmsg (struct msgs
**mpp
, char *msgfile
, int selected
,
21 int unseen
, int preserve
, int deleting
, char *from_dir
)
23 int infd
, outfd
, linkerr
, msgnum
;
24 char *nmsg
, newmsg
[BUFSIZ
];
31 /* should we preserve the numbering of the message? */
32 if (preserve
&& (msgnum
= m_atoi (msgfile
)) > 0) {
34 } else if (mp
->nummsg
== 0) {
35 /* check if we are adding to empty folder */
38 /* else use highest message number + 1 */
39 msgnum
= mp
->hghmsg
+ 1;
43 * We might need to make several attempts
44 * in order to add the message to the folder.
49 * See if we need more space. If we need space at the
50 * end, then we allocate space for an addition 100 messages.
51 * If we need space at the beginning of the range, then just
52 * extend message status range to cover this message number.
54 if (msgnum
> mp
->hghoff
) {
55 if (!(mp
= folder_realloc (mp
, mp
->lowoff
, msgnum
+ 100))) {
56 inform("unable to allocate folder storage");
60 } else if (msgnum
< mp
->lowoff
) {
61 if (!(mp
= folder_realloc (mp
, msgnum
, mp
->hghoff
))) {
62 inform("unable to allocate folder storage");
69 * If a message is already in that slot,
70 * then loop to next available slot.
72 if (does_exist (mp
, msgnum
))
75 /* setup the bit flags for this message */
76 clear_msg_flags (mp
, msgnum
);
77 set_exists (mp
, msgnum
);
79 /* should we set the SELECT_UNSEEN bit? */
81 set_unseen (mp
, msgnum
);
84 /* should we set the SELECTED bit? */
86 set_selected (mp
, msgnum
);
88 /* check if highest or lowest selected */
89 if (mp
->numsel
== 0) {
93 if (msgnum
< mp
->lowsel
)
95 if (msgnum
> mp
->hghsel
)
99 /* increment number selected */
104 * check if this is highest or lowest message
106 if (mp
->nummsg
== 0) {
110 if (msgnum
< mp
->lowmsg
)
112 if (msgnum
> mp
->hghmsg
)
116 /* increment message count */
119 nmsg
= m_name (msgnum
);
120 snprintf (newmsg
, sizeof(newmsg
), "%s/%s", mp
->foldpath
, nmsg
);
123 * Now try to link message into folder.
124 * Then run the external hook on the message if one was specified in the context.
125 * Run the refile hook if we're moving the message from one place to another.
126 * We have to construct the from path name for this because it's not there.
127 * Run the add hook if the message is getting copied or linked somewhere else.
129 if (link (msgfile
, newmsg
) != -1) {
131 (void)snprintf(oldmsg
, sizeof (oldmsg
), "%s/%s", from_dir
, msgfile
);
132 (void)ext_hook("ref-hook", oldmsg
, newmsg
);
135 (void)ext_hook("add-hook", newmsg
, NULL
);
142 if (linkerr
== EISREMOTE
)
144 #endif /* EISREMOTE */
147 * Check if the file in our desired location is the same
148 * as the source file. If so, then just leave it alone
149 * and return. Otherwise, we will continue the main loop
150 * and try again at another slot (hghmsg+1).
152 if (linkerr
== EEXIST
) {
153 if (stat (msgfile
, &st2
) == 0 && stat (newmsg
, &st1
) == 0
154 && st2
.st_ino
== st1
.st_ino
) {
161 * If link failed because we are trying to link
162 * across devices, then check if there is a message
163 * already in the desired location. If so, then return
164 * error, else just copy the message.
165 * Cygwin with FAT32 filesystem produces EPERM.
167 if (linkerr
== EXDEV
|| linkerr
== EPERM
) {
168 if (stat (newmsg
, &st1
) == 0) {
169 inform("message %s:%s already exists", mp
->foldpath
, newmsg
);
173 if ((infd
= open (msgfile
, O_RDONLY
)) == -1) {
174 advise (msgfile
, "unable to open message %s", msgfile
);
178 if ((outfd
= creat (newmsg
, (int) st1
.st_mode
& 0777)) == -1) {
179 advise (newmsg
, "unable to create");
183 cpydata (infd
, outfd
, msgfile
, newmsg
);
188 (void)snprintf(oldmsg
, sizeof (oldmsg
), "%s/%s", from_dir
, msgfile
);
189 (void)ext_hook("ref-hook", oldmsg
, newmsg
);
192 (void)ext_hook("add-hook", newmsg
, NULL
);
198 * Else, some other type of link error,
199 * so just return error.
201 advise (newmsg
, "error linking %s to", msgfile
);