/*## (c) SECURITY EXPLORATIONS    2018 poland                                #*/
/*##     http://www.security-explorations.com                                #*/

/* THIS SOFTWARE IS PROTECTED BY DOMESTIC AND INTERNATIONAL COPYRIGHT LAWS    */
/* UNAUTHORISED COPYING OF THIS SOFTWARE IN EITHER SOURCE OR BINARY FORM IS   */
/* EXPRESSLY FORBIDDEN. ANY USE, INCLUDING THE REPRODUCTION, MODIFICATION,    */
/* DISTRIBUTION, TRANSMISSION, RE-PUBLICATION, STORAGE OR DISPLAY OF ANY      */
/* PART OF THE SOFTWARE, FOR COMMERCIAL OR ANY OTHER PURPOSES REQUIRES A      */
/* VALID LICENSE FROM THE COPYRIGHT HOLDER.                                   */

/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS    */
/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,*/
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    */
/* SECURITY EXPLORATIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF  */
/* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE     */
/* SOFTWARE.                                                                  */

import java.lang.*;
import java.io.*;
import java.util.*;
import java.text.*;

public class Interpreter {
 public static class CmdDesc {
  String name;
  String opt_string;
  int id;

  public CmdDesc(String name,String option,int id) {
   this.name=name;
   this.opt_string=option;
   this.id=id;
  }

  public boolean no_options() {
   if ((opt_string==null)||(opt_string.equals(""))) return true;
    else return false;
  }
 }

 public static final CmdDesc cmd_table[]={
  new CmdDesc("list"       , null           ,  Proto.CMD_LIST),
  new CmdDesc("go"         , "I"            ,  Proto.CMD_GO  ),
  new CmdDesc("exit"       , null           ,  Proto.CMD_EXIT),
  new CmdDesc("ecmroutes"  , null           ,  Proto.CMD_ECMROUTES),

  new CmdDesc("sysinfo"    , null           ,  Proto.CMD_SYS_INFO),
  new CmdDesc("cardinfo"   , null           ,  Proto.CMD_CARD_INFO),

  new CmdDesc("pwd"        , null           ,  Proto.CMD_SYS_PWD),
  new CmdDesc("jpwd"       , null           ,  Proto.CMD_JVM_PWD),

  new CmdDesc("cd"         , "S"            ,  Proto.CMD_SYS_CHDIR),
  new CmdDesc("jcd"        , "S"            ,  Proto.CMD_JVM_CHDIR),

  new CmdDesc("ls"         , "SRf"          ,  Proto.CMD_SYS_DIR),
  new CmdDesc("jls"        , "SRf"          ,  Proto.CMD_JVM_DIR),

  new CmdDesc("get"        , "S"            ,  Proto.CMD_SYS_GET),
  new CmdDesc("jget"       , "S"            ,  Proto.CMD_JVM_GET),

  new CmdDesc("put"        , "SSf"          ,  Proto.CMD_SYS_PUT),
  new CmdDesc("jput"       , "SSf"          ,  Proto.CMD_JVM_PUT),

  new CmdDesc("del"        , "S"            ,  Proto.CMD_SYS_DEL),
  new CmdDesc("jdel"       , "S"            ,  Proto.CMD_JVM_DEL),

  new CmdDesc("dumpfs"     , "SRz"          ,  Proto.CMD_SYS_FSDUMP),
  new CmdDesc("jdumpfs"    , "SRz"          ,  Proto.CMD_JVM_FSDUMP),

  new CmdDesc("mkdir"      , "S"            ,  Proto.CMD_SYS_MKDIR),
  new CmdDesc("jmkdir"     , "S"            ,  Proto.CMD_JVM_MKDIR),

  new CmdDesc("rmdir"      , "S"            ,  Proto.CMD_SYS_RMDIR),
  new CmdDesc("jrmdir"     , "S"            ,  Proto.CMD_JVM_RMDIR),

  new CmdDesc("root"       , null           ,  Proto.CMD_ROOT),
  new CmdDesc("id"         , null           ,  Proto.CMD_ID),

  new CmdDesc("output"     , "S"            ,  Proto.CMD_OUTPUT),

  new CmdDesc("jthreads"   , null           ,  Proto.CMD_JVM_THREADS),

  new CmdDesc("kdump"      , "II"           ,  Proto.CMD_KDUMP),

  new CmdDesc("openurl"    , "S"            ,  Proto.CMD_OPENURL),

  new CmdDesc("quit"       , null           ,  Proto.CMD_QUIT),

  new CmdDesc("play"       , "Ss"           ,  Proto.CMD_PLAY),

  new CmdDesc("avinfo"     , null           ,  Proto.CMD_AV_INFO),
  new CmdDesc("srvinfo"    , "Iscftp"       ,  Proto.CMD_SRV_INFO),

  new CmdDesc("cat"        , "S"            ,  Proto.CMD_SYS_CAT),
  new CmdDesc("jcat"       , "S"            ,  Proto.CMD_JVM_CAT),

  new CmdDesc("service"    , "Ilu"          ,  Proto.CMD_SERVICE),

  new CmdDesc("dvrinfo"    , "up"           ,  Proto.CMD_DVR_INFO),

  new CmdDesc("jprops"     , null           ,  Proto.CMD_JVM_PROPS),
  new CmdDesc("dialog"     , "SSacplw"      ,  Proto.CMD_DIALOG),

  new CmdDesc("httpsniff"  , "rshc"         ,  Proto.CMD_HTTPSNIFF),

  new CmdDesc("ps"         , null           ,  Proto.CMD_SYS_PS),
  new CmdDesc("keys"       , "S"            ,  Proto.CMD_KEYS),

  new CmdDesc("urimap"     , "SmSd"         ,  Proto.CMD_URIMAP),

  new CmdDesc("subsinfo"   , null           ,  Proto.CMD_SUBS_INFO),

  new CmdDesc("epginfo"    , "IcI"          ,  Proto.CMD_EPG_INFO),

  new CmdDesc("capture"    , "S"            ,  Proto.CMD_CAPTURE),

  new CmdDesc("mpegsniff"  , "II"           ,  Proto.CMD_MPEGSNIFF),

  new CmdDesc("pat"        , "f"            ,  Proto.CMD_PAT),
  new CmdDesc("pmt"        , "I"            ,  Proto.CMD_PMT),

  new CmdDesc("dmesg"      , null           ,  Proto.CMD_DMESG),
  new CmdDesc("reboot"     , null           ,  Proto.CMD_REBOOT),

  new CmdDesc("invoices"   , "IfraI"        ,  Proto.CMD_INVOICES),

  new CmdDesc("dsmccmount" , "S"            ,  Proto.CMD_DSMCCMOUNT),

  new CmdDesc("ssuinfo"    , null           ,  Proto.CMD_SSU_INFO),

  new CmdDesc("emmblock"   , "rs"           ,  Proto.CMD_EMMBLOCK),

  new CmdDesc("keyinfo"    , null           ,  Proto.CMD_KEYINFO),
  new CmdDesc("upgdnl"     , "I"            ,  Proto.CMD_UPGDNL),

  new CmdDesc("dvrmgr"     , "aIfStSsIdIrI" ,  Proto.CMD_DVRMGR),
  new CmdDesc("emmsniff"   , "rs"           ,  Proto.CMD_EMMSNIFF),

  new CmdDesc("mpegdump"   , "rsdIcItIfS"   ,  Proto.CMD_MPEGDUMP),

  new CmdDesc("hdcpinfo"   , null           ,  Proto.CMD_HDCP_INFO),

  new CmdDesc("chmod"      , "IS"           ,  Proto.CMD_CHMOD),
  new CmdDesc("chown"      , "SS"           ,  Proto.CMD_CHOWN),

  new CmdDesc("exec"       , "S"            ,  Proto.CMD_EXEC),//remove
  new CmdDesc("fwflush"    , null           ,  Proto.CMD_FWFLUSH),
  new CmdDesc("emmload"    , "Sv"           ,  Proto.CMD_EMMLOAD),

  new CmdDesc("ecmreceive" , "cIrs"         ,  Proto.CMD_ECMRECEIVE),
  new CmdDesc("ecmforward" , "cIrs"         ,  Proto.CMD_ECMFORWARD),

  new CmdDesc("conaxinfo"  , null           ,  Proto.CMD_CONAX_INFO),

  new CmdDesc("cwinfo"     , "I"            ,  Proto.CMD_CW_INFO),

  new CmdDesc("vodprops"   , "I"            ,  Proto.CMD_VODPROPS),

  new CmdDesc("vodecm"     , "IsSlSvu"      ,  Proto.CMD_VODECM),

  new CmdDesc("vodserver"  , "rs"           ,  Proto.CMD_VODSERVER),

  new CmdDesc("voddump"    , "rsdIiItIfS"   ,  Proto.CMD_VODDUMP),

  new CmdDesc("fakesubs"   , "rsadpSmIv"    ,  Proto.CMD_FAKESUBS),
  new CmdDesc("script"     , "S"            ,  Proto.CMD_SCRIPT),
  new CmdDesc("mem"        , "II"           ,  Proto.CMD_MEM),

  new CmdDesc("tkdinput"   , "Ssw"          ,  Proto.CMD_TKDINPUT),
  new CmdDesc("tkdreg"     , "ISsw"         ,  Proto.CMD_TKDREG),
  new CmdDesc("tkdregs"    , null           ,  Proto.CMD_TKDREGS),
  new CmdDesc("tkdcmd"     , "I"            ,  Proto.CMD_TKDCMD),
  new CmdDesc("tkdrun"     , "S"            ,  Proto.CMD_TKDRUN),
  new CmdDesc("tkdmem"     , "II"           ,  Proto.CMD_TKDMEM),

  new CmdDesc("tkdpeek8"   , "I"            ,  Proto.CMD_TKDPEEK8),
  new CmdDesc("tkdpeek16"  , "I"            ,  Proto.CMD_TKDPEEK16),
  new CmdDesc("tkdpeek32"  , "I"            ,  Proto.CMD_TKDPEEK32),

  new CmdDesc("tkdpoke8"   , "II"           ,  Proto.CMD_TKDPOKE8),
  new CmdDesc("tkdpoke16"  , "II"           ,  Proto.CMD_TKDPOKE16),
  new CmdDesc("tkdpoke32"  , "II"           ,  Proto.CMD_TKDPOKE32),

  new CmdDesc("iomem"      , "II"           ,  Proto.CMD_IOMEM),

  new CmdDesc("stbprops"   , null           ,  Proto.CMD_STBPROPS),

  new CmdDesc("isolate"    , null           ,  Proto.CMD_ISOLATE),

  new CmdDesc("scwatch"    , "rs"           ,  Proto.CMD_SCWATCH),

  new CmdDesc("nostbprops" , null           ,  Proto.CMD_NOSTBPROPS),
  new CmdDesc("stbprop"    , "SS"           ,  Proto.CMD_STBPROP),
  new CmdDesc("cardaddr"   , "S"            ,  Proto.CMD_CARDADDR),
  new CmdDesc("macaddr"    , "S"            ,  Proto.CMD_MACADDR),
  new CmdDesc("serial"     , "S"            ,  Proto.CMD_SERIAL),

  new CmdDesc("getcwpk"    , null           ,  Proto.CMD_GETCWPK),
  new CmdDesc("setcwpk"    , "Ssw"          ,  Proto.CMD_SETCWPK),

  new CmdDesc("secfuses"   , null           ,  Proto.CMD_SECFUSES),

  new CmdDesc("ivodurl"    , "sS"           ,  Proto.CMD_IVODURL),

  new CmdDesc("test"       , "S"            ,  Proto.CMD_TEST)
 };

