Friday, October 17, 2014

Mount windows shared folder in linux

On Windows

If no folder is shared, share a folder on windows machine by running
C:\> net share toLinux=c:\shared\toLinux /grant:windows-login-id,read
 Verify if the share is visible
C:\> net share

On SuSE

If mount.cifs is not installed, install it by running
$ zypper install cifs-utils 
Create a mount point for mounting the shared folder by running
$ mkdir /mnt/fromWindows 
Now, mount the Windows shared folder on Linux by running below command and provide password when prompted
$ mount -t cifs -o username=windows-login-id windows-host:/toLinux /mnt/fromWindows 
Verify if the mount is listed by running
$ mount 
If successfully mounted, the files from Windows folder c:\shared\toLinux can be accessed in Linux folder /mnt/fromWindows
$ ls /mnt/fromWindows

On Ubuntu

Substitute these commands in the respective places of above section, On SuSE.
 
$ apt-get install cifs-utils 
 
$ mkdir /mnt/fromWindows 
 
$ mount -t cifs -o username=windows-login-id //windows-host/toLinux /mnt/fromWindows 
 
$ mount 
 
$ ls /mnt/fromWindows

Friday, February 06, 2009

Password Prompt In Java Console Application

The most wanted feature in Java has been finally made available - console based application to process password entry without echoing on console. If you were a C/C++ programmer, you might have used getch() to read password from console without revealing what the user is typing on the console.

This enhancement request was tracked from 1.1 release of Java and now resolved in 1.6 release. The implementation is to get an access to Console and then use appropriate methods. A quick code snippet:
char[] password=System.console().readPassword("Enter password:", new Object[0]);

Console instance has to be obtained from System through console() method, not like System.in or System.out instance variable. This is because, the host application may have cases that there is no supported console available and the method would return null. Hence the above code should be actually written as:
Console console=System.console();
if (null!=console){
password=console.readPassword("Enter password:", new Object[0]);
}else{
throw IOException("No console available");
}

Why char[] is returned? Garbage collection won't clear the content of freed memory. If it is an array of character, the values are in memory and hence can be overwritten after use.
//after use
java.util.Arrays.fill(password, ' ');

What is the need for the arguments? It is just to ease the use of this function through these parameters. First argument is a format string which can have format specifiers like %s, %d and so on. The second argument is the data for those place holders specified in format string.
Object[] params=new Object[2]; //we will be using 2 variable data while prompting
params[0]=5; //auto boxing
params[1]="th attempt,";
console.readPassword("[%04d %s] password please:", params);

For simple use, there is an overloaded method with no argument:
console.readPassword();

Other usability features:
console.readLine(); //no need to construct many io classes to do a plain readLine.
console.printf(format, params); //same as c printf
console.flush(); //flush the output buffer to be printed immediately

No more waiting, start using this feature...

Monday, December 15, 2008

Automating DOS Command Shell (batch file) multiple Inputs

Another wonderful problem I had been working was automate the command line input of a batch file. I have used redirect and pipe in both <x>nix and Windows platforms but had to spend more hours in troubleshooting this particular issue as there was no generally knows answers.

I've a batch file which takes couple of input by prompting at the shell. The content of the batch file named 'askquestion.bat' is given below:

@echo off
:step1
set A1=
set A2=
set /a COUNT=1

:step2
set /p A1=What is your name?
echo Hi %A1%,

:step3
set /p A2=How old are you?
if "%A2%"=="" set A2=0
set /a A2=1+("%A2%")-1 > nul 2>&1
if not ERRORLEVEL 0 set A2=0
if /i "%1"=="noval" goto :step4

if %A2% LEQ 0 (
echo %A1%, '%A2%' may not be a valid age, please try again.
set /a COUNT+=1
if %COUNT% GEQ 5 goto :step4
goto :step3
)

:step4
if %A2% LEQ 10 echo Welcome kid
echo Name:%A1%, Age:%A2%
echo bye
set A1=
set A2=
set COUNT=

It prompts for two inputs - name and age. But the age could be validated and prompted more than once if required. For avoiding infinite loop, the validation will be done for 5 wrong retries.

The common attempt to automate the input would be though using pipe. For single input, we can use echo
c:\>echo Thilak | askquestion.bat
This does not give input for second question and so the script runs on the unfinished (not sure what state it will be) pipe without input causing the script to run 5 retries (or infinitely without that retries check).

How to give multiple input?
Attempt 1:
c:\>echo Thilak\n35 | askquestion.bat
Attempt 2:
c:\>for %a in (Thilak 35) do echo %a | askquestion.bat
Attempt 3:
Create a file with answers in each line and save with a name answer.txt
c:\>type answer.txt | askquestion.bat
Attempt 4:
c:\>echo Thilak & echo 32 | askquestion.bat
Attemp 5:
c:\>(echo Thilak & echo 32) | askquestion.bat

