]>
diplodocus.org Git - nmh/blob - sbr/folder_addmsg.c
3 * folder_addmsg.c -- Link message into folder
13 * Link message into a folder. Return the new number
14 * of the message. If an error occurs, return -1.
18 folder_addmsg (struct msgs
**mpp
, char *msgfile
, int selected
,
19 int unseen
, int preserve
)
21 int infd
, outfd
, linkerr
, first_time
, msgnum
;
22 char *nmsg
, newmsg
[BUFSIZ
];
26 first_time
= 1; /* this is first attempt */
30 * We might need to make several attempts
31 * in order to add the message to the folder.
35 * Get the message number we will attempt to add.
38 /* should we preserve the numbering of the message? */
39 if (preserve
&& (msgnum
= m_atoi (msgfile
)) > 0) {
41 } else if (mp
->nummsg
== 0) {
42 /* check if we are adding to empty folder */
45 /* else use highest message number + 1 */
46 msgnum
= mp
->hghmsg
+ 1;
50 /* another attempt, so try next higher message number */
55 * See if we need more space. If we need space at the
56 * end, then we allocate space for an addition 100 messages.
57 * If we need space at the beginning of the range, then just
58 * extend message status range to cover this message number.
60 if (msgnum
> mp
->hghoff
) {
61 if ((mp
= folder_realloc (mp
, mp
->lowoff
, msgnum
+ 100)))
64 advise (NULL
, "unable to allocate folder storage");
67 } else if (msgnum
< mp
->lowoff
) {
68 if ((mp
= folder_realloc (mp
, msgnum
, mp
->hghoff
)))
71 advise (NULL
, "unable to allocate folder storage");
77 * If a message is already in that slot,
78 * then loop to next available slot.
80 if (does_exist (mp
, msgnum
))
83 /* setup the bit flags for this message */
84 clear_msg_flags (mp
, msgnum
);
85 set_exists (mp
, msgnum
);
87 /* should we set the SELECT_UNSEEN bit? */
89 set_unseen (mp
, msgnum
);
92 /* should we set the SELECTED bit? */
94 set_selected (mp
, msgnum
);
96 /* check if highest or lowest selected */
97 if (mp
->numsel
== 0) {
101 if (msgnum
< mp
->lowsel
)
103 if (msgnum
> mp
->hghsel
)
107 /* increment number selected */
112 * check if this is highest or lowest message
114 if (mp
->nummsg
== 0) {
118 if (msgnum
< mp
->lowmsg
)
120 if (msgnum
> mp
->hghmsg
)
124 /* increment message count */
127 nmsg
= m_name (msgnum
);
128 snprintf (newmsg
, sizeof(newmsg
), "%s/%s", mp
->foldpath
, nmsg
);
131 * Now try to link message into folder
133 if (link (msgfile
, newmsg
) != -1) {
139 if (linkerr
== EISREMOTE
)
141 #endif /* EISREMOTE */
144 * Check if the file in our desired location is the same
145 * as the source file. If so, then just leave it alone
146 * and return. Otherwise, we will continue the main loop
147 * and try again at another slot (hghmsg+1).
149 if (linkerr
== EEXIST
) {
150 if (stat (msgfile
, &st2
) == 0 && stat (newmsg
, &st1
) == 0
151 && st2
.st_ino
== st1
.st_ino
) {
159 * If link failed because we are trying to link
160 * across devices, then check if there is a message
161 * already in the desired location. If so, then return
162 * error, else just copy the message.
164 if (linkerr
== EXDEV
) {
165 if (stat (newmsg
, &st1
) == 0) {
166 advise (NULL
, "message %s:%s already exists", newmsg
);
169 if ((infd
= open (msgfile
, O_RDONLY
)) == -1) {
170 advise (msgfile
, "unable to open message %s");
174 if ((outfd
= creat (newmsg
, (int) st1
.st_mode
& 0777)) == -1) {
175 advise (newmsg
, "unable to create");
179 cpydata (infd
, outfd
, msgfile
, newmsg
);
187 * Else, some other type of link error,
188 * so just return error.
190 advise (newmsg
, "error linking %s to", msgfile
);