 public static CmdDesc lookup_cmd(String cmd) {
  for(int i=0;i<cmd_table.length;i++) {
   CmdDesc desc=cmd_table[i];

   if (desc.name.equals(cmd)) return desc;
  }

  return null;
 }

 private static boolean box_command(int cmd) {
  boolean res;

  switch(cmd) {
   case Proto.CMD_CLIENTS_COUNT:
   case Proto.CMD_CLIENT_ID:
   case Proto.CMD_LIST:
   case Proto.CMD_GO:
   case Proto.CMD_EXIT:
   case Proto.CMD_ECMROUTES:
    res=false;
    break;
   default:
    res=true;
    break;
  }

  return res;
 }

 private static boolean cmd_list(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_list();

  return true;
 }

 private static boolean cmd_go(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  Shell.Option opt=options[0];

  int id=opt.int_arg();

  int status=cl.cmd_go(id);

  boolean res=true;

  if (status!=0) {
   Shell.err_string="invalid box id";
   res=false;
  }

  return res;
 }

 private static boolean cmd_exit(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_exit();
  Shell.stop();

  return true;
 }

 private static boolean cmd_ecmroutes(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_ecmroutes();

  return true;
 }

 private static boolean cmd_sys_info(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_sys_info();

  return true;
 }

 private static boolean cmd_card_info(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_card_info();

  return true;
 }

 private static boolean cmd_sys_pwd(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String dir=cl.cmd_sys_pwd();

  cl.outputln(dir);

  return true;
 }

 private static boolean cmd_jvm_pwd(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String dir=cl.cmd_jvm_pwd();

  cl.outputln(dir);

  return true;
 }

 private static boolean cmd_sys_chdir(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String dir=options[0].str_arg();

  int status=cl.cmd_sys_chdir(dir);

  boolean res=true;

  if (status!=0) {
   Shell.err_string="invalid directory";
   res=false;
  }

  return res;
 }

 private static boolean cmd_jvm_chdir(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String dir=options[0].str_arg();

  int status=cl.cmd_jvm_chdir(dir);

  boolean res=true;

  if (status!=0) {
   Shell.err_string="invalid directory";
   res=false;
  }

  return res;
 }

 private static boolean cmd_sys_dir(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String dir=null;

  if (options.length!=0) {
   if (options[0].pure_arg()) {
    dir=options[0].str_arg();
   }
  }

  boolean recurse=false;

  Shell.Option opt=Shell.getopt(options,'R');

  if (opt!=null) {
   recurse=true;
  }

  boolean fullpath=false;

  opt=Shell.getopt(options,'f');

  if (opt!=null) {
   fullpath=true;
  }

  int status=cl.cmd_sys_dir(dir,recurse,fullpath);

  boolean res=true;

  if (status!=0) {
   Shell.err_string="invalid directory";
   res=false;
  }

  return res;
 }

 private static boolean cmd_jvm_dir(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String dir=null;

  if (options.length!=0) {
   if (options[0].pure_arg()) {
    dir=options[0].str_arg();
   }
  }

  boolean recurse=false;

  Shell.Option opt=Shell.getopt(options,'R');

  if (opt!=null) {
   recurse=true;
  }

  boolean fullpath=false;

  opt=Shell.getopt(options,'f');

  if (opt!=null) {
   fullpath=true;
  }

  int status=cl.cmd_jvm_dir(dir,recurse,fullpath);

  boolean res=true;

  if (status!=0) {
   Shell.err_string="invalid directory";
   res=false;
  }

  return res;
 }

 private static boolean cmd_get_internal(ConsoleIf cl,Shell.Option[] options,boolean sys) throws Throwable {
  String filename=null;

  if (options.length!=0) {
   if (options[0].pure_arg()) {
    filename=options[0].str_arg();
   }
  }

  if (filename==null) {
   Shell.err_string="missing filename argument";
   return false;
  }

  boolean res=true;

  int status=0;

  if (sys) {
   status=cl.cmd_sys_get(filename);
  } else {
   status=cl.cmd_jvm_get(filename);
  }

  if (status!=0) {
   switch(status) {
    case FSDefs.FGET_CANNOT_OPEN:
     Shell.err_string="cannot open file";
     break;
    case FSDefs.FGET_ZERO_LENGTH:
     Shell.err_string="file has zero length";
     break;
    case FSDefs.FGET_DIR:
     Shell.err_string="expecting file not dir";
     break;
   }

   res=false;
  }

  return res;
 }

 private static boolean cmd_cat_internal(ConsoleIf cl,Shell.Option[] options,boolean sys) throws Throwable {
  String filename=null;

  if (options.length!=0) {
   if (options[0].pure_arg()) {
    filename=options[0].str_arg();
   }
  }

  if (filename==null) {
   Shell.err_string="missing filename argument";
   return false;
  }

  boolean res=true;

  int status=0;

  if (sys) {
   status=cl.cmd_sys_cat(filename);
  } else {
   status=cl.cmd_jvm_cat(filename);
  }

  if (status!=0) {
   switch(status) {
    case FSDefs.FGET_CANNOT_OPEN:
     Shell.err_string="cannot open file";
     break;
    case FSDefs.FGET_ZERO_LENGTH:
     Shell.err_string="file has zero length";
     break;
    case FSDefs.FGET_DIR:
     Shell.err_string="expecting file not dir";
     break;
   }

   res=false;
  }

  return res;
 }

 private static boolean cmd_sys_get(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  return cmd_get_internal(cl,options,true);
 }

 private static boolean cmd_jvm_get(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  return cmd_get_internal(cl,options,false);
 }

 private static boolean cmd_sys_cat(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  return cmd_cat_internal(cl,options,true);
 }

 private static boolean cmd_jvm_cat(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  return cmd_cat_internal(cl,options,false);
 }

 private static boolean cmd_sys_dumpfs(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String dirname=null;

  if (options.length!=0) {
   if (options[0].pure_arg()) {
    dirname=options[0].str_arg();
   }
  }

  if (dirname==null) {
   Shell.err_string="missing directory name argument";
   return false;
  }

  boolean recurse=false;

  Shell.Option opt=Shell.getopt(options,'R');

  if (opt!=null) {
   recurse=true;
  }

  boolean zerolen=false;

  opt=Shell.getopt(options,'z');

  if (opt!=null) {
   zerolen=true;
  }

  boolean res=true;

  int status=cl.cmd_sys_dumpfs(dirname,recurse,zerolen);

  if (status!=0) {
   switch(status) {
    case FSDefs.FGET_CANNOT_OPEN:
     Shell.err_string="cannot open file";
     break;
    case FSDefs.FGET_ZERO_LENGTH:
     Shell.err_string="file has zero length";
     break;
    case FSDefs.FGET_DIR:
     Shell.err_string="expecting file not dir";
     break;
   }

   res=false;
  }

  return res;
 }

 private static boolean cmd_jvm_dumpfs(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String dirname=null;

  if (options.length!=0) {
   if (options[0].pure_arg()) {
    dirname=options[0].str_arg();
   }
  }

  if (dirname==null) {
   Shell.err_string="missing directory name argument";
   return false;
  }

  boolean recurse=false;

  Shell.Option opt=Shell.getopt(options,'R');

  if (opt!=null) {
   recurse=true;
  }

  boolean zerolen=false;

  opt=Shell.getopt(options,'z');

  if (opt!=null) {
   zerolen=true;
  }

  boolean res=true;

  int status=cl.cmd_jvm_dumpfs(dirname,recurse,zerolen);

  if (status!=0) {
   switch(status) {
    case FSDefs.FGET_CANNOT_OPEN:
     Shell.err_string="cannot open file";
     break;
    case FSDefs.FGET_ZERO_LENGTH:
     Shell.err_string="file has zero length";
     break;
    case FSDefs.FGET_DIR:
     Shell.err_string="expecting file not dir";
     break;
   }

   res=false;
  }

  return res;
 }

 private static boolean cmd_root(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_root();

  return true;
 }

 private static boolean cmd_output(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String name=null;

  if (options.length!=0) {
   if (options[0].pure_arg()) {
    name=options[0].str_arg();
   }
  }

  if (name==null) {
   Shell.err_string="missing output name argument";
   return false;
  }

  if (name.equals("console")) {
   if (cl.get_output()!=System.out) {
    cl.get_output().close();
   }

   cl.set_output(System.out);
  } else {
   try {
    cl.set_output(new PrintStream(new FileOutputStream(name,false)));
   } catch(Throwable t) {
    cl.set_output(System.out);
    Shell.err_string="invalid output name";
    return false;
   }
  }

  return true;
 }

