This is misc.c in view mode; [Download] [Up]
/* Copyright (c) 1995 John E. Davis (davis@space.mit.edu)
* All rights reserved.
*/
#include "config.h"
#include "features.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <signal.h>
#include <ctype.h>
#include <errno.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifndef VMS
# include <pwd.h>
# include <sys/types.h>
# include <sys/stat.h>
#else
# include <stat.h>
# include <unixio.h>
#endif
#include <slang.h>
#include "jdmacros.h"
#include "misc.h"
#include "group.h"
#include "slrn.h"
#include "post.h"
#include "server.h"
#if SLRN_HAS_MIME
#include "mime.h"
#endif
#ifdef VMS
/* valid filname chars for unix equiv of vms filename */
#define VALID_FILENAME_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_-/"
#endif
static int Error_Present;
int Slrn_Full_Screen_Update = 1;
int Slrn_User_Wants_Confirmation = 1;
#ifndef VMS
char *Slrn_SendMail_Command;
#endif
char *Slrn_Editor;
void slrn_set_color (int color)
{
#if 0
if (SLtt_Use_Ansi_Colors == 0)
{
if (color >= STATUS_COLOR) SLsmg_reverse_video ();
else SLsmg_normal_video ();
}
else
#endif
SLsmg_set_color (color);
}
void slrn_redraw (void)
{
SLsmg_cls ();
Slrn_Full_Screen_Update = 1;
if ((Slrn_Current_Mode != NULL)
&& (Slrn_Current_Mode->redraw_fun != NULL))
(*Slrn_Current_Mode->redraw_fun) ();
slrn_smg_refresh ();
}
int Slrn_Message_Present;
void slrn_clear_message (void)
{
Slrn_Message_Present = Error_Present = 0;
/* SLang_Error = 0; */
SLKeyBoard_Quit = 0;
if ((Slrn_TT_Initialized & 1) == 0)
return;
SLsmg_gotorc (SLtt_Screen_Rows - 1, 0);
SLsmg_erase_eol ();
}
int slrn_message (char *fmt, ...)
{
int ok;
va_list ap;
if (Error_Present) return -1;
if (Slrn_TT_Initialized & 1)
{
ok = Slrn_Suspension_Ok;
if (ok) slrn_set_suspension (0);
SLsmg_gotorc (SLtt_Screen_Rows - 1, 0);
slrn_set_color (0);
va_start(ap, fmt);
(void) SLsmg_vprintf(fmt, ap);
SLsmg_erase_eol ();
Slrn_Message_Present = 1;
if (ok) slrn_set_suspension (1);
}
else
{
va_start(ap, fmt);
(void) vfprintf(stderr, fmt, ap);
va_end(ap);
putc ('\n', stderr);
}
return 0;
}
extern void slrn_error (char *fmt, ...)
{
va_list ap;
if ((Slrn_TT_Initialized & 1) == 0)
{
va_start(ap, fmt);
(void) vfprintf(stderr, fmt, ap);
va_end(ap);
putc ('\n', stderr);
}
else
{
int ok;
if (Error_Present) return;
ok = Slrn_Suspension_Ok;
if (ok) slrn_set_suspension (0);
SLtt_beep ();
slrn_clear_message ();
Error_Present = 1;
Slrn_Message_Present = 1;
slrn_set_color (ERROR_COLOR);
va_start(ap, fmt);
(void) SLsmg_vprintf(fmt, ap);
va_end(ap);
slrn_set_color (0);
SLang_flush_input ();
if (ok) slrn_set_suspension (1);
}
if (SLang_Error == 0) SLang_Error = INTRINSIC_ERROR;
}
void slrn_print_percent (int row, int col, int n, int nmax, int width)
{
SLsmg_erase_eol ();
SLsmg_gotorc (row, col);
SLsmg_printf ("-- %d/%d", n, nmax);
if (n == 1)
{
#if 1
SLsmg_write_string ( (n + width > nmax) ? " (All)" : " (Top)" );
#else
SLsmg_printf (" (Top)");
#endif
}
else if (n + width > nmax) SLsmg_write_string(" (Bot)");
else SLsmg_printf(" (%d%%)", ((n + width - 1) * 100) / nmax);
SLsmg_erase_eol ();
}
static void fixup_path (char *path)
{
int len;
len = strlen (path);
if (len == 0) return;
if (path[len - 1] == '/') return;
path[len] = '/';
path[len + 1] = 0;
}
#ifdef VMS
static void vms_fix_name(char *name)
{
int idx, pos;
pos = strspn(name, VALID_FILENAME_CHARS);
if (pos == strlen(name))
return;
for(idx=pos;idx<strlen(name);idx++)
if (!(isdigit(name[idx]) || isalpha(name[idx]) || (name[idx] == '$') || (name[idx] == '_') || (name[idx] == '-')
|| (name[idx] == '/')))
name[idx] = '-';
}
static char Copystr[256];
static int vms_copyname1 (char *name)
{
strcpy(Copystr, name);
return(1);
}
static int vms_copyname2 (char *name, int type)
{
strcpy(Copystr, name);
return(1);
}
#endif
void slrn_make_home_filename (char *name, char *file)
{
char *home;
#ifndef VMS
if (
#ifdef __os2__
(*name == '/') || (*name == '\\') || (*(name + 1) == ':')
|| ((*name == '.') && (*(name + 1) == '/'))
|| ((*name == '.') && (*(name + 1) == '\\'))
#else
(*name == '/') || ((*name == '.') && (*(name + 1) == '/'))
#endif
)
{
strcpy (file, name);
return;
}
if (NULL == (home = getenv ("SLRNHOME")))
home = getenv ("HOME");
*file = 0;
if (home != NULL) strcpy (file, home);
fixup_path (file);
strcat (file, name);
#else
char *cp, *cp1;
static char fname[256];
char fn[256], fn1[256];
int rc, idx;
strcpy (fn1, name);
if (NULL != slrn_strchr (name, ':'))
{
strcpy (file, name);
return;
}
if (NULL == (home = getenv ("SLRNHOME")))
home = getenv ("HOME");
*file = 0;
if (NULL != (cp = slrn_strchr (fn1, '/')))
{
# ifdef __DECC
*cp = '\0'; cp++;
cp1 = decc$translate_vms(home);
if (cp1 == 0 || (int)cp1 == -1)
{ /* error translating */ }
else
{
strcpy(fname, cp1);
strcat(cp1, "/");
}
strcat (cp1, fn1);
vms_fix_name (cp1);
rc = decc$to_vms(cp1, vms_copyname2, 0, 2);
if (rc > 0)
{
strcpy(fname, Copystr);
rc = mkdir(fname, 0755);
}
strcat(fname, cp);
# else
*cp = '\0'; cp++;
cp1 = shell$translate_vms(home);
if (cp1 == 0 || (int)cp1 == -1)
{ /* error translating */ }
else
{
strcpy(fname, cp1);
strcat(cp1, "/");
}
strcat (cp1, fn1);
vms_fix_name (cp1);
rc = shell$to_vms(cp1, vms_copyname2, 0, 2);
if (rc > 0)
{
strcpy(fname, Copystr);
rc = mkdir(fname, 0755);
}
strcat(fname, cp);
# endif
strcpy(file,fname);
}
else
{
if (home != NULL) strcpy(file, home);
strcat(file, name);
}
#endif /* VMS */
}
int slrn_make_home_dirname (char *name, char *dir)
{
/* This needs modified to deal with VMS directory syntax */
#ifndef VMS
slrn_make_home_filename (name, dir);
#else
char *home, *cp;
char fn[256];
static char fname[256];
int rc, idx, len;
if (NULL != slrn_strchr (name, ':'))
{
strcpy (dir, name);
return;
}
home = getenv ("HOME");
*dir = 0;
if (cp = strchr(name,'/'))
{
#ifdef __DECC
cp = decc$translate_vms(home);
if (cp == 0 || (int)cp == -1)
{ /* error translating */ }
else
{
strcpy(fname, cp);
strcat(cp, "/");
}
strcat (cp, name);
vms_fix_name (cp);
rc = decc$to_vms(cp, vms_copyname2, 0, 2);
if (rc > 0)
{
strcpy(fname, Copystr);
rc = mkdir(fname, 0755);
}
#else
if (shell$from_vms(home, vms_copyname1, 0))
{
if (Copystr != NULL) strcpy (fn, Copystr);
strcat(fn, "/");
}
strcat (fn, name);
vms_fix_name(fn);
if (shell$to_vms(fn, vms_copyname1, 0))
strcpy(fname, Copystr);
#endif
strcpy(dir,fname);
}
else
{
if (home != NULL)
{
strcpy(dir, home);
len = strlen(dir) - 1;
if (dir[len] == ']')
{
dir[len] = '.';
strcat(dir, name);
strcat(dir, "]");
}
else
strcat(dir, name);
}
else
strcat(dir, name);
}
#endif /* VMS */
return 0;
}
FILE *slrn_open_tmpfile (char *file, char *mode)
{
FILE *fp = NULL;
#ifdef _AIX /* AIX doesn't have mktemp() */
char *f = tempnam (NULL, "SLRN");
if (f != NULL)
{
strcpy (file, f);
fp = fopen (f, mode);
free (f);
}
#else
char *dir;
# ifdef __os2__
dir = getenv ("TMP");
if (dir == NULL)
# endif
dir = getenv ("TMPDIR");
# ifdef VMS
if (dir == NULL) dir = "SYS$LOGIN:";
sprintf (file, "%sSLRN%uXXXXXX", dir, (unsigned int) getpid ());
# else
if (dir == NULL) dir = "/tmp";
sprintf (file, "%s/SLRN%uXXXXXX", dir, (unsigned int) getpid ());
# endif
if (NULL != mktemp (file)) fp = fopen (file, mode);
#endif
return fp;
}
FILE *slrn_open_home_file (char *name, char *mode, char *file, int create_flag)
{
slrn_make_home_filename (name, file);
#ifdef VMS
if (create_flag)
{
FILE *fp = fopen (file, mode, "fop=cif");
if (fp == NULL) perror ("fopen");
return fp;
}
#endif
return fopen (file, mode);
}
/* invoke the editor */
int slrn_posix_system (char *cmd, int reset)
{
int init_mode = Slrn_TT_Initialized;
#ifndef VMS
void (*sint)(int);
void (*squit)(int);
int ret;
sint = signal (SIGINT, SIG_IGN);
squit = signal (SIGQUIT, SIG_IGN);
if (reset) slrn_reset_display (0);
ret = system (cmd);
signal (SIGINT, sint);
# ifdef SIGQUIT
signal (SIGQUIT, squit);
# endif
#else
int ret;
if (reset) slrn_reset_display (0);
ret = system (cmd);
#endif
if (reset) slrn_init_display (init_mode, 0);
return ret;
}
static int create_edit_command (char *edit, char *cmd, char *file, unsigned int line)
{
int d, s;
char ch, *p = edit;
/* Look for %d and %s */
d = s = 0;
while (0 != (ch = *p++))
{
if (ch != '%') continue;
ch = *p;
if (!d && (ch == 'd'))
{
*p = 'u'; /* map %d to %u (unsigned) */
if (s == 0) d = 1; else d = 2;
}
else if (!s && (ch == 's'))
{
if (d == 0) s = 1; else s = 2;
}
else
{
slrn_error ("Invalid Editor definition.");
return 0;
}
p++;
}
/* No %d, %s */
if ((d == 0) && (s == 0))
{
sprintf (cmd, "%s %s", edit, file);
}
else if (d == 0)
{
sprintf (cmd, edit, file);
}
else if (s == 0)
{
sprintf (cmd, edit, (int) line);
strcat (edit, " ");
strcat (edit, file);
}
else /* d and s */
{
if (d == 1)
sprintf (cmd, edit, line, file);
else sprintf (cmd, edit, file, line);
}
return 1;
}
int slrn_edit_file (char *file, unsigned int line)
{
char buf[512];
char editbuf[512];
int ret;
char *editor = Slrn_Editor;
if ((editor == NULL)
&& (NULL == (editor = getenv("SLRN_EDITOR")))
&& (NULL == (editor = getenv("SLANG_EDITOR")))
&& (NULL == (editor = getenv("EDITOR")))
&& (NULL == (editor = getenv("VISUAL"))))
{
#ifdef VMS
editor = "edit";
#else
# ifdef __os2__
editor = "e";
# else
# ifdef unix
editor = "vi";
# endif
# endif
#endif
}
strcpy (editbuf, editor);
if (0 == create_edit_command(editbuf, buf, file, line)) return -1;
ret = slrn_posix_system (buf, 1);
/* Am I the only one who thinks this is a good idea?? */
if (Slrn_TT_Initialized) while (SLang_input_pending (5))
{
SLang_flush_input ();
}
/* slrn_redraw (); */
return ret;
}
void slrn_suspend_cmd (void)
{
slrn_suspend (0);
}
char slrn_get_response (char *valid_chars, char *str, ...)
{
char ch;
va_list ap;
char *v;
/* if (SLang_Error) return -1; */
while (1)
{
if (Slrn_TT_Initialized == 0)
{
char buf[256];
va_start(ap, str);
(void) vfprintf(stdout, str, ap);
va_end(ap);
fflush (stdout);
*buf = 0;
(void) fgets (buf, sizeof(buf), stdin);
ch = *buf;
}
else
{
SLang_flush_input ();
slrn_clear_message ();
va_start(ap, str);
(void) SLsmg_vprintf(str, ap);
va_end(ap);
slrn_smg_refresh ();
ch = SLang_getkey ();
slrn_clear_message ();
SLang_Error = SLKeyBoard_Quit = 0;
}
v = valid_chars;
while (*v)
{
if (*v == ch) return ch;
v++;
}
slrn_error ("Invalid response! Try again.");
if (Slrn_TT_Initialized & 1)
{
slrn_smg_refresh ();
(void) SLang_input_pending (15);
}
}
}
int slrn_get_yesno (int dflt, char *str, ...)
{
va_list ap;
char buf[512];
char ch, rsp;
char *fmt;
/* if (SLang_Error) return -1; */
va_start(ap, str);
(void) vsprintf(buf, str, ap);
va_end(ap);
if (dflt)
{
ch = 'y';
fmt = "? ([y]/n)";
}
else
{
ch = 'n';
fmt = "? (y/[n])";
}
strcat (buf, fmt);
rsp = slrn_get_response ("yYnN\r", buf);
if (rsp == '\r') rsp = ch;
else rsp |= 0x20;
if (rsp == 'n') return 0;
return 1;
}
int slrn_get_yesno_cancel (char *str, ...)
{
va_list ap;
char buf[512];
if (SLang_Error) return -1;
va_start(ap, str);
(void) vsprintf(buf, str, ap);
va_end(ap);
strcat (buf, "? [Y]-es, N-o, C-ancel");
switch (slrn_get_response ("\007yYnNcC\r", buf))
{
case '\r':
case 'Y':
case 'y':
return 1;
case 'n':
case 'N':
return 0;
default:
return -1;
}
}
Slrn_User_Info_Type Slrn_User_Info =
{
NULL, /* realname */
NULL, /* username */
"", /* host */
NULL, /* reply to */
NULL, /* org */
NULL, /* followup_string */
NULL /* signature */
};
#if defined(VMS) && defined(MULTINET)
# include "multinet_root:[multinet.include]netdb.h"
#else
# include <netdb.h>
# ifndef h_errno
extern int h_errno;
# endif
#endif
char *slrn_make_startup_string (char *s)
{
char *ss;
ss = (char *) SLMALLOC (strlen (s) + 1);
if (ss == NULL)
{
slrn_exit_error ("Out of memory.");
}
strcpy (ss, s);
return ss;
}
char *slrn_skip_whitespace (char *b)
{
register char ch;
while (((ch = *b) == ' ') || (ch == '\t') || (ch == '\n'))
b++;
return b;
}
/* returns a pointer to the end of the string */
char *slrn_trim_string (char *smin)
{
register char *s, ch;
if (smin == NULL) return NULL;
s = smin + strlen (smin);
while (s > smin)
{
s--;
ch = *s;
if ((ch == ' ')
|| (ch == '\n')
|| (ch == '\t'))
{
*s = 0;
continue;
}
s++;
break;
}
return s;
}
char *slrn_strchr (char *s, char ch)
{
register char ch1;
while (((ch1 = *s) != 0) && (ch != ch1)) s++;
if (ch1 == 0) return NULL;
return s;
}
int slrn_is_fqdn (char *h)
{
char *p;
/* Believe it or not, I have come across one system with a '(' character
* as part of the hostname!!! I suppose that I should also check for
* other strange characters as well. This is an issue since a message
* id will be composed from the fqdn. For that reason, such names will
* be rejected. Sigh.
*/
if ((NULL != slrn_strchr (h, '('))
|| (NULL != slrn_strchr (h, '@')))
return 0;
p = slrn_strchr (h, '.');
return ((p != NULL) && (p != h));
}
void slrn_get_user_info (void)
{
struct hostent *host_entry;
char *name, *host;
#ifndef VMS
struct passwd *pw;
pw = getpwuid (getuid ());
#endif
/* Fill in what is assumed to be non-NULL by rest of program. */
Slrn_User_Info.followup_string = slrn_make_startup_string ("In article %m, %r wrote:");
Slrn_Courtesy_CC_Message = slrn_make_startup_string ("[This message has also been posted.]");
/* Now get default values for rest. */
host = Slrn_User_Info.host;
/* gethostname may not provide the full name so use gethostbyname
* to get more information. Why isn't there a simplified interface to
* get the FQDN!!!!
*/
host_entry = NULL;
if (-1 != gethostname (host, MAX_HOST_NAME_LEN))
host_entry = gethostbyname (host);
#ifdef TRY_AGAIN
if ((host_entry == NULL) && (h_errno == TRY_AGAIN))
{
sleep (2);
host_entry = gethostbyname (host);
}
#endif
if ((host_entry == NULL) || (host_entry->h_name == NULL))
*host = 0;
else
{
if (slrn_is_fqdn ((char *)host_entry->h_name))
{
Slrn_User_Info.posting_host = slrn_make_startup_string ((char *)host_entry->h_name);
}
else
{
char **aliases;
aliases = host_entry->h_aliases;
if (aliases != NULL) while (*aliases != NULL)
{
if (slrn_is_fqdn (*aliases))
{
Slrn_User_Info.posting_host = slrn_make_startup_string (*aliases);
break;
}
aliases++;
}
}
if (Slrn_User_Info.posting_host == NULL)
{
strcpy (host, (char *) host_entry->h_name);
}
else strcpy (host, Slrn_User_Info.posting_host);
}
#if defined(USE_DOMAIN_NAME) && defined(MY_DOMAIN_NAME)
if (*host && (0 == slrn_is_fqdn (host)))
{
char *my_domain_name;
unsigned int len;
len = strlen (host);
my_domain_name = MY_DOMAIN_NAME;
if (*my_domain_name != '.')
{
host[len++] = '.';
}
strcpy (host + len, my_domain_name);
}
#endif
/* If a value was compiled in, use it. */
#ifdef OUR_HOSTNAME
# ifdef unix
/* If the value is a file, read the file for the FQDN */
if (OUR_HOSTNAME[0] == '/')
{
FILE *fp;
if (NULL != (fp = fopen(OUR_HOSTNAME, "r")))
{
char tmphost[MAX_HOST_NAME_LEN];
if (fgets(tmphost, MAX_HOST_NAME_LEN , fp) != NULL)
{
char *p;
if ((p = slrn_strchr (tmphost, '\n')) != NULL)
*p = '\0';
/* If the entry is valid, we're done */
if (slrn_is_fqdn(tmphost))
strcpy(host, tmphost);
}
fclose(fp);
}
}
else
# endif
if (slrn_is_fqdn (OUR_HOSTNAME)
&& strlen(OUR_HOSTNAME) < MAX_HOST_NAME_LEN)
strcpy (host, OUR_HOSTNAME);
#endif
/* Allow user chance to over ride this. Until now, host was a pointer
* to Slrn_User_Info.host.
*/
if ((NULL != (host = getenv ("HOSTNAME")))
&& slrn_is_fqdn (host))
{
strncpy (Slrn_User_Info.host, host, MAX_HOST_NAME_LEN);
Slrn_User_Info.host[MAX_HOST_NAME_LEN - 1] = 0;
}
if (
#ifdef VMS
((name = getlogin()) == NULL)
#else
/* I cannot use getlogin under Unix because some implementations
* truncate the username to 8 characters. Besides, I suspect that
* it is equivalent to the following line.
*/
((pw == NULL)
|| (NULL == (name = pw->pw_name))
|| (*name == 0))
#endif
&& ((name = getenv("USER")) == NULL)
&& ((name = getenv("LOGNAME")) == NULL))
name = "";
Slrn_User_Info.username = slrn_make_startup_string (name);
if ((Slrn_User_Info.replyto = getenv ("REPLYTO")) == NULL)
Slrn_User_Info.replyto = "";
Slrn_User_Info.replyto = slrn_make_startup_string (Slrn_User_Info.replyto);
#ifdef VMS
Slrn_User_Info.realname = fix_fullname(get_uaf_fullname());
#else
if (((Slrn_User_Info.realname = getenv ("NAME")) == NULL)
&& ((pw == NULL) || ((Slrn_User_Info.realname = pw->pw_gecos) == NULL)))
{
Slrn_User_Info.realname = "";
}
#endif
Slrn_User_Info.realname = slrn_make_startup_string (Slrn_User_Info.realname);
/* truncate at character used to delineate extra gecos fields */
name = Slrn_User_Info.realname;
while (*name && (*name != ',')) name++;
*name = 0;
Slrn_User_Info.org = getenv ("ORGANIZATION");
#ifdef OUR_ORGANIZATION
if (Slrn_User_Info.org == NULL) Slrn_User_Info.org = OUR_ORGANIZATION;
#endif
if (Slrn_User_Info.org != NULL)
{
/* Check to see if this is an organization file. */
char orgbuf[512];
if (*Slrn_User_Info.org == '/')
{
FILE *fporg;
if (NULL != (fporg = fopen (Slrn_User_Info.org, "r")))
{
if (NULL != fgets (orgbuf, sizeof (orgbuf) - 1, fporg))
{
unsigned int orglen = strlen (orgbuf);
if (orglen && (orgbuf[orglen - 1] == '\n'))
orgbuf[orglen - 1] = 0;
Slrn_User_Info.org = orgbuf;
}
slrn_fclose (fporg);
}
}
Slrn_User_Info.org = slrn_make_startup_string (Slrn_User_Info.org);
}
Slrn_User_Info.signature = slrn_make_startup_string (SLRN_SIGNATURE_FILE);
#if SLRN_HAS_MIME
Slrn_Mime_Display_Charset = slrn_make_startup_string ("iso-8859-1");
#endif
#ifdef SLRN_SENDMAIL_COMMAND
Slrn_SendMail_Command = slrn_make_startup_string (SLRN_SENDMAIL_COMMAND);
#endif
}
void update_top_status_line (void)
{
if (Slrn_Full_Screen_Update == 0) return;
SLsmg_gotorc (0, 0);
slrn_set_color (MENU_COLOR);
SLsmg_printf ("\
slrn %s ** Press '?' for help, 'q' to quit. ** Server: %s",
Slrn_Version,
Slrn_Server_Obj->sv_name);
SLsmg_erase_eol ();
slrn_set_color (0);
}
static void rline_update (unsigned char *buf, int len, int col)
{
SLsmg_gotorc (SLtt_Screen_Rows - 1, 0);
SLsmg_write_nchars ((char *) buf, len);
SLsmg_erase_eol ();
SLsmg_gotorc (SLtt_Screen_Rows - 1, col);
slrn_smg_refresh ();
}
SLang_RLine_Info_Type *Slrn_Keymap_RLI;
static SLang_RLine_Info_Type *init_readline (void)
{
unsigned char *buf = NULL;
SLang_RLine_Info_Type *rli;
if ((NULL == (rli = (SLang_RLine_Info_Type *) SLMALLOC (sizeof(SLang_RLine_Info_Type))))
|| (NULL == (buf = (unsigned char *) SLMALLOC (256))))
{
if (rli != NULL) SLFREE (rli);
fprintf(stderr, "malloc error.\n");
return NULL;
}
SLMEMSET ((char *) rli, 0, sizeof (SLang_RLine_Info_Type));
rli->buf = buf;
rli->buf_len = 255;
rli->tab = 8;
rli->dhscroll = 20;
rli->getkey = SLang_getkey;
rli->tt_goto_column = NULL;
rli->update_hook = rline_update;
if (SLang_init_readline (rli) < 0)
{
SLFREE (rli);
SLFREE (buf);
rli = NULL;
}
return rli;
}
int slrn_init_readline (void)
{
if ((Slrn_Keymap_RLI == NULL)
&& (NULL == (Slrn_Keymap_RLI = init_readline ())))
return -1;
return 0;
}
int slrn_read_input (char *prompt, char *str, int trim_flag)
{
int i;
Slrn_Keymap_RLI->edit_width = SLtt_Screen_Cols - 1;
Slrn_Keymap_RLI->prompt = prompt;
*Slrn_Keymap_RLI->buf = 0;
if (*str)
{
strcpy ((char *) Slrn_Keymap_RLI->buf, str);
Slrn_Keymap_RLI->point = 0; /* strlen (str); */
}
*str = 0;
slrn_enable_mouse (0);
i = SLang_read_line (Slrn_Keymap_RLI);
slrn_enable_mouse (1);
if ((i >= 0) && !SLang_Error && !SLKeyBoard_Quit)
{
char *b = (char *) Slrn_Keymap_RLI->buf;
/* SLang_rline_save_line (Slrn_Keymap_RLI); */
if (trim_flag)
{
slrn_trim_string (b);
b = slrn_skip_whitespace (b);
}
strcpy (str, b);
i = strlen (str);
}
if (SLKeyBoard_Quit) i = -1;
SLang_Error = SLKeyBoard_Quit = 0;
/* put cursor at edge of screen to comfort user */
SLsmg_gotorc (SLtt_Screen_Rows - 1, 0);
slrn_smg_refresh ();
return i;
}
int slrn_read_integer (char *prompt, int *dflt, int *np)
{
char buf[256];
char str[256];
int n;
if (dflt != NULL)
{
sprintf (buf, "%s (default: %d) ", prompt, *dflt);
}
else strcpy (buf, prompt);
*str = 0;
if (-1 == (n = slrn_read_input (buf, str, 1)))
{
slrn_error ("Abort!");
return -1;
}
if (1 != sscanf(str, "%d", &n))
{
if ((*str == 0) && (dflt != NULL)) n = *dflt;
else
{
slrn_error ("Integer expected.");
return -1;
}
}
*np = n;
return 0;
}
int slrn_mail_file (char *file, int edit, unsigned int editline, char *to, char *subject)
{
char buf[256];
if (edit)
{
if (slrn_edit_file (file, editline) < 0) return -1;
while (1)
{
char rsp;
rsp = slrn_get_response ("yYnNeE", "Mail the message? y/n/e(dit)");
rsp |= 0x20;
if (rsp == 'n') return -1;
if (rsp == 'y') break;
if (slrn_edit_file (file, 1) < 0) return -1;
}
}
slrn_message ("Sending..."); slrn_smg_refresh ();
#ifdef VMS
sprintf(buf, "%s\"%s\"", MAIL_PROTOCOL, to);
vms_send_mail( buf, subject, file );
#else
/* What I need to do is to open the file and feed it line by line to the
* sendmail program. This way I can strip out blank headers.
*/
if (Slrn_Use_Mime)
{
FILE *fp, *pp;
int header = 1;
char line[1024];
fp = fopen (file, "r");
if (fp == NULL) return (-1);
slrn_mime_scan_file (fp);
pp = slrn_popen (Slrn_SendMail_Command, "w");
if (pp == NULL)
{
slrn_fclose (fp);
return (-1);
}
while (fgets (line, sizeof(line), fp) != NULL)
{
int len = strlen (line);
line[len - 1] = 0;
if (header)
{
if (line[0] == 0)
{
header = 0;
slrn_mime_add_headers (pp);
fp = slrn_mime_encode (fp);
}
slrn_mime_header_encode (line, sizeof(line));
}
fputs (line, pp);
putc('\n', pp);
}
slrn_pclose (pp);
slrn_fclose (fp);
}
else
{
#ifdef __os2__
sprintf (buf, "%s -af %s", Slrn_SendMail_Command, file);
#else
sprintf (buf, "%s < %s", Slrn_SendMail_Command, file);
#endif
slrn_posix_system (buf, 0);
}
#endif /* NOT VMS */
slrn_message ("Sending...done");
return 0;
}
char *slrn_fix_regexp (char *pat)
{
static char newpat[256];
char *p, ch;
p = newpat;
*p++ = '^';
while ((ch = *pat++) != 0)
{
if (ch == '.')
{
*p++ = '\\';
}
else if (ch == '*')
{
*p++ = '.';
}
*p++ = ch;
}
*p = 0;
return newpat;
}
SLRegexp_Type *slrn_compile_regexp_pattern (char *pat)
{
static unsigned char compiled_pattern_buf [512];
static SLRegexp_Type re;
re.pat = (unsigned char *) pat;
re.buf = compiled_pattern_buf;
re.buf_len = sizeof (compiled_pattern_buf);
re.case_sensitive = 0;
if (0 != SLang_regexp_compile (&re))
{
slrn_error ("Invalid regular expression or expression too long.");
return NULL;
}
return &re;
}
unsigned char *slrn_regexp_match (SLRegexp_Type *re, char *str)
{
unsigned int len;
if ((str == NULL)
|| (re->min_length > (len = strlen (str))))
return NULL;
return SLang_regexp_match ((unsigned char *)str, len, re);
}
int slrn_file_exists (char *file)
{
struct stat st;
int m;
#ifdef _S_IFDIR
# ifndef S_IFDIR
# define S_IFDIR _S_IFDIR
# endif
#endif
#ifndef S_ISDIR
# ifdef S_IFDIR
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
# else
# define S_ISDIR(m) 0
# endif
#endif
if (stat(file, &st) < 0) return 0;
m = st.st_mode;
if (S_ISDIR(m)) return (2);
return 1;
}
void slrn_get_mouse_rc (int *rp, int *cp)
{
int r, c;
c = (unsigned char) SLang_getkey () - 32;
r = (unsigned char) SLang_getkey () - 32;
if (cp != NULL) *cp = c;
if (rp != NULL) *rp = r;
}
#if SLRN_HAS_PIPING
int slrn_pclose (FILE *fp)
{
int ret;
if (fp == NULL) return -1;
ret = pclose (fp);
if (ret)
{
char buf[256];
fprintf (stderr, "Command returned non-zero exit status. Press RETURN.\n");
fgets (buf, 255, stdin);
}
slrn_init_display (3, 0);
return 0;
}
FILE *slrn_popen (char *cmd, char *mode)
{
FILE *fp;
slrn_reset_display (0);
fp = popen (cmd, mode);
if (fp == NULL)
{
char buf[256];
fprintf (stderr, "Command %s failed to run. Press RETURN.\n", cmd);
fgets (buf, 255, stdin);
slrn_init_display (3, 0);
}
return fp;
}
#endif
int slrn_delete_file (char *f)
{
#ifdef VMS
return delete(f);
#else
return unlink(f);
#endif
}
char *slrn_simple_strtok (char *s, char *chp)
{
static char *s1;
char ch = *chp;
if (s == NULL)
{
if (s1 == NULL) return NULL;
s = s1;
}
else s1 = s;
while (*s1 && (*s1 != ch)) s1++;
if (*s1 == 0)
{
s1 = NULL;
}
else *s1++ = 0;
return s;
}
int slrn_fclose (FILE *fp)
{
if (0 == fclose (fp)) return 0;
slrn_error ("Error closing file. File system full? (errno = %d)", errno);
return -1;
}
void slrn_do_key (SLKeyMap_List_Type *map)
{
SLang_Key_Type *key;
static SLKeyMap_List_Type *last_map;
static SLang_Key_Type *last_key;
key = SLang_do_key (map, (int (*)(void)) SLang_getkey);
if (Slrn_Message_Present || SLang_Error)
{
#if SLRN_HAS_SLANG
if (SLang_Error) SLang_restart (0);
#endif
slrn_clear_message ();
}
SLang_Error = SLKeyBoard_Quit = 0;
if ((key == NULL) || (key->type == 0))
{
SLtt_beep ();
return;
}
if (key->type == SLKEY_F_INTRINSIC)
{
if ((map == last_map) && (key->f.f == (FVOID_STAR) slrn_repeat_last_key))
key = last_key;
/* set now to avoid problems with recursive call */
last_key = key;
last_map = map;
if (key->type == SLKEY_F_INTRINSIC)
{
(((void (*)(void))(key->f.f)) ());
return;
}
}
/* Otherwise we have interpreted key. */
#if SLRN_HAS_SLANG
last_key = key;
last_map = map;
Slrn_Full_Screen_Update = 1;
if ((*key->f.s == '.')
|| !SLang_execute_function (key->f.s))
SLang_load_string(key->f.s);
#endif
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.