/* * main.cpp * * Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org> * * Requires the Qt widget libraries, available at no cost at * http://www.troll.no/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include <config.h> #include <tqlayout.h> #include <kaboutdata.h> #include <kgenericfactory.h> #include <kimageio.h> #include <kmessagebox.h> #include <kurldrag.h> #include "kdm-appear.h" #include "kdm-font.h" #include "kdm-users.h" #include "kdm-shut.h" #include "kdm-conv.h" #include "main.h" #include "background.h" #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <locale.h> #include <pwd.h> #include <grp.h> typedef KGenericFactory<KDModule, TQWidget> KDMFactory; K_EXPORT_COMPONENT_FACTORY( kcm_kdm, KDMFactory("kdmconfig") ) KURL *decodeImgDrop(TQDropEvent *e, TQWidget *wdg) { KURL::List uris; if (KURLDrag::decode(e, uris) && (uris.count() > 0)) { KURL *url = new KURL(uris.first()); KImageIO::registerFormats(); if( KImageIO::canRead(KImageIO::type(url->fileName())) ) return url; TQStringList qs = TQStringList::split('\n', KImageIO::pattern()); qs.remove(qs.begin()); TQString msg = i18n( "%1 " "does not appear to be an image file.\n" "Please use files with these extensions:\n" "%2") .arg(url->fileName()) .arg(qs.join("\n")); KMessageBox::sorry( wdg, msg); delete url; } return 0; } KSimpleConfig *config; KDModule::KDModule(TQWidget *parent, const char *name, const TQStringList &) : KCModule(KDMFactory::instance(), parent, name) , minshowuid(0) , maxshowuid(0) , updateOK(false) { KAboutData *about = new KAboutData(I18N_NOOP("kcmkdm"), I18N_NOOP("KDE Login Manager Config Module"), 0, 0, KAboutData::License_GPL, I18N_NOOP("(c) 1996 - 2005 The KDM Authors")); about->addAuthor("Thomas Tanghus", I18N_NOOP("Original author"), "tanghus@earthling.net"); about->addAuthor("Steffen Hansen", 0, "hansen@kde.org"); about->addAuthor("Oswald Buddenhagen", I18N_NOOP("Current maintainer"), "ossi@kde.org"); setQuickHelp( i18n( "<h1>Login Manager</h1> In this module you can configure the " "various aspects of the KDE Login Manager. This includes " "the look and feel as well as the users that can be " "selected for login. Note that you can only make changes " "if you run the module with superuser rights. If you have not started the KDE " "Control Center with superuser rights (which is absolutely the right thing to " "do, by the way), click on the <em>Modify</em> button to acquire " "superuser rights. You will be asked for the superuser password." "<h2>Appearance</h2> On this tab page, you can configure how " "the Login Manager should look, which language it should use, and which " "GUI style it should use. The language settings made here have no influence on " "the user's language settings." "<h2>Font</h2>Here you can choose the fonts that the Login Manager should use " "for various purposes like greetings and user names. " "<h2>Background</h2>If you want to set a special background for the login " "screen, this is where to do it." "<h2>Shutdown</h2> Here you can specify who is allowed to shutdown/reboot the machine " "and whether a boot manager should be used." "<h2>Users</h2>On this tab page, you can select which users the Login Manager " "will offer you for logging in." "<h2>Convenience</h2> Here you can specify a user to be logged in automatically, " "users not needing to provide a password to log in, and other convenience features.<br>" "Note, that these settings are security holes by their nature, so use them very carefully.")); setAboutData( about ); setlocale( LC_COLLATE, "C" ); KGlobal::locale()->insertCatalogue("kcmbackground"); TQStringList sl; TQMap<gid_t,TQStringList> tgmap; TQMap<gid_t,TQStringList>::Iterator tgmapi; TQMap<gid_t,TQStringList>::ConstIterator tgmapci; TQMap<TQString, QPair<int,TQStringList> >::Iterator umapi; struct passwd *ps; for (setpwent(); (ps = getpwent()); ) { TQString un( TQFile::decodeName( ps->pw_name ) ); if (usermap.find( un ) == usermap.end()) { usermap.insert( un, QPair<int,TQStringList>( ps->pw_uid, sl ) ); if ((tgmapi = tgmap.find( ps->pw_gid )) != tgmap.end()) (*tgmapi).append( un ); else tgmap[ps->pw_gid] = un; } } endpwent(); struct group *grp; for (setgrent(); (grp = getgrent()); ) { TQString gn( TQFile::decodeName( grp->gr_name ) ); bool delme = false; if ((tgmapi = tgmap.find( grp->gr_gid )) != tgmap.end()) { if ((*tgmapi).count() == 1 && (*tgmapi).first() == gn) delme = true; else for (TQStringList::ConstIterator it = (*tgmapi).begin(); it != (*tgmapi).end(); ++it) usermap[*it].second.append( gn ); tgmap.remove( tgmapi ); } if (!*grp->gr_mem || (delme && !grp->gr_mem[1] && gn == TQFile::decodeName( *grp->gr_mem ))) continue; do { TQString un( TQFile::decodeName( *grp->gr_mem ) ); if ((umapi = usermap.find( un )) != usermap.end()) { if ((*umapi).second.find( gn ) == (*umapi).second.end()) (*umapi).second.append( gn ); } else kdWarning() << "group '" << gn << "' contains unknown user '" << un << "'" << endl; } while (*++grp->gr_mem); } endgrent(); for (tgmapci = tgmap.begin(); tgmapci != tgmap.end(); ++tgmapci) kdWarning() << "user(s) '" << tgmapci.data().join(",") << "' have unknown GID " << tgmapci.key() << endl; struct stat st; if( stat( KDE_CONFDIR "/kdm/kdmdistrc" ,&st ) == 0) { config = new KSimpleConfig( TQString::fromLatin1( KDE_CONFDIR "/kdm/kdmdistrc" )); } else { config = new KSimpleConfig( TQString::fromLatin1( KDE_CONFDIR "/kdm/kdmrc" )); } TQVBoxLayout *top = new TQVBoxLayout(this); tab = new TQTabWidget(this); // ***** // _don't_ add a theme configurator until the theming engine is _really_ done!! // ***** appearance = new KDMAppearanceWidget(this); tab->addTab(appearance, i18n("A&ppearance")); connect(appearance, TQT_SIGNAL(changed(bool)), TQT_SIGNAL( changed(bool))); font = new KDMFontWidget(this); tab->addTab(font, i18n("&Font")); connect(font, TQT_SIGNAL(changed(bool)), TQT_SIGNAL(changed(bool))); background = new KBackground(this); tab->addTab(background, i18n("&Background")); connect(background, TQT_SIGNAL(changed(bool)), TQT_SIGNAL(changed(bool))); sessions = new KDMSessionsWidget(this); tab->addTab(sessions, i18n("&Shutdown")); connect(sessions, TQT_SIGNAL(changed(bool)), TQT_SIGNAL(changed(bool))); users = new KDMUsersWidget(this, 0); tab->addTab(users, i18n("&Users")); connect(users, TQT_SIGNAL(changed(bool)), TQT_SIGNAL(changed(bool))); connect(users, TQT_SIGNAL(setMinMaxUID(int,int)), TQT_SLOT(slotMinMaxUID(int,int))); connect(this, TQT_SIGNAL(addUsers(const TQMap<TQString,int> &)), users, TQT_SLOT(slotAddUsers(const TQMap<TQString,int> &))); connect(this, TQT_SIGNAL(delUsers(const TQMap<TQString,int> &)), users, TQT_SLOT(slotDelUsers(const TQMap<TQString,int> &))); connect(this, TQT_SIGNAL(clearUsers()), users, TQT_SLOT(slotClearUsers())); convenience = new KDMConvenienceWidget(this, 0); tab->addTab(convenience, i18n("Con&venience")); connect(convenience, TQT_SIGNAL(changed(bool)), TQT_SIGNAL(changed(bool))); connect(this, TQT_SIGNAL(addUsers(const TQMap<TQString,int> &)), convenience, TQT_SLOT(slotAddUsers(const TQMap<TQString,int> &))); connect(this, TQT_SIGNAL(delUsers(const TQMap<TQString,int> &)), convenience, TQT_SLOT(slotDelUsers(const TQMap<TQString,int> &))); connect(this, TQT_SIGNAL(clearUsers()), convenience, TQT_SLOT(slotClearUsers())); load(); if (getuid() != 0 || !config->checkConfigFilesWritable( true )) { appearance->makeReadOnly(); font->makeReadOnly(); background->makeReadOnly(); users->makeReadOnly(); sessions->makeReadOnly(); convenience->makeReadOnly(); } top->addWidget(tab); } KDModule::~KDModule() { delete config; } void KDModule::load() { appearance->load(); font->load(); background->load(); users->load(); sessions->load(); convenience->load(); propagateUsers(); } void KDModule::save() { appearance->save(); font->save(); background->save(); users->save(); sessions->save(); convenience->save(); config->sync(); } void KDModule::defaults() { if ( getuid() == 0 ) { appearance->defaults(); font->defaults(); background->defaults(); users->defaults(); sessions->defaults(); convenience->defaults(); propagateUsers(); } } void KDModule::propagateUsers() { groupmap.clear(); emit clearUsers(); TQMap<TQString,int> lusers; TQMapConstIterator<TQString, QPair<int,TQStringList> > it; TQStringList::ConstIterator jt; TQMap<TQString,int>::Iterator gmapi; for (it = usermap.begin(); it != usermap.end(); ++it) { int uid = it.data().first; if (!uid || (uid >= minshowuid && uid <= maxshowuid)) { lusers[it.key()] = uid; for (jt = it.data().second.begin(); jt != it.data().second.end(); ++jt) if ((gmapi = groupmap.find( *jt )) == groupmap.end()) { groupmap[*jt] = 1; lusers['@' + *jt] = -uid; } else (*gmapi)++; } } emit addUsers(lusers); updateOK = true; } void KDModule::slotMinMaxUID(int min, int max) { if (updateOK) { TQMap<TQString,int> alusers, dlusers; TQMapConstIterator<TQString, QPair<int,TQStringList> > it; TQStringList::ConstIterator jt; TQMap<TQString,int>::Iterator gmapi; for (it = usermap.begin(); it != usermap.end(); ++it) { int uid = it.data().first; if (!uid) continue; if ((uid >= minshowuid && uid <= maxshowuid) && !(uid >= min && uid <= max)) { dlusers[it.key()] = uid; for (jt = it.data().second.begin(); jt != it.data().second.end(); ++jt) { gmapi = groupmap.find( *jt ); if (!--(*gmapi)) { groupmap.remove( gmapi ); dlusers['@' + *jt] = -uid; } } } else if ((uid >= min && uid <= max) && !(uid >= minshowuid && uid <= maxshowuid)) { alusers[it.key()] = uid; for (jt = it.data().second.begin(); jt != it.data().second.end(); ++jt) if ((gmapi = groupmap.find( *jt )) == groupmap.end()) { groupmap[*jt] = 1; alusers['@' + *jt] = -uid; } else (*gmapi)++; } } emit delUsers(dlusers); emit addUsers(alusers); } minshowuid = min; maxshowuid = max; } #include "main.moc"