package PFS.ramfs;
import java.io.*;
import java.util.*;
public class node_type {
private boolean is_dir;
private ByteArray data;
private Vector dir;
private String path;
private node_type back_node;
private int len;
private long mode;
private long mtime;
private long atime;
private Date clock=new Date();
public node_type(long nmode) {
path="/";
len=0;
back_node=this;
setmtime();
mode=nmode;
is_dir=true;
dir=new Vector();
}
private node_type( boolean d, String name, node_type bnode, long nmode) {
path=name;
mode=nmode;
back_node=bnode;
setmtime();
is_dir=d;
if (is_dir) {
dir=new Vector();
}
else {
data = new ByteArray();
}
}
public String getName() {
return path;
}
public long getSize() {
return len;
}
public long getId() {
return (long)this.hashCode();
}
public long getMode() {
return mode;
}
public boolean isDir() {
return is_dir;
}
public long getmtime() {
return mtime;
}
public long getatime() {
return atime;
}
public boolean exist_file(String name) {
return (getIndexOfChild(name)!=-1);
}
public node_type[] listDir() throws Exception {
node_type[] st;
int tam;
permToRead();
if (!is_dir)
throw new Exception("Object is file.");
if (dir.isEmpty())
return new node_type[0];
tam=dir.size();
st = new node_type[tam];
for(int i=0; i<tam; i++)
st[i] = (node_type) dir.elementAt(i);
setatime();
return st;
}
public String[] list() {
String[] rt;
int tam;
if (!is_dir)
return null;
if (dir.isEmpty())
return null;
tam=dir.size();
rt = new String[tam];
for(int i=0; i<tam; i++)
rt[i] = ((node_type) dir.elementAt(i)).getName();
return rt;
}
public synchronized void setName(String s) { path=s; }
public synchronized void setMode(long nmode) { mode=nmode & 0xFFFFFFFFL; }
public synchronized void setmtime(long t) {
mtime=t;
atime=mtime;
}
public synchronized void setmtime() {
mtime=System.currentTimeMillis()/1000;
atime=mtime;
}
public synchronized void setatime(long t) {
atime=t;
}
public synchronized void setatime() {
atime=System.currentTimeMillis()/1000;
}
public void delete() throws Exception {
node_type upnode=upNode();
if (is_dir&&(dir.size()!=0))
throw new Exception("Directory not empty.");
permToWrite();
node_type nodo_temp;
int tam=upnode.dir.size();
for(int i=0; i<tam; i++) {
nodo_temp = (node_type) upnode.dir.elementAt(i);
if (nodo_temp.getName()==getName()) {
upnode.dir.removeElementAt(i);
break;
}
}
}
public void mkdir(String name, long nmode) throws Exception {
permToWrite();
if (checkGoodName(name))
throw new Exception("Bad file name.");
if (getIndexOfChild(name)!=-1)
throw new Exception("File name exist.");
dir.addElement(new node_type(true,name,this,nmode));
}
public void create_file(String name, long nmode) throws Exception {
permToWrite();
if (checkGoodName(name))
throw new Exception("Bad file name.");
if (getIndexOfChild(name)!=-1)
throw new Exception("File name exist.");
dir.addElement(new node_type(false,name,this,nmode));
}
public byte[] read(int num, int offset) throws Exception {
permToRead();
if (is_dir)
throw new Exception("Cant read directory.");
byte[] temp = data.readBytes(num, offset);
setatime();
return temp;
}
public int write(byte[] cad, int offset) throws Exception {
permToWrite();
if (is_dir)
throw new Exception("Cant write directory.");
int num_bytes=data.writeBytes(cad,offset);
update_file_size();
setmtime();
return num_bytes;
}
public void truncate() throws Exception {
permToWrite();
if (is_dir)
throw new Exception("Cant write directory.");
data.delete();
update_file_size();
setmtime();
}
public node_type downNode(String name) throws Exception {
int tam;
node_type nodo_temp;
if (name.equals(".."))
return upNode();
if (name.equals("."))
return this;
if (dir.isEmpty())
throw new Exception("File not found.");
tam=dir.size();
for(int i=0; i<tam; i++) {
permToExec();
nodo_temp = (node_type) dir.elementAt(i);
if (name.equals(nodo_temp.path)) {
return nodo_temp;
}
}
throw new Exception("File not found.");
}
public node_type upNode() throws Exception {
int tam;
node_type nodo_temp;
if (back_node==null)
throw new Exception("File is root.");
return back_node;
}
private void update_file_size() {
len = data.size();
}
private int getIndexOfChild (String name) {
int tam;
node_type nodo_temp;
if (dir.isEmpty())
return -1;
tam=dir.size();
for(int i=0; i<tam; i++) {
nodo_temp = (node_type) dir.elementAt(i);
if (nodo_temp.path==name)
return i;
}
return -1;
}
private String getNameOfChild (int index) {
int tam;
node_type nodo_temp;
if (dir.isEmpty()||(dir.size()>=index))
return ("");
nodo_temp = (node_type) dir.elementAt(index);
return(nodo_temp.path);
}
private boolean checkGoodName (String cad){
if (cad.indexOf("?")==-1)
return false;
if (cad.indexOf("*")==-1)
return false;
if (cad.indexOf("/")==-1)
return false;
return true;
}
private static final int DMREAD = 0x4;
private static final int DMWRITE = 0x2;
private static final int DMEXEC = 0x1;
private void permToRead () throws Exception {
if (!isReadable())
throw new Exception("Access permission denied [read]") ;
}
private void permToWrite () throws Exception {
if (!isWritable())
throw new Exception("Access permission denied [write]") ;
}
private void permToExec () throws Exception {
if (!isExecutable())
throw new Exception("Access permission denied [exec]") ;
}
private boolean checkPerm (int c) {
int dm = c << getPermGroup();
return ((mode&dm)==dm);
}
public boolean isReadable() {
return checkPerm(DMREAD);
}
public boolean isWritable() {
return checkPerm(DMWRITE);
}
public boolean isExecutable() {
return checkPerm(DMEXEC);
}
private static boolean isUserOwner() {
return true;
}
private static boolean isUserMember(String group) {
return true;
}
private static byte getPermGroup() {
return 6;
}
}