00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00025 #include "Storage_i.h"
00026
00027 #include "../utils/File.h"
00028 #include "../utils/NameServer.h"
00029 #include "../Object/Object.h"
00030 #include "../idl/Storage.hh"
00031
00032 #include <dirent.h>
00033
00034 Storage_i::Storage_i(Prefs &p, const CORBA::ORB_ptr &o) : prefs(p), orb(o) {;
00035 dirname = prefs.get("datadir", "data");
00036 metadirname = prefs.get("metadatadir", dirname);
00037 };
00038
00039 Obj *Storage_i::get(const Security &cert, const Obj_id &id)
00040 throw(NotFound, SecurityException, InternalError) {
00041 string ident(id.name);
00042 try {
00043 lock.lock(ident);
00044 string strobj = File::read( ident, dirname );
00045 lock.unlock(ident);
00046 return Object::string2Obj(strobj);
00047 } catch (File::NotFound) {
00048 lock.unlock(ident);
00049 throw NotFound();
00050 } catch (...) {
00051 lock.unlock(ident);
00052 throw InternalError();
00053 };
00054 };
00055
00056 Obj_ts Storage_i::get_ts(const Security &cert, const Obj_id &id)
00057 throw(NotFound, SecurityException, InternalError) {
00058 string ident(id.name);
00059 try {
00060 lock.lock(ident);
00061 string strobj = File::read( ident + ".ts", metadirname );
00062 lock.unlock(ident);
00063 return Object::string2Obj_ts(strobj);
00064 } catch (File::NotFound) {
00065 lock.unlock(ident);
00066 throw NotFound();
00067 } catch (...) {
00068 lock.unlock(ident);
00069 throw InternalError();
00070 };
00071 };
00072
00073 Obj_prop Storage_i::get_prop(const Security &cert, const Obj_id &id)
00074 throw(NotFound, SecurityException, InternalError) {
00075 string ident(id.name);
00076 try {
00077 lock.lock(ident);
00078 string strobj = File::read( ident + ".prop", metadirname );
00079 lock.unlock(ident);
00080 return Object::string2Obj_prop(strobj);
00081 } catch (File::NotFound) {
00082 lock.unlock(ident);
00083 throw NotFound();
00084 } catch (...) {
00085 lock.unlock(ident);
00086 throw InternalError();
00087 };
00088 };
00089
00090 void Storage_i::put(const Security &cert, const Obj &obj, const Obj_id &id, const Obj_prop &prop,
00091 const Obj_ts &ts) throw(AlreadyPresent, SecurityException, InternalError) {
00092 string ident(id.name);
00093 string obj_str = Object::Obj2string(obj);
00094 string obj_ts_str = Object::Obj_ts2string(ts);
00095 string obj_prop_str = Object::Obj_prop2string(prop);
00096
00097 lock.lock(ident, true);
00098
00099
00100 try {
00101 File::write(obj_str, ident, dirname);
00102 } catch (File::AlreadyPresent) {
00103 lock.unlock(ident);
00104 throw AlreadyPresent();
00105 };
00106
00107 try {
00108
00109 File::write(obj_ts_str, ident+".ts", metadirname, true);
00110 File::write(obj_prop_str, ident+".prop", metadirname, true);
00111 } catch (...) {
00112
00113
00114 try { File::remove(ident, dirname); } catch (...) {};
00115 try { File::remove(ident+".ts", metadirname); } catch (...) {};
00116 try { File::remove(ident+".prop", metadirname); } catch (...) {};
00117 lock.unlock(ident);
00118 throw InternalError();
00119 };
00120 lock.unlock(ident);
00121 };
00122
00123 Obj_infoList *Storage_i::list(const Security &cert) throw(SecurityException, InternalError) {
00124 DIR *dir;
00125 struct dirent * entry;
00126 int count=0;
00127
00128 dir = opendir( metadirname.c_str() );
00129 if(dir == NULL)
00130 throw InternalError();
00131 while( entry=readdir(dir) ) {
00132 string name(entry->d_name);
00133 if(name.find(".ts")==name.length()-3 && name.length()>3 )
00134 count++;
00135 };
00136 free(entry);
00137 closedir(dir);
00138
00139 Obj_infoList *list = new Obj_infoList(count);
00140 list->length(count);
00141
00142 dir = opendir( metadirname.c_str() );
00143 if(dir == NULL)
00144 throw InternalError();
00145 int i=0;
00146 while( entry=readdir(dir) ) {
00147 string name(entry->d_name);
00148 if(name.find(".ts")==name.length()-3 && name.length()>3 ) {
00149 name = name.substr(0,name.length()-3);
00150
00151 Obj_info info;
00152 info.id.name= CORBA::string_dup(name.c_str());
00153 try{ info.ts = Object::string2Obj_ts(File::read(name+".ts", metadirname)); } catch (...) {};
00154 try{ info.prop = Object::string2Obj_prop(File::read(name+".prop", metadirname)); } catch (...) {};
00155
00156 (*list)[i++] = info;
00157 };
00158 };
00159 free(entry);
00160 closedir(dir);
00161 return list;
00162 };
00163
00164 void Storage_i::put_from_peer(const Security &cert, const Obj_id &id, const char *peer)
00165 throw(NotFound, PeerNotAvailable, AlreadyPresent, SecurityException, InternalError) {
00166
00167
00168 string ident(id.name);
00169 lock.lock(ident, true);
00170
00171
00172 utils::URI uri(peer);
00173
00174 Storage_var storage;
00175
00176 try {
00177
00178 CORBA::Object_var stor_obj = utils::NameServer::get_object(orb, uri);
00179 storage = fbfs::Storage::_narrow(stor_obj);
00180 } catch(...) {
00181 lock.unlock(ident);
00182 throw PeerNotAvailable();
00183 };
00184
00185 Obj *obj;
00186 Obj_ts obj_ts;
00187 Obj_prop obj_prop;
00188 try {
00189 obj = storage->get(cert, id);
00190 obj_ts = storage->get_ts(cert, id);
00191 obj_prop = storage->get_prop(cert, id);
00192 } catch(NotFound) {
00193 lock.unlock(ident);
00194 throw NotFound();
00195 } catch(SecurityException) {
00196 lock.unlock(ident);
00197 throw SecurityException();
00198 } catch(...) {
00199 lock.unlock(ident);
00200 throw PeerNotAvailable();
00201 };
00202
00203 try{
00204 lock.unlock(ident);
00205 put(cert, *obj, id, obj_prop, obj_ts);
00206 } catch(AlreadyPresent) {
00207 throw AlreadyPresent();
00208 } catch(SecurityException) {
00209 throw SecurityException();
00210 } catch(...) {
00211 throw InternalError();
00212 };
00213 };
00214
00215 void Storage_i::remove(const Security &cert, const Obj_id &id)
00216 throw(NotFound, SecurityException, InternalError) {
00217 string ident(id.name);
00218
00219
00220 lock.lock(ident, true);
00221
00222 bool failed = false;
00223 try {
00224 File::remove(ident, dirname);
00225 } catch (File::NotFound) {
00226 lock.unlock(ident);
00227 throw NotFound();
00228 } catch (...) {
00229 failed = true;
00230 };
00231 try { File::remove(ident+".ts", metadirname); } catch (NotFound) {} catch (...) { failed = true;};
00232 try { File::remove(ident+".prop", metadirname); } catch (NotFound) {} catch (...) { failed = true;};
00233
00234 lock.unlock(ident);
00235 if(failed)
00236 throw InternalError();
00237 };