diff -r 093341bd6ac1 keyring.impl/src/org/netbeans/modules/keyring/kde/KWalletProvider.java --- a/keyring.impl/src/org/netbeans/modules/keyring/kde/KWalletProvider.java Mon Dec 13 00:17:21 2010 +0300 +++ b/keyring.impl/src/org/netbeans/modules/keyring/kde/KWalletProvider.java Mon Dec 13 14:35:06 2010 +0300 @@ -56,13 +56,14 @@ /** * - * @author psychollek + * @author psychollek, ynov */ @ServiceProvider(service=KeyringProvider.class, position=99) public class KWalletProvider implements KeyringProvider{ private static final Logger logger = Logger.getLogger(KWalletProvider.class.getName()); private char[] handler = "0".toCharArray(); + private boolean timeoutHappened = false; @Override public boolean enabled(){ @@ -70,63 +71,80 @@ logger.fine("native keyring integration disabled"); return false; } - if (new String(runCommand("isEnabled")).equals("true")){ + CommandResult result = runCommand("isEnabled"); + if(new String(result.retVal).equals("true")) { return updateHandler(); - } + } return false; }; @Override public char[] read(String key){ - if (updateHandler()){ - char[] pwd = runCommand("readPassword", handler, getApplicationName(), key.toCharArray(), getApplicationName(true)); - return pwd.length > 0 ? pwd : null; + if (!timeoutHappened && updateHandler()){ + CommandResult result = runCommand("readPassword", handler, getApplicationName(), key.toCharArray(), getApplicationName(true)); + if (result.exitCode != 0){ + error("read action returned not 0 exitCode"); + } + return result.retVal.length > 0 ? result.retVal : null; } - throw new KwalletException("read"); + return null; + //throw new KwalletException("read"); }; @Override public void save(String key, char[] password, String description){ //description is forgoten ! kdewallet dosen't have any facility to store //it by default and I don't want to do it by adding new fields to kwallet - if (updateHandler()){ - if (new String(runCommand("writePassword", handler , getApplicationName() - , key.toCharArray(), password , getApplicationName(true)) - ).equals("-1")){ - throw new KwalletException("save"); + if (!timeoutHappened && updateHandler()){ + CommandResult result = runCommand("writePassword", handler , getApplicationName() + , key.toCharArray(), password , getApplicationName(true)); + if (result.exitCode != 0 || (new String(result.retVal)).equals("-1")){ + error("save action failed"); } return; } - throw new KwalletException("save"); + //throw new KwalletException("save"); }; @Override public void delete(String key){ - if (updateHandler()){ - if (new String(runCommand("removeEntry" ,handler, - getApplicationName() , key.toCharArray() , getApplicationName(true) - )).equals("-1")){ - throw new KwalletException("delete"); + if (!timeoutHappened && updateHandler()){ + CommandResult result = runCommand("removeEntry" ,handler, + getApplicationName() , key.toCharArray() , getApplicationName(true)); + if (result.exitCode != 0 || (new String(result.retVal)).equals("-1")){ + error("delete action failed"); } return; } - throw new KwalletException("delete"); + //throw new KwalletException("delete"); }; private boolean updateHandler(){ handler = new String(handler).equals("")? "0".toCharArray() : handler; - if(new String(runCommand("isOpen",handler)).equals("true")){ + CommandResult result = runCommand("isOpen",handler); + if(new String(result.retVal).equals("true")){ return true; } - char[] localWallet = runCommand("localWallet"); - handler = runCommand("open", localWallet , "0".toCharArray() , getApplicationName(true)); - if(!(new String(handler)).equals("-1")){ - return true; + char[] localWallet = runCommand("localWallet").retVal; + + result = runCommand("open", localWallet , "0".toCharArray() , getApplicationName(true)); + if(result.exitCode == 2) { //time out error + error("time out happened while accessing KWallet"); + //don't try to open KWallet anymore until bug https://bugs.kde.org/show_bug.cgi?id=259229 is fixed + timeoutHappened = true; + return false; } - return false; + if(result.exitCode != 0 || new String(result.retVal).equals("-1")) { + error("failed to access KWallet"); + return false; + } + handler = result.retVal; + return true; } + + - private char[] runCommand(String command,char[]... commandArgs){ + private CommandResult runCommand(String command,char[]... commandArgs) { String[] argv = new String[commandArgs.length+4]; argv[0] = "qdbus"; argv[1] = "org.kde.kwalletd"; @@ -137,9 +155,10 @@ //TODO: find a way to avoid changing char[] into String argv[i+4] = new String(commandArgs[i]); } - Runtime rt = Runtime.getRuntime(); String retVal = ""; + String errVal = ""; + int exitCode = 0; try { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "executing {0}", Arrays.toString(argv)); @@ -154,23 +173,23 @@ retVal = retVal.concat("\n"); } retVal = retVal.concat(line); - } + } input.close(); input = new BufferedReader(new InputStreamReader(pr.getErrorStream())); while((line = input.readLine()) != null) { - if (!retVal.equals("")){ - retVal = retVal.concat("\n"); + if (!errVal.equals("")){ + errVal = errVal.concat("\n"); } - retVal = retVal.concat(line); + errVal = errVal.concat(line); } input.close(); - - int exitVal = pr.waitFor(); + exitCode = pr.waitFor(); if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, "application exit with code {0} for commandString: {1}", new Object[]{exitVal, Arrays.toString(argv)}); - } + logger.log(Level.FINE, "application exit with code {0} for commandString: {1}; errVal: {2}", + new Object[]{exitCode, Arrays.toString(argv), errVal}); + } } catch (InterruptedException ex) { logger.log(Level.FINE, "exception thrown while invoking the command \""+Arrays.toString(argv)+"\"", @@ -180,8 +199,8 @@ "exception thrown while invoking the command \""+Arrays.toString(argv)+"\"", ex); } - return retVal.trim().toCharArray(); - } + return new CommandResult(exitCode, retVal.trim().toCharArray(), errVal.trim()); + } private char[] getApplicationName(){ return getApplicationName(false); @@ -197,12 +216,20 @@ return appName.toCharArray(); } - public class KwalletException extends RuntimeException{ + private void error(String descr) { + logger.log(Level.WARNING, "Something went wrong: {0}", descr); + } + + private class CommandResult { + private int exitCode; + private char[] retVal; + private String errVal; - public KwalletException(String desc) { - super("error while trying to access KWallet, during "+desc); - } - + public CommandResult(int exitCode, char[] retVal, String errVal) { + this.exitCode = exitCode; + this.retVal = retVal; + this.errVal = errVal; + } } }