Most of the common approaches failed. This mean to me that there it is a challenge for me. I took it up and started working on it. Google-ing and forum postings did not give answer to the specific scenario.

Dragged further by the attempt 3, I used dir instead of type. Luckily there were lots of files in that folder and my first observation itself gave me a clue.
c:\>dir | askquestion.bat

The important observation is that, the script received it's second input. And the input was taken after 1023 characters. So, this number is a well know one and I was able to do few assumptions quickly that the DOS shell input buffer is of size 1024 and the last character has to be NULL '\0' and so, 1023 character can be taken as input and flushed to receive the next set of inputs.

Now I started changing my answer.txt to have each answer to be of 1023 characters in each line. Line should be terminated with \n (\r\f or [cr][lf]). Basically I used spaces as the filler and it reflected immediately as a wrong choice. I should have used '\0' (NULL) as the fillers, but how? Then I tried another approach - First line with the actual data followed with dummy lines to fill the rest of the 1023 bytes and then the next actual data. During this, I realized that the last answer does not require to follow with the filler.

This was hard to get automated and did not spend much time in using the shell commands. I used to do Perl scripting and thought of using it here. The file name is 'ansquestion.pl'.

my @ans=("Thilak", "10");
open(QUESTION, "|cmd.exe /c askquestion.bat") or die "psht! problem while open.\n";
foreach(@ans){
$|=1;
print QUESTION pack("a1023", ($_, "\n"));
}
close(QUESTION) or die "problem while close";

The Perl pack() method was very handy to solve the filler issue. In the above code, the pack method creates a character byte stream of length 1023 filled with the list of arguments and remaining bytes with NULL. Following command would fulfill my requirement.

c:\>ansquestion.pl | askquestion.bat

Hopefully, someone can find a batch file to generate this output using for, if and echo commands.

Friday, March 07, 2008

My Mobile Story

In today's world, people are more vulnerable to new technologies so easily. I mean it as I could see a drastic adoption of Mobile phone over the land line phone. It all started with only one convenience - be reachable on move. And now, that has come to a stage where the rest of the technology needs to live in this piece of solution.
When I was out of my college, I saw mobile phone which were bulky like walkie-talkie. I heard from the owners that the call rates were arbitrarily high that they use it to get and give the famous 'missed call'. It was used much like a Pager. I was not excited by this.
The time was changing and 'incoming calls' were announced as free of cost. By that time, I got engaged. And badly felt the need for a way to have calls in privacy. Went to a shop in Bangalore with one of my friend and bought a then slim & flip model mobile phone - Ericsson T28s along with connection from SPICE network. I did not have enough information like today to search for the best mobile. This model did attracted me at the first sight. I used it to the most but for voice calls, SMS and address book only. It worked well for 2 years of use until my kid spoiled it with water. The body of the phone was so sturdy that even after multiple drops it did not have any scratch or broken edge.
It was time to get a new phone, now the reason has become that just to be reachable. I went for another best of class mobile - Nokia 3315. I believe this model to be a best as the casing and features were just what I needed. You may be surprised, I used this phone for more than 6 years and that too without changing the original battery. When I 'packed' it, the battery was keeping my phone alive for 3 full days max or 60 min of talk time.
Recently I went for a new mobile, but this time my requirements were different. Professional and personal needs. I did many analysis with many from old to latest 'available' models. Four were my final choices - Moto Rokr E6, Sony Ericsson P1, HTC Touch and Nokia E50. Finally Nokia E50 won the race due to it's compact form, price, business features and software availability. I'm still a satisfied customer of SPICE network and hence did not change it yet.

Monday, February 25, 2008

Java and Perl

When launching an executable created using Perl archive mechanism or kick starting the Perl interpreter from within Java, one might get into an issue of improper i/o handling in their Perl modules. I've not come across a solution so far. The temporary workaround tried is to launch the Perl application in a command shell like
cmd /start /wait <path to perl.exe> <arguments>

Java and Plugin for Win Runner

There was an interesting issue identified, that Win Runner with 1.5 Java Plugin is able to sense 1st window but not the second. It works well if the tool is executed for second time.
Win Runner was launching the Java application and tries to sense a window and its controls. The Java application was using 1.5 private JRE. Private JRE is nothing but bundling a separate copy of JRE along with an application. Public JRE is the one (but mostly many versions of it) available in C:\Program Files\Java\ folder.

Java 1.5 and later versions come with a feature for quick startup. This feature does have a penalty at the first run while creating a jsa file required for quicker startup in later runs. In the context of the issue, the Java application was taking time to show the first window. The Win Runner script used for detecting the window was able to wait and detect it. But there was a time gap for showing second window. In this period Win Runner detection API comes out with -1 (unknown error). After investigation, the first JVM launches another JVM and when there is a point where no JVM is available for Win Runner Java Plugin to work with, it is skipping the process of detecting the Java window by returning -1. There are many valid error return values for the detecting API but -1 is not part of it and code gets skipped in the execution flow.

