static char rcsid[] = "@(#)$Id: info.c,v 1.11 2006/07/01 08:40:52 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.11 $   $State: Exp $
 *
 *  Author: Kari Hurtta <hurtta+elm@posti.FMI.FI>
 *      or  Kari Hurtta <elm@elmme-mailer.org>
 *****************************************************************************/

#include "def_list.h"
#include "s_me.h"
#include "mailerlib.h"


DEBUG_VAR(Debug,__FILE__,"mail");

struct menu_anon_param {
    struct list_info *list_info;
};


enum { list_info_mp_param,
       list_info_mp_COUNT };


#if ANSI_C
#define S_(x) static x;
#else
#define S_(x)
#endif


S_(subpage_simple_redraw sb_update_list_info_title)
static int sb_update_list_info_title(ptr,list)
     struct menu_context  *ptr;
     struct menu_param *list;
{
    menu_ClearScreen(ptr);

    menu_print_format_center(ptr,0,
			     CATGETS(elm_msg_cat, MeSet, MeListInfoTitle,
				     "List info"));

    return 1;   /* title completed */
}

S_(subpage_simple_redraw sb_update_list_info_menu)
static int sb_update_list_info_menu(ptr,list)
     struct menu_context  *ptr;
     struct menu_param *list;
{
    menu_ClearScreen(ptr);

    menu_print_format_center(ptr,0,
			     CATGETS(elm_msg_cat, MeSet, 
				     MeListInfoMenu1,
				     "Mail to l)ist, list o)wner, or go to i)index"));

    menu_print_format_center(ptr,1,
			     CATGETS(elm_msg_cat, MeSet, 
				     MeListInfoMenu2,
				     "List h)elp, list a)rchive, s)ubscribe or u)nsubscribe list"));


    return 1;   /* title completed */
}

S_(subpage_simple_redraw sb_update_list_info_part)
static int sb_update_list_info_part(ptr,list)
     struct menu_context  *ptr;
     struct menu_param *list;
{

    struct menu_anon_param *A = mp_lookup_anon(list,list_info_mp_param);
    int line = 0;

    int LINES, COLUMNS;

    menu_get_sizes(ptr, &LINES, &COLUMNS);

    menu_ClearScreen(ptr);


