How to get the current umask value from Java? - java

I am running java 7 applications on unix machines. Is there a way to get the current umask value in pure java ?
In C I would use a combination of umask system calls, but I don't think I can call that in Java without resorting to JNI. Is there another approach ?
Edit: Here is a C example (from GUN libc docs):
mode_t
read_umask (void)
{
mode_t mask = umask (0);
umask (mask);
return mask;
}

A simple solution, if there is no Class/Method to get the umask, why don't you get it before call java and pass as a property?

Can you clarify? Do you want to read the umask of the application(the current java process)? Or do you want to read the umask value of some files on the file system?
You can use NIO (the used code is from the javadocs) to get some file attributes, or you can execute a shell command, since the process created with Runtime.execute inherits the umask of it's creator process.
So you should be able to solve your problem without the use of JNI.
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermissions;
public class Test {
private static final String COMMAND = "/bin/bash -c umask -S";
public static String getUmask() {
final Runtime runtime = Runtime.getRuntime();
Process process = null;
try {
process = runtime.exec(COMMAND);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String umask = reader.readLine();
if (process.waitFor() == 0)
return umask;
} catch (final IOException e) {
e.printStackTrace();
} catch (final InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
return "";
}
public static void main(String[] args) throws IOException {
/*
* NIO
*/
PosixFileAttributes attrs = Files.getFileAttributeView(Paths.get("testFile"), PosixFileAttributeView.class)
.readAttributes();
System.out.format("%s %s%n", attrs.owner().getName(), PosixFilePermissions.toString(attrs.permissions()));
/*
* execute shell command to get umask of current process
*/
System.out.println(getUmask());
}
}

Related

I can't run a python script from java and I think it's because the script does not have execute permissions

I'm trying to run a python script whenever a button on my gui (swing) is pressed. However, the script never runs and I'm not sure how to fix this. I know the script works fine independently, it should be py not python because windows, and my file system ntfs.
So far I've been trying to use code that can be summarized as below:
myBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
Process p = Runtime.getRuntime().exec("py myScript.py");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
I don't think I can chmod ntfs stuff but I tried setting permissions via right clicking the python file and trying to mess with the security settings. Full control for the script to users does nothing.
The python script has the following permissions, my guess is my code isn't working because it does not have execute permissions.
-rw-r--r--
Use complete python executable path instead of "py". It executes the file with just read permissions.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Sample {
public static void main(String[] args) throws Exception {
try {
Process p = Runtime.getRuntime().exec("C:/Windows/py myScript.py");
String cmdOutput = null;
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
// read the output from the command
while ((cmdOutput = stdInput.readLine()) != null) {
System.out.println(cmdOutput);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
myScript.py
print("This line will be printed.")
Output:
C:\Users\Administrator\Documents\demo>javac Sample.java
C:\Users\Administrator\Documents\demo>java Sample
This line will be printed.

Java authentication against local SASL

I'm trying to make a java class in order to authenticate users against local SASL. My saslauthd configuration is like this:
$ cat /etc/sysconfig/saslauthd
# Directory in which to place saslauthd's listening socket, pid file, and so
# on. This directory must already exist.
SOCKETDIR=/run/saslauthd
# Mechanism to use when checking passwords. Run "saslauthd -v" to get a list
# of which mechanism your installation was compiled with the ablity to use.
MECH=pam
# Additional flags to pass to saslauthd on the command line. See saslauthd(8)
# for the list of accepted flags.
FLAGS="-t 1"
Basically it redirects an authentication against PAM. So, if I'm doing for example a test like this.
testsaslauthd -s login -u <user> -p <password>
0: OK "Success."
It is all working correctly.
I now want to manage this mechanism through Java so I compiled something like this:
import java.util.Arrays;
import java.util.List;
import java.io.*;
public class PamAuthenticator {
public static void main(String args[]) {
String s = null;
try {
Process p = Runtime.getRuntime().exec("testsaslauthd -s "+args[2]+" -u "+args[0]+" -p "+args[1]);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
System.exit(0);
}
catch (IOException e) {
System.out.println("Exception: ");
e.printStackTrace();
System.exit(-1);
}
}
}
This is correctly working:
$ java -cp .:* PamAuthenticator <user> <password> login
0: OK "Success."
My problem is that I don't want to execute the testsaslauthd command, since this is just a test command. Is there something better and smart I can do in order to try the authentication agains SASL with java?
You are on the right track, not to use the code above. Besides being a test solution it would introduce a serious security problem: command injection.
From Java 1.6 there is an interface called SaslClient. This does exactly what you need. An example on the JDK8 version of it:
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
import java.util.HashMap;
public class Test {
public static void main(String[] args) throws SaslException {
String userName = "username";
String password = "password";
SaslClient saslClient = Sasl.createSaslClient(new String[]{"PLAIN"},
null, null, null, new HashMap<>(), callbacks -> {
for (final Callback callback : callbacks) {
if (callback instanceof NameCallback) {
NameCallback.class.cast(callback).setName(userName);
continue;
}
if (callback instanceof PasswordCallback) {
PasswordCallback.class.cast(callback).setPassword(password.toCharArray());
continue;
}
throw new UnsupportedCallbackException(callback);
}
});
}
}
Of course you should alter the source of the username and password.

Parallel processing Windows batch file

I have a pretty big number of files that need to be converted to a different format. The converting is done via a Java-JAR-File that gets takes the filename as a parameter. I now have a Windows batchfile that uses a for loop to loop through all the files (there is a file that contains a list of all files that need to be converted)
for /F %%i in (all_files.txt) do call java -cp %Classpath% de.xyz.Convert -xml %%i .\xml
Now the machine I want to do this on has eight cores. The number of files is about 360.000 and I would like it to take as little time as possible, so I'd like to use as many cores as possible. How would I go about using multiple cores as easy as possible? Is Windows going to be doing that on its own?
Ok, because I hadn't actually done it before, I knocked this up. It's not great, and the lib I used was a jar I created to crash after 2 mins.. Hopefully you'll be able to reverse engineer this for your needs.
package test;
import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String[] args) throws InterruptedException, IOException {
BlockingQueue<Runnable> runnableQueue = new LinkedBlockingQueue<>();
ExecutorService executorServ = new ThreadPoolExecutor(8, 8, 1, TimeUnit.MINUTES, runnableQueue);
runnableQueue.add(new RunCrash("Example")); // Add one for each file...
executorServ.shutdown();
while(!executorServ.isTerminated()) {
// running
}
}
}
class RunCrash implements Runnable {
private String fileName;
RunCrash(String fileName) {
this.fileName = fileName;
}
#Override
public void run() {
System.out.println(fileName);
try {
crash.CrashMe.main(new String[]{fileName});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Oh, you can let the main thread die before the others finish, I believe the JVM will keep the executor and associated queue. :)

Executing Hive Query from Java

I tried to execute a small hive query from Java, but it is failing with below error, bur when I copy the same query and run on terminal it is giving me the result.
Can someone help me on this.
Java Code:
Runtime.getRuntime().exec("hive -e 'show databases;'");
Error thrown:
FAILED: ParseException line 1:5 cannot recognize input near '<EOF>' '<EOF>' '<EOF>' in ddl statement
Regards,
GHK.
I have been working with this Java problem for a while, and I believe I have solved this problem. Basically the reason you are failing is because the environment variables are not ser up properly. put the following in your /home/<username>/.bash_profile file and restart your machine to fix this.
HIVE_HOME=/usr/lib/hive
export HIVE_HOME
PATH=$PATH:$HIVE_HOME/bin/hive
export PATH
This will ensure that they get set up properly.
However while this will get rid of the error it still won't show you a list of databases because the process that runs the hive command will run in the background, not on the console the main program is running from. The following code will let you redirect the outputs of the program to the console that the main program is running from.
package testing.console;
import java.io.IOException;
import java.lang.ProcessBuilder;
import java.util.Map;
import testing.console.OutputRedirector;
//This Works
public class ConsoleTester {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
ProcessBuilder hiveProcessBuilder = new ProcessBuilder("hive", "-e",
"show databases");
String path = processEnv.get("PATH");
Process hiveProcess = hiveProcessBuilder.start();
OutputRedirector outRedirect = new OutputRedirector(
hiveProcess.getInputStream(), "HIVE_OUTPUT");
OutputRedirector outToConsole = new OutputRedirector(
hiveProcess.getErrorStream(), "HIVE_LOG");
outRedirect.start();
outToConsole.start();
}
}
And the OutputRedirector class used to get the output to console.
package testing.console;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class OutputRedirector extends Thread {
InputStream is;
String type;
public OutputRedirector(InputStream is, String type){
this.is = is;
this.type = type;
}
#Override
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(type + "> " + line);
}
} catch (IOException ioE) {
}
}
}

How to run the Linux "cd" command from Java?

I want to write a Java program to delete ~12 directories or files which are under my home directory. I am able to do this by using
Process proc = Runtime.getRuntime().exec("rm -rf *path*")
But I have to run this command 12 times or I can keep it in loop. What I really want is to have a file in my home directory that contains the names of all the directories and files to delete in it. My Java program should go to the home directory, read the file, and delete all the specified files.
I am stuck at the very first step – I am not able to cd to the home directory. Please let me know how can I achieve this.
Thanks for all of your replies.
But, here I don't really want to use the Java util classes rather I want to learn a way using which I can run Linux commands in my Java class. Being a deployment Intern, I have to reset the environment every time before deploying a new environment for the customer. For this, I repeatedly use some basic Linux commands. I can write a shell script to do this but for this time, I want to write a Java class in which I can put all these Linux commands and run from one class.
The commands which I use are:
kill all java processes which are started by the admin ONLY – for this I need to use multiple Linux commands with “pipe”
Remove all 12-directories/files from home directory
stop some services (like siebel, etc.) – for this I need to go under the particular directories and run ./shutdown.sh or ./stop_ns, etc.
run some database scripts – to reset the database schemas
again start the services – same as step 2 except this time I need to run ./start_ns, etc.
I really appreciate if you can let me know
a. How can I navigate into a directory using Java code
b. How can I run multiple Linux commands using pipe using Java code
Why do you need to "go" to the home directory? Just read the file wherever you are:
String homeDirectory = System.getProperty("user.home");
File file = new File(homeDirectory, "filenames.txt"); // Or whatever
// Now load the file using "file" in the constructor call to FileInputStream etc
It's very rarely a good idea to require that a process changes working directory just to do the right thing.
You dont need to change directory. You can just read file using absolute path using FileReader(String fileName).
For deleting entire directories, try Apache Commons IO's class FileUtils:
FileUtils.deleteDirectory(new File(System.getProperty("user.home")));
Or use cleanDirectory to delete everything in home but not home itself:
FileUtils.cleanDirectory(new File(System.getProperty("user.home")));
If you want to delete specific files only (e.g. those matching a name pattern), list the files first, then delete them:
File startDir = new File(System.getProperty("user.home"));
//this should return the leaf files first, then the inner nodes of the directory tree
Collection<File> files = FileUtils.listFiles(startDir , someFileFiler, someDirFilter);
for(File f : files) {
f.delete();
}
"cd" is a shell internal command, not a executable program.
Even you can change dir in java program by whatever means like JNA, when it exit, the current dir in shell is not changed, because the java program runs in another process than the shell.
But we still can do something about it.
eg. I want to make a new shell command called xcd, it popup a GUI shows a list let you select directories existed in bash history, and change current dir to it for you.
in ~/.bashrc add a line:
xcd(){
XCDRES=`xcd.sh`
if [ "$XCDRES" ]; then
cd "$XCDRES"
fi
}
2.xcd.sh is
#!/bin/bash
java -cp $PATH1/xcd.jar neoe.xcd.Main
and add xcd.sh to PATH
the java program is
package neoe.xcd;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
public class Main {
public static String getUserHomeDir() {
return System.getProperty("user.home");
}
public static void main(String[] args) throws Exception {
new Main().run();
}
public static String readString(InputStream ins, String enc) throws IOException {
if (enc == null)
enc = "UTF-8";
BufferedReader in = new BufferedReader(new InputStreamReader(ins, enc));
char[] buf = new char[1000];
int len;
StringBuffer sb = new StringBuffer();
while ((len = in.read(buf)) > 0) {
sb.append(buf, 0, len);
}
in.close();
return sb.toString();
}
private String[] selection = new String[1];
private void run() throws Exception {
File hisfile = new File(getUserHomeDir(), ".bash_history");
if (!hisfile.exists()) {
System.err.println(".bash_history not exists, quit");
return;
}
String[] ss = readString(new FileInputStream(hisfile), null).split("\n");
List<String> res = new ArrayList<String>();
Set uniq = new HashSet();
for (String s : ss) {
s = s.trim();
if (!s.startsWith("cd /")) {
continue;
}
s = s.substring(3);
File f = new File(s);
if (f.isDirectory()) {
s = f.getAbsolutePath();
if (uniq.contains(s)) {
continue;
}
uniq.add(s);
res.add(s);
}
}
if (res.isEmpty()) {
System.err.println("no cd entry, quit");
return;
}
Collections.sort(res);
String cd1 = selectFromList(res);
if (cd1 == null) {
System.err.println("not selected, quit");
return;
}
doCd(cd1);
}
private void doCd(String cd1) throws Exception {
System.out.println(cd1);
}
private String selectFromList(List<String> res) {
final JList list = new JList(res.toArray());
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final JDialog frame = wrapFrame(new JScrollPane(list), "select dir to cd");
list.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 1) {
String s = (String) list.getSelectedValue();
selection[0] = s;
frame.dispose();
}
}
});
list.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
int kc = e.getKeyCode();
if (kc == KeyEvent.VK_ESCAPE) {
frame.dispose();
} else if (kc == KeyEvent.VK_ENTER) {
String s = (String) list.getSelectedValue();
selection[0] = s;
frame.dispose();
}
}
});
frame.setVisible(true);
frame.requestFocus();
return selection[0];
}
private JDialog wrapFrame(JComponent comp, String title) {
JDialog frame = new JDialog();
frame.setTitle("select dir to cd");
frame.setModal(true);
frame.add(comp);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(400, 600);
frame.setLocationRelativeTo(null);
return frame;
}
}
use xcd in shell.
You can't really do that. Java programs don't really allow you to change the "current working directory" as most people understand it (not without using native code, anyway). The normal Java approach is to open a File instance on the directory you want to manipulate, and then use operations on that instance to manipulate the files/directories in question.
For details on how to delete directories programatically in Java, see: Delete directories recursively in Java

Categories

Resources