3 * Copyright (C) 2007, Rus V. Brushkoff, All rights reserved.
11 void sfinx_app::dbopen()
13 dbname_ = "/usr/local/sfinx/sfinx.fdb";
16 db_ = driver_->DatabaseFactory("", dbname_, dbuser_, dbpass_);
18 log("dbopen", "Connected to database %s", dbname_.c_str());
21 void sfinx_app::listen()
23 InetAddress addr((InetAddrValidator *)0);
24 log("sfinx:listen", "server listening at %d port", SFINX_PORT);
26 sfinx_socket server(addr);
27 while(server.isPendingConnection()) {
28 faraon_session *faraon = new faraon_session(server, SFINX_MAX_PACKET_SIZE);
32 catch(Socket *socket) {
35 int err = socket->getErrorNumber();
36 cerr << "client socket error : ";
37 if (err == Socket::errBindingFailed) {
38 cerr << "bind failed; port busy, bye." << endl;
41 IPV4Address saddr = socket->getPeer(&port);
43 if (!saddr.isInetAddress())
46 host = saddr.getHostname();
47 cerr << host << ":" << port << \
48 " failed : " << socket->getErrorString() << endl;
50 cerr << "listen terminated" << endl;
53 u32_t sfinx_app::get_object_slice(u32_t obj_type, u32_t obj_id)
55 sfinx_object_t o(obj_type, obj_id);
57 if (o.otype == SFINX_SLICE_OBJECT)
59 if (!parent_object(o, &o))
64 u32_t sfinx_app::parent_slice_id(u32_t slice_id)
66 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
67 IBPP::ilConcurrency, IBPP::lrWait);
69 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
70 st->Prepare("select parent_id from slices where id = ?");
71 st->Set(1, (int32_t)slice_id);
77 debug("no parent for %d slice !", slice_id);
82 string sfinx_app::slice_name(u32_t slice_id)
85 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
86 IBPP::ilConcurrency, IBPP::lrWait);
88 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
89 st->Prepare("select name from slices where id = ?");
90 st->Set(1, (int32_t)slice_id);
99 string sfinx_app::slice_directory(u32_t slice_id)
102 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
103 IBPP::ilConcurrency, IBPP::lrWait);
105 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
106 st->Prepare("select directory from slices where id = ?");
107 st->Set(1, (int32_t)slice_id);
109 while (st->Fetch()) {
116 bool sfinx_app::parent_object(sfinx_object_t &src, sfinx_object_t *dst)
119 case SFINX_SLICE_OBJECT:
121 dst->oid = parent_slice_id(src.oid);
129 // for objects other than slices if the main_obj_id == SFINX_SLICE_OBJECT
130 // directory is the slice one
131 // for other main_obj_id we look up in the hierarchy - all is created from the
133 // TODO: think about editing object property (main_obj_xxx) !
135 bool sfinx_app::set_sorted_path(sfinx_object_t &obj)
138 sfinx->files_module_conf.get(FILES_MODULE_SORTED_TREE_PATH, obj.sorted_path);
139 sfinx_object_t t = obj;
141 if (t.otype == SFINX_SLICE_OBJECT) {
142 path.insert(0, "/" + slice_directory(t.oid)); // TODO: handle spaces in names
143 if (t.oid == 1) // root slice
146 if (!parent_object(obj, &t))
149 obj.sorted_path += path;
153 // returns true on error
154 bool sfinx_app::sorted_path_mkdir(sfinx_object_t &obj)
156 if (set_sorted_path(obj))
158 return system(("mkdir -p " + obj.sorted_path).c_str());
161 int main(int argc, char **argv)
163 setlocale(LC_ALL, "");
165 sprintf(version, "v%0d.%0d.%0d", SFINX_VERSION_MAJOR, SFINX_VERSION_MINOR, SFINX_VERSION_PLEVEL);
166 sfinx = new sfinx_app(argc, argv, "sfinx", version,
167 "Harbour <Harbour@Sfinx.Od.UA>", "GPL");
170 sfinx->start_ui(); // start ui first
173 catch(IBPP::Exception& e) {
174 log("IBPP::Exception", "%s", e.what());
176 sfinx->ui()->alert("%s() Error !", e.Origin());
181 bool faraon_session::connect()
183 // send plain packet with daemon version
185 tx_elements.add(daemon_version);
186 // and available crypt types
187 tx_elements.add(packet_crypt_types);
189 tx_elements.add(min_auth_levels);
190 // ÐÅÒÅÄÅÌÁÔØ Ó ÉÓÐÏÌØÚÏ×ÁÎÉÅÍ -lgcrypt
191 sfinx_8bit_vector_t md5_challenge(SFINX_MD5_SUM);
192 sfinx_crypter::get_random_bytes(md5_challenge, gcry_md_get_algo_dlen(GCRY_MD_MD5));
193 tx_elements.add(md5_challenge);
196 log("sfinx:connect", "Error reading faraon request");
200 // got SFINX_AUTH_REQUEST + auth data
201 // validate user_name/pass or rsa key
204 // send SFINX_ACCESS_GRANTED/SFINX_ACCESS_DENIED
206 sfinx_8bit_t access(SFINX_ACCESS_GRANTED);
207 access.set(0); // ÐÒÉÞÉÎÁ ÄÏÓÔÕÐÁ/ÏÔËÁÚÁ
208 tx_elements.add(access);
213 void faraon_session::run()
221 if (isPending(pendingInput, 10)) { // faraon'Ù ÐÒÏÓÀÔØ ...
222 if (process_requests()) {
223 log("sfinx:run", "Bad faraon request");
232 InetAddress saddr = (InetAddress)getPeer(&port);
233 log("sfinx:run","Faraon client error at %s:%d - %s", saddr.getHostname(),
234 port, getErrorString());
236 catch (IBPP::Exception& e) {
237 log("sfinx:run", "%s", e.what());
238 sfinx->ui()->alert("%s() Error !", e.Origin());
243 void faraon_session::get_slice(u32_t slice_id, u32_t el_id)
245 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
246 IBPP::ilConcurrency, IBPP::lrWait);
248 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
249 st->Prepare("select m.id, m.name, m.description, m.parent_id, (select name from slices where id = m.parent_id) as parent_name, m.ctime, m.etime, m.directory from slices m where m.id = ?");
250 st->Set(1, (int32_t)slice_id);
252 string name, directory, description, parent_name;
253 int32_t id, parent_id;
254 IBPP::Timestamp ctime, etime;
259 st->Get(3, description);
260 st->Get(4, &parent_id);
264 st->Get(5, parent_name);
268 st->Get(8, directory);
269 sfinx_slice_t slice(id, name, directory, description, parent_name, parent_id, ctime, etime);
275 void faraon_session::get_slices(u32_t el_id, u32_t except)
277 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
278 IBPP::ilConcurrency, IBPP::lrWait);
280 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
282 st->Prepare("select m.id, m.name, m.description, m.parent_id, (select name from slices where id = m.parent_id) as parent_name, m.ctime, m.etime, m.directory from slices m order by id");
284 st->Prepare("select m.id, m.name, m.description, m.parent_id, (select name from slices where id = m.parent_id) as parent_name, m.ctime, m.etime, m.directory from slices m where id <> ? order by id");
285 st->Set(1, int32_t(except));
288 string name, description, parent_name, directory;
289 int32_t id, parent_id;
290 IBPP::Timestamp ctime, etime;
291 sfinx_slice_vector_t slices(el_id);
292 while (st->Fetch()) {
295 st->Get(3, description);
296 st->Get(4, &parent_id);
300 st->Get(5, parent_name);
304 st->Get(8, directory);
305 sfinx_slice_t slice(id, name, directory, description, parent_name, parent_id, ctime, etime);
312 static void fill_files(sfinx_slice_t *slice)
316 static void fill_notes(sfinx_slice_t *slice)
318 // "select name, main_obj_type, main_obj_id from notes";
320 // if (main_obj_type == SFINX_SLICE_OBJECT) {
321 // sfinx_object_t note;
328 // ÐÅÒÅÄÁÅÔ ÄÅÒÅ×Ï ÓÌÁÊÓÏ× + ×ÌÏÖÅÎÎÙÅ ÏÂØÅËÔÙ, ÔÉÐ ËÏÔÏÒÙÈ ÏÇÒÁÎÉÞÅÎ ÍÁÓËÏÊ
329 void faraon_session::get_objects(u32_t reply_id, u32_t obj_mask)
331 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
332 IBPP::ilConcurrency, IBPP::lrWait);
334 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
335 st->Prepare("select m.id, m.name, m.description, m.parent_id, (select name from slices where id = m.parent_id) as parent_name, m.ctime, m.etime, m.directory from slices m order by id");
337 string name, description, parent_name, directory;
338 int32_t id, parent_id;
339 IBPP::Timestamp ctime, etime;
340 sfinx_slice_vector_t slices(reply_id);
341 while (st->Fetch()) {
344 st->Get(3, description);
345 st->Get(4, &parent_id);
349 st->Get(5, parent_name);
353 st->Get(8, directory);
354 sfinx_slice_t slice(id, name, directory, description, parent_name, parent_id, ctime, etime);
355 if (obj_mask & 1 << SFINX_FILE_OBJECT)
357 if (obj_mask & 1 << SFINX_NOTE_OBJECT)
365 bool move(string &from, string &to)
367 return system(("mv \"" + from + "\" \"" + to + "\"").c_str());
370 // TODO: make reply alert
371 void faraon_session::update_slice(sfinx_slice_t *slice)
373 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
374 IBPP::ilConcurrency, IBPP::lrWait);
376 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
377 string old_dir = sfinx->slice_directory(slice->slice_id);
378 if (old_dir != slice->directory()) {
381 o.otype = SFINX_SLICE_OBJECT;
382 o.oid = slice->slice_id;
383 sfinx->set_sorted_path(o);
384 from = o.sorted_path;
385 const char *p = strrchr(from.c_str(), '/');
390 strncat(path, from.c_str(), p - from.c_str());
393 to += slice->directory();
396 st->Prepare("update slices set etime = NULL, name = ?, description = ?, directory = ? where id = ?");
397 st->Set(1, slice->name());
398 st->Set(2, slice->description());
399 st->Set(3, slice->directory());
400 st->Set(4, (int32_t)slice->slice_id);
405 void faraon_session::new_slice(sfinx_slice_t *slice)
407 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
408 IBPP::ilConcurrency, IBPP::lrWait);
410 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
411 st->Prepare("insert into slices (parent_id, name, description, directory) values (?, ?, ?, ?)");
412 st->Set(1, (int32_t)slice->parent_slice_id);
413 st->Set(2, slice->name());
414 st->Set(3, slice->description());
415 st->Set(4, slice->directory());
420 void faraon_session::delete_slice_recursivly(u32_t slice_id)
422 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
423 IBPP::ilConcurrency, IBPP::lrWait);
425 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
426 st->Prepare("select id from slices where parent_id = ?");
427 st->Set(1, (int32_t)slice_id);
430 while (st->Fetch()) {
432 delete_slice_recursivly(id);
434 st->Prepare("delete from slices where id = ?");
435 st->Set(1, (int32_t)slice_id);
437 tr->Commit(); // may be we need commit only at the end of the whole recursive deletion ?
440 void faraon_session::delete_slice_with_reattach(u32_t slice_id)
442 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
443 IBPP::ilConcurrency, IBPP::lrWait);
445 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
446 st->Prepare("update slices set parent_id = (select parent_id from slices where id = ?) where parent_id = ?");
447 st->Set(1, (int32_t)slice_id);
448 st->Set(2, (int32_t)slice_id);
450 st->Prepare("delete from slices where id = ?");
451 st->Set(1, (int32_t)slice_id);
456 void faraon_session::delete_slice_assoc_data(u32_t slice_id, bool recursivly)
458 mark_files_unsorted(slice_id, recursivly, true);
463 void faraon_session::delete_slice_mark_data_unsorted(u32_t slice_id, bool recursivly)
465 mark_files_unsorted(slice_id, recursivly);
466 // mark_notes_unsorted();
470 void faraon_session::mark_files_unsorted(u32_t slice_id, bool recursivly, bool remove)
472 // delete from file_tags
473 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
474 IBPP::ilConcurrency, IBPP::lrWait);
476 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
477 st->Prepare("delete from file_tags where obj_type = 1 and obj_id = ?");
478 st->Set(1, (int32_t)slice_id);
480 // move to unsorted location
481 st->Prepare("select name from files where main_obj_type = 1 and main_obj_id = ?");
482 st->Set(1, (int32_t)slice_id);
485 sfinx_object_t o(SFINX_SLICE_OBJECT, slice_id);
486 sfinx->set_sorted_path(o);
487 sdir = o.sorted_path + "/";
488 sfinx->files_module_conf.get(FILES_MODULE_UNSORTED_PATH, udir);
494 unlink(from.c_str());
499 st->Prepare("delete from files where main_obj_id = 1 and main_obj_id = ?");
500 st->Set(1, (int32_t)slice_id);
502 gen_desc_file(SFINX_SLICE_OBJECT, slice_id);
504 u32_t pid = sfinx->parent_slice_id(slice_id);
506 mark_files_unsorted(pid, true, remove);
511 // ÕÓÔÁÎÏ×ÌÅÎ file_id = main_slice_id É name
512 // ÎÕÖÎÏ ÎÁÊÔÉ ÆÁÊÌ Õ ËÏÔÏÒÏÇÏ ÉÌÉ parent ÉÌÉ ÒÏÄÎÏÊ ÓÌÁÊÓ ÔÁËÏÊ-ÖÅ
513 void faraon_session::mark_file_unsorted(sfinx_file_t *f, bool remove)
515 // delete from file_tags
516 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
517 IBPP::ilConcurrency, IBPP::lrWait);
519 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
520 f->main_obj_id = f->file_id;
521 f->main_obj_type = SFINX_SLICE_OBJECT;
523 st->Prepare("select id from files where main_obj_type = ? and main_obj_id = ? and name = ?");
524 st->Set(1, (int32_t)f->main_obj_type);
525 st->Set(2, (int32_t)f->main_obj_id);
529 if (!st->Fetch()) { // try to find parent id
534 st->Prepare("delete from file_tags where file_id = ?");
537 // move to unsorted location
539 sfinx_object_t o(f->main_obj_type, f->main_obj_id);
540 sfinx->set_sorted_path(o);
541 sdir = o.sorted_path + "/";
542 sfinx->files_module_conf.get(FILES_MODULE_UNSORTED_PATH, udir);
543 string from = sdir + f->name;
545 unlink(from.c_str());
549 st->Prepare("delete from files where id = ?");
553 gen_desc_file(f->main_obj_type, f->main_obj_id);
556 void faraon_session::update_files_module_conf(sfinx_pair_vector_t *conf)
558 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
559 IBPP::ilConcurrency, IBPP::lrWait);
561 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
562 st->Prepare("update files_module_conf set unsorted_files_path = ?, sorted_file_tree = ?, "
563 "desc_file_name = ?, desc_file_enable = ?");
565 conf->get(FILES_MODULE_UNSORTED_PATH, t);
567 conf->get(FILES_MODULE_SORTED_TREE_PATH, t);
569 conf->get(FILES_MODULE_DESC_FILE_NAME, t);
571 u32_t gen_desc_files;
572 conf->get(FILES_MODULE_DESC_FILE_ENABLE, &gen_desc_files);
573 st->Set(4, (int32_t)gen_desc_files);
576 module_conf_request(SFINX_FILES_MODULE_CONF_REQUEST);
579 void sfinx_app::load_module_conf(u32_t id)
581 IBPP::Transaction tr = driver_->TransactionFactory(db_, IBPP::amRead,
582 IBPP::ilConcurrency, IBPP::lrWait);
584 IBPP::Statement st = driver_->StatementFactory(db_, tr);
586 case SFINX_FILES_MODULE_CONF_REQUEST:
587 st->Prepare("select unsorted_files_path, sorted_file_tree, desc_file_name, desc_file_enable from files_module_conf");
589 files_module_conf.clear();
590 files_module_conf.id(SFINX_FILES_MODULE_CONF);
591 while (st->Fetch()) {
594 files_module_conf.add(FILES_MODULE_UNSORTED_PATH, val);
596 files_module_conf.add(FILES_MODULE_SORTED_TREE_PATH, val);
598 files_module_conf.add(FILES_MODULE_DESC_FILE_NAME, val);
601 files_module_conf.add(FILES_MODULE_DESC_FILE_ENABLE, enable);
605 log("sfinx:load_module_conf", "Unknown module id - 0x%x", id);
611 void faraon_session::module_conf_request(u32_t id)
614 case SFINX_FILES_MODULE_CONF_REQUEST:
615 sfinx->load_module_conf(id);
616 send(sfinx->files_module_conf);
619 log("sfinx:module_conf_request", "Unknown module id - 0x%x", id);
624 void faraon_session::relink_slice(sfinx_slice_t *slice)
628 sfinx_object_t o_from(SFINX_SLICE_OBJECT, slice->slice_id);
629 sfinx->set_sorted_path(o_from);
630 from = o_from.sorted_path;
631 sfinx_object_t o_to(SFINX_SLICE_OBJECT, slice->parent_slice_id);
632 sfinx->set_sorted_path(o_to);
633 to = o_to.sorted_path;
634 sfinx->sorted_path_mkdir(SFINX_SLICE_OBJECT, slice->parent_slice_id);
637 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
638 IBPP::ilConcurrency, IBPP::lrWait);
640 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
641 st->Prepare("update slices set parent_id = ? where id = ?");
642 st->Set(1, (int32_t)slice->parent_slice_id);
643 st->Set(2, (int32_t)slice->slice_id);
652 // × file_id ÈÒÁÎÉÔÓÑ id ÔÅËÕÝÅÊ ÄÉÒÅËÔÏÒÉÉ-ÓÌÁÊÓÁ × ËÏÔÏÒÏÊ ÎÁÈÏÄÉÍÓÑ/×ÙÂÒÁÌÉ
653 // × main_slice_id - parent_id ÄÉÒÅËÔÏÒÉÉ
654 // name - full dir path
655 // orig_name - dir entry
656 void faraon_session::send_dir(bool sorted, sfinx_file_t *f)
659 sfinx->files_module_conf.get(sorted ? FILES_MODULE_SORTED_TREE_PATH : FILES_MODULE_UNSORTED_PATH, dir);
660 sfinx_files_vector_t files(sorted ? SFINX_FILES_MODULE_SORTED_TREE : SFINX_FILES_MODULE_UNSORTED_TREE);
663 bool mime_detect = false; // true;
664 // TODO: change mime_detect
667 // 1 - deferable detect - send list firts, ÚÁÔÅÍ ÄÏÓÙÌÁÅÍ mimes ÞÁÓÔÑÍÉ
670 struct magic_set *ms;
672 ms = magic_open(MAGIC_MIME | MAGIC_PRESERVE_ATIME | MAGIC_COMPRESS);
676 if (magic_load(ms, NULL) == -1)
680 struct dirent **namelist;
681 int n = scandir(dir.c_str(), &namelist, 0, alphasort);
683 debug("%s scandir error: %s !", dir.c_str(), strerror(errno));
687 sfinx_progress_t prg("Processing files metadata ...");
690 u32_t p_id = sfinx->parent_slice_id(f->file_id);
691 for (int i = 0; i < n; i++) {
692 if (prg.set(i, .5)) // ÛÁÇ 0.5%
695 if (!strcmp(namelist[i]->d_name, ".") || !strcmp(namelist[i]->d_name, ".."))
697 file.name = namelist[i]->d_name;
699 string full_path = dir + '/' + file.name;
700 if (stat64(full_path.c_str(), &inode))
701 debug("%s stat error: %s", full_path.c_str(), strerror(errno));
703 file.fsize = inode.st_size;
704 if (inode.st_mode & S_IFDIR)
705 file.is_directory = true;
706 file.etime.set(inode.st_ctime); // status changes
707 file.ctime.set(inode.st_mtime); // last modification
708 // set parent_id for up traverse
709 file.compressed_fsize = p_id;
711 if (file.is_directory) { // set dir id & dir parent_id from database
712 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
713 IBPP::ilConcurrency, IBPP::lrWait);
715 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
716 st->Prepare("select id from slices where directory = ? and parent_id = ?");
717 st->Set(1, file.name);
718 st->Set(2, (int32_t)f->file_id);
721 debug("*** no data for name %s and pid %d", file.name.c_str(), f->file_id);
726 file.main_obj_id = f->file_id;
727 file.main_obj_type = SFINX_SLICE_OBJECT;
728 // debug("for name %s id %d, pid %d", file.name.c_str(), id, f->file_id);
731 } else { // file - ÄÏÓÔÁÔÏÞÎÏ ÕÓÔÁÎÏ×ÉÔØ dir id, ÞÔÏ ÂÕÄÅÔ main_slice_id ÄÌÑ ÄÁÎÎÏÇÏ ÆÁÊÌÁ
732 file.file_id = f->file_id;
733 file.main_obj_type = file.main_obj_id = 0;
735 } else { // not sorted
737 file.main_obj_type = file.main_obj_id = 0;
740 const char *mimetype = magic_file(ms, full_path.c_str());
742 file.mimetype = mimetype;
744 if (file.is_directory)
745 file.mimetype = "inode/directory"; // "application/x-not-regular-file";
747 file.mimetype = "application/octet-stream";
758 // may be use 7z.so ?
759 bool compress(string &infile, string *newname)
761 int res = system(("/usr/local/bin/sfinx_compress.sh " + infile).c_str());
765 unlink(infile.c_str());
766 *newname = infile + ".7z";
770 // × ÄÉÒÅËÔÏÒÉÉ main_slice_id ÄÌÑ ×ÓÅÈ ÆÁÊÌÏ× ÓÏÚÄÁÅÍ description.txt ×ÉÄÁ:
772 // slice_name - slice_decription
774 // -----------------------------
780 // compressed size1 - XXX
781 // compressed csum1 - XXX
793 // -------------------------------
797 bool faraon_session::gen_desc_file(u32_t obj_type, u32_t obj_id)
800 u32_t slice_id = sfinx->get_object_slice(obj_type, obj_id);
801 sfinx_object_t o(SFINX_SLICE_OBJECT, slice_id);
802 sfinx->set_sorted_path(o);
804 sfinx->files_module_conf.get(FILES_MODULE_DESC_FILE_NAME, fname);
805 string desc_fname = dir + "/" + fname;
806 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
807 IBPP::ilConcurrency, IBPP::lrWait);
809 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
810 st->Prepare("select name, description, ctime, etime from slices where id = ?");
811 st->Set(1, (int32_t)slice_id);
813 if (!st->Fetch()) { // hmm, no such slice ?
814 unlink(desc_fname.c_str());
817 ofstream f(desc_fname.c_str(), ios::out | ios::binary | ios::trunc);
821 st->Get(1, t); // name
824 st->Get(2, t); // description
825 f << t << endl << endl;
827 IBPP::Timestamp xtime;
829 int year, month, day, hour, min, sec;
830 xtime.GetDate(year, month, day);
831 xtime.GetTime(hour, min, sec);
833 sprintf(buf, "Slice created: %02d/%02d/%04d %02d:%02d:%02d", day, month, year, hour, min, sec);
836 xtime.GetDate(year, month, day);
837 xtime.GetTime(hour, min, sec);
838 sprintf(buf, "Slice modified: %02d/%02d/%04d %02d:%02d:%02d", day, month, year, hour, min, sec);
844 st->Prepare("select id, name, title, authority, description, comments, ctime, etime, main_slice_id, "
845 "fsize, sha256, fsize_compressed, sha256_compressed, csum_last_checked, csum_valid, "
846 "store_in_sorted_location from files where main_obj_type = 1 and main_obj_id = ?");
847 st->Set(1, (int32_t)slice_id);
849 while (st->Fetch()) {
850 ofstream f(desc_fname.c_str(), ios::out | ios::binary | ios::app);
856 f << endl << "-------------------------------------------------------------------" << endl << endl;
857 st->Get(2, t); // name
858 f << "Name: " << t << endl;
859 st->Get(3, t); // title
860 f << "Title: " << t << endl;
861 st->Get(4, t); // authority
862 f << "Authority: " << t << endl;
863 st->Get(5, t); // description
864 f << "Description: " << t << endl;
865 st->Get(6, t); // comments
866 f << "Comments: " << t << endl;
867 IBPP::Timestamp xtime;
868 int year, month, day, hour, min, sec;
871 xtime.GetDate(year, month, day);
872 xtime.GetTime(hour, min, sec);
873 sprintf(buf, "Entry created: %02d/%02d/%04d %02d:%02d:%02d", day, month, year, hour, min, sec);
876 xtime.GetDate(year, month, day);
877 xtime.GetTime(hour, min, sec);
878 sprintf(buf, "Entry modifed: %02d/%02d/%04d %02d:%02d:%02d", day, month, year, hour, min, sec);
880 int64_t fsize, compressed_fsize;
881 int32_t main_slice_id;
882 st->Get(9, main_slice_id);
884 f << "Size: " << fsize << endl;
885 st->Get(11, t); // csum
886 f << "Csum: " << t << endl;
887 st->Get(12, compressed_fsize);
888 f << "Compressed size: " << compressed_fsize << endl;
889 st->Get(13, t); // compressed_csum
890 f << "Compressed csum: " << t << endl;
892 IBPP::Statement st1 = sfinx->driver_->StatementFactory(sfinx->db_, tr);
893 st1->Prepare("select s.name, s.description from slices s, file_tags fs where fs.file_id = ? and fs.obj_id = s.id and fs.obj_type = 1");
894 st1->Set(1, (int32_t)fid);
897 f << "Additional Slices: ";
899 while (st1->Fetch()) {
902 st1->Get(1, t); // name
904 st1->Get(2, t); // description
916 // send file by name & main_obj
917 void faraon_session::send_file(sfinx_file_t *f)
919 //debug("name - %s, fid - %d, msid - %d", f->name.c_str(), f->file_id, f->main_slice_id);
920 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
921 IBPP::ilConcurrency, IBPP::lrWait);
923 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
926 st->Prepare("select id, name, title, authority, description, comments, ctime, etime, "
927 "fsize, sha256, fsize_compressed, sha256_compressed, csum_last_checked, csum_valid, "
928 "store_in_sorted_location from files where main_obj_type = 1 and main_obj_id = ? and name = ?");
929 st->Set(1, (int32_t)f->file_id);
933 sfinx_file_t file(f->id());
935 sfinx_string_t alert(SFINX_ALERT);
936 alert.set("No such file in database !");
942 st->Get(2, file.name);
943 st->Get(3, file.title);
944 st->Get(4, file.authority);
945 st->Get(5, file.description);
946 st->Get(6, file.comments);
947 st->Get(7, file.ctime);
948 st->Get(8, file.etime);
949 int64_t fsize, compressed_fsize;
951 st->Get(10, file.csum);
952 st->Get(11, compressed_fsize);
953 file.main_obj_id = f->file_id;
954 file.main_obj_type = SFINX_SLICE_OBJECT;
956 file.compressed_fsize = compressed_fsize;
957 st->Get(12, file.compressed_csum);
958 int32_t sorted_location;
959 st->Get(15, &sorted_location);
960 file.sorted_location = sorted_location;
961 file.mimetype = "Not Set";
964 st->Prepare("select obj_id, obj_type from file_tags where file_id = ?");
967 while (st->Fetch()) {
968 int32_t obj_id, obj_type;
970 st->Get(2, &obj_type);
971 sfinx_object_t o(obj_id, obj_type);
972 file.objects.push_back(o);
978 void faraon_session::files_module_classify(sfinx_file_t *f)
980 IBPP::Transaction tr;
982 sfinx_string_t reply(SFINX_FILES_MODULE_CLASSIFY_REPLY);
983 string compressed_name, sorted_location, dir, fname;
984 sfinx_hash_t csum(GCRY_MD_SHA256), compressed_csum(GCRY_MD_SHA256);
985 sfinx->files_module_conf.get(FILES_MODULE_UNSORTED_PATH, dir);
986 fname = dir + "/" + f->name;
988 if (f->name != f->orig_name) {
989 if (rename((dir + "/" + f->orig_name).c_str(), (dir + "/" + f->name).c_str())) {
990 reply.set("Error renaming file !");
995 reply.set("Error calculating checksum for file !");
996 if (f->generate_csum && csum.hash(fname))
998 f->csum = csum.strvalue();
999 if (f->sorted_location) {
1000 sfinx_object_t o(f->main_obj_type, f->main_obj_id);
1001 reply.set("Error creating Sorted Location !");
1002 if (!sfinx->set_sorted_path(o))
1004 sorted_location = o.sorted_path;
1005 if (sfinx->sorted_path_mkdir(f->main_obj_type, f->main_obj_id))
1007 reply.set("Error moving file to Sorted Location !");
1008 if (move(fname, sorted_location))
1011 fname = sorted_location + "/" + f->name;
1013 struct stat64 inode;
1014 reply.set("Error getting file size !");
1015 if (stat64(fname.c_str(), &inode))
1018 f->fsize = inode.st_size;
1020 if (f->store_compressed) {
1021 // check if file already compressed
1022 bool compressed = false;
1023 if (f->name.size() > 3) {
1024 string ext(f->name, f->name.size() - 3);
1028 reply.set("Error compressing file !");
1030 if (compress(fname, &compressed_name))
1035 compressed_name = fname;
1036 reply.set("Error calculating checksum for compressed file !");
1037 if (f->generate_csum && compressed_csum.hash(compressed_name))
1039 f->compressed_csum = compressed_csum.strvalue();
1040 reply.set("Error getting compressed file size !");
1041 if (stat64(compressed_name.c_str(), &inode))
1044 f->compressed_fsize = inode.st_size;
1047 tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite, IBPP::ilConcurrency, IBPP::lrWait);
1049 st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1050 st->Prepare("insert into files (name, title, authority, description, comments, main_obj_id, main_obj_type, fsize, "
1051 "sha256, fsize_compressed, sha256_compressed, store_in_sorted_location) values (?, ?, ?, ?, ?, ?, ?, "
1053 st->Set(1, f->name);
1054 st->Set(2, f->title);
1055 st->Set(3, f->authority);
1056 st->Set(4, f->description);
1057 st->Set(5, f->comments);
1058 st->Set(6, (int32_t)f->main_obj_id);
1059 st->Set(7, (int32_t)f->main_obj_type);
1060 st->Set(8, (int64_t)f->fsize);
1061 st->Set(9, f->csum);
1062 st->Set(10, (int64_t)f->compressed_fsize);
1063 st->Set(11, f->compressed_csum);
1064 st->Set(12, f->sorted_location);
1067 st->Prepare("select id from files where name = ? and main_obj_type = ? and main_obj_id = ?");
1068 st->Set(1, f->name);
1069 st->Set(2, (int32_t)f->main_obj_type);
1070 st->Set(3, (int32_t)f->main_obj_id);
1076 st->Get(1, &file_id);
1077 // debug("added file has id - %d", file_id);
1080 for (u32_t i = 0; i < f->objects.size(); i++) {
1081 st->Prepare("insert into file_tags (file_id, obj_id. obj_type) values (?, ?, ?)");
1082 st->Set(1, file_id);
1083 sfinx_object_t o = f->objects[i];
1084 st->Set(2, (int64_t)o.oid);
1085 st->Set(3, (int64_t)o.otype);
1089 u32_t gen_desc_files;
1090 sfinx->files_module_conf.get(FILES_MODULE_DESC_FILE_ENABLE, &gen_desc_files);
1091 if (gen_desc_files) { // generate decription file
1092 reply.set("Error generating description file !");
1093 if (gen_desc_file(f->main_obj_type, f->main_obj_id))
1096 reply.set(""); // No error
1101 void faraon_session::notes_module_add(sfinx_note_t *n)
1103 IBPP::Transaction tr;
1105 sfinx_string_t reply(SFINX_NOTES_MODULE_ADD_REPLY);
1107 tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite, IBPP::ilConcurrency, IBPP::lrWait);
1109 st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1110 st->Prepare("insert into notes (name, text, url, main_obj_id, main_obj_type) values (?, ?, ?, ?, ?)");
1111 st->Set(1, n->name);
1112 st->Set(2, n->text);
1114 st->Set(4, (int32_t)n->main_obj_id);
1115 st->Set(5, (int32_t)n->main_obj_type);
1118 /* st->Prepare("select id from notes where name = ? and main_obj_type = ? and main_obj_id = ?");
1119 st->Set(1, n->name);
1120 st->Set(2, (int32_t)f->main_obj_type);
1121 st->Set(3, (int32_t)f->main_obj_id);
1127 st->Get(1, ¬e_id);
1128 // debug("added file has id - %d", file_id);
1131 for (u32_t i = 0; i < f->objects.size(); i++) {
1132 st->Prepare("insert into file_tags (file_id, obj_id. obj_type) values (?, ?, ?)");
1133 st->Set(1, file_id);
1134 sfinx_object_t o = f->objects[i];
1135 st->Set(2, (int64_t)o.oid);
1136 st->Set(3, (int64_t)o.otype);
1140 reply.set(""); // No error
1144 bool faraon_session::get_file_by_id(sfinx_file_t *f)
1146 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
1147 IBPP::ilConcurrency, IBPP::lrWait);
1149 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1152 st->Prepare("select name, title, authority, description, comments, ctime, etime, main_obj_id, "
1153 "main_obj_type, fsize, sha256, fsize_compressed, sha256_compressed, csum_last_checked, csum_valid, "
1154 "store_in_sorted_location from files where id = ?");
1155 st->Set(1, (int32_t)f->file_id);
1160 st->Get(1, f->name);
1161 st->Get(2, f->title);
1162 st->Get(3, f->authority);
1163 st->Get(4, f->description);
1164 st->Get(5, f->comments);
1165 st->Get(6, f->ctime);
1166 st->Get(7, f->etime);
1167 int64_t fsize, compressed_fsize;
1168 int32_t main_obj_id, main_obj_type;
1169 st->Get(8, main_obj_id);
1170 st->Get(9, main_obj_type);
1172 st->Get(11, f->csum);
1173 st->Get(12, compressed_fsize);
1174 f->main_obj_id = main_obj_id;
1175 f->main_obj_type = main_obj_type;
1177 f->compressed_fsize = compressed_fsize;
1178 st->Get(13, f->compressed_csum);
1179 int32_t sorted_location;
1180 st->Get(16, &sorted_location);
1181 f->sorted_location = sorted_location;
1182 // st->Get(xxx, f->mimetype);
1186 st->Prepare("select obj_id, obj_type from file_tags where file_id = ?");
1187 st->Set(1, (int32_t)f->file_id);
1189 while (st->Fetch()) {
1190 int32_t object_type, object_id;
1191 st->Get(1, &object_id);
1192 st->Get(2, &object_type);
1193 sfinx_object_t o(object_type, object_id);
1194 f->objects.push_back(o);
1200 void faraon_session::edit_file(sfinx_file_t *f)
1202 sfinx_file_t old_file;
1203 old_file.file_id = f->file_id;
1204 if (!get_file_by_id(&old_file))
1206 IBPP::Transaction tr;
1208 sfinx_string_t reply(SFINX_FILES_MODULE_EDIT_REPLY);
1209 string compressed_name, sorted_location, dir, fname;
1210 if (f->sorted_location) {
1211 sfinx_object_t o(f->main_obj_type, f->main_obj_id);
1212 sfinx->set_sorted_path(o);
1213 dir = o.sorted_path;
1215 sfinx->files_module_conf.get(FILES_MODULE_UNSORTED_PATH, dir);
1216 fname = dir + "/" + f->name;
1218 if (f->name != f->orig_name) {
1219 if (rename((dir + "/" + f->orig_name).c_str(), (dir + "/" + f->name).c_str())) {
1220 reply.set("Error renaming file !");
1225 tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite, IBPP::ilConcurrency, IBPP::lrWait);
1227 st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1228 st->Prepare("update files set name = ?, title = ?, authority = ?, description = ?, comments = ?, "
1229 "main_obj_id = ?, main_obj_type = ?, fsize = ?, sha256 = ?, fsize_compressed = ?, sha256_compressed = ?, "
1230 "store_in_sorted_location = ? where id = ?");
1231 st->Set(1, f->name);
1232 st->Set(2, f->title);
1233 st->Set(3, f->authority);
1234 st->Set(4, f->description);
1235 st->Set(5, f->comments);
1236 st->Set(6, (int32_t)f->main_obj_id);
1237 st->Set(7, (int32_t)f->main_obj_type);
1238 st->Set(8, (int64_t)f->fsize);
1239 st->Set(9, f->csum);
1240 st->Set(10, (int64_t)f->compressed_fsize);
1241 st->Set(11, f->compressed_csum);
1242 st->Set(12, f->sorted_location);
1243 st->Set(13, (int32_t)f->file_id);
1247 st->Prepare("delete from file_tags where file_id = ?");
1248 st->Set(1, (int32_t)f->file_id);
1250 for (u32_t i = 0; i < f->objects.size(); i++) {
1251 st->Prepare("insert into file_tags (file_id, obj_id, obj_type) values (?, ?, ?)");
1252 st->Set(1, (int32_t)f->file_id);
1253 sfinx_object_t o = f->objects[i];
1254 st->Set(2, (int64_t)o.oid);
1255 st->Set(3, (int64_t)o.otype);
1259 u32_t gen_desc_files;
1260 sfinx->files_module_conf.get(FILES_MODULE_DESC_FILE_ENABLE, &gen_desc_files);
1261 if (gen_desc_files) { // generate decription file
1262 reply.set("Error generating description file !");
1263 if (gen_desc_file(f->main_obj_type, f->main_obj_id))
1267 if (old_file.sorted_location && f->sorted_location &&
1268 (old_file.main_obj_id != f->main_obj_id) ||
1269 (old_file.main_obj_type != f->main_obj_type)) {
1270 sfinx_object_t o(old_file.main_obj_type, old_file.main_obj_id);
1271 sfinx->set_sorted_path(o);
1272 string from = o.sorted_path + "/" + old_file.name;
1273 o.otype = f->main_obj_type;
1274 o.oid = f->main_obj_id;
1275 sfinx->set_sorted_path(o);
1276 string to = o.sorted_path + "/" + f->name;
1277 sfinx->sorted_path_mkdir(f->main_obj_type, f->main_obj_id);
1280 gen_desc_file(f->main_obj_type, f->main_obj_id);
1281 gen_desc_file(old_file.main_obj_type, old_file.main_obj_id);
1283 reply.set(""); // No error
1288 void faraon_session::search_in_files(string &pattern, sfinx_pair_vector_t *r)
1290 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
1291 IBPP::ilConcurrency, IBPP::lrWait);
1293 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr),
1294 st1 = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1295 st->Prepare("select id, name, title, authority, description, comments, ctime, etime, main_obj_id, "
1296 "main_obj_type, fsize, sha256, fsize_compressed, sha256_compressed, csum_last_checked, csum_valid, "
1297 "store_in_sorted_location from files where name like ? or title like ? or authority like ? or "
1298 "description like ? or comments like ?");
1299 st->Set(1, pattern);
1300 st->Set(2, pattern);
1301 st->Set(3, pattern);
1302 st->Set(4, pattern);
1303 st->Set(5, pattern);
1306 while (st->Fetch()) {
1311 st->Get(2, file.name);
1312 st->Get(3, file.title);
1313 st->Get(4, file.authority);
1314 st->Get(5, file.description);
1315 st->Get(6, file.comments);
1316 st->Get(7, file.ctime);
1317 st->Get(8, file.etime);
1318 int64_t fsize, compressed_fsize;
1319 int32_t main_obj_id, main_obj_type;
1320 st->Get(9, main_obj_id);
1321 st->Get(10, main_obj_type);
1323 st->Get(12, file.csum);
1324 st->Get(13, compressed_fsize);
1325 file.main_obj_id = main_obj_id;
1326 file.main_obj_type = main_obj_type;
1328 file.compressed_fsize = compressed_fsize;
1329 st->Get(14, file.compressed_csum);
1330 int32_t sorted_location;
1331 st->Get(17, &sorted_location);
1332 file.sorted_location = sorted_location;
1333 file.mimetype = "Not Set";
1335 st1->Prepare("select obj_id, obj_type from file_tags where file_id = ?");
1338 while (st1->Fetch()) {
1339 int32_t obj_id, obj_type;
1340 st1->Get(1, &obj_id);
1341 st1->Get(2, &obj_type);
1342 sfinx_object_t o(obj_type, obj_id);
1343 file.objects.push_back(o);
1345 r->add(rid++, &file);
1350 void faraon_session::search_query(sfinx_search_query_t *q)
1352 // debug("got pattern - %s", q->pattern.c_str());
1353 sfinx_pair_vector_t r(SFINX_ELEMENT_SEARCH_RESULT);
1354 // TODO: make threaded search, add sort rules
1355 string ptrn = '%' + q->pattern + '%';
1356 // search_in_slices(q->pattern, &r);
1357 search_in_files(ptrn, &r);
1358 // search_in_notes(q->pattern, &r);
1362 bool faraon_session::process_requests()
1364 if (read_packet()) {
1365 log("sfinx:process", "Error reading faraon request");
1370 while ((el = rx_elements.next())) {
1372 case SFINX_NOTES_MODULE_ADD:
1373 notes_module_add((sfinx_note_t *)el);
1375 case SFINX_NOTES_MODULE_TREE_REQUEST:
1376 get_objects(SFINX_NOTES_MODULE_TREE, (1 << SFINX_NOTE_OBJECT));
1378 case SFINX_FILES_MODULE_SORTED_UNLINK:
1379 mark_file_unsorted((sfinx_file_t *)el, true);
1381 case SFINX_FILES_MODULE_UNSORT:
1382 mark_file_unsorted((sfinx_file_t *)el);
1384 case SFINX_FILES_MODULE_UNLINK:
1385 unlink(((sfinx_string_t *)el)->c_str());
1387 case SFINX_ELEMENT_SEARCH_QUERY:
1388 search_query((sfinx_search_query_t *)el);
1390 case SFINX_FILES_MODULE_EDIT_FILE:
1391 edit_file((sfinx_file_t *)el);
1393 case SFINX_FILES_MODULE_EDIT_FILE_REQUEST:
1394 send_file((sfinx_file_t *)el);
1396 case SFINX_FILES_MODULE_CLASSIFY_REQUEST:
1397 files_module_classify((sfinx_file_t *)el);
1399 case SFINX_FILES_MODULE_SORTED_TREE_REQUEST:
1400 send_dir(true, (sfinx_file_t *)el);
1402 case SFINX_FILES_MODULE_UNSORTED_TREE_REQUEST:
1403 send_dir(false, (sfinx_file_t *)el);
1405 case SFINX_FILES_MODULE_CONF:
1406 update_files_module_conf((sfinx_pair_vector_t *)el);
1408 case SFINX_FILES_MODULE_CONF_REQUEST:
1409 // case SFINX_XXX_MODULE_CONF_REQUEST:
1410 module_conf_request(el->id());
1412 case SFINX_SLICE_RELINK:
1413 relink_slice((sfinx_slice_t *)el);
1415 case SFINX_DELETE_SLICE_ASSOC_DATA:
1416 delete_slice_assoc_data(((sfinx_32bit_t *)el)->get(), 0);
1418 case SFINX_DELETE_SLICE_ASSOC_DATA_RECURSIVLY:
1419 delete_slice_assoc_data(((sfinx_32bit_t *)el)->get(), 1);
1421 case SFINX_DELETE_SLICE_MARK_DATA_UNSORTED:
1422 delete_slice_mark_data_unsorted(((sfinx_32bit_t *)el)->get(), 0);
1424 case SFINX_DELETE_SLICE_MARK_DATA_UNSORTED_RECURSIVLY:
1425 delete_slice_mark_data_unsorted(((sfinx_32bit_t *)el)->get(), 1);
1427 case SFINX_DELETE_SLICE_WITH_REATTACH:
1428 delete_slice_with_reattach(((sfinx_32bit_t *)el)->get());
1430 case SFINX_DELETE_SLICE_RECURSIVLY:
1431 delete_slice_recursivly(((sfinx_32bit_t *)el)->get());
1433 case SFINX_NEW_SLICE:
1434 new_slice((sfinx_slice_t *)el);
1436 case SFINX_EDIT_SLICE:
1437 update_slice((sfinx_slice_t *)el);
1439 case SFINX_OBJECTS_TREE_REQUEST:
1440 get_objects(SFINX_OBJECTS_TREE, ((sfinx_32bit_t *)el)->get());
1442 case SFINX_SLICES_MODULE_TREE_REQUEST:
1443 get_slices(SFINX_SLICES_MODULE_TREE);
1445 case SFINX_SLICES_MODULE_TREE_REQUEST_EXCEPT:
1446 get_slices(SFINX_SLICES_MODULE_TREE_EXCEPT, ((sfinx_32bit_t *)el)->get());
1448 case SFINX_EDIT_SLICE_REQUEST:
1449 get_slice(((sfinx_32bit_t *)el)->get(), SFINX_EDIT_SLICE);
1452 log("sfinx:process", "Unknown element id - 0x%x", el->id());