diff options
Diffstat (limited to 'libslang/slsh/slsh.c')
-rw-r--r-- | libslang/slsh/slsh.c | 481 |
1 files changed, 481 insertions, 0 deletions
diff --git a/libslang/slsh/slsh.c b/libslang/slsh/slsh.c new file mode 100644 index 0000000..ffa6c3d --- /dev/null +++ b/libslang/slsh/slsh.c @@ -0,0 +1,481 @@ +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#ifdef __WIN32__ +# include <windows.h> +#endif + +#include <sys/stat.h> + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif +#include <string.h> +#include <slang.h> + +static char *Slsh_Version = "0.6-0"; +#define SLSHRC_FILE "slsh.rc" + +#ifdef REAL_UNIX_SYSTEM +/* # define DEFAULT_LIBRARY_PATH "/usr/local/share/slsh:/usr/local/lib/slsh:/usr/share/slsh:/usr/lib/slsh"; */ +# define DEFAULT_CONF_PATH "/usr/local/etc:/usr/local/slsh:/etc:/etc/slsh"; +# define USER_SLSHRC ".slshrc" +#else +# define DEFAULT_LIBRARY_PATH NULL +# define USER_SLSHRC "slsh.rc" +#endif + +#ifdef __os2__ +# ifdef __IBMC__ +/* IBM VA3 doesn't declare S_IFMT */ +# define S_IFMT (S_IFDIR | S_IFCHR | S_IFREG) +# endif +#endif + +#ifndef S_ISLNK +# ifdef S_IFLNK +# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +# else +# define S_ISLNK(m) 0 +# endif +#endif + +#ifndef S_ISREG +# ifdef S_IFREG +# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +# else +# define S_ISREG(m) 0 +# 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 + +#ifndef S_ISCHR +# ifdef S_IFCHR +# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +# else +# define S_ISCHR(m) 0 +# endif +#endif + +#ifndef S_ISBLK +# ifdef S_IFBLK +# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +# else +# define S_ISBLK(m) 0 +# endif +#endif + +#ifndef S_ISFIFO +# ifdef S_IFIFO +# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +# else +# define S_ISFIFO(m) 0 +# endif +#endif + +#ifndef S_ISSOCK +# ifdef S_IFSOCK +# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) +# else +# define S_ISSOCK(m) 0 +# endif +#endif + + +#ifndef S_IRUSR +# define S_IRUSR 0400 +#endif +#ifndef S_IWUSR +# define S_IWUSR 0200 +#endif +#ifndef S_IXUSR +# define S_IXUSR 0100 +#endif +#ifndef S_IRGRP +# define S_IRGRP 0040 +#endif +#ifndef S_IWGRP +# define S_IWGRP 0020 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0010 +#endif +#ifndef S_IROTH +# define S_IROTH 0004 +#endif +#ifndef S_IWOTH +# define S_IWOTH 0002 +#endif +#ifndef S_IXOTH +# define S_IXOTH 0001 +#endif +#ifndef S_ISUID +# define S_ISUID 04000 +#endif +#ifndef S_ISGID +# define S_ISGID 02000 +#endif +#ifndef S_ISVTX +# define S_ISVTX 01000 +#endif + +typedef struct _AtExit_Type +{ + SLang_Name_Type *nt; + struct _AtExit_Type *next; +} +AtExit_Type; + +static AtExit_Type *AtExit_Hooks; + +static void at_exit (SLang_Ref_Type *ref) +{ + SLang_Name_Type *nt; + AtExit_Type *a; + + if (NULL == (nt = SLang_get_fun_from_ref (ref))) + return; + + a = (AtExit_Type *) SLmalloc (sizeof (AtExit_Type)); + if (a == NULL) + return; + + a->nt = nt; + a->next = AtExit_Hooks; + AtExit_Hooks = a; +} + +static void c_exit (int *code) +{ + while (AtExit_Hooks != NULL) + { + AtExit_Type *next = AtExit_Hooks->next; + if (SLang_Error == 0) + (void) SLexecute_function (AtExit_Hooks->nt); + + SLfree ((char *) AtExit_Hooks); + AtExit_Hooks = next; + } + exit (*code); +} + + +static void stat_mode_to_string (void) +{ + int mode, opts; + char mode_string[12]; + + opts = 0; + if (SLang_Num_Function_Args == 2) + { + if (-1 == SLang_pop_integer (&opts)) + return; + } + + if (-1 == SLang_pop_integer (&mode)) + return; + + + if (S_ISREG(mode)) mode_string[0] = '-'; + else if (S_ISDIR(mode)) mode_string[0] = 'd'; + else if (S_ISLNK(mode)) mode_string[0] = 'l'; + else if (S_ISCHR(mode)) mode_string[0] = 'c'; + else if (S_ISFIFO(mode)) mode_string[0] = 'f'; + else if (S_ISSOCK(mode)) mode_string[0] = 's'; + else if (S_ISBLK(mode)) mode_string[0] = 'b'; + + if (mode & S_IRUSR) mode_string[1] = 'r'; else mode_string[1] = '-'; + if (mode & S_IWUSR) mode_string[2] = 'w'; else mode_string[2] = '-'; + if (mode & S_IXUSR) mode_string[3] = 'x'; else mode_string[3] = '-'; + if (mode & S_ISUID) mode_string[3] = 's'; + +#ifdef __WIN32__ + mode_string[4] = '-'; + mode_string[5] = '-'; + mode_string[6] = '-'; + + if (opts & FILE_ATTRIBUTE_ARCHIVE) mode_string[7] = 'A'; else mode_string[7] = '-'; + if (opts & FILE_ATTRIBUTE_SYSTEM) mode_string[8] = 'S'; else mode_string[8] = '-'; + if (opts & FILE_ATTRIBUTE_HIDDEN) mode_string[9] = 'H'; else mode_string[9] = '-'; +#else + if (mode & S_IRGRP) mode_string[4] = 'r'; else mode_string[4] = '-'; + if (mode & S_IWGRP) mode_string[5] = 'w'; else mode_string[5] = '-'; + if (mode & S_IXGRP) mode_string[6] = 'x'; else mode_string[6] = '-'; + if (mode & S_ISGID) mode_string[6] = 'g'; + + if (mode & S_IROTH) mode_string[7] = 'r'; else mode_string[7] = '-'; + if (mode & S_IWOTH) mode_string[8] = 'w'; else mode_string[8] = '-'; + if (mode & S_IXOTH) mode_string[9] = 'x'; else mode_string[9] = '-'; + if (mode & S_ISVTX) mode_string[9] = 't'; +#endif + + mode_string[10] = 0; + (void) SLang_push_string (mode_string); +} + + +static int Verbose_Loading; + +static int try_to_load_file (char *path, char *file, char *ns) +{ + int status; + + if (path == NULL) + path = "."; + + if (file != NULL) + { + file = SLpath_find_file_in_path (path, file); + if (file == NULL) + return 0; + } + /* otherwise use stdin */ + + status = SLns_load_file (file, ns); + SLfree (file); + if (status == 0) + return 1; + return -1; +} + + +static int load_startup_file (void) +{ + char *dir; + int status; + + dir = getenv ("SLSH_CONF_DIR"); + if (dir == NULL) + dir = getenv ("SLSH_LIB_DIR"); + + if (NULL == dir) + { +#ifdef SLSH_CONF_DIR + dir = SLSH_CONF_DIR; + if (dir != NULL) + { + status = try_to_load_file (dir, SLSHRC_FILE, NULL); + if (status == -1) + return -1; + if (status == 1) + return 0; + } +#endif + dir = DEFAULT_CONF_PATH; + } + + if (-1 == (status = try_to_load_file (dir, SLSHRC_FILE, NULL))) + return -1; + + if ((status == 0) && Verbose_Loading) + { + SLang_vmessage ("*** Installation Problem? Unable to find the %s config file.", + SLSHRC_FILE); + } + + return 0; +} + + +#if 0 +static int is_script (char *file) +{ + FILE *fp; + char buf[3]; + int is; + + if (NULL == (fp = fopen (file, "r"))) + return 0; + + is = ((NULL != fgets (buf, sizeof(buf), fp)) + && (buf[0] == '#') && (buf[1] == '!')); + + fclose (fp); + return is; +} +#endif + +static int setup_paths (void) +{ + char *libpath; + + if (NULL == (libpath = getenv ("SLSH_PATH"))) + { +#ifdef SLSH_PATH + libpath = SLSH_PATH; +#endif + } + + return SLpath_set_load_path (libpath); +} + +/* Create the Table that S-Lang requires */ +static SLang_Intrin_Fun_Type Intrinsics [] = +{ + MAKE_INTRINSIC_I("exit", c_exit, VOID_TYPE), + MAKE_INTRINSIC_1("atexit", at_exit, VOID_TYPE, SLANG_REF_TYPE), + MAKE_INTRINSIC_0("stat_mode_to_string", stat_mode_to_string, VOID_TYPE), + SLANG_END_INTRIN_FUN_TABLE +}; + +static void usage (void) +{ + char *libpath; + fprintf (stderr, "\ +Usage: slsh [OPTIONS] [-|file [args...]]\n\ + --help Print this help\n\ + --version Show slsh version information\n\ + -g Compile with debugging code, tracebacks, etc\n\ + -n Don't load personal init file\n\ + -i init-file Use this file instead of ~/%s\n\ + -v Show verbose loading messages\n\ +", + USER_SLSHRC + ); + libpath = SLpath_get_load_path (); + fprintf (stderr, "Default search path: %s\n", (libpath == NULL) ? "" : libpath); + SLang_free_slstring (libpath); + + exit (1); +} + +static void version (void) +{ + fprintf (stdout, "slsh version %s\n", Slsh_Version); + fprintf (stdout, "S-Lang Library Version: %s\n", SLang_Version_String); + if (SLANG_VERSION != SLang_Version) + { + fprintf (stdout, "\t** Note: This program was compiled against version %s.\n", + SLANG_VERSION_STRING); + } + + exit (0); +} + +int main (int argc, char **argv) +{ + char *file = NULL; + char *init_file = USER_SLSHRC; + char *init_file_dir; + + if (SLang_Version < SLANG_VERSION) + { + fprintf (stderr, "***Warning: Executable compiled against S-Lang %s but linked to %s\n", + SLANG_VERSION_STRING, SLang_Version_String); + fflush (stderr); + } + + if ((-1 == SLang_init_all ()) + || (-1 == SLang_init_array_extra ()) + || (-1 == SLang_init_import ()) /* dynamic linking */ + || (-1 == SLadd_intrin_fun_table (Intrinsics, NULL))) + { + fprintf(stderr, "Unable to initialize S-Lang.\n"); + return 1; + } + + /* FIXME for other systems */ + init_file_dir = getenv ("HOME"); + + if (-1 == setup_paths ()) + return -1; + + while (argc > 1) + { + if (0 == strcmp (argv[1], "--version")) + version (); + + if (0 == strcmp (argv[1], "--help")) + usage (); + + if (0 == strcmp (argv[1], "-g")) + { + SLang_generate_debug_info (1); + argc--; + argv++; + continue; + } + + if (0 == strcmp (argv[1], "-n")) + { + init_file = NULL; + argc--; + argv++; + continue; + } + + if (0 == strcmp (argv[1], "-v")) + { + (void) SLang_load_file_verbose (1); + Verbose_Loading = 1; + argc--; + argv++; + continue; + } + + if ((0 == strcmp (argv[1], "-i")) + && (argc > 2)) + { + init_file = argv[2]; + init_file_dir = NULL; + argc -= 2; + argv += 2; + continue; + } + break; + } + + if (argc == 1) + { + if (0 == isatty (fileno(stdin))) + file = NULL; + else + usage (); + } + else + { + file = argv[1]; + if (0 == strcmp (file, "-")) + file = NULL; +#if 0 + if (is_script (file)) + { + argv++; + argc--; + } +#else + argc--; + argv++; +#endif + } + /* fprintf (stdout, "slsh: argv[0]=%s\n", argv[0]); */ + if (-1 == SLang_set_argc_argv (argc, argv)) + return 1; + + /* Turn on traceback generation */ + SLang_Traceback = 1; + + if (-1 == load_startup_file ()) + return SLang_Error; + + if ((init_file != NULL) + && (-1 == try_to_load_file (init_file_dir, init_file, NULL))) + return SLang_Error; + + /* Now load an initialization file and exit */ + if (0 == try_to_load_file (NULL, file, NULL)) + { + fprintf (stderr, "%s: file not found\n", file); + exit (1); + } + + (void) SLang_run_hooks ("slsh_main", 0); + return SLang_Error; +} |