/* textfncs.c */
#include "ml.h"
Boolean hex_flag = FALSE;
Boolean found_hex = FALSE;
static unsigned char hex1 = NUL_TERM;
Widget textshell;
int textdone;
int confirm_done;
Menu confirm_menu[] =
{
{ NULL, "confirm_ok", NUL_TERM,
confirm_ok, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "confirm_cancel", NUL_TERM,
confirm_cancel, NULL, 0, NULL, NULL, BTN_ON },
};
Menu confirm_yn_menu[] =
{
{ NULL, "confirm_yes", NUL_TERM,
confirm_ok, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "confirm_no", NUL_TERM,
confirm_cancel, NULL, 0, NULL, NULL, BTN_ON },
};
Menu text_input_menu[] =
{
{ NULL, "text_input_accept", NUL_TERM,
text_input_accept, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "text_input_cancel", NUL_TERM,
text_input_cancel, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "text_input_HELP", NUL_TERM,
text_input_help, NULL, 0, NULL, NULL, BTN_ON },
};
Menu spell_menu[] =
{
{ NULL, "spell_next", NUL_TERM,
spell_next, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "spell_cancel", NUL_TERM,
spell_cancel, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "spell_remember", NUL_TERM,
spell_remember, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "spell_HELP", NUL_TERM,
spell_help, NULL, 0, NULL, NULL, BTN_ON },
};
Menu search_menu[] =
{
{ NULL, "search_search", NUL_TERM,
search_search, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "search_replace", NUL_TERM,
search_replace, NULL, 0, NULL, NULL, BTN_MAILBOX_NOEDIT },
{ NULL, "search_cancel", NUL_TERM,
search_cancel, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "search_HELP", NUL_TERM,
search_help, NULL, 0, NULL, NULL, BTN_ON },
};
/*
* Keep from dragging the current selection in a modal list widget into
* another widget which has no keyboard focus ability, which core dumps.
*
*/
char GLOBAL_modal_list_translations[] =
" <Btn2Down>: ListEndSelect() \n\
<Btn2Up>: ListEndSelect() \n\
<Btn2Motion>: ListEndSelect() \n";
char GLOBAL_lview_pop_translations[] =
" <Btn3Down>: lview-pop() \n";
char GLOBAL_read_pop_translations[] =
" <Btn3Down>: read-pop() \n";
char GLOBAL_compose_pop_translations[] =
" <Btn3Down>: compose-pop() \n";
char GLOBAL_filters_pop_translations[] =
" <Btn3Down>: filters-pop() \n";
char GLOBAL_mailboxes_pop_translations[] =
" <Btn3Down>: mailboxes-pop() \n";
char GLOBAL_mailcopy_pop_translations[] =
" <Btn3Down>: mailcopy-pop() \n";
char GLOBAL_addresses_pop_translations[] =
" <Btn3Down>: addresses-pop() \n";
char GLOBAL_note_pop_translations[] =
" <Btn3Down>: note-pop() \n";
char GLOBAL_help_pop_translations[] =
" <Btn3Down>: help-pop() \n";
char GLOBAL_netconf_pop_translations[] =
" <Btn3Down>: netconf-pop() \n";
char GLOBAL_messages_pop_translations[] =
" <Btn3Down>: messages-pop() \n";
char GLOBAL_text_translations[] =
" ~Meta ~Alt Ctrl<Key>a: beginning-of-line() \n\
~Meta ~Alt Ctrl<Key>b: backward-character() \n\
~Meta ~Alt Ctrl<Key>d: delete-next-character() \n\
~Meta ~Alt Ctrl<Key>e: end-of-line() \n\
~Meta ~Alt Ctrl<Key>f: forward-character() \n\
~Meta ~Alt Ctrl<Key>g: process-cancel() \n\
~Meta ~Alt Ctrl<Key>h: delete-previous-character() \n\
~Meta ~Alt Ctrl<Key>k: delete-to-end-of-line() \n\
~Meta ~Alt Ctrl<Key>n: next-line() \n\
~Meta ~Alt Ctrl<Key>p: previous-line() \n\
~Meta ~Alt Ctrl<Key>s: search-text() \n\
~Meta ~Alt Ctrl<Key>v: next-page() \n\
~Meta ~Alt Ctrl<Key>w: cut-clipboard() \n\
~Meta ~Alt Ctrl<Key>y: paste-clipboard() \n\
~Meta ~Alt Ctrl<Key>/: hex-input() \n\
Meta ~Ctrl<Key>b: backward-word() \n\
Alt ~Ctrl<Key>b: backward-word() \n\
Meta ~Ctrl<Key>d: delete-next-word() \n\
Alt ~Ctrl<Key>d: delete-next-word() \n\
Meta ~Ctrl<Key>f: forward-word() \n\
Alt ~Ctrl<Key>f: forward-word() \n\
Meta ~Ctrl<Key>w: copy-clipboard() \n\
Alt ~Ctrl<Key>w: copy-clipboard() \n\
Meta ~Ctrl<Key>osfLeft: backward-word() \n\
Alt ~Ctrl<Key>osfLeft: backward-word() \n\
Meta ~Ctrl<Key>osfRight: forward-word() \n\
Alt ~Ctrl<Key>osfRight: forward-word() \n\
Meta ~Ctrl<Key>osfBackSpace: delete-previous-word() \n\
Alt ~Ctrl<Key>osfBackSpace: delete-previous-word() \n\
Meta ~Ctrl<Key>osfDelete: delete-next-word() \n\
Alt ~Ctrl<Key>osfDelete: delete-next-word() \n\
<Key>osfPageUp: previous-page() \n\
<Key>osfPageDown: next-page() \n\
~Meta ~Alt Ctrl<Key>osfPageUp: previous-page() \n\
~Meta ~Alt Ctrl<Key>osfPageDown: next-page() \n\
Meta ~Ctrl<Key>v: previous-page() \n\
Alt ~Ctrl<Key>v: previous-page() \n ";
char GLOBAL_text_field_translations[] =
" ~Meta ~Alt Ctrl<Key>a: beginning-of-line() \n\
~Meta ~Alt Ctrl<Key>b: backward-character() \n\
~Meta ~Alt Ctrl<Key>d: delete-next-character() \n\
~Meta ~Alt Ctrl<Key>e: end-of-line() \n\
~Meta ~Alt Ctrl<Key>f: forward-character() \n\
~Meta ~Alt Ctrl<Key>g: process-cancel() \n\
~Meta ~Alt Ctrl<Key>h: delete-previous-character() \n\
~Meta ~Alt Ctrl<Key>k: delete-to-end-of-line() \n\
~Meta ~Alt Ctrl<Key>s: search-text() \n\
~Meta ~Alt Ctrl<Key>w: cut-clipboard() \n\
~Meta ~Alt Ctrl<Key>y: paste-clipboard() \n\
~Meta ~Alt Ctrl<Key>/: hex-input() \n\
Meta ~Ctrl<Key>b: backward-word() \n\
Alt ~Ctrl<Key>b: backward-word() \n\
Meta ~Ctrl<Key>d: delete-next-word() \n\
Alt ~Ctrl<Key>d: delete-next-word() \n\
Meta ~Ctrl<Key>f: forward-word() \n\
Alt ~Ctrl<Key>f: forward-word() \n\
Meta ~Ctrl<Key>w: copy-clipboard() \n\
Alt ~Ctrl<Key>w: copy-clipboard() \n\
Meta ~Ctrl<Key>osfLeft: backward-word() \n\
Alt ~Ctrl<Key>osfLeft: backward-word() \n\
Meta ~Ctrl<Key>osfRight: forward-word() \n\
Alt ~Ctrl<Key>osfRight: forward-word() \n\
Meta ~Ctrl<Key>osfBackSpace: delete-previous-word() \n\
Alt ~Ctrl<Key>osfBackSpace: delete-previous-word() \n\
Meta ~Ctrl<Key>osfDelete: delete-next-word() \n\
Alt ~Ctrl<Key>osfDelete: delete-next-word() \n ";
char GLOBAL_nonterminal_text_field_translations[] =
" !<Key>Return: next-tab-group() \n\
!<Key>Linefeed: next-tab-group() \n ";
char GLOBAL_terminal_text_field_translations[] =
" <Key>Return: activate() \n\
<Key>Linefeed: activate() \n ";
#ifdef __STDC__
int ml_strcoll(unsigned char *s1, unsigned char *s2)
#else
int ml_strcoll(s1, s2)
unsigned char *s1;
unsigned char *s2;
#endif
{
return(strcoll((char *) s1, (char *) s2));
}
#ifdef __STDC__
unsigned char *GetUnTextField(Widget w)
#else
unsigned char *GetUnTextField(w)
Widget w;
#endif
{
return((unsigned char *) XmTextGetString(w));
}
#ifdef __STDC__
char *GetTextField(Widget w)
#else
char *GetTextField(w)
Widget w;
#endif
{
return(XmTextGetString(w));
}
#ifdef __STDC__
void TextSetString(Widget w, unsigned char *str)
#else
void TextSetString(w, str)
Widget w;
unsigned char *str;
#endif
{
XmTextSetString(w,(char *) str);
}
#ifdef __STDC__
void AppendText(Widget w, char *str)
#else
void AppendText(w, str)
Widget w;
char *str;
#endif
{
XmTextPosition pos;
if(!str)
return;
pos = XmTextGetLastPosition(w);
XmTextInsert(w,pos,str);
pos = XmTextGetLastPosition(w);
XmTextSetInsertionPosition(w, pos);
return;
}
#ifdef __STDC__
void InsertText(Widget w, char *str)
#else
void InsertText(w, str)
Widget w;
char *str;
#endif
{
XmTextPosition pos;
if(!str)
return;
pos = XmTextGetInsertionPosition(w);
XmTextInsert(w,pos,str);
XmTextSetInsertionPosition(w, pos + strlen(str));
return;
}
#ifdef __STDC__
void text_nospace_edit(Widget w, XtPointer zilch, XtPointer call_data)
#else
void text_nospace_edit(w,zilch,call_data)
Widget w;
XtPointer zilch;
XtPointer call_data;
#endif
{
XmTextVerifyCallbackStruct *ptr = (XmTextVerifyCallbackStruct *) call_data;
register char *n;
if(ptr == NULL)
return;
if(ptr->text->length != 0) {
for(n = ptr->text->ptr; *n != NUL_TERM; n ++)
if((*n == SPACECHAR) || (*n == TABCHAR))
*n = '-';
ptr->text->length = strlen(ptr->text->ptr);
ptr->doit = TRUE;
}
return;
}
#ifdef __STDC__
void text_hex_edit(Widget w, XtPointer zilch, XtPointer call_data)
#else
void text_hex_edit(w,zilch,call_data)
Widget w;
XtPointer zilch;
XtPointer call_data;
#endif
{
unsigned char a;
unsigned char x;
XmTextVerifyCallbackStruct *ptr = (XmTextVerifyCallbackStruct *) call_data;
if(ptr == NULL)
return;
if(hex_flag == FALSE) {
ptr->doit = TRUE;
found_hex = FALSE;
hex1 = NUL_TERM;
return;
}
else {
x = *ptr->text->ptr;
if(! isxdigit(x)) {
hex_flag = FALSE;
ptr->doit = TRUE;
found_hex = FALSE;
hex1 = NUL_TERM;
return;
}
if(found_hex == FALSE) {
found_hex = TRUE;
if(isdigit(x))
hex1 = x - '0';
else
hex1 = x - (isupper(x) ? 'A' - 10 : 'a' - 10);
ptr->text->length = 0;
ptr->doit = TRUE;
return;
}
else {
if(isdigit(x))
a = x - '0';
else
a = x - (isupper(x) ? 'A' - 10 : 'a' - 10);
x = (hex1 << 4);
x += a;
*(ptr->text->ptr) = x;
hex_flag = FALSE;
found_hex = FALSE;
ptr->doit = TRUE;
}
}
return;
}
#ifdef __STDC__
void text_field_edit(Widget w, XtPointer zilch, XtPointer call_data)
#else
void text_field_edit(w,zilch,call_data)
Widget w;
XtPointer zilch;
XtPointer call_data;
#endif
{
unsigned char a;
unsigned char x;
XmTextVerifyCallbackStruct *ptr = (XmTextVerifyCallbackStruct *) call_data;
register char *n;
if(ptr == NULL)
return;
if((hex_flag == FALSE) || (ptr->text->length > 1)) {
if(ptr->text->length != 0) {
for(n = ptr->text->ptr; *n != NUL_TERM; n ++)
if(*n == LFCHAR)
*n = NUL_TERM;
ptr->text->length = strlen(ptr->text->ptr);
}
ptr->doit = TRUE;
found_hex = FALSE;
hex1 = NUL_TERM;
return;
}
else {
x = *ptr->text->ptr;
if(! isxdigit((unsigned char) x)) {
hex_flag = FALSE;
ptr->doit = TRUE;
found_hex = FALSE;
hex1 = NUL_TERM;
return;
}
if(found_hex == FALSE) {
found_hex = TRUE;
if(isdigit((unsigned char) x))
hex1 = x - '0';
else
hex1 = x - (isupper((unsigned char) x) ? 'A' - 10 : 'a' - 10);
ptr->text->length = 0;
ptr->doit = TRUE;
return;
}
else {
if(isdigit((unsigned char) x))
a = x - '0';
else
a = x - (isupper((unsigned char) x) ? 'A' - 10 : 'a' - 10);
x = (hex1 << 4);
x += a;
if((x == LFCHAR) || (x == NUL_TERM))
ptr->doit = FALSE;
else {
*(ptr->text->ptr) = x;
ptr->doit = TRUE;
}
hex_flag = FALSE;
found_hex = FALSE;
}
}
return;
}
#ifdef __STDC__
void passwd_edit(Widget w, Remote_Auth *authst, XtPointer call_data)
#else
void passwd_edit(w,authst,call_data)
Widget w;
Remote_Auth *authst;
XtPointer call_data;
#endif
{
XmTextVerifyCallbackStruct * ptr;
int n = 0;
int num_inserted;
ptr = (XmTextVerifyCallbackStruct *) call_data;
if(ptr == NULL)
return;
if(ptr->text->length == 0) {
delete_at(ptr->startPos,
ptr->endPos,
authst->workspace);
}
else {
num_inserted = insert_at(ptr->currInsert,
ptr->text->ptr,
authst->workspace);
for(n = 0; n < num_inserted; n ++)
ptr->text->ptr[n] = PASSWD_CHAR;
ptr->doit = TRUE;
}
return;
}
#ifdef __STDC__
void delete_at(int pos1, int pos2, char *str)
#else
void delete_at(pos1,pos2,str)
int pos1;
int pos2;
char *str;
#endif
{
int i, j;
char buf[FILEBUFFLEN];
for(i = 0; i < pos1; i ++)
buf[i] = str[i];
j = i;
for(i = pos1; i < pos2; i ++ )
;
while(str[i]) {
buf[j] = str[i];
j++;
i++;
}
buf[j] = NUL_TERM;
strcpy(str,buf);
for(i = 0; i < FILEBUFFLEN; i ++)
buf[i] = NUL_TERM;
return;
}
#ifdef __STDC__
int insert_at(int pos, char *ins, char *str)
#else
int insert_at(pos,ins,str)
int pos;
char *ins;
char *str;
#endif
{
int i, j, k;
int base_len = strlen(str);
int insert_len = strlen(ins);
char buf[FILEBUFFLEN];
if(pos >= base_len) {
strcat(str,ins);
return(insert_len);
}
else {
for(i = 0; i < pos; i ++)
buf[i] = str[i];
buf[i] = NUL_TERM;
j = 0;
for(k = pos; k < (pos + insert_len); k ++) {
buf[k] = ins[j];
j ++;
}
buf[pos + insert_len] = NUL_TERM;
strcat(buf,&str[pos]);
strcpy(str, buf);
}
for(i = 0; i < FILEBUFFLEN; i ++)
buf[i] = NUL_TERM;
return(insert_len);
}
/*
* scramble() produces a non (easily) readable copy of a string,
* in allocated space. It also works in reverse to unscramble
* previously scrambled strings. This program calls "wipeout" as
* soon as it is able to zero our the password strings it uses.
* This is all just so we don't leave cleartext passwords laying
* around in core files. To steal a quote from "Road Warrior",
* ... "A clever fella'; a REAL clever fella'... might..."
* But there's NOTHING we can do to fool a REAL clever fella'.
* The user is gonna' get annoyed if we ask them for the same password
* over and over again. That could be even more dangerous across the
* net by means of "XKey snoops" than a core file with scrambled passwords.
* Anybody who is able, should make use of the server's autologin feature
* which uses rsh protocols to exec the server when it's linked to
* "/etc/rimapd". PGP and FTP also use the authentication module,
* so even that's not perfect. We just try and do the best we can.
* Caller needs to free the returned string.
*/
#ifdef __STDC__
char *scramble(char *str)
#else
char *scramble(str)
char *str;
#endif
{
int i;
char *ret;
if(! str)
return(NULL);
ret = (cpystr(str));
for(i = 0; (ret[i] != NUL_TERM) ; i ++)
ret[i] = ret[i] ^ PASSWORD_PATTERN;
return(ret);
}
/* Zero out a text string. */
#ifdef __STDC__
void wipeout(char *str)
#else
void wipeout(str)
char *str;
#endif
{
register char *ptr;
if(! str)
return;
for(ptr = str; *ptr != NUL_TERM; ptr ++)
*ptr = NUL_TERM;
return;
}
#ifdef __STDC__
void zap_commas(char *str)
#else
void zap_commas(str)
char *str;
#endif
{
register char *ptr;
if(! str)
return;
for(ptr = str; *ptr != NUL_TERM; ptr ++)
if(*ptr == ',')
*ptr = SPACECHAR;
return;
}
#ifdef __STDC__
char *stripcr(char *str)
#else
char *stripcr(str)
char *str;
#endif
{
register int i,j;
if (str) {
for (i = j = 0; str[i] != NUL_TERM; i++)
if(str[i] != CRCHAR || str[i+1] != LFCHAR )
str[j++] = str[i];
str[j] = NUL_TERM;
}
return (str);
}
#ifdef __STDC__
char *striplf(char *str)
#else
char *striplf(str)
char *str;
#endif
{
register int i,j;
if (str) {
for (i = j = 0; str[i] != NUL_TERM; i++)
if(str[i] != LFCHAR )
str[j++] = str[i];
str[j] = NUL_TERM;
}
return (str);
}
#ifdef __STDC__
char *tabtospace(char *str)
#else
char *tabtospace(str)
char *str;
#endif
{
register int i;
if (str) {
for (i = 0; str[i] != NUL_TERM; i++)
if(str[i] == TABCHAR )
str[i] = SPACECHAR;
}
return (str);
}
#ifdef __STDC__
char *unquote(char *s)
#else
char *unquote(s)
char *s;
#endif
{
char *ret = NULL;
char *dst;
char *src = s;
if(s == NULL)
return(cpystr(EMPTYSTR));
dst = ret = fs_get(strlen(s) + 1);
while(*src != NUL_TERM) {
if(*src == DQUOTECHAR) {
src ++;
continue;
}
*dst++ = *src++;
}
*dst = NUL_TERM;
return(ret);
}
/*
* first_nonwhite returns a pointer to the first non-whitspace
* character in a string. Warning: Don't free the result. Keep the
* original base of the string around if it's in allocated space.
* All this does is point to the first non-white character therein.
*/
#ifdef __STDC__
char *first_nonwhite(char *str)
#else
char *first_nonwhite(str)
char *str;
#endif
{
char *ptr = str;
if(ptr != NULL)
while(isspace(*(unsigned char *)ptr))
ptr ++;
return((char *) ptr);
}
#ifdef __STDC__
void remove_trailing_white(char *str)
#else
void remove_trailing_white(str)
char *str;
#endif
{
char *ptr = NULL;
if((str == NULL) || (*str == NUL_TERM))
return;
ptr = str + ((strlen(str)) - 1);
while(isspace(*(unsigned char *)ptr)) {
*ptr = NUL_TERM;
ptr --;
}
return;
}
#ifdef __STDC__
Binary_Buffer *load_binary_file(char *filename)
#else
Binary_Buffer *load_binary_file(filename)
char *filename;
#endif
{
FILE *fp;
Binary_Buffer *binary_buffer = NULL;
struct stat st;
unsigned long bytes_read = 0L;
unsigned long bytes_total = 0L;
char *ptr;
if(((stat(filename,&st)) != SYSCALL_SUCCESS)
|| (st.st_size == 0)
|| ((fp = fopen(filename,"r")) == NULL))
return(NULL);
binary_buffer = (Binary_Buffer *) fs_get(sizeof(Binary_Buffer));
binary_buffer->length = (unsigned long) st.st_size;
binary_buffer->data = (unsigned char *) fs_get(st.st_size + 1);
ptr = (char *) binary_buffer->data;
do {
bytes_read = fread(ptr, 1, ((unsigned long) st.st_size) - bytes_total, fp);
bytes_total += bytes_read;
ptr += bytes_read;
} while ((bytes_read != 0) && (bytes_total < (unsigned long) st.st_size));
fclose(fp);
binary_buffer->data[binary_buffer->length] = NUL_TERM;
if(bytes_total != (unsigned long) st.st_size) {
free_binary_buffer(binary_buffer);
binary_buffer = NULL;
}
return(binary_buffer);
}
#ifdef __STDC__
char *wrap_text(char *str, int linelen)
#else
char *wrap_text(str,linelen)
char *str;
int linelen;
#endif
{
int i = 0;
char *src = str;
char *dst, *ptr;
unsigned long dstsize;
if(! str)
return(NULL);
/* allocate source length + overhead to allow expansion */
dstsize = (unsigned long) strlen(src)
+ (((unsigned long) strlen(src)) / (unsigned long) linelen) + 2;
ptr = (char *) fs_get(dstsize);
dst = ptr;
while( *src != NUL_TERM ) {
i ++;
switch(*src) {
case TABCHAR:
if((i + (TABSIZE - 1)) > linelen) {
*dst = LFCHAR;
i = 0;
break;
}
*dst = *src;
i += (TABSIZE - 1);
break;
case LFCHAR:
*dst = *src;
i = 0;
break;
case SPACECHAR:
if((i + wordlen(src + 1)) > linelen ) {
*dst = LFCHAR;
i = 0;
break;
}
else {
*dst = *src;
break;
}
default:
*dst = *src;
break;
}
src ++;
dst ++;
}
*dst = NUL_TERM;
return(ptr);
}
#ifdef __STDC__
char *wrap_header_text(char *str, int linelen)
#else
char *wrap_header_text(str,linelen)
char *str;
int linelen;
#endif
{
int i = 0;
char *src = str;
char *dst, *ptr;
unsigned long dstsize;
if(! str)
return(NULL);
/* allocate source length + overhead to allow expansion */
dstsize = (unsigned long) strlen(src)
+ (2 * (((unsigned long) strlen(src)) / (unsigned long) linelen)) + 2;
ptr = (char *) fs_get(dstsize);
dst = ptr;
while( *src != NUL_TERM ) {
i ++;
switch(*src) {
case TABCHAR:
if((i + (TABSIZE - 1)) > linelen) {
*dst = LFCHAR;
i = 0;
break;
}
*dst = *src;
i += (TABSIZE - 1);
break;
case LFCHAR:
*dst = *src;
i = 0;
break;
case SPACECHAR:
if((i + wordlen(src + 1)) > linelen ) {
*dst = LFCHAR;
i = 0;
break;
}
else {
*dst = *src;
break;
}
default:
*dst = *src;
break;
}
src ++;
dst ++;
}
*dst = NUL_TERM;
return(ptr);
}
/* returns the number of chars in the string contained in 's' up
* to the next whitespace character.
*/
#ifdef __STDC__
int wordlen(char *s)
#else
int wordlen(s)
char *s;
#endif
{
register int cnt = 0;
register char *ptr = s;
while((*ptr) && (!isspace(*ptr))) {
ptr ++;
cnt ++;
}
return(cnt);
}
#ifdef __STDC__
char *lftocrlf(char *src)
#else
char *lftocrlf(src)
char *src;
#endif
{
char *dst = NULL;
register char *ptr;
register unsigned int lines = 0;
register unsigned int i;
register unsigned int j;
if(! src)
return(NULL);
for(ptr = src; *ptr != NUL_TERM ; ptr ++)
if(*ptr == LFCHAR || *ptr == CRCHAR)
lines ++;
dst = (char *) fs_get(strlen(src) + lines + 1);
for (i = j = 0; src[i] != NUL_TERM ; i++) {
if (src[i] == LFCHAR)
dst[j++] = CRCHAR;
else
if(src[i] == CRCHAR && src[i+1] == LFCHAR)
dst[j++] = src[i++];
dst[j++] = src[i];
if (src[i] == CRCHAR)
dst[j++] = LFCHAR;
}
dst[j] = NUL_TERM;
return(dst);
}
#ifdef __STDC__
char *input_string(Widget w, char *title,
char *default_string, char *help_file)
#else
char *input_string(w,title,default_string,help_file)
Widget w;
char *title;
char *default_string;
char *help_file;
#endif
{
Arg args[ARGLISTSIZE];
char buff[FILEBUFFLEN];
char *ret = NULL;
int n = 0;
Widget form, menubar, label, text;
XtTranslations translations;
XmString xstr;
textdone = 0;
if(preferences.autoPlace == TRUE) {
XtSetArg(args[n], XtNx, -1000); n ++;
XtSetArg(args[n], XtNy, -1000); n ++;
}
XtSetArg (args[n], XmNdeleteResponse, XmDO_NOTHING); n++;
XtSetArg(args[n], XmNtitle, title); n ++;
textshell = XtCreatePopupShell("text_input_shell",
topLevelShellWidgetClass, w,
args, n);
n = 0;
AddDestroyCallback (textshell);
setup_editres(textshell);
if(pirate_icon != (Pixmap) None)
XtVaSetValues(textshell,
XmNiconPixmap,pirate_icon,
NULL);
form = XmCreateForm(textshell, "text_input_form", args, n); n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
menubar = XmCreateMenuBar(form,"text_input_menubar", args, n); n = 0;
XtManageChild(menubar);
create_buttons(NULL, menubar,
text_input_menu,
XtNumber(text_input_menu), BTN_ON,
help_file, ROOTMENULEVEL);
sprintf(buff,"%s :",title);
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET ); n ++;
XtSetArg(args[n], XmNtopWidget, menubar ); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM ); n ++;
XtSetArg(args[n], XmNborderWidth, 0 ); n ++;
xstr = XmStringCreateSimple(buff);
XtSetArg(args[n], XmNlabelString, xstr ); n ++;
label = XmCreateLabel(form, "text_input_lbl", args, n ); n = 0;
XtManageChild(label);
XmStringFree(xstr);
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET ); n ++;
XtSetArg(args[n], XmNtopWidget, menubar ); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM ); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET ); n ++;
XtSetArg(args[n], XmNleftWidget, label ); n ++;
text = XmCreateTextField(form,"text_input_textfld",args, n); n = 0;
XtManageChild(text);
if(default_string)
AppendText(text,default_string);
translations = XtParseTranslationTable(GLOBAL_text_field_translations);
XtOverrideTranslations(text,translations);
translations =
XtParseTranslationTable(GLOBAL_terminal_text_field_translations);
XtOverrideTranslations(text,translations);
XtAddCallback(text, XmNactivateCallback,
(XtCallbackProc) text_input_accept, NULL);
XtAddCallback(text, XmNmodifyVerifyCallback,
(XtCallbackProc) text_field_edit, NULL);
XtManageChild(form);
push_cursor(PIRATE_CURSOR);
XtPopup(textshell,XtGrabExclusive);
position_popup_widget(textshell, TRUE);
modal_main_loop(&textdone);
ret = GetTextField(text);
XtPopdown(textshell);
XtDestroyWidget(textshell);
pop_cursor();
if((textdone > 0) && (*ret != NUL_TERM))
return(ret);
if(ret)
fs_give((void **) &ret);
return(NULL);
}
#ifdef __STDC__
void text_input_accept(Widget w, XtPointer zilch, XtPointer xp)
#else
void text_input_accept(w,zilch,xp)
Widget w;
XtPointer zilch;
XtPointer xp;
#endif
{
textdone = 1;
return;
}
#ifdef __STDC__
void text_input_cancel(Widget w, XtPointer zilch, XtPointer xp)
#else
void text_input_cancel(w,zilch,xp)
Widget w;
XtPointer zilch;
XtPointer xp;
#endif
{
textdone = (-1);
return;
}
#ifdef __STDC__
void text_input_help(Widget w, XtPointer zilch, XtPointer xp)
#else
void text_input_help(w,zilch,xp)
Widget w;
char *zilch;
XtPointer xp;
#endif
{
help(textshell,zilch);
return;
}
#ifdef __STDC__
char *ML_Strstr(char *cs, char *ct)
#else
char *ML_Strstr(cs,ct)
char *cs;
char *ct;
#endif
{
char *s;
char *t;
while (cs = strchr (cs,*ct)) {/* for each occurance of the first character */
/* see if remainder of string matches */
for (s = cs + 1, t = ct + 1; *t && *s == *t; s++, t++);
if (!*t) return cs; /* if ran out of substring then have match */
cs++; /* try from next character */
}
return NIL; /* not found */
}
#ifdef __STDC__
int count_lines(char *s)
#else
int count_lines(s)
char *s;
#endif
{
int n = 1;
char *ptr;
if(s == NULL)
return(0);
for(ptr = s; *ptr; ptr ++)
if(*ptr == LFCHAR)
n ++;
return(n);
}
/*
* XmTextInsertString() seems to have a bug which screws up the scroll
* bars when inserting more than a screenful at a time. This is a
* function to bypass it. We break up the existing text into that before
* and after the insert position, and then recombine with our inserted text,
* using XmTextSetString() to blast it onto the screen. Before finishing up,
* the new insert position is set.
*/
#ifdef __STDC__
void text_blast(Widget w, char *str)
#else
void text_blast(w,str)
Widget w;
char *str;
#endif
{
char *begin;
char *end;
char *existing;
XmTextPosition pos = XmTextGetInsertionPosition(w);
existing = XmTextGetString(w);
if(pos) {
begin = (char *) fs_get(pos + 1);
strncpy(begin,existing,pos);
begin[pos] = NUL_TERM;
}
else
begin = cpystr(EMPTYSTR);
end = cpystr(existing + pos);
fs_give((void **) &existing); /* free it up for re-use. */
existing = (char *) fs_get(strlen(begin) + strlen(str) + strlen(end) + 1);
strcpy(existing,begin);
strcat(existing,str);
strcat(existing,end);
XmTextSetString(w, existing);
XmTextSetInsertionPosition(w, pos + strlen(str));
fs_give((void **) &existing);
fs_give((void **) &begin);
fs_give((void **) &end);
}
#ifdef __STDC__
void search_text(Widget w, XtPointer xp)
#else
void search_text(w,xp)
Widget w;
XtPointer xp;
#endif
{
make_text_search_window(w);
return;
}
#ifdef __STDC__
void hex_input(Widget w, XtPointer xp)
#else
void hex_input(w,xp)
Widget w;
XtPointer xp;
#endif
{
hex_flag = TRUE;
}
#ifdef __STDC__
void spell_do_search(Widget w, Search_Win *search_win, XtPointer xp)
#else
void spell_do_search(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
Arg args[ARGLISTSIZE];
int n = 0;
XmTextPosition new_position, last_position;
Boolean result = FALSE;
last_position = XmTextGetLastPosition(search_win->parent);
XmTextSetHighlight(search_win->parent, 0L,
last_position,
XmHIGHLIGHT_NORMAL);
result = XmTextFindString(search_win->parent,
search_win->position,
search_win->search_text,
XmTEXT_FORWARD,
&new_position);
if(result == TRUE) {
if(new_position == search_win->position) {
search_win->position ++;
spell_do_search(w,search_win,xp);
return;
}
XmTextShowPosition(search_win->parent, new_position);
search_win->position = new_position;
XmTextSetHighlight(search_win->parent,new_position,
new_position + strlen(search_win->search_text),
XmHIGHLIGHT_SELECTED);
XtSetArg(args[n], XmNsensitive, TRUE); n ++;
XtSetValues(search_win->sbutton,args, n); n = 0;
XtSetArg(args[n], XmNsensitive, TRUE); n ++;
XtSetValues(search_win->rbutton,args, n); n = 0;
}
else {
XtSetArg(args[n], XmNsensitive, FALSE); n ++;
XtSetValues(search_win->sbutton,args, n); n = 0;
XtSetArg(args[n], XmNsensitive, FALSE); n ++;
XtSetValues(search_win->rbutton,args, n); n = 0;
spell_next(w,search_win,xp);
}
return;
}
#ifdef __STDC__
void spell_do_replace(Widget w, Search_Win *search_win, XtPointer xp)
#else
void spell_do_replace(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
if(search_win->replace_text != NULL)
fs_give((void **) &search_win->replace_text);
search_win->replace_text = XmTextGetString(search_win->replacew);
if((strcmp(search_win->replace_text, search_win->search_text)) == STRMATCH) {
search_win->position ++;
spell_do_search(w,search_win,xp);
return;
}
XmTextReplace(search_win->parent,
search_win->position,
search_win->position + strlen(search_win->search_text),
search_win->replace_text);
search_win->position ++; /* step over the current guy */
spell_do_search(w,search_win,xp);
return;
}
#ifdef __STDC__
void make_text_spell_window(Widget w, String_List *string_list)
#else
void make_text_spell_window(w, string_list)
Widget w;
String_List *string_list;
#endif
{
Arg args[ARGLISTSIZE];
int n = 0;
Widget form, menubar;
Search_Win *search_win = NULL;
if((session->compose != NULL) && (session->compose->spellwindow == NULL)) {
search_win = (Search_Win *) fs_get(sizeof(Search_Win));
session->compose->spellwindow = search_win;
}
else
search_win = session->compose->spellwindow;
search_win->parent = w;
search_win->is_realized = FALSE;
search_win->reverse = FALSE;
search_win->replace = TRUE;
search_win->button_state = BTN_ON;
search_win->search_text = NULL;
search_win->replace_text = NULL;
search_win->position = 0L;
search_win->string_list = string_list;
search_win->base = string_list;
if(preferences.autoPlace == TRUE) {
XtSetArg(args[n], XtNx, -1000); n ++;
XtSetArg(args[n], XtNy, -1000); n ++;
}
XtSetArg (args[n], XmNdeleteResponse, XmDO_NOTHING); n++;
search_win->shell = XtCreateWidget("spell_shell",
topLevelShellWidgetClass, session->shell,
args, n);
n = 0;
AddDestroyCallback (search_win->shell);
setup_editres(search_win->shell);
if(pirate_icon != (Pixmap) None)
XtVaSetValues(search_win->shell,
XmNiconPixmap,pirate_icon,
NULL);
form = XmCreateForm(search_win->shell, "spell_form", args, n); n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
menubar = XmCreateMenuBar(form,"spell_menubar", args, n); n = 0;
XtManageChild(menubar);
create_buttons(NULL, menubar,
spell_menu,
XtNumber(spell_menu), BTN_ON,
(XtPointer) search_win,
ROOTMENULEVEL);
XtSetArg(args[n], XmNsensitive, FALSE ); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM ); n ++;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++;
XtSetArg(args[n], XmNtopWidget, menubar); n ++;
search_win->sbutton
= XmCreatePushButton(form,"spell_search_button",args,n); n = 0;
XtAddCallback(search_win->sbutton, XmNactivateCallback,
(XtCallbackProc) spell_do_search, search_win);
XtManageChild(search_win->sbutton);
XtSetArg(args[n], XmNsensitive, FALSE); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n ++;
XtSetArg(args[n], XmNleftWidget,search_win->sbutton); n ++;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++;
XtSetArg(args[n], XmNtopWidget, menubar); n ++;
search_win->rbutton
= XmCreatePushButton(form,"spell_replace_button", args, n); n = 0;
XtAddCallback(search_win->rbutton, XmNactivateCallback,
(XtCallbackProc) spell_do_replace, search_win);
XtManageChild(search_win->rbutton);
search_win->search_text = cpystr(string_list->string);
search_win->searchw = create_text_field(form, search_win->sbutton,
"spell_word", string_list->string, 0, NULL, NULL);
XtSetArg(args[n], XmNeditable, FALSE ); n ++;
XtSetValues(search_win->searchw, args, n ); n = 0;
search_win->replacew =
create_text_field(form, search_win->searchw, "spell_replace",
string_list->string, 0,
(XtPointer) spell_accept, (XtPointer) search_win);
XtAddCallback(search_win->shell, XmNdestroyCallback,
(XtCallbackProc) spell_destroy, search_win);
XtAddCallback(search_win->parent, XmNdestroyCallback,
(XtCallbackProc) spell_parent_destroy, search_win);
search_win->replace_text = cpystr(string_list->string);
XtManageChild(form);
XtManageChild(search_win->shell);
XtRealizeWidget(search_win->shell);
position_popup_widget(search_win->shell, TRUE);
search_win->is_realized = TRUE;
spell_do_search(w,search_win,NULL);
return;
}
#ifdef __STDC__
void spell_accept(Widget w, Search_Win *search_win, XtPointer xp)
#else
void spell_accept(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
spell_do_replace(w,search_win,xp);
return;
}
#ifdef __STDC__
void spell_next(Widget w, Search_Win *search_win, XtPointer xp)
#else
void spell_next(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
Arg args[ARGLISTSIZE];
int n = 0;
search_win->position = 0L;
search_win->string_list = search_win->string_list->next;
if((search_win->string_list != NULL)
&& (search_win->string_list->string != NULL)) {
XmTextSetString(search_win->searchw, search_win->string_list->string);
XmTextSetString(search_win->replacew,search_win->string_list->string);
if(search_win->search_text != NULL)
fs_give((void **) &search_win->search_text);
search_win->search_text = cpystr(search_win->string_list->string);
if(search_win->replace_text != NULL)
fs_give((void **) &search_win->replace_text);
search_win->replace_text = XmTextGetString(search_win->replacew);
XtSetArg(args[n], XmNsensitive, FALSE); n ++;
XtSetValues(search_win->sbutton, args, n ); n = 0;
XtSetArg(args[n], XmNsensitive, FALSE); n ++;
XtSetValues(search_win->rbutton, args, n ); n = 0;
spell_do_search(w,search_win,xp);
}
else
spell_cancel(w,search_win,xp);
return;
}
#ifdef __STDC__
void spell_cancel(Widget w, Search_Win *search_win, XtPointer xp)
#else
void spell_cancel(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
char command[FILEBUFFLEN];
/* This is ridiculous, but it just happens to work. */
if(access(SPELLOUTFILE,R_OK) == SYSCALL_SUCCESS) {
sprintf(command,SPELL_SORT_COMMAND,SPELLSTOPFILE,
SPELLOUTFILE,SPELLSTOPFILE,SPELLJUNKFILE,
SPELLJUNKFILE,SPELLSTOPFILE,SPELLOUTFILE);
mm_log(MLGetLocalized(XtNmsgUpdatingStopFile,MsgUpdatingStopFile), NIL);
set_watch_cursors();
system(command);
pop_cursor();
}
XtDestroyWidget(search_win->shell);
return;
}
#ifdef __STDC__
void spell_destroy(Widget w, Search_Win *search_win, XtPointer xp)
#else
void spell_destroy(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
if(! search_win->parent_destroyed) {
XmTextSetHighlight(search_win->parent, 0L,
XmTextGetLastPosition(search_win->parent),
XmHIGHLIGHT_NORMAL);
XtRemoveCallback(search_win->parent, XmNdestroyCallback,
(XtCallbackProc) spell_parent_destroy, search_win);
}
if(search_win->search_text != NULL)
fs_give((void **) &search_win->search_text);
if(search_win->replace_text != NULL)
fs_give((void **) &search_win->replace_text);
search_win->position = 0L;
free_string_list(search_win->base, TRUE);
search_win->base = NULL;
search_win->is_realized = FALSE;
return;
}
#ifdef __STDC__
void spell_parent_destroy(Widget w, Search_Win *search_win, XtPointer xp)
#else
void spell_parent_destroy(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
search_win->parent_destroyed = TRUE;
XtDestroyWidget(search_win->shell);
return;
}
#ifdef __STDC__
void spell_remember(Widget w, Search_Win *search_win, XtPointer xp)
#else
void spell_remember(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
FILE *fp;
fp = fopen(SPELLOUTFILE,"a");
if(fp)
fprintf(fp,"%s\n", search_win->search_text);
fclose(fp);
spell_next(w,search_win,xp);
return;
}
#ifdef __STDC__
void spell_help(Widget w, Search_Win *search_win, XtPointer xp)
#else
void spell_help(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
help(search_win->shell, SPELLHELPFILE);
return;
}
#ifdef __STDC__
void make_text_search_window(Widget w)
#else
void make_text_search_window(w)
Widget w;
#endif
{
Arg args[ARGLISTSIZE];
int n = 0;
Widget form, menubar;
Boolean editable;
Search_Win *search_win;
search_win = (Search_Win *) fs_get(sizeof(Search_Win));
search_win->parent = w;
search_win->parent_destroyed = FALSE;
search_win->is_realized = FALSE;
search_win->reverse = FALSE;
search_win->replace = TRUE;
search_win->button_state = BTN_ON;
search_win->search_text = NULL;
search_win->replace_text = NULL;
search_win->position = 0L;
search_win->string_list = NULL;
search_win->base = NULL;
if(preferences.autoPlace == TRUE) {
XtSetArg(args[n], XtNx, -1000); n ++;
XtSetArg(args[n], XtNy, -1000); n ++;
}
XtSetArg (args[n], XmNdeleteResponse, XmDO_NOTHING); n++;
search_win->shell = XtCreateWidget("search_shell",
topLevelShellWidgetClass, session->shell,
args, n);
n = 0;
AddDestroyCallback (search_win->shell);
setup_editres(search_win->shell);
if(pirate_icon != (Pixmap) None)
XtVaSetValues(search_win->shell,
XmNiconPixmap,pirate_icon,
NULL);
XtSetArg(args[n], XmNeditable, &editable ); n ++;
XtGetValues(search_win->parent, args, n);
search_win->editable = editable;
form = XmCreateForm(search_win->shell, "search_form", args, n); n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
menubar = XmCreateMenuBar(form,"search_menubar", args, n); n = 0;
XtManageChild(menubar);
create_buttons(NULL, menubar,
search_menu,
XtNumber(search_menu), BTN_ON,
(XtPointer) search_win,
ROOTMENULEVEL);
search_win->searchw = create_text_field(form, menubar,
"search_word", NULL, 0,
(XtPointer)search_search,
(XtPointer)search_win);
search_win->replacew =
create_text_field(form, search_win->searchw, "search_replace_word",
NULL, 0,
(XtPointer) search_replace, (XtPointer) search_win);
if(search_win->editable == FALSE) {
XtSetArg(args[n], XmNeditable, FALSE); n ++;
XtSetValues(search_win->replacew, args, n); n = 0;
search_win->button_state |= BTN_MAILBOX_NOEDIT; /* it'll work */
}
XtAddCallback(search_win->shell, XmNdestroyCallback,
(XtCallbackProc) search_destroy, search_win);
XtAddCallback(search_win->parent, XmNdestroyCallback,
(XtCallbackProc) search_parent_destroy, search_win);
check_buttons(search_menu,XtNumber(search_menu),
NULL, search_win->button_state);
XtManageChild(form);
XtManageChild(search_win->shell);
XtRealizeWidget(search_win->shell);
position_popup_widget(search_win->shell, TRUE);
return;
}
#ifdef __STDC__
void search_search(Widget w, Search_Win *search_win, XtPointer xp)
#else
void search_search(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
char *currword;
XmTextPosition new_position, last_position;
Boolean result = FALSE;
last_position = XmTextGetLastPosition(search_win->parent);
currword = XmTextGetString(search_win->searchw);
if(search_win->search_text == NULL) {
search_win->position = 0L;
search_win->search_text = cpystr(currword);
}
else {
if((strcmp(currword,search_win->search_text)) != STRMATCH) {
fs_give((void **) &search_win->search_text);
search_win->search_text = cpystr(currword);
search_win->position = 0L;
}
}
XmTextSetHighlight(search_win->parent, 0L,
last_position,
XmHIGHLIGHT_NORMAL);
result = XmTextFindString(search_win->parent,
search_win->position,
search_win->search_text,
XmTEXT_FORWARD,
&new_position);
if(result == TRUE) {
if(new_position == search_win->position) {
search_win->position ++;
search_search(w,search_win,xp);
return;
}
XmTextShowPosition(search_win->parent, new_position);
search_win->position = new_position;
XmTextSetHighlight(search_win->parent,new_position,
new_position + strlen(search_win->search_text),
XmHIGHLIGHT_SELECTED);
}
else
XBell(display,1000);
return;
}
#ifdef __STDC__
void search_replace(Widget w, Search_Win *search_win, XtPointer xp)
#else
void search_replace(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
if((search_win->editable == FALSE) || (search_win->search_text == NULL))
return;
if(search_win->replace_text != NULL)
fs_give((void **) &search_win->replace_text);
search_win->replace_text = XmTextGetString(search_win->replacew);
if((strcmp(search_win->replace_text, search_win->search_text)) == STRMATCH) {
search_win->position ++;
search_search(w,search_win,xp);
return;
}
XmTextReplace(search_win->parent,
search_win->position,
search_win->position + strlen(search_win->search_text),
search_win->replace_text);
search_win->position ++; /* step over the current guy */
search_search(w,search_win,xp);
return;
}
#ifdef __STDC__
void search_cancel(Widget w, Search_Win *search_win, XtPointer xp)
#else
void search_cancel(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
XtDestroyWidget(search_win->shell);
return;
}
#ifdef __STDC__
void search_destroy(Widget w, Search_Win *search_win, XtPointer xp)
#else
void search_destroy(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
if(! search_win->parent_destroyed) {
XmTextSetHighlight(search_win->parent, 0L,
XmTextGetLastPosition(search_win->parent),
XmHIGHLIGHT_NORMAL);
XtRemoveCallback(search_win->parent, XmNdestroyCallback,
(XtCallbackProc) search_parent_destroy, search_win);
}
if(search_win->search_text != NULL)
fs_give((void **) &search_win->search_text);
if(search_win->replace_text != NULL)
fs_give((void **) &search_win->replace_text);
fs_give((void **) &search_win);
return;
}
#ifdef __STDC__
void search_parent_destroy(Widget w, Search_Win *search_win, XtPointer xp)
#else
void search_parent_destroy(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
search_win->parent_destroyed = TRUE;
XtDestroyWidget(search_win->shell);
return;
}
#ifdef __STDC__
void search_help(Widget w, Search_Win *search_win, XtPointer xp)
#else
void search_help(w, search_win, xp)
Widget w;
Search_Win *search_win;
XtPointer xp;
#endif
{
help(search_win->shell, SEARCHREPHELPFILE);
return;
}
#ifdef __STDC__
Boolean ml_confirm(Widget w, char *prompt, int type)
#else
Boolean ml_confirm(w,prompt,type)
Widget w;
char *prompt;
int type;
#endif
{
Arg args[ARGLISTSIZE];
int n = 0;
Widget shell, form, menubar, label;
Boolean result;
XmString xstr;
if(preferences.autoPlace == TRUE) {
XtSetArg(args[n], XtNx, -1000); n ++;
XtSetArg(args[n], XtNy, -1000); n ++;
}
XtSetArg (args[n], XmNdeleteResponse, XmDO_NOTHING); n ++;
shell = XtCreatePopupShell("confirm_shell",
topLevelShellWidgetClass, w,
args, n);
n = 0;
AddDestroyCallback(shell);
setup_editres(shell);
if(pirate_icon != (Pixmap) None)
XtVaSetValues(shell,
XmNiconPixmap,pirate_icon,
NULL);
form = XmCreateForm(shell, "confirm_form", args, n); n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
menubar = XmCreateMenuBar(form,"confirm_menubar", args, n); n = 0;
XtManageChild(menubar);
if(type == 0) { /* OK|Cancel */
create_buttons(NULL, menubar,
confirm_menu,
XtNumber(confirm_menu), BTN_ON,
&result,
ROOTMENULEVEL);
}
if(type == 1) { /* Yes|No */
create_buttons(NULL, menubar,
confirm_yn_menu,
XtNumber(confirm_yn_menu), BTN_ON,
&result,
ROOTMENULEVEL);
}
xstr = XmStringCreateSimple(prompt);
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++;
XtSetArg(args[n], XmNtopWidget, menubar); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNborderWidth, 0); n ++;
XtSetArg(args[n], XmNlabelString,xstr); n ++;
label = XmCreateLabel(form,"confirm_lbl",args,n); n = 0;
XtManageChild(label);
XmStringFree(xstr);
XtManageChild(form);
XtManageChild(shell);
XtPopup(shell,XtGrabExclusive);
position_popup_widget(shell, TRUE);
push_cursor(PIRATE_CURSOR);
confirm_done = 0;
modal_main_loop(&confirm_done);
XtPopdown(shell);
XtDestroyWidget(shell);
pop_cursor();
return(result);
}
#ifdef __STDC__
void confirm_ok(Widget w, Boolean *result, XtPointer xp)
#else
void confirm_ok(w, result, xp)
Widget w;
Boolean *result;
XtPointer xp;
#endif
{
*result = TRUE;
confirm_done = MODAL_LOOP_DONE;
return;
}
#ifdef __STDC__
void confirm_cancel(Widget w, Boolean *result, XtPointer xp)
#else
void confirm_cancel(w, result, xp)
Widget w;
Boolean *result;
XtPointer xp;
#endif
{
*result = FALSE;
confirm_done = MODAL_LOOP_DONE;
return;
}
#ifdef __STDC__
char *iso_encode_subject(char *s)
#else
char *iso_encode_subject(s)
char *s;
#endif
{
unsigned char *ptr;
Boolean needs_encoding = FALSE;
char *ret;
int linelen = 0;
char buffer[80];
if((strcasecmp(preferences.charset,US_ASCII_STR)) == STRMATCH)
return(cpystr(s));
for(ptr = (unsigned char *) s; *ptr; ptr ++)
if(*ptr >= 0x80)
needs_encoding = TRUE;
if(needs_encoding == FALSE)
return(cpystr(s));
ret = (char *) fs_get((strlen(s) * 5) + 128);
sprintf(buffer,"=?%s?Q?",preferences.charset);
linelen = strlen(buffer);
strcpy(ret,buffer);
ptr = (unsigned char *) s;
while((*(ptr)) != NUL_TERM) {
if((linelen > 70) && ((*(ptr + 1)) != NUL_TERM)) {
strcat(ret,"?=\n ");
strcat(ret,buffer);
linelen = strlen(buffer + 1);
}
if(*ptr == SPACECHAR) {
strcat(ret,"_");
linelen ++;
ptr ++;
continue;
}
if((*ptr == '?') || (*ptr == '=') || (*ptr == '_') || (*ptr >= 0x80)) {
strcat(ret,qhexstr((int) *ptr));
linelen += 3;
ptr ++;
continue;
}
strncat(ret,(char *) ptr,1);
linelen ++;
ptr ++;
}
strcat(ret,"?=");
return(ret);
}
#ifdef __STDC__
void iso_encode_address(ADDRESS *ad)
#else
void iso_encode_address(ad)
ADDRESS *ad;
#endif
{
ADDRESS *curr;
unsigned char *ptr;
Boolean needs_encoding = FALSE;
Boolean in_encoding = FALSE;
char *ret;
unsigned char *comment;
unsigned char *end_comment;
int linelen = 0;
char buffer[80];
if((strcasecmp(preferences.charset,US_ASCII_STR)) == STRMATCH)
return;
for(curr = ad; curr; curr = curr->next) {
if(curr->personal == NULL)
continue;
for(ptr = (unsigned char *) curr->personal; *ptr; ptr++)
if(*ptr > 0x80)
needs_encoding = TRUE;
if(needs_encoding == FALSE)
continue;
ret = (char *) fs_get((strlen(curr->personal) * 5) + 128);
sprintf(buffer,"=?%s?Q?",preferences.charset);
ptr = (unsigned char *) curr->personal;
comment = (unsigned char *) strchr((char *) ptr,'(');
if(comment)
end_comment = (unsigned char *) strchr((char *) comment,')');
if(comment == ptr) {
in_encoding = FALSE;
linelen = 0;
}
else {
strcpy(ret,buffer);
in_encoding = TRUE;
linelen = strlen(buffer);
}
while((*(ptr)) != NUL_TERM) {
if(ptr == comment) {
if(in_encoding) {
strcat(ret,"?= ( ");
linelen += 5;
in_encoding = FALSE;
}
else {
strcat(ret," ( ");
linelen += 3;
}
}
if(ptr == end_comment) {
if(in_encoding) {
strcat(ret, "?= ) ");
linelen += 5;
in_encoding = FALSE;
}
else {
strcat(ret, " ) ");
linelen += 3;
}
}
if((linelen > 70) && ((*(ptr +1)) != NUL_TERM)) {
if(in_encoding) {
strcat(ret,"?=\n ");
strcat(ret,buffer);
linelen = strlen(buffer + 1);
}
else {
strcat(ret,"\n ");
linelen = 2;
}
}
if(*ptr == SPACECHAR) {
strcat(ret,"_");
linelen ++;
ptr ++;
continue;
}
if((!isalnum(*ptr)) || (*ptr >= 0x80)) {
strcat(ret,qhexstr((int) *ptr));
linelen += 3;
ptr ++;
continue;
}
strncat(ret,(char *) ptr,1);
linelen ++;
ptr ++;
}
if(in_encoding)
strcat(ret,"?= ");
fs_give((void **) &curr->personal);
curr->personal = ret;
}
return;
}
/* Not necessarily efficient, but it does the job. */
static char qhexbuffer[4];
#ifdef __STDC__
char *qhexstr(int c)
#else
char *qhexstr(c)
int c;
#endif
{
sprintf(qhexbuffer,"=%02X",c);
return(qhexbuffer);
}
/*
* do_any is a flag that can be overriden for reading or printing messages
* by the preferences variable "decode_all". When we use it to reference the
* absolute message, we restrict decoding to the native charset or us-ascii.
*/
#ifdef __STDC__
char *iso_decode(char **s, Boolean do_any)
#else
char *iso_decode(s,do_any)
char **s;
Boolean do_any;
#endif
{
char *start;
char *end;
char *ret;
char *encoding;
char *target;
char *result;
char *ptr;
unsigned long newlen;
char buffer[128];
char *recurse_ptr;
if(*s == NULL)
return(NULL);
ret = (char *) fs_get(strlen(*s) + 1);
*ret = NUL_TERM;
/* Does it have our special encoding tags? */
if((wildmat(*s,ENCODING_REGEX)) == WILDNOMATCH) {
strcpy(ret,*s);
*s = NULL;
return(ret);
}
/* Hmmm. So far so good. Let's see if it's in our character set. */
start = ML_Strstr(*s,"=?");
sprintf(buffer,"=?%s?",preferences.charset);
if((do_any == FALSE) || (preferences.decode_all == FALSE)) {
if((strncasecmp(start,buffer,strlen(buffer))) != STRMATCH) {
/* Nope. But let's try US-ASCII. Let's hope they're using ISO-8859 */
sprintf(buffer,"=?%s?", US_ASCII_STR);
if((strncasecmp(start,buffer,strlen(buffer))) != STRMATCH) {
/* Sorry. Can't display it.... */
strcpy(ret,*s);
*s = NULL;
return(ret);
}
}
}
/*
* OK, we've found something. But was there leading cruft?
* If so, we have to pass that back, and go through this again.
*/
if(start != (*s)) {
strncpy(ret,*s,start - (*s));
ret[start - (*s)] = NUL_TERM;
*s = start;
return(ret);
}
/* OK. It looks valid. */
encoding = (strchr(start + 2,'?')) + 1;
/* Now, we're more or less committed unless the decode fails. */
end = ML_Strstr(encoding + 2,"?=");
target = (char *) fs_get(end - (encoding + 1));
strncpy(target,encoding + 2,end - (encoding + 2));
target[end - (encoding + 2)] = NUL_TERM;
if((*(encoding) == 'q') || (*(encoding) == 'Q')) {
for(ptr = target; *ptr != NUL_TERM; ptr ++)
if(*ptr == '_')
*ptr = SPACECHAR;
result = (char *) rfc822_qprint((unsigned char *) target,
strlen(target),&newlen);
}
else
result = (char *) rfc822_base64((unsigned char *) target,
strlen(target),&newlen);
fs_give((void **) &target); /* Through with this one. */
if(result == NIL) {
/*
* Ack!! It didn't decode. Must'a been corrupted, 'cause they
* made it this far without problems.
*/
fs_give((void **) &target);
strcpy(ret,*s);
*s = NULL;
return(ret);
}
/*
* Otherwise, we've done our job. Now to clean up. We have to point
* at the end so they can come back through and catch any trailing
* cruft or yet more encodings. Also, to be consistent with the
* spec, we ignore whitespace up to a subsequent encoding.
*/
end += 2;
recurse_ptr = end;
while((*recurse_ptr != NUL_TERM) && (isspace(*recurse_ptr)))
recurse_ptr ++;
if((wildmat(recurse_ptr,CONTINUE_REGEX)) == WILDMATCH)
*s = recurse_ptr;
else
*s = end;
fs_give((void **) &ret);
return(result);
}
TagPair HTMLtags[] = {
"<P>", "\n",
"<BR>", "\n",
"<LI>", "\n\t",
"<UL>", "\n",
"<TR>", "\n",
"</BLOCKQUOTE>", "\n-----\n",
NULL, NULL
};
TagPair AMPtags[] = {
" ", " ",
"&", "&",
"<", "<",
">", ">",
"©", "\251",
NULL, NULL
};
#ifdef __STDC__
char * strip_html(char *src)
#else
char *strip_html(src)
char *src;
#endif
{
char *ret = NULL;
char *sptr = src;
char *rptr = NULL;
int tptr;
int preformatted = 0;
if((src == NULL) || (*src == NUL_TERM))
return ret;
rptr = ret = fs_get(strlen(src) + FILEBUFFLEN);
while(*sptr != NUL_TERM) {
if(*sptr == '\n' && !preformatted) {
*rptr++ = ' ';
*sptr++;
continue;
}
if(*sptr != '<' && *sptr != '&') {
*rptr++ = *sptr++;
continue;
}
if((preformatted) && ((strncasecmp(sptr,"</PRE>",6)) == STRMATCH))
preformatted = 0;
if(*sptr == '&') {
for(tptr = 0; AMPtags[tptr].tag != NULL; tptr ++) {
if((strncasecmp(sptr,
AMPtags[tptr].tag,
strlen(AMPtags[tptr].tag))) == STRMATCH) {
strcpy(rptr,AMPtags[tptr].value);
rptr += strlen(AMPtags[tptr].value);
break;
}
}
/* advance to end of symbol */
while((*sptr != NUL_TERM) && (*sptr != ';'))
sptr ++;
if(*sptr)
sptr ++;
continue;
}
if(*sptr == '<') {
for(tptr = 0; HTMLtags[tptr].tag != NULL; tptr ++) {
if((strncasecmp(sptr,
HTMLtags[tptr].tag,
strlen(HTMLtags[tptr].tag))) == STRMATCH) {
strcpy(rptr,HTMLtags[tptr].value);
rptr += strlen(HTMLtags[tptr].value);
sptr ++; /* advance past tag start so no more matches */
break;
}
}
/* fall through to find tag end */
/* special cases: */
/* link - retain the href */
if((strncasecmp(sptr,"<A ",3)) == STRMATCH) {
while((*sptr != NUL_TERM) && (*sptr != '>')) {
if((strncasecmp(sptr," HREF=",6)) == STRMATCH) {
sptr += 6;
*rptr++ = '<';
while((*sptr != NUL_TERM) && (*sptr != ' ') && (*sptr != '>'))
*rptr++ = *sptr++;
*rptr++ = '>';
continue;
}
else
sptr++;
}
if(*sptr) sptr ++;
continue; /* do not fall through */
}
/* blockquote - pretty it up a bit */
if((strncasecmp(sptr,"<BLOCKQUOTE",11)) == STRMATCH) {
strcpy(rptr,"\n-----\n");
rptr += 7;
/* fall through to find tag end */
}
/* paragraph tags with args, very common */
if((strncasecmp(sptr,"<P ",3)) == STRMATCH)
*rptr++ = '\n';
/* fall through to find tag end */
/* preformatted text - flag it for special handling */
if(((strncasecmp(sptr,"<PRE>",5)) == STRMATCH)
|| ((strncasecmp(sptr,"<PRE ",5)) == STRMATCH))
preformatted = 1;
/* catch fall throughs and all other unrecognized tags */
while((*sptr != NUL_TERM) && (*sptr != '>'))
sptr ++;
if(*sptr) sptr ++;
continue;
}
}
*rptr = NUL_TERM;
return ret;
}
/*
** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
** Rich $alz is now <rsalz@osf.org>.
*/
#define MATCH_ABORT -1
/* What character marks an inverted character class? */
#define NEGATE_CLASS '^'
/* Is "*" a common pattern? */
#define OPTIMIZE_JUST_STAR
/* Do tar(1) matching rules, which ignore a trailing slash? */
#undef MATCH_TAR_PATTERN
/*
** Match text and p, return WILDMATCH, WILDNOMATCH, or MATCH_ABORT.
*/
#ifdef __STDC__
int DoMatch(register char *text, register char *p)
#else
int DoMatch(text, p)
register char *text;
register char *p;
#endif
{
register int last;
register int matched;
register int reverse;
for ( ; *p; text++, p++) {
if (*text == '\0' && *p != '*')
return MATCH_ABORT;
switch (*p) {
case '\\':
/* Literal match with following character. */
p++;
/* FALLTHROUGH */
default:
if (*text != *p)
return WILDNOMATCH;
continue;
case '?':
/* Match anything. */
continue;
case '*':
while (*++p == '*')
/* Consecutive stars act just like one. */
continue;
if (*p == '\0')
/* Trailing star matches everything. */
return WILDMATCH;
while (*text)
if ((matched = DoMatch(text++, p)) != WILDNOMATCH)
return matched;
return MATCH_ABORT;
case '[':
reverse = p[1] == NEGATE_CLASS ? WILDMATCH : WILDNOMATCH;
if (reverse)
/* Inverted character class. */
p++;
matched = WILDNOMATCH;
if (p[1] == ']' || p[1] == '-')
if (*++p == *text)
matched = WILDMATCH;
for (last = *p; *++p && *p != ']'; last = *p)
/* This next line requires a good C compiler. */
if (*p == '-' && p[1] != ']'
? *text <= *++p && *text >= last : *text == *p)
matched = WILDMATCH;
if (matched == reverse)
return WILDNOMATCH;
continue;
}
}
#ifdef MATCH_TAR_PATTERN
if (*text == '/')
return WILDMATCH;
#endif /* MATCH_TAR_PATTERN */
return *text == '\0';
}
/*
** User-level routine. Returns WILDMATCH or WILDNOMATCH.
*/
#ifdef __STDC__
int wildmat(char *text, char *p)
#else
int wildmat(text, p)
char *text;
char *p;
#endif
{
#ifdef OPTIMIZE_JUST_STAR
if (p[0] == '*' && p[1] == '\0')
return WILDMATCH;
#endif /* OPTIMIZE_JUST_STAR */
return DoMatch(text, p) == WILDMATCH;
}
#ifdef __STDC__
void free_binary_buffer(Binary_Buffer *binary_buffer)
#else
void free_binary_buffer(binary_buffer)
Binary_Buffer *binary_buffer;
#endif
{
if(binary_buffer) {
if(binary_buffer->data)
fs_give((void **) &binary_buffer->data);
fs_give((void **) &binary_buffer);
}
return;
}
#ifdef __STDC__
String_List *new_string_list(void)
#else
String_List *new_string_list()
#endif
{
String_List *string_list = (String_List *) fs_get(sizeof(String_List));
string_list->string = NULL;
string_list->next = NULL;
return(string_list);
}
#ifdef __STDC__
void free_string_list(String_List *string_list, Boolean recurse)
#else
void free_string_list(string_list,recurse)
String_List *string_list;
Boolean recurse;
#endif
{
if(string_list == NULL)
return;
if(recurse)
free_string_list(string_list->next, recurse);
if(string_list->string != NULL)
fs_give((void **) &string_list->string);
fs_give((void **) &string_list);
return;
}
/* One heck of a tough problem. Reformat the original text,
preserving reply carets.
*/
#ifdef __STDC__
char *copywrap(char *s, int wrapcols)
#else
char *copywrap(s, wrapcols)
char * s;
int wrapcols;
#endif
{
char *last, *temp;
char *raw, *dst;
char **strtab;
int lines;
unsigned long dstlen = 0L;
unsigned long size = 0L;
Boolean prefixed = FALSE;
Boolean wrapped = FALSE;
int tabcount;
int cnt;
char *ptr;
int wraplen = 0;
if(s == NULL)
return(cpystr(EMPTYSTR));
size = strlen(s) + 1024;
dst = (char *) fs_get(size);
*dst = NUL_TERM;
last = (char *) fs_get(wrapcols + 100);
temp = (char *) fs_get((2 * wrapcols) + 100);
*last = *temp = NUL_TERM;
raw = cpystr(s);
strtab = build_line_table(raw);
for(lines = 0; strtab[lines]; lines ++)
strtab[lines] = untabify(strtab[lines]);
for(lines = 0; strtab[lines]; lines ++) {
if(dstlen >= size)
dst = realloc(dst, (size += 1024));
if(! strlen(strtab[lines])) {
strcat(dst,LFSTR);
dstlen ++;
if(wrapped) {
strcat(dst,LFSTR);
dstlen ++;
*last = NUL_TERM;
wrapped = 0;
wraplen = 0;
}
continue;
}
if((! wrapped) && ((strlen(strtab[lines])) < wrapcols)) {
strcat(dst,strtab[lines]);
strcat(dst, LFSTR);
dstlen += strlen(strtab[lines]) + 1;
continue;
}
/* If we got here, the line needs wrapping */
if(! wrapped) {
wrapped = TRUE;
/* stash the prefix for comparison */
strncpy(last,strtab[lines],wrapcols);
last[wrapcols] = NUL_TERM;
for(cnt = 0; last[cnt]; cnt ++) {
if((last[cnt] != '>') && (last[cnt] != SPACECHAR)) {
last[cnt] = NUL_TERM;
break;
}
}
strncpy(temp,strtab[lines],wrapcols);
temp[wrapcols] = NUL_TERM;
/* find the last useable space */
for(ptr = temp + (wrapcols - 1); *ptr != SPACECHAR; ptr --)
;
if(ptr <= temp) { /* no spaces found. */
strcat(dst,strtab[lines]);
strcat(dst, LFSTR);
dstlen += strlen(strtab[lines]) + 1;
wraplen = 0;
wrapped = FALSE;
continue;
}
else { /* spit out this line */
strncat(dst, temp, ptr - temp);
strcat(dst,LFSTR);
dstlen += ((ptr - temp) + 1);
/* start the next line with a prefix if any */
/* We'll ignore a tab (now spaces) as a prefix. */
if(strcmp(last," ")) {
strcat(dst,last);
dstlen += strlen(last);
wraplen = strlen(last);
}
else
strcpy(last,EMPTYSTR);
/* spit out the remaining stuff */
strcat(dst,&strtab[lines][(ptr - temp) + 1]);
strcat(dst,SPACESTR);
dstlen += (strlen(strtab[lines]) - (ptr - temp)) + 1;
wraplen += (strlen(strtab[lines]) - (ptr - temp)) + 1;
continue;
}
}
else { /* already wrapped. second or 'n' line to wrap */
/* If it doesn't have the same prefix, we're done wrapping. */
if((strncmp(strtab[lines],last,strlen(last))) != STRMATCH) {
strcat(dst,LFSTR);
wrapped = FALSE;
wraplen = 0;
dstlen += 1;
lines --; /* push this line back to re-evaluate */
continue;
}
else { /* keep wrapping */
/* we've already got the prefix. */
strncpy(temp,&strtab[lines][strlen(last)],wrapcols);
temp[wrapcols] = NUL_TERM;
/* is THIS line too long ? */
if(((strlen(temp)) + wraplen) >= wrapcols)
for(ptr = temp + (wrapcols - wraplen - 1);
*ptr != SPACECHAR; ptr --)
;
else { /* It fits just fine. */
ptr = temp + strlen(temp);
strncat(dst, temp, ptr - temp);
strcat(dst,LFSTR);
dstlen += ((ptr - temp) + 1);
wraplen = 0; /* += ((ptr - temp) + 1); */
wrapped = FALSE;
continue;
}
if(ptr <= temp) { /* it just won't fit... */
strcat(dst,&strtab[lines][strlen(last)]);
strcat(dst, LFSTR);
dstlen += strlen(strtab[lines]) + strlen(last) + 1;
wraplen = 0;
wrapped = FALSE;
continue;
}
else { /* spit out what we've got and end this line. */
strncat(dst, temp, ptr - temp);
strcat(dst,LFSTR);
dstlen += ((ptr - temp) + 1);
/* start a new line. */
strcat(dst,last);
dstlen += strlen(last);
wraplen = strlen(last);
/* spit out the rest of this line. */
strcat(dst,&strtab[lines][(ptr - temp) + strlen(last) + 1]);
strcat(dst,SPACESTR);
dstlen += strlen(&strtab[lines][(ptr - temp) + strlen(last) + 1]);
wraplen += strlen(&strtab[lines][(ptr - temp) + strlen(last) + 1]);
continue;
}
}
}
}
/* go home */
for(lines = 0; strtab[lines]; lines ++)
fs_give((void **) &strtab[lines]);
free(strtab);
fs_give((void **) &last);
fs_give((void **) &temp);
fs_give((void **) &raw);
return(dst);
}
#ifdef __STDC__
char *untabify(char *s)
#else
char *untabify(s)
char *s;
#endif
{
int i = 0;
int y;
char *src;
char *ret = fs_get((5 * strlen(s)) + 1);
char *dst = ret;
for(src = s; *src; src ++) {
if(*src == TABCHAR) {
for(i = 0; i < 5; i ++) {
*dst = SPACECHAR;
dst ++;
}
}
else
*dst++ = *src;
}
*dst = NUL_TERM;
return(ret);
}
#ifdef __STDC__
char **build_line_table(char *s)
#else
char **build_line_table(s)
char *s;
#endif
{
int lines = count_lines(s);
char *start = s;
char *end = NULL;
char **ret;
int count = 0;
ret = (char **) fs_get(((lines) ? (lines + 1) : 1) * sizeof(char *));
while((ret[count] = get_next_strline(start, &end)) != NULL) {
count ++;
start = end;
}
ret[count] = NULL;
return(ret);
}
#ifdef __STDC__
char *get_next_strline(char *s, char **end)
#else
char *get_next_strline(s,end)
char *s;
char **end;
#endif
{
char *ptr;
if(*s == NUL_TERM) {
*end = NULL;
return(NULL);
}
if((ptr = strchr(s,LFCHAR)) != NULL) {
*ptr = NUL_TERM;
*end = ptr +1;
return(s);
}
*end = s + strlen(s);
return(s);
}
#ifdef __STDC__
char *add_prefix(char *s)
#else
char *add_prefix(s)
char * s;
#endif
{
int carets = 0;
unsigned nlength = 0;
char *temp = NULL;
char *insert = NULL;
int prefixLength = strlen(preferences.reply_prefix);
carets = count_lines(s);
nlength = (carets*prefixLength) + strlen(s);
insert = XtMalloc(nlength+1);
strcpy(insert, preferences.reply_prefix);
temp = insert + strlen(insert);
while( *s ) {
*temp++ = *s;
if( (*s == LFCHAR) && (*(s+1) != NUL_TERM)){
strncpy(temp, preferences.reply_prefix, prefixLength );
temp += prefixLength;
}
s++;
}
*temp = NUL_TERM;
return(insert);
}
syntax highlighted by Code2HTML, v. 0.9.1