    if (A->list_info->list_phrase) {
	menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListName,
					 "List name       : %S"),
		      A->list_info->list_phrase);
	line++;
    }
    if (A->list_info->list_id) {
	menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListID,
					 "List ID         : %s"),
		      A->list_info->list_id);
	line++;
    }

    if (A->list_info->list_post_no) {

	if (line) 
	    line++;

	if (A->list_info->list_post_no_comment) {
	    menu_print_format_center(ptr,line,CATGETS(elm_msg_cat, MeSet, 
					     MeListInfoListNoPostX,
					     "Mailing list do not accept postings (%S)"),
			  A->list_info->list_post_no_comment);
	} else {
	    menu_print_format_center(ptr,line,CATGETS(elm_msg_cat, MeSet, 
						      MeListInfoListNoPost,
						      "Mailing list do not accept postings."));
	}
	line ++;

    }

    if (line) 
	line++;

    if (A->list_info->list_post_len > 0) {
	int i;
	
	for ( i = 0; i < A->list_info->list_post_len; i++) {
	    struct string * X = raw_from_url (A->list_info->list_post[i].url);

	    if (!X)
		X = format_string(FRM("?ERROR?"));

	    if (0 == i) {
		if (A->list_info->list_post[i].comment)
		    menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListPost,
						     "List post       : <%S> (%S)"),
				  X,A->list_info->list_post[i].comment);
		else
		    menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListPost0,
						     "List post       : <%S>"),
				  X);
	    } else {
		if (A->list_info->list_post[i].comment)
		    menu_PutLineX(ptr,line,0,FRM(    "                : <%S> (%S)"),
				  X,A->list_info->list_post[i].comment);
		else
		    menu_PutLineX(ptr,line,0,FRM(    "                : <%S>"),
				  X);
	    }
	    
	    free_string(&X);
	    line++;
	}
    }


    if (A->list_info->list_owner_len > 0) {
	int i;
	
	for ( i = 0; i < A->list_info->list_owner_len; i++) {
	    struct string * X = raw_from_url (A->list_info->list_owner[i].url);

	    if (!X)
		X = format_string(FRM("?ERROR?"));

	    if (0 == i) {
		if (A->list_info->list_owner[i].comment)
		    menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListOwner,
						     "List owner      : <%S> (%S)"),
				  X,A->list_info->list_owner[i].comment);
		else
		    menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListOwner0,
						     "List owner      : <%S>"),
				  X);
	    } else {
		if (A->list_info->list_owner[i].comment)
		    menu_PutLineX(ptr,line,0,FRM(    "                : <%S> (%S)"),
				  X,A->list_info->list_owner[i].comment);
		else
		    menu_PutLineX(ptr,line,0,FRM(    "                : <%S>"),
				  X);
	    }
	    
	    free_string(&X);
	    line++;
	}
    }

    if (A->list_info->list_subscribe_len > 0) {
	int i;
	
	for ( i = 0; i < A->list_info->list_subscribe_len; i++) {
	    struct string * X = raw_from_url (A->list_info->list_subscribe[i].url);

	    if (!X)
		X = format_string(FRM("?ERROR?"));

	    if (0 == i) {
		if (A->list_info->list_subscribe[i].comment)
		    menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListSubscribe,
						     "List subscribe  : <%S> (%S)"),
				  X,A->list_info->list_subscribe[i].comment);
		else
		    menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListSubscribe0,
						     "List subscribe  : <%S>"),
				  X);
	    } else {
		if (A->list_info->list_subscribe[i].comment)
		    menu_PutLineX(ptr,line,0,FRM(    "                : <%S> (%S)"),
				  X,A->list_info->list_subscribe[i].comment);
		else
		    menu_PutLineX(ptr,line,0,FRM(    "                : <%S>"),
				  X);
	    }
	    
	    free_string(&X);
	    line++;
	}
    }

    if (A->list_info->list_unsubscribe_len > 0) {
	int i;
	
	for ( i = 0; i < A->list_info->list_unsubscribe_len; i++) {
	    struct string * X = raw_from_url (A->list_info->list_unsubscribe[i].url);

	    if (!X)
		X = format_string(FRM("?ERROR?"));

	    if (0 == i) {
		if (A->list_info->list_unsubscribe[i].comment)
		    menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListUnsubscribe,
						     "List unsubscribe: <%S> (%S)"),
				  X,A->list_info->list_unsubscribe[i].comment);
		else
		    menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListUnsubscribe0,
						     "List unsubscribe: <%S>"),
				  X);
	    } else {
		if (A->list_info->list_unsubscribe[i].comment)
		    menu_PutLineX(ptr,line,0,FRM(    "                : <%S> (%S)"),
				  X,A->list_info->list_unsubscribe[i].comment);
		else
		    menu_PutLineX(ptr,line,0,FRM(    "                : <%S>"),
				  X);
	    }
	    
	    free_string(&X);
	    line++;
	}
    }

    if (A->list_info->list_help_len > 0) {
	int i;
	
	for ( i = 0; i < A->list_info->list_help_len; i++) {
	    struct string * X = raw_from_url (A->list_info->list_help[i].url);

	    if (!X)
		X = format_string(FRM("?ERROR?"));

	    if (0 == i) {
		if (A->list_info->list_help[i].comment)
		    menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListHelp,
						     "List help       : <%S> (%S)"),
				  X,A->list_info->list_help[i].comment);
		else
		    menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListHelp0,
						     "List help       : <%S>"),
				  X);
	    } else {
		if (A->list_info->list_help[i].comment)
		    menu_PutLineX(ptr,line,0,FRM(    "                : <%S> (%S)"),
				  X,A->list_info->list_help[i].comment);
		else
		    menu_PutLineX(ptr,line,0,FRM(    "                : <%S>"),
				  X);
	    }
	    
	    free_string(&X);
	    line++;
	}
    }

    if (A->list_info->list_archive_len > 0) {
	int i;
	
	for ( i = 0; i < A->list_info->list_archive_len; i++) {
	    struct string * X = raw_from_url (A->list_info->list_archive[i].url);

	    if (!X)
		X = format_string(FRM("?ERROR?"));

	    if (0 == i) {
		if (A->list_info->list_archive[i].comment)
		    menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListArchive,
						     "List archive    : <%S> (%S)"),
				  X,A->list_info->list_archive[i].comment);
		else
		    menu_PutLineX(ptr,line,0,CATGETS(elm_msg_cat, MeSet, MeListInfoListArchive0,
						     "List archive    : <%S>"),
				  X);
	    } else {
		if (A->list_info->list_archive[i].comment)
		    menu_PutLineX(ptr,line,0,FRM(    "                : <%S> (%S)"),
				  X,A->list_info->list_archive[i].comment);
		else
		    menu_PutLineX(ptr,line,0,FRM(    "                : <%S>"),
				  X);
	    }
	    
	    free_string(&X);
	    line++;
	}
    }

    return 1;   /* info completed */
}





static void set_list_info_screen P_((struct menu_context  *page, 
				  struct screen_parts *LOC,
				  struct menu_param  *LIST));
static void set_list_info_screen(page,LOC, LIST)
     struct menu_context  *page;
     struct screen_parts *LOC;
     struct menu_param  *LIST;    
{    
    int   LINES, COLUMNS;	

    menu_get_sizes(page,&LINES, &COLUMNS);

    /* Title part */

    if (! LOC->title_page)
	LOC->title_page = new_menu_subpage(page,0,2,sb_update_list_info_title,
					   LIST);
    else
	menu_subpage_relocate(LOC->title_page,page,0,2);

    /* Info part */

    if (! LOC->header_page)
	LOC->header_page = new_menu_subpage(page,2,LINES-8,
					    sb_update_list_info_part,LIST);
    else
	menu_subpage_relocate(LOC->header_page,page,2,LINES-8);

    /* Menu part */

    if (LOC->menu_page)
	menu_subpage_relocate(LOC->menu_page,page,LINES-6,2);
    else 
	LOC->menu_page = new_menu_subpage(page,LINES-6,2,
					  sb_update_list_info_menu,LIST);
  
