* clear out some warnings by gcc 9.3.1.
[alpine.git] / alpine / newmail.c
blob9a769a6b5fe25af41a96f5ccc47b1173401d83eb
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: newmail.c 1266 2009-07-14 18:39:12Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2013-2020 Eduardo Chappa
8 * Copyright 2009 University of Washington
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
19 #include "../pith/headers.h"
20 #include "../pith/newmail.h"
21 #include "../pith/conf.h"
22 #include "../pith/flag.h"
23 #include "../pith/mailindx.h"
24 #include "../pith/msgno.h"
25 #include "../pith/bldaddr.h"
26 #include "../pith/stream.h"
27 #include "../pith/sort.h"
28 #include "../pith/status.h"
29 #include "../pith/util.h"
30 #include "../pith/thread.h"
31 #include "../pith/options.h"
32 #include "../pith/folder.h"
33 #include "../pith/ablookup.h"
35 #ifdef _WINDOWS
36 #include "../pico/osdep/mswin.h"
37 #endif
41 * Internal prototypes
43 void new_mail_win_mess(MAILSTREAM *, long);
44 void new_mail_mess(MAILSTREAM *, long, long, int);
45 void newmailfifo(int, char *, char *, char *);
48 /*----------------------------------------------------------------------
49 pith optional function to queue a newmail announcement
52 ----*/
53 void
54 newmail_status_message(MAILSTREAM *stream, long n, long t_nm_count)
56 #ifdef _WINDOWS
57 if(mswin_newmailwinon())
58 new_mail_win_mess(stream, t_nm_count);
59 #elif !defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)
60 if(ps_global->VAR_FIFOPATH)
61 new_mail_win_mess(stream, t_nm_count);
62 #endif
63 if(n){
64 new_mail_mess(stream, sp_mail_since_cmd(stream), n, 0);
70 * alert for each new message individually. new_mail_mess lumps
71 * messages together, we call new_mail_mess with 1 message at a time.
72 * This is currently for PC-Pine new mail window, but could probably
73 * be used more generally.
74 * stream - new mail stream
75 * number - number of new messages to alert for
77 void
78 new_mail_win_mess(MAILSTREAM *stream, long int number)
80 int n, i;
81 MESSAGECACHE *mc;
83 if(!stream)
84 return;
86 /*
87 * spare6, or MN_STMP, should be safe to use for now, we
88 * just want to set which messages to alert about before
89 * going to c-client.
91 for(n = stream->nmsgs, i = 0; n > 1L && i < number; n--){
92 if(!get_lflag(stream, NULL, n, MN_EXLD)){
93 mc = mail_elt(stream, n);
94 if(mc)
95 mc->spare6 = 1;
97 if(++i == number)
98 break;
100 else{
101 mc = mail_elt(stream, n);
102 if(mc)
103 mc->spare6 = 0;
107 * Here n is the first new message we want to notify about.
108 * spare6 will tell us which ones to use. We set spare6
109 * in case of new mail or expunge that could happen when
110 * we mail_fetchstructure in new_mail_mess.
112 for(; n <= stream->nmsgs; n++)
113 if(n > 0L && (mc = mail_elt(stream, n)) && mc->spare6){
114 mc->spare6 = 0;
115 new_mail_mess(stream, 1, n, 1);
120 /*----------------------------------------------------------------------
121 Format and queue a "new mail" message
123 Args: stream -- mailstream on which a mail has arrived
124 number -- number of new messages since last command
125 max_num -- The number of messages now on stream
126 for_new_mail_win -- for separate new mail window (curr. PC-Pine)
128 Not too much worry here about the length of the message because the
129 status_message code will fit what it can on the screen and truncation on
130 the right is about what we want which is what will happen.
131 ----*/
132 void
133 new_mail_mess(MAILSTREAM *stream, long int number, long int max_num, int for_new_mail_win)
135 char subject[MAILTMPLEN+1], subjtext[MAILTMPLEN+1], from[MAILTMPLEN+1],
136 *folder = NULL, intro[MAILTMPLEN+1];
137 ENVELOPE *e = NULL;
139 if(stream)
140 e = pine_mail_fetchstructure(stream, max_num, NULL);
142 if(stream){
143 if(sp_flagged(stream, SP_INBOX))
144 folder = NULL;
145 else{
146 folder = STREAMNAME(stream);
147 if(folder[0] == '?' && folder[1] == '\0')
148 folder = NULL;
152 format_new_mail_msg(folder, number, e, intro, from, subject, subjtext, sizeof(subject));
154 if(!for_new_mail_win)
155 q_status_message5(SM_ASYNC | SM_DING, 0, 60,
156 "%s%s%s%.80s%.80s", intro,
157 from && from[0] ? ((number > 1L) ? " Most recent f" : " F") : "",
158 from && from[0] ? "rom " : "",
159 from && from[0] ? from : "",
160 subjtext);
161 #if (!defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)) || defined(_WINDOWS)
162 else {
163 int is_us = 0;
164 ADDRESS *tadr;
166 if(e)
167 for(tadr = e->to; tadr; tadr = tadr->next)
168 if(address_is_us(tadr, ps_global)){
169 is_us = 1;
170 break;
172 #ifdef _WINDOWS
173 mswin_newmailwin(is_us, from, subject, folder);
174 #else
175 newmailfifo(is_us, from, subject, folder);
176 #endif
178 #endif
180 if(pith_opt_icon_text){
181 if(F_ON(F_ENABLE_XTERM_NEWMAIL, ps_global)
182 && F_ON(F_ENABLE_NEWMAIL_SHORT_TEXT, ps_global)){
183 long inbox_nm;
184 if(!sp_flagged(stream, SP_INBOX)
185 && (inbox_nm = sp_mail_since_cmd(sp_inbox_stream()))){
186 snprintf(tmp_20k_buf, SIZEOF_20KBUF, "[%ld, %ld] %s",
187 inbox_nm > 1L ? inbox_nm : 1L,
188 number > 1L ? number: 1L,
189 ps_global->pine_name);
191 else
192 snprintf(tmp_20k_buf, SIZEOF_20KBUF, "[%ld] %s", number > 1L ? number: 1L,
193 ps_global->pine_name);
195 else
196 snprintf(tmp_20k_buf, SIZEOF_20KBUF, "%s%s%s%.80s", intro,
197 from && from[0] ? ((number > 1L) ? " Most recent f" : " F") : "",
198 from && from[0] ? "rom " : "",
199 from && from[0] ? from : "");
201 (*pith_opt_icon_text)(tmp_20k_buf, IT_NEWMAIL);
206 #if !defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)
207 static char *fifoname = NULL;
208 static int fifoopenerrmsg = 0;
209 static int fifofd = -1;
210 static int fifoheader = 0;
212 void
213 init_newmailfifo(char *fname)
215 if(fifoname)
216 close_newmailfifo();
218 if(!(fname && *fname))
219 return;
221 if(!fifoname){
222 if(mkfifo(fname, 0600) == -1){
223 q_status_message2(SM_ORDER,3,3,
224 "Can't create NewMail FIFO \"%s\": %s",
225 fname, error_description(errno));
226 return;
228 else
229 q_status_message1(SM_ORDER,0,3, "NewMail FIFO: \"%s\"", fname);
231 fifoname = cpystr(fname);
236 void
237 close_newmailfifo(void)
239 if(fifoname){
240 if(fifofd >= 0)
241 (void) close(fifofd);
243 if(*fifoname)
244 our_unlink(fifoname);
246 fs_give((void **) &fifoname);
249 fifoheader = 0;
250 fifoname = NULL;
251 fifofd = -1;
252 fifoopenerrmsg = 0;
256 void
257 newmailfifo(int is_us, char *from, char *subject, char *folder)
259 char buf[MAX_SCREEN_COLS+1], buf2[MAX_SCREEN_COLS+1];
260 char buf3[MAX_SCREEN_COLS+1], buf4[MAX_SCREEN_COLS+1];
262 if(!(fifoname && *fifoname)){
263 if(fifoname)
264 close_newmailfifo();
266 return;
269 if(fifofd < 0){
270 fifofd = our_open(fifoname, O_WRONLY | O_NONBLOCK | O_BINARY, 0600);
271 if(fifofd < 0){
272 if(!fifoopenerrmsg){
273 if(errno == ENXIO)
274 q_status_message2(SM_ORDER,0,3, "Nothing reading \"%s\": %s",
275 fifoname, error_description(errno));
276 else
277 q_status_message2(SM_ORDER,0,3, "Can't open \"%s\": %s",
278 fifoname, error_description(errno));
280 fifoopenerrmsg++;
283 return;
287 if(fifofd >= 0){
288 int width;
289 int fromlen, subjlen, foldlen;
291 width = MIN(MAX(20, ps_global->nmw_width), MAX_SCREEN_COLS);
293 foldlen = .18 * width;
294 foldlen = MAX(5, foldlen);
295 fromlen = .28 * width;
296 subjlen = width - 2 - foldlen - fromlen;
298 if(!fifoheader){
299 time_t now;
300 char *tmtxt;
302 now = time((time_t *) 0);
303 tmtxt = ctime(&now);
304 if(!tmtxt)
305 tmtxt = "";
307 snprintf(buf, sizeof(buf), "New Mail window started at %.*s\n",
308 (int) MIN(100, strlen(tmtxt)-1), tmtxt);
309 (void) write(fifofd, buf, strlen(buf));
311 snprintf(buf, sizeof(buf), " %-*s%-*s%-*s\n",
312 fromlen, "From:",
313 subjlen, "Subject:",
314 foldlen, "Folder:");
315 (void) write(fifofd, buf, strlen(buf));
317 snprintf(buf, sizeof(buf), "%-*.*s\n", width, width, repeat_char(width, '-'));
318 (void) write(fifofd, buf, strlen(buf));
320 fifoheader++;
323 snprintf(buf, sizeof(buf), "%s %-*.*s %-*.*s %-*.*s\n", is_us ? "+" : " ",
324 fromlen - 1, fromlen - 1,
325 short_str(from ? from : "", buf2, sizeof(buf2), fromlen-1, EndDots),
326 subjlen - 1, subjlen - 1,
327 short_str(subject ? subject : "(no subject)",
328 buf3, sizeof(buf3), subjlen-1, EndDots),
329 foldlen, foldlen,
330 short_str(folder ? folder : "INBOX", buf4, sizeof(buf4), foldlen, FrontDots));
331 (void) write(fifofd, buf, strlen(buf));
334 #endif