ftp.nice.ch/pub/next/unix/network/news/slrn0.9.0.0.s.tar.gz#/slrn/src/startup.c

This is startup.c in view mode; [Download] [Up]

/*  Copyright (c) 1995 John E. Davis (davis@space.mit.edu)
 *  All rights reserved.
 */
/* Read startup .slrnrc file */

/* This file contains the following types of lines:
 *    server SERVER-NAME NEWSRC-FILE
 *    setkey KEYMAP FUNCTION KEYSEQUENCE
 *    unsetkey KEYMAP KEYSEQUENCE
 *
 * Lines are considered commented out if they start with a '%' character.
 */

#include "config.h"
#include "features.h"

#include <stdio.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif

#include <string.h>
#include <slang.h>

#include "jdmacros.h"

#include "slrn.h"
#include "group.h"
#include "misc.h"
#include "art.h"
#include "post.h"
#include "startup.h"
#include "score.h"
#include "uudecode.h"
#if SLRN_HAS_MIME
# include "mime.h"
#endif
#if SLRN_HAS_GROUPLENS
# include "grplens.h"
#endif
#if SLRN_HAS_SLANG
# include "interp.h"
#endif
#include "server.h"


static SLcmd_Cmd_Table_Type Slrn_Cmd_Table;


static int unsetkey_fun (int, SLcmd_Cmd_Table_Type *);
static int setkey_fun (int, SLcmd_Cmd_Table_Type *);
static int server_fun (int, SLcmd_Cmd_Table_Type *);
static int color_fun (int, SLcmd_Cmd_Table_Type *);
static int mono_fun (int, SLcmd_Cmd_Table_Type *);
static int user_data_fun (int, SLcmd_Cmd_Table_Type *);
static int ignore_quote_fun (int, SLcmd_Cmd_Table_Type *);
static int set_quote_fun (int, SLcmd_Cmd_Table_Type *);
static int autobaud_fun (int, SLcmd_Cmd_Table_Type *);
static int set_variable_fun (int, SLcmd_Cmd_Table_Type *);
static int nnrp_fun (int, SLcmd_Cmd_Table_Type *);
static int grouplens_fun (int, SLcmd_Cmd_Table_Type *);
static int interpret_fun (int, SLcmd_Cmd_Table_Type *);

static SLcmd_Cmd_Type Slrn_Startup_File_Cmds[] =
{
     {unsetkey_fun, "unsetkey", "SS"},
     {setkey_fun, "setkey", "SSS"},
     {server_fun, "server", "SS"},
     {color_fun, "color", "SSS"},
     {mono_fun, "mono", "SSsss"},
     {set_variable_fun, "set", "SG"},
     {user_data_fun, "replyto", "S"},
     {user_data_fun, "organization", "S"},
     {user_data_fun, "signature", "S"},
     {user_data_fun, "hostname", "S"},
     {user_data_fun, "realname", "S"},
     {user_data_fun, "followup", "S"},
     {user_data_fun, "username", "S"},
     {user_data_fun, "scorefile", "S"},
     {user_data_fun, "cc_followup_string", "S"},
#if SLRN_HAS_DECODE
     {user_data_fun, "decode_directory", "S"},
#endif
     {user_data_fun, "editor_command", "S"},
     {nnrp_fun, "nnrpaccess", "SSS" },
#define SLRN_MAX_QUOTE_REGEXP 5
     {ignore_quote_fun, "ignore_quotes", "Sssss"},
     {set_quote_fun, "quote_string", "S"},
     {autobaud_fun, "autobaud", ""},
     {grouplens_fun, "grouplens_add", "S"},
     {interpret_fun, "interpret", "S"},
     {NULL, "", ""}
};

SLRegexp_Type *Slrn_Ignore_Quote_Regexp [SLRN_MAX_QUOTE_REGEXP + 1];

static int This_Line_Num;		       /* current line number in startup file */
static char *This_File;
static char *This_Line;		       /* line being parsed */

static void exit_malloc_error (void)
{
   if (This_File == NULL)
     slrn_exit_error ("Memory Allocation Failure");
   
   slrn_exit_error ("%s: Line %d\n%sMemory Allocation Failure",
		    This_File, This_Line_Num, This_Line);
}

static char *safe_malloc (unsigned int n)
{
   char *s;
   s = (char *) SLMALLOC (n);
   if (s == NULL) exit_malloc_error ();
   return s;
}