 private static boolean cmd_put_internal(ConsoleIf cl,Shell.Option[] options,boolean sys) throws Throwable {
  String srcfile=null;
  String filename=null;

  if (options.length>=2) {
   if (options[0].pure_arg()) {
    srcfile=options[0].str_arg();
   }

   if (options[1].pure_arg()) {
    filename=options[1].str_arg();
   }
  }

  boolean overwrite=false;

  Shell.Option opt=Shell.getopt(options,'f');

  if (opt!=null) {
   overwrite=true;
  }

  if ((srcfile==null)||(filename==null)) {
   Shell.err_string="missing filename arguments";
   return false;
  }

  FileInputStream fis=null;

  try {
   fis=new FileInputStream(srcfile);
  } catch(Throwable t) {}

  if (fis==null) {
   Shell.err_string="cannot open source file";
   return false;
  }

  fis.close();

  File f=new File(srcfile);
  int size=(int)f.length();

  if (size==0) {
   Shell.err_string="source file has zero length";
   return false;
  }

  boolean res=true;

  int status=0;

  if (sys) {
   status=cl.cmd_sys_put(srcfile,filename,size,overwrite);
  } else {
   status=cl.cmd_jvm_put(srcfile,filename,size,overwrite);
  }

  if (status!=0) {
   switch(status) {
    case FSDefs.FPUT_CANNOT_WRITE:
     Shell.err_string="cannot write target file";
     break;
    case FSDefs.FPUT_EXISTS:
     Shell.err_string="target file exists";
     break;
    case FSDefs.FPUT_CANNOT_OPEN:
     Shell.err_string="cannot open source file";
     break;
    case FSDefs.FPUT_DIR:
     Shell.err_string="expecting file not dir";
     break;
   }

   res=false;
  }

  return res;
 }

 private static boolean cmd_sys_put(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  return cmd_put_internal(cl,options,true);
 }
  
 private static boolean cmd_jvm_put(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  return cmd_put_internal(cl,options,false);
 }

 private static boolean cmd_del_internal(ConsoleIf cl,Shell.Option[] options,boolean sys) throws Throwable {
  if (options.length!=1) {
   Shell.err_string="expecting file to delete";
   return false;
  }

  String filename=options[0].str_arg();

  int status=0;

  if (sys) {
   status=cl.cmd_sys_del(filename);
  } else {
   status=cl.cmd_jvm_del(filename);
  }

  boolean res=true;

  if (status!=0) {
   Shell.err_string="cannot delete file";
   res=false;
  }

  return res;
 }

 private static boolean cmd_sys_del(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  return cmd_del_internal(cl,options,true);
 }

 private static boolean cmd_jvm_del(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  return cmd_del_internal(cl,options,false);
 }

 private static boolean cmd_id(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_id();

  return true;
 }

 private static boolean cmd_mkdir_internal(ConsoleIf cl,Shell.Option[] options,boolean sys) throws Throwable {
  if (options.length!=1) {
   Shell.err_string="expecting directory to create";
   return false;
  }

  String dirname=options[0].str_arg();

  int status=0;

  if (sys) {
   status=cl.cmd_sys_mkdir(dirname);
  } else {
   status=cl.cmd_jvm_mkdir(dirname);
  }

  boolean res=true;

  if (status!=0) {
   Shell.err_string="cannot create directory";
   res=false;
  }

  return res;
 }

 private static boolean cmd_sys_mkdir(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  return cmd_mkdir_internal(cl,options,true);
 }

 private static boolean cmd_jvm_mkdir(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  return cmd_mkdir_internal(cl,options,false);
 }

 private static boolean cmd_rmdir_internal(ConsoleIf cl,Shell.Option[] options,boolean sys) throws Throwable {
  if (options.length!=1) {
   Shell.err_string="expecting directory to remove";
   return false;
  }

  String dirname=options[0].str_arg();

  int status=0;

  if (sys) {
   status=cl.cmd_sys_rmdir(dirname);
  } else {
   status=cl.cmd_jvm_rmdir(dirname);
  }

  boolean res=true;

  if (status!=0) {
   Shell.err_string="cannot remove directory";
   res=false;
  }

  return res;
 }

 private static boolean cmd_sys_rmdir(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  return cmd_rmdir_internal(cl,options,true);
 }

 private static boolean cmd_jvm_rmdir(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  return cmd_rmdir_internal(cl,options,false);
 }

 private static boolean cmd_jvm_threads(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_jvm_threads();

  return true;
 }

 private static boolean cmd_kdump(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int kaddr=-1;
  int size=-1;

  if (options.length!=2) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (options[0].pure_arg()) {
   kaddr=options[0].int_arg();
  }

  if (options[1].pure_arg()) {
   size=options[1].int_arg();
  }

  if (kaddr==-1) {
   Shell.err_string="missing kaddr argument";
   return false;
  }

  if (size==-1) {
   Shell.err_string="missing size argument";
   return false;
  }

  cl.cmd_kdump(kaddr,size);

  return true;
 }

 private static boolean cmd_openurl(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String url=null;

  if (options.length!=0) {
   if (options[0].pure_arg()) {
    url=options[0].str_arg();
   }
  }

  if (url==null) {
   Shell.err_string="missing url argument";
   return false;
  }

  boolean status=cl.cmd_openurl(url);

  if (!status) {
   Shell.err_string="cannot open url";
   return false;
  }

  return true;
 }

 private static boolean cmd_quit(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_quit();

  return true;
 }

 private static boolean cmd_play(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String url=null;
  Shell.Option opt=null;

  if (options.length!=1) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (options[0].pure_arg()) {
   url=options[0].str_arg();
  }

  if (url==null) {
   opt=Shell.getopt(options,'s');

   if (opt==null) {
    Shell.err_string="expecting url argument";
    return false;
   }
  }

  boolean status=cl.cmd_play(url);

  if (!status) {
   if (url!=null) Shell.err_string="cannot play url";
    else Shell.err_string="cannot stop player";

   return false;
  }

  return true;
 }

 private static boolean cmd_avinfo(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_avinfo();

  return true;
 }

 private static boolean cmd_srvinfo(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int id=-1;
  int type=-1;

  if (options.length==0) {
   type=SrvUtilsDefs.S_CURRENT;
  } else

  if (options.length==1) {
   if (options[0].pure_arg()) {
    type=SrvUtilsDefs.S_CURRENT;
    id=options[0].int_arg();
   } else {
    if (Shell.getopt(options,'s')!=null) {
     type=SrvUtilsDefs.S_SUBSCRIBED;
    } else

    if (Shell.getopt(options,'c')!=null) {
     type=SrvUtilsDefs.S_CRYPTED;
    } else

    if (Shell.getopt(options,'f')!=null) {
     type=SrvUtilsDefs.S_FTA;
    } else

    if (Shell.getopt(options,'t')!=null) {
     type=SrvUtilsDefs.S_SAME_TS;
    } else

    if (Shell.getopt(options,'p')!=null) {
     type=SrvUtilsDefs.S_PROPS;
    }

   }
  } else

  if (options.length==2) {
   if (options[0].pure_arg()) {
    id=options[0].int_arg();
   } else {
    Shell.err_string="expecting channel id argument";
    return false;
   }

   if (Shell.getopt(options,'t')!=null) {
    type=SrvUtilsDefs.S_SAME_TS;
   } else

   if (Shell.getopt(options,'p')!=null) {
    type=SrvUtilsDefs.S_PROPS;
   } else {
    Shell.err_string="expecting -t or -p switch option";
    return false;
   }

  }

  boolean status=cl.cmd_srvinfo(id,type);

  if (!status) {
   Shell.err_string="unknown service id";
   return false;
  }

  return status;
 }

 private static boolean cmd_service(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int id=-1;
  int type=-1;

  if (options.length<1) {
   Shell.err_string="invalid number of arguments";
   return false;
  } else

  if (options.length==1) {
   if (options[0].pure_arg()) {
    type=SrvUtilsDefs.S_SELECT;
    id=options[0].int_arg();
   } else {
    if (Shell.getopt(options,'l')!=null) {
     type=SrvUtilsDefs.S_LOCK;
    } else

    if (Shell.getopt(options,'u')!=null) {
     type=SrvUtilsDefs.S_UNLOCK;
    }
   }
  } else

  if (options.length==2) {
   if (options[0].pure_arg()) {
    id=options[0].int_arg();
   } else {
    Shell.err_string="expecting channel id argument";
    return false;
   }

   if (Shell.getopt(options,'l')!=null) {
    type=SrvUtilsDefs.S_LOCK;
   } else

   if (Shell.getopt(options,'u')!=null) {
    type=SrvUtilsDefs.S_UNLOCK;
   } else {
    Shell.err_string="expecting -l or -u switch option";
    return false;
   }
  }

  boolean status=cl.cmd_service(id,type);

  if (!status) {
   Shell.err_string="unknown service id";
   return false;
  }

  return status;
 }

