/* * Copyright (C) 2004 Robert Hogan */ #include "directorylist.h" #include "schedule.h" #include "klamav.h" #include "datepicker.h" #include "ktview.h" #include #include #include #include //#include #include #include #include #include #include #include // REMOVEME /* Finding out ICEauthority path */ #include Schedule::Schedule( TQWidget* parent, const char* name, bool modal, WFlags fl ) : TQDialog( parent, name, modal, fl ) { setCaption( i18n( "Schedule Scan" ) ); cthost = new CTHost(); // const CTHost& cth(*cthost); // for each user // CTCronIterator i = const_cast(cth).cron.begin(); // CTCron* ctcron((CTCron*)*i); /* Figure out where the ICEauthority file is located */ getICEauth(); //bool isRTL = TQApplication::reverseLayout(); TQHBoxLayout *hbox = new TQHBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint(), "hbox"); /* CollectionSetup not in full mode due to issue #19 */ setup = new CollectionSetup(this, true, false); hbox->addWidget(setup); TQVBoxLayout *vbox = new TQVBoxLayout(0, 0, 0, "vbox"); hbox->addLayout(vbox); TQGroupBox *group = new TQGroupBox("Schedule Scan of Selected Folders", this); vbox->addWidget(group); TQGridLayout *layout = new TQGridLayout( group, 6, 6, KDialog::spacingHint(), KDialog::spacingHint(), "layout"); layout->addRowSpacing(0, group->fontMetrics().height()); layout->setColStretch(0, 1); layout->setColStretch(1, 1); check_combo = new TQComboBox(false, group); check_combo->insertItem( i18n("When I log in to TDE")); check_combo->insertItem( i18n("Every day at ")); check_combo->insertItem( i18n("Every day at the current time")); check_combo->insertItem( i18n("Every week from now on at the current time")); check_combo->insertItem( i18n("Every week from now on at")); check_combo->insertItem( i18n("Every week from a specific date at")); check_combo->insertItem( i18n("Every month from now on at the current time")); check_combo->insertItem( i18n("Every month from now on at")); check_combo->insertItem( i18n("Every month from a specific date at")); check_combo->insertItem( i18n("Once only on a specific date at the current time")); check_combo->insertItem( i18n("Once only on a specific date at")); layout->addWidget(check_combo,1,0); connect( check_combo, SIGNAL(activated(int)),this, SLOT(slotQueryDatePicker(int)) ); hour = new HMSTimeWidget( group ); hour->setWrapping(true); hour->setMaxValue(23); hour->setValidator(new KStrictIntValidator(0, 23, hour)); layout->addWidget(hour, 1, 1); TQLabel *dots1 = new TQLabel(":", group); dots1->setMinimumWidth( 7 ); dots1->setAlignment( TQLabel::AlignCenter ); layout->addWidget(dots1, 1, 2); minute = new HMSTimeWidget( group ); minute->setWrapping(true); minute->setMinValue(0); minute->setMaxValue(59); minute->setValidator(new KStrictIntValidator(0, 59, minute)); layout->addWidget(minute, 1, 3); TQPushButton* add = new TQPushButton ("Add", group); layout->addWidget(add,1,5); //add->setFixedSize(add->sizeHint()); connect( add, SIGNAL(clicked()), SLOT(slotScheduleScan()) ); TQPushButton* del = new TQPushButton ("Delete", group); layout->addWidget(del,1,6); //del->setFixedSize(del->sizeHint()); connect( del, SIGNAL(clicked()), SLOT(slotDelete()) ); //schedulebox = new TQListView(group); schedulebox = new KTView(group); TQFontMetrics rb_fm(schedulebox->fontMetrics()); schedulebox->setMinimumSize(rb_fm.width("0")*55, rb_fm.lineSpacing()*15); /* //kdDebug() << ((schedulebox->width())/2) << endl; schedulebox->addColumn( "Paths to Scan",(group->width())); schedulebox->addColumn( "When to Scan",(group->width())); schedulebox->setResizeMode(TQListView::AllColumns); schedulebox->setSelectionMode( TQListView::Extended ); schedulebox->setAllColumnsShowFocus(true);*/ layout->addMultiCellWidget(schedulebox, 2, 4,0,6); TQHBoxLayout *h5 = new TQHBoxLayout( vbox, KDialog::spacingHint() ); h5->addStretch( 1 ); // OK KPushButton *pbOk = new KPushButton(KStdGuiItem::ok(), this, "pbOk"); pbOk->setDefault(true); h5->addWidget( pbOk); // Cancel // KPushButton *pbCancel = new KPushButton(KStdGuiItem::cancel(), this, "pbCancel"); // h5->addWidget( pbCancel); connect(pbOk, SIGNAL(clicked()), SLOT(slotOK())); /* connect(pbCancel, SIGNAL(clicked()), SLOT(slotCancel()));*/ schedulebox->hideCommand(); } Schedule::~Schedule() { delete cthost; } void Schedule::slotQueryDatePicker(int) { if (check_combo->currentText().contains(i18n("specific date")) ){ DatePicker *_calendar; _calendar = new DatePicker(this, TQDateTime::currentDateTime().date()); int x = this->width() - (this->width()/2); int y = this->height() - (this->height()/2); _calendar->move(TQPoint(x,y)); _calendar->show(); _calendar->setFocus(); connect( _calendar, SIGNAL(signalSelectedDate(TQDate)),this, SLOT(slotAddDateToCombo(TQDate)) ); } } void Schedule::slotAddDateToCombo(TQDate newdate) { //check_combo->insertItem _date = newdate; //kdDebug() << newdate.toString() << endl; TQString newstring = check_combo->currentText().replace("a specific date",newdate.toString()); check_combo->insertItem(newstring); check_combo->setCurrentItem(check_combo->count()-1); DCOPClient* client = TDEApplication::dcopClient(); client->attach(); client->registerAs(kapp->name()); } void Schedule::slotScheduleScan() { // Update directory list filepattern = setup->dirs(); setup->reset(); /* cthost = new CTHost();*/ /* const CTHost& cth(*cthost); // // // for each user CTCronIterator i = const_cast(cth).cron.begin(); CTCron* ctcron((CTCron*)*i); */ //delete cttask; TQString command = check_combo->currentText(); cttask = new CTTask ("", "", TRUE); cttask->user = ""; if (command.contains(i18n("When I log in to TDE")) ){ TQString startupcommand = createStartupScript(); cttask->comment = (const char *)i18n("KlamAV Scheduled Scan at TDE Login of %1").arg(filepattern.join(" ")).local8Bit(); cttask->command = (const char *)TQString("%1").arg(startupcommand).local8Bit(); cttask->enabled = FALSE; }else{ cttask->comment = (const char *)i18n("KlamAV Scheduled Scan of %1").arg(filepattern.join(" ")).local8Bit(); cttask->command = (const char *)TQString("%1 '%2'").arg(createScanScript()).arg(filepattern.join("' '")).local8Bit(); cttask->enabled = TRUE; } cttask->silent = FALSE; int curhour = (TQTime::currentTime()).hour(); unsigned int curmin = (TQTime::currentTime()).minute(); int shour = TQString(hour->text()).toInt(); unsigned int smin = TQString(minute->text()).toInt(); int sdatedayofweek = _date.dayOfWeek(); int todaydayofweek = TQDate::currentDate().dayOfWeek(); if (command.contains(i18n("at the current time")) ){ cttask->hour.set(curhour, TRUE); cttask->minute.set(curmin, TRUE); }else{ cttask->hour.set(shour, TRUE); cttask->minute.set(smin, TRUE); } if (command.contains(i18n("Every week")) ){ if (command.contains(i18n("from now on") )) cttask->dayOfWeek.set(todaydayofweek, TRUE); else cttask->dayOfWeek.set(sdatedayofweek, TRUE); for (int dm = 1; dm <= 31; dm++) { cttask->dayOfMonth.set(dm, true); } for (int mo = 1; mo <= 12; mo++) { cttask->month.set(mo, true); } }else if (command.contains(i18n("Every month")) ){ if (command.contains(i18n("from now on") )) cttask->dayOfMonth.set(TQDate::currentDate().day(), TRUE); else cttask->dayOfMonth.set(_date.day(), TRUE); for (int dw = 1; dw <= 7; dw++) { cttask->dayOfWeek.set(dw, true); } for (int mo = 1; mo <= 12; mo++) { cttask->month.set(mo, true); } }else if (command.contains(i18n("Every day")) ){ for (int dw = 1; dw <= 7; dw++) { cttask->dayOfWeek.set(dw, true); } for (int dm = 1; dm <= 31; dm++) { cttask->dayOfMonth.set(dm, true); } for (int mo = 1; mo <= 12; mo++) { cttask->month.set(mo, true); } }else if (command.contains(i18n("Once only")) ){ cttask->month.set(_date.month(), TRUE); cttask->dayOfMonth.set(_date.day(), TRUE); }else{ cttask->month.set(1, TRUE); cttask->dayOfMonth.set(1, TRUE); cttask->dayOfWeek.set(1, true); cttask->hour.set(0, TRUE); cttask->minute.set(0, TRUE); } TQString description = TQString::fromLocal8Bit(cttask->describe().c_str()); CTCron* ctcron(schedulebox->getCTCron()); if (cttask->dirty()) ctcron->task.push_back(cttask); //new KTListTask(this, ctcron, cttask); // TQt will clean up else delete cttask; schedulebox->refresh(); cthost->apply(); //TQListViewItem* tm = new TQListViewItem( schedulebox, _filepattern, description); /* if (cthost->isError()) { KMessageBox::error(this, cthost->errorMessage()); } //kdDebug() << "finished crontab" << endl; delete cthost;*/ } void Schedule::slotDelete() { //kdDebug() << schedulebox->currentItem()->text(1) << endl; TQFile file(schedulebox->currentItem()->text(1).section(" ",0,0).stripWhiteSpace()); file.remove(); schedulebox->remove(); cthost->apply(); } void Schedule::slotOK() { cthost->apply(); close(); } void Schedule::slotCancel() { close(); } TQString Schedule::createScanScript() { TQString path = getenv("HOME"); path += "/.klamav"; TQDir klamavdir(path); if (!klamavdir.exists() && !klamavdir.mkdir(path)) return TQString("Error"); TQTime now = TQTime::currentTime(); TQDate today = TQDate::currentDate(); TQString timestring = TQString("%1%2") .arg(today.toString("ddMMyy")) .arg(now.toString("hhmmss")); TQFile file( TQString("%1/ScanWithKlamav.sh").arg(path) ); if ( file.open( IO_WriteOnly ) ) { TQTextStream ts( &file ); TQString tdedir = getenv("TDEDIR"); ts << "#!/bin/bash" << "\n"; ts << "export HOSTNAME=`hostname`" << "\n"; ts << TQString("export PATH=%1").arg(TQString(getenv("PATH"))) << "\n"; /* The following inspired by https://unix.stackexchange.com/a/17278 */ ts << "if [ -z \"$DISPLAY\" ]; then" << "\n"; ts << " for d in /tmp/.X11-unix/X*" << "\n"; ts << " do" << "\n"; ts << " export DISPLAY=$(echo $d|sed \"s!/tmp/.X11-unix/X!:!\")" << "\n"; ts << " done" << "\n"; ts << "fi" << "\n"; ts << "export DCOPSERVER=`cat ${HOME}/.DCOPserver_${HOSTNAME}_${DISPLAY} | grep local`" << "\n"; /* This path is always the same for the current user */ ts << TQString("export ICEAUTHORITY=%1 # issue 21").arg(iceauth) << "\n"; ts << "# Execution starts here" << "\n"; ts << "if [ \"$1\" = \"\" ]; then" << "\n"; ts << " exit 1" << "\n"; ts << "fi" << "\n"; ts << "until [ -z \"$1\" ] # Until all parameters used up..." << "\n"; ts << "do" << "\n"; ts << " if [ \"${URL}\" = \"\" ]; then" << "\n"; ts << " URL=$1" << "\n"; ts << " SCANTHIS=$1" << "\n"; ts << " else" << "\n"; ts << " URL=${URL}'*'$1" << "\n"; ts << " SCANTHIS=${SCANTHIS}' '$1" << "\n"; ts << " fi" << "\n"; ts << " shift" << "\n"; ts << "done" << "\n"; ts << "DCOPEXEC=`which dcop`" << "\n"; ts << "KLAMAVEXEC=`which klamav`" << "\n"; ts << "if ${DCOPEXEC} `${DCOPEXEC}|grep klamav|head -1` DCOPKlamscan scanURLs \"${URL}\"; then" << "\n"; ts << " exit 0" << "\n"; ts << "else" << "\n"; ts << " ${KLAMAVEXEC} --scanthis ${SCANTHIS}" << "\n"; ts << "fi" << "\n"; file.close(); chmod(file.name().ascii(), S_IWUSR | S_IRUSR | S_IEXEC ); return file.name(); }else return TQString("Error"); } TQString Schedule::createStartupScript() { TQString path = TDEGlobalSettings::autostartPath(); TQDir startupdir(path); if (!startupdir.exists()) return TQString("Error"); TQTime now = TQTime::currentTime(); TQDate today = TQDate::currentDate(); TQString timestring = TQString("%1%2") .arg(today.toString("ddMMyy")) .arg(now.toString("hhmmss")); TQFile file( TQString("%1klamav_%2.desktop").arg(path).arg(timestring )); if ( file.open( IO_WriteOnly ) ) { TQTextStream ts( &file ); ts << "[Desktop Entry]" << "\n"; ts << "Encoding=UTF-8" << "\n"; ts << "Name=Klamav" << "\n"; ts << TQString("Exec=klamav %i %m -caption \"%c\" --scanthis '%1'").arg(filepattern.join("' '")) << "\n"; ts << "Icon=klamav" << "\n"; ts << "Type=Application" << "\n"; ts << "DocPath=klamav/klamav.html" << "\n"; ts << "Comment=An Anti-Virus Manager" << "\n"; ts << "Comment[cs]=Aplikace typu KPart" << "\n"; ts << "Comment[da]=Et TDE KPart program" << "\n"; ts << "Comment[de]=Ein TDE-Programm" << "\n"; ts << "Comment[el]=Μια εφαρμογή TDE KPart" << "\n"; ts << "Comment[eo]=TDEa Parto-aplikaĵo" << "\n"; ts << "Comment[es]=Una aplicación KPart para TDE" << "\n"; ts << "Comment[et]=TDE KPart rakendus" << "\n"; ts << "Comment[fi]=TDE KPart sovellus" << "\n"; ts << "Comment[fr]=Une Application KPart pour TDE" << "\n"; ts << "Comment[he]=TDE לש KPart םושיי" << "\n"; ts << "Comment[hu]=Egy TDE KPart tesztalkalmazás" << "\n"; ts << "Comment[is]=TDE KPart forrit" << "\n"; ts << "Comment[it]=Un'applicazione \"part\" di TDE" << "\n"; ts << "Comment[ja]=TDE KPart アプリケーション" << "\n"; ts << "Comment[ko]=TDE용 KPart 응용 프로그램" << "\n"; ts << "Comment[lv]=TDE KPart Aplikācija" << "\n"; ts << "Comment[nl]=een TDE KPart-applicatie" << "\n"; ts << "Comment[no_NY]=Eit TDE KPart-program" << "\n"; ts << "Comment[pt]=Uma aplicação KPart" << "\n"; ts << "Comment[pt_BR]=Uma aplicação KPart do TDE" << "\n"; ts << "Comment[ro]=O aplicaţie KPart pentru TDE" << "\n"; ts << "Comment[ru]=Приложение KPart TDE" << "\n"; ts << "Comment[sk]=TDE KPart aplikácia" << "\n"; ts << "Comment[sl]=Program za TDE KPart" << "\n"; ts << "Comment[sr]=TDE KPart aplikacija" << "\n"; ts << "Comment[sv]=Ett TDE KPart-program" << "\n"; ts << "Comment[tr]=TDE Kpart Uygulaması" << "\n"; ts << "Comment[uk]=Програма KPart для TDE" << "\n"; ts << "Comment[zh_CN.GB2312]=TDE KPart程序" << "\n"; ts << "Terminal=0" << "\n"; file.close(); chmod(file.name().ascii(), S_IWUSR | S_IRUSR | S_IEXEC ); return file.name(); }else return TQString("Error"); } void Schedule::getICEauth() { /* Code taken from freshklam.cpp */ TQString command=TQString("iceauth -v exit"); iceproc = new KProcIO(); iceproc->setUseShell(TRUE); iceproc->setUsePty(KProcIO::Stdout,TRUE); *iceproc<start(KProcIO::NotifyOnExit); iceproc->closeWhenDone(); } void Schedule::slotICEexited() { delete iceproc; } void Schedule::slotICEoutput(KProcIO *) { TQString lineout = ""; int pos; if ((pos = (iceproc->readln(lineout))) != -1) { if ((pos = (lineout.find("Using authority file"))) != -1){ lineout = lineout.stripWhiteSpace(); int StartPoint = (lineout.find("Using authority file") + 20); iceauth = lineout.mid(StartPoint).stripWhiteSpace(); // kdDebug() << "iceauth file: " << iceauth << endl; } } iceproc->ackRead(); lineout = ""; } HMSTimeWidget::HMSTimeWidget(TQWidget *parent, const char *name) : KIntSpinBox(parent, name) { } TQString HMSTimeWidget::mapValueToText(int value) { TQString s = TQString::number(value); if( value < 10 ) { s = "0" + s; } return s; } TQValidator::State KStrictIntValidator::validate( TQString & input, int & d ) const { if( input.isEmpty() ) return Valid; State st = TQIntValidator::validate( input, d ); if( st == Intermediate ) return Invalid; return st; } const CTHost& Schedule::getCTHost() const { return *cthost; } #include "schedule.moc"