static void exit_unknown_object (void)
{
   slrn_exit_error ("%s: Error encountered processing line %d\n%s",
		    This_File, This_Line_Num, This_Line);
}


static int setkey_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
   char *map = table->string_args[1];
   char *fun = table->string_args[2];
   char *key = table->string_args[3];
   
   SLKeyMap_List_Type *kmap = NULL;
   
   if (!strcmp (map, "group")) kmap = Slrn_Group_Keymap;
   else if (!strcmp (map, "article")) kmap = Slrn_Article_Keymap;
   else slrn_exit_error ("%s: line %d:\n%sNo such keymap: %s", This_File, This_Line_Num, This_Line, map);
   
   if (SLang_define_key (key, fun, kmap) != 0)
     {
	slrn_exit_error ("%s: line %d:\n%serror defining key.", This_File, This_Line_Num, This_Line);
     }
   return 0;
}

int Slrn_Autobaud = 0;
static int autobaud_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
   Slrn_Autobaud = 1;
   return 0;
}


static int unsetkey_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
   char *map = table->string_args[1];
   char *key = table->string_args[2];
   SLKeyMap_List_Type *kmap = NULL;
   
   if (!strcmp (map, "group")) kmap = Slrn_Group_Keymap;
   else if (!strcmp (map, "article")) kmap = Slrn_Article_Keymap;
   else slrn_exit_error ("%s: line %d:\n%sNo such keymap: %s",
			 This_File, This_Line_Num, This_Line, map);
   
   SLang_undefine_key (key, kmap);
   return 0;
}


static SLRegexp_Type *compile_quote_regexp (char *str)
{
   unsigned char *compiled_pattern_buf;
   SLRegexp_Type *r;
   
   compiled_pattern_buf = (unsigned char *) safe_malloc (512);
   r = (SLRegexp_Type *) safe_malloc (sizeof (SLRegexp_Type));
   
   r->pat = (unsigned char *) str;
   r->buf = compiled_pattern_buf;
   r->case_sensitive = 1;
   r->buf_len = 512;
   
   if (SLang_regexp_compile (r))
     {
	slrn_exit_error ("%s: line %d:\n%sInvalid regular expression.",
			 This_File, This_Line_Num, This_Line);
     }
   
   return r;
}

static int ignore_quote_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
   unsigned int i;
   SLRegexp_Type *r;
   
   if (argc > SLRN_MAX_QUOTE_REGEXP + 1)
     {
	slrn_exit_error ("%s: line %d:\n%sToo many expressions specified.",
			 This_File, This_Line_Num, This_Line);
     }
   
   for (i = 0; i < SLRN_MAX_QUOTE_REGEXP; i++)
     {
	r = Slrn_Ignore_Quote_Regexp[i];
	if (r != NULL)
	  {
	     if (r->buf != NULL)
	       SLFREE (r->buf);
	     SLFREE (r);
	     Slrn_Ignore_Quote_Regexp [i] = NULL;
	  }
     }
	
   for (i = 1; i < argc; i++)
     {
	Slrn_Ignore_Quote_Regexp[i - 1] 
	  = compile_quote_regexp (table->string_args[i]);
     }
   return 0;
}

static int set_quote_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
   static char quote[32];
   
   strncpy (quote, table->string_args[1], 31);
   quote[31] = 0;
   Slrn_Quote_String = quote;
   return 0;
}

static int grouplens_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
#if SLRN_HAS_GROUPLENS
   (void) slrn_grouplens_add_group (table->string_args[1]);
#endif
   return 0;
}

typedef struct
{
   char *what;
   int *valuep;
}
Set_Int_Type;