    /* Prompt part */

    if (LOC->prompt_page)
	menu_subpage_relocate(LOC->prompt_page,page,LINES-4,4);
    else 
	LOC->prompt_page = new_menu_subpage(page,LINES-4,4,
					    subpage_simple_noredraw,LIST);
}

static void check_list_info_screen P_((struct screen_parts *LOC,
				   struct menu_param *list));
static void check_list_info_screen(LOC,list)
     struct screen_parts *LOC;
     struct menu_param *list;
{
    /* Title area */

    if (menu_resized(LOC->title_page)) {
	DPRINT(Debug,1, (&Debug, "title page resized\n"));

    }
    if (menu_need_redraw(LOC->title_page)) {
	DPRINT(Debug,1, (&Debug, "title page redraw???\n"));
	sb_update_list_info_title(LOC->title_page,list);
    }

    /* Menu area */

    if (menu_resized(LOC->menu_page)) {
	DPRINT(Debug,1, (&Debug, "menu page resized\n"));
	
    }
    if (menu_need_redraw(LOC->menu_page)) {
	DPRINT(Debug,1, (&Debug, "menu page redraw\n"));
	sb_update_list_info_menu(LOC->menu_page,list);
    }

    /* Prompt area */
    if (menu_resized(LOC->prompt_page)) {
	DPRINT(Debug,1, (&Debug, "prompt page resized\n"));
    }
    if (menu_need_redraw(LOC->prompt_page)) {
	DPRINT(Debug,7, (&Debug, "prompt page redraw\n"));
	menu_ClearScreen(LOC->prompt_page);

	show_last_error();	/* for those operations that have to
				 * clear the footer except for a message.
				 */
    }

    if (menu_resized(LOC->header_page)) {
	DPRINT(Debug,1, (&Debug, "header page resized\n"));

	menu_trigger_redraw(LOC->header_page);
    }

    if (menu_need_redraw(LOC->header_page)) {

	DPRINT(Debug,7, (&Debug, "info page redraw\n"));

	sb_update_list_info_part(LOC->header_page,list);
    }
}

/* ------------------------------------------------------------------------- */

/* May not be 
      uin16 port
   because this is promoted to int
*/

