static char rcsid[] = "@(#)$Id: utils.c,v 1.40 2006/04/09 07:37:19 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.40 $ $State: Exp $
*
* Modified by: Kari Hurtta <hurtta+elm@posti.FMI.FI>
* (was hurtta+elm@ozone.FMI.FI)
******************************************************************************
* The Elm Mail System
*
* Copyright (c) 1988-1992 USENET Community Trust
* Copyright (c) 1986,1987 Dave Taylor
*****************************************************************************/
/** Utility routines for ELM
**/
#include "def_elm.h"
#include "s_elm.h"
DEBUG_VAR(Debug,__FILE__,"ELM");
#include <errno.h>
#ifndef ANSI_C
extern int errno;
#endif
void create_new_folders()
{
/* give_dt_estr_as_str adds / to end */
char * folders_val = give_dt_estr_as_str(&folders_e,"maildir");
/* this creates a new folders directory */
(void) mkdir(folders_val, 0700);
(void) elm_chown(folders_val, userid, groupid);
}
void create_new_elmdir()
{
/** this routine is just for allowing new users who don't have the
old elm files to create a new .elm directory **/
char source[SLEN];
elm_sfprintf(source, sizeof source,
FRM("%s/.elm"), home);
(void) mkdir(source, 0700);
(void) elm_chown( source, userid, groupid);
}
/*
* The initialize() procedure sets the "xalloc_fail_handler" vector to
* point here in the event that xmalloc() or friends fail.
*/
/*ARGSUSED*/
void malloc_failed_exit(proc, len)
char *proc;
unsigned len;
{
int LINES, COLUMNS;
menu_get_sizes(default_context, &LINES, &COLUMNS);
MoveCursor(LINES-1,0);
Raw(OFF);
/* NOTE:
Can't use elm_fprintf (or routines of lib/output.c)
because here also malloc may fail, therefore
can not use CATGETS macro;
And can't use catgets because it may have given
incorrent format string from catalog ...
Same problem also with Write_to_screen() on src/curses.c
... perhaps should use WriteRaw() from src/curses.c
*/
FlushBuffer();
fprintf(stderr,"\n\nCouldn't malloc %d bytes!!\n\n", len);
/* SIGDPRINT does not call malloc */
SIGDPRINT(Debug,1, (&Debug, "Couldn't malloc %d bytes!!\n",len));
panic("PANIC",__FILE__,__LINE__,"malloc_failed_exit",
"Out of memory",0);
}
static void leave_cursor P_((int interrupt));
static void leave_cursor(interrupt)
int interrupt;
{
/* MoveCursor() is not safe on interrupt */
if (interrupt) {
ClearScreen(0);
Raw(OFF|RAW_FROM_SIGNAL);
} else {
Raw_OFF(0);
}
}
/* Tjis routine is called by panic() */
void emergency_exit(interrupt)
int interrupt;
{
struct MailboxView *m;
int idx = 0;
/* if interrupt is true we can't call anything which
* is not reentrant
*/
/** used in dramatic cases when we must leave without altering
ANYTHING about the system... **/
int do_cursor = RawState();
/*
* some OS's get extra cont signal, so once this far into the
* exit, ignore those signals (Especially Ultrix)
*/
#ifdef SIGTSTP
signal(SIGTSTP,SIG_IGN);
#endif
#ifdef SIGSTOP
signal(SIGSTOP,SIG_IGN);
#endif
#ifdef SIGCONT
signal(SIGCONT,SIG_IGN);
#endif
if (interrupt)
SIGDPRINT(Debug,1, (&Debug,
"\nLeaving mailer from signal handler (emergency_exit)\n"));
SIGDPRINT(Debug,1, (&Debug,
"\nERROR: Something dreadful is happening! Taking emergency exit!!\n\n"));
SIGDPRINT(Debug,1, (&Debug,
" possibly leaving behind the following files;\n"));
while (NULL != (m = give_next_open_mailbox(&idx,interrupt))) {
int mc = get_storage_count(m);
int i;
for (i = 0; i < mc; i++) {
struct current_storage * storage = get_storage(m,i);
if (storage && storage->current_folder) {
SIGDPRINT(Debug,1, (&Debug,
" The mailbox temp file : %s\n",
storage->current_folder->cur_tempfolder));
}
}
}
SIGDPRINT(Debug,1, (&Debug,
" The composition file : %s\n",
cur_editfile));
/* softkeys_off(); */
/* MoveCursor() is not safe to be called from interrupt */
if (do_cursor)
leave_cursor(interrupt);
/* lib_error is not safe to be called from signal handler */
if (!interrupt)
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmEmergencyExitTaken,
"\nEmergency exit taken! All temp files intact!\n\n"));
else
WriteRaw("\nEmergency exit taken! All temp files intact!\n\n");
#ifdef USE_PGP
/* Don't put passphrase to core file! */
pgp_void_passphrase();
#endif
/* This routine is called by panic() so
DO NOT call panic on here ...
*/
if (interrupt) {
WriteRaw("\nABORTING...\n");
abort();
}
exit(127);
}
void rm_temps_exit()
{
int do_cursor = RawState();
int LINES, COLUMNS;
menu_get_sizes(default_context, &LINES, &COLUMNS);
/*
* some OS's get extra cont signal, so once this far into the
* exit, ignore those signals (Especially Ultrix)
*/
#ifdef SIGTSTP
signal(SIGTSTP,SIG_IGN);
#endif
#ifdef SIGSTOP
signal(SIGSTOP,SIG_IGN);
#endif
#ifdef SIGCONT
signal(SIGCONT,SIG_IGN);
#endif
PutLineX(LINES-1, 0,
CATGETS(elm_msg_cat, ElmSet, ElmWriteFailedExitingIntact,
"\nWrite to temp file failed, exiting leaving mailbox intact!\n\n"));
SIGDPRINT(Debug,1, (&Debug,
"\nrm_temps_exit, deleteing temp files\n"));
/* softkeys_off(); */
if (cur_editfile[0])
unlink(cur_editfile); /* editor buffer */
free_all_mailboxes();
free_all_aliasviews();
#ifdef REMOTE_MBX
close_cached_connections();
#endif
if(do_cursor) {
Raw_OFF(1);
}
exit(1);
}
/*ARGSUSED*/
/*VARARGS0*/
static void mailbox_unlock P_((int interrupt));
static void mailbox_unlock(interrupt)
int interrupt;
{
struct MailboxView *m;
int idx = 0;
while (NULL != (m = give_next_open_mailbox(&idx,interrupt))) {
int mc = get_storage_count(m);
int i;
for (i = 0; i < mc; i++) {
struct current_storage * storage = get_storage(m,i);
if (storage) {
if (storage->current_folder) {
unlock(interrupt, storage->current_folder); /* remove lock file if any */
}
}
}
}
}
static void mailbox_close P_((int interrupt));
static void mailbox_close(interrupt)
int interrupt;
{
mailbox_unlock(interrupt);
if (!interrupt)
free_all_mailboxes();
}
void leave(interrupt)
int interrupt;
{
int do_cursor = RawState();
/* if interrupt is true do not call anything which is not re-entrant */
/*
* some OS's get extra cont signal, so once this far into the
* exit, ignore those signals (Especially Ultrix)
*/
#ifdef SIGTSTP
signal(SIGTSTP,SIG_IGN);
#endif
#ifdef SIGCONT
signal(SIGCONT,SIG_IGN);
#endif
if (interrupt)
SIGDPRINT(Debug,2,
(&Debug,
"\nLeaving mailer from signal handler (leave)\n"));
else {
SIGDPRINT(Debug,2, (&Debug,
"\nLeaving mailer normally (leave)\n"));
}
/* Set terminal title to "Elm: exiting" ... can be called from
signal handler
*/
switch_title(2);
/* softkeys_off(); */
if (cur_editfile[0])
unlink(cur_editfile); /* editor buffer */
mailbox_close(interrupt);
if (!interrupt)
free_all_aliasviews();
#ifdef REMOTE_MBX
if (!interrupt)
close_cached_connections();
#endif
/* MoveCursor() is not safe to be called from interrupt */
if (do_cursor)
leave_cursor(interrupt);
if (!interrupt)
exit(0);
_exit(0);
}
void silently_exit()
{
/** This is the same as 'leave', but it doesn't remove any non-pid
files. It's used when we notice that we're trying to create a
temp mail file and one already exists!!
**/
int do_cursor = RawState();
/*
* some OS's get extra cont signal, so once this far into the
* exit, ignore those signals (Especially Ultrix)
*/
#ifdef SIGTSTP
signal(SIGTSTP,SIG_IGN);
#endif
#ifdef SIGSTOP
signal(SIGSTOP,SIG_IGN);
#endif
#ifdef SIGCONT
signal(SIGCONT,SIG_IGN);
#endif
DPRINT(Debug,2, (&Debug, "\nLeaving mailer quietly (silently_exit)\n"));
/* softkeys_off(); */
if (cur_editfile[0])
unlink(cur_editfile);
if (do_cursor) {
Raw_OFF(1);
}
mailbox_unlock(0);
free_all_aliasviews();
#ifdef REMOTE_MBX
close_cached_connections();
#endif
exit(0);
}
/*ARGSUSED0*/
#ifndef REMOVE_AT_LAST
void leave_locked()
{
struct MailboxView *m;
int idx = 0;
/** same as leave routine, but don't disturb lock file **/
int do_cursor = RawState();
/*
* some OS's get extra cont signal, so once this far into the
* exit, ignore those signals (Especially Ultrix)
*/
#ifdef SIGTSTP
signal(SIGTSTP,SIG_IGN);
#endif
#ifdef SIGSTOP
signal(SIGSTOP,SIG_IGN);
#endif
#ifdef SIGCONT
signal(SIGCONT,SIG_IGN);
#endif
SIGDPRINT(Debug,3, (&Debug,
"\nLeaving mailer due to presence of lock file (leave_locked)\n"));
/* softkeys_off(); */
if (cur_editfile[0])
unlink(cur_editfile); /* editor buffer */
while (NULL != (m = give_next_open_mailbox(&idx,0))) {
int mc = get_storage_count(m);
int i;
for (i = 0; i < mc; i++) {
struct current_storage * storage = get_storage(m,i);
if (storage && storage->current_folder) {
leave_old_folder(& storage->current_folder,CLOSE_LEAVE_LOCKED);
}
}
}
free_all_aliasviews();
#ifdef REMOTE_MBX
close_cached_connections();
#endif
if (do_cursor) {
Raw_OFF(1);
}
exit(0);
}
#endif
void get_page(menu, header_page)
struct menu_common *menu;
struct menu_context *header_page;
{
/** Ensure that 'current' is on the displayed page,**/
int current = mcommon_get_current(menu);
int top = menu_header_get(header_page,header_top_line);
int topO = top;
int j = menu_header_get(header_page,header_current);
/* but what is it on the SCREEN??? */
int msg_pointer = compute_visible(current, menu) -1;
int li,co;
if (j != msg_pointer) {
DPRINT(Debug,5,(&Debug,
"get_page: current %d: header_page current %d => %d\n",
current,j,msg_pointer));
menu_header_change(header_page, header_current,msg_pointer);
}
menu_get_sizes(header_page, &li, &co);
if (msg_pointer >= top+li) {
top = msg_pointer;
DPRINT(Debug,5,(&Debug,
"get_page: current %d: header_page top %d => %d\n",
current,topO,top));
menu_header_change(header_page, header_top_line,top);
}
if (msg_pointer < top) {
top -= li;
if (msg_pointer < top)
top = msg_pointer -2;
if (top < 0)
top = 0;
DPRINT(Debug,5,(&Debug,
"get_page: current %d: header_page top %d => %d\n",
current,topO,top));
menu_header_change(header_page, header_top_line,top);
}
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1