static Set_Int_Type Int_Things_To_Set [] =
{
     {"ignore_signature", &Slrn_Sig_Is_End_Of_Article},
#if SLRN_HAS_NNTP_SUPPORT
     {"query_reconnect", &Slrn_Query_Reconnect},
#else
     {"query_reconnect", NULL},
#endif
#if SLRN_HAS_SORT_BY_SCORE
     {"display_score", &Slrn_Display_Score},
#else
     {"display_score", NULL},
#endif
     {"use_xgtitle", &Slrn_Use_Xgtitle},
     {"show_article", &Slrn_Startup_With_Article},
     {"author_display", &Slrn_Show_Author},
     {"show_descriptions", &Slrn_Group_Display_Descriptions},
     {"no_backups", &Slrn_No_Backups},
     {"beep", &SLtt_Ignore_Beep},
     {"unsubscribe_new_groups", &Slrn_Unsubscribe_New_Groups},
     {"show_thread_subject", &Slrn_Show_Thread_Subject},
     {"mouse", &Slrn_Use_Mouse},
     {"query_next_group", &Slrn_Query_Next_Group},
     {"query_next_article", &Slrn_Query_Next_Article},
     {"confirm_actions", &Slrn_User_Wants_Confirmation},
     {"cc_followup", &Slrn_Auto_CC_To_Poster},
     {"use_tmpdir", &Slrn_Use_Tmpdir},
     {"sorting_method", &Slrn_Sorting_Mode},
     {"uncollapse_threads", &Slrn_Threads_Visible},
     {"read_active", &Slrn_List_Active_File},
     {"use_metamail", &Slrn_Use_Meta_Mail},
     {"group_dsc_start_column", &Slrn_Group_Description_Column},
     {"lines_per_update", &Slrn_Reads_Per_Update},
#ifndef __os2__
     {"use_blink", &SLtt_Blink_Mode},
#endif
     {"wrap_flags", &Slrn_Wrap_Mode},
     {"write_newsrc_flags", &Slrn_Write_Newsrc_Flags},
     {"query_read_group_cutoff", &Slrn_Query_Group_Cutoff},
     {"prompt_next_group", &Slrn_Prompt_Next_Group},
     {"use_header_numbers", &Slrn_Use_Header_Numbers},
#if SLRN_HAS_SPOILERS
     {"spoiler_char", &Slrn_Spoiler_Char},
#else
     {"spoiler_char", NULL},
#endif
#if SLRN_HAS_MIME
     {"use_mime", &Slrn_Use_Mime},
#else
     {"use_mime", NULL},
#endif
#if SLRN_HAS_GROUPLENS
     {"use_grouplens", &Slrn_Use_Group_Lens},
     {"grouplens_port", &Slrn_GroupLens_Port},
#else
     {"use_grouplens", NULL},
#endif
#if 0
#if SLRN_HAS_INEWS_SUPPORT
     {"use_inews", &Slrn_Use_Inews},
#else
     {"use_inews", NULL},
#endif
#endif
     {NULL, NULL}
};

typedef struct
{
   char *what;
   char **svaluep;
}
Set_String_Type;

static Set_String_Type String_Things_To_Set [] =
{
     {"non_Xbrowser", &Slrn_NonX_Browser},
     {"Xbrowser", &Slrn_X_Browser},
     {"save_posts", &Slrn_Save_Posts_File},
     {"save_directory", &Slrn_Save_Directory},
     {"signature", &Slrn_User_Info.signature},
     {"custom_headers", &Slrn_Custom_Headers},
#if SLRN_HAS_GROUPLENS
     {"grouplens_pseudoname", &Slrn_GroupLens_Pseudoname},
     {"grouplens_host", &Slrn_GroupLens_Host},
#else
     {"grouplens_pseudoname", NULL},
     {"grouplens_host", NULL},
#endif
     {"decode_directory", 
#if SLRN_HAS_DECODE
	  &Slrn_Decode_Directory
#else
	  NULL
#endif
     },
   
     {"inews_program",
#if SLRN_HAS_INEWS_SUPPORT && SLRN_HAS_USER_INEWS
	  &Slrn_Inews_Pgm
#else
	  NULL
#endif
     },
     
#if SLRN_HAS_MIME
     {"mime_charset", &Slrn_Mime_Display_Charset},
#else
     {"mime_charset", NULL},
#endif
#ifndef VMS
     {"sendmail_command", &Slrn_SendMail_Command},
#endif
     {"spool_inn_root", 
#if SLRN_HAS_SPOOL_SUPPORT
     &Slrn_Inn_Root
#else
     NULL
#endif
     },
     {"spool_root",
#if SLRN_HAS_SPOOL_SUPPORT
     &Slrn_Spool_Root
#else
     NULL
#endif
     },
     {"spool_nov_root",
#if SLRN_HAS_SPOOL_SUPPORT
     &Slrn_Nov_Root
#else
     NULL
#endif
     },
     {"spool_nov_file",
#if SLRN_HAS_SPOOL_SUPPORT
     &Slrn_Nov_File
#else
     NULL
#endif
     },
     {"spool_active_file",
#if SLRN_HAS_SPOOL_SUPPORT
     &Slrn_Active_File
#else
     NULL
#endif
     },
     {"spool_activetimes_file",
#if SLRN_HAS_SPOOL_SUPPORT
     &Slrn_ActiveTimes_File
#else
     NULL
#endif
     },
     {"spool_newsgroups_file",
#if SLRN_HAS_SPOOL_SUPPORT
     &Slrn_Newsgroups_File
#else
     NULL
#endif
     },
   
     {NULL, NULL}
};