int verify_remote_url(url,user,host,anon_passwd,port,default_port)
     CONST struct url *url;
     CONST struct string  * user;
     CONST struct string  * host;
     struct string  ** anon_passwd;  /* prompt for 'anon password' */
     int port;
     int default_port;
{
    struct menu_context * page = new_menu_context();
    int redraw = 1;
    int li,co;
    int prompt_line, prompt_col = 0;
    int ret = 0;

    menu_get_sizes(page,&li,&co);

    prompt_line = li-5;

    do {
	int defans = *def_ans_yes;
	int ch = '\0';

	if (anon_passwd && !*anon_passwd)
	    defans = 'C';
	else if (port && port != default_port)
	    defans = *def_ans_no;

    resize_mark:
	if (menu_resized(page)) {
	    menu_get_sizes(page,&li,&co);
	    redraw = 1;

	    prompt_line = li-5;
	}
	
	if (menu_need_redraw(page) ||    
	    redraw) {
	    
	    struct string * url_text = NULL;
	    int Y = 6;

	    redraw = 0;

	    menu_ClearScreen(page);

	    menu_print_format_center(page,0,
				     CATGETS(elm_msg_cat,
					     MeSet, MeRemoteUrlVerification,
					     "Remote URL verification"));
	    
	    url_text = raw_from_url(url);

	    if (url_text) {

		menu_PutLineX(page,2,0,CATGETS(elm_msg_cat,
					       MeSet, MeRemoteUrlText,
					       "Remote URL: %S"),
			      url_text);


		free_string(&url_text);
	    }


	    menu_PutLineX(page,4,0,CATGETS(elm_msg_cat,
					   MeSet, MeRemoteUrlRef,
					   "This URL refer to remote resource. Please confirm connection to resource."));


	    if (user) {
		menu_PutLineX(page,Y,0,CATGETS(elm_msg_cat,
					       MeSet, MeRemoteUrlUser,
					       "User:          %S"),
			      user);
		Y++;
	    }
	    if (host) {
		menu_PutLineX(page,Y,0,CATGETS(elm_msg_cat,
					       MeSet, MeRemoteUrlHost,
					       "Host:          %S"),
			      host);
		Y++;
	    }
	    if (port) {
		menu_PutLineX(page,Y,0,CATGETS(elm_msg_cat,
					       MeSet, MeRemoteUrlPort,
					       "Port:          %d"),
			      port);
		Y++;
	    }


	    if (port & port != default_port) {
		Y++;

		menu_PutLineX(page,Y,0,CATGETS(elm_msg_cat,
					       MeSet, MeRemoteUrlWarningPort,
					       "WARNING: Resource port %d differs from default port (%d) for resource."),
			      port,default_port);
		Y++;

	    }

	    if (anon_passwd) {
		Y++;
		menu_PutLineX(page,Y,0,CATGETS(elm_msg_cat,
					       MeSet, MeRemoteUrlAnonymous,
					       "Connection uses anonymous account. Please you email address as password."));
		Y += 2;

		if (*anon_passwd) {
		    menu_PutLineX(page,Y,0,CATGETS(elm_msg_cat,
						   MeSet, MeRemoteUrlAnonPasswd,
						   "Anonymous passwd: %S"),
						   *anon_passwd);
		} else {
		    menu_PutLineX(page,Y,0,CATGETS(elm_msg_cat,
						   MeSet, MeRemoteUrlAnonPasswdNone,
						   "Anonymous passwd: <not specified>"));		    
		}
		Y++;

	    }

	    if (anon_passwd) 
		menu_PutLineX(page,prompt_line,0,CATGETS(elm_msg_cat,
							 MeSet, MeRemoteUrlPromptChange,
							 "Connect to remote URL ? (%c/%c/[C]hange passwd) "),
			      *def_ans_yes, *def_ans_no);
	    else		
		menu_PutLineX(page,prompt_line,0,CATGETS(elm_msg_cat,
							 MeSet, MeRemoteUrlPrompt,
							 "Connect to remote URL ? (%c/%c) "),
			      *def_ans_yes, *def_ans_no);
	    
	    
	    menu_GetXYLocation(page,
			       &prompt_line,&prompt_col);
	    
	    
	}


	menu_MoveCursor(page,prompt_line,prompt_col);
	menu_CleartoEOLN(page);   /* Clear current answer */
	
	menu_Write_to_screen(page,
			     FRM("%c%c"),defans,BACKSPACE);
	FlushBuffer();

		
	ch = menu_ReadCh(page,REDRAW_MARK|READCH_CURSOR|
			 READCH_resize|READCH_sig_char);
	
	if (ch == '\n') 
	    ch = defans;
		
	switch (ch) {
	    int code;

	case TERMCH_interrupt_char:	
	    ret = 0;
	    goto failure;

	case RESIZE_MARK:
	    
	    DPRINT(Debug,4, (&Debug,"    .... resizing\n"));
	    goto resize_mark;
	    
	case REDRAW_MARK:
	    DPRINT(Debug,4, (&Debug,"    .... redrawing\n"));

	    redraw = 1;
	    break;

	case 'C':

	    menu_Write_to_screen(page,CATGETS(elm_msg_cat, MeSet, 
					      MeRemoteUrlChangePasswd,
					      "Change password"));

	    menu_MoveCursor(page,prompt_line+1,0);
	    menu_CleartoEOS(page);

	    code = optionally_enter2(page,
				     anon_passwd, prompt_line+1, 0,
				     OE_REDRAW_MARK
				     |OE_SIG_CHAR /* Ctrl-C */,
				     CATGETS(elm_msg_cat, MeSet, 
					     MeRemoteUrlAnonPasswdPrompt,
					     "Anonymous passwd: "));
	    redraw = 1;
	    break;

	default:

	    
	    if(ch == *def_ans_yes) {
		menu_Write_to_screen(page,CATGETS(elm_msg_cat, MeSet, 
						  MeYesWord, "Yes."));
		ret = 1;
		
		FlushBuffer();
#if POLL_METHOD
		wait_for_timeout(1);
#else
		sleep(1);
#endif

		goto done;
	    } else if (ch == *def_ans_no) {
		menu_Write_to_screen(page,CATGETS(elm_msg_cat, MeSet, 
						  MeNoWord, "No."));
		ret = 0;
		
		FlushBuffer();
#if POLL_METHOD
		wait_for_timeout(1);
#else
		sleep(1);
#endif
		goto done;
	    }
	    
	    menu_Writechar(page,'?');
	    FlushBuffer();
#if POLL_METHOD
	    wait_for_timeout(1);
#else
	    sleep(1);
#endif
	    break;
	}
    } while(1);
    
 failure:
 done:
    erase_menu_context(&page);


    return ret;
}


/* Return 'i' if must go to index */
static int visit_on_url_mailbox P_((struct menu_context  *page,
				    struct menu_context *prompt_area,
				    struct MailboxView *mailbox,
				    const struct url *url,
				    struct AliasView   *aview));
				   

static int visit_on_url_mailbox(page,prompt_area,mailbox,url,aview) 
     struct menu_context  *page;
     struct menu_context *prompt_area;
     struct MailboxView *mailbox;
     CONST struct url *url;
     struct AliasView   *aview;
{
    struct folder_info *folder = get_folder_from_url(url,verify_remote_url);
    struct MailboxView *main_mailbox = NULL;
    int retch = '\0';

    /* Force default to current page --- 
       verify_remote_url may have changed page ... */

    menu_set_default(page); 

    if (!folder)
	return retch;


    /* folder is set to NULL, if it is not needed
       to free

       read in the folder! 
    */
    main_mailbox = enter_mailbox(&folder,page);

    if (!main_mailbox)
	goto fail;
    
    retch = visit_mailbox_loop(main_mailbox,aview);
    menu_set_default(page); 

 fail:
    if (folder)
	leave_old_folder(&folder,CLOSE_NORMAL);

    if (main_mailbox)
	free_mailbox(&main_mailbox);

    return retch;
}


static void mail_to_url_mailing P_((struct menu_context  *page,
				   struct menu_context *prompt_area,
				   struct MailboxView *mailbox,
				   const struct url *url,
				   struct AliasView   *aview,
				   int edit, int ask_send));

