void ObjectManipulator::moveObject(FWObject *targetLib, FWObject *obj) { FWObject *cl=getCurrentLib(); if (cl==targetLib) return; FWObject *grp = NULL; if (FWObjectDatabase::isA(targetLib)) grp = targetLib; else { grp = FWBTree().getStandardSlotForObject( targetLib, obj->getTypeName().c_str()); } if (grp==NULL) grp=targetLib; if (!grp->isReadOnly()) { map<int, set<FWObject*> > reference_holders; FWCmdMoveObject *cmd = new FWCmdMoveObject(m_project, obj->getParent(), grp, obj, reference_holders, "Move object"); m_project->undoStack->push(cmd); } if (fwbdebug) qDebug("ObjectManipulator::moveObject all done"); }
int main(int argc, char **argv) { QCoreApplication app(argc, argv, false); // compilers always write file names into manifest in Utf8 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8")); #endif QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8")); QStringList args = app.arguments(); if (args.size()<=1) { usage(argv[0]); exit(1); } QString last_arg; string filename; for (int idx=0; idx < args.size(); idx++) { QString arg = args.at(idx); last_arg = arg; if (arg == "-V") { usage(argv[0]); exit(0); } if (arg == "-f") { idx++; filename = string(args.at(idx).toLatin1().constData()); continue; } } if (filename.empty()) { usage(argv[0]); exit(1); } init(argv); try { new Resources(Constants::getResourcesFilePath()); /* create database */ objdb = new FWObjectDatabase(); /* load the data file */ UpgradePredicate upgrade_predicate; cout << " *** Loading data ..."; objdb->setReadOnly( false ); objdb->load( filename, &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(filename); objdb->reIndex(); cout << " done\n"; FWObject *slib = objdb->getById(FWObjectDatabase::STANDARD_LIB_ID); if (slib && slib->isReadOnly()) slib->setReadOnly(false); CompilerDriver_nxosacl *driver = new CompilerDriver_nxosacl(objdb); if (!driver->prepare(args)) { usage(argv[0]); exit(1); } driver->compile(); //int ret = (driver->getStatus() == BaseCompiler::FWCOMPILER_SUCCESS) ? 0 : 1; int ret = driver->getStatus(); delete driver; delete objdb; return ret; } catch(libfwbuilder::FWException &ex) { cerr << ex.toString() << endl; return 1; } catch (std::string s) { cerr << s << endl; return 1; } catch (std::exception ex) { cerr << "exception: " << ex.what() << endl; return 1; } catch (...) { cerr << "Unsupported exception"; return 1; } return 0; }
bool ProjectPanel::loadFromRCS(RCS *_rcs) { resetFD(); editingStandardLib = false; editingTemplateLib = false; bool forceSave=false; // use this flag to force 'save' operation if file should be renamed MessageBoxUpgradePredicate upgrade_predicate(mainW); assert(_rcs!=nullptr); rcs = _rcs; try { /* load the data file */ systemFile = false; clearObjects(); if (objdb) { objdb->destroyChildren(); delete objdb; } objdb = new FWObjectDatabase(); // need to drop read-only flag on the database before I load new objects objdb->setReadOnly( false ); // always loading system objects mw->showStatusBarMessage(tr("Loading system objects...") ); objdb->load( Constants::getStandardObjectsFilePath(), &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(""); // objects from a data file are in database ndb mw->showStatusBarMessage(tr("Reading and parsing data file...")); FWObjectDatabase *ndb = new FWObjectDatabase(); ndb->load(rcs->getFileName().toLocal8Bit().constData(), &upgrade_predicate,Constants::getDTDDirectory()); time_t oldtimestamp = ndb->getTimeLastModified(); /* loadingLib is true if user wants to open a library or master library file */ bool loadingLib = editingLibrary(); if (fwbdebug) { list<FWObject*> ll = ndb->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { qDebug("* Found library %s %s in the data file", FWObjectDatabase::getStringId((*i)->getId()).c_str(), (*i)->getName().c_str() ); } } /* if user opens library file, clear read-only flag so they can edit it */ if (loadingLib) { list<FWObject*> ll = ndb->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { if ((*i)->getId()==FWObjectDatabase::STANDARD_LIB_ID) editingStandardLib=true; if ((*i)->getId()==FWObjectDatabase::TEMPLATE_LIB_ID) editingTemplateLib=true; (*i)->setReadOnly( false ); } } mw->showStatusBarMessage(tr("Merging with system objects...") ); MergeConflictRes mcr(mainW); objdb->merge(ndb, &mcr); ndb->destroyChildren(); delete ndb; objdb->setFileName(rcs->getFileName().toLocal8Bit().constData()); objdb->resetTimeLastModified(oldtimestamp); objdb->setDirty(false); if (fwbdebug) { qDebug("* Merge is done"); list<FWObject*> ll = db()->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { qDebug("* Library %s %s in the data file", FWObjectDatabase::getStringId((*i)->getId()).c_str(), (*i)->getName().c_str() ); } } /* this is a hack: 'Standard' library should be read-only. I * have too many files I already converted to the new API/DTD * and I am too lazy to convert them again, so I patch it up * here. * * However, if I am editing standard library, it should not be * read-only. */ FWObject *slib = objdb->findInIndex(FWObjectDatabase::STANDARD_LIB_ID); if (slib!=nullptr ) { if (fwbdebug) qDebug("standard library read-only status: %d, " "editingStandardLib: %d", slib->isReadOnly(), editingStandardLib); slib->setReadOnly(! editingStandardLib); } /* if the file name has an old extension .xml, change it to .fwb and * warn the user */ QString fn = rcs->getFileName(); QFileInfo ofinfo(fn); if ( ofinfo.suffix()=="xml") { if (fwbdebug) { qDebug("Need to rename file: %s", fn.toLatin1().constData()); qDebug(" dirPath: %s", ofinfo.dir().absolutePath().toLatin1().constData()); qDebug(" filePath: %s", ofinfo.absoluteFilePath().toLatin1().constData()); } QString newFileName = ofinfo.dir().absolutePath() + "/" + ofinfo.completeBaseName() + ".fwb"; bool needToRename = true; /* need these dances with symlinks to fix bug #1008956: * "Existing .fwb file gets overwritten if has wrong * extension" */ QFileInfo nfinfo(newFileName); if (nfinfo.exists() && ofinfo.isSymLink() && ofinfo.readLink()==newFileName) { // .xml file is a symlink pointing at .fwb file // no need to rename needToRename = false; } if (needToRename) { if (nfinfo.exists()) { /* .fwb file exists but .xml is not a symlink * .fwb is a separate file with the same name. * * tell the user we need to rename old file but * the new file exists, then ask them to choose a * new name. If the user chooses the same name and * agrees to overwrite the file, just use this * name. If the user hits cancel, tell them they * need to choose a new name and open "file save" * dialog again. * * Show the first dialog only once. If user hits * Cancel, they see shorted version of the dialog * and will be presented with "save file" dialog * again. */ QMessageBox::warning( this,"Firewall Builder", tr("Firewall Builder uses file extension '.fwb' and\n" "needs to rename old data file '%1' to '%2',\n" "but file '%3' already exists.\n" "Choose a different name for the new file.") .arg(fn).arg(newFileName).arg(newFileName), tr("&Continue"), QString::null,QString::null, 0, 1 ); newFileName = chooseNewFileName( fn, tr("Choose name and location for the new file")); if (newFileName.isEmpty()) { QString oldFileName = ofinfo.absoluteFilePath() + ".bak"; rename(oldFileName.toLocal8Bit().constData(), fn.toLocal8Bit().constData()); QMessageBox::warning( this,"Firewall Builder", tr("Load operation cancelled and data file reverted" "to original version."), tr("&Continue"), QString::null,QString::null, 0, 1 ); loadStandardObjects(); return false; } nfinfo.setFile(newFileName); } rename(fn.toLocal8Bit().constData(), newFileName.toLocal8Bit().constData()); QMessageBox::warning( this,"Firewall Builder", tr("Firewall Builder uses file extension '.fwb'. Your data" "file '%1' \nhas been renamed '%2'") .arg(fn).arg(newFileName), tr("&Continue"), QString::null,QString::null, 0, 1 ); } fn = newFileName; } rcs->setFileName(fn); db()->setFileName(fn.toLocal8Bit().constData()); //setWindowTitle(getPageTitle()); //QCoreApplication::postEvent(mw, new updateSubWindowTitlesEvent()); mainW->disableActions(m_panel->ruleSets->count()!=0); time_t last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::load(): load complete dirty=%d " "last_modified=%s", db()->isDirty(), ctime(&last_modified)); } catch(FWException &ex) { QString trans = ex.getProperties()["failed_transformation"].c_str(); QString elem = ex.getProperties()["failed_element"].c_str(); if(!trans.isEmpty() || !elem.isEmpty()) { QString msg = tr("Exception: %1").arg(ex.toString().c_str()); if (!trans.isEmpty()) { trans.truncate(LONG_ERROR_CUTOFF); msg+="\n"+tr("Failed transformation : %1").arg(trans); } if (!elem.isEmpty()) { elem.truncate(LONG_ERROR_CUTOFF); msg+="\n"+tr("XML element : %1").arg(elem); } QMessageBox::critical( this,"Firewall Builder", tr("The program encountered error trying to load data file.\n" "The file has not been loaded. Error:\n%1").arg(msg), tr("&Continue"), QString::null,QString::null, 0, 1 ); } else { // this was not XML error, perhaps permissions or other // filesystem problem QString error_txt = QString::fromUtf8(ex.toString().c_str()); if (error_txt.length() > LONG_ERROR_CUTOFF) { error_txt.truncate(LONG_ERROR_CUTOFF); error_txt += "\n\n" + tr("(Long error message was truncated)"); } QMessageBox::critical( this,"Firewall Builder", tr("The program encountered error trying to load data file.\n" "The file has not been loaded. Error:\n%1").arg( error_txt), tr("&Continue"), QString::null,QString::null, 0, 1 ); } // load standard objects so the window does not remain empty loadStandardObjects(); return false; } db()->setReadOnly( rcs->isRO() || rcs->isTemp() ); // clear dirty flag for all objects, recursively if (!forceSave) db()->setDirty(false); mw->showStatusBarMessage(tr("Building object tree...")); QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 100); loadObjects(); QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 100); mw->showStatusBarMessage(tr("Indexing...") ); db()->reIndex(); setupAutoSave(); time_t last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::load(): all done: " "dirty=%d last_modified=%s", db()->isDirty(), ctime(&last_modified)); return true; }
bool ProjectPanel::event(QEvent *event) { if (event->type() >= QEvent::User) { fwbUpdateEvent *ev = dynamic_cast<fwbUpdateEvent*>(event); int event_code = event->type() - QEvent::User; QString data_file = ev->getFileName(); int obj_id = ev->getObjectId(); FWObject *obj = db()->findInIndex(obj_id); if (fwbdebug) qDebug() << this << "rcs:" << rcs << "rcs->getFileName():" << QString((rcs!=NULL) ? rcs->getFileName() : "") << "file:" << data_file << "event:" << ev->getEventName() << "object:" << ((obj!=NULL) ? QString::fromUtf8(obj->getName().c_str()) : "") << "(" << ((obj!=NULL) ? obj->getTypeName().c_str() : "") << ")" << "id=" << ((obj!=NULL) ? obj->getId() : -1); if (event_code == UPDATE_GUI_STATE_EVENT && mdiWindow != NULL) { m_panel->om->updateCreateObjectMenu(getCurrentLib()); ev->accept(); return true; } if ((rcs && rcs->getFileName() == data_file) || (!rcs && data_file.isEmpty())) { switch (event_code) { case RELOAD_OBJECT_TREE_EVENT: registerTreeReloadRequest(); ev->accept(); return true; case RELOAD_OBJECT_TREE_IMMEDIATELY_EVENT: m_panel->om->reload(); ev->accept(); return true; case RELOAD_RULESET_EVENT: registerRuleSetRedrawRequest(); // update rule set title as well //updateFirewallName(); ev->accept(); return true; case MAKE_CURRENT_RULE_VISIBLE_IN_RULESET_EVENT: { RuleSetView* rsv = getCurrentRuleSetView(); if (rsv) rsv->makeCurrentRuleVisible(); ev->accept(); return true; } case RELOAD_RULESET_IMMEDIATELY_EVENT: redrawRuleSets(); //reopenFirewall(); // update rule set title as well //updateFirewallName(); ev->accept(); return true; } if (obj == NULL) return false; switch (event_code) { case DATA_MODIFIED_EVENT: { // This event does not trigger any updates in the UI, // this purely data structure update event. FWObject *p = obj; while (p && Firewall::cast(p)==NULL) p = p->getParent(); Firewall *f = Firewall::cast(p); // when user locks firewall object, this code tries to // update last_modified timestamp in it because it // depends on itself. Dont. if (f && !f->isReadOnly()) { f->updateLastModifiedTimestamp(); QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(data_file, f->getId())); } registerModifiedObject(obj); QCoreApplication::postEvent(mw, new updateGUIStateEvent()); ev->accept(); return true; } case UPDATE_OBJECT_EVERYWHERE_EVENT: { Rule *rule = NULL; RuleSet* current_ruleset = NULL; RuleSetView* rsv = getCurrentRuleSetView(); RuleSetModel* md = NULL; if (rsv) { md = (RuleSetModel*)rsv->model(); current_ruleset = md->getRuleSet(); } if (RuleElement::cast(obj)) rule = Rule::cast(obj->getParent()); if (Rule::cast(obj)) rule = Rule::cast(obj); if (rule && current_ruleset && md && rule->isChildOf(current_ruleset)) { md->rowChanged(md->index(rule, 0)); ev->accept(); return true; } if (rule) { QCoreApplication::postEvent( this, new showObjectInRulesetEvent(data_file, obj_id)); ev->accept(); return true; } if (rsv) rsv->updateObject(obj); if (Library::cast(obj)) { m_panel->om->updateLibName(obj); m_panel->om->updateLibColor(obj); } QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(data_file, obj_id)); // QCoreApplication::postEvent( // this, new reloadRulesetEvent(data_file)); ev->accept(); return true; } case OBJECT_NAME_CHANGED_EVENT: { objectNameChangedEvent *name_change_event = dynamic_cast<objectNameChangedEvent*>(event); m_panel->om->updateObjectInTree(obj); if (name_change_event->rename_children) { // This performs automatic renaming of child objects if necessary m_panel->om->autoRenameChildren(obj, name_change_event->old_name); } ev->accept(); return true; } case UPDATE_LAST_COMPILED_TIMESTAMP_EVENT: if (rcs && !rcs->isRO() && Firewall::cast(obj) && !obj->isReadOnly()) { Firewall::cast(obj)->updateLastCompiledTimestamp(); QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(data_file, obj_id)); ev->accept(); return true; } break; case UPDATE_LAST_INSTALLED_TIMESTAMP_EVENT: if (rcs && !rcs->isRO() && Firewall::cast(obj) && !obj->isReadOnly()) { Firewall::cast(obj)->updateLastInstalledTimestamp(); QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(data_file, obj_id)); ev->accept(); return true; } break; } // Events below this should only be processed if // ProjectPanel has been attached to an MDI window. There // is no MDI window right after project panel is created // but some operations may already be performed. See // FWWindow::fileOpen where ProjectPanel is cfeated and // file is opened before MDI window is attached. So the UI // update events below will only be processed if MDI // window exists. if (mdiWindow == NULL) return false; switch (event->type() - QEvent::User) { case INSERT_OBJECT_IN_TREE_EVENT: { FWObject *parent = db()->findInIndex( dynamic_cast<insertObjectInTreeEvent*>(event)->parent_id); m_panel->om->insertSubtree(parent, obj); ev->accept(); return true; } case REMOVE_OBJECT_FROM_TREE_EVENT: { m_panel->om->removeObjectFromTreeView(obj); ev->accept(); return true; } case ADD_TREE_PAGE_EVENT: m_panel->om->addLib(obj); ev->accept(); return true; case REMOVE_TREE_PAGE_EVENT: m_panel->om->removeLib(obj); ev->accept(); return true; case UPDATE_OBJECT_IN_TREE_EVENT: registerObjectToUpdateInTree(obj, false); ev->accept(); return true; case UPDATE_OBJECT_AND_SUBTREE_IN_TREE_EVENT: registerObjectToUpdateInTree(obj, true); ev->accept(); return true; case UPDATE_OBJECT_AND_SUBTREE_IMMEDIATELY_EVENT: m_panel->om->updateObjectInTree(obj, true); ev->accept(); return true; case OPEN_RULESET_EVENT: openRuleSet(obj); // update rule set title as well //updateFirewallName(); ev->accept(); return true; case OPEN_RULESET_IMMEDIATELY_EVENT: openRuleSet(obj, true); // update rule set title as well //updateFirewallName(); ev->accept(); return true; case SELECT_RULE_ELEMENT_EVENT: { RuleSetView* rsv = getCurrentRuleSetView(); rsv->selectRE(Rule::cast(obj), dynamic_cast<selectRuleElementEvent*>(event)->column_type); rsv->setFocus(Qt::OtherFocusReason); ev->accept(); return true; } case SHOW_OBJECT_IN_RULESET_EVENT: { // if obj is child of RuleElement (i.e. a reference object) FWReference *ref = FWReference::cast(obj); if (ref) { RuleSet* current_ruleset = NULL; RuleSetView* rsv = getCurrentRuleSetView(); RuleSetModel* md = NULL; if (rsv) { md = (RuleSetModel*)rsv->model(); current_ruleset = md->getRuleSet(); } if (current_ruleset && obj->isChildOf(current_ruleset)) { clearManipulatorFocus(); rsv->selectRE(ref); rsv->setFocus(Qt::OtherFocusReason); } else { FWObject *rs = obj; while (rs && RuleSet::cast(rs)==NULL) rs = rs->getParent(); if (rs) { // reopen rule set right now, before we post event // to show the object in it. openRuleSet(rs); QCoreApplication::postEvent( this, new showObjectInRulesetEvent(data_file, obj_id)); } } ev->accept(); return true; } // if obj is RuleElement - select its first element RuleElement *re = RuleElement::cast(obj); if (re && re->size() > 0) { QCoreApplication::postEvent( this, new showObjectInRulesetEvent(data_file, obj->front()->getId())); ev->accept(); return true; } // if obj is Rule - select its comment (the only common rule element) Rule *rule = Rule::cast(obj); if (rule) { RuleSet* current_ruleset = NULL; RuleSetView* rsv = getCurrentRuleSetView(); RuleSetModel* md = NULL; if (rsv) { md = (RuleSetModel*)rsv->model(); current_ruleset = md->getRuleSet(); } if (current_ruleset && rule->isChildOf(current_ruleset)) { rsv->selectRE(rule, ColDesc::Comment); rsv->setFocus(Qt::OtherFocusReason); ev->accept(); return true; } else { // this rule does not belong to the current ruleset // reopen rule set right now, before we post event // to show the object in it. openRuleSet(rule->getParent(), true); QCoreApplication::postEvent( this, new showObjectInRulesetEvent(data_file, obj->getId())); } ev->accept(); return true; } ev->accept(); return true; } case SHOW_OBJECT_IN_TREE_EVENT: //m_panel->om->setFocus(); m_panel->om->openObjectInTree(obj); ev->accept(); return true; case EXPAND_OBJECT_IN_TREE: m_panel->om->expandObjectInTree(obj); ev->accept(); return true; case OPEN_LIBRARY_FOR_OBJECT_EVENT: m_panel->om->openLibForObject(obj); ev->accept(); return true; case CLOSE_OBJECT_EVENT: if (RuleSet::cast(obj)) { if (visibleRuleSet == obj) { clearFirewallTabs(); closeRuleSet(obj); } } else { m_panel->om->closeObject(); mdiWindow->update(); } ev->accept(); return true; case ADD_USER_FOLDER_EVENT: m_panel->om->addUserFolderToTree(obj, dynamic_cast<addUserFolderEvent *>(event)->m_userFolder); ev->accept(); return true; case REMOVE_USER_FOLDER_EVENT: m_panel->om->removeUserFolderFromTree(obj, dynamic_cast<removeUserFolderEvent *>(event)->m_userFolder); ev->accept(); return true; case MOVE_TOFROM_USER_FOLDER_EVENT: moveToFromUserFolderEvent *moveEvent = dynamic_cast<moveToFromUserFolderEvent *>(event); m_panel->om->moveToFromUserFolderInTree(obj, db()->findInIndex(moveEvent->m_objIdToMove), moveEvent->m_oldFolder, moveEvent->m_newFolder); ev->accept(); return true; } } return false; } //if (fwbdebug) qDebug() << this << "event:" << event; return QWidget::event(event); }