int slrn_set_string_variable (char *name, char *value)
{
   Set_String_Type *sp = String_Things_To_Set;
	
   while (sp->what != NULL)
     {
	if (!strcmp (sp->what, name))
	  {
	     char *ss;
		  
	     if (sp->svaluep == NULL) return 0;
	     
	     ss = *sp->svaluep;
		  
	     if (ss != NULL) SLFREE (ss);
	     if (NULL == (ss = SLmake_string (value)))
	       exit_malloc_error ();
		  
	     *sp->svaluep = ss;
	     return 0;
	  }
	sp++;
     }
   return -1;
}

int slrn_set_integer_variable (char *name, int value)
{
   Set_Int_Type *ip = Int_Things_To_Set;
   
   while (ip->what != NULL)
     {
	if (!strcmp (ip->what, name))
	  {
	     if (ip->valuep == NULL) return 0;
	     *ip->valuep = value;
	     return 0;
	  }
	ip++;
     }
   return -1;
}

int slrn_get_variable_value (char *name, int *type, char ***sval, int **ival)
{
   Set_String_Type *sp;
   Set_Int_Type *ip;
   
   sp = String_Things_To_Set;
   while (sp->what != NULL)
     {
	if (!strcmp (sp->what, name))
	  {
	     *sval = sp->svaluep;
	     *type = STRING_TYPE;
	     return 0;
	  }
	sp++;
     }
   
   ip = Int_Things_To_Set;
   while (ip->what != NULL)
     {
	if (!strcmp (ip->what, name))
	  {
	     *ival = ip->valuep;
	     *type = INT_TYPE;
	     return 0;
	  }
	ip++;
     }
   
   return -1;
}

static int set_variable_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
   int ret;
   char *what = table->string_args[1];
   int ivalue = table->int_args[2];
   char *svalue = table->string_args[2];
   int type = table->arg_type[2];
   
   if (type == STRING_TYPE)
     ret = slrn_set_string_variable (what, svalue);
   else if (type == INT_TYPE) 
     ret = slrn_set_integer_variable (what, ivalue);
   else ret = -1;
   
   if (ret != 0) exit_unknown_object ();
   return 0;
}


typedef struct Server_List_Type
{
   struct Server_List_Type *next;
   char *file;
   char *host;
}
Server_List_Type;

static Server_List_Type *Server_List;

static int server_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
   char *file = NULL, *host;
   char *the_file = table->string_args[2], *the_host = table->string_args[1];
   int n;
   Server_List_Type *s;
   
   n = strlen (the_file);
   
   s = (Server_List_Type *) safe_malloc (sizeof (Server_List_Type));
   file = safe_malloc (n + 2 + strlen (the_host));
   
   strcpy (file, the_file);
   host = file + (n + 1);
   strcpy (host, the_host);
   
   s->next = Server_List;  Server_List = s;
   s->host = host;
   s->file = file;
   return 0;
}

typedef struct
{
   char *name;
   int value;
   char *fg, *bg;
   SLtt_Char_Type mono;
}
Color_Handle_Type;

/* default colors -- suitable for a color xterm */
   
Color_Handle_Type Color_Handles[] =
{
     {"normal",		0,		"black",	"white", 0},
     {"status",		STATUS_COLOR,	"yellow",	"blue", SLTT_REV_MASK},
     {"menu",		MENU_COLOR,	"yellow",	"blue", SLTT_REV_MASK},
     {"menu_press",	MENU_PRESS_COLOR,"blue",	"yellow", 0},
     {"headers",	HEADER_COLOR,	"brightcyan",	"white", SLTT_BOLD_MASK},
     {"group",		GROUP_COLOR,	"blue",		"white", 0},
     {"subject",	SUBJECT_COLOR,	"black",	"white", 0},
     {"author",		AUTHOR_COLOR,	"magenta",	"white", 0},
     {"error",		ERROR_COLOR,	"red",		"white", SLTT_BLINK_MASK},
     {"cursor",		CURSOR_COLOR,	"brightgreen",	"white", SLTT_REV_MASK},
     {"article",	ARTICLE_COLOR,	"blue",		"white", 0},
     {"tree",		TREE_COLOR,	"red",		"white", 0},
     {"quotes",		QUOTE_COLOR,	"red",		"white", 0},
     {"signature",	SIGNATURE_COLOR,"red",		"white", 0},
     {"thread_number",	THREAD_NUM_COLOR,"blue",	"white", SLTT_BLINK_MASK},
     {"header_number",	HEADER_NUMBER_COLOR,"green",	"white", 0},
     {"high_score",	HIGH_SCORE_COLOR,"red",		"white", SLTT_BOLD_MASK},
     {"description",	GROUP_DESCR_COLOR,"magenta",	"white", 0},
     {"grouplens_display",GROUPLENS_DISPLAY_COLOR,"blue","white", 0},
     {"tilde",		SLRN_TILDE_COLOR,"green",	"white", SLTT_BOLD_MASK},
     {NULL, -1, NULL, NULL, 0}
};


