Article 125132 of comp.os.vms:
Path: nntpd.lkg.dec.com!crl.dec.com!crl.dec.com!caen!zip.eecs.umich.edu!newshost.marcam.com!usc!howland.reston.ans.net!newsfeed.internetmci.com!usenet.eel.ufl.edu!news.gmi.edu!news.sojourn.com!frankensun.altair.com!rebecca!CNSVAX.ALBANY.EDU!SYSBRC
From: sysbrc@CNSVAX.ALBANY.EDU (Gandalf the Grey)
Newsgroups: comp.os.vms
Subject: Re: VMS S_MAIL.EXE wanted
Date: 18 Jul 1995 15:19:54 GMT
Organization: University of Albany, SUNY
Lines: 3256
Message-ID: <3ugjeq$lan@rebecca.albany.edu>
References: <3u5n07$e8u@goliat.eik.bme.hu>
Reply-To: sysbrc@CNSVAX.ALBANY.EDU
NNTP-Posting-Host: uacsc1.albany.edu

In article <3u5n07$e8u@goliat.eik.bme.hu>, lnagy@goliat.eik.bme.hu (NAGY Lajos) writes:
>Hi all!
>I have S_MAIL.EXE & I need sources code.
>Who is make this program?
>Thank you very much!

Here is _a_ copy of the s_mail.c source code.

I believe it is public domain (else I would not post it here) - but there
is NO documentation of any kind in the file. I do not know who wrote it or
when (but it is at least 2 years old because I have it at least that long).

Gold_Mail may do what you want - is definitely supported - and faster.
I believe other full screen mail utilities exist - including one called
DECWindows Mail.

 +---------------------------------------------------------------------------+
 | Brian R Cuttler              |  bitnet:   sysbrc@albnyvms                 |
 | VMS System Manager           |  internet: sysbrc@albnyvms.albany.edu      |
 | State Univ of NY at Albany   |  phone:    518-442-3906  fax: 518-442-3697 |
 +---------------------------------------------------------------------------+

/* s_mail.c */
/* totally and utterly VMS specific code. */

#include <ctype.h>
#include <descrip.h>
#include <file.h>
#include <lib$routines.h>
#include <maildef.h>
#include <nam.h>
#include <signal.h>
#include <smgdef.h>
#include <smgmsg.h>
#include <ssdef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <trmdef.h>
#include <unixio.h>

#define MAIL$_NOTEXIST 8290522
#define MAIL$_NOMOREMSG 8290386
#define MAIL$_NOSUCHUSR 8290346
#define MAIL$_USERSPEC 8290402
#define MAIL$_NOMOREREC 8314792
typedef struct {
	short	buffer_length;
	short	item_code;
	long	buffer_address;
	long	return_length_address;
} ITMLST;

struct node {
	struct node *next;
	char	*folder_name;
	long	message_count;
};

typedef struct {
	long	deleted_bytes;
	long	total_folders;
	long	total_messages;
	long	auto_purge;
	long	cc_prompt;
	long	copy_forward;
	long	copy_reply;
	long	copy_send;
	short	new_messages;
	char	wastebasket[256];
	char	result_spec[256];
	char	editor[256];
	char	forwarding[256];
	char	form[256];
	char	full_directory[256];
	char	personal_name[256];
	char	queue[256];
	char	sub_directory[256];
	char	user_name[256];
} user_data;

struct m_descripter {
	short	length;
	char	dtype;
	char	class;
	char	*pointer;
	char	scale;
	char	digits;
	char	aflags;
	char	dimct;
	long	arsize;
	char	*a0;
	long	m1;
	long	l1;
	long	u1;
};
typedef struct {
	short	len;
	short	type;
	char	*addr;
} s_desc;

typedef struct {
	struct to_user_list *next;
	char	user_name[256];
} to_user_list;

typedef struct {
	struct message_entry *next;
	long	id;
	long	size;
	char	date[256];
	char	from[256];
	char	reply[256];
	char	subject[256];
} message_entry;

long	file_context = 0;
long	message_context = 0;
long	user_context = 0, send_context = 0;
long	pasteboard_id, title_id, message_id, body_id, command_id, keyboard_id;


void clean_screen()
{
	if ((smg$erase_display(&message_id) & 1) == 0) {
		perror("Erase message update error");
		exit(1);
	}
	if ((smg$erase_display(&body_id) & 1) == 0) {
		perror("Erase body update error");
		exit(1);
	}
	if ((smg$erase_display(&command_id) & 1) == 0) {
		perror("Erase command update error");
		exit(1);
	}
}


int	folder_routine(struct node *list, struct dsc$descriptor *name)
{
	if (name->dsc$w_length > 0) {
		while (list->next)
			list = list->next;
		list->next = malloc(sizeof(struct node ));
		list = list->next;
		list->next = 0;
		list->folder_name = malloc(name->dsc$w_length + 1);
		strncpy(list->folder_name, name->dsc$a_pointer, name->dsc$w_length);
		list->folder_name[name->dsc$w_length] = '\0';
		list->message_count = 0;
	}
	return(SS$_NORMAL);
}


void init_mail()
{
	long	indexed = 0;
	ITMLST null_list[] = {
		{ 0, 0, 0, 0 }
	};	

	ITMLST open_list_out[2] = {
		{ sizeof(indexed), MAIL$_MAILFILE_INDEXED, &indexed, 0 },
		{ 0, 0, 0, 0 }
	};	

	if (mail$mailfile_begin(&file_context, null_list, null_list) != SS$_NORMAL) {
		perror("mail$mailfile_begin error ");
		exit(1);
	}

	if (mail$mailfile_open(&file_context, null_list, open_list_out) != SS$_NORMAL) {
		perror("mail$mailfile_open error ");
		exit(1);
	}

	if (indexed != 1) {
		fprintf(stderr, "Mail file not ISAM \n");
		exit(1);
	}

	if (mail$user_begin(&user_context, null_list, null_list) != SS$_NORMAL) {
		perror("mail$user_begin error");
		exit(1);
	}
}


