mirror of
https://github.com/webmin/webmin.git
synced 2026-02-03 06:03:28 +00:00
Move legacy modules to modules/legacy branch
https://github.com/webmin/webmin/tree/modules/legacy
This commit is contained in:
@@ -1,127 +0,0 @@
|
||||
package Webmin::API;
|
||||
|
||||
require 5.005_62;
|
||||
|
||||
require Exporter;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
|
||||
# Items to export into callers namespace by default. Note: do not export
|
||||
# names by default without a very good reason. Use EXPORT_OK instead.
|
||||
# Do not simply export all your public functions/methods/constants.
|
||||
|
||||
our @EXPORT = (
|
||||
'$config_directory',
|
||||
'$var_directory',
|
||||
'$remote_error_handler',
|
||||
'%month_to_number_map',
|
||||
'%number_to_month_map',
|
||||
'$config_file',
|
||||
'%gconfig',
|
||||
'$null_file',
|
||||
'$path_separator',
|
||||
'$root_directory',
|
||||
'$module_name',
|
||||
'@root_directories',
|
||||
'$base_remote_user',
|
||||
'$remote_user',
|
||||
'$module_config_directory',
|
||||
'$module_config_file',
|
||||
'%config',
|
||||
'$current_theme',
|
||||
'$theme_root_directory',
|
||||
'%tconfig',
|
||||
'$tb',
|
||||
'$cb',
|
||||
'$scriptname',
|
||||
'$webmin_logfile',
|
||||
'$current_lang',
|
||||
'$current_lang_info',
|
||||
'@lang_order_list',
|
||||
'%text',
|
||||
'%module_info',
|
||||
'$module_root_directory',
|
||||
'$default_lang',
|
||||
);
|
||||
|
||||
our $VERSION = '1.0';
|
||||
|
||||
# Find old symbols by Webmin import
|
||||
my %oldsyms = %Webmin::API::;
|
||||
|
||||
# Preloaded methods go here.
|
||||
$main::no_acl_check++;
|
||||
$ENV{'WEBMIN_CONFIG'} ||= "/etc/webmin";
|
||||
$ENV{'WEBMIN_VAR'} ||= "/var/webmin";
|
||||
open(MINISERV, $ENV{'WEBMIN_CONFIG'}."/miniserv.conf") ||
|
||||
die "Could not open Webmin config file ".
|
||||
$ENV{'WEBMIN_CONFIG'}."/miniserv.conf : $!";
|
||||
my $webmin_root;
|
||||
while(<MINISERV>) {
|
||||
s/\r|\n//g;
|
||||
if (/^root=(.*)/) {
|
||||
$webmin_root = $1;
|
||||
}
|
||||
}
|
||||
close(MINISERV);
|
||||
$webmin_root || die "Could not find Webmin root directory";
|
||||
chdir($webmin_root);
|
||||
if ($0 =~ /\/([^\/]+)$/) {
|
||||
$0 = $webmin_root."/".$1;
|
||||
}
|
||||
else {
|
||||
$0 = $webmin_root."/api.pl"; # Fake name
|
||||
}
|
||||
require './web-lib.pl';
|
||||
&init_config();
|
||||
|
||||
# Export core symbols
|
||||
foreach my $lib ("$webmin_root/web-lib.pl",
|
||||
"$webmin_root/web-lib-funcs.pl") {
|
||||
open(WEBLIB, $lib);
|
||||
while(<WEBLIB>) {
|
||||
if (/^sub\s+([a-z0-9\_]+)/i) {
|
||||
push(@EXPORT, $1);
|
||||
}
|
||||
}
|
||||
close(WEBLIB);
|
||||
}
|
||||
our @EXPORT_OK = ( @EXPORT );
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Webmin::API - Perl module to make calling of Webmin functions from regular
|
||||
command-line Perl scripts easier.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Webmin::API;
|
||||
@pids = &find_byname("httpd");
|
||||
foreign_require("cron", "cron-lib.pl");
|
||||
@jobs = &cron::list_cron_jobs();
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module just provides a convenient way to call Webmin API functions
|
||||
from a script that is not run as a Webmin CGI, without having to include a
|
||||
bunch of boilerplate initialization code at the top. It's main job is to export
|
||||
all API functions into the namespace of the caller, and to setup the Webmin
|
||||
environment.
|
||||
|
||||
=head2 EXPORT
|
||||
|
||||
All core Webmin API functions, like find_byname, foreign_config and so on.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Jamie Cameron, jcameron@webmin.com
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
perl(1).
|
||||
|
||||
=cut
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
Revision history for Perl extension Webmin::API.
|
||||
|
||||
1.0 Mon Dec 10 11:09:17 2007
|
||||
- original version; created by h2xs 1.20 with options
|
||||
-AXc -n Webmin::API
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
API.pm
|
||||
Changes
|
||||
MANIFEST
|
||||
Makefile.PL
|
||||
test.pl
|
||||
@@ -1,768 +0,0 @@
|
||||
# This Makefile is for the Webmin::API extension to perl.
|
||||
#
|
||||
# It was generated automatically by MakeMaker version
|
||||
# 6.30_01 (Revision: Revision: 4535 ) from the contents of
|
||||
# Makefile.PL. Don't edit this file, edit Makefile.PL instead.
|
||||
#
|
||||
# ANY CHANGES MADE HERE WILL BE LOST!
|
||||
#
|
||||
# MakeMaker ARGV: ()
|
||||
#
|
||||
# MakeMaker Parameters:
|
||||
|
||||
# NAME => q[Webmin::API]
|
||||
# PREREQ_PM => { }
|
||||
# VERSION_FROM => q[API.pm]
|
||||
|
||||
# --- MakeMaker post_initialize section:
|
||||
|
||||
|
||||
# --- MakeMaker const_config section:
|
||||
|
||||
# These definitions are from config.sh (via /usr/lib/perl/5.8/Config.pm)
|
||||
|
||||
# They may have been overridden via Makefile.PL or on the command line
|
||||
AR = ar
|
||||
CC = cc
|
||||
CCCDLFLAGS = -fPIC
|
||||
CCDLFLAGS = -Wl,-E
|
||||
DLEXT = so
|
||||
DLSRC = dl_dlopen.xs
|
||||
LD = cc
|
||||
LDDLFLAGS = -shared -L/usr/local/lib
|
||||
LDFLAGS = -L/usr/local/lib
|
||||
LIBC = /lib/libc-2.7.so
|
||||
LIB_EXT = .a
|
||||
OBJ_EXT = .o
|
||||
OSNAME = linux
|
||||
OSVERS = 2.6.24-19-server
|
||||
RANLIB = :
|
||||
SITELIBEXP = /usr/local/share/perl/5.8.8
|
||||
SITEARCHEXP = /usr/local/lib/perl/5.8.8
|
||||
SO = so
|
||||
EXE_EXT =
|
||||
FULL_AR = /usr/bin/ar
|
||||
VENDORARCHEXP = /usr/lib/perl5
|
||||
VENDORLIBEXP = /usr/share/perl5
|
||||
|
||||
|
||||
# --- MakeMaker constants section:
|
||||
AR_STATIC_ARGS = cr
|
||||
DIRFILESEP = /
|
||||
DFSEP = $(DIRFILESEP)
|
||||
NAME = Webmin::API
|
||||
NAME_SYM = Webmin_API
|
||||
VERSION = 1.0
|
||||
VERSION_MACRO = VERSION
|
||||
VERSION_SYM = 1_0
|
||||
DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\"
|
||||
XS_VERSION = 1.0
|
||||
XS_VERSION_MACRO = XS_VERSION
|
||||
XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\"
|
||||
INST_ARCHLIB = blib/arch
|
||||
INST_SCRIPT = blib/script
|
||||
INST_BIN = blib/bin
|
||||
INST_LIB = blib/lib
|
||||
INST_MAN1DIR = blib/man1
|
||||
INST_MAN3DIR = blib/man3
|
||||
MAN1EXT = 1p
|
||||
MAN3EXT = 3pm
|
||||
INSTALLDIRS = site
|
||||
DESTDIR =
|
||||
PREFIX = /usr
|
||||
PERLPREFIX = $(PREFIX)
|
||||
SITEPREFIX = $(PREFIX)/local
|
||||
VENDORPREFIX = $(PREFIX)
|
||||
INSTALLPRIVLIB = $(PERLPREFIX)/share/perl/5.8
|
||||
DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB)
|
||||
INSTALLSITELIB = $(SITEPREFIX)/share/perl/5.8.8
|
||||
DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB)
|
||||
INSTALLVENDORLIB = $(VENDORPREFIX)/share/perl5
|
||||
DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB)
|
||||
INSTALLARCHLIB = $(PERLPREFIX)/lib/perl/5.8
|
||||
DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB)
|
||||
INSTALLSITEARCH = $(SITEPREFIX)/lib/perl/5.8.8
|
||||
DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH)
|
||||
INSTALLVENDORARCH = $(VENDORPREFIX)/lib/perl5
|
||||
DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH)
|
||||
INSTALLBIN = $(PERLPREFIX)/bin
|
||||
DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN)
|
||||
INSTALLSITEBIN = $(SITEPREFIX)/bin
|
||||
DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN)
|
||||
INSTALLVENDORBIN = $(VENDORPREFIX)/bin
|
||||
DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN)
|
||||
INSTALLSCRIPT = $(PERLPREFIX)/bin
|
||||
DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT)
|
||||
INSTALLSITESCRIPT = $(SITEPREFIX)/bin
|
||||
DESTINSTALLSITESCRIPT = $(DESTDIR)$(INSTALLSITESCRIPT)
|
||||
INSTALLVENDORSCRIPT = $(VENDORPREFIX)/bin
|
||||
DESTINSTALLVENDORSCRIPT = $(DESTDIR)$(INSTALLVENDORSCRIPT)
|
||||
INSTALLMAN1DIR = $(PERLPREFIX)/share/man/man1
|
||||
DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR)
|
||||
INSTALLSITEMAN1DIR = $(SITEPREFIX)/man/man1
|
||||
DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR)
|
||||
INSTALLVENDORMAN1DIR = $(VENDORPREFIX)/share/man/man1
|
||||
DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR)
|
||||
INSTALLMAN3DIR = $(PERLPREFIX)/share/man/man3
|
||||
DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR)
|
||||
INSTALLSITEMAN3DIR = $(SITEPREFIX)/man/man3
|
||||
DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR)
|
||||
INSTALLVENDORMAN3DIR = $(VENDORPREFIX)/share/man/man3
|
||||
DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR)
|
||||
PERL_LIB = /usr/share/perl/5.8
|
||||
PERL_ARCHLIB = /usr/lib/perl/5.8
|
||||
LIBPERL_A = libperl.a
|
||||
FIRST_MAKEFILE = Makefile
|
||||
MAKEFILE_OLD = Makefile.old
|
||||
MAKE_APERL_FILE = Makefile.aperl
|
||||
PERLMAINCC = $(CC)
|
||||
PERL_INC = /usr/lib/perl/5.8/CORE
|
||||
PERL = /usr/bin/perl
|
||||
FULLPERL = /usr/bin/perl
|
||||
ABSPERL = $(PERL)
|
||||
PERLRUN = $(PERL)
|
||||
FULLPERLRUN = $(FULLPERL)
|
||||
ABSPERLRUN = $(ABSPERL)
|
||||
PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
|
||||
FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
|
||||
ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
|
||||
PERL_CORE = 0
|
||||
PERM_RW = 644
|
||||
PERM_RWX = 755
|
||||
|
||||
MAKEMAKER = /usr/share/perl/5.8/ExtUtils/MakeMaker.pm
|
||||
MM_VERSION = 6.30_01
|
||||
MM_REVISION = Revision: 4535
|
||||
|
||||
# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle).
|
||||
# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle)
|
||||
# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
|
||||
# DLBASE = Basename part of dynamic library. May be just equal BASEEXT.
|
||||
FULLEXT = Webmin/API
|
||||
BASEEXT = API
|
||||
PARENT_NAME = Webmin
|
||||
DLBASE = $(BASEEXT)
|
||||
VERSION_FROM = API.pm
|
||||
OBJECT =
|
||||
LDFROM = $(OBJECT)
|
||||
LINKTYPE = dynamic
|
||||
BOOTDEP =
|
||||
|
||||
# Handy lists of source code files:
|
||||
XS_FILES =
|
||||
C_FILES =
|
||||
O_FILES =
|
||||
H_FILES =
|
||||
MAN1PODS =
|
||||
MAN3PODS = API.pm
|
||||
|
||||
# Where is the Config information that we are using/depend on
|
||||
CONFIGDEP = $(PERL_ARCHLIB)$(DFSEP)Config.pm $(PERL_INC)$(DFSEP)config.h
|
||||
|
||||
# Where to build things
|
||||
INST_LIBDIR = $(INST_LIB)/Webmin
|
||||
INST_ARCHLIBDIR = $(INST_ARCHLIB)/Webmin
|
||||
|
||||
INST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT)
|
||||
INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT)
|
||||
|
||||
INST_STATIC =
|
||||
INST_DYNAMIC =
|
||||
INST_BOOT =
|
||||
|
||||
# Extra linker info
|
||||
EXPORT_LIST =
|
||||
PERL_ARCHIVE =
|
||||
PERL_ARCHIVE_AFTER =
|
||||
|
||||
|
||||
TO_INST_PM = API.pm
|
||||
|
||||
PM_TO_BLIB = API.pm \
|
||||
$(INST_LIB)/Webmin/API.pm
|
||||
|
||||
|
||||
# --- MakeMaker platform_constants section:
|
||||
MM_Unix_VERSION = 1.50_01
|
||||
PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc
|
||||
|
||||
|
||||
# --- MakeMaker tool_autosplit section:
|
||||
# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
|
||||
AUTOSPLITFILE = $(ABSPERLRUN) -e 'use AutoSplit; autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1)'
|
||||
|
||||
|
||||
|
||||
# --- MakeMaker tool_xsubpp section:
|
||||
|
||||
|
||||
# --- MakeMaker tools_other section:
|
||||
SHELL = /bin/sh
|
||||
CHMOD = chmod
|
||||
CP = cp
|
||||
MV = mv
|
||||
NOOP = $(SHELL) -c true
|
||||
NOECHO = @
|
||||
RM_F = rm -f
|
||||
RM_RF = rm -rf
|
||||
TEST_F = test -f
|
||||
TOUCH = touch
|
||||
UMASK_NULL = umask 0
|
||||
DEV_NULL = > /dev/null 2>&1
|
||||
MKPATH = $(ABSPERLRUN) "-MExtUtils::Command" -e mkpath
|
||||
EQUALIZE_TIMESTAMP = $(ABSPERLRUN) "-MExtUtils::Command" -e eqtime
|
||||
ECHO = echo
|
||||
ECHO_N = echo -n
|
||||
UNINST = 0
|
||||
VERBINST = 0
|
||||
MOD_INSTALL = $(ABSPERLRUN) -MExtUtils::Install -e 'install({@ARGV}, '\''$(VERBINST)'\'', 0, '\''$(UNINST)'\'');'
|
||||
DOC_INSTALL = $(ABSPERLRUN) "-MExtUtils::Command::MM" -e perllocal_install
|
||||
UNINSTALL = $(ABSPERLRUN) "-MExtUtils::Command::MM" -e uninstall
|
||||
WARN_IF_OLD_PACKLIST = $(ABSPERLRUN) "-MExtUtils::Command::MM" -e warn_if_old_packlist
|
||||
MACROSTART =
|
||||
MACROEND =
|
||||
USEMAKEFILE = -f
|
||||
FIXIN = $(PERLRUN) "-MExtUtils::MY" -e "MY->fixin(shift)"
|
||||
|
||||
|
||||
# --- MakeMaker makemakerdflt section:
|
||||
makemakerdflt: all
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
|
||||
# --- MakeMaker dist section:
|
||||
TAR = tar
|
||||
TARFLAGS = cvf
|
||||
ZIP = zip
|
||||
ZIPFLAGS = -r
|
||||
COMPRESS = gzip --best
|
||||
SUFFIX = .gz
|
||||
SHAR = shar
|
||||
PREOP = $(NOECHO) $(NOOP)
|
||||
POSTOP = $(NOECHO) $(NOOP)
|
||||
TO_UNIX = $(NOECHO) $(NOOP)
|
||||
CI = ci -u
|
||||
RCS_LABEL = rcs -Nv$(VERSION_SYM): -q
|
||||
DIST_CP = best
|
||||
DIST_DEFAULT = tardist
|
||||
DISTNAME = Webmin-API
|
||||
DISTVNAME = Webmin-API-1.0
|
||||
|
||||
|
||||
# --- MakeMaker macro section:
|
||||
|
||||
|
||||
# --- MakeMaker depend section:
|
||||
|
||||
|
||||
# --- MakeMaker cflags section:
|
||||
|
||||
|
||||
# --- MakeMaker const_loadlibs section:
|
||||
|
||||
|
||||
# --- MakeMaker const_cccmd section:
|
||||
|
||||
|
||||
# --- MakeMaker post_constants section:
|
||||
|
||||
|
||||
# --- MakeMaker pasthru section:
|
||||
|
||||
PASTHRU = LIBPERL_A="$(LIBPERL_A)"\
|
||||
LINKTYPE="$(LINKTYPE)"\
|
||||
PREFIX="$(PREFIX)"
|
||||
|
||||
|
||||
# --- MakeMaker special_targets section:
|
||||
.SUFFIXES : .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT)
|
||||
|
||||
.PHONY: all config static dynamic test linkext manifest blibdirs clean realclean disttest distdir
|
||||
|
||||
|
||||
|
||||
# --- MakeMaker c_o section:
|
||||
|
||||
|
||||
# --- MakeMaker xs_c section:
|
||||
|
||||
|
||||
# --- MakeMaker xs_o section:
|
||||
|
||||
|
||||
# --- MakeMaker top_targets section:
|
||||
all :: pure_all manifypods
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
|
||||
pure_all :: config pm_to_blib subdirs linkext
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
subdirs :: $(MYEXTLIB)
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
config :: $(FIRST_MAKEFILE) blibdirs
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
help :
|
||||
perldoc ExtUtils::MakeMaker
|
||||
|
||||
|
||||
# --- MakeMaker blibdirs section:
|
||||
blibdirs : $(INST_LIBDIR)$(DFSEP).exists $(INST_ARCHLIB)$(DFSEP).exists $(INST_AUTODIR)$(DFSEP).exists $(INST_ARCHAUTODIR)$(DFSEP).exists $(INST_BIN)$(DFSEP).exists $(INST_SCRIPT)$(DFSEP).exists $(INST_MAN1DIR)$(DFSEP).exists $(INST_MAN3DIR)$(DFSEP).exists
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
# Backwards compat with 6.18 through 6.25
|
||||
blibdirs.ts : blibdirs
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
$(INST_LIBDIR)$(DFSEP).exists :: Makefile.PL
|
||||
$(NOECHO) $(MKPATH) $(INST_LIBDIR)
|
||||
$(NOECHO) $(CHMOD) 755 $(INST_LIBDIR)
|
||||
$(NOECHO) $(TOUCH) $(INST_LIBDIR)$(DFSEP).exists
|
||||
|
||||
$(INST_ARCHLIB)$(DFSEP).exists :: Makefile.PL
|
||||
$(NOECHO) $(MKPATH) $(INST_ARCHLIB)
|
||||
$(NOECHO) $(CHMOD) 755 $(INST_ARCHLIB)
|
||||
$(NOECHO) $(TOUCH) $(INST_ARCHLIB)$(DFSEP).exists
|
||||
|
||||
$(INST_AUTODIR)$(DFSEP).exists :: Makefile.PL
|
||||
$(NOECHO) $(MKPATH) $(INST_AUTODIR)
|
||||
$(NOECHO) $(CHMOD) 755 $(INST_AUTODIR)
|
||||
$(NOECHO) $(TOUCH) $(INST_AUTODIR)$(DFSEP).exists
|
||||
|
||||
$(INST_ARCHAUTODIR)$(DFSEP).exists :: Makefile.PL
|
||||
$(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
|
||||
$(NOECHO) $(CHMOD) 755 $(INST_ARCHAUTODIR)
|
||||
$(NOECHO) $(TOUCH) $(INST_ARCHAUTODIR)$(DFSEP).exists
|
||||
|
||||
$(INST_BIN)$(DFSEP).exists :: Makefile.PL
|
||||
$(NOECHO) $(MKPATH) $(INST_BIN)
|
||||
$(NOECHO) $(CHMOD) 755 $(INST_BIN)
|
||||
$(NOECHO) $(TOUCH) $(INST_BIN)$(DFSEP).exists
|
||||
|
||||
$(INST_SCRIPT)$(DFSEP).exists :: Makefile.PL
|
||||
$(NOECHO) $(MKPATH) $(INST_SCRIPT)
|
||||
$(NOECHO) $(CHMOD) 755 $(INST_SCRIPT)
|
||||
$(NOECHO) $(TOUCH) $(INST_SCRIPT)$(DFSEP).exists
|
||||
|
||||
$(INST_MAN1DIR)$(DFSEP).exists :: Makefile.PL
|
||||
$(NOECHO) $(MKPATH) $(INST_MAN1DIR)
|
||||
$(NOECHO) $(CHMOD) 755 $(INST_MAN1DIR)
|
||||
$(NOECHO) $(TOUCH) $(INST_MAN1DIR)$(DFSEP).exists
|
||||
|
||||
$(INST_MAN3DIR)$(DFSEP).exists :: Makefile.PL
|
||||
$(NOECHO) $(MKPATH) $(INST_MAN3DIR)
|
||||
$(NOECHO) $(CHMOD) 755 $(INST_MAN3DIR)
|
||||
$(NOECHO) $(TOUCH) $(INST_MAN3DIR)$(DFSEP).exists
|
||||
|
||||
|
||||
|
||||
# --- MakeMaker linkext section:
|
||||
|
||||
linkext :: $(LINKTYPE)
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
|
||||
# --- MakeMaker dlsyms section:
|
||||
|
||||
|
||||
# --- MakeMaker dynamic section:
|
||||
|
||||
dynamic :: $(FIRST_MAKEFILE) $(INST_DYNAMIC) $(INST_BOOT)
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
|
||||
# --- MakeMaker dynamic_bs section:
|
||||
|
||||
BOOTSTRAP =
|
||||
|
||||
|
||||
# --- MakeMaker dynamic_lib section:
|
||||
|
||||
|
||||
# --- MakeMaker static section:
|
||||
|
||||
## $(INST_PM) has been moved to the all: target.
|
||||
## It remains here for awhile to allow for old usage: "make static"
|
||||
static :: $(FIRST_MAKEFILE) $(INST_STATIC)
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
|
||||
# --- MakeMaker static_lib section:
|
||||
|
||||
|
||||
# --- MakeMaker manifypods section:
|
||||
|
||||
POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--"
|
||||
POD2MAN = $(POD2MAN_EXE)
|
||||
|
||||
|
||||
manifypods : pure_all \
|
||||
API.pm \
|
||||
API.pm
|
||||
$(NOECHO) $(POD2MAN) --section=$(MAN3EXT) --perm_rw=$(PERM_RW) \
|
||||
API.pm $(INST_MAN3DIR)/Webmin::API.$(MAN3EXT)
|
||||
|
||||
|
||||
|
||||
|
||||
# --- MakeMaker processPL section:
|
||||
|
||||
|
||||
# --- MakeMaker installbin section:
|
||||
|
||||
|
||||
# --- MakeMaker subdirs section:
|
||||
|
||||
# none
|
||||
|
||||
# --- MakeMaker clean_subdirs section:
|
||||
clean_subdirs :
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
|
||||
# --- MakeMaker clean section:
|
||||
|
||||
# Delete temporary files but do not touch installed files. We don't delete
|
||||
# the Makefile here so a later make realclean still has a makefile to use.
|
||||
|
||||
clean :: clean_subdirs
|
||||
- $(RM_F) \
|
||||
*$(LIB_EXT) core \
|
||||
core.[0-9] $(INST_ARCHAUTODIR)/extralibs.all \
|
||||
core.[0-9][0-9] $(BASEEXT).bso \
|
||||
pm_to_blib.ts core.[0-9][0-9][0-9][0-9] \
|
||||
$(BASEEXT).x $(BOOTSTRAP) \
|
||||
perl$(EXE_EXT) tmon.out \
|
||||
*$(OBJ_EXT) pm_to_blib \
|
||||
$(INST_ARCHAUTODIR)/extralibs.ld blibdirs.ts \
|
||||
core.[0-9][0-9][0-9][0-9][0-9] *perl.core \
|
||||
core.*perl.*.? $(MAKE_APERL_FILE) \
|
||||
perl $(BASEEXT).def \
|
||||
core.[0-9][0-9][0-9] mon.out \
|
||||
lib$(BASEEXT).def perlmain.c \
|
||||
perl.exe so_locations \
|
||||
$(BASEEXT).exp
|
||||
- $(RM_RF) \
|
||||
blib
|
||||
- $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL)
|
||||
|
||||
|
||||
# --- MakeMaker realclean_subdirs section:
|
||||
realclean_subdirs :
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
|
||||
# --- MakeMaker realclean section:
|
||||
# Delete temporary files (via clean) and also delete dist files
|
||||
realclean purge :: clean realclean_subdirs
|
||||
- $(RM_F) \
|
||||
$(MAKEFILE_OLD) $(FIRST_MAKEFILE)
|
||||
- $(RM_RF) \
|
||||
$(DISTVNAME)
|
||||
|
||||
|
||||
# --- MakeMaker metafile section:
|
||||
metafile : create_distdir
|
||||
$(NOECHO) $(ECHO) Generating META.yml
|
||||
$(NOECHO) $(ECHO) '# http://module-build.sourceforge.net/META-spec.html' > META_new.yml
|
||||
$(NOECHO) $(ECHO) '#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#' >> META_new.yml
|
||||
$(NOECHO) $(ECHO) 'name: Webmin-API' >> META_new.yml
|
||||
$(NOECHO) $(ECHO) 'version: 1.0' >> META_new.yml
|
||||
$(NOECHO) $(ECHO) 'version_from: API.pm' >> META_new.yml
|
||||
$(NOECHO) $(ECHO) 'installdirs: site' >> META_new.yml
|
||||
$(NOECHO) $(ECHO) 'requires:' >> META_new.yml
|
||||
$(NOECHO) $(ECHO) '' >> META_new.yml
|
||||
$(NOECHO) $(ECHO) 'distribution_type: module' >> META_new.yml
|
||||
$(NOECHO) $(ECHO) 'generated_by: ExtUtils::MakeMaker version 6.30_01' >> META_new.yml
|
||||
-$(NOECHO) $(MV) META_new.yml $(DISTVNAME)/META.yml
|
||||
|
||||
|
||||
# --- MakeMaker signature section:
|
||||
signature :
|
||||
cpansign -s
|
||||
|
||||
|
||||
# --- MakeMaker dist_basics section:
|
||||
distclean :: realclean distcheck
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
distcheck :
|
||||
$(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck
|
||||
|
||||
skipcheck :
|
||||
$(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck
|
||||
|
||||
manifest :
|
||||
$(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest
|
||||
|
||||
veryclean : realclean
|
||||
$(RM_F) *~ *.orig */*~ */*.orig
|
||||
|
||||
|
||||
|
||||
# --- MakeMaker dist_core section:
|
||||
|
||||
dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE)
|
||||
$(NOECHO) $(ABSPERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \
|
||||
-e ' if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\'' < -M '\''$(FIRST_MAKEFILE)'\'';'
|
||||
|
||||
tardist : $(DISTVNAME).tar$(SUFFIX)
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
uutardist : $(DISTVNAME).tar$(SUFFIX)
|
||||
uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu
|
||||
|
||||
$(DISTVNAME).tar$(SUFFIX) : distdir
|
||||
$(PREOP)
|
||||
$(TO_UNIX)
|
||||
$(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME)
|
||||
$(RM_RF) $(DISTVNAME)
|
||||
$(COMPRESS) $(DISTVNAME).tar
|
||||
$(POSTOP)
|
||||
|
||||
zipdist : $(DISTVNAME).zip
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
$(DISTVNAME).zip : distdir
|
||||
$(PREOP)
|
||||
$(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME)
|
||||
$(RM_RF) $(DISTVNAME)
|
||||
$(POSTOP)
|
||||
|
||||
shdist : distdir
|
||||
$(PREOP)
|
||||
$(SHAR) $(DISTVNAME) > $(DISTVNAME).shar
|
||||
$(RM_RF) $(DISTVNAME)
|
||||
$(POSTOP)
|
||||
|
||||
|
||||
# --- MakeMaker distdir section:
|
||||
create_distdir :
|
||||
$(RM_RF) $(DISTVNAME)
|
||||
$(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \
|
||||
-e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');"
|
||||
|
||||
distdir : create_distdir distmeta
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
|
||||
|
||||
# --- MakeMaker dist_test section:
|
||||
disttest : distdir
|
||||
cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL
|
||||
cd $(DISTVNAME) && $(MAKE) $(PASTHRU)
|
||||
cd $(DISTVNAME) && $(MAKE) test $(PASTHRU)
|
||||
|
||||
|
||||
|
||||
# --- MakeMaker dist_ci section:
|
||||
|
||||
ci :
|
||||
$(PERLRUN) "-MExtUtils::Manifest=maniread" \
|
||||
-e "@all = keys %{ maniread() };" \
|
||||
-e "print(qq{Executing $(CI) @all\n}); system(qq{$(CI) @all});" \
|
||||
-e "print(qq{Executing $(RCS_LABEL) ...\n}); system(qq{$(RCS_LABEL) @all});"
|
||||
|
||||
|
||||
# --- MakeMaker distmeta section:
|
||||
distmeta : create_distdir metafile
|
||||
$(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{META.yml} => q{Module meta-data (added by MakeMaker)}}) } ' \
|
||||
-e ' or print "Could not add META.yml to MANIFEST: $${'\''@'\''}\n"'
|
||||
|
||||
|
||||
|
||||
# --- MakeMaker distsignature section:
|
||||
distsignature : create_distdir
|
||||
$(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{SIGNATURE} => q{Public-key signature (added by MakeMaker)}}) } ' \
|
||||
-e ' or print "Could not add SIGNATURE to MANIFEST: $${'\''@'\''}\n"'
|
||||
$(NOECHO) cd $(DISTVNAME) && $(TOUCH) SIGNATURE
|
||||
cd $(DISTVNAME) && cpansign -s
|
||||
|
||||
|
||||
|
||||
# --- MakeMaker install section:
|
||||
|
||||
install :: all pure_install doc_install
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
install_perl :: all pure_perl_install doc_perl_install
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
install_site :: all pure_site_install doc_site_install
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
install_vendor :: all pure_vendor_install doc_vendor_install
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
pure_install :: pure_$(INSTALLDIRS)_install
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
doc_install :: doc_$(INSTALLDIRS)_install
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
pure__install : pure_site_install
|
||||
$(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
|
||||
|
||||
doc__install : doc_site_install
|
||||
$(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
|
||||
|
||||
pure_perl_install ::
|
||||
$(NOECHO) umask 022; $(MOD_INSTALL) \
|
||||
$(INST_LIB) $(DESTINSTALLPRIVLIB) \
|
||||
$(INST_ARCHLIB) $(DESTINSTALLARCHLIB) \
|
||||
$(INST_BIN) $(DESTINSTALLBIN) \
|
||||
$(INST_SCRIPT) $(DESTINSTALLSCRIPT) \
|
||||
$(INST_MAN1DIR) $(DESTINSTALLMAN1DIR) \
|
||||
$(INST_MAN3DIR) $(DESTINSTALLMAN3DIR)
|
||||
$(NOECHO) $(WARN_IF_OLD_PACKLIST) \
|
||||
$(SITEARCHEXP)/auto/$(FULLEXT)
|
||||
|
||||
|
||||
pure_site_install ::
|
||||
$(NOECHO) umask 02; $(MOD_INSTALL) \
|
||||
read $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist \
|
||||
write $(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist \
|
||||
$(INST_LIB) $(DESTINSTALLSITELIB) \
|
||||
$(INST_ARCHLIB) $(DESTINSTALLSITEARCH) \
|
||||
$(INST_BIN) $(DESTINSTALLSITEBIN) \
|
||||
$(INST_SCRIPT) $(DESTINSTALLSITESCRIPT) \
|
||||
$(INST_MAN1DIR) $(DESTINSTALLSITEMAN1DIR) \
|
||||
$(INST_MAN3DIR) $(DESTINSTALLSITEMAN3DIR)
|
||||
$(NOECHO) $(WARN_IF_OLD_PACKLIST) \
|
||||
$(PERL_ARCHLIB)/auto/$(FULLEXT)
|
||||
|
||||
pure_vendor_install ::
|
||||
$(NOECHO) umask 022; $(MOD_INSTALL) \
|
||||
$(INST_LIB) $(DESTINSTALLVENDORLIB) \
|
||||
$(INST_ARCHLIB) $(DESTINSTALLVENDORARCH) \
|
||||
$(INST_BIN) $(DESTINSTALLVENDORBIN) \
|
||||
$(INST_SCRIPT) $(DESTINSTALLVENDORSCRIPT) \
|
||||
$(INST_MAN1DIR) $(DESTINSTALLVENDORMAN1DIR) \
|
||||
$(INST_MAN3DIR) $(DESTINSTALLVENDORMAN3DIR)
|
||||
|
||||
doc_perl_install ::
|
||||
|
||||
doc_site_install ::
|
||||
$(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLSITEARCH)/perllocal.pod
|
||||
-$(NOECHO) umask 02; $(MKPATH) $(DESTINSTALLSITEARCH)
|
||||
-$(NOECHO) umask 02; $(DOC_INSTALL) \
|
||||
"Module" "$(NAME)" \
|
||||
"installed into" "$(INSTALLSITELIB)" \
|
||||
LINKTYPE "$(LINKTYPE)" \
|
||||
VERSION "$(VERSION)" \
|
||||
EXE_FILES "$(EXE_FILES)" \
|
||||
>> $(DESTINSTALLSITEARCH)/perllocal.pod
|
||||
|
||||
doc_vendor_install ::
|
||||
|
||||
|
||||
uninstall :: uninstall_from_$(INSTALLDIRS)dirs
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
uninstall_from_perldirs ::
|
||||
|
||||
uninstall_from_sitedirs ::
|
||||
$(NOECHO) $(UNINSTALL) $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist
|
||||
|
||||
uninstall_from_vendordirs ::
|
||||
|
||||
|
||||
|
||||
# --- MakeMaker force section:
|
||||
# Phony target to force checking subdirectories.
|
||||
FORCE:
|
||||
$(NOECHO) $(NOOP)
|
||||
|
||||
|
||||
# --- MakeMaker perldepend section:
|
||||
|
||||
|
||||
# --- MakeMaker makefile section:
|
||||
# We take a very conservative approach here, but it's worth it.
|
||||
# We move Makefile to Makefile.old here to avoid gnu make looping.
|
||||
$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP)
|
||||
$(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?"
|
||||
$(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..."
|
||||
-$(NOECHO) $(RM_F) $(MAKEFILE_OLD)
|
||||
-$(NOECHO) $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD)
|
||||
- $(MAKE) $(USEMAKEFILE) $(MAKEFILE_OLD) clean $(DEV_NULL)
|
||||
$(PERLRUN) Makefile.PL
|
||||
$(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <=="
|
||||
$(NOECHO) $(ECHO) "==> Please rerun the $(MAKE) command. <=="
|
||||
false
|
||||
|
||||
|
||||
|
||||
# --- MakeMaker staticmake section:
|
||||
|
||||
# --- MakeMaker makeaperl section ---
|
||||
MAP_TARGET = perl
|
||||
FULLPERL = /usr/bin/perl
|
||||
|
||||
$(MAP_TARGET) :: static $(MAKE_APERL_FILE)
|
||||
$(MAKE) $(USEMAKEFILE) $(MAKE_APERL_FILE) $@
|
||||
|
||||
$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) pm_to_blib
|
||||
$(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET)
|
||||
$(NOECHO) $(PERLRUNINST) \
|
||||
Makefile.PL DIR= \
|
||||
MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
|
||||
MAKEAPERL=1 NORECURS=1 CCCDLFLAGS=
|
||||
|
||||
|
||||
# --- MakeMaker test section:
|
||||
|
||||
TEST_VERBOSE=0
|
||||
TEST_TYPE=test_$(LINKTYPE)
|
||||
TEST_FILE = test.pl
|
||||
TEST_FILES =
|
||||
TESTDB_SW = -d
|
||||
|
||||
testdb :: testdb_$(LINKTYPE)
|
||||
|
||||
test :: $(TEST_TYPE)
|
||||
|
||||
test_dynamic :: pure_all
|
||||
PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE)
|
||||
|
||||
testdb_dynamic :: pure_all
|
||||
PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE)
|
||||
|
||||
test_ : test_dynamic
|
||||
|
||||
test_static :: test_dynamic
|
||||
testdb_static :: testdb_dynamic
|
||||
|
||||
|
||||
# --- MakeMaker ppd section:
|
||||
# Creates a PPD (Perl Package Description) for a binary distribution.
|
||||
ppd:
|
||||
$(NOECHO) $(ECHO) '<SOFTPKG NAME="$(DISTNAME)" VERSION="1,0,0,0">' > $(DISTNAME).ppd
|
||||
$(NOECHO) $(ECHO) ' <TITLE>$(DISTNAME)</TITLE>' >> $(DISTNAME).ppd
|
||||
$(NOECHO) $(ECHO) ' <ABSTRACT></ABSTRACT>' >> $(DISTNAME).ppd
|
||||
$(NOECHO) $(ECHO) ' <AUTHOR></AUTHOR>' >> $(DISTNAME).ppd
|
||||
$(NOECHO) $(ECHO) ' <IMPLEMENTATION>' >> $(DISTNAME).ppd
|
||||
$(NOECHO) $(ECHO) ' <OS NAME="$(OSNAME)" />' >> $(DISTNAME).ppd
|
||||
$(NOECHO) $(ECHO) ' <ARCHITECTURE NAME="i486-linux-gnu-thread-multi" />' >> $(DISTNAME).ppd
|
||||
$(NOECHO) $(ECHO) ' <CODEBASE HREF="" />' >> $(DISTNAME).ppd
|
||||
$(NOECHO) $(ECHO) ' </IMPLEMENTATION>' >> $(DISTNAME).ppd
|
||||
$(NOECHO) $(ECHO) '</SOFTPKG>' >> $(DISTNAME).ppd
|
||||
|
||||
|
||||
# --- MakeMaker pm_to_blib section:
|
||||
|
||||
pm_to_blib : $(TO_INST_PM)
|
||||
$(NOECHO) $(ABSPERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', '\''$(PM_FILTER)'\'')' \
|
||||
API.pm $(INST_LIB)/Webmin/API.pm
|
||||
$(NOECHO) $(TOUCH) pm_to_blib
|
||||
|
||||
|
||||
# --- MakeMaker selfdocument section:
|
||||
|
||||
|
||||
# --- MakeMaker postamble section:
|
||||
|
||||
|
||||
# End.
|
||||
@@ -1,8 +0,0 @@
|
||||
use ExtUtils::MakeMaker;
|
||||
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
|
||||
# the contents of the Makefile that is written.
|
||||
WriteMakefile(
|
||||
'NAME' => 'Webmin::API',
|
||||
'VERSION_FROM' => 'API.pm', # finds $VERSION
|
||||
'PREREQ_PM' => {}, # e.g., Module::Name => 1.1
|
||||
);
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
cd /usr/local/webadmin
|
||||
tar --exclude blib --exclude .svn --exclude make-module.sh --exclude Makefile -cvzf ~/webmin.com/Webmin-API-1.0.tar.gz Webmin-API-1.0/
|
||||
@@ -1,20 +0,0 @@
|
||||
# Before `make install' is performed this script should be runnable with
|
||||
# `make test'. After `make install' it should work as `perl test.pl'
|
||||
|
||||
######################### We start with some black magic to print on failure.
|
||||
|
||||
# Change 1..1 below to 1..last_test_to_print .
|
||||
# (It may become useful if the test is moved to ./t subdirectory.)
|
||||
|
||||
BEGIN { $| = 1; print "1..1\n"; }
|
||||
END {print "not ok 1\n" unless $loaded;}
|
||||
use Webmin::API;
|
||||
$loaded = 1;
|
||||
print "ok 1\n";
|
||||
|
||||
######################### End of black magic.
|
||||
|
||||
# Insert your test code below (better if it prints "ok 13"
|
||||
# (correspondingly "not ok 13") depending on the success of chunk 13
|
||||
# of the test code):
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
---- Changes since 1.550 ----
|
||||
First version of this module, which allows shell logins without the need to use a separate SSH client or even run an SSH server.
|
||||
@@ -1,120 +0,0 @@
|
||||
= [http://antony.lesuisse.org/qweb/trac/wiki/AjaxTerm Ajaxterm] =
|
||||
|
||||
Ajaxterm is a web based terminal. It was totally inspired and works almost
|
||||
exactly like http://anyterm.org/ except it's much easier to install (see
|
||||
comparaison with anyterm below).
|
||||
|
||||
Ajaxterm written in python (and some AJAX javascript for client side) and depends only on python2.3 or better.[[BR]]
|
||||
Ajaxterm is '''very simple to install''' on Linux, MacOS X, FreeBSD, Solaris, cygwin and any Unix that runs python2.3.[[BR]]
|
||||
Ajaxterm was written by Antony Lesuisse (email: al AT udev.org), License Public Domain.
|
||||
|
||||
Use the [/qweb/forum/viewforum.php?id=2 Forum], if you have any question or remark.
|
||||
|
||||
== News ==
|
||||
|
||||
* 2006-10-29: v0.10 allow space in login, cgi launch fix, redhat init
|
||||
* 2006-07-12: v0.9 change uid, daemon fix (Daniel Fischer)
|
||||
* 2006-07-04: v0.8 add login support to ssh (Sven Geggus), change max width to 256
|
||||
* 2006-05-31: v0.7 minor fixes, daemon option
|
||||
* 2006-05-23: v0.6 Applied debian and gentoo patches, renamed to Ajaxterm, default port 8022
|
||||
|
||||
== Download and Install ==
|
||||
|
||||
* Release: [/qweb/files/Ajaxterm-0.10.tar.gz Ajaxterm-0.10.tar.gz]
|
||||
* Browse src: [/qweb/trac/browser/trunk/ajaxterm/ ajaxterm/]
|
||||
|
||||
To install Ajaxterm issue the following commands:
|
||||
{{{
|
||||
wget http://antony.lesuisse.org/qweb/files/Ajaxterm-0.10.tar.gz
|
||||
tar zxvf Ajaxterm-0.10.tar.gz
|
||||
cd Ajaxterm-0.10
|
||||
./ajaxterm.py
|
||||
}}}
|
||||
Then point your browser to this URL : http://localhost:8022/
|
||||
|
||||
== Screenshot ==
|
||||
|
||||
{{{
|
||||
#!html
|
||||
<center><img src="/qweb/trac/attachment/wiki/AjaxTerm/scr.png?format=raw" alt="ajaxterm screenshot" style=""/></center>
|
||||
}}}
|
||||
|
||||
== Documentation and Caveats ==
|
||||
|
||||
* Ajaxterm only support latin1, if you use Ubuntu or any LANG==en_US.UTF-8 distribution don't forget to "unset LANG".
|
||||
|
||||
* If run as root ajaxterm will run /bin/login, otherwise it will run ssh
|
||||
localhost. To use an other command use the -c option.
|
||||
|
||||
* By default Ajaxterm only listen at 127.0.0.1:8022. For remote access, it is
|
||||
strongly recommended to use '''https SSL/TLS''', and that is simple to
|
||||
configure if you use the apache web server using mod_proxy.[[BR]][[BR]]
|
||||
Using ssl will also speed up ajaxterm (probably because of keepalive).[[BR]][[BR]]
|
||||
Here is an configuration example:
|
||||
|
||||
{{{
|
||||
Listen 443
|
||||
NameVirtualHost *:443
|
||||
|
||||
<VirtualHost *:443>
|
||||
ServerName localhost
|
||||
SSLEngine On
|
||||
SSLCertificateKeyFile ssl/apache.pem
|
||||
SSLCertificateFile ssl/apache.pem
|
||||
|
||||
ProxyRequests Off
|
||||
<Proxy *>
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
</Proxy>
|
||||
ProxyPass /ajaxterm/ http://localhost:8022/
|
||||
ProxyPassReverse /ajaxterm/ http://localhost:8022/
|
||||
</VirtualHost>
|
||||
}}}
|
||||
|
||||
* Using GET HTTP request seems to speed up ajaxterm, just click on GET in the
|
||||
interface, but be warned that your keystrokes might be loggued (by apache or
|
||||
any proxy). I usually enable it after the login.
|
||||
|
||||
* Ajaxterm commandline usage:
|
||||
|
||||
{{{
|
||||
usage: ajaxterm.py [options]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-pPORT, --port=PORT Set the TCP port (default: 8022)
|
||||
-cCMD, --command=CMD set the command (default: /bin/login or ssh localhost)
|
||||
-l, --log log requests to stderr (default: quiet mode)
|
||||
-d, --daemon run as daemon in the background
|
||||
-PPIDFILE, --pidfile=PIDFILE
|
||||
set the pidfile (default: /var/run/ajaxterm.pid)
|
||||
-iINDEX_FILE, --index=INDEX_FILE
|
||||
default index file (default: ajaxterm.html)
|
||||
-uUID, --uid=UID Set the daemon's user id
|
||||
}}}
|
||||
|
||||
* Ajaxterm was first written as a demo for qweb (my web framework), but
|
||||
actually doesn't use many features of qweb.
|
||||
|
||||
* Compared to anyterm:
|
||||
* There are no partial updates, ajaxterm updates either all the screen or
|
||||
nothing. That make the code simpler and I also think it's faster. HTTP
|
||||
replies are always gzencoded. When used in 80x25 mode, almost all of
|
||||
them are below the 1500 bytes (size of an ethernet frame) and we just
|
||||
replace the screen with the reply (no javascript string handling).
|
||||
* Ajaxterm polls the server for updates with an exponentially growing
|
||||
timeout when the screen hasn't changed. The timeout is also resetted as
|
||||
soon as a key is pressed. Anyterm blocks on a pending request and use a
|
||||
parallel connection for keypresses. The anyterm approch is better
|
||||
when there aren't any keypress.
|
||||
|
||||
* Ajaxterm files are released in the Public Domain, (except [http://sarissa.sourceforge.net/doc/ sarissa*] which are LGPL).
|
||||
|
||||
== TODO ==
|
||||
|
||||
* insert mode ESC [ 4 h
|
||||
* change size x,y from gui (sending signal)
|
||||
* vt102 graphic codepage
|
||||
* use innerHTML or prototype instead of sarissa
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
.TH ajaxterm "1" "May 2006" "ajaxterm 0.5" "User commands"
|
||||
.SH NAME
|
||||
ajaxterm \- Web based terminal written in python
|
||||
|
||||
.SH DESCRITPION
|
||||
\fBajaxterm\fR is a web based terminal written in python and some AJAX
|
||||
javascript for client side.
|
||||
It can use almost any web browser and even works through firewalls.
|
||||
|
||||
.SH USAGE
|
||||
\fBajaxterm.py\fR [options]
|
||||
|
||||
.SH OPTIONS
|
||||
A summary of the options supported by \fBajaxterm\fR is included below.
|
||||
\fB-h, --help\fR show this help message and exit
|
||||
\fB-pPORT, --port=PORT\fR Set the TCP port (default: 8022)
|
||||
\fB-cCMD, --command=CMD\fR set the command (default: /bin/login or ssh localhost)
|
||||
\fB-l, --log\fR log requests to stderr (default: quiet mode)
|
||||
|
||||
.SH AUTHOR
|
||||
Antony Lesuisse <al@udev.org>
|
||||
|
||||
This manual page was written for the Debian system by
|
||||
Julien Valroff <julien@kirya.net> (but may be used by others).
|
||||
|
||||
.SH "REPORTING BUGS"
|
||||
Report any bugs to the author: Antony Lesuisse <al@udev.org>
|
||||
|
||||
.SH COPYRIGHT
|
||||
Copyright Antony Lesuisse <al@udev.org>
|
||||
|
||||
.SH SEE ALSO
|
||||
- \fBajaxterm\fR wiki page: http://antony.lesuisse.org/qweb/trac/wiki/AjaxTerm
|
||||
.br
|
||||
- \fBajaxterm\fR forum: http://antony.lesuisse.org/qweb/forum/viewforum.php?id=2
|
||||
@@ -1,72 +0,0 @@
|
||||
pre.stat {
|
||||
margin: 0px;
|
||||
padding: 4px;
|
||||
display: block;
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
background-color: black;
|
||||
border-top: 1px solid black;
|
||||
color: white;
|
||||
}
|
||||
pre.stat span {
|
||||
padding: 0px;
|
||||
}
|
||||
pre.stat .on {
|
||||
background-color: #080;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
pre.stat .off {
|
||||
background-color: #888;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
pre.term {
|
||||
margin: 0px;
|
||||
padding: 4px;
|
||||
display: block;
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
background-color: black;
|
||||
border-top: 1px solid white;
|
||||
color: #eee;
|
||||
}
|
||||
pre.term span.f0 { color: #000; }
|
||||
pre.term span.f1 { color: #b00; }
|
||||
pre.term span.f2 { color: #0b0; }
|
||||
pre.term span.f3 { color: #bb0; }
|
||||
pre.term span.f4 { color: #00b; }
|
||||
pre.term span.f5 { color: #b0b; }
|
||||
pre.term span.f6 { color: #0bb; }
|
||||
pre.term span.f7 { color: #bbb; }
|
||||
pre.term span.f8 { color: #666; }
|
||||
pre.term span.f9 { color: #f00; }
|
||||
pre.term span.f10 { color: #0f0; }
|
||||
pre.term span.f11 { color: #ff0; }
|
||||
pre.term span.f12 { color: #00f; }
|
||||
pre.term span.f13 { color: #f0f; }
|
||||
pre.term span.f14 { color: #0ff; }
|
||||
pre.term span.f15 { color: #fff; }
|
||||
pre.term span.b0 { background-color: #000; }
|
||||
pre.term span.b1 { background-color: #b00; }
|
||||
pre.term span.b2 { background-color: #0b0; }
|
||||
pre.term span.b3 { background-color: #bb0; }
|
||||
pre.term span.b4 { background-color: #00b; }
|
||||
pre.term span.b5 { background-color: #b0b; }
|
||||
pre.term span.b6 { background-color: #0bb; }
|
||||
pre.term span.b7 { background-color: #bbb; }
|
||||
|
||||
body { background-color: #ffffff; }
|
||||
#term {
|
||||
float: left;
|
||||
margin: 0px;
|
||||
padding: 4px;
|
||||
display: block;
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
background-color: black;
|
||||
border-top: 1px solid white;
|
||||
color: #eee;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Ajaxterm</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
|
||||
<link rel="stylesheet" type="text/css" href="ajaxterm.css"/>
|
||||
<script type="text/javascript" src="sarissa.js"></script>
|
||||
<script type="text/javascript" src="sarissa_dhtml.js"></script>
|
||||
<script type="text/javascript" src="ajaxterm.js"></script>
|
||||
<script type="text/javascript">
|
||||
window.onload=function() {
|
||||
t=ajaxterm.Terminal("term",80,25);
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="term"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,285 +0,0 @@
|
||||
ajaxterm={};
|
||||
ajaxterm.Terminal_ctor=function(id,width,height) {
|
||||
var ie=0;
|
||||
if(window.ActiveXObject)
|
||||
ie=1;
|
||||
var sid=""+Math.round(Math.random()*1000000000);
|
||||
var query0="s="+sid+"&w="+width+"&h="+height;
|
||||
var query1=query0+"&c=1&k=";
|
||||
var buf="";
|
||||
var timeout;
|
||||
var error_timeout;
|
||||
var keybuf=[];
|
||||
var sending=0;
|
||||
var rmax=1;
|
||||
|
||||
var div=document.getElementById(id);
|
||||
var dstat=document.createElement('pre');
|
||||
var sled=document.createElement('span');
|
||||
var opt_get=document.createElement('a');
|
||||
var opt_color=document.createElement('a');
|
||||
var opt_paste=document.createElement('a');
|
||||
var sdebug=document.createElement('span');
|
||||
var dterm=document.createElement('div');
|
||||
|
||||
function debug(s) {
|
||||
sdebug.innerHTML=s;
|
||||
}
|
||||
function error() {
|
||||
sled.className='off';
|
||||
debug("Connection lost timeout ts:"+((new Date).getTime()));
|
||||
}
|
||||
function opt_add(opt,name) {
|
||||
opt.className='off';
|
||||
opt.innerHTML=' '+name+' ';
|
||||
dstat.appendChild(opt);
|
||||
dstat.appendChild(document.createTextNode(' '));
|
||||
}
|
||||
function do_get(event) {
|
||||
opt_get.className=(opt_get.className=='off')?'on':'off';
|
||||
debug('GET '+opt_get.className);
|
||||
}
|
||||
function do_color(event) {
|
||||
var o=opt_color.className=(opt_color.className=='off')?'on':'off';
|
||||
if(o=='on')
|
||||
query1=query0+"&c=1&k=";
|
||||
else
|
||||
query1=query0+"&k=";
|
||||
debug('Color '+opt_color.className);
|
||||
}
|
||||
function mozilla_clipboard() {
|
||||
// mozilla sucks
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
} catch (err) {
|
||||
debug('Access denied, <a href="http://kb.mozillazine.org/Granting_JavaScript_access_to_the_clipboard" target="_blank">more info</a>');
|
||||
return undefined;
|
||||
}
|
||||
var clip = Components.classes["@mozilla.org/widget/clipboard;1"].createInstance(Components.interfaces.nsIClipboard);
|
||||
var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
|
||||
if (!clip || !trans) {
|
||||
return undefined;
|
||||
}
|
||||
trans.addDataFlavor("text/unicode");
|
||||
clip.getData(trans,clip.kGlobalClipboard);
|
||||
var str=new Object();
|
||||
var strLength=new Object();
|
||||
try {
|
||||
trans.getTransferData("text/unicode",str,strLength);
|
||||
} catch(err) {
|
||||
return "";
|
||||
}
|
||||
if (str) {
|
||||
str=str.value.QueryInterface(Components.interfaces.nsISupportsString);
|
||||
}
|
||||
if (str) {
|
||||
return str.data.substring(0,strLength.value / 2);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
function do_paste(event) {
|
||||
var p=undefined;
|
||||
if (window.clipboardData) {
|
||||
p=window.clipboardData.getData("Text");
|
||||
} else if(window.netscape) {
|
||||
p=mozilla_clipboard();
|
||||
}
|
||||
if (p) {
|
||||
debug('Pasted');
|
||||
queue(encodeURIComponent(p));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
function update() {
|
||||
// debug("ts: "+((new Date).getTime())+" rmax:"+rmax);
|
||||
if(sending==0) {
|
||||
sending=1;
|
||||
sled.className='on';
|
||||
var r=new XMLHttpRequest();
|
||||
var send="";
|
||||
while(keybuf.length>0) {
|
||||
send+=keybuf.pop();
|
||||
}
|
||||
var query=query1+send;
|
||||
if(opt_get.className=='on') {
|
||||
r.open("GET","u?"+query,true);
|
||||
if(ie) {
|
||||
r.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
|
||||
}
|
||||
} else {
|
||||
r.open("POST","u",true);
|
||||
}
|
||||
r.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
|
||||
r.onreadystatechange = function () {
|
||||
// debug("xhr:"+((new Date).getTime())+" state:"+r.readyState+" status:"+r.status+" statusText:"+r.statusText);
|
||||
if (r.readyState==4) {
|
||||
if(r.status==200) {
|
||||
window.clearTimeout(error_timeout);
|
||||
de=r.responseXML.documentElement;
|
||||
if(de.tagName=="pre") {
|
||||
if(ie) {
|
||||
Sarissa.updateContentFromNode(de, dterm);
|
||||
} else {
|
||||
Sarissa.updateContentFromNode(de, dterm);
|
||||
// old=div.firstChild;
|
||||
// div.replaceChild(de,old);
|
||||
}
|
||||
rmax=100;
|
||||
} else {
|
||||
rmax*=2;
|
||||
if(rmax>2000)
|
||||
rmax=2000;
|
||||
}
|
||||
sending=0;
|
||||
sled.className='off';
|
||||
timeout=window.setTimeout(update,rmax);
|
||||
} else {
|
||||
debug("Connection error status:"+r.status);
|
||||
}
|
||||
}
|
||||
}
|
||||
error_timeout=window.setTimeout(error,5000);
|
||||
if(opt_get.className=='on') {
|
||||
r.send(null);
|
||||
} else {
|
||||
r.send(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
function queue(s) {
|
||||
keybuf.unshift(s);
|
||||
if(sending==0) {
|
||||
window.clearTimeout(timeout);
|
||||
timeout=window.setTimeout(update,1);
|
||||
}
|
||||
}
|
||||
function keypress(ev) {
|
||||
if (!ev) var ev=window.event;
|
||||
// s="kp keyCode="+ev.keyCode+" which="+ev.which+" shiftKey="+ev.shiftKey+" ctrlKey="+ev.ctrlKey+" altKey="+ev.altKey;
|
||||
// debug(s);
|
||||
// return false;
|
||||
// else { if (!ev.ctrlKey || ev.keyCode==17) { return; }
|
||||
var kc;
|
||||
var k="";
|
||||
if (ev.keyCode)
|
||||
kc=ev.keyCode;
|
||||
if (ev.which)
|
||||
kc=ev.which;
|
||||
if (ev.altKey) {
|
||||
if (kc>=65 && kc<=90)
|
||||
kc+=32;
|
||||
if (kc>=97 && kc<=122) {
|
||||
k=String.fromCharCode(27)+String.fromCharCode(kc);
|
||||
}
|
||||
} else if (ev.ctrlKey) {
|
||||
if (kc>=65 && kc<=90) k=String.fromCharCode(kc-64); // Ctrl-A..Z
|
||||
else if (kc>=97 && kc<=122) k=String.fromCharCode(kc-96); // Ctrl-A..Z
|
||||
else if (kc==54) k=String.fromCharCode(30); // Ctrl-^
|
||||
else if (kc==109) k=String.fromCharCode(31); // Ctrl-_
|
||||
else if (kc==219) k=String.fromCharCode(27); // Ctrl-[
|
||||
else if (kc==220) k=String.fromCharCode(28); // Ctrl-\
|
||||
else if (kc==221) k=String.fromCharCode(29); // Ctrl-]
|
||||
else if (kc==219) k=String.fromCharCode(29); // Ctrl-]
|
||||
else if (kc==219) k=String.fromCharCode(0); // Ctrl-@
|
||||
} else if (ev.which==0) {
|
||||
if (kc==9) k=String.fromCharCode(9); // Tab
|
||||
else if (kc==8) k=String.fromCharCode(127); // Backspace
|
||||
else if (kc==27) k=String.fromCharCode(27); // Escape
|
||||
else {
|
||||
if (kc==33) k="[5~"; // PgUp
|
||||
else if (kc==34) k="[6~"; // PgDn
|
||||
else if (kc==35) k="[4~"; // End
|
||||
else if (kc==36) k="[1~"; // Home
|
||||
else if (kc==37) k="[D"; // Left
|
||||
else if (kc==38) k="[A"; // Up
|
||||
else if (kc==39) k="[C"; // Right
|
||||
else if (kc==40) k="[B"; // Down
|
||||
else if (kc==45) k="[2~"; // Ins
|
||||
else if (kc==46) k="[3~"; // Del
|
||||
else if (kc==112) k="[[A"; // F1
|
||||
else if (kc==113) k="[[B"; // F2
|
||||
else if (kc==114) k="[[C"; // F3
|
||||
else if (kc==115) k="[[D"; // F4
|
||||
else if (kc==116) k="[[E"; // F5
|
||||
else if (kc==117) k="[17~"; // F6
|
||||
else if (kc==118) k="[18~"; // F7
|
||||
else if (kc==119) k="[19~"; // F8
|
||||
else if (kc==120) k="[20~"; // F9
|
||||
else if (kc==121) k="[21~"; // F10
|
||||
else if (kc==122) k="[23~"; // F11
|
||||
else if (kc==123) k="[24~"; // F12
|
||||
if (k.length) {
|
||||
k=String.fromCharCode(27)+k;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (kc==8)
|
||||
k=String.fromCharCode(127); // Backspace
|
||||
else
|
||||
k=String.fromCharCode(kc);
|
||||
}
|
||||
if(k.length) {
|
||||
// queue(encodeURIComponent(k));
|
||||
if(k=="+") {
|
||||
queue("%2B");
|
||||
} else {
|
||||
queue(escape(k));
|
||||
}
|
||||
}
|
||||
ev.cancelBubble=true;
|
||||
if (ev.stopPropagation) ev.stopPropagation();
|
||||
if (ev.preventDefault) ev.preventDefault();
|
||||
return false;
|
||||
}
|
||||
function keydown(ev) {
|
||||
if (!ev) var ev=window.event;
|
||||
if (ev.keyCode == 8 || ev.keyCode == 27 || ev.keyCode == 17 ||
|
||||
ev.ctrlKey) {
|
||||
// In chrome, keypress isn't called for backspace,
|
||||
// escape or ctrl-something
|
||||
return keypress(ev);
|
||||
}
|
||||
if (ie) {
|
||||
// s="kd keyCode="+ev.keyCode+" which="+ev.which+" shiftKey="+ev.shiftKey+" ctrlKey="+ev.ctrlKey+" altKey="+ev.altKey;
|
||||
// debug(s);
|
||||
o={9:1,8:1,27:1,33:1,34:1,35:1,36:1,37:1,38:1,39:1,40:1,45:1,46:1,112:1,
|
||||
113:1,114:1,115:1,116:1,117:1,118:1,119:1,120:1,121:1,122:1,123:1};
|
||||
if (o[ev.keyCode] || ev.ctrlKey || ev.altKey) {
|
||||
ev.which=0;
|
||||
return keypress(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
function init() {
|
||||
sled.appendChild(document.createTextNode('\xb7'));
|
||||
sled.className='off';
|
||||
dstat.appendChild(sled);
|
||||
dstat.appendChild(document.createTextNode(' '));
|
||||
opt_add(opt_color,'Colors');
|
||||
opt_color.className='on';
|
||||
opt_add(opt_get,'GET');
|
||||
opt_add(opt_paste,'Paste');
|
||||
dstat.appendChild(sdebug);
|
||||
dstat.className='stat';
|
||||
div.appendChild(dstat);
|
||||
div.appendChild(dterm);
|
||||
if(opt_color.addEventListener) {
|
||||
opt_get.addEventListener('click',do_get,true);
|
||||
opt_color.addEventListener('click',do_color,true);
|
||||
opt_paste.addEventListener('click',do_paste,true);
|
||||
} else {
|
||||
opt_get.attachEvent("onclick", do_get);
|
||||
opt_color.attachEvent("onclick", do_color);
|
||||
opt_paste.attachEvent("onclick", do_paste);
|
||||
}
|
||||
document.onkeypress=keypress;
|
||||
document.onkeydown=keydown;
|
||||
timeout=window.setTimeout(update,100);
|
||||
}
|
||||
init();
|
||||
}
|
||||
ajaxterm.Terminal=function(id,width,height) {
|
||||
return new this.Terminal_ctor(id,width,height);
|
||||
}
|
||||
|
||||
@@ -1,567 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
""" Ajaxterm """
|
||||
|
||||
import array,cgi,fcntl,glob,mimetypes,optparse,os,pty,random,re,signal,select,sys,threading,time,termios,struct,pwd
|
||||
|
||||
os.chdir(os.path.normpath(os.path.dirname(__file__)))
|
||||
# Optional: Add QWeb in sys path
|
||||
sys.path[0:0]=glob.glob('../../python')
|
||||
|
||||
import qweb
|
||||
|
||||
class Terminal:
|
||||
def __init__(self,width=80,height=24):
|
||||
self.width=width
|
||||
self.height=height
|
||||
self.init()
|
||||
self.reset()
|
||||
def init(self):
|
||||
self.esc_seq={
|
||||
"\x00": None,
|
||||
"\x05": self.esc_da,
|
||||
"\x07": None,
|
||||
"\x08": self.esc_0x08,
|
||||
"\x09": self.esc_0x09,
|
||||
"\x0a": self.esc_0x0a,
|
||||
"\x0b": self.esc_0x0a,
|
||||
"\x0c": self.esc_0x0a,
|
||||
"\x0d": self.esc_0x0d,
|
||||
"\x0e": None,
|
||||
"\x0f": None,
|
||||
"\x1b#8": None,
|
||||
"\x1b=": None,
|
||||
"\x1b>": None,
|
||||
"\x1b(0": None,
|
||||
"\x1b(A": None,
|
||||
"\x1b(B": None,
|
||||
"\x1b[c": self.esc_da,
|
||||
"\x1b[0c": self.esc_da,
|
||||
"\x1b]R": None,
|
||||
"\x1b7": self.esc_save,
|
||||
"\x1b8": self.esc_restore,
|
||||
"\x1bD": None,
|
||||
"\x1bE": None,
|
||||
"\x1bH": None,
|
||||
"\x1bM": self.esc_ri,
|
||||
"\x1bN": None,
|
||||
"\x1bO": None,
|
||||
"\x1bZ": self.esc_da,
|
||||
"\x1ba": None,
|
||||
"\x1bc": self.reset,
|
||||
"\x1bn": None,
|
||||
"\x1bo": None,
|
||||
}
|
||||
for k,v in self.esc_seq.items():
|
||||
if v==None:
|
||||
self.esc_seq[k]=self.esc_ignore
|
||||
# regex
|
||||
d={
|
||||
r'\[\??([0-9;]*)([@ABCDEFGHJKLMPXacdefghlmnqrstu`])' : self.csi_dispatch,
|
||||
r'\]([^\x07]+)\x07' : self.esc_ignore,
|
||||
}
|
||||
self.esc_re=[]
|
||||
for k,v in d.items():
|
||||
self.esc_re.append((re.compile('\x1b'+k),v))
|
||||
# define csi sequences
|
||||
self.csi_seq={
|
||||
'@': (self.csi_at,[1]),
|
||||
'`': (self.csi_G,[1]),
|
||||
'J': (self.csi_J,[0]),
|
||||
'K': (self.csi_K,[0]),
|
||||
}
|
||||
for i in [i[4] for i in dir(self) if i.startswith('csi_') and len(i)==5]:
|
||||
if not self.csi_seq.has_key(i):
|
||||
self.csi_seq[i]=(getattr(self,'csi_'+i),[1])
|
||||
# Init 0-256 to latin1 and html translation table
|
||||
self.trl1=""
|
||||
for i in range(256):
|
||||
if i<32:
|
||||
self.trl1+=" "
|
||||
elif i<127 or i>160:
|
||||
self.trl1+=chr(i)
|
||||
else:
|
||||
self.trl1+="?"
|
||||
self.trhtml=""
|
||||
for i in range(256):
|
||||
if i==0x0a or (i>32 and i<127) or i>160:
|
||||
self.trhtml+=chr(i)
|
||||
elif i<=32:
|
||||
self.trhtml+="\xa0"
|
||||
else:
|
||||
self.trhtml+="?"
|
||||
def reset(self,s=""):
|
||||
self.scr=array.array('i',[0x000700]*(self.width*self.height))
|
||||
self.st=0
|
||||
self.sb=self.height-1
|
||||
self.cx_bak=self.cx=0
|
||||
self.cy_bak=self.cy=0
|
||||
self.cl=0
|
||||
self.sgr=0x000700
|
||||
self.buf=""
|
||||
self.outbuf=""
|
||||
self.last_html=""
|
||||
def peek(self,y1,x1,y2,x2):
|
||||
return self.scr[self.width*y1+x1:self.width*y2+x2]
|
||||
def poke(self,y,x,s):
|
||||
pos=self.width*y+x
|
||||
self.scr[pos:pos+len(s)]=s
|
||||
def zero(self,y1,x1,y2,x2):
|
||||
w=self.width*(y2-y1)+x2-x1+1
|
||||
z=array.array('i',[0x000700]*w)
|
||||
self.scr[self.width*y1+x1:self.width*y2+x2+1]=z
|
||||
def scroll_up(self,y1,y2):
|
||||
self.poke(y1,0,self.peek(y1+1,0,y2,self.width))
|
||||
self.zero(y2,0,y2,self.width-1)
|
||||
def scroll_down(self,y1,y2):
|
||||
self.poke(y1+1,0,self.peek(y1,0,y2-1,self.width))
|
||||
self.zero(y1,0,y1,self.width-1)
|
||||
def scroll_right(self,y,x):
|
||||
self.poke(y,x+1,self.peek(y,x,y,self.width))
|
||||
self.zero(y,x,y,x)
|
||||
def cursor_down(self):
|
||||
if self.cy>=self.st and self.cy<=self.sb:
|
||||
self.cl=0
|
||||
q,r=divmod(self.cy+1,self.sb+1)
|
||||
if q:
|
||||
self.scroll_up(self.st,self.sb)
|
||||
self.cy=self.sb
|
||||
else:
|
||||
self.cy=r
|
||||
def cursor_right(self):
|
||||
q,r=divmod(self.cx+1,self.width)
|
||||
if q:
|
||||
self.cl=1
|
||||
else:
|
||||
self.cx=r
|
||||
def echo(self,c):
|
||||
if self.cl:
|
||||
self.cursor_down()
|
||||
self.cx=0
|
||||
self.scr[(self.cy*self.width)+self.cx]=self.sgr|ord(c)
|
||||
self.cursor_right()
|
||||
def esc_0x08(self,s):
|
||||
self.cx=max(0,self.cx-1)
|
||||
def esc_0x09(self,s):
|
||||
x=self.cx+8
|
||||
q,r=divmod(x,8)
|
||||
self.cx=(q*8)%self.width
|
||||
def esc_0x0a(self,s):
|
||||
self.cursor_down()
|
||||
def esc_0x0d(self,s):
|
||||
self.cl=0
|
||||
self.cx=0
|
||||
def esc_save(self,s):
|
||||
self.cx_bak=self.cx
|
||||
self.cy_bak=self.cy
|
||||
def esc_restore(self,s):
|
||||
self.cx=self.cx_bak
|
||||
self.cy=self.cy_bak
|
||||
self.cl=0
|
||||
def esc_da(self,s):
|
||||
self.outbuf="\x1b[?6c"
|
||||
def esc_ri(self,s):
|
||||
self.cy=max(self.st,self.cy-1)
|
||||
if self.cy==self.st:
|
||||
self.scroll_down(self.st,self.sb)
|
||||
def esc_ignore(self,*s):
|
||||
pass
|
||||
# print "term:ignore: %s"%repr(s)
|
||||
def csi_dispatch(self,seq,mo):
|
||||
# CSI sequences
|
||||
s=mo.group(1)
|
||||
c=mo.group(2)
|
||||
f=self.csi_seq.get(c,None)
|
||||
if f:
|
||||
try:
|
||||
l=[min(int(i),1024) for i in s.split(';') if len(i)<4]
|
||||
except ValueError:
|
||||
l=[]
|
||||
if len(l)==0:
|
||||
l=f[1]
|
||||
f[0](l)
|
||||
# else:
|
||||
# print 'csi ignore',c,l
|
||||
def csi_at(self,l):
|
||||
for i in range(l[0]):
|
||||
self.scroll_right(self.cy,self.cx)
|
||||
def csi_A(self,l):
|
||||
self.cy=max(self.st,self.cy-l[0])
|
||||
def csi_B(self,l):
|
||||
self.cy=min(self.sb,self.cy+l[0])
|
||||
def csi_C(self,l):
|
||||
self.cx=min(self.width-1,self.cx+l[0])
|
||||
self.cl=0
|
||||
def csi_D(self,l):
|
||||
self.cx=max(0,self.cx-l[0])
|
||||
self.cl=0
|
||||
def csi_E(self,l):
|
||||
self.csi_B(l)
|
||||
self.cx=0
|
||||
self.cl=0
|
||||
def csi_F(self,l):
|
||||
self.csi_A(l)
|
||||
self.cx=0
|
||||
self.cl=0
|
||||
def csi_G(self,l):
|
||||
self.cx=min(self.width,l[0])-1
|
||||
def csi_H(self,l):
|
||||
if len(l)<2: l=[1,1]
|
||||
self.cx=min(self.width,l[1])-1
|
||||
self.cy=min(self.height,l[0])-1
|
||||
self.cl=0
|
||||
def csi_J(self,l):
|
||||
if l[0]==0:
|
||||
self.zero(self.cy,self.cx,self.height-1,self.width-1)
|
||||
elif l[0]==1:
|
||||
self.zero(0,0,self.cy,self.cx)
|
||||
elif l[0]==2:
|
||||
self.zero(0,0,self.height-1,self.width-1)
|
||||
def csi_K(self,l):
|
||||
if l[0]==0:
|
||||
self.zero(self.cy,self.cx,self.cy,self.width-1)
|
||||
elif l[0]==1:
|
||||
self.zero(self.cy,0,self.cy,self.cx)
|
||||
elif l[0]==2:
|
||||
self.zero(self.cy,0,self.cy,self.width-1)
|
||||
def csi_L(self,l):
|
||||
for i in range(l[0]):
|
||||
if self.cy<self.sb:
|
||||
self.scroll_down(self.cy,self.sb)
|
||||
def csi_M(self,l):
|
||||
if self.cy>=self.st and self.cy<=self.sb:
|
||||
for i in range(l[0]):
|
||||
self.scroll_up(self.cy,self.sb)
|
||||
def csi_P(self,l):
|
||||
w,cx,cy=self.width,self.cx,self.cy
|
||||
end=self.peek(cy,cx,cy,w)
|
||||
self.csi_K([0])
|
||||
self.poke(cy,cx,end[l[0]:])
|
||||
def csi_X(self,l):
|
||||
self.zero(self.cy,self.cx,self.cy,self.cx+l[0])
|
||||
def csi_a(self,l):
|
||||
self.csi_C(l)
|
||||
def csi_c(self,l):
|
||||
#'\x1b[?0c' 0-8 cursor size
|
||||
pass
|
||||
def csi_d(self,l):
|
||||
self.cy=min(self.height,l[0])-1
|
||||
def csi_e(self,l):
|
||||
self.csi_B(l)
|
||||
def csi_f(self,l):
|
||||
self.csi_H(l)
|
||||
def csi_h(self,l):
|
||||
if l[0]==4:
|
||||
pass
|
||||
# print "insert on"
|
||||
def csi_l(self,l):
|
||||
if l[0]==4:
|
||||
pass
|
||||
# print "insert off"
|
||||
def csi_m(self,l):
|
||||
for i in l:
|
||||
if i==0 or i==39 or i==49 or i==27:
|
||||
self.sgr=0x000700
|
||||
elif i==1:
|
||||
self.sgr=(self.sgr|0x000800)
|
||||
elif i==7:
|
||||
self.sgr=0x070000
|
||||
elif i>=30 and i<=37:
|
||||
c=i-30
|
||||
self.sgr=(self.sgr&0xff08ff)|(c<<8)
|
||||
elif i>=40 and i<=47:
|
||||
c=i-40
|
||||
self.sgr=(self.sgr&0x00ffff)|(c<<16)
|
||||
# else:
|
||||
# print "CSI sgr ignore",l,i
|
||||
# print 'sgr: %r %x'%(l,self.sgr)
|
||||
def csi_r(self,l):
|
||||
if len(l)<2: l=[0,self.height]
|
||||
self.st=min(self.height-1,l[0]-1)
|
||||
self.sb=min(self.height-1,l[1]-1)
|
||||
self.sb=max(self.st,self.sb)
|
||||
def csi_s(self,l):
|
||||
self.esc_save(0)
|
||||
def csi_u(self,l):
|
||||
self.esc_restore(0)
|
||||
def escape(self):
|
||||
e=self.buf
|
||||
if len(e)>32:
|
||||
# print "error %r"%e
|
||||
self.buf=""
|
||||
elif e in self.esc_seq:
|
||||
self.esc_seq[e](e)
|
||||
self.buf=""
|
||||
else:
|
||||
for r,f in self.esc_re:
|
||||
mo=r.match(e)
|
||||
if mo:
|
||||
f(e,mo)
|
||||
self.buf=""
|
||||
break
|
||||
# if self.buf=='': print "ESC %r\n"%e
|
||||
def write(self,s):
|
||||
for i in s:
|
||||
if len(self.buf) or (i in self.esc_seq):
|
||||
self.buf+=i
|
||||
self.escape()
|
||||
elif i == '\x1b':
|
||||
self.buf+=i
|
||||
else:
|
||||
self.echo(i)
|
||||
def read(self):
|
||||
b=self.outbuf
|
||||
self.outbuf=""
|
||||
return b
|
||||
def dump(self):
|
||||
r=''
|
||||
for i in self.scr:
|
||||
r+=chr(i&255)
|
||||
return r
|
||||
def dumplatin1(self):
|
||||
return self.dump().translate(self.trl1)
|
||||
def dumphtml(self,color=1):
|
||||
h=self.height
|
||||
w=self.width
|
||||
r=""
|
||||
span=""
|
||||
span_bg,span_fg=-1,-1
|
||||
for i in range(h*w):
|
||||
q,c=divmod(self.scr[i],256)
|
||||
if color:
|
||||
bg,fg=divmod(q,256)
|
||||
else:
|
||||
bg,fg=0,7
|
||||
if i==self.cy*w+self.cx:
|
||||
bg,fg=1,7
|
||||
if (bg!=span_bg or fg!=span_fg or i==h*w-1):
|
||||
if len(span):
|
||||
r+='<span class="f%d b%d">%s</span>'%(span_fg,span_bg,cgi.escape(span.translate(self.trhtml)))
|
||||
span=""
|
||||
span_bg,span_fg=bg,fg
|
||||
span+=chr(c)
|
||||
if i%w==w-1:
|
||||
span+='\n'
|
||||
r='<?xml version="1.0" encoding="ISO-8859-1"?><pre class="term">%s</pre>'%r
|
||||
if self.last_html==r:
|
||||
return '<?xml version="1.0"?><idem></idem>'
|
||||
else:
|
||||
self.last_html=r
|
||||
# print self
|
||||
return r
|
||||
def __repr__(self):
|
||||
d=self.dumplatin1()
|
||||
r=""
|
||||
for i in range(self.height):
|
||||
r+="|%s|\n"%d[self.width*i:self.width*(i+1)]
|
||||
return r
|
||||
|
||||
class SynchronizedMethod:
|
||||
def __init__(self,lock,orig):
|
||||
self.lock=lock
|
||||
self.orig=orig
|
||||
def __call__(self,*l):
|
||||
self.lock.acquire()
|
||||
r=self.orig(*l)
|
||||
self.lock.release()
|
||||
return r
|
||||
|
||||
class Multiplex:
|
||||
def __init__(self,cmd=None):
|
||||
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
|
||||
self.cmd=cmd
|
||||
self.proc={}
|
||||
self.lock=threading.RLock()
|
||||
self.thread=threading.Thread(target=self.loop)
|
||||
self.alive=1
|
||||
# synchronize methods
|
||||
for name in ['create','fds','proc_read','proc_write','dump','die','run']:
|
||||
orig=getattr(self,name)
|
||||
setattr(self,name,SynchronizedMethod(self.lock,orig))
|
||||
self.thread.start()
|
||||
def create(self,w=80,h=25):
|
||||
pid,fd=pty.fork()
|
||||
if pid==0:
|
||||
try:
|
||||
fdl=[int(i) for i in os.listdir('/proc/self/fd')]
|
||||
except OSError:
|
||||
fdl=range(256)
|
||||
for i in [i for i in fdl if i>2]:
|
||||
try:
|
||||
os.close(i)
|
||||
except OSError:
|
||||
pass
|
||||
if self.cmd:
|
||||
cmd=['/bin/sh','-c',self.cmd]
|
||||
elif os.getuid()==0:
|
||||
cmd=['/bin/login']
|
||||
else:
|
||||
sys.stdout.write("Login: ")
|
||||
login=sys.stdin.readline().strip()
|
||||
if re.match('^[0-9A-Za-z-_. ]+$',login):
|
||||
cmd=['ssh']
|
||||
cmd+=['-oPreferredAuthentications=keyboard-interactive,password']
|
||||
cmd+=['-oNoHostAuthenticationForLocalhost=yes']
|
||||
cmd+=['-oLogLevel=FATAL']
|
||||
cmd+=['-F/dev/null','-l',login,'localhost']
|
||||
else:
|
||||
os._exit(0)
|
||||
env={}
|
||||
env["COLUMNS"]=str(w)
|
||||
env["LINES"]=str(h)
|
||||
env["TERM"]="linux"
|
||||
env["PATH"]=os.environ['PATH']
|
||||
os.execvpe(cmd[0],cmd,env)
|
||||
else:
|
||||
fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK)
|
||||
# python bug http://python.org/sf/1112949 on amd64
|
||||
fcntl.ioctl(fd, struct.unpack('i',struct.pack('I',termios.TIOCSWINSZ))[0], struct.pack("HHHH",h,w,0,0))
|
||||
self.proc[fd]={'pid':pid,'term':Terminal(w,h),'buf':'','time':time.time()}
|
||||
return fd
|
||||
def die(self):
|
||||
self.alive=0
|
||||
def run(self):
|
||||
return self.alive
|
||||
def fds(self):
|
||||
return self.proc.keys()
|
||||
def proc_kill(self,fd):
|
||||
if fd in self.proc:
|
||||
self.proc[fd]['time']=0
|
||||
t=time.time()
|
||||
for i in self.proc.keys():
|
||||
t0=self.proc[i]['time']
|
||||
if (t-t0)>120:
|
||||
try:
|
||||
os.close(i)
|
||||
os.kill(self.proc[i]['pid'],signal.SIGTERM)
|
||||
except (IOError,OSError):
|
||||
pass
|
||||
del self.proc[i]
|
||||
def proc_read(self,fd):
|
||||
try:
|
||||
t=self.proc[fd]['term']
|
||||
t.write(os.read(fd,65536))
|
||||
reply=t.read()
|
||||
if reply:
|
||||
os.write(fd,reply)
|
||||
self.proc[fd]['time']=time.time()
|
||||
except (KeyError,IOError,OSError):
|
||||
self.proc_kill(fd)
|
||||
def proc_write(self,fd,s):
|
||||
try:
|
||||
os.write(fd,s)
|
||||
except (IOError,OSError):
|
||||
self.proc_kill(fd)
|
||||
def dump(self,fd,color=1):
|
||||
try:
|
||||
return self.proc[fd]['term'].dumphtml(color)
|
||||
except KeyError:
|
||||
return False
|
||||
def loop(self):
|
||||
while self.run():
|
||||
fds=self.fds()
|
||||
i,o,e=select.select(fds, [], [], 1.0)
|
||||
for fd in i:
|
||||
self.proc_read(fd)
|
||||
if len(i):
|
||||
time.sleep(0.002)
|
||||
for i in self.proc.keys():
|
||||
try:
|
||||
os.close(i)
|
||||
os.kill(self.proc[i]['pid'],signal.SIGTERM)
|
||||
except (IOError,OSError):
|
||||
pass
|
||||
|
||||
class AjaxTerm:
|
||||
def __init__(self,cmd=None,index_file='ajaxterm.html'):
|
||||
self.files={}
|
||||
for i in ['css','html','js']:
|
||||
for j in glob.glob('*.%s'%i):
|
||||
self.files[j]=file(j).read()
|
||||
self.files['index']=file(index_file).read()
|
||||
self.mime = mimetypes.types_map.copy()
|
||||
self.mime['.html']= 'text/html; charset=UTF-8'
|
||||
self.multi = Multiplex(cmd)
|
||||
self.session = {}
|
||||
def __call__(self, environ, start_response):
|
||||
req = qweb.QWebRequest(environ, start_response,session=None)
|
||||
if req.PATH_INFO.endswith('/u'):
|
||||
s=req.REQUEST["s"]
|
||||
k=req.REQUEST["k"]
|
||||
c=req.REQUEST["c"]
|
||||
w=req.REQUEST.int("w")
|
||||
h=req.REQUEST.int("h")
|
||||
if s in self.session:
|
||||
term=self.session[s]
|
||||
else:
|
||||
if not (w>2 and w<256 and h>2 and h<100):
|
||||
w,h=80,25
|
||||
term=self.session[s]=self.multi.create(w,h)
|
||||
if k:
|
||||
self.multi.proc_write(term,k)
|
||||
time.sleep(0.002)
|
||||
dump=self.multi.dump(term,c)
|
||||
req.response_headers['Content-Type']='text/xml'
|
||||
if isinstance(dump,str):
|
||||
req.write(dump)
|
||||
req.response_gzencode=1
|
||||
else:
|
||||
del self.session[s]
|
||||
req.write('<?xml version="1.0"?><idem></idem>')
|
||||
# print "sessions %r"%self.session
|
||||
else:
|
||||
n=os.path.basename(req.PATH_INFO)
|
||||
if n in self.files:
|
||||
req.response_headers['Content-Type'] = self.mime.get(os.path.splitext(n)[1].lower(), 'application/octet-stream')
|
||||
req.write(self.files[n])
|
||||
else:
|
||||
req.response_headers['Content-Type'] = 'text/html; charset=UTF-8'
|
||||
req.write(self.files['index'])
|
||||
return req
|
||||
|
||||
def main():
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option("-p", "--port", dest="port", default="8022", help="Set the TCP port (default: 8022)")
|
||||
parser.add_option("-c", "--command", dest="cmd", default=None,help="set the command (default: /bin/login or ssh localhost)")
|
||||
parser.add_option("-l", "--log", action="store_true", dest="log",default=0,help="log requests to stderr (default: quiet mode)")
|
||||
parser.add_option("-d", "--daemon", action="store_true", dest="daemon", default=0, help="run as daemon in the background")
|
||||
parser.add_option("-P", "--pidfile",dest="pidfile",default="/var/run/ajaxterm.pid",help="set the pidfile (default: /var/run/ajaxterm.pid)")
|
||||
parser.add_option("-i", "--index", dest="index_file", default="ajaxterm.html",help="default index file (default: ajaxterm.html)")
|
||||
parser.add_option("-u", "--uid", dest="uid", help="Set the daemon's user id")
|
||||
(o, a) = parser.parse_args()
|
||||
if o.daemon:
|
||||
pid=os.fork()
|
||||
if pid == 0:
|
||||
#os.setsid() ?
|
||||
os.setpgrp()
|
||||
nullin = file('/dev/null', 'r')
|
||||
nullout = file('/dev/null', 'w')
|
||||
os.dup2(nullin.fileno(), sys.stdin.fileno())
|
||||
os.dup2(nullout.fileno(), sys.stdout.fileno())
|
||||
os.dup2(nullout.fileno(), sys.stderr.fileno())
|
||||
if os.getuid()==0 and o.uid:
|
||||
try:
|
||||
os.setuid(int(o.uid))
|
||||
except:
|
||||
os.setuid(pwd.getpwnam(o.uid).pw_uid)
|
||||
else:
|
||||
try:
|
||||
file(o.pidfile,'w+').write(str(pid)+'\n')
|
||||
except:
|
||||
pass
|
||||
print 'AjaxTerm at http://localhost:%s/ pid: %d' % (o.port,pid)
|
||||
sys.exit(0)
|
||||
else:
|
||||
print 'AjaxTerm at http://localhost:%s/' % o.port
|
||||
at=AjaxTerm(o.cmd,o.index_file)
|
||||
# f=lambda:os.system('firefox http://localhost:%s/&'%o.port)
|
||||
# qweb.qweb_wsgi_autorun(at,ip='localhost',port=int(o.port),threaded=0,log=o.log,callback_ready=None)
|
||||
try:
|
||||
qweb.QWebWSGIServer(at,ip='localhost',port=int(o.port),threaded=0,log=o.log).serve_forever()
|
||||
except KeyboardInterrupt,e:
|
||||
sys.excepthook(*sys.exc_info())
|
||||
at.multi.die()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
32
ajaxterm/ajaxterm/configure
vendored
32
ajaxterm/ajaxterm/configure
vendored
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import optparse,os
|
||||
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option("", "--prefix", dest="prefix",default="/usr/local",help="installation prefix (default: /usr/local)")
|
||||
parser.add_option("", "--confdir", dest="confdir", default="/etc",help="configuration files directory prefix (default: /etc)")
|
||||
parser.add_option("", "--port", dest="port", default="8022", help="set the listening TCP port (default: 8022)")
|
||||
parser.add_option("", "--command", dest="cmd", default=None,help="set the command (default: /bin/login or ssh localhost)")
|
||||
(o, a) = parser.parse_args()
|
||||
|
||||
print "Configuring prefix=",o.prefix," port=",o.port
|
||||
|
||||
etc=o.confdir
|
||||
port=o.port
|
||||
cmd=o.cmd
|
||||
bin=os.path.join(o.prefix,"bin")
|
||||
lib=os.path.join(o.prefix,"share/ajaxterm")
|
||||
man=os.path.join(o.prefix,"share/man/man1")
|
||||
|
||||
file("ajaxterm.bin","w").write(file("configure.ajaxterm.bin").read()%locals())
|
||||
file("Makefile","w").write(file("configure.makefile").read()%locals())
|
||||
|
||||
if os.path.isfile("/etc/gentoo-release"):
|
||||
file("ajaxterm.initd","w").write(file("configure.initd.gentoo").read()%locals())
|
||||
elif os.path.isfile("/etc/fedora-release") or os.path.isfile("/etc/redhat-release"):
|
||||
file("ajaxterm.initd","w").write(file("configure.initd.redhat").read()%locals())
|
||||
else:
|
||||
file("ajaxterm.initd","w").write(file("configure.initd.debian").read()%locals())
|
||||
|
||||
os.system("chmod a+x ajaxterm.bin")
|
||||
os.system("chmod a+x ajaxterm.initd")
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/sbin/runscript
|
||||
|
||||
# AjaxTerm Gentoo script, 08 May 2006 Mark Gillespie
|
||||
|
||||
DAEMON=%(bin)s/ajaxterm
|
||||
PORT=%(port)s
|
||||
PIDFILE=/var/run/ajaxterm.pid
|
||||
|
||||
depend()
|
||||
{
|
||||
need net
|
||||
}
|
||||
|
||||
start()
|
||||
{
|
||||
ebegin "Starting AjaxTerm on port $PORT"
|
||||
start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON -- --daemon --port=$PORT --uid=nobody
|
||||
eend $?
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
ebegin "Stopping AjaxTerm"
|
||||
start-stop-daemon --stop --pidfile $PIDFILE
|
||||
rm -f $PIDFILE
|
||||
eend $?
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
#
|
||||
# ajaxterm Startup script for ajaxterm
|
||||
#
|
||||
# chkconfig: - 99 99
|
||||
# description: Ajaxterm is a yadda yadda yadda
|
||||
# processname: ajaxterm
|
||||
# pidfile: /var/run/ajaxterm.pid
|
||||
# version: 1.0 Kevin Reichhart - ajaxterminit at lastname dot org
|
||||
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
if [ -f /etc/sysconfig/ajaxterm ]; then
|
||||
. /etc/sysconfig/ajaxterm
|
||||
fi
|
||||
|
||||
ajaxterm=/usr/local/bin/ajaxterm
|
||||
prog=ajaxterm
|
||||
pidfile=${PIDFILE-/var/run/ajaxterm.pid}
|
||||
lockfile=${LOCKFILE-/var/lock/subsys/ajaxterm}
|
||||
port=${PORT-8022}
|
||||
user=${xUSER-nobody}
|
||||
RETVAL=0
|
||||
|
||||
|
||||
start() {
|
||||
echo -n $"Starting $prog: "
|
||||
daemon $ajaxterm --daemon --port=$port --uid=$user $OPTIONS
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL = 0 ] && touch ${lockfile}
|
||||
return $RETVAL
|
||||
}
|
||||
stop() {
|
||||
echo -n $"Stopping $prog: "
|
||||
killproc $ajaxterm
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
|
||||
}
|
||||
reload() {
|
||||
echo -n $"Reloading $prog: "
|
||||
killproc $ajaxterm -HUP
|
||||
RETVAL=$?
|
||||
echo
|
||||
}
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
status)
|
||||
status python ajaxterm
|
||||
RETVAL=$?
|
||||
;;
|
||||
restart)
|
||||
stop
|
||||
start
|
||||
;;
|
||||
condrestart)
|
||||
if [ -f ${pidfile} ] ; then
|
||||
stop
|
||||
start
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $prog {start|stop|restart|condrestart}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit $RETVAL
|
||||
@@ -1,20 +0,0 @@
|
||||
build:
|
||||
true
|
||||
|
||||
install:
|
||||
install -d "%(bin)s"
|
||||
install -d "%(lib)s"
|
||||
install ajaxterm.bin "%(bin)s/ajaxterm"
|
||||
install ajaxterm.initd "%(etc)s/init.d/ajaxterm"
|
||||
install -m 644 ajaxterm.css ajaxterm.html ajaxterm.js qweb.py sarissa.js sarissa_dhtml.js "%(lib)s"
|
||||
install -m 755 ajaxterm.py "%(lib)s"
|
||||
gzip --best -c ajaxterm.1 > ajaxterm.1.gz
|
||||
install -d "%(man)s"
|
||||
install ajaxterm.1.gz "%(man)s"
|
||||
|
||||
clean:
|
||||
rm ajaxterm.bin
|
||||
rm ajaxterm.initd
|
||||
rm ajaxterm.1.gz
|
||||
rm Makefile
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,653 +0,0 @@
|
||||
/**
|
||||
* ====================================================================
|
||||
* About
|
||||
* ====================================================================
|
||||
* Sarissa is an ECMAScript library acting as a cross-browser wrapper for native XML APIs.
|
||||
* The library supports Gecko based browsers like Mozilla and Firefox,
|
||||
* Internet Explorer (5.5+ with MSXML3.0+), Konqueror, Safari and a little of Opera
|
||||
* @version 0.9.6.1
|
||||
* @author: Manos Batsis, mailto: mbatsis at users full stop sourceforge full stop net
|
||||
* ====================================================================
|
||||
* Licence
|
||||
* ====================================================================
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 or
|
||||
* the GNU Lesser General Public License version 2.1 as published by
|
||||
* the Free Software Foundation (your choice between the two).
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License or GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* or GNU Lesser General Public License along with this program; if not,
|
||||
* write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* or visit http://www.gnu.org
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* <p>Sarissa is a utility class. Provides "static" methods for DOMDocument and
|
||||
* XMLHTTP objects, DOM Node serializatrion to XML strings and other goodies.</p>
|
||||
* @constructor
|
||||
*/
|
||||
function Sarissa(){};
|
||||
/** @private */
|
||||
Sarissa.PARSED_OK = "Document contains no parsing errors";
|
||||
/**
|
||||
* Tells you whether transformNode and transformNodeToObject are available. This functionality
|
||||
* is contained in sarissa_ieemu_xslt.js and is deprecated. If you want to control XSLT transformations
|
||||
* use the XSLTProcessor
|
||||
* @deprecated
|
||||
* @type boolean
|
||||
*/
|
||||
Sarissa.IS_ENABLED_TRANSFORM_NODE = false;
|
||||
/**
|
||||
* tells you whether XMLHttpRequest (or equivalent) is available
|
||||
* @type boolean
|
||||
*/
|
||||
Sarissa.IS_ENABLED_XMLHTTP = false;
|
||||
/**
|
||||
* tells you whether selectNodes/selectSingleNode is available
|
||||
* @type boolean
|
||||
*/
|
||||
Sarissa.IS_ENABLED_SELECT_NODES = false;
|
||||
var _sarissa_iNsCounter = 0;
|
||||
var _SARISSA_IEPREFIX4XSLPARAM = "";
|
||||
var _SARISSA_HAS_DOM_IMPLEMENTATION = document.implementation && true;
|
||||
var _SARISSA_HAS_DOM_CREATE_DOCUMENT = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.createDocument;
|
||||
var _SARISSA_HAS_DOM_FEATURE = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.hasFeature;
|
||||
var _SARISSA_IS_MOZ = _SARISSA_HAS_DOM_CREATE_DOCUMENT && _SARISSA_HAS_DOM_FEATURE;
|
||||
var _SARISSA_IS_SAFARI = (navigator.userAgent && navigator.vendor && (navigator.userAgent.toLowerCase().indexOf("applewebkit") != -1 || navigator.vendor.indexOf("Apple") != -1));
|
||||
var _SARISSA_IS_IE = document.all && window.ActiveXObject && navigator.userAgent.toLowerCase().indexOf("msie") > -1 && navigator.userAgent.toLowerCase().indexOf("opera") == -1;
|
||||
if(!window.Node || !window.Node.ELEMENT_NODE){
|
||||
var Node = {ELEMENT_NODE: 1, ATTRIBUTE_NODE: 2, TEXT_NODE: 3, CDATA_SECTION_NODE: 4, ENTITY_REFERENCE_NODE: 5, ENTITY_NODE: 6, PROCESSING_INSTRUCTION_NODE: 7, COMMENT_NODE: 8, DOCUMENT_NODE: 9, DOCUMENT_TYPE_NODE: 10, DOCUMENT_FRAGMENT_NODE: 11, NOTATION_NODE: 12};
|
||||
};
|
||||
|
||||
// IE initialization
|
||||
if(_SARISSA_IS_IE){
|
||||
// for XSLT parameter names, prefix needed by IE
|
||||
_SARISSA_IEPREFIX4XSLPARAM = "xsl:";
|
||||
// used to store the most recent ProgID available out of the above
|
||||
var _SARISSA_DOM_PROGID = "";
|
||||
var _SARISSA_XMLHTTP_PROGID = "";
|
||||
/**
|
||||
* Called when the Sarissa_xx.js file is parsed, to pick most recent
|
||||
* ProgIDs for IE, then gets destroyed.
|
||||
* @param idList an array of MSXML PROGIDs from which the most recent will be picked for a given object
|
||||
* @param enabledList an array of arrays where each array has two items; the index of the PROGID for which a certain feature is enabled
|
||||
*/
|
||||
pickRecentProgID = function (idList, enabledList){
|
||||
// found progID flag
|
||||
var bFound = false;
|
||||
for(var i=0; i < idList.length && !bFound; i++){
|
||||
try{
|
||||
var oDoc = new ActiveXObject(idList[i]);
|
||||
o2Store = idList[i];
|
||||
bFound = true;
|
||||
for(var j=0;j<enabledList.length;j++)
|
||||
if(i <= enabledList[j][1])
|
||||
Sarissa["IS_ENABLED_"+enabledList[j][0]] = true;
|
||||
}catch (objException){
|
||||
// trap; try next progID
|
||||
};
|
||||
};
|
||||
if (!bFound)
|
||||
throw "Could not retreive a valid progID of Class: " + idList[idList.length-1]+". (original exception: "+e+")";
|
||||
idList = null;
|
||||
return o2Store;
|
||||
};
|
||||
// pick best available MSXML progIDs
|
||||
_SARISSA_DOM_PROGID = pickRecentProgID(["Msxml2.DOMDocument.5.0", "Msxml2.DOMDocument.4.0", "Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"], [["SELECT_NODES", 2],["TRANSFORM_NODE", 2]]);
|
||||
_SARISSA_XMLHTTP_PROGID = pickRecentProgID(["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"], [["XMLHTTP", 4]]);
|
||||
_SARISSA_THREADEDDOM_PROGID = pickRecentProgID(["Msxml2.FreeThreadedDOMDocument.5.0", "MSXML2.FreeThreadedDOMDocument.4.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);
|
||||
_SARISSA_XSLTEMPLATE_PROGID = pickRecentProgID(["Msxml2.XSLTemplate.5.0", "Msxml2.XSLTemplate.4.0", "MSXML2.XSLTemplate.3.0"], [["XSLTPROC", 2]]);
|
||||
// we dont need this anymore
|
||||
pickRecentProgID = null;
|
||||
//============================================
|
||||
// Factory methods (IE)
|
||||
//============================================
|
||||
// see non-IE version
|
||||
Sarissa.getDomDocument = function(sUri, sName){
|
||||
var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
|
||||
// if a root tag name was provided, we need to load it in the DOM
|
||||
// object
|
||||
if (sName){
|
||||
// if needed, create an artifical namespace prefix the way Moz
|
||||
// does
|
||||
if (sUri){
|
||||
oDoc.loadXML("<a" + _sarissa_iNsCounter + ":" + sName + " xmlns:a" + _sarissa_iNsCounter + "=\"" + sUri + "\" />");
|
||||
// don't use the same prefix again
|
||||
++_sarissa_iNsCounter;
|
||||
}
|
||||
else
|
||||
oDoc.loadXML("<" + sName + "/>");
|
||||
};
|
||||
return oDoc;
|
||||
};
|
||||
// see non-IE version
|
||||
Sarissa.getParseErrorText = function (oDoc) {
|
||||
var parseErrorText = Sarissa.PARSED_OK;
|
||||
if(oDoc.parseError != 0){
|
||||
parseErrorText = "XML Parsing Error: " + oDoc.parseError.reason +
|
||||
"\nLocation: " + oDoc.parseError.url +
|
||||
"\nLine Number " + oDoc.parseError.line + ", Column " +
|
||||
oDoc.parseError.linepos +
|
||||
":\n" + oDoc.parseError.srcText +
|
||||
"\n";
|
||||
for(var i = 0; i < oDoc.parseError.linepos;i++){
|
||||
parseErrorText += "-";
|
||||
};
|
||||
parseErrorText += "^\n";
|
||||
};
|
||||
return parseErrorText;
|
||||
};
|
||||
// see non-IE version
|
||||
Sarissa.setXpathNamespaces = function(oDoc, sNsSet) {
|
||||
oDoc.setProperty("SelectionLanguage", "XPath");
|
||||
oDoc.setProperty("SelectionNamespaces", sNsSet);
|
||||
};
|
||||
/**
|
||||
* Basic implementation of Mozilla's XSLTProcessor for IE.
|
||||
* Reuses the same XSLT stylesheet for multiple transforms
|
||||
* @constructor
|
||||
*/
|
||||
XSLTProcessor = function(){
|
||||
this.template = new ActiveXObject(_SARISSA_XSLTEMPLATE_PROGID);
|
||||
this.processor = null;
|
||||
};
|
||||
/**
|
||||
* Impoprts the given XSLT DOM and compiles it to a reusable transform
|
||||
* @argument xslDoc The XSLT DOMDocument to import
|
||||
*/
|
||||
XSLTProcessor.prototype.importStylesheet = function(xslDoc){
|
||||
// convert stylesheet to free threaded
|
||||
var converted = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID);
|
||||
converted.loadXML(xslDoc.xml);
|
||||
this.template.stylesheet = converted;
|
||||
this.processor = this.template.createProcessor();
|
||||
// (re)set default param values
|
||||
this.paramsSet = new Array();
|
||||
};
|
||||
/**
|
||||
* Transform the given XML DOM
|
||||
* @argument sourceDoc The XML DOMDocument to transform
|
||||
* @return The transformation result as a DOM Document
|
||||
*/
|
||||
XSLTProcessor.prototype.transformToDocument = function(sourceDoc){
|
||||
this.processor.input = sourceDoc;
|
||||
var outDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
|
||||
this.processor.output = outDoc;
|
||||
this.processor.transform();
|
||||
return outDoc;
|
||||
};
|
||||
/**
|
||||
* Set global XSLT parameter of the imported stylesheet
|
||||
* @argument nsURI The parameter namespace URI
|
||||
* @argument name The parameter base name
|
||||
* @argument value The new parameter value
|
||||
*/
|
||||
XSLTProcessor.prototype.setParameter = function(nsURI, name, value){
|
||||
/* nsURI is optional but cannot be null */
|
||||
if(nsURI){
|
||||
this.processor.addParameter(name, value, nsURI);
|
||||
}else{
|
||||
this.processor.addParameter(name, value);
|
||||
};
|
||||
/* update updated params for getParameter */
|
||||
if(!this.paramsSet[""+nsURI]){
|
||||
this.paramsSet[""+nsURI] = new Array();
|
||||
};
|
||||
this.paramsSet[""+nsURI][name] = value;
|
||||
};
|
||||
/**
|
||||
* Gets a parameter if previously set by setParameter. Returns null
|
||||
* otherwise
|
||||
* @argument name The parameter base name
|
||||
* @argument value The new parameter value
|
||||
* @return The parameter value if reviously set by setParameter, null otherwise
|
||||
*/
|
||||
XSLTProcessor.prototype.getParameter = function(nsURI, name){
|
||||
nsURI = nsURI || "";
|
||||
if(nsURI in this.paramsSet && name in this.paramsSet[nsURI]){
|
||||
return this.paramsSet[nsURI][name];
|
||||
}else{
|
||||
return null;
|
||||
};
|
||||
};
|
||||
}
|
||||
else{ /* end IE initialization, try to deal with real browsers now ;-) */
|
||||
if(_SARISSA_HAS_DOM_CREATE_DOCUMENT){
|
||||
/**
|
||||
* <p>Ensures the document was loaded correctly, otherwise sets the
|
||||
* parseError to -1 to indicate something went wrong. Internal use</p>
|
||||
* @private
|
||||
*/
|
||||
Sarissa.__handleLoad__ = function(oDoc){
|
||||
if (!oDoc.documentElement || oDoc.documentElement.tagName == "parsererror")
|
||||
oDoc.parseError = -1;
|
||||
Sarissa.__setReadyState__(oDoc, 4);
|
||||
};
|
||||
/**
|
||||
* <p>Attached by an event handler to the load event. Internal use.</p>
|
||||
* @private
|
||||
*/
|
||||
_sarissa_XMLDocument_onload = function(){
|
||||
Sarissa.__handleLoad__(this);
|
||||
};
|
||||
/**
|
||||
* <p>Sets the readyState property of the given DOM Document object.
|
||||
* Internal use.</p>
|
||||
* @private
|
||||
* @argument oDoc the DOM Document object to fire the
|
||||
* readystatechange event
|
||||
* @argument iReadyState the number to change the readystate property to
|
||||
*/
|
||||
Sarissa.__setReadyState__ = function(oDoc, iReadyState){
|
||||
oDoc.readyState = iReadyState;
|
||||
if (oDoc.onreadystatechange != null && typeof oDoc.onreadystatechange == "function")
|
||||
oDoc.onreadystatechange();
|
||||
};
|
||||
Sarissa.getDomDocument = function(sUri, sName){
|
||||
var oDoc = document.implementation.createDocument(sUri?sUri:"", sName?sName:"", null);
|
||||
oDoc.addEventListener("load", _sarissa_XMLDocument_onload, false);
|
||||
return oDoc;
|
||||
};
|
||||
if(window.XMLDocument){
|
||||
/**
|
||||
* <p>Emulate IE's onreadystatechange attribute</p>
|
||||
*/
|
||||
try {
|
||||
XMLDocument.prototype.onreadystatechange = null;
|
||||
} catch(err) {
|
||||
// May fail on Chrome 43+
|
||||
}
|
||||
/**
|
||||
* <p>Emulates IE's readyState property, which always gives an integer from 0 to 4:</p>
|
||||
* <ul><li>1 == LOADING,</li>
|
||||
* <li>2 == LOADED,</li>
|
||||
* <li>3 == INTERACTIVE,</li>
|
||||
* <li>4 == COMPLETED</li></ul>
|
||||
*/
|
||||
/* Doesn't work in Firefox 3.6
|
||||
XMLDocument.prototype.readyState = 0;
|
||||
*/
|
||||
/**
|
||||
* <p>Emulate IE's parseError attribute</p>
|
||||
*/
|
||||
XMLDocument.prototype.parseError = 0;
|
||||
|
||||
// NOTE: setting async to false will only work with documents
|
||||
// called over HTTP (meaning a server), not the local file system,
|
||||
// unless you are using Moz 1.4+.
|
||||
// BTW the try>catch block is for 1.4; I haven't found a way to check if
|
||||
// the property is implemented without
|
||||
// causing an error and I dont want to use user agent stuff for that...
|
||||
var _SARISSA_SYNC_NON_IMPLEMENTED = false;// ("async" in XMLDocument.prototype) ? false: true;
|
||||
/**
|
||||
* <p>Keeps a handle to the original load() method. Internal use and only
|
||||
* if Mozilla version is lower than 1.4</p>
|
||||
* @private
|
||||
*/
|
||||
XMLDocument.prototype._sarissa_load = XMLDocument.prototype.load;
|
||||
|
||||
/**
|
||||
* <p>Overrides the original load method to provide synchronous loading for
|
||||
* Mozilla versions prior to 1.4, using an XMLHttpRequest object (if
|
||||
* async is set to false)</p>
|
||||
* @returns the DOM Object as it was before the load() call (may be empty)
|
||||
*/
|
||||
XMLDocument.prototype.load = function(sURI) {
|
||||
var oDoc = document.implementation.createDocument("", "", null);
|
||||
Sarissa.copyChildNodes(this, oDoc);
|
||||
this.parseError = 0;
|
||||
Sarissa.__setReadyState__(this, 1);
|
||||
try {
|
||||
if(this.async == false && _SARISSA_SYNC_NON_IMPLEMENTED) {
|
||||
var tmp = new XMLHttpRequest();
|
||||
tmp.open("GET", sURI, false);
|
||||
tmp.send(null);
|
||||
Sarissa.__setReadyState__(this, 2);
|
||||
Sarissa.copyChildNodes(tmp.responseXML, this);
|
||||
Sarissa.__setReadyState__(this, 3);
|
||||
}
|
||||
else {
|
||||
this._sarissa_load(sURI);
|
||||
};
|
||||
}
|
||||
catch (objException) {
|
||||
this.parseError = -1;
|
||||
}
|
||||
finally {
|
||||
if(this.async == false){
|
||||
Sarissa.__handleLoad__(this);
|
||||
};
|
||||
};
|
||||
return oDoc;
|
||||
};
|
||||
|
||||
|
||||
}//if(window.XMLDocument)
|
||||
else if(document.implementation && document.implementation.hasFeature && document.implementation.hasFeature('LS', '3.0')){
|
||||
Document.prototype.async = true;
|
||||
Document.prototype.onreadystatechange = null;
|
||||
Document.prototype.parseError = 0;
|
||||
Document.prototype.load = function(sURI) {
|
||||
var parser = document.implementation.createLSParser(this.async ? document.implementation.MODE_ASYNCHRONOUS : document.implementation.MODE_SYNCHRONOUS, null);
|
||||
if(this.async){
|
||||
var self = this;
|
||||
parser.addEventListener("load",
|
||||
function(e) {
|
||||
self.readyState = 4;
|
||||
Sarissa.copyChildNodes(e.newDocument, self.documentElement, false);
|
||||
self.onreadystatechange.call();
|
||||
},
|
||||
false);
|
||||
};
|
||||
try {
|
||||
var oDoc = parser.parseURI(sURI);
|
||||
}
|
||||
catch(e){
|
||||
this.parseError = -1;
|
||||
};
|
||||
if(!this.async)
|
||||
Sarissa.copyChildNodes(oDoc, this.documentElement, false);
|
||||
return oDoc;
|
||||
};
|
||||
/**
|
||||
* <p>Factory method to obtain a new DOM Document object</p>
|
||||
* @argument sUri the namespace of the root node (if any)
|
||||
* @argument sUri the local name of the root node (if any)
|
||||
* @returns a new DOM Document
|
||||
*/
|
||||
Sarissa.getDomDocument = function(sUri, sName){
|
||||
return document.implementation.createDocument(sUri?sUri:"", sName?sName:"", null);
|
||||
};
|
||||
};
|
||||
};//if(_SARISSA_HAS_DOM_CREATE_DOCUMENT)
|
||||
};
|
||||
//==========================================
|
||||
// Common stuff
|
||||
//==========================================
|
||||
if(!window.DOMParser){
|
||||
/*
|
||||
* DOMParser is a utility class, used to construct DOMDocuments from XML strings
|
||||
* @constructor
|
||||
*/
|
||||
DOMParser = function() {
|
||||
};
|
||||
if(_SARISSA_IS_SAFARI){
|
||||
/**
|
||||
* Construct a new DOM Document from the given XMLstring
|
||||
* @param sXml the given XML string
|
||||
* @param contentType the content type of the document the given string represents (one of text/xml, application/xml, application/xhtml+xml).
|
||||
* @return a new DOM Document from the given XML string
|
||||
*/
|
||||
DOMParser.prototype.parseFromString = function(sXml, contentType){
|
||||
if(contentType.toLowerCase() != "application/xml"){
|
||||
throw "Cannot handle content type: \"" + contentType + "\"";
|
||||
};
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("GET", "data:text/xml;charset=utf-8," + encodeURIComponent(str), false);
|
||||
xmlhttp.send(null);
|
||||
return xmlhttp.responseXML;
|
||||
};
|
||||
}else if(Sarissa.getDomDocument && Sarissa.getDomDocument() && "loadXML" in Sarissa.getDomDocument()){
|
||||
DOMParser.prototype.parseFromString = function(sXml, contentType){
|
||||
var doc = Sarissa.getDomDocument();
|
||||
doc.loadXML(sXml);
|
||||
return doc;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if(window.XMLHttpRequest){
|
||||
Sarissa.IS_ENABLED_XMLHTTP = true;
|
||||
}
|
||||
else if(_SARISSA_IS_IE){
|
||||
/**
|
||||
* Emulate XMLHttpRequest
|
||||
* @constructor
|
||||
*/
|
||||
XMLHttpRequest = function() {
|
||||
return new ActiveXObject(_SARISSA_XMLHTTP_PROGID);
|
||||
};
|
||||
Sarissa.IS_ENABLED_XMLHTTP = true;
|
||||
};
|
||||
|
||||
if(!window.document.importNode && _SARISSA_IS_IE){
|
||||
try{
|
||||
/**
|
||||
* Implements importNode for the current window document in IE using innerHTML.
|
||||
* Testing showed that DOM was multiple times slower than innerHTML for this,
|
||||
* sorry folks. If you encounter trouble (who knows what IE does behind innerHTML)
|
||||
* please gimme a call.
|
||||
* @param oNode the Node to import
|
||||
* @param bChildren whether to include the children of oNode
|
||||
* @returns the imported node for further use
|
||||
*/
|
||||
window.document.importNode = function(oNode, bChildren){
|
||||
var importNode = document.createElement("div");
|
||||
if(bChildren)
|
||||
importNode.innerHTML = Sarissa.serialize(oNode);
|
||||
else
|
||||
importNode.innerHTML = Sarissa.serialize(oNode.cloneNode(false));
|
||||
return importNode.firstChild;
|
||||
};
|
||||
}catch(e){};
|
||||
};
|
||||
if(!Sarissa.getParseErrorText){
|
||||
/**
|
||||
* <p>Returns a human readable description of the parsing error. Usefull
|
||||
* for debugging. Tip: append the returned error string in a <pre>
|
||||
* element if you want to render it.</p>
|
||||
* <p>Many thanks to Christian Stocker for the initial patch.</p>
|
||||
* @argument oDoc The target DOM document
|
||||
* @returns The parsing error description of the target Document in
|
||||
* human readable form (preformated text)
|
||||
*/
|
||||
Sarissa.getParseErrorText = function (oDoc){
|
||||
var parseErrorText = Sarissa.PARSED_OK;
|
||||
if(oDoc && oDoc.parseError && oDoc.parseError != 0){
|
||||
/*moz*/
|
||||
if(oDoc.documentElement.tagName == "parsererror"){
|
||||
parseErrorText = oDoc.documentElement.firstChild.data;
|
||||
parseErrorText += "\n" + oDoc.documentElement.firstChild.nextSibling.firstChild.data;
|
||||
}/*konq*/
|
||||
else{
|
||||
parseErrorText = Sarissa.getText(oDoc.documentElement);/*.getElementsByTagName("h1")[0], false) + "\n";
|
||||
parseErrorText += Sarissa.getText(oDoc.documentElement.getElementsByTagName("body")[0], false) + "\n";
|
||||
parseErrorText += Sarissa.getText(oDoc.documentElement.getElementsByTagName("pre")[0], false);*/
|
||||
};
|
||||
};
|
||||
return parseErrorText;
|
||||
};
|
||||
};
|
||||
Sarissa.getText = function(oNode, deep){
|
||||
var s = "";
|
||||
var nodes = oNode.childNodes;
|
||||
for(var i=0; i < nodes.length; i++){
|
||||
var node = nodes[i];
|
||||
var nodeType = node.nodeType;
|
||||
if(nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE){
|
||||
s += node.data;
|
||||
}else if(deep == true
|
||||
&& (nodeType == Node.ELEMENT_NODE
|
||||
|| nodeType == Node.DOCUMENT_NODE
|
||||
|| nodeType == Node.DOCUMENT_FRAGMENT_NODE)){
|
||||
s += Sarissa.getText(node, true);
|
||||
};
|
||||
};
|
||||
return s;
|
||||
};
|
||||
if(window.XMLSerializer){
|
||||
/**
|
||||
* <p>Factory method to obtain the serialization of a DOM Node</p>
|
||||
* @returns the serialized Node as an XML string
|
||||
*/
|
||||
Sarissa.serialize = function(oDoc){
|
||||
var s = null;
|
||||
if(oDoc){
|
||||
s = oDoc.innerHTML?oDoc.innerHTML:(new XMLSerializer()).serializeToString(oDoc);
|
||||
};
|
||||
return s;
|
||||
};
|
||||
}else{
|
||||
if(Sarissa.getDomDocument && (Sarissa.getDomDocument("","foo", null)).xml){
|
||||
// see non-IE version
|
||||
Sarissa.serialize = function(oDoc) {
|
||||
var s = null;
|
||||
if(oDoc){
|
||||
s = oDoc.innerHTML?oDoc.innerHTML:oDoc.xml;
|
||||
};
|
||||
return s;
|
||||
};
|
||||
/**
|
||||
* Utility class to serialize DOM Node objects to XML strings
|
||||
* @constructor
|
||||
*/
|
||||
XMLSerializer = function(){};
|
||||
/**
|
||||
* Serialize the given DOM Node to an XML string
|
||||
* @param oNode the DOM Node to serialize
|
||||
*/
|
||||
XMLSerializer.prototype.serializeToString = function(oNode) {
|
||||
return oNode.xml;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* strips tags from a markup string
|
||||
*/
|
||||
Sarissa.stripTags = function (s) {
|
||||
return s.replace(/<[^>]+>/g,"");
|
||||
};
|
||||
/**
|
||||
* <p>Deletes all child nodes of the given node</p>
|
||||
* @argument oNode the Node to empty
|
||||
*/
|
||||
Sarissa.clearChildNodes = function(oNode) {
|
||||
// need to check for firstChild due to opera 8 bug with hasChildNodes
|
||||
while(oNode.firstChild){
|
||||
oNode.removeChild(oNode.firstChild);
|
||||
};
|
||||
};
|
||||
/**
|
||||
* <p> Copies the childNodes of nodeFrom to nodeTo</p>
|
||||
* <p> <b>Note:</b> The second object's original content is deleted before
|
||||
* the copy operation, unless you supply a true third parameter</p>
|
||||
* @argument nodeFrom the Node to copy the childNodes from
|
||||
* @argument nodeTo the Node to copy the childNodes to
|
||||
* @argument bPreserveExisting whether to preserve the original content of nodeTo, default is false
|
||||
*/
|
||||
Sarissa.copyChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) {
|
||||
if((!nodeFrom) || (!nodeTo)){
|
||||
throw "Both source and destination nodes must be provided";
|
||||
};
|
||||
if(!bPreserveExisting){
|
||||
Sarissa.clearChildNodes(nodeTo);
|
||||
};
|
||||
var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument;
|
||||
var nodes = nodeFrom.childNodes;
|
||||
if(ownerDoc.importNode && (!_SARISSA_IS_IE)) {
|
||||
for(var i=0;i < nodes.length;i++) {
|
||||
nodeTo.appendChild(ownerDoc.importNode(nodes[i], true));
|
||||
};
|
||||
}
|
||||
else{
|
||||
for(var i=0;i < nodes.length;i++) {
|
||||
nodeTo.appendChild(nodes[i].cloneNode(true));
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* <p> Moves the childNodes of nodeFrom to nodeTo</p>
|
||||
* <p> <b>Note:</b> The second object's original content is deleted before
|
||||
* the move operation, unless you supply a true third parameter</p>
|
||||
* @argument nodeFrom the Node to copy the childNodes from
|
||||
* @argument nodeTo the Node to copy the childNodes to
|
||||
* @argument bPreserveExisting whether to preserve the original content of nodeTo, default is
|
||||
*/
|
||||
Sarissa.moveChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) {
|
||||
if((!nodeFrom) || (!nodeTo)){
|
||||
throw "Both source and destination nodes must be provided";
|
||||
};
|
||||
if(!bPreserveExisting){
|
||||
Sarissa.clearChildNodes(nodeTo);
|
||||
};
|
||||
var nodes = nodeFrom.childNodes;
|
||||
// if within the same doc, just move, else copy and delete
|
||||
if(nodeFrom.ownerDocument == nodeTo.ownerDocument){
|
||||
while(nodeFrom.firstChild){
|
||||
nodeTo.appendChild(nodeFrom.firstChild);
|
||||
};
|
||||
}else{
|
||||
var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument;
|
||||
if(ownerDoc.importNode && (!_SARISSA_IS_IE)) {
|
||||
for(var i=0;i < nodes.length;i++) {
|
||||
nodeTo.appendChild(ownerDoc.importNode(nodes[i], true));
|
||||
};
|
||||
}else{
|
||||
for(var i=0;i < nodes.length;i++) {
|
||||
nodeTo.appendChild(nodes[i].cloneNode(true));
|
||||
};
|
||||
};
|
||||
Sarissa.clearChildNodes(nodeFrom);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* <p>Serialize any object to an XML string. All properties are serialized using the property name
|
||||
* as the XML element name. Array elements are rendered as <code>array-item</code> elements,
|
||||
* using their index/key as the value of the <code>key</code> attribute.</p>
|
||||
* @argument anyObject the object to serialize
|
||||
* @argument objectName a name for that object
|
||||
* @return the XML serializationj of the given object as a string
|
||||
*/
|
||||
Sarissa.xmlize = function(anyObject, objectName, indentSpace){
|
||||
indentSpace = indentSpace?indentSpace:'';
|
||||
var s = indentSpace + '<' + objectName + '>';
|
||||
var isLeaf = false;
|
||||
if(!(anyObject instanceof Object) || anyObject instanceof Number || anyObject instanceof String
|
||||
|| anyObject instanceof Boolean || anyObject instanceof Date){
|
||||
s += Sarissa.escape(""+anyObject);
|
||||
isLeaf = true;
|
||||
}else{
|
||||
s += "\n";
|
||||
var itemKey = '';
|
||||
var isArrayItem = anyObject instanceof Array;
|
||||
for(var name in anyObject){
|
||||
s += Sarissa.xmlize(anyObject[name], (isArrayItem?"array-item key=\""+name+"\"":name), indentSpace + " ");
|
||||
};
|
||||
s += indentSpace;
|
||||
};
|
||||
return s += (objectName.indexOf(' ')!=-1?"</array-item>\n":"</" + objectName + ">\n");
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape the given string chacters that correspond to the five predefined XML entities
|
||||
* @param sXml the string to escape
|
||||
*/
|
||||
Sarissa.escape = function(sXml){
|
||||
return sXml.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
};
|
||||
|
||||
/**
|
||||
* Unescape the given string. This turns the occurences of the predefined XML
|
||||
* entities to become the characters they represent correspond to the five predefined XML entities
|
||||
* @param sXml the string to unescape
|
||||
*/
|
||||
Sarissa.unescape = function(sXml){
|
||||
return sXml.replace(/'/g,"'")
|
||||
.replace(/"/g,"\"")
|
||||
.replace(/>/g,">")
|
||||
.replace(/</g,"<")
|
||||
.replace(/&/g,"&");
|
||||
};
|
||||
// EOF
|
||||
@@ -1,105 +0,0 @@
|
||||
/**
|
||||
* ====================================================================
|
||||
* About
|
||||
* ====================================================================
|
||||
* Sarissa cross browser XML library - AJAX module
|
||||
* @version 0.9.6.1
|
||||
* @author: Copyright Manos Batsis, mailto: mbatsis at users full stop sourceforge full stop net
|
||||
*
|
||||
* This module contains some convinient AJAX tricks based on Sarissa
|
||||
*
|
||||
* ====================================================================
|
||||
* Licence
|
||||
* ====================================================================
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 or
|
||||
* the GNU Lesser General Public License version 2.1 as published by
|
||||
* the Free Software Foundation (your choice between the two).
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License or GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* or GNU Lesser General Public License along with this program; if not,
|
||||
* write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* or visit http://www.gnu.org
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Update an element with response of a GET request on the given URL.
|
||||
* @addon
|
||||
* @param sFromUrl the URL to make the request to
|
||||
* @param oTargetElement the element to update
|
||||
* @param xsltproc (optional) the transformer to use on the returned
|
||||
* content before updating the target element with it
|
||||
*/
|
||||
Sarissa.updateContentFromURI = function(sFromUrl, oTargetElement, xsltproc) {
|
||||
try{
|
||||
oTargetElement.style.cursor = "wait";
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open("GET", sFromUrl);
|
||||
function sarissa_dhtml_loadHandler() {
|
||||
if (xmlhttp.readyState == 4) {
|
||||
oTargetElement.style.cursor = "auto";
|
||||
Sarissa.updateContentFromNode(xmlhttp.responseXML, oTargetElement, xsltproc);
|
||||
};
|
||||
};
|
||||
xmlhttp.onreadystatechange = sarissa_dhtml_loadHandler;
|
||||
xmlhttp.send(null);
|
||||
oTargetElement.style.cursor = "auto";
|
||||
}
|
||||
catch(e){
|
||||
oTargetElement.style.cursor = "auto";
|
||||
throw e;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Update an element's content with the given DOM node.
|
||||
* @addon
|
||||
* @param sFromUrl the URL to make the request to
|
||||
* @param oTargetElement the element to update
|
||||
* @param xsltproc (optional) the transformer to use on the given
|
||||
* DOM node before updating the target element with it
|
||||
*/
|
||||
Sarissa.updateContentFromNode = function(oNode, oTargetElement, xsltproc) {
|
||||
try {
|
||||
oTargetElement.style.cursor = "wait";
|
||||
Sarissa.clearChildNodes(oTargetElement);
|
||||
// check for parsing errors
|
||||
var ownerDoc = oNode.nodeType == Node.DOCUMENT_NODE?oNode:oNode.ownerDocument;
|
||||
if(ownerDoc.parseError && ownerDoc.parseError != 0) {
|
||||
var pre = document.createElement("pre");
|
||||
pre.appendChild(document.createTextNode(Sarissa.getParseErrorText(ownerDoc)));
|
||||
oTargetElement.appendChild(pre);
|
||||
}
|
||||
else {
|
||||
// transform if appropriate
|
||||
if(xsltproc) {
|
||||
oNode = xsltproc.transformToDocument(oNode);
|
||||
};
|
||||
// be smart, maybe the user wants to display the source instead
|
||||
if(oTargetElement.tagName.toLowerCase == "textarea" || oTargetElement.tagName.toLowerCase == "input") {
|
||||
oTargetElement.value = Sarissa.serialize(oNode);
|
||||
}
|
||||
else {
|
||||
// ok that was not smart; it was paranoid. Keep up the good work by trying to use DOM instead of innerHTML
|
||||
if(oNode.nodeType == Node.DOCUMENT_NODE || oNode.ownerDocument.documentElement == oNode) {
|
||||
oTargetElement.innerHTML = Sarissa.serialize(oNode);
|
||||
}
|
||||
else{
|
||||
oTargetElement.appendChild(oTargetElement.ownerDocument.importNode(oNode, true));
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
catch(e) {
|
||||
throw e;
|
||||
}
|
||||
finally{
|
||||
oTargetElement.style.cursor = "auto";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
autologin=0
|
||||
timeout=120
|
||||
@@ -1,2 +0,0 @@
|
||||
autologin=Login mode,1,0-Prompt for username and password,1-Open root shell
|
||||
timeout=Idle timeout before closing connection,0,5,,seconds
|
||||
@@ -1,2 +0,0 @@
|
||||
autologin=وضع تسجيل الدخول,1,0-موجه لاسم المستخدم وكلمة المرور,1-فتح شل الـ root
|
||||
timeout=مهلة الخمول قبل إغلاق الاتصال,0,5,,ثانية
|
||||
@@ -1,2 +0,0 @@
|
||||
autologin=Mode d'entrada,1,0-Demana usuari i contrasenya,1-Obre una shell de root
|
||||
timeout=Temps límit d'inactivitat abans de tancar la connexió,0,5,,segons
|
||||
@@ -1,2 +0,0 @@
|
||||
autologin=Login Modus,1,0-Eingabeaufforderung für Benutzername und Passwort,1-Open-Root-Shell
|
||||
timeout=Leerlaufzeit vor Beenden der Verbindung,0,5,,Sekunden
|
||||
@@ -1,2 +0,0 @@
|
||||
autologin=Mode de connexion,1,0-Demander le nom d'utilisateur et le mot de passe,1-Ouvrir le shell racine
|
||||
timeout=Délai d'inactivité avant la fermeture de la connexion,0,5,,secondes
|
||||
@@ -1,2 +0,0 @@
|
||||
autologin=Mod Log masuk,1,0-Minta nama pengguna dan kata laluan,1-Buka shell root
|
||||
timeout=masa terbiar tamat sebelum sambungan ditutup,0,5,,saat
|
||||
@@ -1,2 +0,0 @@
|
||||
autologin=Inlog mode,1,0-Prompt voor gebruikersnaam en wachtwoord,1-Open root shell
|
||||
timeout=Inactieve wachttijd voordat verbinding word verbroken,0,5,,seconden
|
||||
@@ -1,2 +0,0 @@
|
||||
autologin=Innloggingsmetode,1,0-Be om brukernavn og passord,1-Åpne root-skall
|
||||
timeout=Tid uten aktivitet før forbindelsen lukkes,0,5,,sekunder
|
||||
@@ -1,2 +0,0 @@
|
||||
autologin=Tryb logowania,1,0-Poproś o login i hasło,1-Otwórz root shell
|
||||
timeout=Czas oczekiwania w trybie idle przed zamknięciem połączenia,0,5,,sekund
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 275 B |
@@ -1,111 +0,0 @@
|
||||
#!/usr/local/bin/perl
|
||||
# Start the Ajaxterm webserver on a random port, then print an iframe for
|
||||
# a URL that proxies to it
|
||||
use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
|
||||
BEGIN { push(@INC, ".."); };
|
||||
use WebminCore;
|
||||
use Socket;
|
||||
our(%text, %config, %gconfig);
|
||||
our $module_root_directory;
|
||||
our $module_name;
|
||||
|
||||
&init_config();
|
||||
|
||||
&ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1);
|
||||
|
||||
# Check for python
|
||||
my $python = &has_command("python2") || &has_command("python");
|
||||
if (!$python) {
|
||||
&ui_print_endpage(&text('index_epython', "<tt>python</tt>"));
|
||||
}
|
||||
|
||||
# Pick a free port
|
||||
my %miniserv;
|
||||
&get_miniserv_config(\%miniserv);
|
||||
my $port = $miniserv{'port'} + 1;
|
||||
my $proto = getprotobyname('tcp');
|
||||
socket(TEST, PF_INET, SOCK_STREAM, $proto) ||
|
||||
&error("Socket failed : $!");
|
||||
setsockopt(TEST, SOL_SOCKET, SO_REUSEADDR, pack("l", 1));
|
||||
while(1) {
|
||||
last if (bind(TEST, sockaddr_in($port, INADDR_ANY)));
|
||||
$port++;
|
||||
}
|
||||
close(TEST);
|
||||
|
||||
# Run the Ajaxterm webserver
|
||||
my $pid = fork();
|
||||
if (!$pid) {
|
||||
chdir("$module_root_directory/ajaxterm");
|
||||
my $logfile = $ENV{'WEBMIN_VAR'}.'/ajaxterm.log';
|
||||
undef(*STDIN); untie(*STDIN); open(STDIN, "<", "/dev/null");
|
||||
undef(*STDOUT); untie(*STDOUT); open(STDOUT, ">", $logfile);
|
||||
undef(*STDERR); untie(*STDERR); open(STDERR, ">", $logfile);
|
||||
my $shell = &has_command("bash") ||
|
||||
&has_command("sh") || "/bin/sh";
|
||||
my @uinfo = getpwnam("root");
|
||||
my $home = $uinfo[7] || "/";
|
||||
$shell = "$shell -c ".quotemeta("cd '$home' ; exec $shell");
|
||||
exec($python, "ajaxterm.py", "--port", $port, "--log",
|
||||
$config{'autologin'} ? ("--command", $shell) : ( ));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
# Wait for it to come up
|
||||
my $try = 0;
|
||||
no strict "subs"; # TEST2 is weird. I dunno how to make it lexical without breaking.
|
||||
no warnings;
|
||||
while(1) {
|
||||
my $err;
|
||||
&open_socket("localhost", $port, TEST2, \$err);
|
||||
last if (!$err);
|
||||
$try++;
|
||||
if ($try > 30) {
|
||||
&error(&text('index_estart', 30, $port));
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
close(TEST2);
|
||||
use strict "subs";
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
|
||||
# Show the iframe
|
||||
print "<center>\n";
|
||||
print "<iframe src=@{[&get_webprefix()]}/$module_name/proxy.cgi/$port/ ",
|
||||
"width=700 height=500 frameborder=0></iframe><br>\n";
|
||||
print "<input type=button onClick='window.open(\"proxy.cgi/$port/\", \"ajaxterm\", \"toolbar=no,menubar=no,scrollbars=no,resizable=yes,width=700,height=500\")' value='$text{'index_popup'}'><p>\n";
|
||||
print &text('index_credits', 'http://antony.lesuisse.org/software/ajaxterm/'),
|
||||
"<p>\n";
|
||||
print "</center>\n";
|
||||
|
||||
# Fork process that checks for inactivity
|
||||
if (!fork()) {
|
||||
untie(*STDIN); close(STDIN);
|
||||
untie(*STDOUT); close(STDOUT);
|
||||
untie(*STDERR); close(STDERR);
|
||||
my $statfile = "$ENV{'WEBMIN_VAR'}/ajaxterm/$port";
|
||||
while(1) {
|
||||
my @st = stat($statfile);
|
||||
if (@st && time() - $st[9] > $config{'timeout'}) {
|
||||
# No activity
|
||||
last;
|
||||
}
|
||||
if (!kill(0, $pid)) {
|
||||
# Dead
|
||||
last;
|
||||
}
|
||||
sleep(10);
|
||||
}
|
||||
unlink($statfile);
|
||||
kill('KILL', $pid);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
&ui_print_footer("/", $text{'index'});
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Teksaanmelding
|
||||
index_epython=Ajaxterm vereis dat Python moet loop, maar die $1 -opdrag is nie op u stelsel gevind nie.
|
||||
index_estart=Ajaxterm het na $1 sekondes nie verbindings op poort $2 begin aanvaar nie.
|
||||
index_popup=Maak in 'n aparte venster oop.
|
||||
index_credits=Gebruik kode van <a href='$1' target=_new>Ajaxterm</a> deur Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=دخول النص
|
||||
index_epython=يتطلب Ajaxterm تشغيل Python ، ولكن لم يتم العثور على أمر $1 على النظام الخاص بك.
|
||||
index_estart=لم يبدأ Ajaxterm بقبول الاتصالات على المنفذ $2 بعد $1 ثانية.
|
||||
index_popup=فتح في نافذة منفصلة ..
|
||||
index_credits=استخدام كود من <a href='$1' target=_new>Ajaxterm</a> بواسطة Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Уваход тэксту
|
||||
index_epython=Ajaxterm патрабуе запуску Python, але каманда $1 не знойдзена ў вашай сістэме.
|
||||
index_estart=Ajaxterm не пачаў прымаць злучэнні на порт $2 праз $1 секунду.
|
||||
index_popup=Адкрыць у асобным акне ..
|
||||
index_credits=Выкарыстоўвае код <a href='$1' target=_new>Ajaxterm</a> Энтані Лесюа.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Text Login
|
||||
index_epython=Ajaxterm изисква Python да стартира, но командата $1 не беше намерена във вашата система.
|
||||
index_estart=Ajaxterm не започна да приема връзки на порт $2 след $1 секунди.
|
||||
index_popup=Отваряне в отделен прозорец ..
|
||||
index_credits=Използва код от <a href='$1' target=_new>Ajaxterm</a> от Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Entrada en Mode Text
|
||||
index_epython=Ajaxterm necessita Python per executar-se, però no s'ha trobat l'ordre $1 al sistema.
|
||||
index_estart=Ajaxterm no ha començat a acceptar connexions al port $2 passats $1 segons.
|
||||
index_popup=Obre en una finestra nova...
|
||||
index_credits=Utilitza codi d'<a href='$1' target=_new>Ajaxterm</a> d'Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Textové přihlášení
|
||||
index_epython=Ajaxterm vyžaduje spuštění Pythonu, ale příkaz $1 nebyl ve vašem systému nalezen.
|
||||
index_estart=Ajaxterm nepřijal připojení na portu $2 po $1 sekundách.
|
||||
index_popup=Otevřít v samostatném okně.
|
||||
index_credits=Používá kód od <a href='$1' target=_new>Ajaxterm</a> od Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Tekst login
|
||||
index_epython=Ajaxterm kræver, at Python kører, men kommandoen $1 blev ikke fundet på dit system.
|
||||
index_estart=Ajaxterm begyndte ikke at acceptere forbindelser på port $2 efter $1 sekunder.
|
||||
index_popup=Åbn i separat vindue ..
|
||||
index_credits=Bruger kode fra <a href='$1' target=_new>Ajaxterm</a> af Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Text-Anmeldung
|
||||
index_epython=Ajaxterm erfordert Python zur Ausführung, aber der Befehl $1 wurde auf Ihrem System nicht gefunden.
|
||||
index_estart=Ajaxterm hat nach $1 Sekunden keine Verbindungen auf Port $2 akzeptiert.
|
||||
index_popup=In separatem Fenster öffnen ..
|
||||
index_credits=Verwendet Code von <a href='$1' target=_new>Ajaxterm</a> von Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Σύνδεση Τερματικού
|
||||
index_epython=Το Ajaxterm χρειάζεται Python για να εκτελεστεί, αλλά η εντολή $1 δεν βρέθηκε στο σύστημά σας.
|
||||
index_estart=το Ajaxterm δεν ξεκίνησε να δέχεται συνδέσεις στη θύρα $2 μετά από $1 δευτερόλεπτα.
|
||||
index_popup=Άνοιγμα σε ξεχωριστό παράθυρο ..
|
||||
index_credits=Χρησιμοποιεί κώδικα από το <a href='$1' target=_new>Ajaxterm</a> του Antony Lesuisse.
|
||||
@@ -1,6 +0,0 @@
|
||||
index_title=Text Login
|
||||
index_epython=Ajaxterm requires Python to run, but the $1 command was not found on your system.
|
||||
index_estart=Ajaxterm did not start accepting connections on port $2 after $1 seconds.
|
||||
index_popup=Open in separate window ..
|
||||
index_credits=Uses code from <a href='$1' target=_new>Ajaxterm</a> by Antony Lesuisse.
|
||||
__norefs=1
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Inicio de sesión de texto
|
||||
index_epython=Ajaxterm requiere que Python se ejecute, pero el comando $1 no se encontró en su sistema.
|
||||
index_estart=Ajaxterm no comenzó a aceptar conexiones en el puerto $2 después de $1 segundos.
|
||||
index_popup=Abrir en una ventana separada.
|
||||
index_credits=Utiliza código de <a href='$1' target=_new>Ajaxterm</a> por Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Testu saioa
|
||||
index_epython=Ajaxterm-ek Python exekutatu behar du baina $1 komandoa ez da zure sisteman aurkitu.
|
||||
index_estart=Ajaxterm-ek ez du $1 segundoko konexioak onartzen $1 segundo ondoren.
|
||||
index_popup=Ireki beste leiho batean ..
|
||||
index_credits=Antony Lesuisse-k <a href='$1' target=_new>Ajaxterm</a>-ren kodea erabiltzen du.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=ورود به متن
|
||||
index_epython=Ajaxterm به اجرای پایتون نیاز دارد ، اما دستور$1 در سیستم شما یافت نشد.
|
||||
index_estart=Ajaxterm پس از$1 ثانیه شروع به پذیرش اتصالات در پورت $2 نکرد.
|
||||
index_popup=در پنجره جداگانه باز شود ..
|
||||
index_credits=از کد <a href='$1' target=_new>Ajaxterm</a> توسط آنتونی لزوسه استفاده می کند.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Sisäänkirjautuminen
|
||||
index_epython=Ajaxterm vaatii Pythonin suorittamista, mutta komentoa $1 ei löydy järjestelmästäsi.
|
||||
index_estart=Ajaxterm ei alkanut hyväksyä yhteyksiä porttiin $2 $1 sekunnin kuluttua.
|
||||
index_popup=Avaa erillisessä ikkunassa ..
|
||||
index_credits=Käyttää Antony Lesuisse'n <a href='$1' target=_new>Ajaxterm</a> -koodia.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Connexion texte
|
||||
index_epython=Ajaxterm nécessite Python pour s'exécuter, mais la commande $1 est introuvable sur votre système.
|
||||
index_estart=Ajaxterm n'a pas commencé à accepter les connexions sur le port $2 après $1 secondes.
|
||||
index_popup=Ouvrir dans une fenêtre séparée ..
|
||||
index_credits=Utilise le code de <a href='$1' target=_new>Ajaxterm</a> par Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=כניסה לטקסט
|
||||
index_epython=Ajaxterm דורש ש- Python יפעל, אך הפקודה $1 לא נמצאה במערכת שלך.
|
||||
index_estart=Ajaxterm לא התחיל לקבל חיבורים ביציאה $2 אחרי $1 שניות.
|
||||
index_popup=נפתח בחלון נפרד ..
|
||||
index_credits=משתמש בקוד מאת <a href='$1' target=_new>Ajaxterm</a> מאת אנטוני לסויס.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Prijava teksta
|
||||
index_epython=Ajaxterm zahtijeva pokretanje Pythona, ali naredba $1 nije pronađena u vašem sustavu.
|
||||
index_estart=Ajaxterm nije počeo prihvaćati veze na priključku $2 nakon $1 sekunde.
|
||||
index_popup=Otvori u zasebnom prozoru ..
|
||||
index_credits=Koristi kôd iz <a href='$1' target=_new>Ajaxterm</a> autora Antonija Lesuissea.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Text Login
|
||||
index_epython=Ajaxterm requires Python to run, but the $1 command was not found on your system.
|
||||
index_estart=Ajaxterm did not start accepting connections on port $2 after $1 seconds.
|
||||
index_popup=Open in separate window ..
|
||||
index_credits=Uses code from <a href='$1' target=_new>Ajaxterm</a> by Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Accesso al testo
|
||||
index_epython=Ajaxterm richiede l'esecuzione di Python, ma il comando $1 non è stato trovato sul tuo sistema.
|
||||
index_estart=Ajaxterm non ha iniziato ad accettare connessioni sulla porta $2 dopo $1 secondi.
|
||||
index_popup=Apri in una finestra separata ..
|
||||
index_credits=Utilizza il codice di <a href='$1' target=_new>Ajaxterm</a> di Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=テキストログイン
|
||||
index_epython=Ajaxtermを実行するにはPythonが必要ですが、システムで $1コマンドが見つかりませんでした。
|
||||
index_estart=Ajaxtermは、 $1秒後にポート $2で接続の受け入れを開始しませんでした。
|
||||
index_popup=別のウィンドウで開く ..
|
||||
index_credits=Antony Lesuisseによる<a href='$1' target=_new>Ajaxterm</a>のコードを使用します。
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=텍스트 로그인
|
||||
index_epython=Ajaxterm에는 Python을 실행해야하지만 시스템에서 $1 명령을 찾을 수 없습니다.
|
||||
index_estart=$1 초 후에 Ajaxterm이 포트 $2 에서 연결을 수락하지 않았습니다.
|
||||
index_popup=별도의 창에서 열기 ..
|
||||
index_credits=Antony Lesuisse의 <a href='$1' target=_new>Ajaxterm</a> 코드를 사용합니다.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Teksto prisijungimas
|
||||
index_epython=„Ajaxterm“ reikia paleisti „Python“, tačiau komanda $1 nerasta jūsų sistemoje.
|
||||
index_estart=„Ajaxterm“ nepradėjo priimti jungčių prie $2 prievado po $1 sekundės.
|
||||
index_popup=Atidaryti atskirame lange ..
|
||||
index_credits=Naudojamas kodas iš <a href='$1' target=_new>„Ajaxterm“</a>, kurį sukūrė Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Teksta pieteikšanās
|
||||
index_epython=Ajaxterm prasa Python palaist, bet komanda $1 jūsu sistēmā netika atrasta.
|
||||
index_estart=Ajaxterm nesāka pieņemt savienojumus $2 ostā pēc $1 sekundēm.
|
||||
index_popup=Atvērt atsevišķā logā ..
|
||||
index_credits=Izmanto kodu no <a href='$1' target=_new>Ajaxterm</a>, kuru izveidojis Antonijs Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Log masuk Teks
|
||||
index_epython=Ajaxterm memerlukan Python untuk menjalankan, tetapi arahan $1 tidak dijumpai pada sistem anda.
|
||||
index_estart=Ajaxterm tidak bermula menerima sambungan pada port $2 selepas $1 saat.
|
||||
index_popup=Buka dalam tetingkap berasingan ..
|
||||
index_credits=Menggunakan kod dari <a href='$1' target=_new>Ajaxterm</a> oleh Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Id-dħul tat-test
|
||||
index_epython=Ajaxterm jirrikjedi li Python taħdem, iżda l-kmand $1 ma nstabx fis-sistema tiegħek.
|
||||
index_estart=Ajaxterm ma bediex jaċċetta konnessjonijiet fuq il-port $2 wara $1 sekonda.
|
||||
index_popup=Iftaħ f'tieqa separata ..
|
||||
index_credits=Juża kodiċi minn <a href='$1' target=_new>Ajaxterm</a> minn Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Tekst Inlog
|
||||
index_epython=Ajaxterm heeft Python nodig om te werken, echter de $1 opdracht is niet gevonden op uw systeem.
|
||||
index_estart=Ajaxterm heeft geen verbindingen geaccepteerd op poort $2 na $1 seconden.
|
||||
index_popup=Openen in een aparte window ..
|
||||
index_credits=Gebruik de code van <a href='$1' target=_new>Ajaxterm</a> van Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Tekst-terminal
|
||||
index_epython=Ajaxterm krever Python for å kjøre, men jeg fant ikke kommandoen $1 på systemet ditt.
|
||||
index_estart=Ajaxterm startet ikke med å godta tilkoblinger på port $2 etter $1 sekunder.
|
||||
index_popup=Åpne i nytt vindu ..
|
||||
index_credits=Bruker kode fra <a href='$1' target=_new>Ajaxterm</a> av Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Tryb tekstowy (konsola)
|
||||
index_epython=Ajaxterm wymaga uruchomienia Python, ale komenda $1 nie została znaleziona w systemie.
|
||||
index_estart=Ajaxterm nie rozpoczął przyjmowania połączenia na porcie $2 przez $1 sekund.
|
||||
index_popup=Otwórz w oddzielnym oknie ..
|
||||
index_credits=Wykorzystywany jest kod z <a href='$1' target=_new> Ajaxterm </ a> napisany przez Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Entrada de texto
|
||||
index_epython=O Ajaxterm requer que o Python seja executado, mas o comando $1 não foi encontrado no seu sistema.
|
||||
index_estart=O Ajaxterm não começou a aceitar conexões na porta $2 após $1 segundos.
|
||||
index_popup=Abrir em janela separada.
|
||||
index_credits=Usa o código de <a href='$1' target=_new>Ajaxterm</a> de Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Entrada de texto
|
||||
index_epython=O Ajaxterm requer que o Python seja executado, mas o comando $1 não foi encontrado no seu sistema.
|
||||
index_estart=O Ajaxterm não começou a aceitar conexões na porta $2 após $1 segundos.
|
||||
index_popup=Abrir em janela separada.
|
||||
index_credits=Usa o código de <a href='$1' target=_new>Ajaxterm</a> de Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Logare text
|
||||
index_epython=Ajaxterm necesită rularea Python, dar comanda $1 nu a fost găsită în sistemul dvs.
|
||||
index_estart=Ajaxterm nu a început să accepte conexiuni pe portul 2 după $1 secunde.
|
||||
index_popup=Deschideți în fereastră separată ..
|
||||
index_credits=Utilizează codul de la <a href='$1' target=_new>Ajaxterm</a> de Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Текст Логин
|
||||
index_epython=Ajaxterm требует запуска Python, но команда $1 не найдена в вашей системе.
|
||||
index_estart=Ajaxterm не начал принимать соединения через порт $2 после $1 секунды.
|
||||
index_popup=Открыть в отдельном окне.
|
||||
index_credits=Использует код от <a href='$1' target=_new>Ajaxterm</a> Энтони Лесюссе.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Textové prihlásenie
|
||||
index_epython=Ajaxterm vyžaduje spustenie Pythonu, ale príkaz $1 nebol vo vašom systéme nájdený.
|
||||
index_estart=Ajaxterm nezačal prijímať pripojenia na porte $2 po $1 sekundách.
|
||||
index_popup=Otvoriť v samostatnom okne.
|
||||
index_credits=Používa kód od <a href='$1' target=_new>Ajaxterm</a> od Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Prijava v besedilo
|
||||
index_epython=Ajaxterm zahteva zagon Pythona, vendar ukaza $1 v vašem sistemu ni bilo mogoče najti.
|
||||
index_estart=Ajaxterm ni začel sprejemati povezav na vratih $2 po $1 sekundi.
|
||||
index_popup=Odpri se v ločenem oknu ..
|
||||
index_credits=Uporablja kodo <a href='$1' target=_new>Ajaxterm</a> avtorja Antonija Lesuissea.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Textinloggning
|
||||
index_epython=Ajaxterm kräver att Python körs, men kommandot $1 hittades inte på ditt system.
|
||||
index_estart=Ajaxterm började inte acceptera anslutningar på port $2 efter $1 sekunder.
|
||||
index_popup=Öppna i separat fönster ..
|
||||
index_credits=Använder kod från <a href='$1' target=_new>Ajaxterm</a> av Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=เข้าสู่ระบบข้อความ
|
||||
index_epython=Ajaxterm ต้องการ Python เพื่อให้ทำงานได้ แต่ไม่พบคำสั่ง $1 ในระบบของคุณ
|
||||
index_estart=Ajaxterm ไม่ได้เริ่มยอมรับการเชื่อมต่อบนพอร์ต $2 หลังจาก $1 วินาที
|
||||
index_popup=เปิดในหน้าต่างแยกต่างหาก ..
|
||||
index_credits=ใช้รหัสจาก <a href='$1' target=_new>Ajaxterm</a> โดย Antony Lesuisse
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Metin Girişi
|
||||
index_epython=Ajaxterm, Python'un çalışmasını gerektirir, ancak $1 komutu sisteminizde bulunamadı.
|
||||
index_estart=Ajaxterm, $1 saniye sonra $2 bağlantı noktasındaki bağlantıları kabul etmeye başlamadı.
|
||||
index_popup=Ayrı pencerede aç ..
|
||||
index_credits=Antony Lesuisse tarafından <a href='$1' target=_new>Ajaxterm</a> 'dan kod kullanır.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Текстовий вхід
|
||||
index_epython=Ajaxterm вимагає запуску Python, але команда $1 у вашій системі не знайдена.
|
||||
index_estart=Ajaxterm не почав приймати з'єднання через порт $2 через $1 секунду.
|
||||
index_popup=Відкрити в окремому вікні ..
|
||||
index_credits=Використовує код з <a href='$1' target=_new>Ajaxterm</a> від Антоні Лесюа.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=متن لاگ ان
|
||||
index_epython=ایجیکسٹرم کو ازگر چلانے کے لئے درکار ہے ، لیکن آپ کے سسٹم پر$1 کمانڈ نہیں ملا۔
|
||||
index_estart=ایجیکسٹرم نے پورٹ$2 پر$1 سیکنڈ کے بعد کنکشن قبول کرنا شروع نہیں کیا۔
|
||||
index_popup=علیحدہ ونڈو میں کھولیں ..
|
||||
index_credits=Uses code from <a href='$1' target=_new>Ajaxterm</a> by Antony Lesuisse.
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=Đăng nhập văn bản
|
||||
index_epython=Ajaxterm yêu cầu Python chạy, nhưng không tìm thấy lệnh $1 trên hệ thống của bạn.
|
||||
index_estart=Ajaxterm đã không bắt đầu chấp nhận kết nối trên cổng $2 sau $1 giây.
|
||||
index_popup=Mở trong cửa sổ riêng biệt ..
|
||||
index_credits=Sử dụng mã từ <a href='$1' target=_new>Ajaxterm</a> của Antony Lesuisse.
|
||||
@@ -1,6 +0,0 @@
|
||||
index_title=文字登入
|
||||
index_epython=Ajaxterm 需要运行 Python ,但在系统上找不到 $1 命令.
|
||||
index_estart=$1 秒后Ajaxterm没有开始在端口 $2 上接受连接.
|
||||
index_popup=在新窗口打开 ..
|
||||
index_credits=使用了Antony Lesuisse的 <a href='$1' target=_new>Ajaxterm</a> 代码.
|
||||
__norefs=1
|
||||
@@ -1,5 +0,0 @@
|
||||
index_title=文字登入
|
||||
index_epython=Ajaxterm需要運行Python,但在系統上找不到 $1命令。
|
||||
index_estart=$1秒後,Ajaxterm沒有開始在端口 $2上接受連接。
|
||||
index_popup=在單獨的窗口中打開 ..
|
||||
index_credits=使用Antony Lesuisse的<a href='$1' target=_new>Ajaxterm</a>中的代碼。
|
||||
@@ -1,3 +0,0 @@
|
||||
desc=Text Login
|
||||
name=ajaxterm
|
||||
longdesc=Access the shell on your system without the need for a separate SSH client, using Ajaxterm
|
||||
@@ -1,3 +0,0 @@
|
||||
longdesc_af=Toegang tot die skulp op u stelsel sonder die gebruik van Ajaxterm vir 'n aparte SSH-kliënt
|
||||
name_af=ajaxterm
|
||||
desc_af=Teksaanmelding
|
||||
@@ -1,2 +0,0 @@
|
||||
desc_ar=دخول النص
|
||||
longdesc_ar=يمكنك الوصول إلى الشل على النظام الخاص بك دون الحاجة إلى عميل SSH منفصل، وذلك باستخدام Ajaxterm
|
||||
@@ -1 +0,0 @@
|
||||
name_ar=ajaxterm
|
||||
@@ -1,3 +0,0 @@
|
||||
longdesc_be=Доступ да абалонкі вашай сістэмы без неабходнасці асобнага кліента SSH, выкарыстоўваючы Ajaxterm
|
||||
desc_be=Уваход тэксту
|
||||
name_be=аякстэрм
|
||||
@@ -1,3 +0,0 @@
|
||||
desc_bg=Text Login
|
||||
longdesc_bg=Достъп до черупката на вашата система, без да е необходим отделен SSH клиент, използвайки Ajaxterm
|
||||
name_bg=ajaxterm
|
||||
@@ -1,2 +0,0 @@
|
||||
desc_ca=Entrada en Mode Text
|
||||
longdesc_ca=Accedeix a la shell del sistema sense necessitat d'un client SSH separat utilitzant Ajaxterm
|
||||
@@ -1 +0,0 @@
|
||||
name_ca=ajaxterm
|
||||
@@ -1,3 +0,0 @@
|
||||
desc_cs=Textové přihlášení
|
||||
longdesc_cs=Získejte přístup do shellu ve vašem systému bez nutnosti samostatného klienta SSH pomocí Ajaxterm
|
||||
name_cs=ajaxterm
|
||||
@@ -1,3 +0,0 @@
|
||||
desc_da=Tekst login
|
||||
longdesc_da=Få adgang til skallen på dit system uden behov for en separat SSH-klient ved hjælp af Ajaxterm
|
||||
name_da=ajaxterm
|
||||
@@ -1,3 +0,0 @@
|
||||
desc_de=Text Login
|
||||
name_de=Ajaxterm
|
||||
longdesc_de=Greifen Sie mit Ajaxterm auf die Shell Ihres Systems zu, ohne dass ein separater SSH-Client erforderlich ist
|
||||
@@ -1,3 +0,0 @@
|
||||
desc_el=Σύνδεση κειμένου
|
||||
longdesc_el=Αποκτήστε πρόσβαση στο κέλυφος στο σύστημά σας χωρίς να χρειαστεί ξεχωριστός πελάτης SSH, χρησιμοποιώντας το Ajaxterm
|
||||
name_el=ajaxterm
|
||||
@@ -1,3 +0,0 @@
|
||||
longdesc_es=Acceda al shell en su sistema sin la necesidad de un cliente SSH separado, usando Ajaxterm
|
||||
desc_es=Inicio de sesión de texto
|
||||
name_es=ajaxterm
|
||||
@@ -1,3 +0,0 @@
|
||||
name_eu=ajaxterm
|
||||
longdesc_eu=Sartu zure sisteman shell-a SSH bezero bereizirik beharrik gabe, Ajaxterm erabiliz
|
||||
desc_eu=Testu saioa
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user