package PFS;
import java.io.*;
import java.util.*;
import P9P.type.*;
public class pfiledisk extends pfile {
private File f;
private RandomAccessFile acc;
public pfiledisk(String z) {
f=new File(z);
pfilefather=null;
}
protected pfiledisk(File file, pfile p) {
f=file;
pfilefather=p;
}
public boolean isDir() throws Exception {
if (isDeleted) throw pfileDeleted;
return f.isDirectory();
}
public boolean isReadable() {
return f.canRead();
}
public boolean isWritable() {
return f.canWrite();
}
public boolean isExecutable() {
return isReadable();
}
protected boolean fileExists () {
return f.exists();
}
public String getname() {
if (isDeleted)
return null;
return f.getName();
}
public stat9P getStat() {
return getStat(f);
}
protected stat9P getStat(File file) {
if (isDeleted)
return null;
stat9P st= new stat9P();
st.type.value = 0;
st.dev.value = 0;
st.length.value = file.length();
st.qid.vers.value = 0;
st.qid.path.value = (long) file.hashCode();
if (file.isDirectory()) {
st.mode.value=0x80000007L;
st.qid.type.value=0x80;
}
else {
st.mode.value=0x00000007L;
st.qid.type.value=0x00;
}
st.name.value = file.getName();
st.muid.value = "nobody";
st.uid.value = "nobody";
st.gid.value = "nogroup";
st.mtime.value = f.lastModified()/1000;
st.atime.value = st.mtime.value ;
return st;
}
protected boolean canGetName(String s) {
File aux;
if (isDeleted)
return false;
aux = f.getParentFile();
if (aux==null)
return true;
aux=new File(aux.getAbsolutePath() + File.separatorChar + s);
return aux.exists();
}
public pfile walk(String s) throws Exception {
File ftmp;
pfile ptmp;
if (isDeleted)
throw pfileDeleted;
if (!isExecutable())
throw new Exception("Access permission denied");
ptmp=getPfileCache(s);
if (ptmp==null) {
ftmp=new File(f.getAbsolutePath() + File.separatorChar + s);
if (!ftmp.exists())
throw new Exception("File not found");
ptmp=new pfiledisk(ftmp, this);
}
return ptmp;
}
protected String[] list () {
return f.list();
}
protected synchronized void open(short nmode) throws Exception {
if (isDeleted)
throw pfileDeleted;
checkOpenMode(nmode);
String cad="";
if ((nmode & cons.OREAD)==cons.OREAD)
cad="r";
if ((nmode & cons.OWRITE)==cons.OWRITE)
cad="rw";
if (!isDir())
acc= new RandomAccessFile(f, cad);
}
protected void close() throws Exception {
acc.close();
}
public synchronized pfile create (String name, long perm) throws Exception {
long m;
stat9P stat=getStat();
pfile ptmp;
File aux;
if (!isDir())
throw new Exception("Cant create, not directory");
aux=new File(f.getAbsolutePath() + File.separatorChar + name);
if (isDirectory(perm))
aux.mkdir();
else
aux.createNewFile();
ptmp= new pfiledisk(aux, this);
addPfileCache(ptmp);
return ptmp;
}
protected synchronized byte[] read(long ofset, long coun) throws Exception {
byte[] b;
int byteread;
int l=longToInt(ofset);
int c=longToInt(coun);
if (isDeleted)
throw pfileDeleted;
if (l<0)
throw new Exception("Bad offset");
if (c<0)
throw new Exception("Bad count");
if(isDir()) {
int tam;
int sum=0;
boolean escritura=false;
ByteArrayOutputStream aux=new ByteArrayOutputStream();
File[] lst=f.listFiles();
stat9P st;
if (lst!=null) {
for(int i=0;i<lst.length;i++) {
if (l==sum)
escritura=true;
st=getStat(lst[i]);
tam=st.len();
sum=sum+tam;
if (escritura) {
if((aux.size()+tam)<=c) st.write(aux);
else break;
}
}
b=aux.toByteArray();
}
else throw new Exception("File not read mode");
}
else {
b=new byte[c];
try {
acc.seek(l);
byteread = acc.read(b);
}
catch( Exception e ) {
throw e;
}
if (byteread<0)
byteread=0;
if (byteread<c) {
byte[] new_b = new byte[byteread];
for (int j=0; j<byteread; j++)
new_b[j]=b[j];
b=new_b;
}
}
return b;
}
protected synchronized int write(long ofset, byte[] d) throws Exception {
int l=longToInt(ofset);
if (isDeleted)
throw pfileDeleted;
if (l<0)
throw new Exception("Bad offset");
acc.seek(l);
acc.write(d);
return d.length;
}
protected void truncate(int size) throws Exception {
if (isDeleted)
throw pfileDeleted;
acc.setLength((long) size);
}
public synchronized void remove() throws Exception {
if (isDeleted)
throw pfileDeleted;
if (!f.delete())
throw new Exception("Cant delete");
f=null;
switchToDeletedMode();
}
public synchronized void wstat(stat9P newst) throws Exception {
stat9P stat=checkWStat(newst);
if (isDeleted)
throw pfileDeleted;
stat=newst;
setName(stat.name.value);
}
private long getMode(File file) {
long flag;
if (file.isDirectory())
flag=0x80000000L;
else
flag=0x0L;
if (file.canRead())
flag=flag|0005;
if (file.canWrite())
flag=flag|0002;
return flag;
}
private void setName(String cad) throws Exception {
File newName = new File(cad);
if (!f.renameTo(newName))
throw new Exception("Cant rename or move file");
}
}