static int color_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
   char *what = table->string_args[1];
   char *fg = table->string_args[2];
   char *bg = table->string_args[3];
   
   Color_Handle_Type *ct = Color_Handles;
   
   while (ct->name != NULL)
     {
	if (!strcmp (ct->name, what))
	  {
	     SLtt_set_color (ct->value, what, fg, bg);
	     return 0;
	  }
	ct++;
     }
   exit_unknown_object ();
   return 0;
}

#if SLANG_VERSION < 9932
# ifdef __os2__
void SLtt_set_mono (int a, char *b, SLtt_Char_Type c)
{
   (void) a;
   (void) b;
   (void) c;
}
# endif
#endif

static int mono_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
   char *what = table->string_args[1];
   char *attr;
   int i;
   
   Color_Handle_Type *ct = Color_Handles;
   
   while (ct->name != NULL)
     {
	if (!strcmp (ct->name, what))
	  {
	     SLtt_Char_Type mono_attr = 0;
	     for (i = 2; i < argc; i++)
	       {
		  attr = table->string_args[i];
		  if (!strcmp (attr, "bold")) mono_attr |= SLTT_BOLD_MASK;
		  else if (!strcmp (attr, "blink")) mono_attr |= SLTT_BLINK_MASK;
		  else if (!strcmp (attr, "underline")) mono_attr |= SLTT_ULINE_MASK;
		  else if (!strcmp (attr, "reverse")) mono_attr |= SLTT_REV_MASK;
		  else if (!strcmp (attr, "none")) mono_attr = 0;
		  else exit_unknown_object ();
	       }
	     SLtt_set_mono (ct->value, NULL, mono_attr);
	     return 0;
	  }
	ct++;
     }
   exit_unknown_object ();
   return 0;
}


/*----------------------------------------------------------------------*\
* static int user_data_fun ();
 *
 * convenient mechanism to set Slrn_User_Info fields without adding
 * extra environment variables
 *
 * recognized fields
 *
 *   replyto		- alternative name for replies
 *   organization	- use double quotes if there are spaces!
 *   signature		- an alternate to ~/.signature (for news posting)
 *   hostname		- full name of the current host
\*----------------------------------------------------------------------*/

typedef struct
{
   char *name;
   char **addr;
   unsigned int size;
}
User_Info_Variable_Type;

User_Info_Variable_Type User_Info_Variables[] =
{
     {"realname", &Slrn_User_Info.realname, 0},
     {"username", &Slrn_User_Info.username, 0},
     {"hostname", (char **)Slrn_User_Info.host, MAX_HOST_NAME_LEN},
     {"replyto", &Slrn_User_Info.replyto, 0},
     {"organization", &Slrn_User_Info.org, 0},
     {"followup", &Slrn_User_Info.followup_string, 0},
     {"signature", &Slrn_User_Info.signature, 0},
     {"scorefile", &Slrn_Score_File, 0},
     {"cc_followup_string", &Slrn_Courtesy_CC_Message, 0},
#if SLRN_HAS_DECODE
     {"decode_directory", &Slrn_Decode_Directory, 0},
#endif
     {"editor_command", &Slrn_Editor, 0},
     {NULL, NULL, 0}
};

