1
#if !defined(lint) && !defined(DOS)
2
static char rcsid[] = "$Id: init.c 101 2006-08-10 22:53:04Z mikes@u.washington.edu $";
6
* ========================================================================
7
* Copyright 2006 University of Washington
9
* Licensed under the Apache License, Version 2.0 (the "License");
10
* you may not use this file except in compliance with the License.
11
* You may obtain a copy of the License at
13
* http://www.apache.org/licenses/LICENSE-2.0
15
* ========================================================================
18
/*======================================================================
21
Session initiation support routines
28
#include "../pith/init.h"
29
#include "../pith/conf.h"
30
#include "../pith/status.h"
31
#include "../pith/folder.h"
32
#include "../pith/context.h"
37
/* these are used to report folder directory creation problems */
38
CONF_TXT_T init_md_exists[] = "The \"%s\" subdirectory already exists, but it is not writable by Alpine so Alpine cannot run. Please correct the permissions and restart Alpine.";
40
CONF_TXT_T init_md_file[] = "Alpine requires a directory called \"%s\" and usualy creates it. You already have a regular file by that name which means Alpine cannot create the directory. Please move or remove it and start Alpine again.";
42
CONF_TXT_T init_md_create[] = "Creating subdirectory \"%s\" where Alpine will store its mail folders.";
48
void display_init_err(char *, int);
49
char *context_string(char *);
50
int prune_folders(CONTEXT_S *, char *, int, char *, unsigned);
51
int prune_move_folder(char *, char *, CONTEXT_S *);
52
void delete_old_mail(struct sm_folder *, CONTEXT_S *, char *);
56
/*----------------------------------------------------------------------
57
Make sure the alpine folders directory exists, with proper folders
59
Args: ps -- alpine structure to get mail directory and contexts from
61
Result: returns 0 if it exists or it is created and all is well
62
1 if it is missing and can't be created.
64
init_mail_dir(struct pine *ps)
67
/* MAIL_LIST: can we use imap4 CREATE? */
69
* We don't really care if mail_dir exists if it isn't
70
* part of the first folder collection specified. If this
71
* is the case, it must have been created external to us, so
74
if(ps->VAR_FOLDER_SPEC && ps->VAR_FOLDER_SPEC[0]){
75
char *p = context_string(ps->VAR_FOLDER_SPEC[0]);
76
int rv = strncmp(p, ps->VAR_MAIL_DIRECTORY,
77
strlen(ps->VAR_MAIL_DIRECTORY));
83
switch(is_writable_dir(ps->folders_dir)){
85
/* --- all is well --- */
89
snprintf(tmp_20k_buf, SIZEOF_20KBUF, init_md_exists, ps->folders_dir);
90
display_init_err(tmp_20k_buf, 1);
94
snprintf(tmp_20k_buf, SIZEOF_20KBUF, init_md_file, ps->folders_dir);
95
display_init_err(tmp_20k_buf, 1);
99
snprintf(tmp_20k_buf, SIZEOF_20KBUF, init_md_create, ps->folders_dir);
100
display_init_err(tmp_20k_buf, 0);
104
if(create_mail_dir(ps->folders_dir) < 0){
105
snprintf(tmp_20k_buf, SIZEOF_20KBUF, "Error creating subdirectory \"%s\" : %s",
106
ps->folders_dir, error_description(errno));
107
display_init_err(tmp_20k_buf, 1);
116
/*----------------------------------------------------------------------
117
Make sure the default save folders exist in the default
121
display_init_err(char *s, int err)
124
mswin_messagebox(s, err);
132
if(++n > 60 && isspace((unsigned char)*s)){
135
while(*(s+1) && isspace((unsigned char)*(s+1)))
147
* Return malloc'd string containing only the context specifier given
148
* a string containing the raw pinerc entry
151
context_string(char *s)
153
CONTEXT_S *t = new_context(s, NULL);
158
* Take what we want from context, then free the rest...
161
t->context = NULL; /* don't free it! */
165
return(rv ? rv : cpystr(""));
170
/*----------------------------------------------------------------------
171
Rename the current sent-mail folder to sent-mail for last month
173
open up sent-mail and get date of very first message
174
if date is last month rename and...
175
if files from 3 months ago exist ask if they should be deleted and...
176
if files from previous months and yes ask about them, too.
177
----------------------------------------------------------------------*/
179
expire_sent_mail(void)
181
int cur_month, ok = 1;
185
CONTEXT_S *prune_cntxt;
187
dprint((5, "==== expire_mail called ====\n"));
189
if(!check_prune_time(&now, &tm_now))
192
cur_month = (1900 + tm_now->tm_year) * 12 + tm_now->tm_mon;
193
dprint((5, "Current month %d\n", cur_month));
196
* locate the default save context...
198
if(!(prune_cntxt = default_save_context(ps_global->context_list)))
199
prune_cntxt = ps_global->context_list;
202
* Since fcc's and read-mail can be an IMAP mailbox, be sure to only
203
* try expiring a list if it's an ambiguous name associated with some
206
* If sentmail set outside a context, then pruning is up to the
210
if(ps_global->VAR_DEFAULT_FCC && *ps_global->VAR_DEFAULT_FCC
211
&& context_isambig(ps_global->VAR_DEFAULT_FCC))
212
ok = prune_folders(prune_cntxt, ps_global->VAR_DEFAULT_FCC,
214
ps_global->pruning_rule);
216
if(ok && ps_global->VAR_READ_MESSAGE_FOLDER
217
&& *ps_global->VAR_READ_MESSAGE_FOLDER
218
&& context_isambig(ps_global->VAR_READ_MESSAGE_FOLDER))
219
ok = prune_folders(prune_cntxt, ps_global->VAR_READ_MESSAGE_FOLDER,
221
ps_global->pruning_rule);
225
* Within the default prune context,
226
* prune back the folders with the given name
228
if(ok && prune_cntxt && (p = ps_global->VAR_PRUNED_FOLDERS))
230
if(**p && context_isambig(*p))
231
ok = prune_folders(prune_cntxt, *p, cur_month, "",
232
ps_global->pruning_rule);
235
* Mark that we're done for this month...
238
ps_global->last_expire_year = tm_now->tm_year;
239
ps_global->last_expire_month = tm_now->tm_mon;
240
snprintf(tmp, sizeof(tmp), "%d.%d", ps_global->last_expire_year,
241
ps_global->last_expire_month + 1);
242
set_variable(V_LAST_TIME_PRUNE_QUESTION, tmp, 1, 1, Main);
249
/*----------------------------------------------------------------------
250
Offer to delete old sent-mail folders
252
Args: sml -- The list of sent-mail folders
256
prune_folders(CONTEXT_S *prune_cntxt, char *folder_base, int cur_month,
257
char *type, unsigned int pr)
259
char path2[MAXPATH+1], prompt[128], tmp[21];
260
char ctmp[MAILTMPLEN];
261
int month_to_use, exists;
262
struct sm_folder *mail_list, *sm;
264
mail_list = get_mail_list(prune_cntxt, folder_base);
265
free_folder_list(prune_cntxt);
268
for(sm = mail_list; sm != NULL && sm->name[0] != '\0'; sm++)
269
dprint((5,"Old sent-mail: %5d %s\n", sm->month_num,
270
sm->name ? sm->name : "?"));
273
for(sm = mail_list; sm != NULL && sm->name[0] != '\0'; sm++)
274
if(sm->month_num == cur_month - 1)
275
break; /* matched a month */
277
month_to_use = (sm == NULL || sm->name[0] == '\0') ? cur_month - 1 : 0;
279
dprint((5, "Month_to_use : %d\n", month_to_use));
281
if(month_to_use == 0 || pr == PRUNE_NO_AND_ASK || pr == PRUNE_NO_AND_NO)
284
strncpy(path2, folder_base, sizeof(path2)-1);
285
path2[sizeof(path2)-1] = '\0';
287
if(F_ON(F_PRUNE_USES_ISO,ps_global)){ /* sent-mail-yyyy-mm */
288
snprintf(path2 + strlen(path2), sizeof(path2)-strlen(path2), "-%04.4d-%02.2d", month_to_use/12,
289
month_to_use % 12 + 1);
292
strncpy(tmp, month_abbrev((month_to_use % 12)+1), 20);
293
tmp[sizeof(tmp)-1] = '\0';
294
lcase((unsigned char *) tmp);
296
if(*prune_cntxt->context != '{'){
300
snprintf(path2 + (size_t)((i > 4) ? 4 : i),
301
sizeof(path2)- ((i > 4) ? 4 : i),
302
"%2.2d%2.2d", (month_to_use % 12) + 1,
303
((month_to_use / 12) - 1900) % 100);
307
snprintf(path2 + strlen(path2), sizeof(path2)-strlen(path2), "-%.20s-%d", tmp, month_to_use/12);
311
snprintf(prompt, sizeof(prompt), "Move current \"%.50s\" to \"%.50s\"", folder_base, path2);
312
if((exists = folder_exists(prune_cntxt, folder_base)) == FEX_ERROR){
313
dprint((5, "prune_folders: Error testing existence\n"));
316
else if(exists == FEX_NOENT){ /* doesn't exist */
317
dprint((5, "prune_folders: nothing to prune <%s %s>\n",
318
prune_cntxt->context ? prune_cntxt->context : "?",
319
folder_base ? folder_base : "?"));
322
else if(!(exists & FEX_ISFILE)
323
|| pr == PRUNE_NO_AND_ASK || pr == PRUNE_NO_AND_NO
324
|| ((pr == PRUNE_ASK_AND_ASK || pr == PRUNE_ASK_AND_NO) &&
325
want_to(prompt, 'n', 0, h_wt_expire, WT_FLUSH_IN) == 'n')){
326
dprint((5, "User declines renaming %s\n",
327
ps_global->VAR_DEFAULT_FCC ? ps_global->VAR_DEFAULT_FCC : "?"));
331
prune_move_folder(folder_base, path2, prune_cntxt);
334
if(pr == PRUNE_ASK_AND_ASK || pr == PRUNE_YES_AND_ASK
335
|| pr == PRUNE_NO_AND_ASK)
336
delete_old_mail(mail_list, prune_cntxt, type);
340
fs_give((void **)&(sm->name));
344
fs_give((void **)&mail_list);
351
/*----------------------------------------------------------------------
352
Offer to delete old sent-mail folders
354
Args: sml -- The list of sent-mail folders
355
fcc_cntxt -- context to delete list of folders in
356
type -- label indicating type of folders being deleted
360
delete_old_mail(struct sm_folder *sml, CONTEXT_S *fcc_cntxt, char *type)
363
struct sm_folder *sm;
365
for(sm = sml; sm != NULL && sm->name[0] != '\0'; sm++){
366
snprintf(prompt, sizeof(prompt),
367
"To save disk space, delete old%.10s mail folder \"%.30s\" ",
369
if(want_to(prompt, 'n', 0, h_wt_delete_old, WT_FLUSH_IN) == 'y'){
371
if(!context_delete(fcc_cntxt, NULL, sm->name)){
372
q_status_message1(SM_ORDER,
373
3, 3, "Error deleting \"%.200s\".", sm->name);
374
dprint((1, "Error context_deleting %s in %s\n",
375
sm->name ? sm->name : "?",
376
(fcc_cntxt && fcc_cntxt->context)
377
? fcc_cntxt->context : "<null>"));
382
if((index = folder_index(sm->name, fcc_cntxt, FI_FOLDER)) >= 0)
383
folder_delete(index, FOLDERS(fcc_cntxt));
386
/* break;*/ /* skip out of the whole thing when he says no */
387
/* Decided to keep asking anyway */