static void mail_to_url_mailing(page,prompt_area,mailbox,url,aview, 
			       edit,ask_send)
     struct menu_context  *page;
     struct menu_context *prompt_area;
     struct MailboxView *mailbox;
     CONST struct url *url;
     struct AliasView   *aview;
     int edit;
     int ask_send;
{
    struct mailer_info *mailer_info   = get_mailer_info();
    struct mailing_headers headers;
    int r = 0;
    struct text_block *body = NULL;
    int errors = 0;

    zero_mailing_headers(&headers);
    
    if (!mailer_info) {
        DPRINT(Debug,5,(&Debug, 
			"mail_to_url_mailing: No mailer_info\n"));
	return;
    }

    body = give_text_body_from_url(url,mime_body_keywords,&errors);
    if (errors)
	goto fail;


    r = set_mailing_headers_from_url(&headers,url,mailer_info);
    if (!r) {
	DPRINT(Debug,5,(&Debug, 
			"mail_to_url_mailing: set_mailing_headers_from_url failed!\n"));
	goto fail;
    }

    r = send_msg_middle2(&headers,0,
			 (edit ? MAIL_EDIT_MSG : 0) |
			 (ask_send ? MAIL_ASK_SEND : 0),
			 NO,mailer_info,mailbox,aview,
			 page,prompt_area,body);
    
    if (!r) {
	DPRINT(Debug,5,(&Debug, 
			"mail_to_url_mailing: send_msg_middle2 failed!\n"));
	goto fail;
    }
    
 fail:
    if (body)
	free_block(&body);

    free_mailing_headers(&headers);
    free_mailer_info(&mailer_info);
}

/* Return 'i' if must go to index */
static int visit_to_url P_((struct menu_context  *page,
			   struct menu_context *prompt_area,
			   struct MailboxView *mailbox,
			   const struct url *url,
			   struct AliasView   *aview,
			   int edit));

static int visit_to_url(page,prompt_area,mailbox,url,aview, edit)
     struct menu_context  *page;
     struct menu_context *prompt_area;
     struct MailboxView *mailbox;
     CONST struct url *url;
     struct AliasView   *aview;
     int edit;
{
    int retch = '\0';
    enum url_type T = get_url_type(url);

    struct string *url_text = raw_from_url(url);

    switch (T) {
    case url_unknown:
    case url_mailbox_list:

	if (url_text)
	    lib_error(CATGETS(elm_msg_cat, MeSet, 
			      MeUnknownUrlVisit,
			      "Unsupported URL type. Can not visit on %S"),
		      url_text);
	goto failure;

    case url_mailbox:

	retch = visit_on_url_mailbox(page,prompt_area,mailbox,url,aview);
	
	break;

    case url_mailing: 
	
	mail_to_url_mailing(page,prompt_area,mailbox,url,aview,edit,
			    1);
	break;
    }

 failure:

    if (url_text)
	free_string(& (url_text));

    return retch;
}


static void mail_to_url P_((struct menu_context  *page,
			   struct menu_context *prompt_area,
			   struct MailboxView *mailbox,
			   const struct url *url,
			   struct AliasView   *aview));

static void mail_to_url(page,prompt_area,mailbox,url,aview)
     struct menu_context  *page;
     struct menu_context *prompt_area;
     struct MailboxView *mailbox;
     CONST struct url *url;
     struct AliasView   *aview;
{
    enum url_type T = get_url_type(url);

    struct string *url_text = raw_from_url(url);

    switch (T) {
    case url_unknown:
    case url_mailbox_list:
    case url_mailbox:

	if (url_text)
	    lib_error(CATGETS(elm_msg_cat, MeSet, 
			      MeUnknownUrlMail,
			      "Unsupported URL type. Can not mail to %S"),
		      url_text);
	goto failure;

    case url_mailing: 
	
	mail_to_url_mailing(page,prompt_area,mailbox,url,aview,1,0);
	break;
    }

 failure:

    if (url_text)
	free_string(& (url_text));
}



/* ------------------------------------------------------------------------- */

#if ANSI_C
static subpage_simple_redraw sb_update_title_list_post_selection1;
#endif
static int sb_update_title_list_post_selection1(ptr,list)
     struct menu_context  *ptr;
     struct menu_param *list;
{
    menu_ClearScreen(ptr);

    menu_print_format_center(ptr,0,
			     CATGETS(elm_msg_cat, MeSet, 
				     MeListInfoTitleListPost,
				     "List-Post selection for mailing"));

    return 1;   /* title completed */
}


static void mail_to_list P_((struct list_info *list_info,
			     struct MailboxView *mailbox,
			     struct AliasView   *aview,
			     struct menu_context *page,
			     struct menu_context  *prompt_area));
static void mail_to_list(list_info,mailbox,
			  aview,page,prompt_area)
     struct list_info *list_info;
     struct MailboxView *mailbox;
     struct AliasView   *aview;
     struct menu_context  *page;
     struct menu_context  *prompt_area;
{
    CONST struct url * url = NULL;


    if (list_info->list_post_no) {
	lib_error(CATGETS(elm_msg_cat, MeSet,
			  MeGenericReplyNoPosting,		       
			  "Mailing list do not accept postings!"));
	return;
    }