static int user_data_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
   char *what = table->string_args[0];
   char *field = table->string_args[1];
   User_Info_Variable_Type *u = User_Info_Variables;
   char **ptr, *contents;
   unsigned int n;
   
   while (u->name != NULL)
     {
	if (!strcmp (u->name, what))
	  {
	     n = strlen (field);
	     
	     if (u->size)
	       {
		  contents = (char *) u->addr;
		  strncpy (contents, field, u->size);
		  contents [u->size - 1] = 0;
	       }
	     else
	       {
		  ptr = u->addr;
		  contents = safe_malloc (n + 1);
		  strcpy (contents, field);
		  
		  if (*ptr != NULL) SLFREE (*ptr);
		  *ptr = contents;
	       }
	     return 0;
	  }
	u++;
     }
   exit_unknown_object ();
   return -1;
}


/*----------------------------------------------------------------------*\
* static int nnrp_fun ();
 *
 * convenient mechanism to set nnrp Slrn_User_Info fields without adding
 * extra environment variables
 *
 * recognized fields
 *
 *   nnrpaccess         - used to log in to a server using authinfo
 *                        it has the following format.
 *                         "host  username  password"
\*----------------------------------------------------------------------*/

static int nnrp_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
#if SLRN_HAS_NNTP_SUPPORT
   char *server = table->string_args[1];
   char *name = table->string_args[2];
   char *pass = table->string_args[3];
   unsigned int len;
   
   if (Slrn_NNTP_Server_Name == NULL) 
     return 0;
   
   /* Skip this one it is not the one that we are looking for */
   if (strcmp(server, Slrn_NNTP_Server_Name))
     return 0;
   
   if (Slrn_User_Info.nnrpname != NULL) SLFREE (Slrn_User_Info.nnrpname);
   if (Slrn_User_Info.nnrppass != NULL) SLFREE (Slrn_User_Info.nnrppass);
   
   len = strlen(name);
   Slrn_User_Info.nnrpname = safe_malloc (len + 1);
   strcpy(Slrn_User_Info.nnrpname, name);
   
   len = strlen(pass);
   Slrn_User_Info.nnrppass = safe_malloc (len + 1);
   strcpy(Slrn_User_Info.nnrppass, pass);
#endif   
   return 0;
}

static void slrn_init_modes (void)
{
   slrn_init_group_mode ();
   slrn_init_article_mode ();
}

void slrn_startup_initialize (void)
{
   Color_Handle_Type *h;
   
   slrn_init_modes ();
   SLang_init_case_tables ();
   
   Slrn_Ignore_Quote_Regexp[0] = compile_quote_regexp ("^ ?[:>]");
   
   h = Color_Handles;
   while (h->name != NULL)
     {
	SLtt_set_color (h->value, NULL, h->fg, h->bg);
	SLtt_set_mono (h->value, NULL, h->mono);
	h++;
     }

#ifndef __os2__
   /* We are not using the blink characters (unless in mono) */
   SLtt_Blink_Mode = 0;
#endif
}

void slrn_read_startup_file (char *name)
{
   FILE *fp;
   char file [SLRN_MAX_PATH_LEN];
   char line [256];
   SLPreprocess_Type pt;

   if (-1 == slrn_init_readline ())
     {
	slrn_exit_error ("Unable to initialize S-Lang readline library.");
     }
   

   if (-1 == SLprep_open_prep (&pt))
     {
	slrn_exit_error ("Error initializing S-Lang preprocessor.");
     }
   
   
   fp = slrn_open_home_file (name, "r", file, 0);
   if (fp == NULL) return;
   
   slrn_message ("Reading startup file %s.", file);

   This_File = file;
   This_Line = line;
   
   Slrn_Cmd_Table.table = Slrn_Startup_File_Cmds;
   
   This_Line_Num = 0;
   while (NULL != fgets (line, sizeof(line) - 1, fp))
     {
	This_Line_Num++;
	if (SLprep_line_ok (line, &pt))
	  (void) SLcmd_execute_string (line, &Slrn_Cmd_Table);
	
	if (SLang_Error) exit_unknown_object ();
     }
   slrn_fclose (fp);
   
   SLprep_close_prep (&pt);
}



char *slrn_map_file_to_host (char *host)
{
   Server_List_Type *s = Server_List;
   
   while (s != NULL)
     {
	if (!strcmp (host, s->host)) return s->file;
	s = s->next;
     }
   return NULL;
}


static int interpret_fun (int argc, SLcmd_Cmd_Table_Type *table)
{
#if SLRN_HAS_SLANG
   char *file = table->string_args [1];
   
   if (Slrn_Use_Slang == 0) return 0;
   return slrn_eval_slang_file (file);
#else
   return 0;
#endif
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.