void update_profile(user_data *profile, struct node *list)
{
	struct node *tmp;

	long	len1, len2, len3, len4, len5, len6, len7, len8, len9, len10, len11, len12, len13;

	ITMLST null_list[] = {
		{ 0, 0, 0, 0 }
	};	

	ITMLST folder_info[4] = {
		{ 4, MAIL$_MAILFILE_FOLDER_ROUTINE, &folder_routine, 0 },
		{ 4, MAIL$_MAILFILE_USER_DATA, 0, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST select_in[3] = {
		{ 0, MAIL$_MESSAGE_FOLDER, 0, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST select_out[2] = {
		{ 4, MAIL$_MESSAGE_SELECTED, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST info_out[4] = {
		{ 4, MAIL$_MAILFILE_DELETED_BYTES, 0, 0 },
		{ 255, MAIL$_MAILFILE_WASTEBASKET, 0, 0 },
		{ 255, MAIL$_MAILFILE_RESULTSPEC, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_user_info[15] = {
		{ 4, MAIL$_USER_AUTO_PURGE, 0, 0 },
		{ 4, MAIL$_USER_CC_PROMPT, 0, 0 },
		{ 4, MAIL$_USER_COPY_FORWARD, 0, 0 },
		{ 4, MAIL$_USER_COPY_REPLY, 0, 0 },
		{ 4, MAIL$_USER_COPY_SEND, 0, 0 },
		{ 2, MAIL$_USER_NEW_MESSAGES, 0, 0 },
		{ 255, MAIL$_USER_EDITOR, 0, 0 },
		{ 255, MAIL$_USER_FORWARDING, 0, 0 },
		{ 255, MAIL$_USER_FORM, 0, 0 },
		{ 255, MAIL$_USER_FULL_DIRECTORY, 0, 0 },
		{ 255, MAIL$_USER_PERSONAL_NAME, 0, 0 },
		{ 255, MAIL$_USER_QUEUE, 0, 0 },
		{ 255, MAIL$_USER_SUB_DIRECTORY, 0, 0 },
		{ 255, MAIL$_USER_RETURN_USERNAME, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST message_begin_in[3] = {
		{ sizeof(file_context), MAIL$_MESSAGE_FILE_CTX, &file_context, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	while (list->next != NULL) {
		tmp = list->next;
		free(tmp->folder_name);
		list->next = tmp->next;
		free(tmp);
	}
	folder_info[1].buffer_address = list;
	info_out[0].buffer_address = &profile->deleted_bytes;
	info_out[1].buffer_address = &profile->wastebasket;
	info_out[1].return_length_address = &len2;
	info_out[2].buffer_address = &profile->result_spec;
	info_out[2].return_length_address = &len1;

	if (mail$mailfile_info_file(&file_context, &folder_info, &info_out) != SS$_NORMAL) {
		perror("mail$mailfile_info_file error");
		exit(1);
	}
	profile->wastebasket[len2] = 0;
	profile->result_spec[len1] = 0;
	tmp = list;
	profile->total_folders = profile->total_messages = 0;

	message_context = 0;
	if (mail$message_begin(&message_context, message_begin_in, null_list) != SS$_NORMAL) {
		perror("mail$message_begin error");
		exit(1);
	}
	while (tmp->next) {
		tmp = tmp->next;
		select_in[0].buffer_address = tmp->folder_name;
		select_in[0].buffer_length = strlen(tmp->folder_name);
		select_out[0].buffer_address = &tmp->message_count;
		if (mail$message_select(&message_context, select_in, select_out) != SS$_NORMAL) {
			perror("mail$message_select error");
			exit(1);
		}
		profile->total_folders++;
		profile->total_messages += tmp->message_count;
	}
	if ((mail$message_end(&message_context, &null_list, &null_list) & 1) == 0) {
		perror("message end error");
		exit(1);
	}
	get_user_info[0].buffer_address = &profile->auto_purge;
	get_user_info[1].buffer_address = &profile->cc_prompt;
	get_user_info[2].buffer_address = &profile->copy_forward;
	get_user_info[3].buffer_address = &profile->copy_reply;
	get_user_info[4].buffer_address = &profile->copy_send;
	get_user_info[5].buffer_address = &profile->new_messages;
	get_user_info[6].buffer_address = &profile->editor[0];
	get_user_info[7].buffer_address = &profile->forwarding[0];
	get_user_info[8].buffer_address = &profile->form[0];
	get_user_info[9].buffer_address = &profile->full_directory[0];
	get_user_info[10].buffer_address = &profile->personal_name[0];
	get_user_info[11].buffer_address = &profile->queue[0];
	get_user_info[12].buffer_address = &profile->sub_directory[0];
	get_user_info[13].buffer_address = &profile->user_name[0];
	get_user_info[6].return_length_address = &len6;
	get_user_info[7].return_length_address = &len7;
	get_user_info[8].return_length_address = &len8;
	get_user_info[9].return_length_address = &len9;
	get_user_info[10].return_length_address = &len10;
	get_user_info[11].return_length_address = &len11;
	get_user_info[12].return_length_address = &len12;
	get_user_info[13].return_length_address = &len13;
	if (mail$user_get_info(&user_context, &null_list, &get_user_info) != SS$_NORMAL) {
		perror("mail$user_get_info error");
		exit(1);
	}
	profile->editor[len6] = 0;
	profile->forwarding[len7] = 0;
	profile->form[len8] = 0;
	profile->full_directory[len9] = 0;
	profile->personal_name[len10] = 0;
	profile->queue[len11] = 0;
	profile->sub_directory[len12] = 0;
	profile->user_name[len13] = 0;
}


long	catch_message()
{
	long	istat, msg_len;
	char	message[81];
	s_desc msg_desc, msg_out_desc;

	msg_desc.len = 80;
	msg_desc.type = msg_out_desc.type = 0;
	msg_desc.addr = msg_out_desc.addr = &message[0];
	while (1) {
		istat = smg$get_broadcast_message(&pasteboard_id, &msg_desc, &msg_len);
		if (istat == SMG$_NO_MORMSG)
			return(1);
		if (istat != SS$_NORMAL) {
			perror("Get broadcast message error");
			exit(1);
		}
		if (smg$erase_display(&message_id) != SS$_NORMAL) {
			perror("Erase message error");
			exit(1);
		}
		msg_out_desc.len = msg_len;
		if (smg$put_chars(&message_id, &msg_out_desc, &1, &1) != SS$_NORMAL) {
			perror("Display message error");
			exit(1);
		}
	}
}


void init_screen()
{
	long	istat;
	s_desc msg_desc;

	if ((smg$create_pasteboard(&pasteboard_id) & 1) == 0) {
		perror("Create pasteboard error");
		exit(1);
	}
	if ((smg$create_virtual_display(&2, &80, &title_id) & 1) == 0) {
		perror("Create title display error");
		exit(1);
	}
	if ((smg$erase_display(&title_id) & 1) == 0) {
		perror("Erase title display error");
		exit(1);
	}
	if ((smg$paste_virtual_display(&title_id, &pasteboard_id, &1, &1) & 1) == 0) {
		perror("Paste title display error");
		exit(1);
	}
	msg_desc.len = 4;
	msg_desc.type = 0;
	msg_desc.addr = &"Mail";
	if ((smg$put_chars_highwide(&title_id, &msg_desc, &1, &36) & 1) == 0) {
		perror("Write title display error");
		exit(1);
	}
	if ((smg$create_pasteboard(&pasteboard_id) & 1) == 0) {
		perror("Create pasteboard error");
		exit(1);
	}
	if ((smg$create_virtual_display(&1, &80, &message_id) & 1) == 0) {
		perror("Create message display error");
		exit(1);
	}
	if ((smg$paste_virtual_display(&message_id, &pasteboard_id, &3, &1) & 1) == 0) {
		perror("Paste message display error");
		exit(1);
	}
	if ((smg$set_broadcast_trapping(&pasteboard_id, &catch_message) & 1) == 0) {
		perror("Set broadcast trapping error");
		exit(1);
	}
	if ((smg$create_virtual_display(&20, &80, &body_id) & 1) == 0) {
		perror("Create body display error");
		exit(1);
	}

	if ((smg$paste_virtual_display(&body_id, &pasteboard_id, &4, &1) & 1) == 0) {
		perror("Paste body display error");
		exit(1);
	}
	if ((smg$create_virtual_display(&1, &80, &command_id) & 1) == 0) {
		perror("Create command display error");
		exit(1);
	}
	if ((smg$paste_virtual_display(&command_id, &pasteboard_id, &24, &1) & 1) == 0) {
		perror("Paste command display error");
		exit(1);
	}
	if ((smg$create_virtual_keyboard(&keyboard_id) & 1) == 0) {
		perror("Create virtual keyboard error");
		exit(1);
	}
	clean_screen();
}


long	do_main_menu(user_data *profile, struct node *list, int last_selection)
{
	char	scratch[79];
	long	i, j, k, l;
	char	*name;
	struct node *tmp_list;
	struct m_descripter menu_list = {
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0				};

	clean_screen();

	menu_list.length = 78;
	menu_list.dtype = DSC$K_DTYPE_T;
	menu_list.class = DSC$K_CLASS_A;
	menu_list.pointer = malloc(78 * (profile->total_folders + 7));
	if (menu_list.pointer == NULL) {
		perror("allocation error");
		exit(1);
	}
	memset(menu_list.pointer, 32, 78 * (profile->total_folders + 7));
	menu_list.scale = 0;
	menu_list.digits = 0;
	menu_list.aflags = 14 * 16;
	menu_list.dimct = 1;
	menu_list.arsize = 78 * (profile->total_folders + 7);
	menu_list.a0 = menu_list.pointer - 78;
	menu_list.m1 = profile->total_folders + 7;
	menu_list.l1 = 1;
	menu_list.u1 = profile->total_folders + 7;

	tmp_list = list;
	name = menu_list.pointer;

	sprintf(&scratch, "Open NEWMAIL - %d messages\0", profile->new_messages);
	strcpy(name, &scratch);
	name += 78;
	strcpy(name, &"Send Mail");
	name += 78;
	strcpy(name, &"Set/Show Options");
	name += 78;
	strcpy(name, &"Purge Wastebasket");
	name += 78;
	strcpy(name, &"Compress Mailfile");
	name += 78;
	strcpy(name, &"Refresh Screen");
	name += 78;
	strcpy(name, &"Exit");
	name += 78;
	for (i = 1; i <= profile->total_folders; i++) {
		tmp_list = tmp_list->next;
		sprintf(&scratch, "Open folder %s with %d messages\0", tmp_list->folder_name, tmp_list->message_count);
		strcpy(name, scratch);
		name += 78;
	}
	if ((smg$create_menu(&body_id, &menu_list, &SMG$K_VERTICAL) & 1) == 0) {
		perror("Create main menu error");
		exit(1);
	}
	if (profile->new_messages == 0) {
		l = 2;
	} else
	 {
		l = last_selection;
	}
	k = 0;
	j = smg$select_from_menu(&keyboard_id, &body_id, &k, &l, &SMG$M_RETURN_IMMED);
	if (j == SMG$_EOF)
		return(7);
	if ((j & 1) == 0) {
		perror("Select error");
		exit(1);
	}
	free(menu_list.pointer);
	return(k);
}


void not_implimented()
{
	s_desc msg_desc;

	clean_screen();
	msg_desc.addr = &"Not Implimented Yet";
	msg_desc.type = 0;
	msg_desc.len = strlen(msg_desc.addr);
	smg$put_chars_highwide(&body_id, &msg_desc, &4, &21);
	sleep(5);
}


purge_mail()
{
	long	data_reclaim, data_scan, index_reclaim, deleted_bytes, messages_deleted, total_reclaim;
	short	terminator;

	ITMLST purge_in[2] = {
		{ 0, MAIL$_MAILFILE_RECLAIM, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST purge_out[7] = {
		{ 4, MAIL$_MAILFILE_DATA_RECLAIM, &data_reclaim, 0 },
		{ 4, MAIL$_MAILFILE_DATA_SCAN, &data_scan, 0 },
		{ 4, MAIL$_MAILFILE_INDEX_RECLAIM, &index_reclaim, 0 },
		{ 4, MAIL$_MAILFILE_DELETED_BYTES, &deleted_bytes, 0 },
		{ 4, MAIL$_MAILFILE_MESSAGES_DELETED, &messages_deleted, 0 },
		{ 4, MAIL$_MAILFILE_TOTAL_RECLAIM, &total_reclaim, 0 },
		{ 0, 0, 0, 0 }
	};	

	char	message[81];
	s_desc msg_desc = { 0, 0, &message[0] };

	clean_screen();
	smg$set_cursor_abs(&body_id, &18, &1);
	if ((mail$mailfile_purge_waste(&file_context, &purge_in, &purge_out) & 1) == 0) {
		perror("Purge error");
		exit(1);
	}
	smg$repaint_screen(&pasteboard_id);
	memset(message, 0, 81);
	sprintf(message, "Messages Deleted        %d", messages_deleted);
	msg_desc.len = strlen(msg_desc.addr);
	smg$put_chars(&body_id, &msg_desc, &1, &1);

	memset(message, 0, 81);
	sprintf(message, "Data buckets scanned    %d", data_scan);
	msg_desc.len = strlen(msg_desc.addr);
	smg$put_chars(&body_id, &msg_desc, &2, &1);

	memset(message, 0, 81);
	sprintf(message, "Data buckets reclaimed  %d", data_reclaim);
	msg_desc.len = strlen(msg_desc.addr);
	smg$put_chars(&body_id, &msg_desc, &3, &1);

	memset(message, 0, 81);
	sprintf(message, "Index buckets reclaimed %d", index_reclaim);
	msg_desc.len = strlen(msg_desc.addr);
	smg$put_chars(&body_id, &msg_desc, &4, &1);

	memset(message, 0, 81);
	sprintf(message, "Deleted bytes           %d", deleted_bytes);
	msg_desc.len = strlen(msg_desc.addr);
	smg$put_chars(&body_id, &msg_desc, &5, &1);

	memset(message, 0, 81);
	sprintf(message, "Reclaimed bytes         %d", total_reclaim);
	msg_desc.len = strlen(msg_desc.addr);
	smg$put_chars(&body_id, &msg_desc, &6, &1);

	sleep(2);
}


void compress_mail()
{
	ITMLST compress_in[1]  = { 0, 0, 0, 0 };
	ITMLST compress_out[1] = { 0, 0, 0, 0 };

	clean_screen();
	smg$set_cursor_abs(&body_id, &18, &1);
	if ((mail$mailfile_compress(&file_context, &compress_in, &compress_out) & 1) == 0) {
		perror("Compress error");
		exit(1);
	}
	sleep(3);
	smg$repaint_screen(&pasteboard_id);
}


void personal_name(user_data *profile)
{
	char	name[255];
	unsigned short	r_len;
	s_desc result, prompt, confirm;
	ITMLST get_list = { 0, 0, 0, 0 };

	ITMLST	set_list[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	short	terminator;
	long	status;

	prompt.type = 0;
	prompt.addr = &"Enter new personal name :";

	prompt.len = strlen(prompt.addr);
	result.type = 0;
	result.addr = &name[0];
	result.len = 255;
	confirm.type = 0;
	confirm.addr = &"Confirm change (Y/N) [N] :";
	confirm.len = strlen(confirm.addr);

	if ((smg$set_cursor_abs(&command_id, &1, &1) & 1) == 0)
		exit(1);
	if ((smg$read_string(&keyboard_id, &result, &prompt, &255, 0, 0, 0, &r_len, 0, &command_id) & 1) == 0)
		exit(1);
	if ((smg$put_chars(&command_id, &confirm, &1, &1, &SMG$M_ERASE_LINE) & 1) == 0)
		exit(1);
	if ((smg$read_keystroke(&keyboard_id, &terminator) & 1) == 0)
		exit(1);

	if ((terminator != SMG$K_TRM_UPPERCASE_Y) &  (terminator != SMG$K_TRM_LOWERCASE_Y))
		return;
	memset(profile->personal_name, 0, 255);
	if (r_len == 0) {
		set_list[0].item_code = MAIL$_USER_SET_NO_PERSONAL_NAME;
	} else
	 {
		if (r_len > 255)
			r_len = 255;
		name[r_len] = 0;
		strncpy(&profile->personal_name[0], &name[0], r_len);
		set_list[0].item_code = MAIL$_USER_SET_PERSONAL_NAME;
		set_list[0].buffer_length = r_len;
		set_list[0].buffer_address = &name[0];
	}
	if ((mail$user_set_info(&user_context, set_list, &get_list) & 1) == 0)
		exit(1);
}


void mail_count(user_data *profile)
{
	s_desc prompt, confirm;
	short	terminator;
	long	status;
	long	zero = 0;
	ITMLST get_list = { 0, 0, 0, 0 };
	ITMLST set_list[2] = {
		{ 2, MAIL$_USER_SET_NEW_MESSAGES, &zero, 0 },
		{ 0, 0, 0, 0 }
	};	

	prompt.type = 0;
	prompt.addr = &"Reset new message count to zero (Y/N) ? ";
	prompt.len = strlen(prompt.addr);

	if ((smg$put_chars(&command_id, &prompt, &1, &1, &SMG$M_ERASE_LINE) & 1) == 0)
		exit(1);
	if ((smg$read_keystroke(&keyboard_id, &terminator) & 1) == 0)
		exit(1);
	if ((terminator != SMG$K_TRM_UPPERCASE_Y) &  (terminator != SMG$K_TRM_LOWERCASE_Y))
		return;
	if ((mail$user_set_info(&user_context, set_list, &get_list) & 1) == 0)
		exit(1);
	profile->new_messages = 0;
}


void not_changeable()
{
	s_desc  prompt;
	long	status;

	prompt.type = 0;
	prompt.addr = &"Item can not be modified by this program";
	prompt.len = strlen(prompt.addr);
	if ((smg$put_chars(&command_id, &prompt, &1, &1, &SMG$M_ERASE_LINE) & 1) == 0)
		exit(1);
	sleep(3);
}


void forwarding(user_data *profile)
{
	char	name[255];

	unsigned short	r_len;
	s_desc  result, prompt, confirm;
	ITMLST get_list = { 0, 0, 0, 0 };

	ITMLST set_list[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	short	terminator;
	long	status;

	prompt.type = 0;
	prompt.addr = &"Enter new forwarding address :";
	prompt.len = strlen(prompt.addr);
	result.type = 0;
	result.addr = &name[0];
	result.len = 255;
	confirm.type = 0;
	confirm.addr = &"Confirm change (Y/N) [N] :";
	confirm.len = strlen(confirm.addr);

	if ((smg$set_cursor_abs(&command_id, &1, &1) & 1) == 0)
		exit(1);
	if ((smg$read_string(&keyboard_id, &result, &prompt, &255, 0, 0, 0, &r_len, 0, &command_id) & 1) ==  0)
		exit(1);
	if ((smg$put_chars(&command_id, &confirm, &1, &1, &SMG$M_ERASE_LINE) & 1) == 0)
		exit(1);
	if ((smg$read_keystroke(&keyboard_id, &terminator) & 1) == 0)
		exit(1);
	if ((terminator != SMG$K_TRM_UPPERCASE_Y) &  (terminator != SMG$K_TRM_LOWERCASE_Y))
		return;
	memset(profile->forwarding, 0, 255);
	if (r_len == 0) {
		set_list[0].item_code = MAIL$_USER_SET_NO_FORWARDING;
	} else
	 {
		if (r_len > 255)
			r_len = 255;
		name[r_len] = 0;
		strncpy(&profile->forwarding[0], &name[0], r_len);
		set_list[0].item_code = MAIL$_USER_SET_FORWARDING;
		set_list[0].buffer_length = r_len;
		set_list[0].buffer_address = &name[0];
	}
	if ((mail$user_set_info(&user_context, set_list, &get_list) & 1) == 0)
		exit(1);
}


void editor(user_data *profile)
{
	char	name[255];
	unsigned short	r_len;
	s_desc  result, prompt, confirm, tilt;
	ITMLST get_list = { 0, 0, 0, 0 };

	ITMLST set_list[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	short	terminator;
	long	status, file_number;
	char	file_name[512], message[512];

	prompt.type = 0;

	prompt.addr = &"Enter new editor :";
	prompt.len = strlen(prompt.addr);
	result.type = 0;
	result.addr = &name[0];
	result.len = 255;
	confirm.type = 0;
	confirm.addr = &"Confirm change (Y/N) [N] :";
	confirm.len = strlen(confirm.addr);

	if ((smg$set_cursor_abs(&command_id, &1, &1) & 1) == 0)
		exit(1);
	if ((smg$read_string(&keyboard_id, &result, &prompt, &255, 0, 0, 0, &r_len , 0, &command_id) &  1) == 0)
		exit(1);
	if ((smg$put_chars(&command_id, &confirm, &1, &1, &SMG$M_ERASE_LINE) & 1) == 0)
		exit(1);
	if ((smg$read_keystroke(&keyboard_id, &terminator) & 1) == 0)
		exit(1);
	if ((terminator != SMG$K_TRM_UPPERCASE_Y) &  (terminator != SMG$K_TRM_LOWERCASE_Y))
		return;
	memset(profile->editor, 0, 255);

	if (r_len == 0) {
		set_list[0].item_code = MAIL$_USER_SET_NO_EDITOR;
	} else
	 {
		if (r_len > 255)
			r_len = 255;
		name[r_len] = 0;
		memset(file_name, 0, 512);
		strcpy(file_name, "sys$share:");
		strncat(file_name, name, r_len);
		strcat(file_name, "shr.exe");
		if ((file_number = open(file_name, O_RDONLY, 0, "shr=get")) == -1) {
			memset(message, 0, 512);
			sprintf(&message[0], "Unable to find file %s", &file_name[0]);
			tilt.type = 0;
			tilt.addr =  &message[0];
			tilt.len = strlen(tilt.addr);
			smg$put_chars(&command_id, &tilt, &1, &1, &SMG$M_ERASE_LINE);
			return;
		}
		close(file_number);
		strncpy(&profile->editor[0], &name[0], r_len);
		set_list[0].item_code = MAIL$_USER_SET_EDITOR;
		set_list[0].buffer_length = r_len;
		set_list[0].buffer_address = &name[0];
	}
	if ((mail$user_set_info(&user_context, set_list, &get_list) & 1) == 0)
		exit(1);
}


void print_queue(user_data *profile)
{
	char	name[255];
	unsigned short	r_len;
	s_desc result, prompt, confirm;
	ITMLST get_list = { 0, 0, 0, 0 };

	ITMLST set_list[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	short	terminator;
	long	status;

	prompt.type = 0;
	prompt.addr = &"Enter new print queue :";
	prompt.len = strlen(prompt.addr);
	result.type = 0;
	result.addr = &name[0];
	result.len = 255;
	confirm.type = 0;
	confirm.addr = &"Confirm change (Y/N) [N] :";
	confirm.len = strlen(confirm.addr);

	if ((smg$set_cursor_abs(&command_id, &1, &1) & 1) == 0)
		exit(1);
	if ((smg$read_string(&keyboard_id, &result, &prompt, &255, 0, 0, 0, &r_len , 0, &command_id) & 1) == 0)
		exit(1);
	if ((smg$put_chars(&command_id, &confirm, &1, &1, &SMG$M_ERASE_LINE) & 1) == 0)
		exit(1);
	if ((smg$read_keystroke(&keyboard_id, &terminator) & 1) == 0)
		exit(1);
	if ((terminator != SMG$K_TRM_UPPERCASE_Y) &  (terminator != SMG$K_TRM_LOWERCASE_Y))
		return;
	memset(profile->queue, 0, 255);
	if (r_len == 0) {
		set_list[0].item_code = MAIL$_USER_SET_NO_QUEUE;
	} else
	 {
		if (r_len > 255)
			r_len = 255;
		name[r_len] = 0;
		strncpy(&profile->queue[0], &name[0], r_len);
		set_list[0].item_code = MAIL$_USER_SET_QUEUE;
		set_list[0].buffer_length = r_len;
		set_list[0].buffer_address = &name[0];
	}
	if ((mail$user_set_info(&user_context, set_list, &get_list) & 1) == 0)
		exit(1);
}


void print_form(user_data *profile)
{
	char	name[255];
	unsigned short	r_len;
	s_desc result, prompt, confirm;
	ITMLST get_list = { 0, 0, 0, 0 };

	ITMLST set_list[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	short	terminator;
	long	status;

	prompt.type = 0;
	prompt.addr = &"Enter new printer form :";
	prompt.len = strlen(prompt.addr);
	result.type = 0;
	result.addr = &name[0];
	result.len = 255;
	confirm.type = 0;
	confirm.addr = &"Confirm change (Y/N) [N] :";
	confirm.len = strlen(confirm.addr);

	if ((smg$set_cursor_abs(&command_id, &1, &1) & 1) == 0)
		exit(1);
	if ((smg$read_string(&keyboard_id, &result, &prompt, &255, 0, 0, 0, &r_len , 0, &command_id) & 1) == 0)
		exit(1);
	if ((smg$put_chars(&command_id, &confirm, &1, &1, &SMG$M_ERASE_LINE) &  1) == 0)
		exit(1);
	if ((smg$read_keystroke(&keyboard_id, &terminator) & 1) == 0)
		exit(1);
	if ((terminator != SMG$K_TRM_UPPERCASE_Y) &  (terminator != SMG$K_TRM_LOWERCASE_Y))
		return;
	memset(profile->form, 0, 255);
	if (r_len == 0) {
		set_list[0].item_code = MAIL$_USER_SET_NO_FORM;
	} else
	 {
		if (r_len > 255)
			r_len = 255;
		name[r_len] = 0;
		strncpy(&profile->form[0], &name[0], r_len);
		set_list[0].item_code = MAIL$_USER_SET_FORM;
		set_list[0].buffer_length = r_len;
		set_list[0].buffer_address = &name[0];
	}
	if ((mail$user_set_info(&user_context, set_list, &get_list) & 1) == 0)
		exit(1);
}


void auto_purge(user_data *profile)
{
	ITMLST get_list = { 0, 0, 0, 0 };

	ITMLST set_list[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	long	status;

	if ((profile->auto_purge & 1) == 0) {
		set_list[0].item_code = MAIL$_USER_SET_AUTO_PURGE;
		profile->auto_purge = 1;
	} else
	 {
		set_list[0].item_code = MAIL$_USER_SET_NO_AUTO_PURGE;
		profile->auto_purge = 0;
	}
	if ((mail$user_set_info(&user_context, set_list, &get_list) & 1) == 0)
		exit(1);
}


void cc_prompt(user_data *profile)
{
	ITMLST get_list = { 0, 0, 0, 0 };

	ITMLST set_list[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	


	long	status;

	if ((profile->cc_prompt & 1) == 0) {
		set_list[0].item_code = MAIL$_USER_SET_CC_PROMPT;
		profile->cc_prompt = 1;
	} else
	 {
		set_list[0].item_code = MAIL$_USER_SET_NO_CC_PROMPT;
		profile->cc_prompt = 0;
	}
	if ((mail$user_set_info(&user_context, set_list, &get_list) & 1) == 0)
		exit(1);
}


void copy_forward(user_data *profile)
{
	ITMLST get_list = { 0, 0, 0, 0 };

	ITMLST set_list[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	long	status;

	if ((profile->copy_forward & 1) == 0) {
		set_list[0].item_code = MAIL$_USER_SET_COPY_FORWARD;
		profile->copy_forward = 1;
	} else
	 {
		set_list[0].item_code = MAIL$_USER_SET_NO_COPY_FORWARD;
		profile->copy_forward = 0;
	}
	if ((mail$user_set_info(&user_context, set_list, &get_list) & 1) == 0)
		exit(1);
}


void copy_reply(user_data *profile)
{
	ITMLST get_list = { 0, 0, 0, 0 };

	ITMLST set_list[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	long	status;

	if ((profile->copy_reply & 1) == 0) {
		set_list[0].item_code = MAIL$_USER_SET_COPY_REPLY;
		profile->copy_reply = 1;
	} else
	 {
		set_list[0].item_code = MAIL$_USER_SET_NO_COPY_REPLY;
		profile->copy_reply = 0;
	}
	if ((mail$user_set_info(&user_context, set_list, &get_list) & 1) == 0)
		exit(1);
}


void copy_send(user_data *profile)
{
	ITMLST get_list = { 0, 0, 0, 0 };

	ITMLST set_list[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	long	status;

	if ((profile->copy_send & 1) ==  0) {
		set_list[0].item_code =  MAIL$_USER_SET_COPY_SEND;
		profile->copy_send = 1;
	} else
	 {
		set_list[0].item_code =  MAIL$_USER_SET_NO_COPY_SEND;
		profile->copy_send = 0;
	}
	if ((mail$user_set_info(&user_context, set_list, &get_list) & 1) == 0)
		exit(1);
}


void set_show(user_data *profile)
{
	struct m_descripter menu_list = 
	 {
		0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0
	};

	char	*entry;
	long	i, j, k, last_selection = 1;

	while (1) {
		clean_screen();

		menu_list.length = 78;
		menu_list.dtype = DSC$K_DTYPE_T;
		menu_list.class = DSC$K_CLASS_A;
		menu_list.pointer = malloc(78 *  14);
		if (menu_list.pointer ==  NULL) {
			perror("allocation error");
			exit(1);
		}
		memset(menu_list.pointer, 32, 78 * (14));
		menu_list.scale = 0;
		menu_list.digits = 0;
		menu_list.aflags = 14 *  16;
		menu_list.dimct = 1;
		menu_list.arsize = 78 *  14;
		menu_list.a0 = menu_list.pointer -  78;
		menu_list.m1 = 14;
		menu_list.l1 = 1;
		menu_list.u1 = 14;

		entry = menu_list.pointer;

		sprintf(entry, "Exit");
		entry += 78;
		if (strlen(profile->personal_name) ==  0) {
			sprintf(entry, "No personal name");
		} else
		 {
			sprintf(entry, "Personal Name: %-.*s", (78 -  15), profile->personal_name);
		}
		entry += 78;

		sprintf(entry, "Message Count: %u", profile->new_messages);
		entry += 78;

		sprintf(entry, "Mail dir:      %-.*s", (78 - 15), profile->result_spec);
		entry += 78;

		sprintf(entry, "Wastebasket folder:      %-.*s", (78 - 25), profile->wastebasket);
		entry += 78;

		if (strlen(profile->forwarding) ==  0) {
			sprintf(entry, "No forwarding");
		} else
		 {
			sprintf(entry, "Forward to:    %-.*s", (78 -  15), profile->forwarding);
		}
		entry += 78;

		if (strlen(profile->editor) ==  0) {
			sprintf(entry, "No default editor (EDT used)");
		} else
		 {
			sprintf(entry, "Default Editor:%-.*s", (78 -  15), profile->editor);
		}
		entry += 78;

		if (strlen(profile->queue) ==  0) {
			sprintf(entry, "No default queue (SYS$PRINT used)");
		} else
		 {
			sprintf(entry, "Default Queue :%-.*s", (78 -  15), profile->queue);
		}
		entry += 78;
		if (strlen(profile->form) ==  0) {
			sprintf(entry, "No default form");
		} else
		 {
			sprintf(entry, "Default Form  :%-.*s", (78 -  15), profile->form);
		}
		entry += 78;

		if ((profile->auto_purge &  1) == 0) {
			sprintf(entry, "Autopurge:     Disabled");
		} else
		 {
			sprintf(entry, "Autopurge:     Enabled");
		}
		entry += 78;
		if ((profile->cc_prompt &  1) == 0) {
			sprintf(entry, "CC Prompt:     Disabled");
		} else
		 {
			sprintf(entry, "CC Prompt:     Enabled");
		}
		entry += 78;
		if ((profile->copy_forward &  1) == 0) {
			sprintf(entry, "Copy forward:  Disabled");
		} else
		 {
			sprintf(entry, "Copy forward:  Enabled");
		}
		entry += 78;
		if ((profile->copy_reply &  1) == 0) {
			sprintf(entry, "Copy reply:    Disabled");
		} else
		 {
			sprintf(entry, "Copy reply:    Enabled");
		}
		entry += 78;
		if ((profile->copy_send &  1) == 0) {
			sprintf(entry, "Copy send:     Disabled");
		} else
		 {
			sprintf(entry, "Copy send:     Enabled");
		}
		entry += 78;

		if ((smg$create_menu(&body_id, &menu_list, &SMG$K_VERTICAL) &  1) == 0) {
			perror("Create set/show menu error");
			exit(1);
		}
		k = 0;
		j = smg$select_from_menu(&keyboard_id, &body_id, &k, &last_selection , &SMG$M_RETURN_IMMED);
		free(menu_list.pointer);
		if (j == SMG$_EOF)
			return;
		if ((j & 1) == 0) {
			perror("Select error");
			exit(1);
		}
		last_selection = k;
		switch (k) {
		case 1:
			return;
			break;
		case 2:
			personal_name(profile);
			break;
		case 3:
			mail_count(profile);
			break;
		case 4:
			not_changeable();  /* mail file & subdir */
			break;
		case 5:
			not_changeable(); /* wastebasket folder */
			break;
		case 6:
			forwarding(profile);
			break;
		case 7:
			editor(profile);
			break;
		case 8:
			print_queue(profile);
			break;
		case 9:
			print_form(profile);
			break;
		case 10:
			auto_purge(profile);
			break;
		case 11:
			cc_prompt(profile);
			break;
		case 12:
			copy_forward(profile);
			break;
		case 13:
			copy_reply(profile);
			break;
		case 14:
			copy_send(profile);
			break;
		}

	}
}


long	exit_handler(long *sigargs[], long *mechargs[5])
{
	ITMLST null = {	0, 0, 0, 0 };

	mail$send_abort(&send_context, &null, &null);

	return(SS$_RESIGNAL);
}


int	yes_send(s_desc *name)
{
	char	message[300];
	s_desc output;

	memset(&message, 0, 80);
	strcpy(&message, &"Success sending mail to ");
	strncat(&message, name->addr, name->len);
	output.type = 0;
	output.addr = &message[0];
	output.len = strlen(&message[0]);
	smg$put_line(&body_id, &output);
	return(SS$_NORMAL);
}


int	no_send(s_desc *name)
{
	char	message[300];
	s_desc output;

	memset(&message, 0, 80);
	strcpy(&message, &"Failure sending mail to ");
	strncat(&message, name->addr, name->len);
	output.type = 0;
	output.addr = &message[0];
	output.len = strlen(&message[0]);
	smg$put_line(&body_id, &output);
	return(SS$_NORMAL);
}


void send_basic()
{
	long	status;
	unsigned short	r_len;
	char	message[257];
	s_desc msg_desc = { 256, 0, &message[0]	};
	s_desc header_desc = { 0, 0, &"Enter message, terminate with <^Z>" };

	ITMLST null = {	0, 0, 0, 0 };

	ITMLST body_in[2] = {
		{ 0, MAIL$_SEND_RECORD,	&message[0], 0 },
		{ 0, 0, 0 }
	};	

	header_desc.len = strlen(header_desc.addr);
	clean_screen();

	smg$set_cursor_abs(&body_id, &1, &1);
	if ((smg$put_line(&body_id, &header_desc) &  1) == 0) {
		perror("put_line error");
		exit(1);
	}
	while (1) {
		r_len = 0;
		status = smg$read_string(&keyboard_id, &msg_desc, 0, &256, 0, 0, 0, &r_len, 0, &body_id);
		if (status == SMG$_EOF)
			break;
		if ((status & 1) == 0) {
			perror("read string error");
			exit(1);
		}
		body_in[0].buffer_length =  r_len;
		if ((mail$send_add_bodypart(&send_context, &body_in, &null) & 1) ==  0) {
			perror("add body error");
			exit(1);
		}
	}
	if (r_len != 0) {
		body_in[0].buffer_length =  r_len;
		if ((mail$send_add_bodypart(&send_context, &body_in, &null) & 1) ==  0) {
			perror("add body error");
			exit(1);
		}
	}
}


int	send_edit(user_data *profile)
{
	s_desc file_name;
	s_desc msg_desc;

	ITMLST null = {	0, 0, 0, 0 };

	ITMLST body_in[2] = {
		{ 0, MAIL$_SEND_FILENAME, &"sys$scratch:s_mail$temp_file.tmp", 0 },
		{ 0, 0, 0, 0 }
	};	

	FILE * test_file;

	body_in[0].buffer_length = strlen(body_in[0].buffer_address);
	file_name.type = 0;
	file_name.addr = &"sys$scratch:s_mail$temp_file.tmp";
	file_name.len = strlen(file_name.addr);
	if (strlen(&profile->editor[0]) ==  0) {
		if ((edt$edit(&file_name) &  1) == 0) {
			perror("edit error");
			exit(1);
		}
	} else if (strcmp(&profile->editor[0], &"EDT") == 0) {
		if ((edt$edit(&file_name) &  1) == 0) {
			perror("edit error");
			exit(1);
		}
	} else if (strcmp(&profile->editor[0], &"TPU") == 0) {
		file_name.addr = &"TPU sys$scratch:s_mail$temp_file.tmp ";
		file_name.len = strlen(file_name.addr);
		if ((tpu$tpu(&file_name) &  1) == 0) {
			perror("edit error");
			exit(1);
		}
	} else
	 {
		msg_desc.type = 0;
		msg_desc.addr =  &"Unable to handle this type of editor-useing EDIT";
		msg_desc.len = strlen(msg_desc.addr);
		smg$put_chars(&command_id, &msg_desc, &1, &1 , 0, &SMG$M_ERASE_LINE);
		sleep(3);
		if ((edt$edit(&file_name) &  1) == 0) {
			perror("edit error");
			exit(1);
		}
	}
	if ((test_file = fopen(&"sys$scratch:s_mail$temp_file.tmp", "r")) == NULL) {
		return(1);
	}
	fclose(test_file);
	if ((mail$send_add_bodypart(&send_context, &body_in, &null) & 1) == 0) {
		perror("add body error");
		exit(1);
	}
	return(0);
}


void send_file(char *file)
{
	ITMLST body_in[2] = {
		{ 0, MAIL$_SEND_FILENAME, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST null = { 0, 0, 0, 0 };

	body_in[0].buffer_address = file;
	body_in[0].buffer_length = strlen(file);
	if ((mail$send_add_bodypart(&send_context, &body_in, &null) & 1) == 0) {
		perror("add body error");
		exit(1);
	}
}


int	send_edit_file(user_data *profile, char *file)
{
	s_desc file_name;
	s_desc scr_name;
	s_desc msg_desc;

	ITMLST null = {	0, 0, 0, 0 };

	ITMLST body_in[2] = {
		{ 0, MAIL$_SEND_FILENAME, &"sys$scratch:s_mail$temp_file.tmp", 0 },
		{ 0, 0, 0, 0 }
	};	

	char	message[512];
	FILE * test_file;

	body_in[0].buffer_length = strlen(body_in[0].buffer_address);

	scr_name.type = 0;
	scr_name.addr = &"sys$scratch:s_mail$temp_file.tmp";
	scr_name.len = strlen(scr_name.addr);
	file_name.type = 0;
	file_name.addr = file;
	file_name.len = strlen(file);
	if (strlen(&profile->editor[0]) ==  0) {
		if ((edt$edit(&file_name, &scr_name) & 1) == 0) {
			perror("edit error");
			exit(1);
		}
	} else if (strcmp(&profile->editor[0], &"EDT") == 0) {
		if ((edt$edit(&file_name, &scr_name) & 1) == 0) {
			perror("edit error");
			exit(1);
		}
	} else if (strcmp(&profile->editor[0], &"TPU") == 0) {
		memset(&message[0], 0, 512);
		strcpy(&message[0], &"TPU/output=sys$scratch:s_mail$temp_file.tmp ");
		strcat(&message[0], file);
		file_name.addr = &message[0];
		file_name.len = strlen(file_name.addr);
		if ((tpu$tpu(&file_name) &  1) == 0) {
			perror("TPU error");
			exit(1);
		}
	} else
	 {
		msg_desc.type = 0;
		msg_desc.addr =  &"Unable to handle this type of editor-useing EDIT";
		msg_desc.len = strlen(msg_desc.addr);
		smg$put_chars(&command_id, &msg_desc, &1, &1 , 0, &SMG$M_ERASE_LINE);
		sleep(3);
		if ((edt$edit(&file_name, &scr_name) & 1) == 0) {
			perror("edit error");
			exit(1);
		}
	}
	if ((test_file = fopen(&"sys$scratch:s_mail$temp_file.tmp", "r")) == NULL) {
		return(1);
	}
	fclose(test_file);
	if ((mail$send_add_bodypart(&send_context, &body_in, &null) & 1) == 0) {
		perror("add body error");
		exit(1);
	}
	return(0);
}


to_user_list *parse_user_list(char *list)
{
	to_user_list * parsed, *last, *temp, *dist;
	long	index, length, insert;
	FILE * file_number;
	char	message[512];
	s_desc tilt;

	last = parsed =  NULL;
	length = strlen(list);
	index = 0;
	while (1) {
		while ((index < length) &&  (isspace(list[index]) |  (list[index] == 44))) {
			index++;
		}
		if (index >= length)
			return(parsed);
		if (list[index] == 33)
			return(parsed);
		temp = malloc(sizeof(to_user_list));
		if (temp == NULL) {
			perror("malloc error");
			exit(1);
		}
		insert = 0;
		memset(temp, 0, sizeof(to_user_list));
		while ((index < length) &&  ((isspace(list[index]) ==  0) &  (list[index] != 44) &  (list[index] != 33))) {
			temp->user_name[insert++] =  list[index++];
		}
		if (insert == 0) {
			free(temp);
		} else if (temp->user_name[0] ==  64) {
			if ((file_number =  fopen(&temp->user_name[1], "r", "dna=mail.dis")) ==  NULL) {
				memset(message, 0, 512);
				sprintf(&message[0], "Unable to find mail distribution list file %s", &temp->user_name[0]);
				tilt.type =  0;
				tilt.addr =  &message[0];
				tilt.len =  strlen(tilt.addr);
				smg$put_chars(&command_id, &tilt, &1, &1, &SMG$M_ERASE_LINE);
				sleep(3);
			} else
			 {
				while (1) {
					memset(message, 0, 512);
					if (fgets(&message[0], 512, file_number) == NULL) {
						if (feof(file_number) != 0)
							break;
						perror( "read mail dist file error");
						exit(1);
					}
					dist = parse_user_list(message);
					if (dist != NULL & parsed == NULL) {
						parsed = last = dist;
					} else if (dist != NULL) {
						last->next = dist;
					}
					while (last->next != NULL) {
						last = last->next;
					}
				}
				close(file_number);
			}
			free(temp);
		} else
		 {
			if (parsed == NULL) {
				parsed =  last =  temp;
			} else
			 {
				last->next =  temp;
				last =  temp;
			}
		}
	}
}


void get_user_list(char *prompt, int type)
{
	s_desc msg_desc, reply_desc, tilt_desc;
	char	to[256];
	to_user_list * dest, *temp_dest;
	char	message[256];
	unsigned short	r_len;
	short	mail_to;
	long	status;
	ITMLST add_to_in[4] = {
		{ 2, MAIL$_SEND_USERNAME_TYPE, &mail_to, 0 },
		{ 0, MAIL$_SEND_USERNAME, 0, 0 },
		{ 0, MAIL$_NOSIGNAL, 0,	0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST null = {	0, 0, 0, 0 };

	dest = NULL;
	msg_desc.type = 0;
	msg_desc.addr = prompt;
	msg_desc.len = strlen(prompt);
	reply_desc.type = 0;
	reply_desc.addr = &to[0];
	reply_desc.len = NAM$C_MAXRSS;
	add_to_in[0].buffer_address = &type;

	while (1) {
		if ((smg$put_chars(&body_id, &msg_desc) & 1) == 0) {
			perror("Put char error");
			exit(1);
		}
		memset(&to[0], 0, NAM$C_MAXRSS +  1);
		status = smg$read_string(&keyboard_id, &reply_desc, 0, &NAM$C_MAXRSS, 0, 0, 0, &r_len, 0, &body_id);
		if (status == SMG$_EOF)
			break;
		if ((status & 1) == 0) {
			perror("Read string error");
			exit(1);
		}
		if (r_len == 0)
			break;
		to[r_len] = 0;
		dest = parse_user_list(to);
		while (dest != NULL) {
			add_to_in[1].buffer_address =  &dest->user_name[0];
			add_to_in[1].buffer_length =  strlen(add_to_in[1].buffer_address);
			status =  mail$send_add_address(&send_context, &add_to_in, &null);
			if (status == MAIL$_NOSUCHUSR) {
				memset(message, 0, 256);
				strcpy(message, &"No such user ");
				strcat(message, &dest->user_name[0]);
				tilt_desc.type =  0;
				tilt_desc.addr =  &message[0];
				tilt_desc.len =  strlen(tilt_desc.addr);
				smg$put_line(&body_id, &tilt_desc);
			} else if (status ==  MAIL$_USERSPEC) {
				memset(message, 0, 256);
				strcpy(message, &"Bad user spec input '");
				strcat(message, &dest->user_name[0]);
				strcat(message, &"' ");
				tilt_desc.type =  0;
				tilt_desc.addr =  &message[0];
				tilt_desc.len =  strlen(tilt_desc.addr);
				smg$put_line(&body_id, &tilt_desc);
			} else if ((status &  1) == 0) {
				perror("send_add error");
				exit(1);
			}
			temp_dest = dest;
			dest = dest->next;
			free(temp_dest);
		}
	}
}


void send_mail(user_data *profile)
{
	struct m_descripter menu_list = 
	 {
		0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0			};

	char	menu[5*20], *list;
	long	j, k, status;
	char	to[NAM$C_MAXRSS+1], subj[NAM$C_MAXRSS+1],
	file[NAM$C_MAXRSS+1];
	struct
	 {
		short	len;
		short	type;
		long	addr;
	} msg_desc, reply_desc, tilt_desc;

	short	mail_to = MAIL$_TO;
	short	mail_cc = MAIL$_CC;
	unsigned short	r_len;

	ITMLST null = {	0, 0, 0, 0 };

	ITMLST begin_in[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST add_to_in[4] = {
		{ 2, MAIL$_SEND_USERNAME_TYPE, &mail_to, 0 },
		{ 0, MAIL$_SEND_USERNAME, &to[0], 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST add_cc_in[4] = {
		{ 2, MAIL$_SEND_USERNAME_TYPE, &mail_cc, 0 },
		{ 0, MAIL$_SEND_USERNAME, &to[0], 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST attribute_in[2] = {
		{ 0, MAIL$_SEND_SUBJECT, &subj[0], 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST send_message_in[4] = {
		{ 4, MAIL$_SEND_ERROR_ENTRY, &no_send, 0 },
		{ 4, MAIL$_SEND_SUCCESS_ENTRY, &yes_send, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	


	menu_list.length = 20;
	menu_list.dtype = DSC$K_DTYPE_T;
	menu_list.class = DSC$K_CLASS_A;
	menu_list.pointer = &menu[0];
	menu_list.scale = 0;
	menu_list.digits = 0;
	menu_list.aflags = 14 * 16;
	menu_list.dimct = 1;
	menu_list.arsize = 5 * 20;
	menu_list.a0 = menu_list.pointer -  20;
	menu_list.m1 = 5;
	menu_list.l1 = 1;
	menu_list.u1 = 5;
	memset(menu_list.pointer, 32, 5 *  20);
	list = &menu;
	strcpy(list, "Exit");
	list += 20;
	strcpy(list, "Send");
	list += 20;
	strcpy(list, "Send/edit");
	list += 20;
	strcpy(list, "Send file");
	list += 20;
	strcpy(list, "Send/edit file");

	clean_screen();
	if ((smg$create_menu(&body_id, &menu_list, &SMG$K_VERTICAL) &  1) == 0) {
		perror("Create set/show menu error");
		exit(1);
	}
	k = 0;
	j = smg$select_from_menu(&keyboard_id, &body_id, &k, &2, &SMG$M_RETURN_IMMED);
	if (j == SMG$_EOF)
		return;
	if ((j & 1) == 0) {
		perror("Select error");
		exit(1);
	}
	if (k == 1)
		return;

	clean_screen();

	lib$establish(&exit_handler);
	if (profile->personal_name[0] ==  0) {
		begin_in[0].item_code =  MAIL$_SEND_NO_PERS_NAME;
	} else
	 {
		begin_in[0].item_code =  MAIL$_SEND_PERS_NAME;
		begin_in[0].buffer_address =  &profile->personal_name[0];
		begin_in[0].buffer_length =  strlen(&profile->personal_name[0]);
	}
	if ((mail$send_begin(&send_context, &begin_in, &null) & 1) == 0) {
		perror("Send begin error");
		exit(1);
	}
	smg$set_cursor_abs(&body_id, &1, &1);
	msg_desc.type = 0;
	msg_desc.addr =  &"Enter 'To' list, empty line to terminate";
	msg_desc.len = strlen(msg_desc.addr);
	if ((smg$put_line(&body_id, &msg_desc) &  1) == 0) {
		perror("Put line error");
		exit(1);
	}
	get_user_list(&"To : ", MAIL$_TO);
	if ((profile->cc_prompt & 1) !=  0) {
		msg_desc.addr =  &"Enter 'CC' list one name per line, empty line to terminate";
		msg_desc.len = strlen(msg_desc.addr);
		if ((smg$put_line(&body_id, &msg_desc) & 1) == 0) {
			perror("Put line error");
			exit(1);
		}
		get_user_list(&"CC : ", MAIL$_CC);
	}
	if ((profile->copy_send & 1) !=  0) {
		strcpy(to, profile->user_name);
		add_cc_in[1].buffer_length =  strlen(profile->user_name);
		if ((mail$send_add_address(&send_context, &add_cc_in, &null) & 1) ==  0) {
			perror("send_add error");
			exit(1);
		}
	}
	msg_desc.type = 0;
	msg_desc.addr = &"Subject : ";
	msg_desc.len = strlen(msg_desc.addr);
	if ((smg$put_chars(&body_id, &msg_desc) &  1) == 0) {
		perror("Put char error");
		exit(1);
	}
	msg_desc.addr = &subj[0];
	msg_desc.len = NAM$C_MAXRSS;
	memset(&subj[0], 0, NAM$C_MAXRSS +  1);
	if ((smg$read_string(&keyboard_id, &msg_desc, 0, &NAM$C_MAXRSS, 0, 0, 0, &r_len, 0, &body_id) & 1) ==  0) {
		perror("read string error");
		exit(1);
	}
	if ((attribute_in[0].buffer_length =  r_len) != 0) {
		if ((mail$send_add_attribute(&send_context, &attribute_in, &null) & 1) == 0) {
			perror("add attribute error");
			exit(1);
		}
	}
	if ((k == 4) | (k == 5)) {
		msg_desc.type = 0;
		msg_desc.addr = &"File : ";
		msg_desc.len = strlen(msg_desc.addr);
		if ((smg$put_chars(&body_id, &msg_desc) & 1) == 0) {
			perror("Put char error");
			exit(1);
		}
		msg_desc.addr = &file[0];
		msg_desc.len = NAM$C_MAXRSS;
		memset(&file[0], 0, NAM$C_MAXRSS +  1);
		if ((smg$read_string(&keyboard_id, &msg_desc, 0, &NAM$C_MAXRSS, 0, 0, 0, 0, 0, &body_id) & 1) == 0) {
			perror("read string error");
			exit(1);
		}
	}
	status = 0;
	switch (k) {
	case 2:
		send_basic();
		break;
	case 3:
		status = send_edit(profile);
		break;
	case 4:
		send_file(&file[0]);
		break;
	case 5:
		status = send_edit_file(profile, &file[0]);
		break;
	}
	clean_screen();
	smg$repaint_screen(&pasteboard_id);
	smg$set_cursor_abs(&body_id, &1, &1);
	if (status == 0) {
		if (((mail$send_message(&send_context, &send_message_in, &null)) & 1) == 0) {
			perror("Send message error");
			exit(1);
		}
	} else
	 {
		mail$send_abort(&send_context, &null, &null);
	}
	if ((mail$send_end(&send_context, &null, &null) & 1) == 0) {
		perror("send end error");
		exit(1);
	}
	lib$revert();
	sleep(1);
	if (((k == 3) | (k == 5)) & (status ==  0)) {
		if (delete(&"sys$scratch:s_mail$temp_file.tmp") ==  -1) {
			perror( "Delete temporary file sys$scratch:s_mail$temp_file.tmp error");
			exit(1);
		}
	}
}


void read_plain(message_entry *message_data)
{
	char	message[256], bottom_line[132];
	long	line_count, page_count, status;
	short	terminator;
	long	r_len;
	s_desc bottom = { 0, 0, &bottom_line };
	s_desc mess = {	0, 0, &message };

	ITMLST null = {	0, 0, 0, 0 };
	ITMLST get_sel[2] = {
		{ 4, MAIL$_MESSAGE_ID, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_rec_in[2] =  {
		{ 0, MAIL$_MESSAGE_CONTINUE, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_rec_out[2] =  {
		{ 255, MAIL$_MESSAGE_RECORD, &message, &r_len },
		{ 0, 0, 0, 0 }
	};	

	get_sel[0].buffer_address =  &message_data->id;
	if (((mail$message_get(&message_context, &get_sel, &null)) & 1) ==  0) {
		perror("Select message error");
		exit(1);
	}

	line_count = page_count =  0;
	clean_screen();
	while (1) {
		status = mail$message_get(&message_context, &get_rec_in, &get_rec_out);
		if (status == MAIL$_NOMOREREC) {
			if (line_count !=  0) {
				memset(bottom_line, 0, 132);
				strcpy(bottom_line, &"Hit any key to continue");
				bottom.len = strlen(bottom_line);
				smg$put_chars(&command_id, &bottom, &1, &1, &SMG$M_ERASE_LINE, 0, &SMG$M_BOLD);
				smg$read_keystroke(&keyboard_id, &terminator);
			}
			return;
		}
		line_count++;
		page_count++;
		mess.len = r_len;
		smg$put_line(&body_id, &mess);
		if (page_count >=  20) {
			memset(bottom_line, 0, 132);
			sprintf(bottom_line, "Read %d lines of %d - Hit any key to continue", line_count, message_data->size);
			bottom.len =  sizeof(bottom_line);
			smg$put_chars(&command_id, &bottom, &1, &1, &SMG$M_ERASE_LINE, 0, &SMG$M_BOLD);
			status =  smg$read_keystroke(&keyboard_id, &terminator);
			if (status ==  SMG$_EOF)
				return;
			if ((status &  1) == 0) {
				perror("Read keystroke error");
				exit(1);
			}
			page_count =  0;
		}
	}
}


void read_edit(message_entry *message_data, user_data *profile)
{
	char	message[256];
	long	status;
	short	terminator;
	long	r_len;
	FILE * scratch_file;
	s_desc file_name, null_name, msg_desc;
	ITMLST null = {	0, 0, 0, 0 };
	ITMLST get_sel[2] = {
		{ 4, MAIL$_MESSAGE_ID, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_rec_in[2] =  {
		{ 0, MAIL$_MESSAGE_CONTINUE, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_rec_out[2] =  {
		{ 255, MAIL$_MESSAGE_RECORD, &message, &r_len },
		{ 0, 0, 0, 0 }
	};	

	get_sel[0].buffer_address =  &message_data->id;
	if (((mail$message_get(&message_context, &get_sel, &null)) & 1) ==  0) {
		perror("Select message error");
		exit(1);
	}

	scratch_file = fopen("sys$scratch:s_mail$temp_file.tmp", "w");
	if (scratch_file == NULL) {
		perror("Error opening scratch file");
		exit(1);
	}

	clean_screen();
	while (1) {
		memset(message, 0, 256);
		status = mail$message_get(&message_context, &get_rec_in, &get_rec_out);
		if (status == MAIL$_NOMOREREC)
			break;
		if ((status & 1) ==  0) {
			perror("Get record error");
			exit(1);
		}
		if (fputs(message, scratch_file) <  0) {
			perror("put record to scratch file error");
			exit(1);
		}
		if (fputs(&"\n", scratch_file) <  0) {
			perror("put record to scratch file error");
			exit(1);
		}
	}
	if (fclose(scratch_file) !=  0) {
		perror("Close scratch file error");
		exit(1);
	}

	file_name.type = 0;
	file_name.addr = &"sys$scratch:s_mail$temp_file.tmp";
	file_name.len = strlen(file_name.addr);
	null_name.type = 0;
	null_name.addr = &"nl:";
	null_name.len = strlen(null_name.addr);
	if (strlen(&profile->editor[0]) ==  0) {
		if ((edt$edit(&file_name, &null_name) &  1) == 0) {
			perror("edit error");
			exit(1);
		}
	} else if (strcmp(&profile->editor[0], &"EDT") == 0) {
		if ((edt$edit(&file_name, &null_name) &  1) == 0) {
			perror("edit error");
			exit(1);
		}
	} else if (strcmp(&profile->editor[0], &"TPU") == 0) {
		file_name.addr =  &"TPU/OUTPUT=nl: sys$scratch:s_mail$temp_file.tmp ";
		file_name.len =  strlen(file_name.addr);
		if ((tpu$tpu(&file_name) &  1) == 0) {
			perror("edit error");
			exit(1);
		}
	} else
	 {
		msg_desc.type =  0;
		msg_desc.addr =  &"Unable to handle this type of editor-useing EDIT";
		msg_desc.len =  strlen(msg_desc.addr);
		smg$put_chars(&command_id, &msg_desc, &1, &1 , 0, &SMG$M_ERASE_LINE);
		sleep(3);
		if ((edt$edit(&file_name, &null_name) &  1) == 0) {
			perror("edit error");
			exit(1);
		}
	}

	if (delete(&"sys$scratch:s_mail$temp_file.tmp") ==  -1) {
		perror( "Delete temporary file sys$scratch:s_mail$temp_file.tmp error");
		exit(1);
	}
}


void forward_plain(message_entry *message_data, user_data *profile)
{
	unsigned short	mail_cc = MAIL$_CC, rr_len;
	char	to[NAM$C_MAXRSS], subj[NAM$C_MAXRSS], message[256];
	ITMLST begin_in[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST add_cc_in[4] = {
		{ 2, MAIL$_SEND_USERNAME_TYPE, &mail_cc, 0 },
		{ 0, MAIL$_SEND_USERNAME, &to[0], 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST null = {	0, 0, 0, 0 };

	s_desc msg_desc;

	ITMLST attribute_in[2] =  {
		{ 0, MAIL$_SEND_SUBJECT, &subj[0], 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST body_in[2] = {
		{ 0, MAIL$_SEND_RECORD, &message[0], 0 },
		{ 0, 0, 0 }
	};	

	long	r_len, status;
	ITMLST get_rec_in[2] =  {
		{ 0, MAIL$_MESSAGE_CONTINUE, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_rec_out[2] =  {
		{ 255, MAIL$_MESSAGE_RECORD, &message, &r_len },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_sel[2] = {
		{ 4, MAIL$_MESSAGE_ID, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST send_message_in[4] =  {
		{ 4, MAIL$_SEND_ERROR_ENTRY, &no_send, 0 },
		{ 4, MAIL$_SEND_SUCCESS_ENTRY, &yes_send, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	clean_screen();

	get_sel[0].buffer_address =  &message_data->id;
	if (((mail$message_get(&message_context, &get_sel, &null)) & 1) ==  0) {
		perror("Select message error");
		exit(1);
	}
	lib$establish(&exit_handler);
	if (profile->personal_name[0] ==  0) {
		begin_in[0].item_code =  MAIL$_SEND_NO_PERS_NAME;
	} else
	 {
		begin_in[0].item_code =  MAIL$_SEND_PERS_NAME;
		begin_in[0].buffer_address =  &profile->personal_name[0];
		begin_in[0].buffer_length =  strlen(&profile->personal_name[0]);
	}
	if ((mail$send_begin(&send_context, &begin_in, &null) & 1) ==  0) {
		perror("Send begin error");
		exit(1);
	}
	smg$set_cursor_abs(&body_id, &1, &1);
	msg_desc.type = 0;
	msg_desc.addr = &"Enter 'To' list, empty line to terminate";

	msg_desc.len = strlen(msg_desc.addr);
	if ((smg$put_line(&body_id, &msg_desc) & 1) == 0) {
		perror("Put line error");
		exit(1);
	}
	get_user_list(&"To : ", MAIL$_TO);
	if ((profile->cc_prompt &  1) != 0) {
		msg_desc.addr =  &"Enter 'CC' list one name per line, empty line to terminate";
		msg_desc.len =  strlen(msg_desc.addr);
		if ((smg$put_line(&body_id, &msg_desc) & 1) ==  0) {
			perror("Put line error");
			exit(1);
		}
		get_user_list(&"CC : ", MAIL$_CC);
	}
	if ((profile->copy_forward &  1) != 0) {
		strcpy(to, profile->user_name);
		add_cc_in[1].buffer_length =  strlen(profile->user_name);
		if ((mail$send_add_address(&send_context, &add_cc_in, &null) &  1) == 0) {
			perror("send_add error");
			exit(1);
		}
	}
	msg_desc.type = 0;
	msg_desc.addr = &"Subject : ";
	msg_desc.len = strlen(msg_desc.addr);
	if ((smg$put_chars(&body_id, &msg_desc) & 1) == 0) {
		perror("Put char error");
		exit(1);
	}
	msg_desc.addr = &subj[0];
	msg_desc.len = NAM$C_MAXRSS;
	memset(&subj[0], 0, NAM$C_MAXRSS +  1);
	if ((smg$read_string(&keyboard_id, &msg_desc, 0, &NAM$C_MAXRSS, 0, 0, 0, &rr_len, 0, &body_id) & 1) == 0) {
		perror("read string error");
		exit(1);
	}
	if ((attribute_in[0].buffer_length =  rr_len) != 0) {
		if ((mail$send_add_attribute(&send_context, &attribute_in, &null) & 1) ==  0) {
			perror("add attribute error");
			exit(1);
		}
	}
	while (1) {
		memset(message, 0, 256);
		status = mail$message_get(&message_context, &get_rec_in, &get_rec_out);
		if (status == MAIL$_NOMOREREC)
			break;
		if ((status & 1) ==  0) {
			perror("Get record error");
			exit(1);
		}

		body_in[0].buffer_length =  r_len;
		if ((mail$send_add_bodypart(&send_context, &body_in, &null) &  1) == 0) {
			perror("add body error");
			exit(1);
		}
	}
	clean_screen();
	smg$repaint_screen(&pasteboard_id);
	smg$set_cursor_abs(&body_id, &1, &1);
	if (((mail$send_message(&send_context, &send_message_in, &null)) & 1) == 0) {
		perror("Send message error");
		exit(1);
	}
	if ((mail$send_end(&send_context, &null, &null) & 1) ==  0) {
		perror("send end error");
		exit(1);
	}
	lib$revert();
	sleep(2);
}


void forward_edit(message_entry *message_data, user_data *profile)
{
	unsigned short	mail_cc = MAIL$_CC, rr_len;
	char	to[NAM$C_MAXRSS], subj[NAM$C_MAXRSS], message[256];
	ITMLST begin_in[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST add_cc_in[4] = {
		{ 2, MAIL$_SEND_USERNAME_TYPE, &mail_cc, 0 },
		{ 0, MAIL$_SEND_USERNAME, &to[0], 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST null = {	0, 0, 0, 0 };

	s_desc msg_desc, file_name;

	ITMLST attribute_in[2] =  {
		{ 0, MAIL$_SEND_SUBJECT, &subj[0], 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST body_in[2] = {
		{ 0, MAIL$_SEND_FILENAME, &"sys$scratch:s_mail$temp_file.tmp", 0 },
		{ 0, 0, 0, 0 }
	};	

	long	r_len, status;
	ITMLST get_rec_in[2] =  {
		{ 0, MAIL$_MESSAGE_CONTINUE, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_rec_out[2] =  {
		{ 255, MAIL$_MESSAGE_RECORD, &message, &r_len },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_sel[2] = {
		{ 4, MAIL$_MESSAGE_ID, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST send_message_in[4] =  {
		{ 4, MAIL$_SEND_ERROR_ENTRY, &no_send, 0 },
		{ 4, MAIL$_SEND_SUCCESS_ENTRY, &yes_send, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	FILE * scratch_file, *test_file;

	clean_screen();

	get_sel[0].buffer_address =  &message_data->id;
	if (((mail$message_get(&message_context, &get_sel, &null)) & 1) ==  0) {
		perror("Select message error");
		exit(1);
	}
	lib$establish(&exit_handler);
	if (profile->personal_name[0] ==  0) {
		begin_in[0].item_code =  MAIL$_SEND_NO_PERS_NAME;
	} else
	 {
		begin_in[0].item_code =  MAIL$_SEND_PERS_NAME;
		begin_in[0].buffer_address =  &profile->personal_name[0];
		begin_in[0].buffer_length =  strlen(&profile->personal_name[0]);
	}
	if ((mail$send_begin(&send_context, &begin_in, &null) & 1) ==  0) {
		perror("Send begin error");
		exit(1);
	}
	smg$set_cursor_abs(&body_id, &1, &1);
	msg_desc.type = 0;
	msg_desc.addr =  &"Enter 'To' list, empty line to terminate";
	msg_desc.len = strlen(msg_desc.addr);
	if ((smg$put_line(&body_id, &msg_desc) & 1) == 0) {
		perror("Put line error");
		exit(1);
	}
	get_user_list(&"To : ", MAIL$_TO);
	if ((profile->cc_prompt &  1) != 0) {
		msg_desc.addr =  &"Enter 'CC' list one name per line, empty line to terminate";
		msg_desc.len =  strlen(msg_desc.addr);
		if ((smg$put_line(&body_id, &msg_desc) & 1) ==  0) {
			perror("Put line error");
			exit(1);
		}
		get_user_list(&"CC : ", MAIL$_CC);
	}
	if ((profile->copy_forward &  1) != 0) {
		strcpy(to, profile->user_name);
		add_cc_in[1].buffer_length =  strlen(profile->user_name);
		if ((mail$send_add_address(&send_context, &add_cc_in, &null) &  1) == 0) {
			perror("send_add error");
			exit(1);
		}
	}
	msg_desc.type = 0;
	msg_desc.addr = &"Subject : ";
	msg_desc.len = strlen(msg_desc.addr);
	if ((smg$put_chars(&body_id, &msg_desc) & 1) == 0) {
		perror("Put char error");
		exit(1);
	}
	msg_desc.addr = &subj[0];
	msg_desc.len = NAM$C_MAXRSS;
	memset(&subj[0], 0, NAM$C_MAXRSS +  1);
	if ((smg$read_string(&keyboard_id, &msg_desc, 0, &NAM$C_MAXRSS, 0, 0, 0, &rr_len, 0, &body_id) & 1) == 0) {
		perror("read string error");
		exit(1);
	}
	if ((attribute_in[0].buffer_length =  rr_len) != 0) {
		if ((mail$send_add_attribute(&send_context, &attribute_in, &null) & 1) ==  0) {
			perror("add attribute error");
			exit(1);
		}
	}

	scratch_file = fopen("sys$scratch:s_mail$temp_file.tmp", "w");
	if (scratch_file == NULL) {
		perror("Error opening scratch file");
		exit(1);
	}
	while (1) {
		memset(message, 0, 256);
		status = mail$message_get(&message_context, &get_rec_in, &get_rec_out);
		if (status == MAIL$_NOMOREREC)
			break;
		if ((status & 1) ==  0) {
			perror("Get record error");
			exit(1);
		}
		if (fputs(message, scratch_file) <  0) {
			perror("put record to scratch file error");
			exit(1);
		}
		if (fputs(&"\n", scratch_file) <  0) {
			perror("put record to scratch file error");
			exit(1);
		}
	}
	if (fclose(scratch_file) !=  0) {
		perror("Close scratch file error");
		exit(1);
	}
	file_name.type = 0;
	file_name.addr = &"sys$scratch:s_mail$temp_file.tmp";
	file_name.len = strlen(file_name.addr);
	if (strlen(&profile->editor[0]) ==  0) {
		if ((edt$edit(&file_name) &  1) == 0) {
			perror("edit error");
			exit(1);
		}
	} else if (strcmp(&profile->editor[0], &"EDT") == 0) {
		if ((edt$edit(&file_name) &  1) == 0) {
			perror("edit error");
			exit(1);
		}
	} else if (strcmp(&profile->editor[0], &"TPU") == 0) {
		memset(&message[0], 0, 512);
		strcpy(&message[0], &"TPU  sys$scratch:s_mail$temp_file.tmp ");
		file_name.addr =  &message[0];
		file_name.len =  strlen(file_name.addr);
		if ((tpu$tpu(&file_name) &  1) == 0) {
			perror("TPU error");
			exit(1);
		}
	} else
	 {
		msg_desc.type =  0;
		msg_desc.addr =  &"Unable to handle this type of editor-useing EDIT";
		msg_desc.len =  strlen(msg_desc.addr);
		smg$put_chars(&command_id, &msg_desc, &1, &1 , 0, &SMG$M_ERASE_LINE);
		sleep(3);
		if ((edt$edit(&file_name) &  1) == 0) {
			perror("edit error");
			exit(1);
		}
	}
	if ((test_file = fopen(&"sys$scratch:s_mail$temp_file.tmp;-1", "r")) != NULL) {
		fclose(test_file);
		body_in[0].buffer_length =  strlen(body_in[0].buffer_address);
		if ((mail$send_add_bodypart(&send_context, &body_in, &null) &  1) == 0) {
			perror("add body error");
			exit(1);
		}
		clean_screen();
		smg$repaint_screen(&pasteboard_id);
		smg$set_cursor_abs(&body_id, &1, &1);
		if (((mail$send_message(&send_context, &send_message_in, &null)) & 1) ==  0) {
			perror("Send message error");
			exit(1);
		}
		if (delete(&"sys$scratch:s_mail$temp_file.tmp") ==  -1) {
			perror( "Delete temporary file sys$scratch:s_mail$temp_file.tmp error");
			exit(1);
		}
	} else
	 {
		clean_screen();
		mail$send_abort(&send_context, &null, &null);
	}
	if ((mail$send_end(&send_context, &null, &null) & 1) ==  0) {
		perror("send end error");
		exit(1);
	}
	lib$revert();
	if (delete(&"sys$scratch:s_mail$temp_file.tmp") ==  -1) {
		perror( "Delete temporary file sys$scratch:s_mail$temp_file.tmp error");
		exit(1);
	}
	sleep(2);
}


void reply_plain(message_entry *message_data, user_data *profile)
{
	long	status;
	ITMLST null = {	0, 0, 0, 0 };

	ITMLST begin_in[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	s_desc msg_desc;
	char	to[256], subj[256], message[356];
	short	mail_cc = MAIL$_CC;
	short	mail_to = MAIL$_TO;

	ITMLST add_cc_in[4] = {
		{ 2, MAIL$_SEND_USERNAME_TYPE, 	&mail_cc, 0 },
		{ 0, MAIL$_SEND_USERNAME, &to[0], 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST attribute_in[2] =  {
		{ 0, MAIL$_SEND_SUBJECT, &subj[0], 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST send_message_in[4] =  {
		{ 4, MAIL$_SEND_ERROR_ENTRY, &no_send, 0 },
		{ 4, MAIL$_SEND_SUCCESS_ENTRY, &yes_send, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST add_to_in[4] = {
		{ 2, MAIL$_SEND_USERNAME_TYPE, &mail_to, 0 },
		{ 0, MAIL$_SEND_USERNAME, 0, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	clean_screen();

	lib$establish(&exit_handler);
	if (profile->personal_name[0] ==  0) {
		begin_in[0].item_code =  MAIL$_SEND_NO_PERS_NAME;
	} else
	 {
		begin_in[0].item_code =  MAIL$_SEND_PERS_NAME;
		begin_in[0].buffer_address =  &profile->personal_name[0];
		begin_in[0].buffer_length =  strlen(&profile->personal_name[0]);
	}
	if ((mail$send_begin(&send_context, &begin_in, &null) & 1) ==  0) {
		perror("Send begin error");
		exit(1);
	}
	smg$set_cursor_abs(&body_id, &1, &1);
	add_to_in[1].buffer_address =  &message_data->reply[0];
	add_to_in[1].buffer_length =  strlen(&message_data->reply[0]);
	mail$send_add_address(&send_context, &add_to_in, &null);
	if ((profile->cc_prompt &  1) != 0) {
		msg_desc.addr =  &"Enter 'CC' list one name per line, empty line to terminate";
		msg_desc.len =  strlen(msg_desc.addr);
		if ((smg$put_line(&body_id, &msg_desc) & 1) ==  0) {
			perror("Put line error");
			exit(1);
		}
		get_user_list(&"CC : ", MAIL$_CC);
	}
	if ((profile->copy_reply &  1) != 0) {
		strcpy(to, profile->user_name);
		add_cc_in[1].buffer_length =  strlen(profile->user_name);
		if ((mail$send_add_address(&send_context, &add_cc_in, &null) &  1) == 0) {
			perror("send_add error");
			exit(1);
		}
	}

	memset(subj, 0, 256);
	strcpy(subj, "Re : ");
	strcat(subj, &message_data->subject[0]);
	attribute_in[0].buffer_length =  strlen(subj);
	if ((mail$send_add_attribute(&send_context, &attribute_in, &null) &  1) == 0) {
		perror("add attribute error");
		exit(1);
	}
	msg_desc.type = 0;
	msg_desc.addr = &message[0];
	memset(message, 0, 356);
	strcpy(message, "To : ");
	strcat(message, message_data->reply);
	msg_desc.len = strlen(message);
	smg$put_line(&body_id, &msg_desc);
	memset(message, 0, 356);
	strcpy(message, "Subj : ");
	strcat(message, subj);
	msg_desc.len = strlen(message);
	smg$put_line(&body_id, &msg_desc);
	sleep(2);
	send_basic();
	clean_screen();
	smg$repaint_screen(&pasteboard_id);
	smg$set_cursor_abs(&body_id, &1, &1);
	if (((mail$send_message(&send_context, &send_message_in, &null)) &  1) == 0) {
		perror("Send message error");
		exit(1);
	}
	if ((mail$send_end(&send_context, &null, &null) & 1) ==  0) {
		perror("send end error");
		exit(1);
	}
	lib$revert();
	sleep(2);
}


void reply_edit(message_entry *message_data, user_data *profile)
{
	long	status;
	ITMLST null = {	0, 0, 0, 0 };
	ITMLST begin_in[2] = {
		{ 0, 0, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	s_desc msg_desc;

	char	to[256], subj[256], message[356];
	short	mail_cc = MAIL$_CC;
	short	mail_to = MAIL$_TO;
	ITMLST add_cc_in[4] = {
		{ 2, MAIL$_SEND_USERNAME_TYPE, &mail_cc, 0 },
		{ 0, MAIL$_SEND_USERNAME, &to[0], 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST attribute_in[2] =  {
		{ 0, MAIL$_SEND_SUBJECT, &subj[0], 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST send_message_in[4] =  {
		{ 4, MAIL$_SEND_ERROR_ENTRY, &no_send, 0 },
		{ 4, MAIL$_SEND_SUCCESS_ENTRY, &yes_send, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST add_to_in[4] = {
		{ 2, MAIL$_SEND_USERNAME_TYPE, &mail_to, 0 },
		{ 0, MAIL$_SEND_USERNAME, 0, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	clean_screen();

	lib$establish(&exit_handler);
	if (profile->personal_name[0] ==  0) {
		begin_in[0].item_code =  MAIL$_SEND_NO_PERS_NAME;
	} else
	 {
		begin_in[0].item_code =  MAIL$_SEND_PERS_NAME;
		begin_in[0].buffer_address =  &profile->personal_name[0];
		begin_in[0].buffer_length =  strlen(&profile->personal_name[0]);
	}
	if ((mail$send_begin(&send_context, &begin_in, &null) & 1) ==  0) {
		perror("Send begin error");
		exit(1);
	}
	smg$set_cursor_abs(&body_id, &1, &1);
	add_to_in[1].buffer_address =  &message_data->reply[0];
	add_to_in[1].buffer_length =  strlen(&message_data->reply[0]);
	mail$send_add_address(&send_context, &add_to_in, &null);
	if ((profile->cc_prompt &  1) != 0) {
		msg_desc.addr =  &"Enter 'CC' list one name per line, empty line to terminate";
		msg_desc.len =  strlen(msg_desc.addr);
		if ((smg$put_line(&body_id, &msg_desc) & 1) ==  0) {
			perror("Put line error");
			exit(1);
		}
		get_user_list(&"CC : ", MAIL$_CC);
	}
	if ((profile->copy_reply &  1) != 0) {
		strcpy(to, profile->user_name);
		add_cc_in[1].buffer_length =  strlen(profile->user_name);
		if ((mail$send_add_address(&send_context, &add_cc_in, &null) &  1) == 0) {
			perror("send_add error");
			exit(1);
		}
	}
	memset(subj, 0, 256);
	strcpy(subj, "Re : ");
	strcat(subj, &message_data->subject[0]);
	attribute_in[0].buffer_length =  strlen(subj);
	if ((mail$send_add_attribute(&send_context, &attribute_in, &null) &  1) == 0) {
		perror("add attribute error");
		exit(1);
	}
	msg_desc.type = 0;
	msg_desc.addr = &message[0];
	memset(message, 0, 356);
	strcpy(message, "To : ");
	strcat(message, message_data->reply);
	msg_desc.len = strlen(message);
	smg$put_line(&body_id, &msg_desc);
	memset(message, 0, 356);
	strcpy(message, "Subj : ");
	strcat(message, subj);
	msg_desc.len = strlen(message);
	smg$put_line(&body_id, &msg_desc);
	sleep(2);
	if (send_edit(profile) ==  0) {
		clean_screen();
		smg$repaint_screen(&pasteboard_id);
		smg$set_cursor_abs(&body_id, &1, &1);
		if (((mail$send_message(&send_context, &send_message_in, &null)) & 1) ==  0) {
			perror("Send message error");
			exit(1);
		}
	} else
	 {
		clean_screen();
		mail$send_abort(&send_context, &null, &null);
	}
	if ((mail$send_end(&send_context, &null, &null) & 1) ==  0) {
		perror("send end error");
		exit(1);
	}
	lib$revert();
	sleep(2);
}


void print_msg(message_entry *message_data, user_data *profile)
{
	char	print_command[512], message[256];

	s_desc msg_desc = { 0, 0, &print_command[0] };
	s_desc null_desc = { 5, 0, &"NLA0:" };
	long	r_len, status;

	ITMLST null = {	0, 0, 0, 0 };
	ITMLST body_in[2] = {
		{ 0, MAIL$_SEND_FILENAME, &"sys$scratch:s_mail$temp_file.tmp", 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_rec_in[2] =  {
		{ 0, MAIL$_MESSAGE_CONTINUE, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_rec_out[2] =  {
		{ 255, MAIL$_MESSAGE_RECORD, &message, &r_len },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_sel[2] = {
		{ 4, MAIL$_MESSAGE_ID, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	FILE * scratch_file;

	clean_screen();

	get_sel[0].buffer_address =  &message_data->id;
	if (((mail$message_get(&message_context, &get_sel, &null)) & 1) ==  0) {
		perror("Select message error");
		exit(1);
	}

	scratch_file = fopen("sys$scratch:s_mail$temp_print_file.tmp", "w");
	if (scratch_file == NULL) {
		perror("Error opening scratch file");
		exit(1);
	}
	while (1) {
		memset(message, 0, 256);
		status = mail$message_get(&message_context, &get_rec_in, &get_rec_out);
		if (status == MAIL$_NOMOREREC)
			break;
		if ((status & 1) ==  0) {
			perror("Get record error");
			exit(1);
		}
		if (fputs(message, scratch_file) <  0) {
			perror("put record to scratch file error");
			exit(1);
		}
		if (fputs(&"\n", scratch_file) <  0) {
			perror("put record to scratch file error");
			exit(1);
		}
	}
	if (fclose(scratch_file) !=  0) {
		perror("Close scratch file error");
		exit(1);
	}

	memset(print_command, 0, 512);
	strcpy(print_command, "$ print ");
	if (strlen(profile->queue) !=  0) {
		strcat(print_command, "/queue=");
		strcat(print_command, profile->queue);
	}
	if (strlen(profile->form) !=  0) {
		strcat(print_command, "/form=");
		strcat(print_command, profile->form);
	}
	strcat(print_command, "/delete   ");
	strcat(print_command, "sys$scratch:s_mail$temp_print_file.tmp");
	msg_desc.len = strlen(print_command);
	if (((lib$spawn(&msg_desc, &null_desc, &null_desc)) &  1) == 0) {
		perror("system print error");
		exit(1);
	}
}


void extract_msg(message_entry *message_data)
{
	char	file[NAM$C_MAXRSS];
	char	message[256];
	long	r_len;
	unsigned short	rr_len;

	ITMLST null = {	0, 0, 0, 0 };
	ITMLST get_rec_in[2] =  {
		{ 0, MAIL$_MESSAGE_CONTINUE, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_rec_out[2] =  {
		{ 255, MAIL$_MESSAGE_RECORD, &message, &r_len },
		{ 0, 0, 0, 0 }
	};	

	ITMLST get_sel[2] = {
		{ 4, MAIL$_MESSAGE_ID, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	long	status;

	s_desc msg_desc = { 7, 0, &"File : " };
	s_desc file_desc = { NAM$C_MAXRSS, 0, &file[0] };

	FILE * scratch_file;

	clean_screen();

	get_sel[0].buffer_address =  &message_data->id;
	if (((mail$message_get(&message_context, &get_sel, &null)) & 1) ==  0) {
		perror("Select message error");
		exit(1);
	}

	if ((smg$put_chars(&body_id, &msg_desc) & 1) == 0) {
		perror("Put char error");
		exit(1);
	}
	if ((smg$read_string(&keyboard_id, &file_desc, 0, &NAM$C_MAXRSS, 0, 0, 0, &rr_len, 0, &body_id) & 1) ==  0) {
		perror("read string error");
		exit(1);
	}
	file[rr_len] = 0;

	scratch_file = fopen(&file, "w");
	if (scratch_file == NULL) {
		perror("Error opening file");
		exit(1);
	}
	while (1) {
		memset(message, 0, 256);
		status = mail$message_get(&message_context, &get_rec_in, &get_rec_out);
		if (status == MAIL$_NOMOREREC)
			break;
		if ((status & 1) ==  0) {
			perror("Get record error");
			exit(1);
		}
		if (fputs(message, scratch_file) <  0) {
			perror("put record to file error");
			exit(1);
		}
		if (fputs(&"\n", scratch_file) <  0) {
			perror("put record to file error");
			exit(1);
		}
	}
	if (fclose(scratch_file) !=  0) {
		perror("Close file error");
		exit(1);
	}
}


void file_msg(message_entry *message_data, user_data *profile, long newmail)
{
	ITMLST null = {	0, 0, 0, 0 };
	ITMLST copy_in[6] = {
		{ 0, MAIL$_MESSAGE_FOLDER, 0, 0 },
		{ 4, MAIL$_MESSAGE_ID, 0, 0 },
		{ 0, MAIL$_MESSAGE_DEFAULT_NAME, 0, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, MAIL$_MESSAGE_DELETE, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST set_list[2] = {
		{ 2, MAIL$_USER_SET_NEW_MESSAGES, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	long	status;
	char	folder[NAM$C_MAXRSS];
	unsigned short	rr_len;

	s_desc msg_desc = {
		9, 0, &"Folder : " };
	s_desc folder_desc = { NAM$C_MAXRSS, 0, &folder[0] };

	clean_screen();

	if ((smg$put_chars(&body_id, &msg_desc) & 1) == 0) {
		perror("Put char error");
		exit(1);
	}
	if ((smg$read_string(&keyboard_id, &folder_desc, 0, &NAM$C_MAXRSS, &TRM$M_TM_CVTLOW, 0, 0, &rr_len, 0, &body_id) &
	    1) == 0) {
		perror("read string error");
		exit(1);
	}
	folder[rr_len] = 0;
	copy_in[0].buffer_length =  rr_len;
	copy_in[0].buffer_address =  &folder[0];
	copy_in[1].buffer_address =  &message_data->id;
	copy_in[2].buffer_address =  profile->result_spec;
	copy_in[2].buffer_length =  strlen(copy_in[2].buffer_address);
	if (((mail$message_copy(&message_context, &copy_in, &null)) & 1) ==  0) {
		perror("file message error");
		exit(1);
	}
	if (newmail != 0) {
		if ((--profile->new_messages) <  0)
			profile->new_messages =  0;
		set_list[0].buffer_address =  &profile->new_messages;
		if ((mail$user_set_info(&user_context, set_list, &null) &  1) == 0)
			exit(1);
	}
}


void delete_message(message_entry *message_data, user_data *profile, long newmail)
{
	ITMLST null = {	0, 0, 0, 0 };
	ITMLST del_in[2] = {
		{ 4, MAIL$_MESSAGE_ID, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST set_list[2] = {
		{ 2, MAIL$_USER_SET_NEW_MESSAGES, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	long	status;

	del_in[0].buffer_address =  &message_data->id;
	if (((mail$message_delete(&message_context, &del_in, &null)) & 1) ==  0) {
		perror("delete error");
		exit(1);
	}
	if (newmail != 0) {
		if ((--profile->new_messages) <  0)
			profile->new_messages =  0;
		set_list[0].buffer_address =  &profile->new_messages;
		if ((mail$user_set_info(&user_context, set_list, &null) &  1) == 0)
			exit(1);
	}
}


open_folder(char *folder_name, user_data *profile)
{
	long	msg_count;
	long	i, j, k, l, newmail,
	first_pass, read_file,
	move_file;
	short	terminator;
	long	last_selection = 2,
	last_selection_2 = 2;

	ITMLST null[] = {
		{ 0, 0, 0, 0 }
	};	

	ITMLST folder_info[3] =  {
		{ 0, MAIL$_MESSAGE_FOLDER, 0, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST message_info[7] =  {
		{ 4, MAIL$_MESSAGE_CURRENT_ID,	0, 0 },
		{ 255, MAIL$_MESSAGE_DATE, 0, 0 },
		{ 4, MAIL$_MESSAGE_SIZE, 0, 0 },
		{ 255, MAIL$_MESSAGE_FROM, 0, 0 },
		{ 255, MAIL$_MESSAGE_REPLY_PATH, 0, 0 },
		{ 255, MAIL$_MESSAGE_SUBJECT, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST folder_contents[2] =  {
		{ 4, MAIL$_MESSAGE_SELECTED, &msg_count, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST next_message[3] =  {
		{ 0, MAIL$_MESSAGE_NEXT, 0, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST message_begin_in[3] =  {
		{ sizeof(file_context),	MAIL$_MESSAGE_FILE_CTX,	&file_context, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST copy_in[6] = {
		{ 4, MAIL$_MESSAGE_FOLDER, &"MAIL", 0 },
		{ 4, MAIL$_MESSAGE_ID, 0, 0 },
		{ 0, MAIL$_MESSAGE_DEFAULT_NAME, 0, 0 },
		{ 0, MAIL$_NOSIGNAL, 0, 0 },
		{ 0, MAIL$_MESSAGE_DELETE, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	ITMLST set_list[2] = {
		{ 2, MAIL$_USER_SET_NEW_MESSAGES, 0, 0 },
		{ 0, 0, 0, 0 }
	};	

	message_entry * messages, *temp_mess, *last_mess;
	char	folder_banner[80];
	s_desc msg_desc, folder_desc =  { 80, 0, &folder_banner[0] };

	struct m_descripter menu_list = 
	 {
		0, 0, 0, 0, 0,
		0, 0, 0, 0, 0,
		0, 0, 0		
	};

	char	*temp_list;

	messages = 0;
	newmail = 0;
	first_pass = 0;

	if (strlen("NEWMAIL") ==  strlen(folder_name)) {
		if (strcmp("NEWMAIL", folder_name) ==  0)
			newmail =  1;
	}

	while (1) {
		while (messages !=  0) {
			temp_mess =  messages;
			messages =  messages->next;
			free(temp_mess);
		}
		clean_screen();
		folder_info[0].buffer_length =  i = strlen(folder_name);
		folder_info[0].buffer_address =  folder_name;

		message_context =  0;
		if (mail$message_begin(&message_context, message_begin_in, null) !=  SS$_NORMAL) {
			perror("mail$message_begin error");
			exit(1);
		}
		j = mail$message_select(&message_context, &folder_info, &folder_contents);
		if ((j == MAIL$_NOTEXIST) ||  (msg_count == 0)) {
			if (first_pass ==  0) {
				msg_desc.addr =  &"No Such Folder";
				msg_desc.type = 0;
				msg_desc.len = strlen(msg_desc.addr);
				smg$put_chars_highwide(&body_id, &msg_desc, &4, &26);
				sleep(4);
			}
			return;
		}
		memset(folder_banner, 32, 80);
		strcpy(folder_banner, "Folder : ");
		strcat(folder_banner, folder_name);
		folder_desc.len =  strlen(folder_banner);
		smg$put_chars(&message_id, &folder_desc, &1, &1, 0, &SMG$M_ERASE_LINE);

		first_pass = 1;
		if ((j & 1) ==  0) {
			perror("Message select error");
			exit(j);
		}
		last_mess = 0;
		for (k = 0; k <  msg_count; k++) {
			temp_mess =  malloc(sizeof(message_entry));

			if (temp_mess ==  0) {
				perror("Message allocation error");
				exit(1);
			}
			memset(temp_mess, 0, sizeof(message_entry));
			message_info[0].buffer_address =  &temp_mess->id;
			message_info[1].buffer_address =  &temp_mess->date;
			message_info[2].buffer_address =  &temp_mess->size;
			message_info[3].buffer_address =  &temp_mess->from;
			message_info[4].buffer_address =  &temp_mess->reply;
			message_info[5].buffer_address =  &temp_mess->subject;
			j = mail$message_info(&message_context, &next_message, &message_info);
			if (j ==  MAIL$_NOMOREMSG)
				break;
			if ((j &  1) == 0) {
				perror("Folder message info error");
				exit(j);
			}
			if (messages ==  0) {
				messages =  last_mess = temp_mess;
			} else
			 {
				last_mess->next =  temp_mess;
				last_mess = temp_mess;
			}
		}
		menu_list.length =  79;
		menu_list.dtype =  DSC$K_DTYPE_T;
		menu_list.class =  DSC$K_CLASS_A;
		menu_list.pointer =  malloc(79 * (msg_count +  1));
		if (menu_list.pointer ==  NULL) {
			perror("allocation error");
			exit(1);
		}

		memset(menu_list.pointer, 32, 79 * (msg_count +  1));
		menu_list.scale =  0;
		menu_list.digits =  0;
		menu_list.aflags =  14 * 16;
		menu_list.dimct =  1;
		menu_list.arsize =  79 * (msg_count +  1);
		menu_list.a0 =  menu_list.pointer -  79;
		menu_list.m1 =  msg_count + 1;
		menu_list.l1 =  1;
		menu_list.u1 =  msg_count + 1;
		temp_list = menu_list.pointer;
		strcpy(temp_list, &"Exit");
		temp_list += 79;
		temp_mess = messages;
		for (k = 0; k <  msg_count; k++) {
			strncpy(temp_list, &temp_mess->from[0], 20);
			strncpy(temp_list +  22, &temp_mess->date, 11);
			strncpy(temp_list +  34, &temp_mess->subject, 45);
			temp_list +=  79;
			temp_mess =  temp_mess->next;
		}
		if ((smg$create_menu(&body_id, &menu_list, &SMG$K_VERTICAL) &  1) == 0) {
			perror("Create folder menu error");
			exit(1);
		}
		k = 0;
		j = smg$select_from_menu(&keyboard_id, &body_id, &k, &last_selection , &SMG$M_RETURN_IMMED, 0, 0, &terminator);
		free(menu_list.pointer);
		if (j == SMG$_EOF)
			return;
		if ((j & 1) ==  0) {
			perror("Select error");
			exit(1);
		}
		if (k == 1)
			return;
		last_selection =  k;
		temp_mess = messages;
		k -= 2;
		while (k > 0) {
			temp_mess =  temp_mess->next;
			k--;
		}

		memset(folder_banner, 32, 80);
		strncpy(folder_banner, &temp_mess->from[0], 20);
		strncpy(folder_banner +  22, &temp_mess->date, 11);
		strncpy(folder_banner +  34, &temp_mess->subject, 45);
		folder_desc.len =  79;

		menu_list.length =  20;
		menu_list.dtype =  DSC$K_DTYPE_T;
		menu_list.class =  DSC$K_CLASS_A;
		menu_list.pointer =  malloc(20 * 11);
		if (menu_list.pointer ==  NULL) {
			perror("allocation error");
			exit(1);
		}
		memset(menu_list.pointer, 32, 20 * 11);
		menu_list.scale =  0;
		menu_list.digits =  0;
		menu_list.aflags =  14 * 16;
		menu_list.dimct =  1;
		menu_list.arsize =  20 * 11;
		menu_list.a0 =  menu_list.pointer -  20;
		menu_list.m1 =  11;
		menu_list.l1 =  1;
		menu_list.u1 =  11;
		temp_list = menu_list.pointer;
		strcpy(temp_list, &"Exit");
		temp_list += 20;
		strcpy(temp_list, &"Read");
		temp_list += 20;
		strcpy(temp_list, &"Read/Edit");
		temp_list += 20;
		strcpy(temp_list, &"Forward");
		temp_list += 20;
		strcpy(temp_list, &"Forward/Edit");
		temp_list += 20;
		strcpy(temp_list, &"Reply");
		temp_list += 20;
		strcpy(temp_list, &"Reply/Edit");
		temp_list += 20;
		strcpy(temp_list, &"Print");
		temp_list += 20;
		strcpy(temp_list, &"Extract");
		temp_list += 20;
		strcpy(temp_list, &"File");
		temp_list += 20;
		strcpy(temp_list, &"Delete");
		read_file = 0;
		move_file = 0;
		last_selection_2 =  2;
		while (1) {
			clean_screen();
			smg$repaint_screen(&pasteboard_id);
			smg$put_chars(&message_id, &folder_desc, &1, &1, 0, &SMG$M_ERASE_LINE);
			if ((smg$create_menu(&body_id, &menu_list, &SMG$K_VERTICAL) &  1) == 0) {
				perror("Create message menu error");
				exit(1);
			}
			k = 0;
			j = smg$select_from_menu(&keyboard_id, &body_id, &k , &last_selection_2, &SMG$M_RETURN_IMMED, 0,
			     			     0, &terminator);
			if (j ==  SMG$_EOF)
				break;
			if ((j &  1) == 0) {
				perror("Select error");
				exit(1);
			}
			if (k ==  1)
				break;
			last_selection_2 = k;
			switch (k) {
			case 2:
				read_plain(temp_mess);
				read_file = 1;
				break;
			case 3:
				read_edit(temp_mess, profile);
				read_file = 1;
				break;
			case 4:
				forward_plain(temp_mess, profile);
				break;
			case 5:
				forward_edit(temp_mess, profile);
				read_file = 1;
				break;
			case 6:
				reply_plain(temp_mess, profile);
				break;
			case 7:
				reply_edit(temp_mess, profile);
				break;
			case 8:
				print_msg(temp_mess, profile);
				break;
			case 9:
				extract_msg(temp_mess);
				break;
			case 10:
				file_msg(temp_mess, profile, newmail);
				move_file = 1;
				break;
			case 11:
				delete_message(temp_mess, profile, newmail);
				move_file = 1;
				break;
			}
			if (k ==  10 | k ==  11)
				break;
		}
		if ((newmail !=  0) && (read_file !=  0) && (move_file ==  0)) {
			copy_in[1].buffer_address =  &temp_mess->id;
			copy_in[2].buffer_address =  profile->result_spec;
			copy_in[2].buffer_length =  strlen(copy_in[2].buffer_address);
			if (((mail$message_copy(&message_context, &copy_in, &null)) &  1) == 0) {
				perror("file message error");
				exit(1);
			}
			if ((--profile->new_messages) <  0)
				profile->new_messages =  0;
			set_list[0].buffer_address = &profile->new_messages;
			if ((mail$user_set_info(&user_context, set_list, &null) &  1) == 0) {
				exit(1);
			}
		}
		free(menu_list.pointer);
		if ((mail$message_end(&message_context, &null, &null) &  1) == 0) {
			perror("message end error");
			exit(1);
		}
	}
}


main(int argc, char *argv[])
{
	struct node list = { 0, 0, 0 };
	struct node *tmp;

	user_data profile;

	long	sel, i;
	int	last_selection = 1;

	file_context =  0;
	message_context =  0;
	user_context =  0;
	send_context =  0;

	init_mail();
	init_screen();

	while (1) {
		update_profile(&profile, &list);
		sel = do_main_menu(&profile, &list, last_selection);
		last_selection =  sel;
		switch (sel) {
		case 1:	/*open new*/
			if (profile.new_messages != 0)
				open_folder("NEWMAIL", &profile);
			break;
		case 2:
			send_mail(&profile);
			break;
		case 3: /*set/show*/
			set_show(&profile);
			break;
		case 4: /*purge*/
			purge_mail();
			break;
		case 5: /*compress*/
			compress_mail();
			break;
		case 6: /*refresh*/
			smg$repaint_screen(&pasteboard_id);
			break;
		case 7: /*exit*/
			if ((profile.auto_purge & 1) != 0)
				purge_mail();
			smg$delete_pasteboard(&pasteboard_id);
			exit(0);
			break;
		default: /*open folder*/
			tmp =  &list;
			for (i = 0; i < (sel - 7); i++)
				tmp = tmp->next;
			open_folder(tmp->folder_name, &profile);
			break;
		}
	}
}