 private static boolean cmd_dvrinfo(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int type=-1;

  if (options.length==1) {
   if (Shell.getopt(options,'u')!=null) {
    type=RecManDefs.R_USER;
   } else

   if (Shell.getopt(options,'p')!=null) {
    type=RecManDefs.R_PVOD;
   }
  } else {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  cl.cmd_dvrinfo(type);

  return true;
 }

 private static boolean cmd_jvm_props(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_jvm_props();

  return true;
 }

 private static boolean cmd_dialog(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int type=-1;
  boolean wait=false;
  String s1=null;
  String s2=null;

  if (options.length>1) {
   if (options[0].pure_arg()) {
    s1=options[0].str_arg();
   }

   if (options[1].pure_arg()) {
    s2=options[1].str_arg();
   }
  }

  if (Shell.getopt(options,'w')!=null) {
   wait=true;
  }

  if (Shell.getopt(options,'a')!=null) {
   if (s1==null) {
    Shell.err_string="expecting alert string argument";
    return false;
   }

   type=XionDefs.M_ALERT;
  } else

  if (Shell.getopt(options,'c')!=null) {
   if (s1==null) {
    Shell.err_string="expecting confirm string argument";
    return false;
   }

   type=XionDefs.M_CONFIRM;
  } else

  if (Shell.getopt(options,'p')!=null) {
   if ((s1==null)||(s2==null)) {
    Shell.err_string="expecting confirm string arguments";
    return false;
   }

   type=XionDefs.M_PROMPT;
  } else

  if (Shell.getopt(options,'l')!=null) {
   if ((s1==null)||(s2==null)) {
    Shell.err_string="expecting login string arguments";
    return false;
   }

   type=XionDefs.M_LOGIN;
  } else {
   Shell.err_string="invalid option";
   return false;
  }

  cl.cmd_dialog(type,s1,s2,wait);

  return true;
 }

 private static boolean cmd_httpsniff(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;
  int flags=0;

  if (Shell.getopt(options,'r')!=null) {
   action=HTTPSnifferDefs.SN_RUN;

   if (Shell.getopt(options,'h')!=null) {
    flags|=HTTPSnifferDefs.SN_HEADERS;
   }

   if (Shell.getopt(options,'c')!=null) {
    flags|=HTTPSnifferDefs.SN_CONTENT;
   }
  } else

  if (Shell.getopt(options,'s')!=null) {
   action=HTTPSnifferDefs.SN_STOP;

   if (options.length!=1) {
    Shell.err_string="invalid number of arguments";
    return false;
   }
  }

  if (action==-1) {
   Shell.err_string="invalid option";
   return false;
  }

  boolean status=cl.cmd_httpsniff(action,flags);

  if (!status) {
   switch(action) {
    case HTTPSnifferDefs.SN_RUN:
     Shell.err_string="cannot start HTTP sniffer";
     break;

    case HTTPSnifferDefs.SN_STOP:
     Shell.err_string="cannot stop HTTP sniffer";
     break;
   }
   return false;
  }

  return status;
 }

 private static boolean cmd_sys_ps(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_sys_ps();

  return true;
 }

 private static boolean cmd_keys(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  if (options.length!=1) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  String keyseq=options[0].str_arg();

  if (keyseq.equals("")) {
   Shell.err_string="empty key sequence";
   return false;
  }

  boolean status=cl.cmd_keys(keyseq);

  if (!status) {
   Shell.err_string="invalid key sequence";
   return false;
  }

  return true;
 }

 private static boolean cmd_urimap(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;
  String srcuri=null;
  String dsturi=null;

  if (options.length==0) {
   action=HTTPSnifferDefs.UM_LIST;
  } else {
   if (options[0].pure_arg()) {
    srcuri=options[0].str_arg();
   } else {
    Shell.err_string="expecting source URI argument";
    return false;
   }

   if (Shell.getopt(options,'d')!=null) {
    if (options.length!=2) {
     Shell.err_string="invalid number of arguments";
     return false;
    }

    action=HTTPSnifferDefs.UM_DEL;
   } else {
    Shell.Option opt=Shell.getopt(options,'m');

    if (opt!=null) {
     dsturi=opt.str_arg();
    }

    if (dsturi!=null) {
     action=HTTPSnifferDefs.UM_MAP;
    } else {
     Shell.err_string="invalid arguments";
     return false;
    }
   }   
  }

  boolean status=cl.cmd_urimap(action,srcuri,dsturi);

  if (!status) {
   switch(action) {
    case HTTPSnifferDefs.UM_DEL:
     Shell.err_string="cannot delete URI";
     break;
   }
  }

  return status;
 }

 private static boolean cmd_subsinfo(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_subsinfo();

  return true;
 }

 private static boolean cmd_epginfo(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int id=-1;
  int cnt=-1;

  if (options.length==0) {
   cnt=EPGDefs.DEFAULT_EVENT_COUNT;
  } else

  if (options.length==1) {
   if (options[0].pure_arg()) {
    id=options[0].int_arg();
   } else {
    Shell.Option opt=Shell.getopt(options,'c');

    if (opt!=null) {
     cnt=opt.int_arg();
    } else {
     Shell.err_string="invalid arguments";
     return false;
    }
   }
  } else

  if (options.length==2) {
   if (options[0].pure_arg()) {
    id=options[0].int_arg();
   } else {
    Shell.err_string="expecting channel id argument";
    return false;
   }

   Shell.Option opt=Shell.getopt(options,'c');

   if (opt!=null) {
    cnt=opt.int_arg();
   } else {
    Shell.err_string="invalid arguments";
    return false;
   }
  }

  if (cnt<0) {
   cnt=EPGDefs.DEFAULT_EVENT_COUNT;
  }

  boolean status=cl.cmd_epginfo(id,cnt);

  if (!status) {
   Shell.err_string="unknown service id";
   return false;
  }

  return status;
 }

 private static boolean cmd_capture(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  if (options.length!=1) {
   Shell.err_string="expecting capture name";
   return false;
  }

  String filename=options[0].str_arg();

  boolean res=cl.cmd_capture(filename);

  if (!res) {
   Shell.err_string="cannot take screen capture";
   return false;
  }

  return true;
 }

 private static boolean cmd_mpegsniff(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int pid=-1;
  int tid=-1;

  if ((options.length!=1)&&(options.length!=2)) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (options[0].pure_arg()) {
   pid=options[0].int_arg();
  }

  if (pid==-1) {
   Shell.err_string="missing pid argument";
   return false;
  }

  if (pid>0x1fff) {
   Shell.err_string="invalid pid argument";
   return false;
  }


  if (options.length==2) {
   if (options[1].pure_arg()) {
    tid=options[1].int_arg();
   }
  }

  cl.cmd_mpegsniff(pid,tid);

  return true;
 }

 private static boolean cmd_pat(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  boolean full=false;

  Shell.Option opt=Shell.getopt(options,'f');

  if (opt!=null) {
   full=true;
  }

  cl.cmd_pat(full);

  return true;
 }

 private static boolean cmd_pmt(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int svid=-1;

  if (options.length==1) {
   if (options[0].pure_arg()) {
    svid=options[0].int_arg();
   }
  }

  cl.cmd_pmt(svid);

  return true;
 }

 private static boolean cmd_dmesg(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_dmesg();

  return true;
 }

 private static boolean cmd_reboot(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_reboot();

  return true;
 }

 private static boolean cmd_invoices(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int cnt=-1;
  int addr=-1;

  if (options.length<1) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (options[0].pure_arg()) {
   cnt=options[0].int_arg();
  }

  if (cnt==-1) {
   Shell.err_string="missing cnt argument";
   return false;
  }

  int print_type=0;

  Shell.Option opt=Shell.getopt(options,'f');

  if (opt!=null) {
   print_type=1;
  }

  opt=Shell.getopt(options,'r');

  if (opt!=null) {
   print_type=2;
  }


  opt=Shell.getopt(options,'a');

  if (opt!=null) {
   addr=opt.int_arg();
  }

  boolean res=cl.cmd_invoices(print_type,cnt,addr);

  if (!res) {
   Shell.err_string="Invoice EMM carousel is not visible from this channel";
   return false;
  }

  return true;
 }

 private static boolean cmd_dsmccmount(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String locator=null;

  if (options.length!=1) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (options[0].pure_arg()) {
   locator=options[0].str_arg();
  }

  if (locator==null) {
   Shell.err_string="missing locator argument";
   return false;
  }

  boolean res=cl.cmd_dsmccmount(locator);

  if (!res) {
   Shell.err_string="cannot mount carousel";
   return false;
  }

  return true;
 }

 private static boolean cmd_ssuinfo(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  boolean res=cl.cmd_ssuinfo();

  if (!res) {
   Shell.err_string="SSU service is not visible from this channel";
   return false;
  }

  return true;
 }

 private static boolean cmd_emmblock(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;

  if (options.length==0) {
   action=EMMBlockerDefs.BLK_STATUS;
  } else

  if (Shell.getopt(options,'r')!=null) {
   action=EMMBlockerDefs.BLK_RUN;
  } else

  if (Shell.getopt(options,'s')!=null) {
   action=EMMBlockerDefs.BLK_STOP;
  }

  if (action==-1) {
   Shell.err_string="invalid option";
   return false;
  }

  boolean status=cl.cmd_emmblock(action);

  if (action!=EMMBlockerDefs.BLK_STATUS) {
   if (!status) {
    switch(action) {
     case EMMBlockerDefs.BLK_RUN:
      Shell.err_string="cannot start EMM blocker";
      break;

     case EMMBlockerDefs.BLK_STOP:
      Shell.err_string="cannot stop EMM blocker";
      break;
    }
    return false;
   }
  };

  return true;
 }

 private static boolean cmd_keyinfo(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_keyinfo();

  return true;
 }

 private static boolean cmd_upgdnl(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int hwid=-1;

  if (options.length!=1) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (options[0].pure_arg()) {
   hwid=options[0].int_arg();
  }

  if (hwid==-1) {
   Shell.err_string="missing hwid argument";
   return false;
  }

  int res=cl.cmd_upgdnl(hwid);

  if (res!=SSUDefs.UPGRADE_OK) {
   switch(res) {
    case SSUDefs.READ_KEYS:
     Shell.err_string="must be root to read upgrade keys";
     return false;
    case SSUDefs.UNKNOWN_HWID:
     Shell.err_string="invalid hwid";
     return false;
    case SSUDefs.CREATE_FILTER:
     Shell.err_string="upgrade data is not visible from this channel";
     return false;
   }
  }
  
  return true;
 }

 private static long parse_time(String s) {
  long res=-1;

  try {
   SimpleDateFormat df=new SimpleDateFormat("HH:mm");
   Date date=df.parse(s);

   Calendar helper=Calendar.getInstance();
   helper.setTime(date);

   Calendar cal=Calendar.getInstance();
   cal.set(Calendar.HOUR_OF_DAY,helper.get(Calendar.HOUR_OF_DAY));
   cal.set(Calendar.MINUTE,helper.get(Calendar.MINUTE));
   cal.set(Calendar.SECOND,0);
   
   res=cal.getTime().getTime();
  } catch(Throwable t) {}

  return res;
 }

 private static boolean cmd_dvrmgr(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;
  int channel=-1;
  int id=-1;
  long from=-1;
  long to=-1;

  Shell.Option opt=Shell.getopt(options,'a');

  if (opt!=null) {
   channel=opt.int_arg();

   opt=Shell.getopt(options,'f');

   if (opt!=null) {
    String s=opt.str_arg();

    from=parse_time(s);    

    if (from==-1) {
     Shell.err_string="invalid from time argument";
     return false;
    }
   }
   
   opt=Shell.getopt(options,'t');

   if (opt!=null) {
    String s=opt.str_arg();

    to=parse_time(s);    

    if (to==-1) {
     Shell.err_string="invalid end time argument";
     return false;
    }
   }

   if ((channel!=-1)&&(from!=-1)&&(to!=-1)) {
    action=RecManDefs.RM_ADD;
   } else {
    Shell.err_string="missing arguments for add command";
    return false;
   }
  } else {
   opt=Shell.getopt(options,'s');

   if (opt!=null) {
    id=opt.int_arg();

    action=RecManDefs.RM_STOP;
   } else {
    opt=Shell.getopt(options,'d');

    if (opt!=null) {
     id=opt.int_arg();

     action=RecManDefs.RM_DELETE;
    } else {
     opt=Shell.getopt(options,'r');

     if (opt!=null) {
      id=opt.int_arg();

      action=RecManDefs.RM_REMOVE;
     }
    }
   }
  }

  if (action==-1) {
   Shell.err_string="invalid arguments";
   return false;
  }

  int res=cl.cmd_dvrmgr(action,channel,from,to,id);

  if (res!=RecManDefs.RES_OK) {
   switch(res) {
    case RecManDefs.INVALID_CHANNEL:
     Shell.err_string="invalid channel";
     return false;

    case RecManDefs.INVALID_RECID:
     Shell.err_string="unknown recording id";
     return false;

    case RecManDefs.NOT_IN_RECORD_STATE:
     Shell.err_string="cannot delete recording, not in recording state";
     return false;

    case RecManDefs.CANNOT_DELETE:
     Shell.err_string="cannot delete recording";
     return false;
   }   
  }

  return true;
 }

 private static boolean cmd_emmsniff(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;

  if (options.length==0) {
   action=EMMSnifferDefs.SN_STATUS;
  } else

  if (Shell.getopt(options,'r')!=null) {
   action=EMMSnifferDefs.SN_RUN;
  } else

  if (Shell.getopt(options,'s')!=null) {
   action=EMMSnifferDefs.SN_STOP;
  }

  if (action==-1) {
   Shell.err_string="invalid option";
   return false;
  }

  boolean status=cl.cmd_emmsniff(action);

  if (action!=EMMSnifferDefs.SN_STATUS) {
   if (!status) {
    switch(action) {
     case EMMSnifferDefs.SN_RUN:
      Shell.err_string="cannot start ECM sniffer";
      break;

     case EMMSnifferDefs.SN_STOP:
      Shell.err_string="cannot stop ECM sniffer";
      break;
    }
    return false;
   }
  };

  return true;
 }


 private static boolean cmd_mpegdump(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;
  int dmx_id=-1;
  int channel=-1;
  int secs=-1;
  String filename=null;

  if (Shell.getopt(options,'r')!=null) {
   action=TSRecorderDefs.REC_RUN;

   Shell.Option opt=Shell.getopt(options,'d');

   if (opt!=null) {
    dmx_id=opt.int_arg();
   }

   opt=Shell.getopt(options,'c');

   if (opt!=null) {
    channel=opt.int_arg();
   }

   opt=Shell.getopt(options,'t');

   if (opt!=null) {
    secs=opt.int_arg();
   }

   opt=Shell.getopt(options,'f');

   if (opt!=null) {
    filename=opt.str_arg();
   }

   if (filename==null) {
    Shell.err_string="missing output filename argument";
    return false;
   }

  } else

  if (Shell.getopt(options,'s')!=null) {
   action=TSRecorderDefs.REC_STOP;

   if (options.length!=1) {
    Shell.err_string="invalid number of arguments";
    return false;
   }
  } else {
   Shell.err_string="invalid arguments";
   return false;
  }

  TSReader reader=TSReader.start(filename);

  String host=reader.get_host();
  int port=reader.get_port();

  int status=cl.cmd_mpegdump(action,dmx_id,channel,secs,host,port);

  boolean res=true;

  if (status!=TSRecorderDefs.RES_OK) {
   switch(status) {
    case TSRecorderDefs.UNKNOWN_CHANNEL:
     Shell.err_string="unknown channel";
     res=false;
     break;
    case TSRecorderDefs.INVALID_DEMUX:
     Shell.err_string="invalid demux id";
     res=false;
     break;
    case TSRecorderDefs.ALREADY_STARTED:
     Shell.err_string="mpeg dump already started";
     res=false;
     break;
   }
  }

  return res;
 }

 private static boolean cmd_hdcpinfo(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_sys_cat("/proc/driver/hdcp");

  return true;
 }

 private static boolean cmd_chmod(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  if (options.length!=2) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  int mode=-1;

  if (options[0].pure_arg()) {
   mode=options[0].int_arg();
  }

  String filename=null;

  if (options[1].pure_arg()) {
   filename=options[1].str_arg();
  }

  int status=cl.cmd_chmod(filename,mode);

  boolean res=true;

  if (status!=0) {
   Shell.err_string="cannot change mode of directory/file";
   res=false;
  }

  return res;
 }

 private static boolean cmd_chown(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  if (options.length!=2) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  String ownergroup=null;

  if (options[0].pure_arg()) {
   ownergroup=options[0].str_arg();
  }

  int idx=ownergroup.indexOf('.');

  if (idx==-1) {
   Shell.err_string="expecting owner.group argument";
   return false;
  }

  String filename=null;

  if (options[1].pure_arg()) {
   filename=options[1].str_arg();
  }

  String owner=ownergroup.substring(0,idx);
  String group=ownergroup.substring(idx+1,ownergroup.length());

  int status=cl.cmd_chown(filename,owner,group);

  boolean res=true;

  if (status!=0) {
   Shell.err_string="cannot change owner of directory/file";
   res=false;
  }

  return res;
 }

 private static boolean cmd_exec(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String cmd=null;

  if (options.length!=1) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (options[0].pure_arg()) {
   cmd=options[0].str_arg();
  }

  cl.cmd_exec(cmd);

  return true;
 }

 private static boolean cmd_fwflush(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_fwflush();

  return true;
 }

 private static boolean cmd_emmload(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;
  String name=null;

  if ((options.length==0)||(options.length>2)) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (options[0].pure_arg()) {
   name=options[0].str_arg();
  }

  if (Shell.getopt(options,'v')!=null) {
   action=EMMStoreDefs.EMM_VIEW;
  } else action=EMMStoreDefs.EMM_LOAD;

  if (name==null) {
   Shell.err_string="missing emm name argument";
   return false;
  }

  int res=cl.cmd_emmload(action,name);

  if (res!=EMMStoreDefs.RES_OK) {
   switch(res) {
    case EMMStoreDefs.CANNOT_OPEN:
     Shell.err_string="cannot open emm file";
     return false;
    case EMMStoreDefs.INVALID_FORMAT:
     Shell.err_string="invalid emm format";
     return false;
    case EMMStoreDefs.INVALID_EMM:
     Shell.err_string="emm rejected by smartcard";
     return false;
   }
  }

  return true;
 }

 private static boolean cmd_ecmreceive(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;
  int channel=-1;

  if (Shell.getopt(options,'r')!=null) {
   action=ECMServerDefs.ECMSRV_RUN;

   Shell.Option opt=Shell.getopt(options,'c');

   if (opt!=null) {
    channel=opt.int_arg();
   }
  } else

  if (Shell.getopt(options,'s')!=null) {
   action=ECMServerDefs.ECMSRV_STOP;

   if (options.length!=1) {
    Shell.err_string="invalid number of arguments";
    return false;
   }
  } else {
   Shell.err_string="invalid arguments";
   return false;
  }

  int status=cl.cmd_ecmreceive(action,channel);

  boolean res=true;

  if (status!=ECMServerDefs.RES_OK) {
   switch(status) {
    case ECMServerDefs.UNKNOWN_CHANNEL:
     Shell.err_string="unknown channel";
     res=false;
     break;
    case ECMServerDefs.ALREADY_STARTED:
     Shell.err_string="ECM receiver already started";
     res=false;
     break;
    case ECMServerDefs.NOT_RUNNING:
     Shell.err_string="ECM receiver is not running";
     res=false;
     break;
   }
  }

  return res;
 }

 private static boolean cmd_ecmforward(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;
  int channel=-1;

  if (Shell.getopt(options,'r')!=null) {
   action=ECMServerDefs.ECMSRV_RUN;

   Shell.Option opt=Shell.getopt(options,'c');

   if (opt!=null) {
    channel=opt.int_arg();
   }
  } else

  if (Shell.getopt(options,'s')!=null) {
   action=ECMServerDefs.ECMSRV_STOP;

   if (options.length!=1) {
    Shell.err_string="invalid number of arguments";
    return false;
   }
  } else {
   Shell.err_string="invalid arguments";
   return false;
  }

  int status=cl.cmd_ecmforward(action,channel);

  boolean res=true;

  if (status!=ECMServerDefs.RES_OK) {
   switch(status) {
    case ECMServerDefs.UNKNOWN_CHANNEL:
     Shell.err_string="unknown channel";
     res=false;
     break;
    case ECMServerDefs.ALREADY_STARTED:
     Shell.err_string="ECM forwarder already started";
     res=false;
     break;
    case ECMServerDefs.NOT_RUNNING:
     Shell.err_string="ECM forwarder is not running";
     res=false;
     break;
   }
  }

  return res;
 }

 private static boolean cmd_conax_info(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_conax_info();

  return true;
 }

 private static boolean cmd_cw_info(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int cnt=-1;

  if (options.length==0) {
   cnt=1;
  } else

  if (options.length==1) {
   if (options[0].pure_arg()) {
    cnt=options[0].int_arg();
   }
  } else {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (cnt<0) {
   Shell.err_string="invalid arguments";
   return false;
  }

  cl.cmd_cw_info(cnt);

  return true;
 }

 private static boolean cmd_vodprops(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int id=-1;

  if (options.length>1) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (options.length==1) {
   if (options[0].pure_arg()) {
    id=options[0].int_arg();
   }
  }

  int res=cl.cmd_vodprops(id);

  if (res!=VODDefs.RES_OK) {
   switch(res) {
    case VODDefs.INVALID_RECID:
     Shell.err_string="unknown PVOD recording id";
     return false;
   }   
  }

  return true;
 }

 private static boolean cmd_vodecm(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;
  int recid=-1;
  String name=null;

  if ((options.length==0)||(options.length>2)) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (Shell.getopt(options,'v')!=null) {
   action=VODDefs.ECM_VIEW;

   if (options[0].pure_arg()) {
    recid=options[0].int_arg();
   } else {
    Shell.err_string="missing recid argument";
    return false;
   }
  } else

  if (Shell.getopt(options,'s')!=null) {
   action=VODDefs.ECM_STORE;

   if (options[0].pure_arg()) {
    recid=options[0].int_arg();
   } else {
    Shell.err_string="missing recid argument";
    return false;
   }

   Shell.Option opt=Shell.getopt(options,'s');
   name=opt.str_arg();   
  } else

  if (Shell.getopt(options,'l')!=null) {
   action=VODDefs.ECM_LOAD;

   Shell.Option opt=Shell.getopt(options,'l');
   name=opt.str_arg();   
  } else

  if (Shell.getopt(options,'u')!=null) {
   action=VODDefs.ECM_UNLOAD;
  } else {
   Shell.err_string="invalid arguments";
   return false;
  }

  int res=cl.cmd_vodecm(action,recid,name);

  if (res!=VODDefs.RES_OK) {
   switch(res) {
    case VODDefs.CANNOT_OPEN:
     Shell.err_string="cannot open ecm file";
     return false;
    case VODDefs.INVALID_RECID:
     Shell.err_string="unknown PVOD recording id";
     return false;
   }
  }

  return true;
 }

 private static boolean cmd_vodserver(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;

  if (options.length!=1) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (Shell.getopt(options,'r')!=null) {
   action=ECMServerDefs.ECMSRV_RUN;
  } else

  if (Shell.getopt(options,'s')!=null) {
   action=ECMServerDefs.ECMSRV_STOP;

  } else {
   Shell.err_string="invalid arguments";
   return false;
  }

  int status=cl.cmd_vodserver(action);

  boolean res=true;

  if (status!=ECMServerDefs.RES_OK) {
   switch(status) {
    case ECMServerDefs.ALREADY_STARTED:
     Shell.err_string="VOD server already started";
     res=false;
     break;
    case ECMServerDefs.NOT_RUNNING:
     Shell.err_string="VOD server is not running";
     res=false;
     break;
   }
  }

  return res;
 }

 private static boolean cmd_voddump(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;
  int dmx_id=-1;
  int recid=-1;
  int secs=-1;
  String filename=null;

  if (Shell.getopt(options,'r')!=null) {
   action=TSRecorderDefs.REC_RUN;

   Shell.Option opt=Shell.getopt(options,'d');

   if (opt!=null) {
    dmx_id=opt.int_arg();
   }

   opt=Shell.getopt(options,'i');

   if (opt!=null) {
    recid=opt.int_arg();
   }

   opt=Shell.getopt(options,'t');

   if (opt!=null) {
    secs=opt.int_arg();
   }

   opt=Shell.getopt(options,'f');

   if (opt!=null) {
    filename=opt.str_arg();
   }

   if (filename==null) {
    Shell.err_string="missing output filename argument";
    return false;
   }

  } else

  if (Shell.getopt(options,'s')!=null) {
   action=TSRecorderDefs.REC_STOP;

   if (options.length!=1) {
    Shell.err_string="invalid number of arguments";
    return false;
   }
  } else {
   Shell.err_string="invalid arguments";
   return false;
  }

  TSReader reader=TSReader.start(filename);

  String host=reader.get_host();
  int port=reader.get_port();

  int status=cl.cmd_voddump(action,dmx_id,recid,secs,host,port);

  boolean res=true;

  if (status!=TSRecorderDefs.RES_OK) {
   switch(status) {
    case TSRecorderDefs.UNKNOWN_RECID:
     Shell.err_string="unknown VOD recording id";
     res=false;
     break;
    case TSRecorderDefs.INVALID_DEMUX:
     Shell.err_string="invalid demux id";
     res=false;
     break;
    case TSRecorderDefs.ALREADY_STARTED:
     Shell.err_string="mpeg dump already started";
     res=false;
     break;
   }
  }

  return res;
 }

 private static boolean cmd_fakesubs(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;
  String provider=null;
  int mask=-1;

  if (options.length==1) {
   if (Shell.getopt(options,'r')!=null) {
    action=SubsFakerDefs.SF_RUN;
   } else

   if (Shell.getopt(options,'s')!=null) {
    action=SubsFakerDefs.SF_STOP;
   } else

   if (Shell.getopt(options,'v')!=null) {
    action=SubsFakerDefs.SF_VIEW;
   } else {
    Shell.err_string="invalid arguments";
    return false;
   }
  } else

  if (Shell.getopt(options,'a')!=null) {
   action=SubsFakerDefs.SF_ADD;

   Shell.Option opt=Shell.getopt(options,'p');

   if (opt!=null) {
    provider=opt.str_arg();
   } else {
    Shell.err_string="missing provider argument";
    return false;
   }
   
   opt=Shell.getopt(options,'m');

   if (opt!=null) {
    mask=opt.int_arg();
   } else {
    Shell.err_string="missing mask argument";
    return false;
   }
  } else

  if (Shell.getopt(options,'d')!=null) {
   action=SubsFakerDefs.SF_DEL;

   Shell.Option opt=Shell.getopt(options,'p');

   if (opt!=null) {
    provider=opt.str_arg();
   } else {
    Shell.err_string="missing provider argument";
    return false;
   }
   
   opt=Shell.getopt(options,'m');

   if (opt!=null) {
    mask=opt.int_arg();
   } else {
    Shell.err_string="missing mask argument";
    return false;
   }
  }

  if (action==-1) {
   Shell.err_string="invalid arguments";
   return false;
  }

  int status=cl.cmd_fakesubs(action,provider,mask);

  boolean res=true;

  if (status!=SubsFakerDefs.RES_OK) {
   switch(status) {
    case SubsFakerDefs.NOT_RUNNING:
     Shell.err_string="subscription faker is not running";
     res=false;
     break;
    case SubsFakerDefs.ALREADY_STARTED:
     Shell.err_string="subscription faker already started";
     res=false;
     break;
   }
  }

  return res;
    
 }

 private static boolean cmd_script(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String script=null;

  if ((options.length==0)||(options.length>2)) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (options[0].pure_arg()) {
   script=options[0].str_arg();
  }

  Shell.run_script(cl,script);

  return true;
 }

 private static boolean cmd_mem(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int addr=-1;
  int size=-1;

  if (options.length==1) {
   if (options[0].pure_arg()) {
    addr=options[0].int_arg();
   }
  } else

  if (options.length==2) {
   if (options[0].pure_arg()) {
    addr=options[0].int_arg();
   }

   if (options[1].pure_arg()) {
    size=options[1].int_arg();
   }
  } else {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (addr==-1) {
   Shell.err_string="missing addr argument";
   return false;
  }

  if (size==-1) {
   size=0x100;
  }

  cl.cmd_mem(addr,size);

  return true;
 }

 private static boolean cmd_tkdinput(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  boolean swap=false;
  boolean words=false;

  int input[]=new int[0x10];

  String data=null;

  if (options.length>0) {
   if (options[0].pure_arg()) {
    data=options[0].str_arg();
   }
  } 

  if (Shell.getopt(options,'s')!=null) {
   swap=true;
  }

  if (Shell.getopt(options,'w')!=null) {
   words=true;
   input=new int[4];
  }

  if (data==null) {
   Shell.err_string="missing input argument";
   return false;
  }

  StringTokenizer tokenizer=new StringTokenizer(data," ");

  int pos=0;
                
  while(tokenizer.hasMoreTokens()&&(pos<input.length)) {
   int val=(int)Long.parseLong(tokenizer.nextToken(),16);
   input[pos++]=val;
  }

  byte bytes[]=new byte[0x10];

  if (words) {
   for(int i=0;i<4;i++) {
    int val=input[i];
    bytes[4*i+0]=(byte)(val&0xff);
    bytes[4*i+1]=(byte)((val>>8)&0xff);
    bytes[4*i+2]=(byte)((val>>16)&0xff);
    bytes[4*i+3]=(byte)((val>>24)&0xff);
   }
  } else {
   for(int i=0;i<0x10;i++) {
    bytes[i]=(byte)input[i];
   }
  }

  if (swap) {
   for(int i=0;i<bytes.length;i+=4) {
    byte b0=bytes[i+0];
    byte b1=bytes[i+1];
    byte b2=bytes[i+2];
    byte b3=bytes[i+3];

    bytes[i+0]=b3;
    bytes[i+1]=b2;
    bytes[i+2]=b1;
    bytes[i+3]=b0;
   }
  }

  cl.cmd_tkdinput(bytes);

  return true;
 }


 private static boolean cmd_setcwpk(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  boolean swap=false;
  boolean words=false;

  int input[]=new int[0x10];

  String data=null;

  if (options.length>0) {
   if (options[0].pure_arg()) {
    data=options[0].str_arg();
   }
  } 

  if (Shell.getopt(options,'s')!=null) {
   swap=true;
  }

  if (Shell.getopt(options,'w')!=null) {
   words=true;
   input=new int[4];
  }

  if (data==null) {
   Shell.err_string="missing input argument";
   return false;
  }

  StringTokenizer tokenizer=new StringTokenizer(data," ");

  int pos=0;
                
  while(tokenizer.hasMoreTokens()&&(pos<input.length)) {
   int val=(int)Long.parseLong(tokenizer.nextToken(),16);
   input[pos++]=val;
  }

  byte bytes[]=new byte[0x10];

  if (words) {
   for(int i=0;i<4;i++) {
    int val=input[i];
    bytes[4*i+0]=(byte)(val&0xff);
    bytes[4*i+1]=(byte)((val>>8)&0xff);
    bytes[4*i+2]=(byte)((val>>16)&0xff);
    bytes[4*i+3]=(byte)((val>>24)&0xff);
   }
  } else {
   for(int i=0;i<0x10;i++) {
    bytes[i]=(byte)input[i];
   }
  }

  if (swap) {
   for(int i=0;i<bytes.length;i+=4) {
    byte b0=bytes[i+0];
    byte b1=bytes[i+1];
    byte b2=bytes[i+2];
    byte b3=bytes[i+3];

    bytes[i+0]=b3;
    bytes[i+1]=b2;
    bytes[i+2]=b1;
    bytes[i+3]=b0;
   }
  }

  cl.cmd_setcwpk(bytes);

  return true;
 }

 private static boolean cmd_tkdreg(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  boolean swap=false;
  boolean words=false;

  int input[]=new int[0x10];

  String data=null;
  int idx=-1;

  if (options.length<2) {
   Shell.err_string="missing input argument";
   return false;
  }

  if (options[0].pure_arg()) {
   idx=options[0].int_arg();
  }

  if (options[1].pure_arg()) {
   data=options[1].str_arg();
  }

  if (Shell.getopt(options,'s')!=null) {
   swap=true;
  }

  if (Shell.getopt(options,'w')!=null) {
   words=true;
   input=new int[4];
  }

  if ((data==null)||(idx<0)) {
   Shell.err_string="missing input argument";
   return false;
  }

  StringTokenizer tokenizer=new StringTokenizer(data," ");

  int pos=0;
                
  while(tokenizer.hasMoreTokens()&&(pos<input.length)) {
   int val=(int)Long.parseLong(tokenizer.nextToken(),16);
   input[pos++]=val;
  }

  byte bytes[]=new byte[0x10];

  if (words) {
   for(int i=0;i<4;i++) {
    int val=input[i];
    bytes[4*i+0]=(byte)(val&0xff);
    bytes[4*i+1]=(byte)((val>>8)&0xff);
    bytes[4*i+2]=(byte)((val>>16)&0xff);
    bytes[4*i+3]=(byte)((val>>24)&0xff);
   }
  } else {
   for(int i=0;i<0x10;i++) {
    bytes[i]=(byte)input[i];
   }
  }

  if (swap) {
   for(int i=0;i<bytes.length;i+=4) {
    byte b0=bytes[i+0];
    byte b1=bytes[i+1];
    byte b2=bytes[i+2];
    byte b3=bytes[i+3];

    bytes[i+0]=b3;
    bytes[i+1]=b2;
    bytes[i+2]=b1;
    bytes[i+3]=b0;
   }
  }

  cl.cmd_tkdreg(idx,bytes);

  return true;
 }

 private static boolean cmd_tkdregs(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_tkdregs();

  return true;
 }

 private static boolean cmd_tkdcmd(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int cmd=-1;

  if (options.length==1) {
   if (options[0].pure_arg()) {
    cmd=options[0].int_arg();
   }
  } else {
   Shell.err_string="missing cmd argument";
   return false;
  }

  cl.cmd_tkdcmd(cmd);

  return true;
 }

 private static int[] load_codefile(String name) {
  int tkdcode[]=null;

  try {
   int len=(int)(new File(name)).length();

   if ((len%4)!=0) return null;

   int size=len/4;

   int tmp[]=new int[size];   

   FileInputStream fis=new FileInputStream(name);

   for(int i=0;i<size;i++) {
    int b1=fis.read()&0xff;
    int b2=fis.read()&0xff;
    int b3=fis.read()&0xff;
    int b4=fis.read()&0xff;

    tmp[i]=(b4<<24)|(b3<<16)|(b2<<8)|b1;
   }

   tkdcode=tmp;
  } catch(Throwable t) {}

  return tkdcode;
 }

 private static boolean cmd_tkdrun(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String codefile=null;

  if (options.length==1) {
   if (options[0].pure_arg()) {
    codefile=options[0].str_arg();
   }
  } else {
   Shell.err_string="missing codefile argument";
   return false;
  }

  int data[]=load_codefile(codefile);

  if (data==null) {
   Shell.err_string="invalid codefile";
   return false;
  }

  int tkdcode[]=null;
  int tkddata[]=null;

  try {
   int pos=0;

   int csize=data[pos++];
   tkdcode=new int[csize];

   for(int i=0;i<csize;i++) {
    tkdcode[i]=data[pos++];
   }

   int dsize=data[pos++];
   tkddata=new int[dsize];

   for(int i=0;i<dsize;i++) {
    tkddata[i]=data[pos++];
   }

  } catch(Throwable t) {}

  if ((tkdcode==null)||(tkddata==null)) {
   Shell.err_string="invalid codefile";
   return false;
  }

  cl.cmd_tkdrun(tkdcode,tkddata);

  return true;
 }

 private static boolean cmd_tkdmem(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int off=-1;
  int size=-1;

  if (options.length==1) {
   if (options[0].pure_arg()) {
    off=options[0].int_arg();
   }
  } else

  if (options.length==2) {
   if (options[0].pure_arg()) {
    off=options[0].int_arg();
   }

   if (options[1].pure_arg()) {
    size=options[1].int_arg();
   }
  } else {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (off==-1) {
   Shell.err_string="missing off argument";
   return false;
  }

  if (size==-1) {
   size=0x100;
  }

  cl.cmd_tkdmem(off,size);

  return true;
 }

 private static boolean cmd_tkdpeek(ConsoleIf cl,Shell.Option[] options,int size) throws Throwable {
  int off=-1;

  if (options.length!=1) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (options[0].pure_arg()) {
   off=options[0].int_arg();
  }

  if (off==-1) {
   Shell.err_string="missing off argument";
   return false;
  }

  cl.cmd_tkdpeek(off,size);

  return true;
 }

 private static boolean cmd_tkdpoke(ConsoleIf cl,Shell.Option[] options,int size) throws Throwable {
  int off=-1;
  int val=-1;

  if (options.length!=2) {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (options[0].pure_arg()) {
   off=options[0].int_arg();
  }

  if (options[1].pure_arg()) {
   val=options[1].int_arg();
  }

  if ((off==-1)||(val==-1)) {
   Shell.err_string="missing off argument";
   return false;
  }

  cl.cmd_tkdpoke(off,val,size);

  return true;
 }

 private static boolean cmd_iomem(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int off=-1;
  int size=-1;

  if (options.length==1) {
   if (options[0].pure_arg()) {
    off=options[0].int_arg();
   }
  } else

  if (options.length==2) {
   if (options[0].pure_arg()) {
    off=options[0].int_arg();
   }

   if (options[1].pure_arg()) {
    size=options[1].int_arg();
   }
  } else {
   Shell.err_string="invalid number of arguments";
   return false;
  }

  if (off==-1) {
   Shell.err_string="missing off argument";
   return false;
  }

  if (size==-1) {
   size=0x100;
  }

  cl.cmd_iomem(off,size);

  return true;
 }

 private static boolean cmd_stbprops(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_stbprops();

  return true;
 }

 private static boolean cmd_isolate(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_isolate();

  return true;
 }

 private static boolean cmd_scwatch(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  int action=-1;

  if (options.length==0) {
   action=SCWatchDefs.SC_STATUS;
  } else

  if (Shell.getopt(options,'r')!=null) {
   action=SCWatchDefs.SC_RUN;
  } else

  if (Shell.getopt(options,'s')!=null) {
   action=SCWatchDefs.SC_STOP;
  }

  if (action==-1) {
   Shell.err_string="invalid option";
   return false;
  }

  boolean status=cl.cmd_scwatch(action);

  if (action!=SCWatchDefs.SC_STATUS) {
   if (!status) {
    switch(action) {
     case SCWatchDefs.SC_RUN:
      Shell.err_string="cannot start SC watch";
      break;

     case SCWatchDefs.SC_STOP:
      Shell.err_string="cannot stop SC watch";
      break;
    }
    return false;
   }
  };

  return true;
 }

 private static boolean cmd_nostbprops(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_nostbprops();

  return true;
 }

 private static boolean cmd_stbprop(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String prop=null;
  String val=null;

  if (options.length==2) {
   if (options[0].pure_arg()) {
    prop=options[0].str_arg();
   }

   if (options[1].pure_arg()) {
    val=options[1].str_arg();
   }
  } else {
   Shell.err_string="missing arguments";
   return false;
  }

  if ((prop==null)||(val==null)) {
   Shell.err_string="missing arguments";
   return false;   
  }

  cl.cmd_stbprop(prop,val);

  return true;
 }

 private static boolean cmd_cardaddr(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String addr=null;

  if (options.length==1) {
   if (options[0].pure_arg()) {
    addr=options[0].str_arg();
   }
  } else {
   Shell.err_string="missing string argument";
   return false;
  }

  cl.cmd_cardaddr(addr);

  return true;
 }

 private static boolean cmd_macaddr(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String addr=null;

  if (options.length==1) {
   if (options[0].pure_arg()) {
    addr=options[0].str_arg();
   }
  } else {
   Shell.err_string="missing string argument";
   return false;
  }

  cl.cmd_macaddr(addr);

  return true;
 }

 private static boolean cmd_serial(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String sn=null;

  if (options.length==1) {
   if (options[0].pure_arg()) {
    sn=options[0].str_arg();
   }
  } else {
   Shell.err_string="missing string argument";
   return false;
  }

  cl.cmd_serial(sn);

  return true;
 }

 private static boolean cmd_getcwpk(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  System.out.println("REMOVE SMARTCARD FROM STB AND PRESS ENTER");

  BufferedReader input=new BufferedReader(new InputStreamReader(System.in,"utf-8"));
  input.readLine();

  cl.cmd_getcwpk();

  System.out.println("INSERT SMARTCARD BACK INTO STB");

  return true;
 }

 private static boolean cmd_secfuses(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  cl.cmd_secfuses();

  return true;
 }

 private static boolean cmd_ivodurl(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String url=null;

  Shell.Option opt=Shell.getopt(options,'s');

  if (opt!=null) {
   url=opt.str_arg();
  }

  cl.cmd_ivodurl(url);

  return true;
 }

 private static boolean cmd_test(ConsoleIf cl,Shell.Option[] options) throws Throwable {
  String str=null;

  if (options.length==1) {
   if (options[0].pure_arg()) {
    str=options[0].str_arg();
   }
  } else {
   Shell.err_string="missing string argument";
  }

  cl.cmd_test(str);

  return true;
 }

 public static boolean run_cmd(ConsoleIf cl,Shell.Cmd cmd) throws Throwable {
  boolean res=true;

  CmdDesc desc=cmd.desc;

  if (box_command(desc.id)) {
   if (!cl.client_connected()) {
    Shell.err_string="no box selected for target command";
    return false;
   }

  } else {
   switch(desc.id) {
    case Proto.CMD_LIST:
     res=cmd_list(cl,cmd.options);
     break;
    case Proto.CMD_GO:
     res=cmd_go(cl,cmd.options);
     break;
    case Proto.CMD_EXIT:
     res=cmd_exit(cl,cmd.options);
     break;
    case Proto.CMD_ECMROUTES:
     res=cmd_ecmroutes(cl,cmd.options);
     break;
   }

   return res;
  }

  switch(desc.id) {
   case Proto.CMD_SYS_INFO:
    res=cmd_sys_info(cl,cmd.options);
    break;
   case Proto.CMD_CARD_INFO:
    res=cmd_card_info(cl,cmd.options);
    break;

   case Proto.CMD_SYS_PWD:
    res=cmd_sys_pwd(cl,cmd.options);
    break;
   case Proto.CMD_JVM_PWD:
    res=cmd_jvm_pwd(cl,cmd.options);
    break;

   case Proto.CMD_SYS_CHDIR:
    res=cmd_sys_chdir(cl,cmd.options);
    break;
   case Proto.CMD_JVM_CHDIR:
    res=cmd_jvm_chdir(cl,cmd.options);
    break;

   case Proto.CMD_SYS_DIR:
    res=cmd_sys_dir(cl,cmd.options);
    break;
   case Proto.CMD_JVM_DIR:
    res=cmd_jvm_dir(cl,cmd.options);
    break;

   case Proto.CMD_SYS_GET:
    res=cmd_sys_get(cl,cmd.options);
    break;

   case Proto.CMD_JVM_GET:
    res=cmd_jvm_get(cl,cmd.options);
    break;

   case Proto.CMD_SYS_PUT:
    res=cmd_sys_put(cl,cmd.options);
    break;

   case Proto.CMD_JVM_PUT:
    res=cmd_jvm_put(cl,cmd.options);
    break;

   case Proto.CMD_SYS_DEL:
    res=cmd_sys_del(cl,cmd.options);
    break;

   case Proto.CMD_JVM_DEL:
    res=cmd_jvm_del(cl,cmd.options);
    break;

   case Proto.CMD_SYS_FSDUMP:
    res=cmd_sys_dumpfs(cl,cmd.options);
    break;

   case Proto.CMD_JVM_FSDUMP:
    res=cmd_jvm_dumpfs(cl,cmd.options);
    break;

   case Proto.CMD_SYS_MKDIR:
    res=cmd_sys_mkdir(cl,cmd.options);
    break;

   case Proto.CMD_JVM_MKDIR:
    res=cmd_jvm_mkdir(cl,cmd.options);
    break;

   case Proto.CMD_SYS_RMDIR:
    res=cmd_sys_rmdir(cl,cmd.options);
    break;

   case Proto.CMD_JVM_RMDIR:
    res=cmd_jvm_rmdir(cl,cmd.options);
    break;

   case Proto.CMD_ROOT:
    res=cmd_root(cl,cmd.options);
    break;

   case Proto.CMD_ID:
    res=cmd_id(cl,cmd.options);
    break;

   case Proto.CMD_OUTPUT:
    res=cmd_output(cl,cmd.options);
    break;

   case Proto.CMD_JVM_THREADS:
    res=cmd_jvm_threads(cl,cmd.options);
    break;

   case Proto.CMD_KDUMP:
    res=cmd_kdump(cl,cmd.options);
    break;

   case Proto.CMD_OPENURL:
    res=cmd_openurl(cl,cmd.options);
    break;

   case Proto.CMD_QUIT:
    res=cmd_quit(cl,cmd.options);
    break;

   case Proto.CMD_PLAY:
    res=cmd_play(cl,cmd.options);
    break;

   case Proto.CMD_AV_INFO:
    res=cmd_avinfo(cl,cmd.options);
    break;

   case Proto.CMD_SRV_INFO:
    res=cmd_srvinfo(cl,cmd.options);
    break;

   case Proto.CMD_SYS_CAT:
    res=cmd_sys_cat(cl,cmd.options);
    break;

   case Proto.CMD_JVM_CAT:
    res=cmd_jvm_cat(cl,cmd.options);
    break;

   case Proto.CMD_SERVICE:
    res=cmd_service(cl,cmd.options);
    break;

   case Proto.CMD_DVR_INFO:
    res=cmd_dvrinfo(cl,cmd.options);
    break;

   case Proto.CMD_JVM_PROPS:
    res=cmd_jvm_props(cl,cmd.options);
    break;

   case Proto.CMD_DIALOG:
    res=cmd_dialog(cl,cmd.options);
    break;

   case Proto.CMD_HTTPSNIFF:
    res=cmd_httpsniff(cl,cmd.options);
    break;

   case Proto.CMD_SYS_PS:
    res=cmd_sys_ps(cl,cmd.options);
    break;

   case Proto.CMD_KEYS:
    res=cmd_keys(cl,cmd.options);
    break;

   case Proto.CMD_URIMAP:
    res=cmd_urimap(cl,cmd.options);
    break;

   case Proto.CMD_SUBS_INFO:
    res=cmd_subsinfo(cl,cmd.options);
    break;

   case Proto.CMD_EPG_INFO:
    res=cmd_epginfo(cl,cmd.options);
    break;

   case Proto.CMD_CAPTURE:
    res=cmd_capture(cl,cmd.options);
    break;

   case Proto.CMD_MPEGSNIFF:
    res=cmd_mpegsniff(cl,cmd.options);
    break;

   case Proto.CMD_PAT:
    res=cmd_pat(cl,cmd.options);
    break;

   case Proto.CMD_PMT:
    res=cmd_pmt(cl,cmd.options);
    break;

   case Proto.CMD_DMESG:
    res=cmd_dmesg(cl,cmd.options);
    break;

   case Proto.CMD_REBOOT:
    res=cmd_reboot(cl,cmd.options);
    break;

   case Proto.CMD_INVOICES:
    res=cmd_invoices(cl,cmd.options);
    break;

   case Proto.CMD_DSMCCMOUNT:
    res=cmd_dsmccmount(cl,cmd.options);
    break;

   case Proto.CMD_SSU_INFO:
    res=cmd_ssuinfo(cl,cmd.options);
    break;

   case Proto.CMD_EMMBLOCK:
    res=cmd_emmblock(cl,cmd.options);
    break;

   case Proto.CMD_KEYINFO:
    res=cmd_keyinfo(cl,cmd.options);
    break;

   case Proto.CMD_UPGDNL:
    res=cmd_upgdnl(cl,cmd.options);
    break;

   case Proto.CMD_DVRMGR:
    res=cmd_dvrmgr(cl,cmd.options);
    break;

   case Proto.CMD_EMMSNIFF:
    res=cmd_emmsniff(cl,cmd.options);
    break;

   case Proto.CMD_MPEGDUMP:
    res=cmd_mpegdump(cl,cmd.options);
    break;

   case Proto.CMD_HDCP_INFO:
    res=cmd_hdcpinfo(cl,cmd.options);
    break;

   case Proto.CMD_CHMOD:
    res=cmd_chmod(cl,cmd.options);
    break;

   case Proto.CMD_CHOWN:
    res=cmd_chown(cl,cmd.options);
    break;

   case Proto.CMD_EXEC:
    res=cmd_exec(cl,cmd.options);
    break;

   case Proto.CMD_FWFLUSH:
    res=cmd_fwflush(cl,cmd.options);
    break;

   case Proto.CMD_EMMLOAD:
    res=cmd_emmload(cl,cmd.options);
    break;

   case Proto.CMD_ECMRECEIVE:
    res=cmd_ecmreceive(cl,cmd.options);
    break;

   case Proto.CMD_ECMFORWARD:
    res=cmd_ecmforward(cl,cmd.options);
    break;

   case Proto.CMD_CONAX_INFO:
    res=cmd_conax_info(cl,cmd.options);
    break;

   case Proto.CMD_CW_INFO:
    res=cmd_cw_info(cl,cmd.options);
    break;

   case Proto.CMD_VODPROPS:
    res=cmd_vodprops(cl,cmd.options);
    break;

   case Proto.CMD_VODECM:
    res=cmd_vodecm(cl,cmd.options);
    break;

   case Proto.CMD_VODSERVER:
    res=cmd_vodserver(cl,cmd.options);
    break;

   case Proto.CMD_VODDUMP:
    res=cmd_voddump(cl,cmd.options);
    break;

   case Proto.CMD_FAKESUBS:
    res=cmd_fakesubs(cl,cmd.options);
    break;

   case Proto.CMD_SCRIPT:
    res=cmd_script(cl,cmd.options);
    break;

   case Proto.CMD_MEM:
    res=cmd_mem(cl,cmd.options);
    break;

   case Proto.CMD_TKDINPUT:
    res=cmd_tkdinput(cl,cmd.options);
    break;

   case Proto.CMD_SETCWPK:
    res=cmd_setcwpk(cl,cmd.options);
    break;

   case Proto.CMD_TKDREG:
    res=cmd_tkdreg(cl,cmd.options);
    break;

   case Proto.CMD_TKDREGS:
    res=cmd_tkdregs(cl,cmd.options);
    break;

   case Proto.CMD_TKDCMD:
    res=cmd_tkdcmd(cl,cmd.options);
    break;

   case Proto.CMD_TKDRUN:
    res=cmd_tkdrun(cl,cmd.options);
    break;

   case Proto.CMD_TKDMEM:
    res=cmd_tkdmem(cl,cmd.options);
    break;

   case Proto.CMD_TKDPEEK8:
    res=cmd_tkdpeek(cl,cmd.options,1);
    break;

   case Proto.CMD_TKDPEEK16:
    res=cmd_tkdpeek(cl,cmd.options,2);
    break;

   case Proto.CMD_TKDPEEK32:
    res=cmd_tkdpeek(cl,cmd.options,4);
    break;

   case Proto.CMD_TKDPOKE8:
    res=cmd_tkdpoke(cl,cmd.options,1);
    break;

   case Proto.CMD_TKDPOKE16:
    res=cmd_tkdpoke(cl,cmd.options,2);
    break;

   case Proto.CMD_TKDPOKE32:
    res=cmd_tkdpoke(cl,cmd.options,4);
    break;

   case Proto.CMD_IOMEM:
    res=cmd_iomem(cl,cmd.options);
    break;

   case Proto.CMD_STBPROPS:
    res=cmd_stbprops(cl,cmd.options);
    break;

   case Proto.CMD_ISOLATE:
    res=cmd_isolate(cl,cmd.options);
    break;

   case Proto.CMD_SCWATCH:
    res=cmd_scwatch(cl,cmd.options);
    break;

   case Proto.CMD_NOSTBPROPS:
    res=cmd_nostbprops(cl,cmd.options);
    break;

   case Proto.CMD_STBPROP:
    res=cmd_stbprop(cl,cmd.options);
    break;

   case Proto.CMD_CARDADDR:
    res=cmd_cardaddr(cl,cmd.options);
    break;

   case Proto.CMD_MACADDR:
    res=cmd_macaddr(cl,cmd.options);
    break;

   case Proto.CMD_SERIAL:
    res=cmd_serial(cl,cmd.options);
    break;

   case Proto.CMD_GETCWPK:
    res=cmd_getcwpk(cl,cmd.options);
    break;

   case Proto.CMD_SECFUSES:
    res=cmd_secfuses(cl,cmd.options);
    break;

   case Proto.CMD_IVODURL:
    res=cmd_ivodurl(cl,cmd.options);
    break;

   case Proto.CMD_TEST:
    res=cmd_test(cl,cmd.options);
    break;
  }

  return res;
 }
}
