3 * Copyright (C) 2007, Rus V. Brushkoff, All rights reserved.
12 void sfinx_app::dbopen()
14 dbname_ = db_dir + "/sfinx.fdb";
17 // replace this after converting database to UTF8
18 db_ = driver_->DatabaseFactory("", dbname_, dbuser_, dbpass_, "", "UTF-8", "");
20 log("dbopen", "Connected to database %s", dbname_.c_str());
23 void sfinx_app::listen()
25 InetAddress addr((InetAddrValidator *)0);
26 log("sfinx:listen", "server listening at %d port", SFINX_PORT);
28 sfinx_socket server(addr);
29 while(server.isPendingConnection()) {
30 faraon_session *faraon = new faraon_session(server, SFINX_MAX_PACKET_SIZE);
34 catch(Socket *socket) {
37 int err = socket->getErrorNumber();
38 cerr << "client socket error : ";
39 if (err == Socket::errBindingFailed) {
40 cerr << "bind failed; port busy, bye." << endl;
43 IPV4Address saddr = socket->getPeer(&port);
45 if (!saddr.isInetAddress())
48 host = saddr.getHostname();
49 cerr << host << ":" << port << \
50 " failed : " << socket->getErrorString() << endl;
52 cerr << "listen terminated" << endl;
56 sfinx_id_t sfinx_app::parent_slice_id(sfinx_id_t slice_id)
58 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
59 IBPP::ilConcurrency, IBPP::lrWait);
61 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
62 st->Prepare("select parent_id from slices where id = ?");
63 st->Set(1, (int64_t)slice_id);
69 debug("no parent for %lld slice !", slice_id);
76 string sfinx_app::slice_name(sfinx_id_t slice_id)
79 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
80 IBPP::ilConcurrency, IBPP::lrWait);
82 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
83 st->Prepare("select name from slices where id = ?");
84 st->Set(1, (int64_t)slice_id);
93 string sfinx_app::slice_directory(sfinx_id_t slice_id)
96 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
97 IBPP::ilConcurrency, IBPP::lrWait);
99 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
100 st->Prepare("select directory from slices where id = ?");
101 st->Set(1, (int64_t)slice_id);
103 while (st->Fetch()) {
110 // set path_name to sorted location (slice names as dirs)
111 bool sfinx_app::set_sorted_path(sfinx_object_t &obj)
114 sfinx->files_module_conf.get(FILES_MODULE_SORTED_TREE_PATH, obj.path_name);
115 sfinx_object_t t = obj;
117 if (t.slice_id == 1) // root slice
119 path.insert(0, "/" + slice_directory(t.slice_id)); // TODO: handle spaces in names
120 t.slice_id = parent_slice_id(t.slice_id);
122 obj.path_name += path;
126 // returns true on error
127 bool sfinx_app::sorted_path_mkdir(sfinx_object_t &obj)
129 if (set_sorted_path(obj))
131 return system(("mkdir -p " + obj.path_name).c_str());
134 CommandOption *sfinx_opt_list = 0;
136 CommandOptionArg dbdir_opt("dbdir", "d", "\tSfinx Database Dir", false,
138 CommandOptionArg user_opt("user", "u", "\t\tsetuid() to user", false,
141 #include <sys/types.h>
146 void sfinx_app::parse_command_options(void)
148 static bool called; // ×ÙÚÙ×ÁÅÍ ÐÏÒÁÎØÛÅ ÄÁÎÎÕ f()
152 if (dbdir_opt.numValue)
153 db_dir = dbdir_opt.values[0];
155 db_dir = "/usr/local/share/sfinx";
156 if (user_opt.numValue) {
157 struct passwd *upwd = getpwnam(user_opt.values[0]);
159 log("setuid error", "No such user %s", user_opt.values[0]);
162 if (setuid(upwd->pw_uid))
163 log("setuid error", "%s", strerror(errno));
167 int main(int argc, char **argv)
169 setlocale(LC_ALL, "");
171 sprintf(version, "v%0d.%0d.%0d", SFINX_VERSION_MAJOR, SFINX_VERSION_MINOR, SFINX_VERSION_PLEVEL);
172 sfinx = new sfinx_app(argc, argv, "sfinx", version,
173 "Rus V. Brushkoff <Rus@Sfinx.Od.UA>", "GPL", sfinx_opt_list);
176 sfinx->start_ui(); // start ui first
179 catch(IBPP::Exception& e) {
180 log("IBPP::Exception", "%s", e.what());
182 sfinx->ui()->alert("%s() Error !", e.Origin());
187 bool faraon_session::connect()
189 // send plain packet with daemon version
191 tx_elements.add(daemon_version);
192 // and available crypt types
193 tx_elements.add(packet_crypt_types);
195 tx_elements.add(min_auth_levels);
196 // ÐÅÒÅÄÅÌÁÔØ Ó ÉÓÐÏÌØÚÏ×ÁÎÉÅÍ -lgcrypt
197 sfinx_8bit_vector_t md5_challenge(SFINX_MD5_SUM);
198 sfinx_crypter::get_random_bytes(md5_challenge, gcry_md_get_algo_dlen(GCRY_MD_MD5));
199 tx_elements.add(md5_challenge);
202 log("sfinx:connect", "Error reading faraon request");
206 // got SFINX_AUTH_REQUEST + auth data
207 // validate user_name/pass or rsa key
210 // send SFINX_ACCESS_GRANTED/SFINX_ACCESS_DENIED
212 sfinx_8bit_t access(SFINX_ACCESS_GRANTED);
213 access.set(0); // ÐÒÉÞÉÎÁ ÄÏÓÔÕÐÁ/ÏÔËÁÚÁ
214 tx_elements.add(access);
219 void faraon_session::run()
227 if (isPending(pendingInput, 10)) { // faraon'Ù ÐÒÏÓÀÔØ ...
228 if (process_requests()) {
229 log("sfinx:run", "Bad faraon request");
238 InetAddress saddr = (InetAddress)getPeer(&port);
239 log("sfinx:run","Faraon client error at %s:%d - %s", saddr.getHostname(),
240 port, getErrorString());
242 catch (IBPP::Exception& e) {
243 log("sfinx:run", "%s", e.what());
244 sfinx->ui()->alert("%s() Error !", e.Origin());
249 void faraon_session::get_slice(sfinx_id_t slice_id, sfinx_tid_t tid)
251 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
252 IBPP::ilConcurrency, IBPP::lrWait);
254 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
255 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 = ?");
256 st->Set(1, (int64_t)slice_id);
258 string name, directory, description, parent_name;
259 int64_t id, parent_id;
260 sfinx_timestamp_t ctime, etime;
265 st->Get(3, description);
266 st->Get(4, &parent_id);
270 st->Get(5, parent_name);
274 st->Get(8, directory);
275 sfinx_slice_t slice(id, name, directory, description, parent_name, parent_id, ctime, etime, tid);
280 void faraon_session::fill_files(sfinx_slice_t *slice)
282 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
283 IBPP::ilConcurrency, IBPP::lrWait);
285 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
286 st->Prepare("select id, title, name, description, ctime, etime, mtag_id, mtag_type from files where "
287 "mtag_slice_id = ? order by ctime desc");
288 st->Set(1, int64_t(slice->id));
292 sfinx_timestamp_t ctime, etime;
293 string name, description, title;
294 while (st->Fetch()) {
298 st->Get(4, description);
301 st->Get(7, &mtag_id);
302 st->Get(8, &mtag_type);
303 sfinx_object_t file(SFINX_FILE_OBJECT, (sfinx_id_t)id, slice->id, title.c_str(), ctime, etime);
304 file.description = " [ " + name + (description.size() ? ("/" + description) : "") + " ]";
309 void faraon_session::fill_notes(sfinx_slice_t *slice)
311 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
312 IBPP::ilConcurrency, IBPP::lrWait);
314 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
315 st->Prepare("select id, name, ctime, etime, mtag_id, mtag_type from notes where "
316 "mtag_slice_id = ? order by ctime desc");
317 st->Set(1, int64_t(slice->id));
321 sfinx_timestamp_t ctime, etime;
322 string name, description;
323 while (st->Fetch()) {
326 // note description - ' for [[SFCN] mtag_name ]'
329 st->Get(5, &mtag_id);
330 st->Get(6, &mtag_type);
335 description = " for ";
336 description += tagtype2str(o);
337 description += " " + o.name;
338 if (o.description.size())
339 description += (" [ " + o.description + " ]");
340 sfinx_object_t note(SFINX_NOTE_OBJECT, (sfinx_id_t)id, slice->id, name.c_str(), ctime, etime);
341 note.description = description;
346 void faraon_session::add_slices_from_parent(sfinx_id_t parent_id, IBPP::Transaction tr, sfinx_slice_vector_t *slices,
349 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
350 st->Prepare("select m.id, m.name, m.description, (select name from slices where id = "
351 "m.parent_id) as parent_name, m.ctime, m.etime, m.directory from slices m where parent_id = ? "
353 st->Set(1, (int64_t)parent_id);
355 string name, description, parent_name, directory;
357 sfinx_timestamp_t ctime, etime;
358 while (st->Fetch()) {
361 st->Get(3, description);
365 st->Get(4, parent_name);
369 st->Get(7, directory);
370 sfinx_slice_t slice(id, name, directory, description, parent_name, parent_id, ctime, etime);
371 if (obj_mask & (1 << SFINX_FILE_OBJECT))
373 if (obj_mask & (1 << SFINX_NOTE_OBJECT))
376 add_slices_from_parent(id, tr, slices, obj_mask);
380 // ÐÅÒÅÄÁÅÔ ÄÅÒÅ×Ï ÓÌÁÊÓÏ× + ×ÌÏÖÅÎÎÙÅ ÏÂØÅËÔÙ, ÔÉÐ ËÏÔÏÒÙÈ ÏÇÒÁÎÉÞÅÎ ÍÁÓËÏÊ
381 // ÄÅÒÅ×Ï ÐÅÒÅÄÁÅÔÓÑ ÏÔ ËÏÒÎÑ Ë ÌÉÓÔØÑÍ
382 // ÐÏËÁ ÐÒÉÍÅÎÉÍ application-side ÒÅËÕÒÓÉÀ
383 void faraon_session::get_objects(sfinx_tid_t reply_id, u32_t obj_mask)
385 sfinx_slice_vector_t slices(reply_id);
386 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
387 IBPP::ilConcurrency, IBPP::lrWait);
389 add_slices_from_parent(0, tr, &slices, obj_mask);
394 // convert all names from utf8 to filesystem charset
395 string sfinx_app::utf82fs(string &s)
397 size_t insize = s.size(), outsize = insize + 128, osize = outsize;
398 char *inptr = (char *)s.c_str(), *outbuf = new char[outsize], *buf = outbuf;
399 size_t nconv = iconv (from_utf8_cd, &inptr, &insize, &outbuf, &outsize);
401 if (nconv == (size_t) -1) {
402 F::log("iconv", "conversion error %s", strerror(errno));
406 buf[osize - outsize] = 0;
412 string sfinx_app::fs2utf8(string &s)
414 size_t insize = s.size(), utf8size = insize * 2 + 128, osize = utf8size;
415 char *inptr = (char *)s.c_str(), *utf8buf = new char[utf8size],
417 size_t nconv = iconv (to_utf8_cd, &inptr, &insize, &utf8buf, &utf8size);
419 if (nconv == (size_t) -1) {
420 F::log("iconv", "conversion error %s", strerror(errno));
424 out[osize - utf8size] = 0;
430 bool sfinx_move(string &from, string &to)
432 // debug("moving from %s -> %s", from.c_str(), to.c_str());
433 string fromfs = sfinx->utf82fs(from), tofs = sfinx->utf82fs(to);
434 int res = system(("mv \"" + fromfs + "\" \"" + tofs + "\"").c_str());
436 debug("sfinx_move: res %d", res);
440 bool sfinx_rename(string &from, string &to)
442 return sfinx_move(from, to);
445 bool sfinx_unlink(string &file)
447 string fs = sfinx->utf82fs(file);
448 int res = unlink(fs.c_str());
450 debug("sfinx_unlink %s: error %s", fs.c_str(), strerror(errno));
454 bool sfinx_rmdir(string &dir)
456 string fs = sfinx->utf82fs(dir);
457 int res = rmdir(fs.c_str());
459 debug("sfinx_unlink %s: error %s", fs.c_str(), strerror(errno));
463 // TODO: make reply alert
464 void faraon_session::update_slice(sfinx_slice_t *slice)
466 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
467 IBPP::ilConcurrency, IBPP::lrWait);
469 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
470 string old_dir = sfinx->slice_directory(slice->id);
471 if (old_dir != slice->directory()) {
474 o.type = SFINX_SLICE_OBJECT;
475 o.id = o.slice_id = slice->id;
476 sfinx->set_sorted_path(o);
478 const char *p = strrchr(from.c_str(), '/');
483 strncat(path, from.c_str(), p - from.c_str());
486 to += slice->directory();
487 sfinx_move(from, to);
489 st->Prepare("update slices set name = ?, description = ?, directory = ? where id = ?");
490 st->Set(1, slice->name());
491 st->Set(2, slice->description());
492 st->Set(3, slice->directory());
493 st->Set(4, (int64_t)slice->id);
498 void faraon_session::new_slice(sfinx_slice_t *slice)
500 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
501 IBPP::ilConcurrency, IBPP::lrWait);
503 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
504 st->Prepare("insert into slices (parent_id, name, description, directory) values (?, ?, ?, ?)");
505 st->Set(1, (int64_t)slice->parent_id);
506 st->Set(2, slice->name());
507 st->Set(3, slice->description());
508 st->Set(4, slice->directory());
513 void faraon_session::delete_slice_recursivly(sfinx_id_t slice_id)
515 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
516 IBPP::ilConcurrency, IBPP::lrWait);
518 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
519 st->Prepare("select id from slices where parent_id = ?");
520 st->Set(1, (int64_t)slice_id);
523 while (st->Fetch()) {
525 delete_slice_recursivly(id);
527 st->Prepare("delete from slices where id = ?");
528 st->Set(1, (int64_t)slice_id);
530 tr->Commit(); // may be we need commit only at the end of the whole recursive deletion ?
533 void faraon_session::delete_slice_with_reattach(sfinx_id_t slice_id)
535 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
536 IBPP::ilConcurrency, IBPP::lrWait);
538 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
539 st->Prepare("update slices set parent_id = (select parent_id from slices where id = ?) where parent_id = ?");
540 st->Set(1, (int64_t)slice_id);
541 st->Set(2, (int64_t)slice_id);
543 st->Prepare("delete from slices where id = ?");
544 st->Set(1, (int64_t)slice_id);
549 void faraon_session::delete_slice_assoc_data(sfinx_id_t slice_id, bool recursivly)
551 mark_files_unsorted(slice_id, recursivly, true);
556 void faraon_session::delete_slice_mark_data_unsorted(sfinx_id_t slice_id, bool recursivly)
558 mark_files_unsorted(slice_id, recursivly);
559 // mark_notes_unsorted();
563 void faraon_session::mark_files_unsorted(sfinx_id_t slice_id, bool recursivly, bool remove)
565 // delete from file_tags
566 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
567 IBPP::ilConcurrency, IBPP::lrWait);
569 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
570 st->Prepare("delete from file_tags where obj_type = 1 and obj_id = ?");
571 st->Set(1, (int64_t)slice_id);
573 // move to unsorted location
574 st->Prepare("select name from files where mtag_type = 1 and mtag_id = ?");
575 st->Set(1, (int64_t)slice_id);
578 sfinx_object_t o(SFINX_SLICE_OBJECT, slice_id, slice_id);
579 sfinx->set_sorted_path(o);
580 sdir = o.path_name + "/";
581 sfinx->files_module_conf.get(FILES_MODULE_UNSORTED_PATH, udir);
589 sfinx_move(from, udir);
592 st->Prepare("delete from files where mtag_id = 1 and mtag_id = ?");
593 st->Set(1, (int64_t)slice_id);
597 u32_t pid = sfinx->parent_slice_id(slice_id);
599 mark_files_unsorted(pid, true, remove);
604 void faraon_session::delete_from_files(sfinx_object_t *f, bool remove)
606 // delete from file_tags
607 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
608 IBPP::ilConcurrency, IBPP::lrWait);
610 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
611 st->Prepare("delete from file_tags where file_id = ?");
612 st->Set(1, (int64_t)f->id);
614 // move to unsorted location
616 sfinx->set_sorted_path(*f);
617 sdir = f->path_name + "/";
618 sfinx->files_module_conf.get(FILES_MODULE_UNSORTED_PATH, udir);
619 string from = sdir + f->name;
623 sfinx_move(from, udir);
625 st->Prepare("delete from files where id = ?");
626 st->Set(1, (int64_t)f->id);
632 void faraon_session::delete_from_notes(sfinx_object_t *o, bool remove)
634 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
635 IBPP::ilConcurrency, IBPP::lrWait);
637 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
639 st->Prepare("delete from note_tags where note_id = ?");
640 st->Set(1, (int64_t)o->id);
643 st->Prepare("delete from notes where id = ?");
644 st->Set(1, (int64_t)o->id);
649 void faraon_session::delete_by_mtag_from_notes(sfinx_object_t *o, bool remove)
651 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
652 IBPP::ilConcurrency, IBPP::lrWait);
654 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
655 // search for note mtagged with o
656 st->Prepare("select id from notes where mtag_type = ? and mtag_id = ?");
657 st->Set(1, (int32_t)o->type);
658 st->Set(2, (int64_t)o->id);
663 sfinx_object_t dn(SFINX_NOTE_OBJECT, dn_id); // depended note
664 // × Ó×ÏÀ ÏÞÅÒÅÄØ ÕÄÁÌÑÅÍ ×ÓÅ ÏÂØÅËÔÙ, ÚÁ×ÉÓÑÝÉÅ ÏÔ ÜÔÏÊ note
665 delete_by_mtag(&dn, remove);
666 delete_from_notes(&dn, remove);
671 void faraon_session::delete_by_mtag_from_files(sfinx_object_t *o, bool remove)
673 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
674 IBPP::ilConcurrency, IBPP::lrWait);
676 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
677 // search for note mtagged with o
678 st->Prepare("select id from files where mtag_type = ? and mtag_id = ?");
679 st->Set(1, (int32_t)o->type);
680 st->Set(2, (int64_t)o->id);
685 sfinx_object_t df(SFINX_FILE_OBJECT, df_id); // depended file
686 // × Ó×ÏÀ ÏÞÅÒÅÄØ ÕÄÁÌÑÅÍ ×ÓÅ ÏÂØÅËÔÙ, ÚÁ×ÉÓÑÝÉÅ ÏÔ ÜÔÏÇÏ file
687 delete_by_mtag(&df, remove);
688 delete_from_files(&df, remove);
693 // ÍÏÖÅÔ ÐÅÒÅÄÁ×ÁÔØ tr ÐÏ ÒÅËÕÒÓÉÉ ?
694 void faraon_session::delete_object_recursivly(sfinx_object_t *o, bool remove)
696 // delete depended objects
697 delete_by_mtag(o, remove);
698 // delete object itself
700 case SFINX_NOTE_OBJECT:
701 delete_from_notes(o, remove);
703 case SFINX_FILE_OBJECT:
704 delete_from_files(o, remove);
711 void faraon_session::update_files_module_conf(sfinx_pair_vector_t *conf)
713 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
714 IBPP::ilConcurrency, IBPP::lrWait);
716 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
717 st->Prepare("update files_module_conf set unsorted_files_path = ?, sorted_file_tree = ?, "
718 "desc_file_name = ?, desc_file_enable = ?");
720 conf->get(FILES_MODULE_UNSORTED_PATH, t);
722 conf->get(FILES_MODULE_SORTED_TREE_PATH, t);
724 conf->get(FILES_MODULE_DESC_FILE_NAME, t);
726 u32_t gen_desc_files;
727 conf->get(FILES_MODULE_DESC_FILE_ENABLE, &gen_desc_files);
728 st->Set(4, (int32_t)gen_desc_files);
731 module_conf_request(SFINX_FILES_MODULE_CONF_REQUEST);
734 void sfinx_app::load_module_conf(u32_t id)
736 IBPP::Transaction tr = driver_->TransactionFactory(db_, IBPP::amRead,
737 IBPP::ilConcurrency, IBPP::lrWait);
739 IBPP::Statement st = driver_->StatementFactory(db_, tr);
741 case SFINX_FILES_MODULE_CONF_REQUEST:
742 st->Prepare("select unsorted_files_path, sorted_file_tree, desc_file_name, desc_file_enable from files_module_conf");
744 files_module_conf.clear();
745 files_module_conf.tid(SFINX_FILES_MODULE_CONF);
746 while (st->Fetch()) {
749 files_module_conf.add(FILES_MODULE_UNSORTED_PATH, val);
751 files_module_conf.add(FILES_MODULE_SORTED_TREE_PATH, val);
753 files_module_conf.add(FILES_MODULE_DESC_FILE_NAME, val);
756 files_module_conf.add(FILES_MODULE_DESC_FILE_ENABLE, enable);
760 log("sfinx:load_module_conf", "Unknown module id - 0x%x", id);
766 void faraon_session::module_conf_request(u32_t id)
769 case SFINX_FILES_MODULE_CONF_REQUEST:
770 sfinx->load_module_conf(id);
771 send(sfinx->files_module_conf);
774 log("sfinx:module_conf_request", "Unknown module id - 0x%x", id);
779 void faraon_session::relink_slice(sfinx_slice_t *slice)
783 sfinx_object_t o_from(SFINX_SLICE_OBJECT, slice->id, slice->id);
784 sfinx->set_sorted_path(o_from);
785 from = o_from.path_name;
786 sfinx_object_t o_to(SFINX_SLICE_OBJECT, slice->parent_id, slice->parent_id);
787 sfinx->set_sorted_path(o_to);
789 sfinx->sorted_path_mkdir(SFINX_SLICE_OBJECT, slice->parent_id, slice->parent_id);
790 sfinx_move(from, to);
792 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite,
793 IBPP::ilConcurrency, IBPP::lrWait);
795 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
796 st->Prepare("update slices set parent_id = ? where id = ?");
797 st->Set(1, (int64_t)slice->parent_id);
798 st->Set(2, (int64_t)slice->id);
807 // f->name - current unsorted dir
808 void faraon_session::send_unsorted_dir(sfinx_file_t *f)
811 sfinx->files_module_conf.get(FILES_MODULE_UNSORTED_PATH, dir);
812 sfinx_files_vector_t files(SFINX_FILES_MODULE_UNSORTED_TREE);
815 bool mime_detect = true;
816 // TODO: change mime_detect
819 // 1 - deferable detect - send list firts, ÚÁÔÅÍ ÄÏÓÙÌÁÅÍ mimes ÞÁÓÔÑÍÉ
822 struct magic_set *ms;
824 ms = magic_open(MAGIC_MIME | MAGIC_PRESERVE_ATIME | MAGIC_COMPRESS);
828 if (magic_load(ms, NULL) == -1)
832 struct dirent **namelist;
833 string fsdir = sfinx->utf82fs(dir);
834 int n = scandir(fsdir.c_str(), &namelist, 0, alphasort);
836 debug("%s scandir error: %s !", dir.c_str(), strerror(errno));
840 sfinx_progress_t prg("Processing files metadata ...");
843 for (int i = 0; i < n; i++) {
844 if (prg.set(i, .5)) // ÛÁÇ 0.5%
847 if (!strcmp(namelist[i]->d_name, ".") || !strcmp(namelist[i]->d_name, ".."))
849 file.name = namelist[i]->d_name;
851 string full_path = fsdir + '/' + file.name;
852 if (stat64(full_path.c_str(), &inode))
853 debug("%s stat error: %s", full_path.c_str(), strerror(errno));
855 file.fsize = inode.st_size;
856 if (inode.st_mode & S_IFDIR)
857 file.is_directory = true;
858 file.etime.set(inode.st_ctime); // status changes
859 file.ctime.set(inode.st_mtime); // last modification
860 file.id = file.compressed_fsize = file.mtag.type = file.mtag.id = 0;
862 const char *mimetype = magic_file(ms, full_path.c_str());
864 file.mimetype = mimetype;
866 if (file.is_directory)
867 file.mimetype = "inode/directory"; // "application/x-not-regular-file";
869 file.mimetype = "application/octet-stream";
873 file.name = sfinx->fs2utf8(file.name);
882 // may be use 7z.so, progress bar ?
883 bool sfinx_compress(string &infile, string *newname)
885 string fsfile = sfinx->utf82fs(infile);
886 int res = system(("7zr a -mx=9 " + fsfile + ".7z " + fsfile +
887 " >/dev/null 2>&1").c_str());
889 debug("sfinx_compress %s: res %d", fsfile.c_str(), res);
892 sfinx_unlink(infile);
893 *newname = infile + ".7z";
897 bool sfinx_decompress(string &infile, string *newname)
899 string fsfile = sfinx->utf82fs(infile);
900 int res = system(("7zr x -y -o `dirname " + fsfile + "` " + fsfile +
901 " >/dev/null 2>&1").c_str());
903 debug("sfinx_decompress %s: res %d", fsfile.c_str(), res);
906 sfinx_unlink(infile);
907 *newname = infile.erase(infile.size() - 3, 3); // get rid off ".7z"
911 // × ÄÉÒÅËÔÏÒÉÉ Ó ÉÍÅÎÅÍ ÓÌÁÊÓÁ ÄÌÑ ×ÓÅÈ ÆÁÊÌÏ× ÓÏÚÄÁÅÍ description.txt ×ÉÄÁ:
913 // slice_name - slice_decription
915 // -----------------------------
921 // compressed size1 - XXX
922 // compressed csum1 - XXX
934 // -------------------------------
938 bool faraon_session::gen_desc_file(sfinx_object_t &o)
941 sfinx_object_t t(SFINX_SLICE_OBJECT, o.slice_id, o.slice_id);
942 sfinx->set_sorted_path(t);
944 sfinx->files_module_conf.get(FILES_MODULE_DESC_FILE_NAME, fname);
945 string desc_fname = dir + "/" + fname;
946 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
947 IBPP::ilConcurrency, IBPP::lrWait);
949 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
950 st->Prepare("select name, description, ctime, etime from slices where id = ?");
951 st->Set(1, (int64_t)o.slice_id);
953 if (!st->Fetch()) { // hmm, no such slice ?
954 sfinx_unlink(desc_fname);
955 debug("no such slice %lld", o.slice_id);
958 ofstream f(sfinx->utf82fs(desc_fname).c_str(), ios::out | ios::binary | ios::trunc);
960 debug("Cant open desc file %s", desc_fname.c_str());
964 st->Get(1, t); // name
967 st->Get(2, t); // description
968 f << t << endl << endl;
970 IBPP::Timestamp xtime;
972 int year, month, day, hour, min, sec;
973 xtime.GetDate(year, month, day);
974 xtime.GetTime(hour, min, sec);
976 sprintf(buf, "Slice created: %02d/%02d/%04d %02d:%02d:%02d", day, month, year, hour, min, sec);
979 xtime.GetDate(year, month, day);
980 xtime.GetTime(hour, min, sec);
981 sprintf(buf, "Slice modified: %02d/%02d/%04d %02d:%02d:%02d", day, month, year, hour, min, sec);
987 st->Prepare("select id, name, title, authority, description, comments, ctime, etime, "
988 "fsize, sha256, fsize_compressed, sha256_compressed, csum_last_checked, csum_valid, "
989 "store_in_sorted_location from files where mtag_slice_id = ?");
990 st->Set(1, (int64_t)o.slice_id);
992 while (st->Fetch()) {
993 ofstream f(desc_fname.c_str(), ios::out | ios::binary | ios::app);
995 debug("Cant open desc file %s", desc_fname.c_str());
1001 f << endl << "-------------------------------------------------------------------" << endl << endl;
1002 st->Get(2, t); // name
1003 f << "Name: " << sfinx->utf82fs(t) << endl;
1004 st->Get(3, t); // title
1005 f << "Title: " << sfinx->utf82fs(t) << endl;
1006 st->Get(4, t); // authority
1007 f << "Authority: " << sfinx->utf82fs(t) << endl;
1008 st->Get(5, t); // description
1009 f << "Description: " << sfinx->utf82fs(t) << endl;
1010 st->Get(6, t); // comments
1011 f << "Comments: " << sfinx->utf82fs(t) << endl;
1012 IBPP::Timestamp xtime;
1013 int year, month, day, hour, min, sec;
1016 xtime.GetDate(year, month, day);
1017 xtime.GetTime(hour, min, sec);
1018 sprintf(buf, "Entry created: %02d/%02d/%04d %02d:%02d:%02d", day, month, year, hour, min, sec);
1021 xtime.GetDate(year, month, day);
1022 xtime.GetTime(hour, min, sec);
1023 sprintf(buf, "Entry modifed: %02d/%02d/%04d %02d:%02d:%02d", day, month, year, hour, min, sec);
1025 int64_t fsize, compressed_fsize;
1027 f << "Size: " << fsize << endl;
1028 st->Get(10, t); // csum
1029 f << "Csum: " << t << endl;
1030 st->Get(11, compressed_fsize);
1031 f << "Compressed size: " << compressed_fsize << endl;
1032 st->Get(12, t); // compressed_csum
1033 f << "Compressed csum: " << t << endl;
1035 IBPP::Statement st1 = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1036 st1->Prepare("select obj_id, obj_type from file_tags where file_id = ?");
1037 st1->Set(1, (int64_t)fid);
1040 while (st1->Fetch()) {
1044 f << "Additional Tags: ";
1053 f << tagtype2str(ot) << ": ";
1054 f << sfinx->utf82fs(ot.name) << " [ ";
1055 f << sfinx->utf82fs(ot.description) << " ]";
1065 // sets slice_id, name, description for type/id
1066 // return true if success
1067 bool faraon_session::get_object(sfinx_object_t *dst, sfinx_type_t obj_type, sfinx_id_t obj_id)
1069 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
1070 IBPP::ilConcurrency, IBPP::lrWait);
1072 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1075 case SFINX_SLICE_OBJECT:
1076 st->Prepare("select name, description, ctime, etime from slices where id = ?");
1077 st->Set(1, (int64_t)obj_id);
1081 st->Get(1, dst->name);
1082 st->Get(2, dst->description);
1083 st->Get(3, dst->ctime);
1084 st->Get(4, dst->etime);
1085 dst->slice_id = obj_id;
1087 case SFINX_FILE_OBJECT:
1088 st->Prepare("select name, description, mtag_slice_id, ctime, etime from files where id = ?");
1089 st->Set(1, (int64_t)obj_id);
1093 st->Get(1, dst->name);
1094 st->Get(2, dst->description);
1095 st->Get(3, &slice_id);
1096 st->Get(4, dst->ctime);
1097 st->Get(5, dst->etime);
1098 dst->slice_id = slice_id;
1100 case SFINX_NOTE_OBJECT:
1101 st->Prepare("select name, mtag_slice_id, secured, ctime, etime from notes where id = ?");
1102 st->Set(1, (int64_t)obj_id);
1106 st->Get(1, dst->name);
1107 st->Get(2, &slice_id);
1108 st->Get(4, dst->ctime);
1109 st->Get(5, dst->etime);
1110 dst->slice_id = slice_id;
1111 //st->Get(3, dst->description); // set secured
1121 void faraon_session::send_note(sfinx_note_t *n)
1123 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
1124 IBPP::ilConcurrency, IBPP::lrWait);
1126 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1127 st->Prepare("select name, url, text, ctime, etime, mtag_type, mtag_id, secured from notes where id = ?");
1128 st->Set(1, (int64_t)n->id);
1133 sfinx_string_t alert(SFINX_ALERT);
1134 alert.set("No such note in database !");
1138 st->Get(1, note.name);
1139 st->Get(2, note.url);
1140 st->Get(3, note.text);
1141 st->Get(4, note.ctime);
1142 st->Get(5, note.etime);
1144 st->Get(6, &mtag_type);
1145 note.mtag.type = mtag_type;
1147 st->Get(7, &mtag_id);
1148 note.mtag.id = mtag_id;
1149 get_object(¬e.mtag);
1151 st->Get(8, &secured);
1152 note.secured = secured;
1155 st->Prepare("select obj_id, obj_type from note_tags where note_id = ?");
1156 st->Set(1, (int64_t)n->id);
1158 while (st->Fetch()) {
1161 st->Get(1, &tag_id);
1162 st->Get(2, &tag_type);
1163 // get tag by type and id
1168 note.tags.push_back(o);
1175 void faraon_session::send_file(sfinx_file_t *f)
1177 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
1178 IBPP::ilConcurrency, IBPP::lrWait);
1180 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1183 st->Prepare("select name, title, authority, description, comments, ctime, etime, "
1184 "fsize, sha256, fsize_compressed, sha256_compressed, csum_last_checked, csum_valid, "
1185 "store_in_sorted_location, mtag_type, mtag_id from files where id = ?");
1186 st->Set(1, (int64_t)f->id);
1188 sfinx_file_t file(f->tid());
1191 sfinx_string_t alert(SFINX_ALERT);
1192 alert.set("No such file in database !");
1196 st->Get(1, file.name);
1197 st->Get(2, file.title);
1198 st->Get(3, file.authority);
1199 st->Get(4, file.description);
1200 st->Get(5, file.comments);
1201 st->Get(6, file.ctime);
1202 st->Get(7, file.etime);
1203 int64_t fsize, compressed_fsize;
1205 st->Get(9, file.csum);
1206 st->Get(10, compressed_fsize);
1208 file.compressed_fsize = compressed_fsize;
1209 st->Get(11, file.compressed_csum);
1210 int16_t sorted_location;
1211 st->Get(14, &sorted_location);
1212 file.sorted_location = sorted_location;
1213 file.mimetype = "Not Set";
1216 st->Get(15, &mtype);
1217 file.mtag.type = mtype;
1220 get_object(&file.mtag);
1223 st->Prepare("select obj_id, obj_type from file_tags where file_id = ?");
1224 st->Set(1, (int64_t)f->id);
1226 while (st->Fetch()) {
1235 file.tags.push_back(o);
1241 void faraon_session::files_module_classify(sfinx_file_t *f)
1243 IBPP::Transaction tr;
1245 sfinx_string_t reply(SFINX_FILES_MODULE_CLASSIFY_REPLY);
1246 string compressed_name, dir, fname;
1247 sfinx_hash_t csum(GCRY_MD_SHA256), compressed_csum(GCRY_MD_SHA256);
1248 sfinx->files_module_conf.get(FILES_MODULE_UNSORTED_PATH, dir);
1249 fname = dir + "/" + f->name;
1251 if (f->name != f->orig_name) {
1252 string from = dir + "/" + f->orig_name, to = dir + "/" + f->name;
1253 if (sfinx_rename(from, to)) {
1254 reply.set("Error renaming file !");
1259 reply.set("Error calculating checksum for file !");
1260 if (f->generate_csum && csum.hash(sfinx->utf82fs(fname)))
1262 f->csum = csum.strvalue();
1263 if (f->sorted_location) {
1264 reply.set("Error creating Sorted Location !");
1265 if (sfinx->sorted_path_mkdir(f->mtag))
1267 reply.set("Error moving file to Sorted Location !");
1268 if (sfinx_move(fname, f->mtag.path_name))
1271 fname = f->mtag.path_name + "/" + f->name;
1273 struct stat64 inode;
1274 reply.set("Error getting file size !");
1275 if (stat64(sfinx->utf82fs(fname).c_str(), &inode))
1278 f->fsize = inode.st_size;
1280 if (f->store_compressed) {
1281 // check if file already compressed
1282 bool compressed = false;
1283 if (f->name.size() > 3) {
1284 string ext(f->name, f->name.size() - 3);
1288 reply.set("Error compressing file !");
1290 if (sfinx_compress(fname, &compressed_name))
1295 compressed_name = fname;
1296 reply.set("Error calculating checksum for compressed file !");
1297 if (f->generate_csum && compressed_csum.hash(sfinx->utf82fs(compressed_name)))
1299 f->compressed_csum = compressed_csum.strvalue();
1300 reply.set("Error getting compressed file size !");
1301 if (stat64(sfinx->utf82fs(compressed_name).c_str(), &inode))
1304 f->compressed_fsize = inode.st_size;
1307 tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite, IBPP::ilConcurrency, IBPP::lrWait);
1309 st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1310 st->Prepare("insert into files (name, title, authority, description, comments, mtag_id, mtag_type, "
1311 "mtag_slice_id, fsize, sha256, fsize_compressed, sha256_compressed, store_in_sorted_location) values "
1312 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
1313 st->Set(1, f->name);
1314 st->Set(2, f->title);
1315 st->Set(3, f->authority);
1316 st->Set(4, f->description);
1317 st->Set(5, f->comments);
1318 st->Set(6, (int64_t)f->mtag.id);
1319 st->Set(7, (int32_t)f->mtag.type);
1320 st->Set(8, (int64_t)f->mtag.slice_id);
1321 st->Set(9, (int64_t)f->fsize);
1322 st->Set(10, f->csum);
1323 st->Set(11, (int64_t)f->compressed_fsize);
1324 st->Set(12, f->compressed_csum);
1325 st->Set(13, f->sorted_location);
1328 st->Prepare("select id from files where name = ? and mtag_type = ? and mtag_id = ?");
1329 st->Set(1, f->name);
1330 st->Set(2, (int32_t)f->mtag.type);
1331 st->Set(3, (int64_t)f->mtag.id);
1337 st->Get(1, &file_id);
1338 // debug("added file has id - %d", file_id);
1341 for (u32_t i = 0; i < f->tags.size(); i++) {
1342 st->Prepare("insert into file_tags (file_id, obj_id, obj_type) values (?, ?, ?)");
1343 st->Set(1, file_id);
1344 st->Set(2, (int64_t)f->tags[i].id);
1345 st->Set(3, (int32_t)f->tags[i].type);
1349 u32_t gen_desc_files;
1350 sfinx->files_module_conf.get(FILES_MODULE_DESC_FILE_ENABLE, &gen_desc_files);
1351 if (gen_desc_files) { // generate decription file
1352 reply.set("Error generating description file !");
1353 if (gen_desc_file(f->mtag))
1356 reply.set(""); // No error
1361 void faraon_session::notes_module_add(sfinx_note_t *n)
1363 IBPP::Transaction tr;
1365 sfinx_string_t reply(SFINX_NOTES_MODULE_ADD_REPLY);
1367 tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite, IBPP::ilConcurrency, IBPP::lrWait);
1369 st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1370 st->Prepare("insert into notes (name, text, url, mtag_id, mtag_type, mtag_slice_id) values (?, ?, ?, ?, ?, ?)");
1371 st->Set(1, n->name);
1372 st->Set(2, n->text);
1374 st->Set(4, (int64_t)n->mtag.id);
1375 st->Set(5, (int32_t)n->mtag.type);
1376 st->Set(6, (int64_t)n->mtag.slice_id);
1379 st->Prepare("select id from notes where name = ? and mtag_type = ? and mtag_id = ? and mtag_slice_id = ?");
1380 st->Set(1, n->name);
1381 st->Set(2, (int32_t)n->mtag.type);
1382 st->Set(3, (int64_t)n->mtag.id);
1383 st->Set(4, (int64_t)n->mtag.slice_id);
1389 st->Get(1, ¬e_id);
1390 // debug("added file has id - %d", file_id);
1393 for (u32_t i = 0; i < n->tags.size(); i++) {
1394 st->Prepare("insert into note_tags (note_id, obj_id, obj_type) values (?, ?, ?)");
1395 st->Set(1, note_id);
1396 st->Set(2, (int64_t)n->tags[i].id);
1397 st->Set(3, (int32_t)n->tags[i].type);
1401 reply.set(""); // No error
1405 bool faraon_session::get_file_by_id(sfinx_file_t *f)
1407 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
1408 IBPP::ilConcurrency, IBPP::lrWait);
1410 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1413 st->Prepare("select name, title, authority, description, comments, ctime, etime, mtag_id, "
1414 "mtag_type, fsize, sha256, fsize_compressed, sha256_compressed, csum_last_checked, csum_valid, "
1415 "store_in_sorted_location, mtag_slice_id from files where id = ?");
1416 st->Set(1, (int64_t)f->id);
1421 st->Get(1, f->name);
1422 st->Get(2, f->title);
1423 st->Get(3, f->authority);
1424 st->Get(4, f->description);
1425 st->Get(5, f->comments);
1426 st->Get(6, f->ctime);
1427 st->Get(7, f->etime);
1428 int64_t fsize, compressed_fsize, mtag_id, mtag_slice_id;
1430 st->Get(8, mtag_id);
1431 st->Get(9, mtag_type);
1433 st->Get(11, f->csum);
1434 st->Get(12, compressed_fsize);
1435 f->mtag.id = mtag_id;
1436 f->mtag.type = mtag_type;
1438 f->compressed_fsize = compressed_fsize;
1439 st->Get(13, f->compressed_csum);
1440 int32_t sorted_location;
1441 st->Get(16, &sorted_location);
1442 f->sorted_location = sorted_location;
1443 st->Get(17, &mtag_slice_id);
1444 f->mtag.slice_id = mtag_slice_id;
1445 // st->Get(xxx, f->mimetype);
1449 st->Prepare("select obj_id, obj_type from file_tags where file_id = ?");
1450 st->Set(1, (int64_t)f->id);
1452 while (st->Fetch()) {
1461 f->tags.push_back(o);
1467 void faraon_session::delete_file(sfinx_file_t *f)
1470 sfinx->files_module_conf.get(FILES_MODULE_UNSORTED_PATH, fname);
1471 fname += ("/" + f->name);
1472 if (f->is_directory)
1475 sfinx_unlink(fname);
1478 void faraon_session::update_file(sfinx_file_t *f)
1480 sfinx_file_t old_file;
1481 old_file.id = f->id;
1482 if (!get_file_by_id(&old_file))
1484 IBPP::Transaction tr;
1486 sfinx_string_t reply(SFINX_FILES_MODULE_EDIT_REPLY);
1487 string compressed_name, sorted_location, dir, fname;
1488 if (f->sorted_location) {
1489 sfinx_object_t o(f->mtag.type, f->mtag.id, f->mtag.slice_id);
1490 sfinx->set_sorted_path(o);
1493 sfinx->files_module_conf.get(FILES_MODULE_UNSORTED_PATH, dir);
1494 fname = dir + "/" + f->name;
1495 if (old_file.store_compressed && !f->store_compressed) {
1496 string n = dir + "/" + f->orig_name;
1497 sfinx_decompress(n, &f->orig_name);
1498 f->compressed_csum.clear();
1499 f->compressed_fsize = 0;
1501 if (!old_file.store_compressed && f->store_compressed) {
1506 if (f->name != f->orig_name) {
1507 string from = dir + "/" + f->orig_name, to = dir + "/" + f->name;
1508 if (sfinx_rename(from, to)) {
1509 reply.set("Error renaming file !");
1514 tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite, IBPP::ilConcurrency, IBPP::lrWait);
1516 st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1517 st->Prepare("update files set name = ?, title = ?, authority = ?, description = ?, comments = ?, "
1518 "mtag_id = ?, mtag_type = ?, mtag_slice_id = ?, fsize = ?, sha256 = ?, fsize_compressed = ?, sha256_compressed = ?, "
1519 "store_in_sorted_location = ? where id = ?");
1520 st->Set(1, f->name);
1521 st->Set(2, f->title);
1522 st->Set(3, f->authority);
1523 st->Set(4, f->description);
1524 st->Set(5, f->comments);
1525 st->Set(6, (int64_t)f->mtag.id);
1526 st->Set(7, (int32_t)f->mtag.type);
1527 st->Set(8, (int64_t)f->mtag.slice_id);
1528 st->Set(9, (int64_t)f->fsize);
1529 st->Set(10, f->csum);
1530 st->Set(11, (int64_t)f->compressed_fsize);
1531 st->Set(12, f->compressed_csum);
1532 st->Set(13, f->sorted_location);
1533 st->Set(14, (int64_t)f->id);
1537 st->Prepare("delete from file_tags where file_id = ?");
1538 st->Set(1, (int64_t)f->id);
1540 for (u32_t i = 0; i < f->tags.size(); i++) {
1541 st->Prepare("insert into file_tags (file_id, obj_id, obj_type) values (?, ?, ?)");
1542 st->Set(1, (int64_t)f->id);
1543 sfinx_object_t o = f->tags[i];
1544 st->Set(2, (int64_t)o.id);
1545 st->Set(3, (int32_t)o.type);
1549 u32_t gen_desc_files;
1550 sfinx->files_module_conf.get(FILES_MODULE_DESC_FILE_ENABLE, &gen_desc_files);
1551 // move file and gendesc
1552 if (old_file.sorted_location && f->sorted_location &&
1553 (old_file.mtag.slice_id != f->mtag.slice_id)) {
1554 sfinx_object_t o(old_file.mtag.type, old_file.mtag.id, old_file.mtag.slice_id);
1555 sfinx->set_sorted_path(o);
1556 string from = o.path_name + "/" + old_file.name;
1557 o.type = f->mtag.type;
1559 o.slice_id = f->mtag.slice_id;
1560 sfinx->set_sorted_path(o);
1561 string to = o.path_name + "/" + f->name;
1562 sfinx->sorted_path_mkdir(f->mtag.type, f->mtag.id, f->mtag.slice_id);
1563 sfinx_move(from, to);
1565 if (gen_desc_files) {
1566 reply.set("Error generating new description file");
1567 if (gen_desc_file(f->mtag))
1569 reply.set("Error generating old description file");
1570 if (gen_desc_file(old_file.mtag))
1573 } else { // simple gendesc
1574 if (gen_desc_files) { // generate decription file
1575 reply.set("Error generating description file !");
1576 if (gen_desc_file(f->mtag))
1580 reply.set(""); // No error
1585 void faraon_session::update_note(sfinx_note_t *n)
1587 IBPP::Transaction tr;
1589 sfinx_string_t reply(SFINX_NOTES_MODULE_EDIT_REPLY);
1590 tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amWrite, IBPP::ilConcurrency, IBPP::lrWait);
1592 st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1593 st->Prepare("update notes set name = ?, url = ?, text = ?, mtag_id = ?, mtag_type = ?, mtag_slice_id = ?,"
1594 "secured = ? where id = ?");
1595 st->Set(1, n->name);
1597 st->Set(3, n->text);
1598 st->Set(4, (int64_t)n->mtag.id);
1599 st->Set(5, (int32_t)n->mtag.type);
1600 st->Set(6, (int64_t)n->mtag.slice_id);
1601 st->Set(7, (int16_t)n->secured);
1602 st->Set(8, (int64_t)n->id);
1605 st->Prepare("delete from note_tags where note_id = ?");
1606 st->Set(1, (int64_t)n->id);
1608 for (u32_t i = 0; i < n->tags.size(); i++) {
1609 st->Prepare("insert into note_tags (note_id, obj_id, obj_type) values (?, ?, ?)");
1610 st->Set(1, (int64_t)n->id);
1611 st->Set(2, (int64_t)n->tags[i].id);
1612 st->Set(3, (int32_t)n->tags[i].type);
1616 reply.set(""); // No error
1620 // use get_file_by_id ?
1621 void faraon_session::search_in_files(string &pattern, sfinx_pair_vector_t *r, string &where)
1623 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
1624 IBPP::ilConcurrency, IBPP::lrWait);
1626 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr),
1627 st1 = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1628 string query = "select id, name, title, authority, description, comments, ctime, etime, mtag_id, "
1629 "mtag_type, fsize, sha256, fsize_compressed, sha256_compressed, csum_last_checked, csum_valid, "
1630 "store_in_sorted_location, mtag_slice_id from files where (name like ? or title like ? or "
1631 "authority like ? or description like ? or comments like ?)";
1634 st->Set(1, pattern);
1635 st->Set(2, pattern);
1636 st->Set(3, pattern);
1637 st->Set(4, pattern);
1638 st->Set(5, pattern);
1640 int64_t rid = r->len();
1641 while (st->Fetch()) {
1646 st->Get(2, file.name);
1647 st->Get(3, file.title);
1648 st->Get(4, file.authority);
1649 st->Get(5, file.description);
1650 st->Get(6, file.comments);
1651 st->Get(7, file.ctime);
1652 st->Get(8, file.etime);
1653 int64_t fsize, compressed_fsize, mtag_id, mtag_slice_id;
1655 st->Get(9, mtag_id);
1656 st->Get(10, mtag_type);
1658 st->Get(12, file.csum);
1659 st->Get(13, compressed_fsize);
1660 file.mtag.id = mtag_id;
1661 file.mtag.type = mtag_type;
1663 file.compressed_fsize = compressed_fsize;
1664 st->Get(14, file.compressed_csum);
1665 int32_t sorted_location;
1666 st->Get(17, &sorted_location);
1667 file.sorted_location = sorted_location;
1668 st->Get(18, &mtag_slice_id);
1669 file.mtag.slice_id = mtag_slice_id;
1670 file.mimetype = "Not Set";
1672 st1->Prepare("select obj_id, obj_type from file_tags where file_id = ?");
1675 while (st1->Fetch()) {
1684 file.tags.push_back(o);
1686 r->add(rid++, &file);
1691 void faraon_session::search_in_slices(string &pattern, sfinx_pair_vector_t *r, string &where)
1693 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
1694 IBPP::ilConcurrency, IBPP::lrWait);
1696 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1697 string query = "select id, name, description, ctime, etime from slices where (name like ? or "
1698 "description like ?)";
1701 st->Set(1, pattern);
1702 st->Set(2, pattern);
1704 int64_t rid = r->len();
1705 while (st->Fetch()) {
1706 sfinx_slice_t slice;
1710 st->Get(2, slice.name_);
1711 st->Get(3, slice.description_);
1712 st->Get(4, slice.ctime);
1713 st->Get(5, slice.etime);
1714 r->add(rid++, &slice);
1719 void faraon_session::search_in_notes(string &pattern, sfinx_pair_vector_t *r, string &where)
1721 IBPP::Transaction tr = sfinx->driver_->TransactionFactory(sfinx->db_, IBPP::amRead,
1722 IBPP::ilConcurrency, IBPP::lrWait);
1724 IBPP::Statement st = sfinx->driver_->StatementFactory(sfinx->db_, tr);
1725 string query = "select id, name, url, text, ctime, etime, mtag_type, mtag_id, mtag_slice_id from notes "
1726 "where (name like ? or url like ? or text like ?)";
1729 st->Set(1, pattern);
1730 st->Set(2, pattern);
1731 st->Set(3, pattern);
1733 int64_t rid = r->len();
1734 while (st->Fetch()) {
1739 st->Get(2, note.name);
1740 st->Get(3, note.url);
1741 st->Get(4, note.text);
1742 st->Get(5, note.ctime);
1743 st->Get(6, note.etime);
1744 int64_t mtag_id, mtag_slice_id;
1746 st->Get(7, mtag_type);
1747 st->Get(8, mtag_id);
1748 st->Get(9, mtag_slice_id);
1749 note.mtag.id = mtag_id;
1750 note.mtag.type = mtag_type;
1751 note.mtag.slice_id = mtag_slice_id;
1752 r->add(rid++, ¬e);
1757 // TODO: make threaded search, add sort rules
1758 void faraon_session::search_query(sfinx_search_query_t *q)
1760 sfinx_pair_vector_t r(SFINX_ELEMENT_SEARCH_RESULT);
1761 string pattern = '%' + q->pattern + '%';
1762 string where, where_slices;
1763 if (q->rtags.size()) { // build where
1764 char buf[64], buf_slices[64];
1765 where = where_slices = " and (";
1766 for (u32_t i = 0; i < q->rtags.size(); i++) {
1769 where_slices += " or ";
1771 sprintf(buf, "mtag_slice_id = %lld", q->rtags[i].slice_id);
1772 sprintf(buf_slices, "id = %lld", q->rtags[i].slice_id);
1774 where_slices += buf_slices;
1777 where_slices += ")";
1779 if (q->area(SFINX_SLICE_OBJECT))
1780 search_in_slices(pattern, &r, where_slices);
1781 if (q->area(SFINX_NOTE_OBJECT))
1782 search_in_notes(pattern, &r, where);
1783 if (q->area(SFINX_FILE_OBJECT))
1784 search_in_files(pattern, &r, where);
1788 bool faraon_session::process_requests()
1790 if (read_packet()) {
1791 log("sfinx:process", "Error reading faraon request");
1797 sfinx_string_t reply;
1798 while ((el = rx_elements.next())) {
1799 switch (el->tid()) {
1800 case SFINX_NOTES_MODULE_UNSORT:
1801 o.type = SFINX_NOTE_OBJECT;
1802 o.id = ((sfinx_note_t *)el)->id;
1803 o.slice_id = ((sfinx_file_t *)el)->mtag.slice_id;
1804 delete_object_recursivly(&o);
1805 reply.tid(SFINX_NOTES_MODULE_UNSORT_REPLY);
1808 case SFINX_NOTES_MODULE_UNLINK:
1809 o.type = SFINX_NOTE_OBJECT;
1810 o.id = ((sfinx_note_t *)el)->id;
1811 o.slice_id = ((sfinx_file_t *)el)->mtag.slice_id;
1812 delete_object_recursivly(&o, 1);
1813 reply.tid(SFINX_NOTES_MODULE_UNLINK_REPLY);
1816 case SFINX_NOTES_MODULE_EDIT:
1817 update_note((sfinx_note_t *)el);
1819 case SFINX_NOTES_MODULE_EDIT_REQUEST:
1820 send_note((sfinx_note_t *)el);
1822 case SFINX_NOTES_MODULE_ADD:
1823 notes_module_add((sfinx_note_t *)el);
1825 case SFINX_FILES_MODULE_SORTED_UNLINK:
1826 o.type = SFINX_FILE_OBJECT;
1827 o.id = ((sfinx_file_t *)el)->id;
1828 o.slice_id = ((sfinx_file_t *)el)->mtag.slice_id;
1829 delete_object_recursivly(&o, 1);
1830 reply.tid(SFINX_FILES_MODULE_SORTED_UNLINK_REPLY);
1833 case SFINX_FILES_MODULE_UNSORT:
1834 o.type = SFINX_FILE_OBJECT;
1835 o.id = ((sfinx_file_t *)el)->id;
1836 o.slice_id = ((sfinx_file_t *)el)->mtag.slice_id;
1837 delete_object_recursivly(&o);
1838 reply.tid(SFINX_FILES_MODULE_UNSORT_REPLY);
1841 case SFINX_FILES_MODULE_UNSORTED_DELETE:
1842 delete_file((sfinx_file_t *)el);
1844 case SFINX_ELEMENT_SEARCH_QUERY:
1845 search_query((sfinx_search_query_t *)el);
1847 case SFINX_FILES_MODULE_EDIT_FILE:
1848 update_file((sfinx_file_t *)el);
1850 case SFINX_FILES_MODULE_EDIT_REQUEST:
1851 send_file((sfinx_file_t *)el);
1853 case SFINX_FILES_MODULE_CLASSIFY_REQUEST:
1854 files_module_classify((sfinx_file_t *)el);
1856 case SFINX_FILES_MODULE_UNSORTED_TREE_REQUEST:
1857 send_unsorted_dir((sfinx_file_t *)el);
1859 case SFINX_FILES_MODULE_CONF:
1860 update_files_module_conf((sfinx_pair_vector_t *)el);
1862 case SFINX_FILES_MODULE_CONF_REQUEST:
1863 module_conf_request(el->tid());
1865 case SFINX_SLICE_RELINK:
1866 relink_slice((sfinx_slice_t *)el);
1868 case SFINX_DELETE_SLICE_ASSOC_DATA:
1869 delete_slice_assoc_data(((sfinx_32bit_t *)el)->get(), 0);
1871 case SFINX_DELETE_SLICE_ASSOC_DATA_RECURSIVLY:
1872 delete_slice_assoc_data(((sfinx_32bit_t *)el)->get(), 1);
1874 case SFINX_DELETE_SLICE_MARK_DATA_UNSORTED:
1875 delete_slice_mark_data_unsorted(((sfinx_32bit_t *)el)->get(), 0);
1877 case SFINX_DELETE_SLICE_MARK_DATA_UNSORTED_RECURSIVLY:
1878 delete_slice_mark_data_unsorted(((sfinx_32bit_t *)el)->get(), 1);
1880 case SFINX_DELETE_SLICE_WITH_REATTACH:
1881 delete_slice_with_reattach(((sfinx_32bit_t *)el)->get());
1883 case SFINX_DELETE_SLICE_RECURSIVLY:
1884 delete_slice_recursivly(((sfinx_32bit_t *)el)->get());
1886 case SFINX_NEW_SLICE:
1887 new_slice((sfinx_slice_t *)el);
1889 case SFINX_EDIT_SLICE:
1890 update_slice((sfinx_slice_t *)el);
1892 case SFINX_OBJECTS_TREE_REQUEST:
1893 get_objects(SFINX_OBJECTS_TREE, ((sfinx_32bit_t *)el)->get());
1895 case SFINX_EDIT_SLICE_REQUEST:
1896 get_slice(((sfinx_32bit_t *)el)->get(), SFINX_EDIT_SLICE);
1899 log("sfinx:process", "Unknown element %s (id - 0x%x)", sfinx_cmd2str(el->tid()), el->tid());