    if (list_info->list_post_len < 1) {
	lib_error(CATGETS(elm_msg_cat, MeSet,
			  MeGenericReplyNoListPost,		       
			  "No information for posting to list."));
	return;
    }

    url = select_post_url(list_info->list_post, list_info->list_post_len,
			  page,sb_update_title_list_post_selection1);
    if (!url)
	return;

    mail_to_url(page,prompt_area,mailbox,url,aview);
}

#if ANSI_C
static subpage_simple_redraw sb_update_title_list_owner_selection1;
#endif
static int sb_update_title_list_owner_selection1(ptr,list)
     struct menu_context  *ptr;
     struct menu_param *list;
{
    menu_ClearScreen(ptr);

    menu_print_format_center(ptr,0,
			     CATGETS(elm_msg_cat, MeSet, 
				     MeListInfoTitleListOwner,
				     "List-Owner selection for mailing"));

    return 1;   /* title completed */
}


static void mail_to_list_owner P_((struct list_info *list_info,
				   struct MailboxView *mailbox,
				   struct AliasView   *aview,
				   struct menu_context *page,
				   struct menu_context  *prompt_area));
static void mail_to_list_owner(list_info,mailbox,
			       aview,page,prompt_area)
     struct list_info *list_info;
     struct MailboxView *mailbox;
     struct AliasView   *aview;
     struct menu_context  *page;
     struct menu_context  *prompt_area;
{
    CONST struct url * url = NULL;

    if (list_info->list_owner_len < 1) {
	lib_error(CATGETS(elm_msg_cat, MeSet,
			  MeGenericReplyNoListOwner,		       
			   "No information for posting to list owner."));
	return;

    }

    url = select_post_url(list_info->list_owner, list_info->list_owner_len,
			  page,sb_update_title_list_owner_selection1);
    if (!url)
	return;

    mail_to_url(page,prompt_area,mailbox,url,aview);
}


#if ANSI_C
static subpage_simple_redraw sb_update_title_list_help_selection1;
#endif
static int sb_update_title_list_help_selection1(ptr,list)
     struct menu_context  *ptr;
     struct menu_param *list;
{
    menu_ClearScreen(ptr);

    menu_print_format_center(ptr,0,
			     CATGETS(elm_msg_cat, MeSet, 
				     MeListInfoTitleListHelp,
				     "List-Help selection"));

    return 1;   /* title completed */
}


/* Return 'i' if must go to index */
static int list_help P_((struct list_info *list_info,
			  struct MailboxView *mailbox,
			  struct AliasView   *aview,
			  struct menu_context *page,
			  struct menu_context  *prompt_area));
static int list_help(list_info,mailbox,
		      aview,page,prompt_area)
     struct list_info *list_info;
     struct MailboxView *mailbox;
     struct AliasView   *aview;
     struct menu_context  *page;
     struct menu_context  *prompt_area;
{
    int retch = '\0';
    CONST struct url * url = NULL;

    if (list_info->list_help_len < 1) {
	lib_error(CATGETS(elm_msg_cat, MeSet,
			  MeListInfoNoListHelp,		       
			   "No information for list help."));
	return retch;

    }

    url = select_post_url(list_info->list_help, list_info->list_help_len,
			  page,sb_update_title_list_help_selection1);
    if (!url)
	return retch;

    retch = visit_to_url(page,prompt_area,mailbox,url,aview,0);

    return retch;
}

#if ANSI_C
static subpage_simple_redraw sb_update_title_list_archive_selection1;
#endif
static int sb_update_title_list_archive_selection1(ptr,list)
     struct menu_context  *ptr;
     struct menu_param *list;
{
    menu_ClearScreen(ptr);

    menu_print_format_center(ptr,0,
			     CATGETS(elm_msg_cat, MeSet, 
				     MeListInfoTitleListArchive,
				     "List-Archive selection"));

    return 1;   /* title completed */
}


/* Return 'i' if must go to index */
static int list_archive P_((struct list_info *list_info,
			     struct MailboxView *mailbox,
			     struct AliasView   *aview,
			     struct menu_context *page,
			     struct menu_context  *prompt_area));
static int list_archive(list_info,mailbox,
			 aview,page,prompt_area)
     struct list_info *list_info;
     struct MailboxView *mailbox;
     struct AliasView   *aview;
     struct menu_context  *page;
     struct menu_context  *prompt_area;
{
    int retch = '\0';
    CONST struct url * url = NULL;

    if (list_info->list_archive_len < 1) {
	lib_error(CATGETS(elm_msg_cat, MeSet,
			  MeListInfoNoListArchive,		       
			   "No information for list archive."));
	return retch;

    }

    url = select_post_url(list_info->list_archive, list_info->list_archive_len,
			  page,sb_update_title_list_archive_selection1);
    if (!url)
	return retch;

    retch = visit_to_url(page,prompt_area,mailbox,url,aview,0);

    return retch;
}

#if ANSI_C
static subpage_simple_redraw sb_update_title_list_subscribe_selection1;
#endif
static int sb_update_title_list_subscribe_selection1(ptr,list)
     struct menu_context  *ptr;
     struct menu_param *list;
{
    menu_ClearScreen(ptr);