Adding a validation for -1 and looping the check until some time frame resolved the issue. Looping is important here as Win Runner APIs do have timeout argument. But will not be effective as there is no JVM attached.

Thursday, February 08, 2007

Importing JavaScript file in another

Including an existing code should help almost every programmer from rewritting and testing it again. With any common programming language there will be either an include or import statement. When I tried to get a similar support in JavaScript, the feature is not there yet !!!

Why wait for someone to provide the support ? With small changes in the common javascript code and a javascript function which will import that script file will do the magic. Ofcourse, the usage is very limited but surely can be extended as your own wish and imagination. This script will currently work on Microsoft Windows' Scripting Environment.

The javascript function which imports another JavaScript file:

/////////////////////////////////////////////////////////////////////////////////////////
// SUPPORTED SYNTAX
//
// //FUNCTION-START
// function fn_name([args[,args]]){
// }
// //FUNCTION-END
//
// //GLOBAL-START
// var g_name;
// fn_name();
// //GLOBAL-END
//
// NOTE: Multiline comment (/**/) is not stripped.
// Singleline comment (//) and empty lines are stripped.
//
// USAGE: var global_stmt=importjs("path2js");
// if (global_stmt!="") eval(global_stmt);
//
////////////////////////////////////////////////////////////////////////////////////////
var ____err_count=0;
function importjs(filename){
var line_num=0
var file=(WScript.CreateObject("Scripting.FileSystemObject")).OpenTextFile(filename, 1, false, 0);
var fn_re=/^\s*function\s+(\S+)\s*\(([^\)]*)\)(.*)/g;
var script="",line="",prototype="",global="";
var fn, gen_gl=false, gen_fn=true;
while(true){
try{line=file.Readline();line_num++;}catch(fileread){break;}
if(null!=line.match(/FUNCTION.START/g)){gen_fn=true;continue;}
if(null!=line.match(/FUNCTION.END/g)){gen_fn=false;continue;}
if(null!=line.match(/GLOBAL.START/g)){gen_gl=true;continue;}
if(null!=line.match(/GLOBAL.END/g)){gen_gl=false;continue;}
if((line=line.replace(/(^|[^:])\/\/.*$/g,"$1"))=="")continue;//comment but not url
if(line.replace(/^\s+/g,"")=="")continue;//empty line
if(gen_gl){
try{
global+=("\n"+line);
}catch(e){
____err_count++;
WScript.Echo("error:"+e.message+" in "+filename+":"+line_num);
WScript.Echo(line);
}
}else if(gen_fn){
fn=fn_re.exec(line);
if (fn!=null && fn.length==4){
var arg="";
if(fn[2]!=null && fn[2]!=""){
var args=(fn[2]).split(", ");
for(i in args){
if(i>0) arg+=",";
arg+=("\""+args[i].replace(/\s+/g, "")+"\"");
}
if (arg!="") arg+=",";
}
if (prototype!=""){
try{
eval(prototype+script+"+\"\");");
}catch(e){
____err_count++;
WScript.Echo("error:"+e.message+" in "+filename+":"+line_num);
WScript.Echo(prototype+script+"+\"\");");
}
}
prototype=fn[1]+"=new Function("+arg+"\"";
script=fn[3].replace(/("|\\|')/g, "\\$1")+"\"";//"
}else{
script+=("\n+\""+line.replace(/("|\\|')/g, "\\$1")+"\"");//"
}
}
}
if (prototype!=""){
try{
eval(prototype+script+"+\"\");");
}catch(e){
____err_count++;
WScript.Echo("error:"+e.message+" in "+filename+":"+line_num);
WScript.Echo(prototype+script+"+\"\");");
}
}
//WScript.Echo(""+____err_count+" error(s) found.");
return global;
}


The function call usage:
var g=importjs("importable.js");
if(g!="") eval(g);

After the file has been imported, the function or global variables from the other file can be accessed from this importing script file as usual.

A sample "importable.js" content:
//GLOBAL-START
var g_global=true;
//GLOBAL-END

function deinit( one , two){
WScript.Echo("deinit "+one+" "+two);
}

function init(){
WScript.Echo("init");
}

function alert(message){
WScript.Echo("alert "+message);
}

//GLOBAL-START
WScript.Echo("global - single line statement");
if (true) {
var local="localvalue";
WScript.Echo("global - multi line (if) statement");
alert("global - calling another function (alert) in global scope");
alert("global - accessing a global variable - g_global="+g_global);
alert("global - accessing a local variable - local="+local);
}
//GLOBAL-END

WScript.Echo("global - single line statement, but will not be executed");

Sure, you could find bugs in this code. Please post them :)