package com.zaranux.os.server.zaranuxlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import sun.misc.BASE64Decoder;
import com.zaranux.client.api.exceptions.ResourceAccessFailed;
import com.zaranux.client.api.exceptions.ResourceNotFound;
import com.zaranux.client.api.exceptions.SystemCallNotSupported;
import com.zaranux.os.server.util.ZHTTP;
public class Kernel extends com.zaranux.os.server.core.Kernel {
Kernel()
{
super(new SystemCallACL());
}
@Override
protected String[] attributes(String path) throws SystemCallNotSupported {
if( isRemote(path)) throw new SystemCallNotSupported();
String[] attributes = null;
// "[ndf] , lastModified , size"
File f1 = new File(getPhysicalPath(path));
char ndf = 'n'; // default -> does not exist
long size = 0;
Date lm = null;
if(f1.exists())
{
ndf = (f1.isDirectory()) ? 'd' : 'f';
size = f1.length();
lm = new Date(f1.lastModified());
attributes = new String[]{""+ndf , "" + lm , ""+size};
}
return attributes;
}
@Override
protected boolean create(String path, String type) throws SystemCallNotSupported {
if( isRemote(path)) throw new SystemCallNotSupported();
boolean success = false;
File f = new File(getPhysicalPath(path));
if(type.equals("f"))
{
try
{
success = f.createNewFile(); // true if created/ false if file already exists
}catch(IOException e)
{
}
}else if(type.equals("d"))
{
success = f.mkdir(); // true if created/ false otherwise
}else if(type.equals("ds"))
{
success = f.mkdirs();
}
return success;
}
/* public boolean createuser(String id, String pass) throws SystemCallNotSupported {
throw new SystemCallNotSupported();
}
public String delegate(String access, String grantee, String resource) throws SystemCallNotSupported {
throw new SystemCallNotSupported();
}
*/
@Override
protected boolean delete(String path) throws SystemCallNotSupported {
if( isRemote(path)) throw new SystemCallNotSupported();
File f = new File(getPhysicalPath(path));
return f.delete();
}
/* public String http(String type, String url, String params) throws SystemCallNotSupported {
throw new SystemCallNotSupported();
}
*/
@Override
protected String[] list(String path) throws SystemCallNotSupported,ResourceNotFound {
if( isRemote(path)) throw new SystemCallNotSupported();
path = getPhysicalPath(path);
String[] list = null;
if(path.equals("") || path.equals("/"))
{
File[] lf = File.listRoots();
if(lf!=null)
{
list = new String[lf.length];
for(int i=0; i<list.length; i++)
{
File f = lf[i];
char df = 'd'; //(f1.isDirectory()) ? 'd' : 'f';
long size = 0; //f.length();
Date lm = new Date(f.lastModified());
list[i] = (df + " | " + f.getAbsolutePath() + " | " + lm + " | " + size );
}
}
}else
{
File f = new File(path);
if(!f.exists())
throw new ResourceNotFound();
String[] lf = f.list();
list = new String[lf.length];
if(lf!=null)
{
for(int i=0; i<lf.length; i++)
{
String name = lf[i];
File f1 = new File(path + "/" + name);
char df = (f1.isDirectory()) ? 'd' : 'f';
long size = f1.length();
Date lm = new Date(f1.lastModified());
list[i] = (df + " | " + name + " | " + lm + " | " + size );
}
}
}
return list;
}
/* public boolean login(String id, String pass) throws SystemCallNotSupported {
throw new SystemCallNotSupported();
}
*/
@Override
protected boolean move(String from, String to) throws SystemCallNotSupported {
if(isRemote(from) && isRemote(to)) throw new SystemCallNotSupported();
boolean success = false;
if(isRemote(from) && isLocal(to))
success = download(from,to);
else if(isLocal(from) && isLocal(to))
success = localMove(from,to);
else // isLocal(from) && isRemote(to)
success = upload(from,to);
return success;
}
/* public boolean notify(String reciever, String type, String notification) throws SystemCallNotSupported {
throw new SystemCallNotSupported();
}
*/
/*
public void read(String path, long from , int len,InputStream is) throws SystemCallNotSupported {
throw new SystemCallNotSupported();
}
*/
@Override
protected byte[] read(String path, long from, int len ) throws SystemCallNotSupported, ResourceNotFound,ResourceAccessFailed {
if(isRemote(path)) throw new SystemCallNotSupported();
path = getPhysicalPath(path);
byte[] bytes = null;
FileInputStream fis = null;
try{
File f1 = new File(path);
if(f1.isFile())
{
fis = new FileInputStream(path);
fis.skip(from);
len = Math.min(fis.available(),len);
bytes = new byte[len];
int bytesRead = fis.read(bytes);
}else
{
throw new ResourceNotFound();
}
}catch(IOException e)
{
throw new ResourceAccessFailed();
}finally
{
try
{
fis.close();
}catch(IOException e)
{
logger.severe("read: failed to close the input stream " + e);
}
}
return bytes;
}
@Override
protected boolean write(String path, boolean append,boolean isBase64, InputStream is) throws SystemCallNotSupported,ResourceAccessFailed {
if(isRemote(path)|| (! isBase64)) throw new SystemCallNotSupported();
path = getPhysicalPath(path);
boolean result =false;
FileOutputStream fos = null;
try{
fos = new FileOutputStream(path,append);
new BASE64Decoder().decodeBuffer(is, fos);
result = true;
}
catch(IOException e)
{
throw new ResourceAccessFailed();
}
finally
{
try
{
fos.close();
}catch(IOException e)
{
logger.severe("read: failed to close the output stream " + e);
}
}
return result;
}
private boolean download(String from , String to)
{
final int BUFFER_SIZE = 8*1024;
boolean moveResult = false;
String p1 = from; // remote
String p2 = getPhysicalPath(to);
File destFile = new File(p2);
FileOutputStream fos= null;
InputStream is = null;
try
{
if(!destFile.exists())
{
destFile.createNewFile();
fos = new FileOutputStream(destFile);
is = ZHTTP.syuncHTTPpost(Zaranuxlet.getHost(),Zaranuxlet.getPort(),"read","0,-1", p1,requester);
byte[] buffer = new byte[BUFFER_SIZE];
int len = 0;
try{
len = is.read(buffer);
}catch(org.apache.http.TruncatedChunkException e)
{
len = 0;
}
while((len ) != -1)
{
fos.write(buffer, 0, len);
try{
len = is.read(buffer);
}catch(org.apache.http.TruncatedChunkException e)
{
len = 0;
}
}
moveResult = true;
}
else
moveResult = false;
}catch(Exception e)
{
logger.severe(""+e);
}finally
{
try
{
fos.close();
is.close();
}catch(Exception e)
{
}
}
return moveResult;
}
private boolean upload(String from , String to)
{
boolean moveResult = false;
String p1, p2;
p1 = getPhysicalPath(from);
p2 = to; // remote
File sourceFile = new File(p1);
if(sourceFile.isFile())
{
FileInputStream fis = null;
try
{
fis = new FileInputStream(sourceFile);
//String r = ZHTTP.doSyncPost("write", p2, "false", 5 * 1024, fis);
/*InputStream is = */ ZHTTP.syuncHTTPpost(Zaranuxlet.getHost(),Zaranuxlet.getPort(),"write","false", p2,fis, -1, requester);
moveResult = true; // TODD: fix the ourput result ..
}catch(Exception e)
{
logger.severe("upload failed: " + e);
}finally
{
if(fis!=null)
{
try
{
fis.close();
}catch(IOException e)
{
logger.severe("unable to close input stream for file" + sourceFile.getAbsolutePath() + " : " + e );
}
}
}
}
return moveResult;
}
private boolean localMove(String from, String to)
{
String p1, p2;
p1 = getPhysicalPath(from);
p2 = getPhysicalPath(to);
File sourceFile = new File(p1);
File destFile = new File(p2);
return sourceFile.renameTo(destFile);
}
}