    menu_print_format_center(ptr,0,
			     CATGETS(elm_msg_cat, MeSet, 
				     MeListInfoTitleListSubscribe,
				     "List-Subscribe selection"));

    return 1;   /* title completed */
}


/* Return 'i' if must go to index */
static int list_subscribe P_((struct list_info *list_info,
			       struct MailboxView *mailbox,
			       struct AliasView   *aview,
			       struct menu_context *page,
			       struct menu_context  *prompt_area));
static int list_subscribe(list_info,mailbox,
			   aview,page,prompt_area)
     struct list_info *list_info;
     struct MailboxView *mailbox;
     struct AliasView   *aview;
     struct menu_context  *page;
     struct menu_context  *prompt_area;
{
    int retch = '\0';

    CONST struct url * url = NULL;

    if (list_info->list_subscribe_len < 1) {
	lib_error(CATGETS(elm_msg_cat, MeSet,
			  MeListInfoNoListSubscribe,		       
			   "No information for list subscribe."));
	return retch;

    }

    url = select_post_url(list_info->list_subscribe, 
			  list_info->list_subscribe_len,
			  page,sb_update_title_list_subscribe_selection1);
    if (!url)
	return retch;

    retch = visit_to_url(page,prompt_area,mailbox,url,aview,0);

    return retch;
}

#if ANSI_C
static subpage_simple_redraw sb_update_title_list_unsubscribe_selection1;
#endif
static int sb_update_title_list_unsubscribe_selection1(ptr,list)
     struct menu_context  *ptr;
     struct menu_param *list;
{
    menu_ClearScreen(ptr);

    menu_print_format_center(ptr,0,
			     CATGETS(elm_msg_cat, MeSet, 
				     MeListInfoTitleListUnsubscribe,
				     "List-Unsubscribe selection"));

    return 1;   /* title completed */
}

/* Return 'i' if must go to index */
static int list_unsubscribe P_((struct list_info *list_info,
				 struct MailboxView *mailbox,
				 struct AliasView   *aview,
				 struct menu_context *page,
				 struct menu_context  *prompt_area));
static int list_unsubscribe(list_info,mailbox,
			   aview,page,prompt_area)
     struct list_info *list_info;
     struct MailboxView *mailbox;
     struct AliasView   *aview;
     struct menu_context  *page;
     struct menu_context  *prompt_area;
{
    int retch = '\0';
    CONST struct url * url = NULL;

    if (list_info->list_unsubscribe_len < 1) {
	lib_error(CATGETS(elm_msg_cat, MeSet,
			  MeListInfoNoListUnsubscribe,		       
			   "No information for list unsubscribe."));
	return retch;

    }

    url = select_post_url(list_info->list_unsubscribe, 
			  list_info->list_unsubscribe_len,
			  page,sb_update_title_list_unsubscribe_selection1);
    if (!url)
	return retch;

    retch = visit_to_url(page,prompt_area,mailbox,url,aview,0);

    return retch;
}



/* Returns 'i' if should go index */
int list_info(index,mailbox,aview,parent_page,old_prompt)
     int index;
     struct MailboxView *mailbox;
     struct AliasView   *aview;
     struct menu_context  *parent_page;
     struct menu_context  *old_prompt;
{
    struct header_rec * current_header = give_header(mailbox,index);
    int ch;
    int retch = 0;
    int update = 0;

    int screen_initialized = 0;

    struct menu_anon_param A;
    struct menu_context *page = NULL;
    struct screen_parts  LOC  = { NULL, NULL, NULL, NULL };
    struct menu_param  PARAM[list_info_mp_COUNT+1] = { 
	{ mp_anon_param,0 },
	{ mp_END,0 }
    };

    struct menu_context  *this_page    = NULL;
    struct menu_context  *this_prompt  = NULL;


    if (!current_header) {

	return 0;
    }


    if (! current_header->list_info) {

	lib_error(CATGETS(elm_msg_cat, MeSet,
			  MeGenericReplyNotAList,		       
			  "Mailing list information is not a available."));

	return 0; 
    }

    A.list_info      = current_header->list_info;

    mp_list_set_anon(PARAM,list_info_mp_param,&A);


    /* Make possible type two character commands without printing
       of info screen .. this waits a second for command
    */
    if (old_prompt) {
	int lin,col;
	this_page    = parent_page;
	this_prompt  = old_prompt;

	menu_Write_to_screen(old_prompt,FRM(": "));
	menu_GetXYLocation(old_prompt,&lin,&col);
	menu_CleartoEOS(old_prompt); 
	show_last_error();
	menu_MoveCursor(old_prompt,lin,col);
	
	ch = menu_ReadCh(old_prompt, 
			 REDRAW_MARK|READCH_CURSOR|READCH_resize|
			 READCH_sig_char|READCH_poll);

	if (ch == EOF ||
	    ch == TERMCH_interrupt_char)
	    goto OUT;
	if (ch != TIMEOUT_MARK)
	    goto peek_key;

    }


