This is slrn.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 <signal.h>
#include <string.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef VMS
# include <unixlib.h>
# include <unixio.h>
# include <dvidef.h>
# include <descrip.h>
#else
# ifndef sun
# include <sys/ioctl.h>
# endif
# ifdef HAVE_TERMIOS_H
# include <termios.h>
# endif
# ifdef SYSV
# include <sys/termio.h>
# include <sys/stream.h>
# include <sys/ptem.h>
# include <sys/tty.h>
# endif
#endif /* !VMS */
#include <slang.h>
#include "jdmacros.h"
#include <errno.h>
#include "server.h"
#include "slrn.h"
#include "group.h"
#include "misc.h"
#include "startup.h"
#include "art.h"
#include "score.h"
#if SLRN_HAS_GROUPLENS
# include "grplens.h"
#endif
#if SLRN_HAS_SLANG
# include "interp.h"
#endif
#ifdef __os2__
# define INCL_VIO
# include <os2.h>
#endif
#ifdef SIGSTOP
# define USE_RESUME_SMG
#endif
int Slrn_TT_Initialized = 0;
/* If -1, force mouse. If 1 the mouse will be used on in XTerm. If 0,
* do not use it.
*/
int Slrn_Use_Mouse;
char *Slrn_Version = SLRN_VERSION;
int Slrn_Suspension_Ok;
void slrn_set_suspension (int ok)
{
if (ok == Slrn_Suspension_Ok) return;
#ifdef USE_RESUME_SMG
SLtty_set_suspend_state (ok);
#endif
Slrn_Suspension_Ok = ok;
}
void slrn_smg_refresh (void)
{
int ok = Slrn_Suspension_Ok;
if (ok) slrn_set_suspension (0);
if (Slrn_TT_Initialized & 1) SLsmg_refresh ();
if (ok) slrn_set_suspension (1);
}
static void set_signal_to_restart_syscalls (int sig)
{
#ifdef SLRN_POSIX_SIGNALS
struct sigaction sa;
if (-1 == sigaction (sig, NULL, &sa)) return;
# ifdef SIGALRM
if (sig == SIGALRM)
{
# ifdef SA_INTERRUPT
sa.sa_flags |= SA_INTERRUPT;
# endif
}
else
{
# endif /* SIGALRM */
# ifdef SA_RESTART
sa.sa_flags |= SA_RESTART;
# endif
# ifdef SIGALRM
}
# endif
(void) sigaction (sig, &sa, NULL);
#endif /* SLRN_POSIX_SIGNALS */
}
static int Can_Suspend;
void slrn_suspend (int sig)
{
#ifndef SIGSTOP
slrn_error ("Not implemented.");
#else
int init = Slrn_TT_Initialized;
# ifdef SLRN_POSIX_SIGNALS
sigset_t mask;
if (Can_Suspend == 0)
{
slrn_error ("Suspension not allowed by shell.");
return;
}
sigemptyset (&mask);
sigaddset (&mask, SIGTSTP);
/* This function resets SIGTSTP to default */
slrn_reset_display (sig);
kill (getpid (), SIGTSTP);
/* If SIGTSTP is pending, it will be delivered now. That's ok. */
sigprocmask (SIG_UNBLOCK, &mask, NULL);
# else
if (Can_Suspend == 0)
{
slrn_error ("Suspension not allowed by shell.");
return;
}
slrn_reset_display (sig);
kill(getpid(),SIGSTOP);
# endif
slrn_init_display (init, sig);
if (Slrn_Suspension_Ok) SLtty_set_suspend_state (1);
#endif
}
static void test_lock( char *file )
{
int pid;
FILE *fp;
if ((fp = fopen (file, "r")) != NULL)
{
if (1 == fscanf (fp, "%d", &pid) )
{
if ((pid > 0) && (0 == kill (pid, 0)))
{
slrn_exit_error ("slrn: pid %d is locking the newsrc file.", pid);
}
}
slrn_fclose (fp);
}
}
static int make_lock( char *file )
{
int pid;
FILE *fp;
#ifdef VMS
fp = fopen (file, "w", "fop=cif");
#else
fp = fopen (file, "w");
#endif
if (fp == NULL) return -1;
pid = getpid ();
fprintf (fp, "%d", pid);
slrn_fclose (fp);
return 0;
}
static void lock_file (int how)
{
char file[1024];
char name[256];
static int not_ok_to_unlock;
#if SLRN_HAS_RNLOCK
int rnlock = 0;
char file_rn[1024];
#endif
if (Slrn_Newsrc_File == NULL) return;
if (not_ok_to_unlock) return;
not_ok_to_unlock = 1;
#ifndef __os2__
sprintf (name, "%s-lock", Slrn_Newsrc_File);
#else
sprintf (name, "lk-%s", Slrn_Newsrc_File);
#endif
slrn_make_home_filename (name, file);
#if SLRN_HAS_RNLOCK
if (0 == strcmp(".newsrc", Slrn_Newsrc_File))
{
rnlock = 1;
slrn_make_home_filename (".rnlock", file_rn);
}
#endif
if (how == 1)
{
test_lock (file);
#if SLRN_HAS_RNLOCK
if (rnlock) test_lock (file_rn);
#endif
if (-1 == make_lock (file))
{
slrn_exit_error ("Unable to create lock file %s.", file);
}
#if SLRN_HAS_RNLOCK
if (rnlock && (-1 == make_lock (file_rn)))
{
slrn_delete_file (file); /* delete the "normal" lock file */
slrn_exit_error ("Unable to create lock file %s.", file_rn);
}
#endif
}
else
{
if (-1 == slrn_delete_file (file))
{
/* slrn_exit_error ("Unable to remove lockfile %s.", file); */
}
#if SLRN_HAS_RNLOCK
if (rnlock && -1 == slrn_delete_file (file_rn))
{
/* slrn_exit_error ("Unable to remove lockfile %s.", file_rn); */
}
#endif
}
not_ok_to_unlock = 0;
}
static void slrn_set_screen_size (int sig)
{
int r = 0, c = 0;
#ifdef VMS
int status, code;
unsigned short chan;
$DESCRIPTOR(dev_dsc, "SYS$INPUT:");
#endif
#ifdef __os2__
VIOMODEINFO vioModeInfo;
#endif
#ifdef TIOCGWINSZ
struct winsize wind_struct;
do
{
if ((ioctl(1,TIOCGWINSZ,&wind_struct) == 0)
|| (ioctl(0, TIOCGWINSZ, &wind_struct) == 0)
|| (ioctl(2, TIOCGWINSZ, &wind_struct) == 0))
{
c = (int) wind_struct.ws_col;
r = (int) wind_struct.ws_row;
break;
}
}
while (errno == EINTR);
#endif
#ifdef VMS
status = sys$assign(&dev_dsc,&chan,0,0,0);
if (status & 1)
{
code = DVI$_DEVBUFSIZ;
status = lib$getdvi(&code, &chan,0, &c, 0,0);
if (!(status & 1))
c = 80;
code = DVI$_TT_PAGE;
status = lib$getdvi(&code, &chan,0, &r, 0,0);
if (!(status & 1))
r = 24;
sys$dassgn(chan);
}
#endif
#ifdef __os2__
vioModeInfo.cb = sizeof(vioModeInfo);
VioGetMode (&vioModeInfo, 0);
c = vioModeInfo.col;
r = vioModeInfo.row;
#endif
if (r <= 0)
{
char *s = getenv ("LINES");
if (s != NULL) r = atoi (s);
}
if (c <= 0)
{
char *s = getenv ("COLUMNS");
if (s != NULL) c = atoi (s);
}
if ((r <= 0) || (r > 200)) r = 24;
if ((c <= 0) || (c > 250)) c = 80;
SLtt_Screen_Rows = r;
SLtt_Screen_Cols = c;
Slrn_Group_Window_Size = SLtt_Screen_Rows - 3;
#ifdef SIGWINCH
if (sig == SIGWINCH)
{
SLsmg_reset_smg ();
SLsmg_init_smg ();
if ((Slrn_Current_Mode != NULL)
&& (Slrn_Current_Mode->sigwinch_fun != NULL))
(*Slrn_Current_Mode->sigwinch_fun) ();
slrn_redraw ();
}
signal (SIGWINCH, slrn_set_screen_size);
#endif
}
static void slrn_hangup (int sig)
{
slrn_init_hangup_signals (0);
if ((Slrn_Current_Mode != NULL)
&& (Slrn_Current_Mode->hangup_fun != NULL))
(*Slrn_Current_Mode->hangup_fun) (sig);
else
slrn_write_newsrc ();
slrn_quit (sig);
}
static void init_like_signals (int argc, int *argv,
void (*f0)(int),
void (*f1)(int),
int state)
{
#ifdef HAVE_SIGACTION
struct sigaction sa;
#endif
int i;
if (state == 0)
{
for (i = 0; i < argc; i++)
signal (argv[i], f0);
return;
}
for (i = 0; i < argc; i++)
{
int sig = argv[i];
signal (sig, f1);
#if defined(SLRN_POSIX_SIGNALS)
if (-1 != sigaction (sig, NULL, &sa))
{
int j;
for (j = 0; j < argc; j++)
{
if (j != i) sigaddset (&sa.sa_mask, argv[j]);
}
(void) sigaction (sig, &sa, NULL);
}
#endif
}
}
static void init_suspend_signals (int state)
{
int argv[2];
int argc = 0;
#ifdef SIGTSTP
argv[argc++] = SIGTSTP;
#endif
#ifdef SIGTTIN
argv[argc++] = SIGTTIN;
#endif
init_like_signals (argc, argv, SIG_DFL, slrn_suspend, state);
}
void slrn_init_hangup_signals (int state)
{
int argv[2];
int argc = 0;
#ifdef SIGHUP
argv[argc++] = SIGHUP;
#endif
#ifdef SIGTERM
argv[argc++] = SIGTERM;
#endif
init_like_signals (argc, argv, SIG_IGN, slrn_hangup, state);
}
void slrn_enable_mouse (int mode)
{
#ifndef __os2__
if (Slrn_Use_Mouse)
{
if (-1 == SLtt_set_mouse_mode (mode, (Slrn_Use_Mouse < 0)))
Slrn_Use_Mouse = 0;
}
#endif
}
/* if 1, init just slsmg. If 2, just sltt, if 3, do both */
void slrn_init_display (int init_mode, int sig)
{
Slrn_TT_Initialized |= init_mode;
init_suspend_signals (1);
#ifdef SIGPIPE
signal(SIGPIPE, SIG_IGN);
#endif
#ifdef SIGTTOU
/* Allow background writes */
signal (SIGTTOU, SIG_IGN);
#endif
slrn_init_hangup_signals (1);
if (init_mode & 2)
{
SLang_init_tty (7, 1, 0);
SLang_set_abort_signal (NULL);
#ifdef SIGINT
set_signal_to_restart_syscalls (SIGINT);
#endif
}
if (init_mode & 1)
{
slrn_enable_mouse (1);
#ifdef USE_RESUME_SMG
if (sig == SIGTSTP) SLsmg_resume_smg ();
else
{
#endif
slrn_set_screen_size (0);
SLsmg_init_smg ();
/* We do not want the -> overlay cursor to affect the scroll. */
#ifndef __os2__
SLsmg_Scroll_Hash_Border = 2;
#endif
slrn_redraw ();
}
#ifdef USE_RESUME_SMG
}
#endif
}
void slrn_reset_display (int sig)
{
int init = Slrn_TT_Initialized;
if (init == 0) return;
slrn_enable_mouse (0);
#ifdef USE_RESUME_SMG
if (sig == SIGTSTP) SLsmg_suspend_smg ();
else
{
#endif
SLsmg_gotorc (SLtt_Screen_Rows - 1, 0);
slrn_smg_refresh ();
SLsmg_reset_smg ();
#ifdef SIGWINCH
signal (SIGWINCH, SIG_DFL);
#endif
#ifdef USE_RESUME_SMG
}
#endif
if (init & 2) SLang_reset_tty ();
init_suspend_signals (0);
Slrn_TT_Initialized = 0;
}
void slrn_tty_message (int newline_flag, char *fmt, ...)
{
va_list ap;
if (newline_flag & 1) putc ('\n', stdout);
va_start (ap, fmt);
vfprintf (stdout, fmt, ap);
va_end(ap);
if (newline_flag & 2) putc ('\n', stdout);
fflush (stdout);
}
int slrn_get_new_news (int no_new_groups, int create_flag)
{
char msg1[] = "Checking for new groups...";
char msg2[] = "Checking news...";
char msg3[] = "Checking news via active file...";
char *msg;
if (Slrn_Server_Obj->sv_initialize () != 0) return (-1);
if (create_flag == 0)
{
if (no_new_groups == 0)
{
if (Slrn_TT_Initialized & 1)
{
slrn_message (msg1);
slrn_smg_refresh ();
}
else
slrn_tty_message (1, msg1);
slrn_check_new_groups (create_flag);
}
if (Slrn_List_Active_File) msg = msg3;
else msg = msg2;
if (Slrn_TT_Initialized & 1)
{
slrn_message (msg);
slrn_smg_refresh ();
}
else
slrn_tty_message (1, msg);
}
slrn_read_newsrc (create_flag);
slrn_read_group_descriptions ();
return (0);
}
char *Slrn_Newsrc_File = NULL;
char *Slrn_Lib_Dir = NULL;
#if !defined (SLRN_DEFAULT_SERVER_OBJ)
# if SLRN_HAS_NNTP_SUPPORT
# define SLRN_DEFAULT_SERVER_OBJ SLRN_SERVER_ID_NNTP
# else
# define SLRN_DEFAULT_SERVER_OBJ SLRN_SERVER_ID_SPOOL
# endif
#endif
#if !defined (SLRN_DEFAULT_POST_OBJ)
# if SLRN_HAS_NNTP_SUPPORT
# define SLRN_DEFAULT_POST_OBJ SLRN_POST_ID_NNTP
# else
# define SLRN_DEFAULT_POST_OBJ SLRN_POST_ID_INEWS
# endif
#endif
static void version (void)
{
unsigned int a, b, c;
a = SLANG_VERSION/10000;
b = (SLANG_VERSION - a * 10000) / 100;
c = SLANG_VERSION - (a * 10000) - (b * 100);
#if defined(__DATE__) && defined(__TIME__)
fprintf (stdout, "slrn version: %s (%s %s)\n", Slrn_Version, __DATE__, __TIME__);
#else
fprintf (stdout, "slrn version: %s\n", Slrn_Version);
#endif
fprintf (stdout, "S-Lang version: %u.%u.%u\n", a, b, c);
fprintf (stdout, "\nslrn compiled with support for:\n");
#if SLRN_HAS_NNTP_SUPPORT
fputs (" nntp", stdout);
#endif
#if SLRN_HAS_SPOOL_SUPPORT
fputs (" spool", stdout);
#endif
#if SLRN_HAS_INEWS_SUPPORT
fputs (" inews", stdout);
#endif
#if SLRN_HAS_GROUPLENS
fputs (" GroupLens", stdout);
#endif
#if SLRN_HAS_SLANG
fputs (" S-Lang", stdout);
#endif
fputs ("\nDefault server object: ", stdout);
switch (SLRN_DEFAULT_SERVER_OBJ)
{
case SLRN_SERVER_ID_NNTP:
fputs ("nntp", stdout);
break;
case SLRN_SERVER_ID_SPOOL:
fputs ("spool", stdout);
break;
}
fputs ("\nDefault posting mechanism: ", stdout);
switch (SLRN_DEFAULT_POST_OBJ)
{
case SLRN_POST_ID_NNTP:
fputs ("nntp", stdout);
break;
case SLRN_POST_ID_INEWS:
fputs ("inews", stdout);
#if SLRN_FORCE_INEWS
fputs (" (fixed)", stdout);
#endif
break;
}
fputc ('\n', stdout);
exit (0);
}
static void usage (char *extra)
{
fputs ("\
Usage: slrn [--inews ...] [--nntp ...] [--spool ...] OPTIONS\n\
-n Do not check for new groups. This usually results in\n\
a faster startup.\n\
-f newsrc-file Name of the newsrc file to use.\n\
-C Use colors.\n\
-create Create a newsrc file by getting list of groups from server.\n\
-d Get new text descriptions of each group from server.\n\
Note: This may take a LONG time to retrieve this information.\n\
The resulting file can be several hundred Kilobytes!\n\
-i init-file Name of initialization file to use (default .slrnrc)\n\
-Dname Add 'name' to list of predefined preprocessing tokens.\n\
-k Do not process score file.\n\
-k0 Process score file but inhibit expensive scores.\n\
-a Use active file for getting new news\n\
-m Force XTerm mouse reporting\n\
--help Print this usage.\n\
--version Show version and supported features\n\
\n\
For additional info use one of forms:\n\
slrn --inews --help\n\
slrn --nntp --help\n\
slrn --spool --help\n\
",
stderr);
if (extra != NULL)
{
fprintf (stderr, "\n%s\n", extra);
}
exit (1);
}
static int parse_object_args (char *obj, char **argv, int argc)
{
int num_parsed;
int zero_ok = 1;
if (obj == NULL)
{
zero_ok = 0;
#if SLRN_DEFAULT_SERVER_OBJ == SLRN_SERVER_ID_SPOOL
obj = "spool";
#endif
#if SLRN_DEFAULT_SERVER_OBJ == SLRN_SERVER_ID_NNTP
obj = "nntp";
#endif
}
num_parsed = slrn_parse_object_args (obj, argv, argc);
if (num_parsed == -1)
{
slrn_exit_error ("%s is not a supported option.", *argv);
}
if ((num_parsed == 0) && (zero_ok == 0))
usage (NULL);
return num_parsed;
}
int main (int argc, char **argv)
{
char *hlp_file;
int i;
int create_flag = 0;
int no_new_groups = 0;
int no_score_file = 0;
int use_color = 0;
int use_mouse = 0;
int dsc_flag = 0;
int use_active = 0;
FILE *fp;
char file[512];
char *init_file = SLRN_USER_SLRNRC_FILENAME;
Can_Suspend = 0;
#ifdef SIGTSTP
if (SIG_DFL == signal (SIGTSTP, SIG_DFL))
{
Can_Suspend = 1;
}
#endif
#ifdef __os2__
SLdefine_for_ifdef ("OS2");
#else
# ifdef VMS
SLdefine_for_ifdef ("VMS");
# else
SLdefine_for_ifdef ("UNIX");
# endif
#endif
#if 0
if (NULL != getenv ("AUTOSUBSCRIBE"))
Slrn_Unsubscribe_New_Groups = 0;
if (NULL != getenv ("AUTOUNSUBSCRIBE"))
Slrn_Unsubscribe_New_Groups = 1;
#endif
for (i = 1; i < argc; i++)
{
if (!strcmp ("--spool", argv[i])
|| !strcmp ("--nntp", argv[i])
|| !strcmp ("--inews", argv[i]))
{
i += parse_object_args (argv[i] + 2, argv + (i + 1), argc - (i + 1));
}
else if (!strcmp ("--help", argv[i])) usage (NULL);
else if (!strcmp ("-create", argv[i])) create_flag = 1;
else if (!strcmp ("-C", argv[i])) use_color = 1;
else if (!strcmp ("-a", argv[i])) use_active = 1;
else if (!strcmp ("-n", argv[i])) no_new_groups = 1;
else if (!strcmp ("-d", argv[i])) dsc_flag = 1;
else if (!strcmp ("-m", argv[i])) use_mouse = 1;
else if (!strcmp ("-k", argv[i])) no_score_file = 1;
else if (!strcmp ("-k0", argv[i]))
Slrn_Perform_Scoring &= ~SLRN_EXPENSIVE_SCORING;
else if (!strcmp ("--version", argv[i]))
{
version ();
}
else if (!strncmp ("-D", argv[i], 2) && (argv[i][2] != 0))
{
if (SLdefine_for_ifdef (argv[i] + 2) == 0)
{
slrn_exit_error ("Unable to add preprocessor name %s.",
argv[i] + 2);
}
}
else if (i + 1 < argc)
{
if (!strcmp ("-f", argv[i])) Slrn_Newsrc_File = argv[++i];
else if (!strcmp ("-i", argv[i])) init_file = argv[++i];
else
{
i += parse_object_args (NULL, argv + i, argc - i);
i -= 1;
}
}
else
{
i += parse_object_args (NULL, argv + i, argc - i);
i -= 1;
}
}
if (-1 == slrn_init_objects ())
{
slrn_exit_error ("Error configuring server objects.");
}
if (Slrn_Server_Id == 0) Slrn_Server_Id = SLRN_DEFAULT_SERVER_OBJ;
if (Slrn_Post_Id == 0) Slrn_Post_Id = SLRN_DEFAULT_POST_OBJ;
/* It has been suggested that this be moved to after reading the startup
* files.
*/
if ((-1 == slrn_select_server_object (Slrn_Server_Id))
|| (-1 == slrn_select_post_object (Slrn_Post_Id)))
{
slrn_exit_error ("Unable to select object.");
}
fprintf (stdout, "slrn %s\n", Slrn_Version);
if (dsc_flag && create_flag)
{
usage ("The -d and -create flags must not be specified together.");
}
SLtt_get_terminfo();
if (use_color) SLtt_Use_Ansi_Colors = 1;
slrn_startup_initialize ();
slrn_get_user_info ();
if (Slrn_Lib_Dir == NULL)
{
Slrn_Lib_Dir = getenv ("SLRN_LIB_DIR");
}
if (Slrn_Lib_Dir == NULL) Slrn_Lib_Dir = SLRN_LIB_DIR;
#ifdef VMS
sprintf (file, "%s%s", Slrn_Lib_Dir, "slrn.rc");
#else
sprintf (file, "%s/%s", Slrn_Lib_Dir, "slrn.rc");
#endif
#if SLRN_HAS_SLANG
if (-1 == slrn_init_slang ())
{
fprintf (stderr, "Error initializing S-Lang interpreter.\n");
}
#endif
slrn_read_startup_file (file); /* global file for all users */
slrn_read_startup_file (init_file);
#ifndef __os2__
/* Allow blink characters if in mono */
if (SLtt_Use_Ansi_Colors == 0)
SLtt_Blink_Mode = 1;
#endif
/* Now that we have read in the startup file, check to see if the user
* has a username and a usable hostname. Without those, we are not
* starting up.
*/
if (0 == slrn_is_fqdn (Slrn_User_Info.host))
{
slrn_exit_error ("\
Unable to find a fully qualified hostname. You will have to specify a\r\n\
hostname in your %s file.\r\n",
SLRN_USER_SLRNRC_FILENAME);
}
if ((NULL == Slrn_User_Info.username)
|| (0 == *Slrn_User_Info.username)
|| (NULL != slrn_strchr (Slrn_User_Info.username, '@')))
{
slrn_exit_error ("\
Unable to find you user name. This means that a valid 'From' header line\r\n\
cannot be constructed. Try setting the USER environment variable.\r\n");
}
if ((no_score_file == 0) && (Slrn_Score_File != NULL)
&& (-1 == slrn_read_score_file (Slrn_Score_File)))
{
slrn_exit_error ("Error processing score file %s", Slrn_Score_File);
}
hlp_file = getenv ("SLRNHELP");
if (hlp_file != NULL)
{
slrn_parse_helpfile (hlp_file);
}
if ((Slrn_Newsrc_File == NULL)
&& ((Slrn_Newsrc_File = slrn_map_file_to_host (Slrn_Server_Obj->sv_name)) == NULL))
#if defined(VMS) || defined(__os2__)
Slrn_Newsrc_File = "jnews.rc";
#else
Slrn_Newsrc_File = ".jnewsrc";
#endif
if (use_active) Slrn_List_Active_File = 1;
if (use_mouse) Slrn_Use_Mouse = -1; /* -1 forces it. */
if (dsc_flag)
{
if (Slrn_Server_Obj->sv_initialize () != 0)
{
slrn_exit_error ("Unable to initialize server.");
return (-1);
}
slrn_get_group_descriptions ();
Slrn_Server_Obj->sv_close ();
return 0;
}
if (create_flag == 0)
{
/* Check to see if the .newrc file exists--- I should use the access
* system call but for now, do it this way.
*/
if (NULL == (fp = slrn_open_home_file (Slrn_Newsrc_File, "r", file, 0)))
{
slrn_error ("Unable to open %s. I will try .newsrc.", file);
if (NULL == (fp = slrn_open_home_file (".newsrc", "r", file, 0)))
{
slrn_exit_error ("\r\nUnable to open %s.\r\n\
If you want to create %s, add command line options:\r\n\
-f %s -create\r\n", file, file, file);
}
}
slrn_fclose (fp);
lock_file (1);
}
#ifdef SLRN_HAS_SLANG
(void) SLang_run_hooks ("startup_hook", NULL, NULL);
#endif
#if SLRN_HAS_GROUPLENS
if (Slrn_Use_Group_Lens)
{
fprintf (stdout, "Initializing GroupLens\n");
if (-1 == slrn_init_grouplens ())
{
fprintf (stderr, "GroupLens disabled.\n");
Slrn_Use_Group_Lens = 0;
}
}
#endif
if (-1 == slrn_get_new_news (no_new_groups, create_flag))
{
slrn_exit_error ("Failed to initialize server.");
}
putc ('\n', stdout);
slrn_init_display (1 | 2, 0);
#if defined(unix) && !defined(__os2__)
if (Slrn_Autobaud) SLtt_Baud_Rate = SLang_TT_Baud_Rate;
#endif
slrn_main_loop ();
slrn_quit (0);
return 0;
}
void slrn_quit (int retcode)
{
Slrn_Server_Obj->sv_close ();
slrn_reset_display (0);
lock_file (0);
#if SLRN_HAS_GROUPLENS
slrn_close_grouplens ();
#endif
if (retcode) fprintf (stderr, "slrn: quiting on signal %d.\n", retcode);
exit (retcode);
}
void slrn_exit_error (char *fmt, ...)
{
va_list ap;
if (Slrn_Groups_Dirty) slrn_write_newsrc ();
if (Slrn_TT_Initialized)
{
slrn_reset_display (0);
Slrn_Server_Obj->sv_close ();
}
#if SLRN_HAS_GROUPLENS
slrn_close_grouplens ();
#endif
if (fmt != NULL)
{
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
va_end(ap);
}
putc ('\n', stderr);
lock_file (0);
exit (-1);
}
int slrn_main_loop (void)
{
if (-1 == slrn_select_group_mode ())
return -1;
#ifdef SLRN_HAS_SLANG
(void) SLang_run_hooks ("group_mode_hook", NULL, NULL);
#endif
while (1)
{
if (SLang_Error || !SLang_input_pending(0))
{
(*Slrn_Current_Mode->redraw_fun) ();
slrn_smg_refresh ();
}
slrn_do_key (Slrn_Current_Mode->keymap);
}
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.