    for (;;) {

	if (! screen_initialized) {

	    page = new_menu_context();
	    set_list_info_screen(page,&LOC,PARAM);

	    this_page    = page;
	    this_prompt  = LOC.prompt_page;

	    screen_initialized = 1;
	}

	if (menu_resized(page)) {
	    set_list_info_screen(page,&LOC,PARAM);
	    update = 1;
	}

	if (update || menu_need_redraw(page)) {
	    menu_ClearScreen(page);

	    /* Call refresh routines of children */
	    menu_redraw_children(page);
	    	    
	    update = 0;
	    show_last_error(); 
	} 


	check_list_info_screen(&LOC,PARAM);

	{
	    int lin,col;
	    
	    menu_ClearLine(LOC.prompt_page,0);
	    
 	    menu_PutLineX (LOC.prompt_page,0, 0, 
			   CATGETS(elm_msg_cat, MeSet, MeListInfoPrompt,
				   "List info: "));
	    menu_GetXYLocation(LOC.prompt_page,&lin,&col);
	    
	    menu_CleartoEOS(LOC.prompt_page);   
	    
	    show_last_error();
	    menu_MoveCursor(LOC.prompt_page,lin,col);
	    
	    ch = menu_ReadCh(LOC.prompt_page, 
			     REDRAW_MARK|READCH_CURSOR|READCH_resize|
			     READCH_sig_char);
	    
	    menu_CleartoEOS(LOC.prompt_page);
	    set_error("");	/* clear error buffer */
	}

    peek_key:
	switch (ch) {

	case RESIZE_MARK:
	    DPRINT(Debug,4, (&Debug, " ... resizing\n"));
	    
	    continue;
	    
	case ctrl('L'):
	case REDRAW_MARK:
	    DPRINT(Debug,4, (&Debug, " ... redrawing\n"));

	    menu_ClearScreen(this_page);   /* Clear possible redraw mark */
	    
	    /* Call refresh routines of children */
	    menu_redraw_children(this_page);
	    
	    if (menu_need_redraw(this_prompt))		    
		menu_ClearScreen(this_prompt);   /* Clear redraw mark from prompt_area*/
	    

	    update = 1;
	    continue;

	case ctrl('J'):
	case ctrl('M'):
	    goto OUT;


	case 'l':
	    menu_Write_to_screen(this_prompt,
				 CATGETS(elm_msg_cat, MeSet,
					 MeListInfoMailToList,
					 "Mail to list"));
	    FlushBuffer();

	    mail_to_list(current_header->list_info,mailbox,aview,
			 this_page,this_prompt);
	    goto OUT;

	case 'o':
	    menu_Write_to_screen(this_prompt,
				 CATGETS(elm_msg_cat, MeSet,
					 MeListInfoMailToListOwner,
					 "Mail to list owner"));
	    FlushBuffer();

	    mail_to_list_owner(current_header->list_info,mailbox,aview,
			       this_page,this_prompt);
	    goto OUT;

	case 'h':
	    menu_Write_to_screen(this_prompt,
				 CATGETS(elm_msg_cat, MeSet,
					 MeListInfoListHelpP,
					 "List help"));
	    FlushBuffer();

	    retch = list_help(current_header->list_info,mailbox,aview,
			      this_page,this_prompt);
	    goto OUT;

	case 'a':
	    menu_Write_to_screen(this_prompt,
				 CATGETS(elm_msg_cat, MeSet,
					 MeListInfoListArchiveP,
					 "List archive"));
	    FlushBuffer();

	    retch = list_archive(current_header->list_info,mailbox,aview,
				 this_page,this_prompt);
	    goto OUT;

	case 's':
	    menu_Write_to_screen(this_prompt,
				 CATGETS(elm_msg_cat, MeSet,
					 MeListInfoListSubscribeP,
					 "List subscribe"));
	    FlushBuffer();

	    retch = list_subscribe(current_header->list_info,mailbox,aview,
				   this_page,this_prompt);
	    goto OUT;

	case 'u':
	    menu_Write_to_screen(this_prompt,
				 CATGETS(elm_msg_cat, MeSet,
					 MeListInfoListUnsubscribeP,
					 "List unsubscribe"));
	    FlushBuffer();

	    retch = list_unsubscribe(current_header->list_info,mailbox,aview,
				     this_page,this_prompt);
	    goto OUT;

	case 'i':
	    menu_Write_to_screen(this_prompt,
				 CATGETS(elm_msg_cat, MeSet,
					 MeGenericReplyIndex,
					 "Go to index"));
	    retch = 'i';
	    FlushBuffer();
	    /* FALLTHRU */
	case 'q':
	case 'x':
	case TERMCH_interrupt_char:
	    goto OUT;

	case EOF:
	    retch = EOF;
	    goto OUT;

	default:
	    lib_error(CATGETS(elm_msg_cat, MeSet,
			      MeGenericReplyUnknownCommand,		       
			      "Unknown command: %c"), 
		      ch);
	    continue;
	}    
    }

 OUT:

    error_wait();

    if (screen_initialized) {
	free_mailbox_screen(&LOC);
	
	erase_menu_context(&page);

	/* Force default return to parent page ... */
	menu_set_default(parent_page); 
	
	menu_trigger_redraw(parent_page);
    } else if (old_prompt)
	menu_trigger_redraw(old_prompt);

    return retch;	
}



/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */




syntax highlighted by Code2HTML, v. 0.9.1