From b81e43465b14836b17e4fe2dea91c78a2bdd29b3 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 22 Jan 2012 01:02:36 -0600 Subject: Part 2 of prior commit --- doc/kcontrol/kdm/CMakeLists.txt | 12 - doc/kcontrol/kdm/Makefile.am | 2 - doc/kcontrol/kdm/index.docbook | 518 ---- doc/kcontrol/tdm/CMakeLists.txt | 12 + doc/kcontrol/tdm/Makefile.am | 2 + doc/kcontrol/tdm/index.docbook | 518 ++++ doc/kdm/CMakeLists.txt | 12 - doc/kdm/Makefile.am | 6 - doc/kdm/index.docbook | 1472 ---------- doc/kdm/kdmrc-ref.docbook | 2316 ---------------- doc/tdm/CMakeLists.txt | 12 + doc/tdm/Makefile.am | 6 + doc/tdm/index.docbook | 1472 ++++++++++ doc/tdm/tdmrc-ref.docbook | 2316 ++++++++++++++++ kcontrol/kdm/AUTHORS | 6 - kcontrol/kdm/CMakeLists.txt | 40 - kcontrol/kdm/ChangeLog | 16 - kcontrol/kdm/Makefile.am | 19 - kcontrol/kdm/background.cpp | 111 - kcontrol/kdm/background.h | 50 - kcontrol/kdm/kbackedcombobox.cpp | 40 - kcontrol/kdm/kbackedcombobox.h | 38 - kcontrol/kdm/kdm-appear.cpp | 554 ---- kcontrol/kdm/kdm-appear.h | 97 - kcontrol/kdm/kdm-conv.cpp | 362 --- kcontrol/kdm/kdm-conv.h | 84 - kcontrol/kdm/kdm-font.cpp | 134 - kcontrol/kdm/kdm-font.h | 57 - kcontrol/kdm/kdm-shut.cpp | 227 -- kcontrol/kdm/kdm-shut.h | 64 - kcontrol/kdm/kdm-users.cpp | 500 ---- kcontrol/kdm/kdm-users.h | 106 - kcontrol/kdm/kdm.desktop | 243 -- kcontrol/kdm/main.cpp | 342 --- kcontrol/kdm/main.h | 83 - kcontrol/pics/cr128-app-kdmconfig.png | Bin 15977 -> 0 bytes kcontrol/pics/cr128-app-tdmconfig.png | Bin 0 -> 15977 bytes kcontrol/pics/cr16-app-kdmconfig.png | Bin 868 -> 0 bytes kcontrol/pics/cr16-app-tdmconfig.png | Bin 0 -> 868 bytes kcontrol/pics/cr22-app-kdmconfig.png | Bin 1363 -> 0 bytes kcontrol/pics/cr22-app-tdmconfig.png | Bin 0 -> 1363 bytes kcontrol/pics/cr32-app-kdmconfig.png | Bin 2280 -> 0 bytes kcontrol/pics/cr32-app-tdmconfig.png | Bin 0 -> 2280 bytes kcontrol/pics/cr48-app-kdmconfig.png | Bin 4151 -> 0 bytes kcontrol/pics/cr48-app-tdmconfig.png | Bin 0 -> 4151 bytes kcontrol/pics/cr64-app-kdmconfig.png | Bin 6154 -> 0 bytes kcontrol/pics/cr64-app-tdmconfig.png | Bin 0 -> 6154 bytes kcontrol/tdm/AUTHORS | 6 + kcontrol/tdm/CMakeLists.txt | 40 + kcontrol/tdm/ChangeLog | 16 + kcontrol/tdm/Makefile.am | 19 + kcontrol/tdm/background.cpp | 111 + kcontrol/tdm/background.h | 50 + kcontrol/tdm/kbackedcombobox.cpp | 40 + kcontrol/tdm/kbackedcombobox.h | 38 + kcontrol/tdm/main.cpp | 342 +++ kcontrol/tdm/main.h | 83 + kcontrol/tdm/tdm-appear.cpp | 554 ++++ kcontrol/tdm/tdm-appear.h | 97 + kcontrol/tdm/tdm-conv.cpp | 362 +++ kcontrol/tdm/tdm-conv.h | 84 + kcontrol/tdm/tdm-font.cpp | 134 + kcontrol/tdm/tdm-font.h | 57 + kcontrol/tdm/tdm-shut.cpp | 227 ++ kcontrol/tdm/tdm-shut.h | 64 + kcontrol/tdm/tdm-users.cpp | 500 ++++ kcontrol/tdm/tdm-users.h | 106 + kcontrol/tdm/tdm.desktop | 243 ++ kdm/CMakeLists.txt | 23 - kdm/ChangeLog | 540 ---- kdm/ConfigureChecks.cmake | 139 - kdm/Makefile.am | 20 - kdm/README | 454 ---- kdm/TODO | 243 -- kdm/backend/CMakeLists.txt | 48 - kdm/backend/Imakefile | 203 -- kdm/backend/Makefile.am | 47 - kdm/backend/access.c | 468 ---- kdm/backend/auth.c | 1238 --------- kdm/backend/bootman.c | 277 -- kdm/backend/choose.c | 1051 -------- kdm/backend/client.c | 1865 ------------- kdm/backend/consolekit.c | 557 ---- kdm/backend/consolekit.h | 36 - kdm/backend/ctrl.c | 1015 ------- kdm/backend/daemon.c | 78 - kdm/backend/dm.c | 1669 ------------ kdm/backend/dm.h | 630 ----- kdm/backend/dm_auth.h | 105 - kdm/backend/dm_error.h | 58 - kdm/backend/dm_socket.h | 72 - kdm/backend/dpylist.c | 294 -- kdm/backend/error.c | 130 - kdm/backend/genauth.c | 500 ---- kdm/backend/greet.h | 278 -- kdm/backend/inifile.c | 255 -- kdm/backend/krb5auth.c | 248 -- kdm/backend/mitauth.c | 87 - kdm/backend/netaddr.c | 219 -- kdm/backend/policy.c | 278 -- kdm/backend/printf.c | 872 ------ kdm/backend/process.c | 762 ------ kdm/backend/protodpy.c | 141 - kdm/backend/reset.c | 111 - kdm/backend/resource.c | 486 ---- kdm/backend/rpcauth.c | 89 - kdm/backend/server.c | 376 --- kdm/backend/session.c | 813 ------ kdm/backend/sessreg.c | 307 --- kdm/backend/socket.c | 418 --- kdm/backend/streams.c | 127 - kdm/backend/util.c | 637 ----- kdm/backend/xdmauth.c | 267 -- kdm/backend/xdmcp.c | 1165 -------- kdm/config.def | 2662 ------------------ kdm/configure.in.bot | 8 - kdm/configure.in.in | 361 --- kdm/confproc.pl | 838 ------ kdm/kfrontend/CMakeLists.txt | 101 - kdm/kfrontend/Makefile.am | 67 - kdm/kfrontend/genkdmconf.c | 2849 -------------------- kdm/kfrontend/kchooser.cpp | 227 -- kdm/kfrontend/kchooser.h | 59 - kdm/kfrontend/kconsole.cpp | 183 -- kdm/kfrontend/kconsole.h | 53 - kdm/kfrontend/kdm_config.c | 1477 ---------- kdm/kfrontend/kdm_greet.c | 787 ------ kdm/kfrontend/kdm_greet.h | 91 - kdm/kfrontend/kdmadmindialog.cpp | 176 -- kdm/kfrontend/kdmadmindialog.h | 70 - kdm/kfrontend/kdmclock.cpp | 176 -- kdm/kfrontend/kdmclock.h | 52 - kdm/kfrontend/kdmconfig.cpp | 179 -- kdm/kfrontend/kdmconfig.h | 69 - kdm/kfrontend/kdmctl.c | 234 -- kdm/kfrontend/kdmshutdown.cpp | 925 ------- kdm/kfrontend/kdmshutdown.h | 240 -- kdm/kfrontend/kfdialog.cpp | 182 -- kdm/kfrontend/kfdialog.h | 65 - kdm/kfrontend/kgapp.cpp | 469 ---- kdm/kfrontend/kgapp.h | 50 - kdm/kfrontend/kgdialog.cpp | 240 -- kdm/kfrontend/kgdialog.h | 87 - kdm/kfrontend/kgreeter.cpp | 1280 --------- kdm/kfrontend/kgreeter.h | 180 -- kdm/kfrontend/kgverify.cpp | 1218 --------- kdm/kfrontend/kgverify.h | 249 -- kdm/kfrontend/krootimage.cpp | 140 - kdm/kfrontend/krootimage.h | 48 - kdm/kfrontend/pics/CMakeLists.txt | 18 - kdm/kfrontend/pics/Makefile.am | 9 - kdm/kfrontend/pics/default1.png | Bin 2622 -> 0 bytes kdm/kfrontend/pics/default2.png | Bin 5663 -> 0 bytes kdm/kfrontend/pics/default3.png | Bin 4260 -> 0 bytes kdm/kfrontend/pics/kdelogo-crystal.png | Bin 11375 -> 0 bytes kdm/kfrontend/pics/kdelogo.png | Bin 13450 -> 0 bytes kdm/kfrontend/pics/root1.png | Bin 3070 -> 0 bytes kdm/kfrontend/pics/shutdown.jpg | Bin 2536 -> 0 bytes kdm/kfrontend/sakdlg.cc | 247 -- kdm/kfrontend/sakdlg.h | 64 - kdm/kfrontend/sessions/9wm.desktop | 76 - kdm/kfrontend/sessions/CMakeLists.txt | 29 - kdm/kfrontend/sessions/Makefile.am | 49 - kdm/kfrontend/sessions/admin.desktop | 7 - kdm/kfrontend/sessions/aewm++.desktop | 74 - kdm/kfrontend/sessions/aewm.desktop | 76 - kdm/kfrontend/sessions/afterstep.desktop | 83 - kdm/kfrontend/sessions/amaterus.desktop | 75 - kdm/kfrontend/sessions/amiwm.desktop | 78 - kdm/kfrontend/sessions/asclassic.desktop | 81 - kdm/kfrontend/sessions/blackbox.desktop | 88 - kdm/kfrontend/sessions/cde.desktop | 74 - kdm/kfrontend/sessions/ctwm.desktop | 72 - kdm/kfrontend/sessions/cwwm.desktop | 74 - kdm/kfrontend/sessions/enlightenment.desktop | 86 - kdm/kfrontend/sessions/evilwm.desktop | 77 - kdm/kfrontend/sessions/fluxbox.desktop | 81 - kdm/kfrontend/sessions/flwm.desktop | 77 - kdm/kfrontend/sessions/fvwm.desktop | 71 - kdm/kfrontend/sessions/fvwm2.desktop | 70 - kdm/kfrontend/sessions/fvwm95.desktop | 76 - kdm/kfrontend/sessions/gnome.desktop | 81 - kdm/kfrontend/sessions/golem.desktop | 81 - kdm/kfrontend/sessions/icewm.desktop | 81 - kdm/kfrontend/sessions/ion.desktop | 77 - kdm/kfrontend/sessions/larswm.desktop | 72 - kdm/kfrontend/sessions/lwm.desktop | 76 - kdm/kfrontend/sessions/matchbox.desktop | 82 - kdm/kfrontend/sessions/metacity.desktop | 83 - kdm/kfrontend/sessions/mwm.desktop | 78 - kdm/kfrontend/sessions/olvwm.desktop | 71 - kdm/kfrontend/sessions/olwm.desktop | 76 - kdm/kfrontend/sessions/openbox.desktop | 84 - kdm/kfrontend/sessions/oroborus.desktop | 76 - kdm/kfrontend/sessions/phluid.desktop | 80 - kdm/kfrontend/sessions/pwm.desktop | 72 - kdm/kfrontend/sessions/qvwm.desktop | 80 - kdm/kfrontend/sessions/ratpoison.desktop | 82 - kdm/kfrontend/sessions/sapphire.desktop | 84 - kdm/kfrontend/sessions/sawfish.desktop | 74 - kdm/kfrontend/sessions/tde.desktop.cmake | 45 - kdm/kfrontend/sessions/tde.desktop.in | 45 - kdm/kfrontend/sessions/twm.desktop | 71 - kdm/kfrontend/sessions/ude.desktop | 75 - kdm/kfrontend/sessions/vtwm.desktop | 72 - kdm/kfrontend/sessions/w9wm.desktop | 74 - kdm/kfrontend/sessions/waimea.desktop | 77 - kdm/kfrontend/sessions/wm2.desktop | 77 - kdm/kfrontend/sessions/wmaker.desktop | 82 - kdm/kfrontend/sessions/xfce.desktop | 73 - kdm/kfrontend/sessions/xfce4.desktop | 72 - kdm/kfrontend/themer/CMakeLists.txt | 41 - kdm/kfrontend/themer/Makefile.am | 16 - kdm/kfrontend/themer/kdmitem.cpp | 657 ----- kdm/kfrontend/themer/kdmitem.h | 272 -- kdm/kfrontend/themer/kdmlabel.cpp | 276 -- kdm/kfrontend/themer/kdmlabel.h | 87 - kdm/kfrontend/themer/kdmlayout.cpp | 168 -- kdm/kfrontend/themer/kdmlayout.h | 98 - kdm/kfrontend/themer/kdmpixmap.cpp | 340 --- kdm/kfrontend/themer/kdmpixmap.h | 73 - kdm/kfrontend/themer/kdmrect.cpp | 181 -- kdm/kfrontend/themer/kdmrect.h | 67 - kdm/kfrontend/themer/kdmthemer.cpp | 404 --- kdm/kfrontend/themer/kdmthemer.h | 128 - kdm/kfrontend/themes/CMakeLists.txt | 13 - kdm/kfrontend/themes/Makefile.am | 1 - kdm/kfrontend/themes/circles/CMakeLists.txt | 15 - .../themes/circles/GdmGreeterTheme.desktop | 135 - kdm/kfrontend/themes/circles/Makefile.am | 11 - kdm/kfrontend/themes/circles/background.svg | 39 - kdm/kfrontend/themes/circles/circles.xml | 207 -- kdm/kfrontend/themes/circles/flower.png | Bin 120376 -> 0 bytes kdm/kfrontend/themes/circles/help.png | Bin 2138 -> 0 bytes kdm/kfrontend/themes/circles/options.png | Bin 2297 -> 0 bytes kdm/kfrontend/themes/circles/screenshot.png | Bin 16847 -> 0 bytes kdm/kfrontend/themes/o2_enterprise/CMakeLists.txt | 16 - kdm/kfrontend/themes/o2_enterprise/Dialog.png | Bin 4167 -> 0 bytes .../themes/o2_enterprise/GdmGreeterTheme.desktop | 10 - kdm/kfrontend/themes/o2_enterprise/Makefile.am | 14 - .../themes/o2_enterprise/enter_normal.png | Bin 1639 -> 0 bytes kdm/kfrontend/themes/o2_enterprise/enter_over.png | Bin 2422 -> 0 bytes .../themes/o2_enterprise/enter_pressed.png | Bin 1639 -> 0 bytes kdm/kfrontend/themes/o2_enterprise/enterprise.xml | 99 - kdm/kfrontend/themes/o2_enterprise/gpl.txt | 340 --- kdm/kfrontend/themes/o2_enterprise/preview.png | Bin 381843 -> 0 bytes .../themes/o2_enterprise/system_normal.png | Bin 1623 -> 0 bytes kdm/kfrontend/themes/o2_enterprise/system_over.png | Bin 2491 -> 0 bytes .../themes/o2_enterprise/system_pressed.png | Bin 1623 -> 0 bytes kdmlib/CMakeLists.txt | 85 - kdmlib/Makefile.am | 30 - kdmlib/dmctl.cpp | 442 --- kdmlib/dmctl.h | 93 - kdmlib/kdmtsak.cpp | 180 -- kdmlib/kdmtsak.h | 144 - kdmlib/kgreet_classic.cpp | 513 ---- kdmlib/kgreet_classic.h | 88 - kdmlib/kgreet_pam.cpp | 675 ----- kdmlib/kgreet_pam.h | 94 - kdmlib/kgreet_winbind.cpp | 679 ----- kdmlib/kgreet_winbind.h | 101 - kdmlib/kgreeterplugin.h | 407 --- tdm/CMakeLists.txt | 23 + tdm/ChangeLog | 540 ++++ tdm/ConfigureChecks.cmake | 139 + tdm/Makefile.am | 20 + tdm/README | 454 ++++ tdm/TODO | 243 ++ tdm/backend/CMakeLists.txt | 48 + tdm/backend/Imakefile | 203 ++ tdm/backend/Makefile.am | 47 + tdm/backend/access.c | 468 ++++ tdm/backend/auth.c | 1238 +++++++++ tdm/backend/bootman.c | 277 ++ tdm/backend/choose.c | 1051 ++++++++ tdm/backend/client.c | 1865 +++++++++++++ tdm/backend/consolekit.c | 557 ++++ tdm/backend/consolekit.h | 36 + tdm/backend/ctrl.c | 1015 +++++++ tdm/backend/daemon.c | 78 + tdm/backend/dm.c | 1669 ++++++++++++ tdm/backend/dm.h | 630 +++++ tdm/backend/dm_auth.h | 105 + tdm/backend/dm_error.h | 58 + tdm/backend/dm_socket.h | 72 + tdm/backend/dpylist.c | 294 ++ tdm/backend/error.c | 130 + tdm/backend/genauth.c | 500 ++++ tdm/backend/greet.h | 278 ++ tdm/backend/inifile.c | 255 ++ tdm/backend/krb5auth.c | 248 ++ tdm/backend/mitauth.c | 87 + tdm/backend/netaddr.c | 219 ++ tdm/backend/policy.c | 278 ++ tdm/backend/printf.c | 872 ++++++ tdm/backend/process.c | 762 ++++++ tdm/backend/protodpy.c | 141 + tdm/backend/reset.c | 111 + tdm/backend/resource.c | 486 ++++ tdm/backend/rpcauth.c | 89 + tdm/backend/server.c | 376 +++ tdm/backend/session.c | 813 ++++++ tdm/backend/sessreg.c | 307 +++ tdm/backend/socket.c | 418 +++ tdm/backend/streams.c | 127 + tdm/backend/util.c | 637 +++++ tdm/backend/xdmauth.c | 267 ++ tdm/backend/xdmcp.c | 1165 ++++++++ tdm/config.def | 2662 ++++++++++++++++++ tdm/configure.in.bot | 8 + tdm/configure.in.in | 361 +++ tdm/confproc.pl | 838 ++++++ tdm/kfrontend/CMakeLists.txt | 101 + tdm/kfrontend/Makefile.am | 67 + tdm/kfrontend/gentdmconf.c | 2849 ++++++++++++++++++++ tdm/kfrontend/kchooser.cpp | 227 ++ tdm/kfrontend/kchooser.h | 59 + tdm/kfrontend/kconsole.cpp | 183 ++ tdm/kfrontend/kconsole.h | 53 + tdm/kfrontend/kfdialog.cpp | 182 ++ tdm/kfrontend/kfdialog.h | 65 + tdm/kfrontend/kgapp.cpp | 469 ++++ tdm/kfrontend/kgapp.h | 50 + tdm/kfrontend/kgdialog.cpp | 240 ++ tdm/kfrontend/kgdialog.h | 87 + tdm/kfrontend/kgreeter.cpp | 1280 +++++++++ tdm/kfrontend/kgreeter.h | 180 ++ tdm/kfrontend/kgverify.cpp | 1218 +++++++++ tdm/kfrontend/kgverify.h | 249 ++ tdm/kfrontend/krootimage.cpp | 140 + tdm/kfrontend/krootimage.h | 48 + tdm/kfrontend/pics/CMakeLists.txt | 18 + tdm/kfrontend/pics/Makefile.am | 9 + tdm/kfrontend/pics/default1.png | Bin 0 -> 2622 bytes tdm/kfrontend/pics/default2.png | Bin 0 -> 5663 bytes tdm/kfrontend/pics/default3.png | Bin 0 -> 4260 bytes tdm/kfrontend/pics/kdelogo-crystal.png | Bin 0 -> 11375 bytes tdm/kfrontend/pics/kdelogo.png | Bin 0 -> 13450 bytes tdm/kfrontend/pics/root1.png | Bin 0 -> 3070 bytes tdm/kfrontend/pics/shutdown.jpg | Bin 0 -> 2536 bytes tdm/kfrontend/sakdlg.cc | 247 ++ tdm/kfrontend/sakdlg.h | 64 + tdm/kfrontend/sessions/9wm.desktop | 76 + tdm/kfrontend/sessions/CMakeLists.txt | 29 + tdm/kfrontend/sessions/Makefile.am | 49 + tdm/kfrontend/sessions/admin.desktop | 7 + tdm/kfrontend/sessions/aewm++.desktop | 74 + tdm/kfrontend/sessions/aewm.desktop | 76 + tdm/kfrontend/sessions/afterstep.desktop | 83 + tdm/kfrontend/sessions/amaterus.desktop | 75 + tdm/kfrontend/sessions/amiwm.desktop | 78 + tdm/kfrontend/sessions/asclassic.desktop | 81 + tdm/kfrontend/sessions/blackbox.desktop | 88 + tdm/kfrontend/sessions/cde.desktop | 74 + tdm/kfrontend/sessions/ctwm.desktop | 72 + tdm/kfrontend/sessions/cwwm.desktop | 74 + tdm/kfrontend/sessions/enlightenment.desktop | 86 + tdm/kfrontend/sessions/evilwm.desktop | 77 + tdm/kfrontend/sessions/fluxbox.desktop | 81 + tdm/kfrontend/sessions/flwm.desktop | 77 + tdm/kfrontend/sessions/fvwm.desktop | 71 + tdm/kfrontend/sessions/fvwm2.desktop | 70 + tdm/kfrontend/sessions/fvwm95.desktop | 76 + tdm/kfrontend/sessions/gnome.desktop | 81 + tdm/kfrontend/sessions/golem.desktop | 81 + tdm/kfrontend/sessions/icewm.desktop | 81 + tdm/kfrontend/sessions/ion.desktop | 77 + tdm/kfrontend/sessions/larswm.desktop | 72 + tdm/kfrontend/sessions/lwm.desktop | 76 + tdm/kfrontend/sessions/matchbox.desktop | 82 + tdm/kfrontend/sessions/metacity.desktop | 83 + tdm/kfrontend/sessions/mwm.desktop | 78 + tdm/kfrontend/sessions/olvwm.desktop | 71 + tdm/kfrontend/sessions/olwm.desktop | 76 + tdm/kfrontend/sessions/openbox.desktop | 84 + tdm/kfrontend/sessions/oroborus.desktop | 76 + tdm/kfrontend/sessions/phluid.desktop | 80 + tdm/kfrontend/sessions/pwm.desktop | 72 + tdm/kfrontend/sessions/qvwm.desktop | 80 + tdm/kfrontend/sessions/ratpoison.desktop | 82 + tdm/kfrontend/sessions/sapphire.desktop | 84 + tdm/kfrontend/sessions/sawfish.desktop | 74 + tdm/kfrontend/sessions/tde.desktop.cmake | 45 + tdm/kfrontend/sessions/tde.desktop.in | 45 + tdm/kfrontend/sessions/twm.desktop | 71 + tdm/kfrontend/sessions/ude.desktop | 75 + tdm/kfrontend/sessions/vtwm.desktop | 72 + tdm/kfrontend/sessions/w9wm.desktop | 74 + tdm/kfrontend/sessions/waimea.desktop | 77 + tdm/kfrontend/sessions/wm2.desktop | 77 + tdm/kfrontend/sessions/wmaker.desktop | 82 + tdm/kfrontend/sessions/xfce.desktop | 73 + tdm/kfrontend/sessions/xfce4.desktop | 72 + tdm/kfrontend/tdm_config.c | 1477 ++++++++++ tdm/kfrontend/tdm_greet.c | 787 ++++++ tdm/kfrontend/tdm_greet.h | 91 + tdm/kfrontend/tdmadmindialog.cpp | 176 ++ tdm/kfrontend/tdmadmindialog.h | 70 + tdm/kfrontend/tdmclock.cpp | 176 ++ tdm/kfrontend/tdmclock.h | 52 + tdm/kfrontend/tdmconfig.cpp | 179 ++ tdm/kfrontend/tdmconfig.h | 69 + tdm/kfrontend/tdmctl.c | 234 ++ tdm/kfrontend/tdmshutdown.cpp | 925 +++++++ tdm/kfrontend/tdmshutdown.h | 240 ++ tdm/kfrontend/themer/CMakeLists.txt | 41 + tdm/kfrontend/themer/Makefile.am | 16 + tdm/kfrontend/themer/tdmitem.cpp | 657 +++++ tdm/kfrontend/themer/tdmitem.h | 272 ++ tdm/kfrontend/themer/tdmlabel.cpp | 276 ++ tdm/kfrontend/themer/tdmlabel.h | 87 + tdm/kfrontend/themer/tdmlayout.cpp | 168 ++ tdm/kfrontend/themer/tdmlayout.h | 98 + tdm/kfrontend/themer/tdmpixmap.cpp | 340 +++ tdm/kfrontend/themer/tdmpixmap.h | 73 + tdm/kfrontend/themer/tdmrect.cpp | 181 ++ tdm/kfrontend/themer/tdmrect.h | 67 + tdm/kfrontend/themer/tdmthemer.cpp | 404 +++ tdm/kfrontend/themer/tdmthemer.h | 128 + tdm/kfrontend/themes/CMakeLists.txt | 13 + tdm/kfrontend/themes/Makefile.am | 1 + tdm/kfrontend/themes/circles/CMakeLists.txt | 15 + .../themes/circles/GdmGreeterTheme.desktop | 135 + tdm/kfrontend/themes/circles/Makefile.am | 11 + tdm/kfrontend/themes/circles/background.svg | 39 + tdm/kfrontend/themes/circles/circles.xml | 207 ++ tdm/kfrontend/themes/circles/flower.png | Bin 0 -> 120376 bytes tdm/kfrontend/themes/circles/help.png | Bin 0 -> 2138 bytes tdm/kfrontend/themes/circles/options.png | Bin 0 -> 2297 bytes tdm/kfrontend/themes/circles/screenshot.png | Bin 0 -> 16847 bytes tdm/kfrontend/themes/o2_enterprise/CMakeLists.txt | 16 + tdm/kfrontend/themes/o2_enterprise/Dialog.png | Bin 0 -> 4167 bytes .../themes/o2_enterprise/GdmGreeterTheme.desktop | 10 + tdm/kfrontend/themes/o2_enterprise/Makefile.am | 14 + .../themes/o2_enterprise/enter_normal.png | Bin 0 -> 1639 bytes tdm/kfrontend/themes/o2_enterprise/enter_over.png | Bin 0 -> 2422 bytes .../themes/o2_enterprise/enter_pressed.png | Bin 0 -> 1639 bytes tdm/kfrontend/themes/o2_enterprise/enterprise.xml | 99 + tdm/kfrontend/themes/o2_enterprise/gpl.txt | 340 +++ tdm/kfrontend/themes/o2_enterprise/preview.png | Bin 0 -> 381843 bytes .../themes/o2_enterprise/system_normal.png | Bin 0 -> 1623 bytes tdm/kfrontend/themes/o2_enterprise/system_over.png | Bin 0 -> 2491 bytes .../themes/o2_enterprise/system_pressed.png | Bin 0 -> 1623 bytes tdmlib/CMakeLists.txt | 85 + tdmlib/Makefile.am | 30 + tdmlib/dmctl.cpp | 442 +++ tdmlib/dmctl.h | 93 + tdmlib/kgreet_classic.cpp | 513 ++++ tdmlib/kgreet_classic.h | 88 + tdmlib/kgreet_pam.cpp | 675 +++++ tdmlib/kgreet_pam.h | 94 + tdmlib/kgreet_winbind.cpp | 679 +++++ tdmlib/kgreet_winbind.h | 101 + tdmlib/kgreeterplugin.h | 407 +++ tdmlib/tdmtsak.cpp | 180 ++ tdmlib/tdmtsak.h | 144 + 456 files changed, 54603 insertions(+), 54603 deletions(-) delete mode 100644 doc/kcontrol/kdm/CMakeLists.txt delete mode 100644 doc/kcontrol/kdm/Makefile.am delete mode 100644 doc/kcontrol/kdm/index.docbook create mode 100644 doc/kcontrol/tdm/CMakeLists.txt create mode 100644 doc/kcontrol/tdm/Makefile.am create mode 100644 doc/kcontrol/tdm/index.docbook delete mode 100644 doc/kdm/CMakeLists.txt delete mode 100644 doc/kdm/Makefile.am delete mode 100644 doc/kdm/index.docbook delete mode 100644 doc/kdm/kdmrc-ref.docbook create mode 100644 doc/tdm/CMakeLists.txt create mode 100644 doc/tdm/Makefile.am create mode 100644 doc/tdm/index.docbook create mode 100644 doc/tdm/tdmrc-ref.docbook delete mode 100644 kcontrol/kdm/AUTHORS delete mode 100644 kcontrol/kdm/CMakeLists.txt delete mode 100644 kcontrol/kdm/ChangeLog delete mode 100644 kcontrol/kdm/Makefile.am delete mode 100644 kcontrol/kdm/background.cpp delete mode 100644 kcontrol/kdm/background.h delete mode 100644 kcontrol/kdm/kbackedcombobox.cpp delete mode 100644 kcontrol/kdm/kbackedcombobox.h delete mode 100644 kcontrol/kdm/kdm-appear.cpp delete mode 100644 kcontrol/kdm/kdm-appear.h delete mode 100644 kcontrol/kdm/kdm-conv.cpp delete mode 100644 kcontrol/kdm/kdm-conv.h delete mode 100644 kcontrol/kdm/kdm-font.cpp delete mode 100644 kcontrol/kdm/kdm-font.h delete mode 100644 kcontrol/kdm/kdm-shut.cpp delete mode 100644 kcontrol/kdm/kdm-shut.h delete mode 100644 kcontrol/kdm/kdm-users.cpp delete mode 100644 kcontrol/kdm/kdm-users.h delete mode 100644 kcontrol/kdm/kdm.desktop delete mode 100644 kcontrol/kdm/main.cpp delete mode 100644 kcontrol/kdm/main.h delete mode 100644 kcontrol/pics/cr128-app-kdmconfig.png create mode 100644 kcontrol/pics/cr128-app-tdmconfig.png delete mode 100644 kcontrol/pics/cr16-app-kdmconfig.png create mode 100644 kcontrol/pics/cr16-app-tdmconfig.png delete mode 100644 kcontrol/pics/cr22-app-kdmconfig.png create mode 100644 kcontrol/pics/cr22-app-tdmconfig.png delete mode 100644 kcontrol/pics/cr32-app-kdmconfig.png create mode 100644 kcontrol/pics/cr32-app-tdmconfig.png delete mode 100644 kcontrol/pics/cr48-app-kdmconfig.png create mode 100644 kcontrol/pics/cr48-app-tdmconfig.png delete mode 100644 kcontrol/pics/cr64-app-kdmconfig.png create mode 100644 kcontrol/pics/cr64-app-tdmconfig.png create mode 100644 kcontrol/tdm/AUTHORS create mode 100644 kcontrol/tdm/CMakeLists.txt create mode 100644 kcontrol/tdm/ChangeLog create mode 100644 kcontrol/tdm/Makefile.am create mode 100644 kcontrol/tdm/background.cpp create mode 100644 kcontrol/tdm/background.h create mode 100644 kcontrol/tdm/kbackedcombobox.cpp create mode 100644 kcontrol/tdm/kbackedcombobox.h create mode 100644 kcontrol/tdm/main.cpp create mode 100644 kcontrol/tdm/main.h create mode 100644 kcontrol/tdm/tdm-appear.cpp create mode 100644 kcontrol/tdm/tdm-appear.h create mode 100644 kcontrol/tdm/tdm-conv.cpp create mode 100644 kcontrol/tdm/tdm-conv.h create mode 100644 kcontrol/tdm/tdm-font.cpp create mode 100644 kcontrol/tdm/tdm-font.h create mode 100644 kcontrol/tdm/tdm-shut.cpp create mode 100644 kcontrol/tdm/tdm-shut.h create mode 100644 kcontrol/tdm/tdm-users.cpp create mode 100644 kcontrol/tdm/tdm-users.h create mode 100644 kcontrol/tdm/tdm.desktop delete mode 100644 kdm/CMakeLists.txt delete mode 100644 kdm/ChangeLog delete mode 100644 kdm/ConfigureChecks.cmake delete mode 100644 kdm/Makefile.am delete mode 100644 kdm/README delete mode 100644 kdm/TODO delete mode 100644 kdm/backend/CMakeLists.txt delete mode 100644 kdm/backend/Imakefile delete mode 100644 kdm/backend/Makefile.am delete mode 100644 kdm/backend/access.c delete mode 100644 kdm/backend/auth.c delete mode 100644 kdm/backend/bootman.c delete mode 100644 kdm/backend/choose.c delete mode 100644 kdm/backend/client.c delete mode 100644 kdm/backend/consolekit.c delete mode 100644 kdm/backend/consolekit.h delete mode 100644 kdm/backend/ctrl.c delete mode 100644 kdm/backend/daemon.c delete mode 100644 kdm/backend/dm.c delete mode 100644 kdm/backend/dm.h delete mode 100644 kdm/backend/dm_auth.h delete mode 100644 kdm/backend/dm_error.h delete mode 100644 kdm/backend/dm_socket.h delete mode 100644 kdm/backend/dpylist.c delete mode 100644 kdm/backend/error.c delete mode 100644 kdm/backend/genauth.c delete mode 100644 kdm/backend/greet.h delete mode 100644 kdm/backend/inifile.c delete mode 100644 kdm/backend/krb5auth.c delete mode 100644 kdm/backend/mitauth.c delete mode 100644 kdm/backend/netaddr.c delete mode 100644 kdm/backend/policy.c delete mode 100644 kdm/backend/printf.c delete mode 100644 kdm/backend/process.c delete mode 100644 kdm/backend/protodpy.c delete mode 100644 kdm/backend/reset.c delete mode 100644 kdm/backend/resource.c delete mode 100644 kdm/backend/rpcauth.c delete mode 100644 kdm/backend/server.c delete mode 100644 kdm/backend/session.c delete mode 100644 kdm/backend/sessreg.c delete mode 100644 kdm/backend/socket.c delete mode 100644 kdm/backend/streams.c delete mode 100644 kdm/backend/util.c delete mode 100644 kdm/backend/xdmauth.c delete mode 100644 kdm/backend/xdmcp.c delete mode 100644 kdm/config.def delete mode 100644 kdm/configure.in.bot delete mode 100644 kdm/configure.in.in delete mode 100755 kdm/confproc.pl delete mode 100644 kdm/kfrontend/CMakeLists.txt delete mode 100644 kdm/kfrontend/Makefile.am delete mode 100644 kdm/kfrontend/genkdmconf.c delete mode 100644 kdm/kfrontend/kchooser.cpp delete mode 100644 kdm/kfrontend/kchooser.h delete mode 100644 kdm/kfrontend/kconsole.cpp delete mode 100644 kdm/kfrontend/kconsole.h delete mode 100644 kdm/kfrontend/kdm_config.c delete mode 100644 kdm/kfrontend/kdm_greet.c delete mode 100644 kdm/kfrontend/kdm_greet.h delete mode 100644 kdm/kfrontend/kdmadmindialog.cpp delete mode 100644 kdm/kfrontend/kdmadmindialog.h delete mode 100644 kdm/kfrontend/kdmclock.cpp delete mode 100644 kdm/kfrontend/kdmclock.h delete mode 100644 kdm/kfrontend/kdmconfig.cpp delete mode 100644 kdm/kfrontend/kdmconfig.h delete mode 100644 kdm/kfrontend/kdmctl.c delete mode 100644 kdm/kfrontend/kdmshutdown.cpp delete mode 100644 kdm/kfrontend/kdmshutdown.h delete mode 100644 kdm/kfrontend/kfdialog.cpp delete mode 100644 kdm/kfrontend/kfdialog.h delete mode 100644 kdm/kfrontend/kgapp.cpp delete mode 100644 kdm/kfrontend/kgapp.h delete mode 100644 kdm/kfrontend/kgdialog.cpp delete mode 100644 kdm/kfrontend/kgdialog.h delete mode 100644 kdm/kfrontend/kgreeter.cpp delete mode 100644 kdm/kfrontend/kgreeter.h delete mode 100644 kdm/kfrontend/kgverify.cpp delete mode 100644 kdm/kfrontend/kgverify.h delete mode 100644 kdm/kfrontend/krootimage.cpp delete mode 100644 kdm/kfrontend/krootimage.h delete mode 100644 kdm/kfrontend/pics/CMakeLists.txt delete mode 100644 kdm/kfrontend/pics/Makefile.am delete mode 100644 kdm/kfrontend/pics/default1.png delete mode 100644 kdm/kfrontend/pics/default2.png delete mode 100644 kdm/kfrontend/pics/default3.png delete mode 100644 kdm/kfrontend/pics/kdelogo-crystal.png delete mode 100644 kdm/kfrontend/pics/kdelogo.png delete mode 100644 kdm/kfrontend/pics/root1.png delete mode 100644 kdm/kfrontend/pics/shutdown.jpg delete mode 100644 kdm/kfrontend/sakdlg.cc delete mode 100644 kdm/kfrontend/sakdlg.h delete mode 100644 kdm/kfrontend/sessions/9wm.desktop delete mode 100644 kdm/kfrontend/sessions/CMakeLists.txt delete mode 100644 kdm/kfrontend/sessions/Makefile.am delete mode 100644 kdm/kfrontend/sessions/admin.desktop delete mode 100644 kdm/kfrontend/sessions/aewm++.desktop delete mode 100644 kdm/kfrontend/sessions/aewm.desktop delete mode 100644 kdm/kfrontend/sessions/afterstep.desktop delete mode 100644 kdm/kfrontend/sessions/amaterus.desktop delete mode 100644 kdm/kfrontend/sessions/amiwm.desktop delete mode 100644 kdm/kfrontend/sessions/asclassic.desktop delete mode 100644 kdm/kfrontend/sessions/blackbox.desktop delete mode 100644 kdm/kfrontend/sessions/cde.desktop delete mode 100644 kdm/kfrontend/sessions/ctwm.desktop delete mode 100644 kdm/kfrontend/sessions/cwwm.desktop delete mode 100644 kdm/kfrontend/sessions/enlightenment.desktop delete mode 100644 kdm/kfrontend/sessions/evilwm.desktop delete mode 100644 kdm/kfrontend/sessions/fluxbox.desktop delete mode 100644 kdm/kfrontend/sessions/flwm.desktop delete mode 100644 kdm/kfrontend/sessions/fvwm.desktop delete mode 100644 kdm/kfrontend/sessions/fvwm2.desktop delete mode 100644 kdm/kfrontend/sessions/fvwm95.desktop delete mode 100644 kdm/kfrontend/sessions/gnome.desktop delete mode 100644 kdm/kfrontend/sessions/golem.desktop delete mode 100644 kdm/kfrontend/sessions/icewm.desktop delete mode 100644 kdm/kfrontend/sessions/ion.desktop delete mode 100644 kdm/kfrontend/sessions/larswm.desktop delete mode 100644 kdm/kfrontend/sessions/lwm.desktop delete mode 100644 kdm/kfrontend/sessions/matchbox.desktop delete mode 100644 kdm/kfrontend/sessions/metacity.desktop delete mode 100644 kdm/kfrontend/sessions/mwm.desktop delete mode 100644 kdm/kfrontend/sessions/olvwm.desktop delete mode 100644 kdm/kfrontend/sessions/olwm.desktop delete mode 100644 kdm/kfrontend/sessions/openbox.desktop delete mode 100644 kdm/kfrontend/sessions/oroborus.desktop delete mode 100644 kdm/kfrontend/sessions/phluid.desktop delete mode 100644 kdm/kfrontend/sessions/pwm.desktop delete mode 100644 kdm/kfrontend/sessions/qvwm.desktop delete mode 100644 kdm/kfrontend/sessions/ratpoison.desktop delete mode 100644 kdm/kfrontend/sessions/sapphire.desktop delete mode 100644 kdm/kfrontend/sessions/sawfish.desktop delete mode 100644 kdm/kfrontend/sessions/tde.desktop.cmake delete mode 100644 kdm/kfrontend/sessions/tde.desktop.in delete mode 100644 kdm/kfrontend/sessions/twm.desktop delete mode 100644 kdm/kfrontend/sessions/ude.desktop delete mode 100644 kdm/kfrontend/sessions/vtwm.desktop delete mode 100644 kdm/kfrontend/sessions/w9wm.desktop delete mode 100644 kdm/kfrontend/sessions/waimea.desktop delete mode 100644 kdm/kfrontend/sessions/wm2.desktop delete mode 100644 kdm/kfrontend/sessions/wmaker.desktop delete mode 100644 kdm/kfrontend/sessions/xfce.desktop delete mode 100644 kdm/kfrontend/sessions/xfce4.desktop delete mode 100644 kdm/kfrontend/themer/CMakeLists.txt delete mode 100644 kdm/kfrontend/themer/Makefile.am delete mode 100644 kdm/kfrontend/themer/kdmitem.cpp delete mode 100644 kdm/kfrontend/themer/kdmitem.h delete mode 100644 kdm/kfrontend/themer/kdmlabel.cpp delete mode 100644 kdm/kfrontend/themer/kdmlabel.h delete mode 100644 kdm/kfrontend/themer/kdmlayout.cpp delete mode 100644 kdm/kfrontend/themer/kdmlayout.h delete mode 100644 kdm/kfrontend/themer/kdmpixmap.cpp delete mode 100644 kdm/kfrontend/themer/kdmpixmap.h delete mode 100644 kdm/kfrontend/themer/kdmrect.cpp delete mode 100644 kdm/kfrontend/themer/kdmrect.h delete mode 100644 kdm/kfrontend/themer/kdmthemer.cpp delete mode 100644 kdm/kfrontend/themer/kdmthemer.h delete mode 100644 kdm/kfrontend/themes/CMakeLists.txt delete mode 100644 kdm/kfrontend/themes/Makefile.am delete mode 100644 kdm/kfrontend/themes/circles/CMakeLists.txt delete mode 100644 kdm/kfrontend/themes/circles/GdmGreeterTheme.desktop delete mode 100644 kdm/kfrontend/themes/circles/Makefile.am delete mode 100644 kdm/kfrontend/themes/circles/background.svg delete mode 100644 kdm/kfrontend/themes/circles/circles.xml delete mode 100644 kdm/kfrontend/themes/circles/flower.png delete mode 100644 kdm/kfrontend/themes/circles/help.png delete mode 100644 kdm/kfrontend/themes/circles/options.png delete mode 100644 kdm/kfrontend/themes/circles/screenshot.png delete mode 100644 kdm/kfrontend/themes/o2_enterprise/CMakeLists.txt delete mode 100644 kdm/kfrontend/themes/o2_enterprise/Dialog.png delete mode 100644 kdm/kfrontend/themes/o2_enterprise/GdmGreeterTheme.desktop delete mode 100644 kdm/kfrontend/themes/o2_enterprise/Makefile.am delete mode 100644 kdm/kfrontend/themes/o2_enterprise/enter_normal.png delete mode 100644 kdm/kfrontend/themes/o2_enterprise/enter_over.png delete mode 100644 kdm/kfrontend/themes/o2_enterprise/enter_pressed.png delete mode 100644 kdm/kfrontend/themes/o2_enterprise/enterprise.xml delete mode 100644 kdm/kfrontend/themes/o2_enterprise/gpl.txt delete mode 100644 kdm/kfrontend/themes/o2_enterprise/preview.png delete mode 100644 kdm/kfrontend/themes/o2_enterprise/system_normal.png delete mode 100644 kdm/kfrontend/themes/o2_enterprise/system_over.png delete mode 100644 kdm/kfrontend/themes/o2_enterprise/system_pressed.png delete mode 100644 kdmlib/CMakeLists.txt delete mode 100644 kdmlib/Makefile.am delete mode 100644 kdmlib/dmctl.cpp delete mode 100644 kdmlib/dmctl.h delete mode 100644 kdmlib/kdmtsak.cpp delete mode 100644 kdmlib/kdmtsak.h delete mode 100644 kdmlib/kgreet_classic.cpp delete mode 100644 kdmlib/kgreet_classic.h delete mode 100644 kdmlib/kgreet_pam.cpp delete mode 100644 kdmlib/kgreet_pam.h delete mode 100644 kdmlib/kgreet_winbind.cpp delete mode 100644 kdmlib/kgreet_winbind.h delete mode 100644 kdmlib/kgreeterplugin.h create mode 100644 tdm/CMakeLists.txt create mode 100644 tdm/ChangeLog create mode 100644 tdm/ConfigureChecks.cmake create mode 100644 tdm/Makefile.am create mode 100644 tdm/README create mode 100644 tdm/TODO create mode 100644 tdm/backend/CMakeLists.txt create mode 100644 tdm/backend/Imakefile create mode 100644 tdm/backend/Makefile.am create mode 100644 tdm/backend/access.c create mode 100644 tdm/backend/auth.c create mode 100644 tdm/backend/bootman.c create mode 100644 tdm/backend/choose.c create mode 100644 tdm/backend/client.c create mode 100644 tdm/backend/consolekit.c create mode 100644 tdm/backend/consolekit.h create mode 100644 tdm/backend/ctrl.c create mode 100644 tdm/backend/daemon.c create mode 100644 tdm/backend/dm.c create mode 100644 tdm/backend/dm.h create mode 100644 tdm/backend/dm_auth.h create mode 100644 tdm/backend/dm_error.h create mode 100644 tdm/backend/dm_socket.h create mode 100644 tdm/backend/dpylist.c create mode 100644 tdm/backend/error.c create mode 100644 tdm/backend/genauth.c create mode 100644 tdm/backend/greet.h create mode 100644 tdm/backend/inifile.c create mode 100644 tdm/backend/krb5auth.c create mode 100644 tdm/backend/mitauth.c create mode 100644 tdm/backend/netaddr.c create mode 100644 tdm/backend/policy.c create mode 100644 tdm/backend/printf.c create mode 100644 tdm/backend/process.c create mode 100644 tdm/backend/protodpy.c create mode 100644 tdm/backend/reset.c create mode 100644 tdm/backend/resource.c create mode 100644 tdm/backend/rpcauth.c create mode 100644 tdm/backend/server.c create mode 100644 tdm/backend/session.c create mode 100644 tdm/backend/sessreg.c create mode 100644 tdm/backend/socket.c create mode 100644 tdm/backend/streams.c create mode 100644 tdm/backend/util.c create mode 100644 tdm/backend/xdmauth.c create mode 100644 tdm/backend/xdmcp.c create mode 100644 tdm/config.def create mode 100644 tdm/configure.in.bot create mode 100644 tdm/configure.in.in create mode 100755 tdm/confproc.pl create mode 100644 tdm/kfrontend/CMakeLists.txt create mode 100644 tdm/kfrontend/Makefile.am create mode 100644 tdm/kfrontend/gentdmconf.c create mode 100644 tdm/kfrontend/kchooser.cpp create mode 100644 tdm/kfrontend/kchooser.h create mode 100644 tdm/kfrontend/kconsole.cpp create mode 100644 tdm/kfrontend/kconsole.h create mode 100644 tdm/kfrontend/kfdialog.cpp create mode 100644 tdm/kfrontend/kfdialog.h create mode 100644 tdm/kfrontend/kgapp.cpp create mode 100644 tdm/kfrontend/kgapp.h create mode 100644 tdm/kfrontend/kgdialog.cpp create mode 100644 tdm/kfrontend/kgdialog.h create mode 100644 tdm/kfrontend/kgreeter.cpp create mode 100644 tdm/kfrontend/kgreeter.h create mode 100644 tdm/kfrontend/kgverify.cpp create mode 100644 tdm/kfrontend/kgverify.h create mode 100644 tdm/kfrontend/krootimage.cpp create mode 100644 tdm/kfrontend/krootimage.h create mode 100644 tdm/kfrontend/pics/CMakeLists.txt create mode 100644 tdm/kfrontend/pics/Makefile.am create mode 100644 tdm/kfrontend/pics/default1.png create mode 100644 tdm/kfrontend/pics/default2.png create mode 100644 tdm/kfrontend/pics/default3.png create mode 100644 tdm/kfrontend/pics/kdelogo-crystal.png create mode 100644 tdm/kfrontend/pics/kdelogo.png create mode 100644 tdm/kfrontend/pics/root1.png create mode 100644 tdm/kfrontend/pics/shutdown.jpg create mode 100644 tdm/kfrontend/sakdlg.cc create mode 100644 tdm/kfrontend/sakdlg.h create mode 100644 tdm/kfrontend/sessions/9wm.desktop create mode 100644 tdm/kfrontend/sessions/CMakeLists.txt create mode 100644 tdm/kfrontend/sessions/Makefile.am create mode 100644 tdm/kfrontend/sessions/admin.desktop create mode 100644 tdm/kfrontend/sessions/aewm++.desktop create mode 100644 tdm/kfrontend/sessions/aewm.desktop create mode 100644 tdm/kfrontend/sessions/afterstep.desktop create mode 100644 tdm/kfrontend/sessions/amaterus.desktop create mode 100644 tdm/kfrontend/sessions/amiwm.desktop create mode 100644 tdm/kfrontend/sessions/asclassic.desktop create mode 100644 tdm/kfrontend/sessions/blackbox.desktop create mode 100644 tdm/kfrontend/sessions/cde.desktop create mode 100644 tdm/kfrontend/sessions/ctwm.desktop create mode 100644 tdm/kfrontend/sessions/cwwm.desktop create mode 100644 tdm/kfrontend/sessions/enlightenment.desktop create mode 100644 tdm/kfrontend/sessions/evilwm.desktop create mode 100644 tdm/kfrontend/sessions/fluxbox.desktop create mode 100644 tdm/kfrontend/sessions/flwm.desktop create mode 100644 tdm/kfrontend/sessions/fvwm.desktop create mode 100644 tdm/kfrontend/sessions/fvwm2.desktop create mode 100644 tdm/kfrontend/sessions/fvwm95.desktop create mode 100644 tdm/kfrontend/sessions/gnome.desktop create mode 100644 tdm/kfrontend/sessions/golem.desktop create mode 100644 tdm/kfrontend/sessions/icewm.desktop create mode 100644 tdm/kfrontend/sessions/ion.desktop create mode 100644 tdm/kfrontend/sessions/larswm.desktop create mode 100644 tdm/kfrontend/sessions/lwm.desktop create mode 100644 tdm/kfrontend/sessions/matchbox.desktop create mode 100644 tdm/kfrontend/sessions/metacity.desktop create mode 100644 tdm/kfrontend/sessions/mwm.desktop create mode 100644 tdm/kfrontend/sessions/olvwm.desktop create mode 100644 tdm/kfrontend/sessions/olwm.desktop create mode 100644 tdm/kfrontend/sessions/openbox.desktop create mode 100644 tdm/kfrontend/sessions/oroborus.desktop create mode 100644 tdm/kfrontend/sessions/phluid.desktop create mode 100644 tdm/kfrontend/sessions/pwm.desktop create mode 100644 tdm/kfrontend/sessions/qvwm.desktop create mode 100644 tdm/kfrontend/sessions/ratpoison.desktop create mode 100644 tdm/kfrontend/sessions/sapphire.desktop create mode 100644 tdm/kfrontend/sessions/sawfish.desktop create mode 100644 tdm/kfrontend/sessions/tde.desktop.cmake create mode 100644 tdm/kfrontend/sessions/tde.desktop.in create mode 100644 tdm/kfrontend/sessions/twm.desktop create mode 100644 tdm/kfrontend/sessions/ude.desktop create mode 100644 tdm/kfrontend/sessions/vtwm.desktop create mode 100644 tdm/kfrontend/sessions/w9wm.desktop create mode 100644 tdm/kfrontend/sessions/waimea.desktop create mode 100644 tdm/kfrontend/sessions/wm2.desktop create mode 100644 tdm/kfrontend/sessions/wmaker.desktop create mode 100644 tdm/kfrontend/sessions/xfce.desktop create mode 100644 tdm/kfrontend/sessions/xfce4.desktop create mode 100644 tdm/kfrontend/tdm_config.c create mode 100644 tdm/kfrontend/tdm_greet.c create mode 100644 tdm/kfrontend/tdm_greet.h create mode 100644 tdm/kfrontend/tdmadmindialog.cpp create mode 100644 tdm/kfrontend/tdmadmindialog.h create mode 100644 tdm/kfrontend/tdmclock.cpp create mode 100644 tdm/kfrontend/tdmclock.h create mode 100644 tdm/kfrontend/tdmconfig.cpp create mode 100644 tdm/kfrontend/tdmconfig.h create mode 100644 tdm/kfrontend/tdmctl.c create mode 100644 tdm/kfrontend/tdmshutdown.cpp create mode 100644 tdm/kfrontend/tdmshutdown.h create mode 100644 tdm/kfrontend/themer/CMakeLists.txt create mode 100644 tdm/kfrontend/themer/Makefile.am create mode 100644 tdm/kfrontend/themer/tdmitem.cpp create mode 100644 tdm/kfrontend/themer/tdmitem.h create mode 100644 tdm/kfrontend/themer/tdmlabel.cpp create mode 100644 tdm/kfrontend/themer/tdmlabel.h create mode 100644 tdm/kfrontend/themer/tdmlayout.cpp create mode 100644 tdm/kfrontend/themer/tdmlayout.h create mode 100644 tdm/kfrontend/themer/tdmpixmap.cpp create mode 100644 tdm/kfrontend/themer/tdmpixmap.h create mode 100644 tdm/kfrontend/themer/tdmrect.cpp create mode 100644 tdm/kfrontend/themer/tdmrect.h create mode 100644 tdm/kfrontend/themer/tdmthemer.cpp create mode 100644 tdm/kfrontend/themer/tdmthemer.h create mode 100644 tdm/kfrontend/themes/CMakeLists.txt create mode 100644 tdm/kfrontend/themes/Makefile.am create mode 100644 tdm/kfrontend/themes/circles/CMakeLists.txt create mode 100644 tdm/kfrontend/themes/circles/GdmGreeterTheme.desktop create mode 100644 tdm/kfrontend/themes/circles/Makefile.am create mode 100644 tdm/kfrontend/themes/circles/background.svg create mode 100644 tdm/kfrontend/themes/circles/circles.xml create mode 100644 tdm/kfrontend/themes/circles/flower.png create mode 100644 tdm/kfrontend/themes/circles/help.png create mode 100644 tdm/kfrontend/themes/circles/options.png create mode 100644 tdm/kfrontend/themes/circles/screenshot.png create mode 100644 tdm/kfrontend/themes/o2_enterprise/CMakeLists.txt create mode 100644 tdm/kfrontend/themes/o2_enterprise/Dialog.png create mode 100644 tdm/kfrontend/themes/o2_enterprise/GdmGreeterTheme.desktop create mode 100644 tdm/kfrontend/themes/o2_enterprise/Makefile.am create mode 100644 tdm/kfrontend/themes/o2_enterprise/enter_normal.png create mode 100644 tdm/kfrontend/themes/o2_enterprise/enter_over.png create mode 100644 tdm/kfrontend/themes/o2_enterprise/enter_pressed.png create mode 100644 tdm/kfrontend/themes/o2_enterprise/enterprise.xml create mode 100644 tdm/kfrontend/themes/o2_enterprise/gpl.txt create mode 100644 tdm/kfrontend/themes/o2_enterprise/preview.png create mode 100644 tdm/kfrontend/themes/o2_enterprise/system_normal.png create mode 100644 tdm/kfrontend/themes/o2_enterprise/system_over.png create mode 100644 tdm/kfrontend/themes/o2_enterprise/system_pressed.png create mode 100644 tdmlib/CMakeLists.txt create mode 100644 tdmlib/Makefile.am create mode 100644 tdmlib/dmctl.cpp create mode 100644 tdmlib/dmctl.h create mode 100644 tdmlib/kgreet_classic.cpp create mode 100644 tdmlib/kgreet_classic.h create mode 100644 tdmlib/kgreet_pam.cpp create mode 100644 tdmlib/kgreet_pam.h create mode 100644 tdmlib/kgreet_winbind.cpp create mode 100644 tdmlib/kgreet_winbind.h create mode 100644 tdmlib/kgreeterplugin.h create mode 100644 tdmlib/tdmtsak.cpp create mode 100644 tdmlib/tdmtsak.h diff --git a/doc/kcontrol/kdm/CMakeLists.txt b/doc/kcontrol/kdm/CMakeLists.txt deleted file mode 100644 index 4bdd0a66d..000000000 --- a/doc/kcontrol/kdm/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -tde_create_handbook( DESTINATION kcontrol/tdm ) diff --git a/doc/kcontrol/kdm/Makefile.am b/doc/kcontrol/kdm/Makefile.am deleted file mode 100644 index c81f42bd9..000000000 --- a/doc/kcontrol/kdm/Makefile.am +++ /dev/null @@ -1,2 +0,0 @@ -KDE_LANG = en -KDE_DOCS = kcontrol/tdm diff --git a/doc/kcontrol/kdm/index.docbook b/doc/kcontrol/kdm/index.docbook deleted file mode 100644 index ef1d0b7d4..000000000 --- a/doc/kcontrol/kdm/index.docbook +++ /dev/null @@ -1,518 +0,0 @@ - - - -]> - -
- - - -&Thomas.Tanghus; &Thomas.Tanghus.mail; -&Steffen.Hansen; &Steffen.Hansen.mail; -&Mike.McBride; &Mike.McBride.mail; - - - -2002-02-13 -3.00.00 - - -KDE -KControl -TDM configuration -login manager -login - - - - -Login Manager - -Using this module, you can configure the &kde; graphical login -manager, &tdm;. You can change how the login screen looks, who has -access using the login manager and who can shutdown the -computer. - -In order to organize all of these options, this module is -divided into six sections: Appearance, -Font, Background, -Sessions, -Users and -Convenience. - -You can switch between the sections using the tabs at the top of -the window. - -If you are not currently logged in as a superuser, you -will need to click the Administrator Mode -Button. You will then be asked for a superuser password. Entering a -correct password will allow you to modify the settings of this -module. - - -Appearance - -From this page you can change the visual appearance of &tdm;, -&kde;'s graphical login manager. - -The greeting string is the title of the login screen. If the -string contains the word HOSTNAME it -will be translated to the domainless name of the machine &tdm; is -installed on. - -You can then choose to show either the current system time, a logo -or nothing special in the login box. Make your choice in the radio -buttons labeled Logo area. Using the -Positions setting, you can choose to either center -the content of the logo area or to position it using fixed -coordinates. - -If you chose Show logo you can now choose a -logo: - - - -Drop an image file on the image button. - - -Click on the image button and select a new image from the image chooser -dialog. - - - -If you do not specify a logo the default -$TDEDIR/share/apps/tdm/pics/kdelogo.png -will be displayed. - -While &kde;'s style depends on the settings of the user logged in, -the style used by &tdm; can be configured using the GUI -Style option. - -Below that, you have two dropdown boxes to choose the language and the -country for your login box. - - - - -Font - -From this section of the module you can change the fonts used in -the login window. - -You can select three different font styles from the drop down box -(Greeting, Fail, -Standard). When you click on the Change -font button a dialog appears from which you can select the -new characteristics for the font style. - - - -The Greeting font is the font used for the title -(Greeting String). - - -The Fail font is used when a login fails. - - -The Standard font is used in all other places in the -login window. - - - -An example of each font can be seen in the -Example Box. - - - - -Background - -Here you can change the desktop background which will be displayed -when a user logs in. You can have a single color or an image as a -background. If you have an image as the background and select center, the -selected background color will be used around the image if it isn't -large enough to cover the entire desktop. - -The background colors and effects are controlled by the options on -the tab labeled Background and you select a -background image and its placement from the options on the tab labeled -Wallpaper. - -To change the default background color(s) simply click either of -the color buttons and select a new color. - -The dropdown box above the color buttons provides you with several -different blend effects. Choose one from the list, and it will be -previewed on the small monitor at the top of the window. Your choices -are: - - - -Flat -By choosing this mode, you select one color (using the color -button labeled Color 1), and the entire background is -covered with this one color. - - -Pattern -By choosing this mode, you select two colors (using both color -buttons). You then select a pattern by clicking -Setup. This opens a new dialog window, which gives you -the opportunity to select a pattern. Simply click once on the pattern of your -choice, then click on OK, and &kde; will render the pattern -you selected using the two colors you selected. For more on patterns, see the -section Background: Adding, Removing and Modifying -Patterns. - - -Background Program -By selecting this option, you can have &kde; use an external -program to determine the background. This can be any program of your choosing. -For more information on this option, see the section entitled Background: Using an external program. - - -Horizontal Gradient -By choosing this mode, you select two colors (using both color -buttons). &kde; will then start with the color selected by Color -1 on the left edge of the screen, and slowly transform into the -color selected by Color 2 by the time it gets to the -right edge of the screen. - - -Vertical Gradient -By choosing this mode, you select two colors (using both color -buttons). &kde; will then start with the color selected by Color -1 on the top edge of the screen, and slowly transform into the color -selected by Color 2 as it moves to the bottom of the -screen. - - -Pyramid Gradient -By choosing this mode, you select two colors (using both color -buttons). &kde; will then start with the color selected by Color -1 in each corner of the screen, and slowly transform into the color -selected by Color 2 as it moves to the center of the -screen. - - -Pipecross Gradient -By choosing this mode, you select two colors (using both color -buttons). &kde; will then start with the color selected by Color -1 in each corner of the screen, and slowly transform into the color -selected by Color 2 as it moves to the center of the -screen. The shape of this gradient is different then the pyramid -gradient. - - -Elliptic Gradient -By choosing this mode, you select two colors (using both color -buttons). &kde; will then start with the color selected by Color -2 in the center of the screen, and slowly transform into the color -selected by Color 1 as it moves to the edges, in an -elliptical pattern. - - - -The setup button is only needed for if you select Background -program or Patterns. In these instances, -another window will appear to configure the specifics. -Wallpaper -To select a new background image first, click on the -Wallpapers tab, then you can either select an image from the -drop-down list labeled Wallpaper or select -Browse... and select an image file from a file -selector. - -The image can be displayed in six different ways: - - -No wallpaper -No image is displayed. Just the background colors. - - -Centered -The image will be centered on the screen. The background colors -will be present anywhere the image does not cover. - - -Tiled -The image will be duplicated until it fills the entire -desktop. The first image will be placed in the upper left corner of the screen, -and duplicated downward and to the right. - - -Center Tiled -The image will be duplicated until it fills the entire -desktop. The first image will be placed in the center of the screen, and -duplicated upward, downward to the right, and to the left. - - -Centered Maxpect -The image will be placed in the center of the screen. It will -be scaled to fit the desktop, but it will not change the aspect ratio of the -original image. This will provide you with an image that is not distorted. - - - -Scaled -The image will be scaled to fit the desktop. It will be -stretched to fit all four corners. - - - - - - -Sessions - -Allow to shutdown -Use this dropdown box to choose who is allowed to shut down: - - -None: No one can shutdown the computer using &tdm;. -You must be logged in, and execute a command. - - -All: Everyone can shutdown the computer using -&tdm;. - -Root only: &tdm; requires that the -root password be entered before shutting down the -computer. -Console only: The user must be at this -console, to shut down the computer. - - -Commands -Use these 3 blanks to define the exact shutdown command. -The shutdown command defaults to: - -/sbin/shutdown - -The restart command defaults to: - -/sbin/reboot - -The Console mode (which restarts the computer as a console only terminal) -defaults to: - -/sbin/init - -When Show boot options is enabled, &tdm; will on reboot -offer you options for the lilo boot manager. For this feature to work, you will -need to supply the correct paths to your lilo command and to -lilo's map file. - - - -Session types - -Define which session types should be accessible from the login -window. - - For more information on this subject, look at /etc/X11/xdm/Xsession to find your -xdm setup files. Also review the xdm man pages, especially under the SESSION -PROGRAM section. - -To add a session, type its name in the -blank entitled New types, and click -Add new. - -To remove a session, select the session from the list and click -Remove. - - - - - - - -Users - -From here you can change the way users are represented in the -login window. - -As you look on this window, you will see three lists (All users, -selected users, and no-show users). You also see an image box, and a -set of options along the right side of the window. - -The first thing you must decide, is if you are going to show users -or not. - - -If you choose to show users, then the login window will show -images (which you select), of a list of users. When someone is ready to -login, they select their user name/image, enter their password, and they -are granted access. - -If you choose not to show users, then the login window will be -more traditional. Users will need to type their username, and password -to gain entrance. This is the preferred way if you have many users on -this terminal. - - -To show (and sort) or not to show users - -Along the right edge of the window are two check boxes: - -If Show users is selected, you have chosen to -show images of users, instead of making them type their login -name. - -If Sort users is selected, then the list of -users will be sorted alphabetically in the login window. If unchecked, -users will be listed in the same order as they are on this page. If -Show users is not checked, this has no -effect. - - - - -How to determine which users to show and which users to hide - -Below the user image box, and above the Show -users check box, is a set of two radio buttions: - - -Show only selected users: If this option is selected, only the -users contained in the list labelled Selected Users, will -be displayed in the login window. If Show users is not -checked, this has no effect. -Show all users but no-show users: If this option is selected, -all users will be listed, except those users contained in -the list entitled No show users. If Show -users is not checked, this has no effect. - - - - - -Select users - -This page contains three listboxes. The large listbox on the left -shows all the users on the system which might be a genuine user. - -The top rightmost listbox shows the selected users and the bottom -rightmost listbox shows the users we don't want displayed in the login -window. - -To move a user from one listbox to another you click on the -username in the listbox and click >> to -move the user from the leftmost box the the rightmost box or -<< to move the user from the rightmost box -to the leftmost box. - - - - -Images - -This section of the manual only applies if Show -users is selected. If it is not, this image box has no -effect. - -Every user on the system can be represented by a image. The image -for the user is kept in a file called -$TDEDIR/share/apps/tdm/pics/users/$USER.xpm. -If the user doesn't have such a file the file -$TDEDIR/share/apps/tdm/pics/users/default.xpm -will be used instead. - -To assign a new image to a user just select the user in one of the -listboxes and either drop an imagefile on the image button to the right -or click on the image button and select a new image from the image -selector. - -If no user is currently selected you will be asked if you want to change -the default image. - -The replacement is performed by a &konqueror; process so if the -image file already exists you will be prompted by &konqueror; if you -want to replace it. If you confirm the image will be replaced - you will -not have to press the Apply -button. - - - - - - -Convenience - -In the convenience tab you can configure some -options that make life easier for lazy people, like auto login or -disabling passwords. - -Please think more than twice before using these -options. Every option in the convenience tab is -well-suited to seriously compromise your system security. Practically, -these options are only to be used in a completely non-critical -environment, ⪚ a private computer at home. - - -Automatic Login - -Automatic login will give anyone access to a certain account on -your system without doing any authentication. You can enable it using -the option Enable auto-login. - -Automatic login comes in two flavors: truly automatic -login acts like you would expect automatic login to, &ie; -&tdm; will automatically login without expecting any input from the -user. Enable this using the Truly automatic login -option. If this option is not enabled, &tdm; will start normally, -enabling you to login as any user, and will only perform automatic login -if you kill the X server, ⪚ by pressing &Ctrl;&Alt;Backspace. - -You can choose the account to be used for automatic login in the -list below. - - - - -Password-less Login - -Using this feature, you can allow certain users to login without -having to provide their password. Enable this feature using the -Enable password-less logins option. - -Below this option you will see a list of users for which a password -is required, as well as a (by default, empty) list of users that do not -need to provide a password. When Enable password-less -logins is enabled, you can move users from one list into the -other, by selecting them and then clicking the ->> and << -buttons. - -Again, this option should only be used in a safe -environment. If you enable it on a rather public system you should take -care that only users with heavy access restrictions are granted -password-less login, ⪚ -guest. - -The Automatically login after X server crash -option allows you to skip the authentication procedure when your X -server accidentally crashed. Show previous user -will show the name of the last login already entered into the login -field in &tdm;. Some site administrators would consider even this a -possible security weakness, because potential attackers then know at -least one valid login. - - - - - - - - -
diff --git a/doc/kcontrol/tdm/CMakeLists.txt b/doc/kcontrol/tdm/CMakeLists.txt new file mode 100644 index 000000000..4bdd0a66d --- /dev/null +++ b/doc/kcontrol/tdm/CMakeLists.txt @@ -0,0 +1,12 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +tde_create_handbook( DESTINATION kcontrol/tdm ) diff --git a/doc/kcontrol/tdm/Makefile.am b/doc/kcontrol/tdm/Makefile.am new file mode 100644 index 000000000..c81f42bd9 --- /dev/null +++ b/doc/kcontrol/tdm/Makefile.am @@ -0,0 +1,2 @@ +KDE_LANG = en +KDE_DOCS = kcontrol/tdm diff --git a/doc/kcontrol/tdm/index.docbook b/doc/kcontrol/tdm/index.docbook new file mode 100644 index 000000000..ef1d0b7d4 --- /dev/null +++ b/doc/kcontrol/tdm/index.docbook @@ -0,0 +1,518 @@ + + + +]> + +
+ + + +&Thomas.Tanghus; &Thomas.Tanghus.mail; +&Steffen.Hansen; &Steffen.Hansen.mail; +&Mike.McBride; &Mike.McBride.mail; + + + +2002-02-13 +3.00.00 + + +KDE +KControl +TDM configuration +login manager +login + + + + +Login Manager + +Using this module, you can configure the &kde; graphical login +manager, &tdm;. You can change how the login screen looks, who has +access using the login manager and who can shutdown the +computer. + +In order to organize all of these options, this module is +divided into six sections: Appearance, +Font, Background, +Sessions, +Users and +Convenience. + +You can switch between the sections using the tabs at the top of +the window. + +If you are not currently logged in as a superuser, you +will need to click the Administrator Mode +Button. You will then be asked for a superuser password. Entering a +correct password will allow you to modify the settings of this +module. + + +Appearance + +From this page you can change the visual appearance of &tdm;, +&kde;'s graphical login manager. + +The greeting string is the title of the login screen. If the +string contains the word HOSTNAME it +will be translated to the domainless name of the machine &tdm; is +installed on. + +You can then choose to show either the current system time, a logo +or nothing special in the login box. Make your choice in the radio +buttons labeled Logo area. Using the +Positions setting, you can choose to either center +the content of the logo area or to position it using fixed +coordinates. + +If you chose Show logo you can now choose a +logo: + + + +Drop an image file on the image button. + + +Click on the image button and select a new image from the image chooser +dialog. + + + +If you do not specify a logo the default +$TDEDIR/share/apps/tdm/pics/kdelogo.png +will be displayed. + +While &kde;'s style depends on the settings of the user logged in, +the style used by &tdm; can be configured using the GUI +Style option. + +Below that, you have two dropdown boxes to choose the language and the +country for your login box. + + + + +Font + +From this section of the module you can change the fonts used in +the login window. + +You can select three different font styles from the drop down box +(Greeting, Fail, +Standard). When you click on the Change +font button a dialog appears from which you can select the +new characteristics for the font style. + + + +The Greeting font is the font used for the title +(Greeting String). + + +The Fail font is used when a login fails. + + +The Standard font is used in all other places in the +login window. + + + +An example of each font can be seen in the +Example Box. + + + + +Background + +Here you can change the desktop background which will be displayed +when a user logs in. You can have a single color or an image as a +background. If you have an image as the background and select center, the +selected background color will be used around the image if it isn't +large enough to cover the entire desktop. + +The background colors and effects are controlled by the options on +the tab labeled Background and you select a +background image and its placement from the options on the tab labeled +Wallpaper. + +To change the default background color(s) simply click either of +the color buttons and select a new color. + +The dropdown box above the color buttons provides you with several +different blend effects. Choose one from the list, and it will be +previewed on the small monitor at the top of the window. Your choices +are: + + + +Flat +By choosing this mode, you select one color (using the color +button labeled Color 1), and the entire background is +covered with this one color. + + +Pattern +By choosing this mode, you select two colors (using both color +buttons). You then select a pattern by clicking +Setup. This opens a new dialog window, which gives you +the opportunity to select a pattern. Simply click once on the pattern of your +choice, then click on OK, and &kde; will render the pattern +you selected using the two colors you selected. For more on patterns, see the +section Background: Adding, Removing and Modifying +Patterns. + + +Background Program +By selecting this option, you can have &kde; use an external +program to determine the background. This can be any program of your choosing. +For more information on this option, see the section entitled Background: Using an external program. + + +Horizontal Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the color selected by Color +1 on the left edge of the screen, and slowly transform into the +color selected by Color 2 by the time it gets to the +right edge of the screen. + + +Vertical Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the color selected by Color +1 on the top edge of the screen, and slowly transform into the color +selected by Color 2 as it moves to the bottom of the +screen. + + +Pyramid Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the color selected by Color +1 in each corner of the screen, and slowly transform into the color +selected by Color 2 as it moves to the center of the +screen. + + +Pipecross Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the color selected by Color +1 in each corner of the screen, and slowly transform into the color +selected by Color 2 as it moves to the center of the +screen. The shape of this gradient is different then the pyramid +gradient. + + +Elliptic Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the color selected by Color +2 in the center of the screen, and slowly transform into the color +selected by Color 1 as it moves to the edges, in an +elliptical pattern. + + + +The setup button is only needed for if you select Background +program or Patterns. In these instances, +another window will appear to configure the specifics. +Wallpaper +To select a new background image first, click on the +Wallpapers tab, then you can either select an image from the +drop-down list labeled Wallpaper or select +Browse... and select an image file from a file +selector. + +The image can be displayed in six different ways: + + +No wallpaper +No image is displayed. Just the background colors. + + +Centered +The image will be centered on the screen. The background colors +will be present anywhere the image does not cover. + + +Tiled +The image will be duplicated until it fills the entire +desktop. The first image will be placed in the upper left corner of the screen, +and duplicated downward and to the right. + + +Center Tiled +The image will be duplicated until it fills the entire +desktop. The first image will be placed in the center of the screen, and +duplicated upward, downward to the right, and to the left. + + +Centered Maxpect +The image will be placed in the center of the screen. It will +be scaled to fit the desktop, but it will not change the aspect ratio of the +original image. This will provide you with an image that is not distorted. + + + +Scaled +The image will be scaled to fit the desktop. It will be +stretched to fit all four corners. + + + + + + +Sessions + +Allow to shutdown +Use this dropdown box to choose who is allowed to shut down: + + +None: No one can shutdown the computer using &tdm;. +You must be logged in, and execute a command. + + +All: Everyone can shutdown the computer using +&tdm;. + +Root only: &tdm; requires that the +root password be entered before shutting down the +computer. +Console only: The user must be at this +console, to shut down the computer. + + +Commands +Use these 3 blanks to define the exact shutdown command. +The shutdown command defaults to: + +/sbin/shutdown + +The restart command defaults to: + +/sbin/reboot + +The Console mode (which restarts the computer as a console only terminal) +defaults to: + +/sbin/init + +When Show boot options is enabled, &tdm; will on reboot +offer you options for the lilo boot manager. For this feature to work, you will +need to supply the correct paths to your lilo command and to +lilo's map file. + + + +Session types + +Define which session types should be accessible from the login +window. + + For more information on this subject, look at /etc/X11/xdm/Xsession to find your +xdm setup files. Also review the xdm man pages, especially under the SESSION +PROGRAM section. + +To add a session, type its name in the +blank entitled New types, and click +Add new. + +To remove a session, select the session from the list and click +Remove. + + + + + + + +Users + +From here you can change the way users are represented in the +login window. + +As you look on this window, you will see three lists (All users, +selected users, and no-show users). You also see an image box, and a +set of options along the right side of the window. + +The first thing you must decide, is if you are going to show users +or not. + + +If you choose to show users, then the login window will show +images (which you select), of a list of users. When someone is ready to +login, they select their user name/image, enter their password, and they +are granted access. + +If you choose not to show users, then the login window will be +more traditional. Users will need to type their username, and password +to gain entrance. This is the preferred way if you have many users on +this terminal. + + +To show (and sort) or not to show users + +Along the right edge of the window are two check boxes: + +If Show users is selected, you have chosen to +show images of users, instead of making them type their login +name. + +If Sort users is selected, then the list of +users will be sorted alphabetically in the login window. If unchecked, +users will be listed in the same order as they are on this page. If +Show users is not checked, this has no +effect. + + + + +How to determine which users to show and which users to hide + +Below the user image box, and above the Show +users check box, is a set of two radio buttions: + + +Show only selected users: If this option is selected, only the +users contained in the list labelled Selected Users, will +be displayed in the login window. If Show users is not +checked, this has no effect. +Show all users but no-show users: If this option is selected, +all users will be listed, except those users contained in +the list entitled No show users. If Show +users is not checked, this has no effect. + + + + + +Select users + +This page contains three listboxes. The large listbox on the left +shows all the users on the system which might be a genuine user. + +The top rightmost listbox shows the selected users and the bottom +rightmost listbox shows the users we don't want displayed in the login +window. + +To move a user from one listbox to another you click on the +username in the listbox and click >> to +move the user from the leftmost box the the rightmost box or +<< to move the user from the rightmost box +to the leftmost box. + + + + +Images + +This section of the manual only applies if Show +users is selected. If it is not, this image box has no +effect. + +Every user on the system can be represented by a image. The image +for the user is kept in a file called +$TDEDIR/share/apps/tdm/pics/users/$USER.xpm. +If the user doesn't have such a file the file +$TDEDIR/share/apps/tdm/pics/users/default.xpm +will be used instead. + +To assign a new image to a user just select the user in one of the +listboxes and either drop an imagefile on the image button to the right +or click on the image button and select a new image from the image +selector. + +If no user is currently selected you will be asked if you want to change +the default image. + +The replacement is performed by a &konqueror; process so if the +image file already exists you will be prompted by &konqueror; if you +want to replace it. If you confirm the image will be replaced - you will +not have to press the Apply +button. + + + + + + +Convenience + +In the convenience tab you can configure some +options that make life easier for lazy people, like auto login or +disabling passwords. + +Please think more than twice before using these +options. Every option in the convenience tab is +well-suited to seriously compromise your system security. Practically, +these options are only to be used in a completely non-critical +environment, ⪚ a private computer at home. + + +Automatic Login + +Automatic login will give anyone access to a certain account on +your system without doing any authentication. You can enable it using +the option Enable auto-login. + +Automatic login comes in two flavors: truly automatic +login acts like you would expect automatic login to, &ie; +&tdm; will automatically login without expecting any input from the +user. Enable this using the Truly automatic login +option. If this option is not enabled, &tdm; will start normally, +enabling you to login as any user, and will only perform automatic login +if you kill the X server, ⪚ by pressing &Ctrl;&Alt;Backspace. + +You can choose the account to be used for automatic login in the +list below. + + + + +Password-less Login + +Using this feature, you can allow certain users to login without +having to provide their password. Enable this feature using the +Enable password-less logins option. + +Below this option you will see a list of users for which a password +is required, as well as a (by default, empty) list of users that do not +need to provide a password. When Enable password-less +logins is enabled, you can move users from one list into the +other, by selecting them and then clicking the +>> and << +buttons. + +Again, this option should only be used in a safe +environment. If you enable it on a rather public system you should take +care that only users with heavy access restrictions are granted +password-less login, ⪚ +guest. + +The Automatically login after X server crash +option allows you to skip the authentication procedure when your X +server accidentally crashed. Show previous user +will show the name of the last login already entered into the login +field in &tdm;. Some site administrators would consider even this a +possible security weakness, because potential attackers then know at +least one valid login. + + + + + + + + +
diff --git a/doc/kdm/CMakeLists.txt b/doc/kdm/CMakeLists.txt deleted file mode 100644 index 9a29fa8f8..000000000 --- a/doc/kdm/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -tde_create_handbook( DESTINATION tdm ) diff --git a/doc/kdm/Makefile.am b/doc/kdm/Makefile.am deleted file mode 100644 index 3db537e3f..000000000 --- a/doc/kdm/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -conf_def = $(top_srcdir)/tdm/config.def -ref: $(conf_def) $(top_srcdir)/tdm/confproc.pl - $(PERL) -w $(top_srcdir)/tdm/confproc.pl --doc $(conf_def) tdmrc-ref.docbook - -KDE_LANG = en -KDE_DOCS = AUTO diff --git a/doc/kdm/index.docbook b/doc/kdm/index.docbook deleted file mode 100644 index dde535328..000000000 --- a/doc/kdm/index.docbook +++ /dev/null @@ -1,1472 +0,0 @@ - - - - tdmrc"> - ksmserver"> - kdesktop"> - XDMCP"> - xdm"> - - - -]> - - - -The &tdm; Handbook - - - -&Oswald.Buddenhagen; &Oswald.Buddenhagen.mail; - - - - - - - -2000 -&Neal.Crook; - - - -2002 -&Oswald.Buddenhagen; - - - -2003 -&Lauri.Watts; - - -2003-03-01 -0.05.02 - - -This document describes &tdm; the &kde; Display Manager. &tdm; -is also known as the Login Manager. - - - -KDE -tdm -xdm -display manager -login manager - - - - - -Introduction - -&tdm; provides a graphical interface that allows you to log in to a -system. It prompts for login (username) and password, authenticates the user -and starts a session. &tdm; is superior to &xdm;, the X -Display Manager, in a number of ways. - - - - - - - -Quick Start Guide - -This is a quick start guide for users who fit the following -pattern: - - - -X is configured and works with the command -startx from the commandline. - - -Each user will generally only use a single window manager or -desktop environment, and does not change this choice very -often, or is comfortable editing a single text file in order to change -their choice. - - - -This scenario will be sufficient for many environments where a single -user or several users normally boot the computer and log into their -preferred environment. - - -Setting up a Default Session - -Create or open the file ~/.xinitrc -If you already have a working ~/.xinitrc, go to -the next step - - -If one does not already exist, add a line to the -~/.xinitrc to start your preferred window manager -or desktop environment. -For &kde; you should enter: -starttde -For other window managers or desktop environments, you should -look in their documentation for the correct command. - -Make a link as follows: -ln ~/.xinitrc ~/.xsession - - - -At this point, typing startx -on the commandline should start X, with a &kde; session. The next task is -to try &tdm;. - -As root, type -tdm at the prompt. - -You should see a login window, which is described more fully in . - -Typing your normal username and password in the fields provided, and -leaving selected as the session type should now -open a &kde; session for your user. - -If you have other users to configure, you should repeat the procedure -above for each of them. - - -This is a quick guide to getting up and running only. You probably -will want to customize &tdm; further, for example, to hide the names of the -system accounts, to allow further sessions, and much more. Please read -through the rest of this manual to find out how to do these things. - - - - - -The Login Window - - The user interface to &tdm; consists of two dialog boxes. The main -dialog box has these controls: - - - -A Username: field for you to enter your -username. - - - -A Password: field for you to enter your -password. - - - -(Optionally) a graphical image of each user (for example, a digitized -photograph). Clicking on an image is equivalent to typing the associated -username into the Username: field. (This feature is an -imitation of the login box on &IRIX;). - - - -A Menu drop down box that allows &tdm; to be used -to start sessions with various different window managers or desktop -environments installed on the system. - - - -(Optionally) a region to the right of the -Username:, Password: and -Session Type: fields which can be used to display -either a static image or an analog clock. - - - -A Login button that validates the -username/password combination and attempts to start a session of the -selected type. - - - -A Clear button that clears the text from -the Login and Pass -fields. - - - -A Menu button that opens an action menu -with the following items: - - - -(On local displays) A Restart X Server item -that terminates the currently running &X-Server;, starts a new one and -displays the login dialog again. You can use this if the display content -seems to be broken somehow. - - - -(On remote displays) A Close Connection -item that closes the connection to the &XDMCP; server you are currently -connected to. If you got to this server through a host chooser, this will -bring you back to the chooser, otherwise it will only reset the &X-Server; -and bring up the login dialog again. - - - -(Optionally on local displays) A Console -Mode item that terminates the currently running &X-Server; and -leaves you alone with a console login. &tdm; will resume the graphical login -if nobody is logged in at the console for some time. - - - - - -(Optionally) A Shutdown button that displays -the Shutdown dialog box. - - - -The Shutdown dialog box presents a set of -radio buttons that allow one of these options to be selected: - - - -Shutdown - -Shut the system down in a controlled manner, ready for -power-down. - - - -Restart - -Shut the system down and reboot. For systems that use -Lilo, an optional drop down box allows you to -select a particular operating-system kernel to be used for the -reboot. - - - -Restart X Server - -Stop and then restart the X-server. Typically, you might need to use -this option if you have changed your X11 configuration in some way. - - - -Console Mode - -Stop the &X-Server; and return the system to console mode. This is -achieved by bringing the system down to runlevel 3. Typically, the system -manager might need to use this option before upgrading or re-configuring X11 -software. - - - - -Pressing the OK button initiates the selected -action; pressing the Cancel button returns to the -main &tdm; dialog box. - - - - - -Configuring &tdm; - -This chapter assumes that &tdm; is already up and running on your -system, and that you simply want to change its behavior in some way. - -When &tdm; starts up, it reads its configuration from the folder -$TDEDIR/share/config/tdm/ (this may -be /etc/trinity/tdm/ or something else -on your system). - -The main configuration file is &tdmrc;; all other files are -referenced from there and could be stored under any name anywhere on -the system - but usually that would not make much sense for obvious -reasons (one particular exception is referencing configuration files -of an already installed &xdm; - however when a new &tdm; is installed, -it will import settings from those files if it finds an already installed -&xdm;). - -Since &tdm; must run before any user is logged in, it is not -associated with any particular user. Therefore, it is not possible to have -user-specific configuration files; all users share the common &tdmrc;. It -follows from this that the configuration of &tdm; can only be altered by -those users that have write access to -$TDEDIR/share/config/tdm/tdmrc (normally -restricted to system administrators logged in as root). - -You can view the &tdmrc; file currently in use on your system, and you -can configure &tdm; by editing this file. Alternatively, you can use the -graphical configuration tool provided by the &kcontrolcenter; (under -System AdministrationLogin -Manager), which is described in the &kcontrolcenter; help files. - - -The remainder of this chapter describes configuration of &tdm; -via the &kcontrolcenter; module, and the next -chapter describes the options available in &tdmrc; itself. If -you only need to configure for local users, the &kcontrolcenter; module -should be sufficient for your needs. If you need to configure remote -logins, or have multiple &tdm; sessions running, you will need to read -on. - - - - -&Thomas.Tanghus; &Thomas.Tanghus.mail; -&Steffen.Hansen; &Steffen.Hansen.mail; -&Mike.McBride; &Mike.McBride.mail; - - - -The Login Manager &kcontrolcenter; Module - -Using this module, you can configure the &kde; graphical login -manager, &tdm;. You can change how the login screen looks, who has -access using the login manager and who can shutdown the -computer. - -All settings will be written to the configuration file -&tdmrc;, which in its original state has many comments to help you -configure &tdm;. Using this &kcontrolcenter; module will strip these -comments from the file. All available options in &tdmrc; are covered -in . - -The options listed in this chapter are cross referenced with -their equivalents in &tdmrc;. All options available in the &kcontrol; -module are also available directly in &tdmrc; but the reverse is not -true. - -In order to organize all of these options, this module is -divided into several sections: Appearance, -Font, Background, -Shutdown, -Users and -Convenience. - -You can switch between the sections using the tabs at the top of -the window. - -If you are not currently logged in as a superuser, you -will need to click the Administrator Mode... -Button. You will then be asked for a superuser password. Entering a -correct password will allow you to modify the settings of this -module. - - -Appearance - -From this page you can change the visual appearance of &tdm;, -&kde;'s graphical login manager. - -The Greeting: is the title of the login - screen. Setting this is especially useful if you have many servers users - may log in to. You may use various placeholders, which are described - along with the corresponding key - - in &tdmrc;. - - -You can then choose to show either the current system time, a logo or -nothing special in the login box. Make your choice in the radio buttons -labeled Logo area:. This corresponds to in &tdmrc; - -If you chose Show logo you can now choose a -logo: - - - -Drop an image file on the image button. - - -Click on the image button and select a new image from the image chooser -dialog. - - - -If you do not specify a logo the default -$TDEDIR/share/apps/tdm/pics/kdelogo.xpm -will be displayed. - -Normally the login box is centered on the screen. Use the -Position: options if you want it to appear -elsewhere on the screen. You can specify the relative position -(percentage of the screen size) for the center of the login window, -relative to the top left of the display, in the fields labeled -X: and Y: respectively. -These correspond to the key - -in &tdmrc;. - -While &kde;'s style depends on the settings of the user logged -in, the style used by &tdm; can be configured using the GUI -Style: and Color Scheme: options. -These correspond to the keys and in -&tdmrc; respectively. - -Below that, you have a drop down box to choose the language for -your login box, corresponding to setting in -&tdmrc;. - - - - -Font - -From this section of the module you can change the fonts used in the -login window. Only fonts available to all users are available here, not -fonts you have installed on a per user basis. - -You can select three different font styles from the drop down box -(General:, Failures:, -Greeting:). When you click on the -Choose... button a dialog appears from which you can -select the new characteristics for the font style. - - - -The General: font is used in all other places in the -login window. - - -The Failures: font is used when a login -fails. - - -The Greeting: font is the font used for the title -(Greeting String). - - - -You can also check the box labeled Use anti-aliasing for -fonts if you want smoothed fonts in the login dialog. - - - - -Background - -Here you can change the desktop background which will be displayed -before a user logs in. You can have a single color or an image as a -background. If you have an image as the background and select center, the -selected background color will be used around the image if it is not -large enough to cover the entire desktop. - -The background colors and effects are controlled by the options on -the tab labeled Background and you select a -background image and its placement from the options on the tab labeled -Wallpaper. - -To change the default background color(s) simply click either of -the color buttons and select a new color. - -The drop down box above the color buttons provides you with several -different blend effects. Choose one from the list, and it will be -previewed on the small monitor at the top of the window. Your choices -are: - - - -Flat -By choosing this mode, you select one color (using the color -button labeled Color 1), and the entire background is -covered with this one color. - - -Pattern -By choosing this mode, you select two colors (using both color -buttons). You then select a pattern by clicking -Setup. This opens a new dialog window, which gives you -the opportunity to select a pattern. Simply click once on the pattern of your -choice, then click on OK, and &kde; will render the pattern -you selected using the two colors you selected. For more on patterns, see the -section Background: Adding, Removing and Modifying -Patterns. - - -Background Program -By selecting this option, you can have &kde; use an external -program to determine the background. This can be any program of your choosing. -For more information on this option, see the section entitled Background: Using an external program. - - -Horizontal Gradient -By choosing this mode, you select two colors (using both color -buttons). &kde; will then start with the color selected by Color -1 on the left edge of the screen, and slowly transform into the -color selected by Color 2 by the time it gets to the -right edge of the screen. - - -Vertical Gradient -By choosing this mode, you select two colors (using both color -buttons). &kde; will then start with the color selected by Color -1 on the top edge of the screen, and slowly transform into the color -selected by Color 2 as it moves to the bottom of the -screen. - - -Pyramid Gradient -By choosing this mode, you select two colors (using both color -buttons). &kde; will then start with the color selected by Color -1 in each corner of the screen, and slowly transform into the color -selected by Color 2 as it moves to the center of the -screen. - - -Pipecross Gradient -By choosing this mode, you select two colors (using both color -buttons). &kde; will then start with the color selected by Color -1 in each corner of the screen, and slowly transform into the color -selected by Color 2 as it moves to the center of the -screen. The shape of this gradient is different then the pyramid -gradient. - - -Elliptic Gradient -By choosing this mode, you select two colors (using both color -buttons). &kde; will then start with the color selected by Color -2 in the center of the screen, and slowly transform into the color -selected by Color 1 as it moves to the edges, in an -elliptical pattern. - - - -The setup button is only needed for if you select Background -program or Patterns. In these instances, -another window will appear to configure the specifics. -Wallpaper -To select a new background image first, click on the -Wallpapers tab, then you can either select an image from the drop down list labeled Wallpaper or select -Browse... and select an image file from a file -selector. - -The image can be displayed in six different ways: - - -No wallpaper -No image is displayed. Just the background colors. - - -Centered -The image will be centered on the screen. The background colors -will be present anywhere the image does not cover. - - -Tiled -The image will be duplicated until it fills the entire -desktop. The first image will be placed in the upper left corner of the screen, -and duplicated downward and to the right. - - -Center Tiled -The image will be duplicated until it fills the entire -desktop. The first image will be placed in the center of the screen, and -duplicated upward, downward to the right, and to the left. - - -Centered Maxpect -The image will be placed in the center of the screen. It will -be scaled to fit the desktop, but it will not change the aspect ratio of the -original image. This will provide you with an image that is not distorted. - - - -Scaled -The image will be scaled to fit the desktop. It will be -stretched to fit all four corners. - - - - - - -<guilabel>Shutdown</guilabel> - -Allow Shutdown -Use this drop down box to choose who is allowed to shut down: - - -Nobody: No one can shutdown the computer using -&tdm;. You must be logged in, and execute a command. - - -Everybody: Everyone can shutdown the computer using -&tdm;. - -Only Root: &tdm; requires that the -root password be entered before shutting down the -computer. - - -You can independently configure who is allowed to issue a -shutdown command for the Local: and -Remote: users. - -Commands Use these text fields to -define the exact shutdown command. The -Halt: command defaults to -/sbin/halt. The Restart: command -defaults to -/sbin/reboot. - -When Show boot options is enabled, &tdm; -will on reboot offer you options for the lilo boot manager. For this -feature to work, you will need to supply the correct paths to your -lilo command and to lilo's map file. Note that this -option is not available on all operating systems. - - - - -Users - -From here you can change the way users are represented in the -login window. - -You may disable the user list in &tdm; entirely in the -Show Users section. You can choose from: - - - -Show List - -Only show users you have specifically enabled in the list -alongside -If you do not check this box, no list will be shown. This is the most secure setting, since an -attacker would then have to guess a valid login name as well as a -password. It's also the preferred option if you have more than a -handful of users to list, or the list itself would become -unwieldy. - - - -Inverse selection - -Allows you to intead select a list of users that should -not be shown, and all other users will be -listed. - - - - -Independently of the users you specify by name, you can use the -System UIDs to specify a range of valid -UIDs that are shown in the list. By default user -id's under 1000, which are often system or daemon users, and user id's -over 65000, are not shown. - -You can also enable the Sort users -checkbox, to have the user list sorted alphabetically. If this is -disabled, users will appear in the order they are listed in the -password file. &tdm; will also autocomplete user names if you enable the -Autocompletion option. - -If you choose to show users, then the login window will show -images (which you select), of a list of users. When someone is ready -to login, they may select their user name/image, enter their password, -and they are granted access. - -If you permit a user image, then you can configure the source -for those images. - -You can configure the admin picture here, for each user on the -system. Depending on the order selected above, users may be able to -override your selection. - -If you choose not to show users, then the login window will be -more traditional. Users will need to type their username and password -to gain entrance. This is the preferred way if you have many users on -this terminal. - - - - -Convenience - -In the convenience tab you can configure -some options that make life easier for lazy people, like automatic -login or disabling passwords. - -Please think more than twice before using these -options. Every option in the Convenience tab is -well-suited to seriously compromise your system security. Practically, -these options are only to be used in a completely non-critical -environment, ⪚ a private computer at home. - - -Automatic Login - -Automatic login will give anyone access to a certain account on -your system without doing any authentication. You can enable it using -the option Enable Auto-login. - -You can choose the account to be used for automatic login from -the list labeled User:. - - - - -<guilabel>Password-Less Login</guilabel> - -Using this feature, you can allow certain users to login without -having to provide their password. Enable this feature using the -Enable Password-less logins option. - -Below this option you'll see a list of users on the system. -Enable password-less login for specific users by checking the checkbox -next to the login names. By default, this feature is disabled for -all users. - -Again, this option should only be used in a safe -environment. If you enable it on a rather public system you should -take care that only users with heavy access restrictions are granted -password-less login, ⪚ -guest. - -You can also choose which user is preselected -when &tdm; starts. The default is None, but you -can choose Previous to have &tdm; default to the -last successfully logged in user, or you can -Specify a particular user to always be selected -from the list. You can also have &tdm; set the focus to the password -field, so that when you reach the &tdm; login screen, you can type the -password immediately. - -The Automatically login after X server crash -option allows you to skip the authentication procedure when your X -server accidentally crashed. - - - - - - - - - -&tdmrc-ref; - - - -Configuring your system to use &tdm; - -This chapter assumes that your system is already configured to -run the &X-Window;, and that you only need to reconfigure it to -allow graphical login. - - -Setting up &tdm; - -The fundamental thing that controls whether your computer boots to a -terminal prompt (console mode) or a graphical login prompt is the default -runlevel. The runlevel is set by the program /sbin/init under the control of the -configuration file /etc/inittab. The default runlevels -used by different &UNIX; systems (and different &Linux; distributions) vary, -but if you look at /etc/inittab the start of it should -be something like this: - -# Default runlevel. The runlevels used by RHS are: -# 0 - halt (Do NOT set initdefault to this) -# 1 - Single user mode -# 2 - Multiuser, without NFS -# 3 - Full multiuser mode -# 4 - unused -# 5 - X11 -# 6 - reboot (Do NOT set initdefault to this) - -id:3:initdefault: - - -All but the last line of this extract are comments. The comments -show that runlevel 5 is used for X11 and that runlevel 3 is used for -multi-user mode without X11 (console mode). The final line specifies -that the default runlevel of the system is 3 (console mode). If your -system currently uses graphical login (for example, using &xdm;) its -default runlevel will match the runlevel specified for X11. - -The runlevel with graphical login (&xdm;) for some common &Linux; -distributions is: - - -5 for &RedHat; 3.x and later, and for &Mandrake; -4 for Slackware -3 for &SuSE;. 4.x and 5.x - - -The first step in configuring your system is to ensure that you -can start &tdm; from the command line. Once this is working, you can -change your system configuration so that &tdm; starts automatically -each time you reboot your system. - -To test &tdm;, you must first bring your system to a runlevel -that does not run &xdm;. To do so, issue a command like this: - -/sbin/init - -Instead of the number you should specify the -appropriate runlevel for console mode on your system. - -If your system uses Pluggable Authentication Modules -(PAM), which is normal with recent &Linux; and &Solaris; -systems, you should check that your PAM configuration permits -login through the service named kde. If you previously used -&xdm; successfully, you should not need to make any -changes to your PAM configuration in order to use -&tdm;. /etc/pam.conf or -/etc/pam.d/kde. Information on configuring -PAM is beyond the scope of this handbook, but -PAM comes with comprehensive documentation (try looking in -/usr/share/doc/*pam*/html/). - -Now it's time for you to test &tdm; by issuing the following -command: - -tdm - - -If you get a &tdm; login dialog and you are able to log in, -things are going well. The main thing that can go wrong here is that -the run-time linker might not find the shared &Qt; or &kde; libraries. -If you have a binary distribution of the &kde; libraries, make sure -&tdm; is installed where the libraries believe &kde; is installed and -try setting some environment variables to point to your &kde; and &Qt; -libraries. - -For example: - -export - -export - -export - -export - - - -If you are still unsuccessful, try starting &xdm; instead, to -make sure that you are not suffering from a more serious X -configuration problem. - -When you are able to start &tdm; successfully, you can start to -replace &xdm; by &tdm;. Again, this is distribution-dependent. - - - -For &RedHat;, edit /etc/inittab, look for this - line: -x:5:respawn:/usr/X11/bin/xdm -nodaemon -and replace with: -x:5:respawn:/opt/kde/bin/tdm -This tells init(8) to respawn &tdm; when the -system is in run level 5. Note that &tdm; does not need the - option. - - -For &Mandrake;, the X11 runlevel in -/etc/inittab invokes the shell script -/etc/X11/prefdm, which is set up to select from -amongst several display managers, including &tdm;. Make sure that all -the paths are correct for your installation. - - -For &SuSE;, edit /sbin/init.d/xdm to add a -first line: - -. /etc/rc.config -DISPLAYMANAGER=tdm -export DISPLAYMANAGER - -For FreeBSD, edit /etc/ttys and find -the line like this: -ttyv8 "/usr/X11R6/bin/xdm -nodaemon" xterm off secure -and edit it to this: -ttyv8 "/usr/local/bin/tdm" xterm on secure - - -Most other distributions are a variation of one of -these. - - -At this stage, you can test &tdm; again by bringing your system -to the runlevel that should now run &tdm;. To do so, issue a command -like this: - -/sbin/init - - -Instead of the number you should specify the -appropriate runlevel for running X11 on your system. - -The final step is to edit the initdefault -entry in /etc/inittab to specify the appropriate -runlevel for X11. - -Before you make this change, ensure that you have a way -to reboot your system if a problem occurs. This might be a -rescue floppy-disk provided by your operating system -distribution or a specially-designed rescue -floppy-disk, such as tomsrtbt. Ignore this advice -at your peril. - -This usually involves changing the line: -id:3:initdefault: -to -id:5:initdefault: - -When you reboot your system, you should end up with the -graphical &tdm; login dialog. - -If this step is unsuccessful the most likely problem is that the -environment used at boot time differs from the environment that you used for -testing at the command line. If you are trying to get two versions of &kde; -to co-exist, be particularly careful that the settings you use for your -PATH and LD_LIBRARY_PATH environment variables -are consistent, and that the startup scripts are not over-riding them in -some way. - - - - - - -Supporting multiple window managers - -&tdm; detects most available window manager and desktop environments when -it is run. Installing a new one should make it automatically available in -the &tdm; main dialog Session Type:. - -If you have a very new window manager, or something that &tdm; does -not support, the first thing you should check is that the application to be -run is in the PATH and has not been renamed during the -install into something unexpected. - -If the case is that the application is too new and not yet supported -by &tdm;, you can quite simply add a new session. - -The sessions are defined in .desktop files in -$TDEDIR/share/apps/tdm/sessions. -You can simply add an appropriately named .desktop file in this directory. The fields -are: - -[Desktop Entry] -Encoding=UTF-8 This is fixed to and -may be omitted -Type=XSession This is fixed to and -may be omitted -Exec=executable name Passed to -eval exec in a Bourne shell -TryExec=executable name Supported -but not required -Name=name to show in the &tdm; session list - -There are also three magic: - - - -default - - -The default session for &tdm; is normally &kde; but can be configured by the -system administrator. - - - - -custom - - -The Custom session will run the users ~/.xsession if it exists. - - - - -failsafe - - -Failsafe will run a very plain session, and is useful only for debugging -purposes. - - - - - -To override a session type, copy the .desktop file from the data dir -to the config dir and edit it at will. Removing the shipped session types -can be accomplished by shadowing them with .desktop files -containing Hidden=true. For the magic session types no .desktop files exist -by default, but &tdm; pretends they would, so you can override them like any -other type. I guess you already know how to add a new session type by -now. ;-) - - - - -Using &tdm; for Remote Logins (&XDMCP;) - -&XDMCP; is the Open Group standard, the X Display Manager -Control Protocol. This is used to set up connections between -remote systems over the network. - -&XDMCP; is useful in multiuser situations where there are users -with workstations and a more powerful server that can provide the -resources to run multiple X sessions. For example, &XDMCP; is a good -way to reuse old computers - a Pentium or even 486 computer with 16 Mb -RAM is sufficient to run X itself, and using &XDMCP; such a computer can -run a full modern &kde; session from a server. For the server part, -once a single &kde; (or other environment) session is running, running -another one requires very few extra resources. - -However, allowing another method of login to your machine -obviously has security implications. You should run this service only -if you need to allow remote X Servers to start login sessions on your -system. Users with a single &UNIX; computer should not need to run -this. - - - - -Advanced Topics - - -Command Sockets - -This is a feature you can use to remote-control &tdm;. It's mostly -intended for use by &ksmserver; and &kdesktop; from a running session, but -other applications are possible as well. - -The sockets are &UNIX; domain sockets which live in subdirectories of the -directory specified by =. The subdir is the key to -addressing and security; the sockets all have the file name -socket and file permissions -rw-rw-rw- (0666). This is because some systems don't care -for the file permission of the socket files. - -There are two types of sockets: the global one (dmctl) and the -per-display ones (dmctl-<display>). - -The global one's subdir is owned by root, the subdirs of the per-display -ones' are owned by the user currently owning the session (root or the -logged in user). Group ownership of the subdirs can be set via FifoGroup=, -otherwise it is root. The file permissions of the subdirs are rwxr-x--- -(0750). - -The fields of a command are separated by tabs (\t), the -fields of a list are separated by spaces, literal spaces in list fields are -denoted by \s. - -The command is terminated by a newline (\n). - -The same applies to replies. The reply on success is -ok, possibly followed by the requested -information. The reply on error is an errno-style word (⪚ -perm, noent, &etc;) -followed by a longer explanation. - - -Global commands: - -login -(now | schedule) user password -[session_arguments] - -login user at specified display. if now is -specified, a possibly running session is killed, otherwise the login is done -after the session exits. session_arguments are printf-like escaped contents -for .dmrc. Unlisted keys will default to previously saved values. - - - - - -Per-display commands: - -lock - -The display is marked as locked. If the &X-Server; crashes in this -state, no auto-relogin will be performed even if the option is on. - - - -unlock - -Reverse the effect of lock, and re-enable -auto-relogin. - - - -suicide - -The currently running session is forcibly terminated. No auto-relogin -is attempted, but a scheduled "login" command will be executed. - - - - - -Commands for all sockets - -caps - -Returns a list of this socket's capabilities: - - - -&tdm; - -identifies &tdm;, in case some other DM implements this protocol, -too - - - -list, lock, -suicide, login - -The respective command is supported - - - -bootoptions - -The listbootoptions command and the - to shutdown are supported - - - -shutdown <list> - -shutdown is supported and allowed for the listed -users (a comma separated list.) * means all -authenticated users. - - - -nuke <list> - -Forced shutdown may be performed by the listed users. - - - -nuke - -Forced shutdown may be performed by everybody - - - -reserve <number> - -Reserve displays are configured, and number -are available at this time - - - - -list [all | -alllocal] - -Return a list of running sessions. By default all active sessions are -listed. if all is specified, passive sessions are -listed as well. If alllocal is specified, passive -sessions are listed as well, but all incoming remote sessions are -skipped. -Each session entry is a comma separated tuple of: - -Display or TTY name -VT name for local sessions -Logged in user's name, empty for passive sessions and -outgoing remote sessions (local chooser mode) -Session type or <remote> for outgoing -remote sessions, empty for passive sessions. -A Flag field: -* for the display belonging -to the requesting socket. -! for sessions that cannot be killed by the -reqeusting socket. - - - -New fields may be added in the future. - - - - -reserve [timeout in -seconds] - -Start a reserve login screen. If nobody logs in within the specified -amount of time (one minute by default), the display is removed again. When -the session on the display exits, the display is removed, too. -Permitted only on sockets of local displays and the global -socket. - - - - -activate -(vt|display) - -Switch to a particular VT (virtual terminal). The VT may be specified -either directly (⪚ vt3) or by a display using it -(eg; :2). -Permitted only on sockets of local displays and the global -socket. - - - - -listbootoptions - -List available boot options. - - - - - -shutdown (reboot | -halt) -[=bootchoice] -(ask|trynow|forcenow|schedule|start -(-1|end -(force|forcemy|cancel)))) - -Request a system shutdown, either a reboot or a halt/poweroff. -An OS choice for the next boot may be specified from the list returned -by listbootoptions -Shutdowns requested from per-display sockets are executed when the -current sessino on that display exits. Such a request may pop up a dialog -asking for confirmation and/or authentication -start is the time for which the shutdown is -scheduled. If it starts with a plus-sign, the current time is added. Zero -means immediately. -end is the latest time at which the shutdown -should be performed if active sessions are still running. If it starts with -a plus-sign, the start time is added. -1 means wait infinitely. If end is -through and active sessions are still running, &tdm; can do one of the -following: - -cancel - give up the -shutdown -force - shut down -nonetheless -forcemy - shut down nonetheless if -all active sessions belong to the requesting user. Only for per-display sockets. - -start and end are -specified in seconds since the &UNIX; epoch. -trynow is a synonym for 0 0 -cancel, forcenow for 0 0 -force and schedule for 0 --1. -ask attempts an immediate shutdown and -interacts with the user if active sessions are still running. Only for -per-display sockets. - - - - -shutdown cancel -[local|global} - -Cancel a scheduled shutdown. The global socket always cancels the -currently pending shutdown, while per-display sockets default to cancelling -their queued request. - - - - -shutdown status - -Return a list with information about shutdowns. -The entries are a comma-separated tuples of: - - -(global|local) - -pending vs. queued shutdown. A local entry can be returned only by a -per-display socket. - -(halt|reboot) -start -end -("ask"|"force"|"forcemy"|"cancel") -Numeric user ID of the requesting user, -1 for the global -socket. -The next boot OS choice or "-" for none. - -New fields might be added later - - - - - - -There are two ways of using the sockets: - - -Connecting them directly. FifoDir is exported as -$DM_CONTROL; the name of per-display sockets can be derived -from $DISPLAY. - - -By using the tdmctl command (⪚ from within a -shell script). Try tdmctl to find out -more. - - - -Here is an example bash script reboot into FreeBSD: - -if tdmctl | grep -q shutdown; then - IFS=$'\t' - set -- `tdmctl listbootoptions` - if [ "$1" = ok ]; then - fbsd=$(echo "$2" | tr ' ' '\n' | sed -ne 's,\\s, ,g;/freebsd/I{p;q}') - if [ -n "$fbsd" ]; then - tdmctl shutdown reboot "=$fbsd" ask > /dev/null - else - echo "FreeBSD boot unavailable." - fi - else - echo "Boot options unavailable." - fi -else - echo "Cannot reboot system." -fi - - - - - - -Other sources of information - -Since &tdm; is descended from &xdm;, the &xdm; man page may provide useful background -information. For X-related problems try the man pages X and startx. If you have -questions about &tdm; that are not answered by this handbook, take advantage of -the fact the &tdm; is provided under the terms of the &GNU; -General Public License: look at the source code. - - - - - -Credits and License - -&tdm; is derived from, and includes code from, -&xdm; (C) Keith Packard, MIT X Consortium. - -&tdm; 0.1 was written by &Matthias.Ettrich;. Later versions till &kde; -2.0.x were written by &Steffen.Hansen;. Some new features for &kde; 2.1.x and -a major rewrite for &kde; 2.2.x made by &Oswald.Buddenhagen;. - -Other parts of the &tdm; code are copyright by the authors, and -licensed under the terms of the &GNU; -GPL. Anyone is allowed to change &tdm; and redistribute the result -as long as the names of the authors are mentioned. - -&tdm; requires the &Qt; library, which is copyright Troll Tech AS. - -Documentation contributors: - - -Documentation written by &Steffen.Hansen; -stefh@dit.ou.dk - -Documentation extended by Gregor -Zumsteinzumstein@ssd.ethz.ch. Last update August 9, -1998 - -Documentation revised for &kde; 2 by &Neal.Crook; &Neal.Crook.mail;. Last update August 6, 2000 - -Documentation extended and revised for &kde; 2.2 by &Oswald.Buddenhagen; &Oswald.Buddenhagen.mail;. Last update August, -2001 - - - -Documentation copyright &Steffen.Hansen;, Gregor Zumstein, &Neal.Crook; -and &Oswald.Buddenhagen;. This document also includes large parts of the &xdm; -man page, which is © Keith Packard. - - - -&underFDL; -&underGPL; - - - - -Glossary - - -greeter -The greeter is the login dialog, &ie; the part of &tdm; -which the user sees. - - - - -entropy -The entropy of a system is the measure of its -unpredictability. This is used during the generation of random numbers. - - - - - - diff --git a/doc/kdm/kdmrc-ref.docbook b/doc/kdm/kdmrc-ref.docbook deleted file mode 100644 index f2cfd2f0e..000000000 --- a/doc/kdm/kdmrc-ref.docbook +++ /dev/null @@ -1,2316 +0,0 @@ - - - -The Files &tdm; Uses for Configuration - -This chapter documents the files that control &tdm;'s behavior. -Some of this can be also controlled from the &kcontrol; module, but -not all. - - -&tdmrc; - The &tdm; master configuration file - -The basic format of the file is INI-like. -Options are key/value pairs, placed in sections. -Everything in the file is case sensitive. -Syntactic errors and unrecognized key/section identifiers cause &tdm; to -issue non-fatal error messages. - -Lines beginning with # are comments; empty lines -are ignored as well. - -Sections are denoted by -[Name of Section]. - - -You can configure every X-display individually. -Every display has a display name, which consists of a host name -(which is empty for local displays specified in -or ), a colon, and a display number. -Additionally, a display belongs to a -display class (which can be ignored in most cases). - -Sections with display-specific settings have the formal syntax -[X- host [ : number [ _ class ] ] - sub-section ] - -All sections with the same sub-section -make up a section class. - -You can use the wildcard * (match any) for -host, number, -and class. You may omit trailing components; -they are assumed to be * then. The host part may be a -domain specification like .inf.tu-dresden.de -or the wildcard + (match non-empty). - -From which section a setting is actually taken is determined by -these rules: - - - -An exact match takes precedence over a partial match (for the -host part), which in turn takes precedence over a wildcard -(+ taking precendence over *). - - - -Precedence decreases from left to right for equally exact matches. - - - - - -Example: display name myhost.foo:0, class dpy - - - -[X-myhost.foo:0_dpy] precedes - - -[X-myhost.foo:0_*] (same as [X-myhost.foo:0]) precedes - - -[X-myhost.foo:*_dpy] precedes - - -[X-myhost.foo:*_*] (same as [X-myhost.foo]) precedes - - -[X-.foo:*_*] (same as [X-.foo]) precedes - - -[X-+:0_dpy] precedes - - -[X-*:0_dpy] precedes - - -[X-*:0_*] (same as [X-*:0]) precedes - - -[X-*:*_*] (same as [X-*]). - - -These sections do not match this display: -[X-hishost], [X-myhost.foo:0_dec], [X-*:1], [X-:*] - - - - - - - -Common sections are [X-*] (all displays), [X-:*] (all local displays) -and [X-:0] (the first local display). - -The format for all keys is - = value. -Keys are only valid in the section class they are defined for. -Some keys do not apply to particular displays, in which case they are ignored. - - -If a setting is not found in any matching section, the default -is used. - -Special characters need to be backslash-escaped (leading and trailing -spaces (\s), tab (\t), linefeed -(\n), carriage return (\r) and the -backslash itself (\\)). -In lists, fields are separated with commas without whitespace in between. - -Some command strings are subject to simplified sh-style word splitting: -single quotes (') and double quotes (") -have the usual meaning; the backslash quotes everything (not only special -characters). Note that the backslashes need to be doubled because of the -two levels of quoting. - -A pristine &tdmrc; is very thoroughly commented. -All comments will be lost if you change this file with the -kcontrol frontend. - - - -The [General] section of &tdmrc; - - -This section contains global options that do not fit into any specific section. - - - - - - - - -This option exists solely for the purpose of clean automatic upgrades. -Do not change it, you may interfere with future -upgrades and this could result in &tdm; failing to run. - - - - - - - - -List of displays (&X-Server;s) permanently managed by &tdm;. Displays with a -hostname are foreign displays which are expected to be already running, -the others are local displays for which &tdm; starts an own &X-Server;; -see . Each display may belong to a display class; -append it to the display name separated by an underscore. -See for the details. - -The default is :0. - - - - - - - -List of on-demand displays. See for syntax. - -Empty by default. - - - - - - - -List of Virtual Terminals to allocate to &X-Server;s. For negative numbers the -absolute value is used, and the VT will be allocated only -if the kernel says it is free. If &tdm; exhausts this list, it will allocate -free VTs greater than the absolute value of the last entry -in this list. -Currently Linux only. - -Empty by default. - - - - - - - -This option is for operating systems (OSs) with support -for virtual terminals (VTs), by both &tdm; and the -OSs itself. -Currently this applies only to Linux. - -When &tdm; switches to console mode, it starts monitoring all -TTY lines listed here (without the leading -/dev/). -If none of them is active for some time, &tdm; switches back to the X login. - -Empty by default. - - - - - - - -The filename specified will be created to contain an ASCII representation -of the process ID of the main &tdm; process; the PID will not be stored -if the filename is empty. - -Empty by default. - - - - - - - -This option controls whether &tdm; uses file locking to keep multiple -display managers from running onto each other. - -The default is true. - - - - - - - -This names a directory under which &tdm; stores &X-Server; authorization -files while initializing the session. &tdm; expects the system to clean up -this directory from stale files on reboot. - -The authorization file to be used for a particular display can be -specified with the option in [X-*-Core]. - -The default is /var/run/xauth. - - - - - - - -This boolean controls whether &tdm; automatically re-reads its -configuration files if it finds them to have changed. - -The default is true. - - - - - - - -Additional environment variables &tdm; should pass on to all programs it runs. -LD_LIBRARY_PATH and XCURSOR_THEME are good candidates; -otherwise, it should not be necessary very often. - -Empty by default. - - - - - - - -If the system has no native entropy source like /dev/urandom (see -) and no entropy daemon like EGD (see - and ) is running, -&tdm; will fall back to its own pseudo-random number generator -that will, among other things, successively checksum parts of this file -(which, obviously, should change frequently). - -This option does not exist on Linux and various BSDs. - -The default is /dev/mem. - - - - - - - -If the system has no native entropy source like /dev/urandom (see -), read random data from a Pseudo-Random -Number Generator Daemon, -like EGD (http://egd.sourceforge.net) via this UNIX domain socket. - -This option does not exist on Linux and various BSDs. - -Empty by default. - - - - - - - -Same as , only use a TCP socket on localhost. - - - - - - - - -The path to a character device which &tdm; should read random data from. -Empty means to use the system's preferred entropy device if there is one. - -This option does not exist on OpenBSD, as it uses the arc4_random -function instead. - -Empty by default. - - - - - - - -The directory in which the command FiFos should -be created; make it empty to disable them. - -The default is /var/run/xdmctl. - - - - - - - -The group to which the global command FiFo should belong; -can be either a name or a numerical ID. - - - - - - - - -The directory in which &tdm; should store persistent working data; such data -is, for example, the previous user that logged in on a particular display. - -The default is /var/lib/tdm. - - - - - - - -The directory in which &tdm; should store users' .dmrc files. This is only -needed if the home directories are not readable before actually logging in -(like with AFS). - -Empty by default. - - - - - - - - -The [Xdmcp] section of &tdmrc; - - -This section contains options that control &tdm;'s handling of -&XDMCP; requests. - - - - - - - - -Whether &tdm; should listen to incoming &XDMCP; requests. - -The default is true. - - - - - - - -This indicates the UDP port number which &tdm; uses to listen for incoming -&XDMCP; requests. Unless you need to debug the system, leave this with its -default value. - -The default is 177. - - - - - - - -XDM-AUTHENTICATION-1 style &XDMCP; authentication requires a private -key to be shared between &tdm; and the terminal. This option specifies -the file containing those values. Each entry in the file consists of a -display name and the shared key. - -Empty by default. - - - - - - - -To prevent unauthorized &XDMCP; service and to allow forwarding of &XDMCP; -IndirectQuery requests, this file contains a database of hostnames which -are either allowed direct access to this machine, or have a list of hosts -to which queries should be forwarded to. The format of this file is -described in . - -The default is ${kde_confdir}/tdm/Xaccess. - - - - - - - -Number of seconds to wait for the display to respond after the user has -selected a host from the chooser. If the display sends an &XDMCP; -IndirectQuery within this time, the request is forwarded to the chosen -host; otherwise, it is assumed to be from a new session and the chooser -is offered again. - -The default is 15. - - - - - - - -When computing the display name for &XDMCP; clients, the name resolver will -typically create a fully qualified host name for the terminal. As this is -sometimes confusing, &tdm; will remove the domain name portion of the host -name if it is the same as the domain name of the local host when this option -is enabled. - -The default is true. - - - - - - - -Use the numeric IP address of the incoming connection on multihomed hosts -instead of the host name. This is to avoid trying to connect on the wrong -interface which might be down at this time. - -The default is false. - - - - - - - -This specifies a program which is run (as -root) when an &XDMCP; -DirectQuery or BroadcastQuery is received and this host is configured -to offer &XDMCP; display management. The output of this program may be -displayed in a chooser window. If no program is specified, the string -Willing to manage is sent. - -Empty by default. - - - - - - - - -The [Shutdown] section of &tdmrc; - - -This section contains global options concerning system shutdown. - - - - - - - - -The command (subject to word splitting) to run to halt/poweroff the system. - -The default is something reasonable for the system on which &tdm; was built, like -/sbin/shutdown  now. - - - - - - - - -The command (subject to word splitting) to run to reboot the system. - -The default is something reasonable for the system &tdm; on which was built, like -/sbin/shutdown  now. - - - - - - - - -Whether it is allowed to shut down the system via the global command FiFo. - -The default is false. - - - - - - - -Whether it is allowed to abort active sessions when shutting down the -system via the global command FiFo. - -This will have no effect unless is enabled. - -The default is true. - - - - - - - -The boot manager &tdm; should use for offering boot options in the -shutdown dialog. - - - -None -no boot manager - - -Grub -Grub boot manager - - -Lilo -Lilo boot manager (Linux on i386 & x86-64 only) - - -The default is None. - - - - - - - - -The [X-*-Core] section class of &tdmrc; - - -This section class contains options concerning the configuration -of the &tdm; backend (core). - - - - - - - - -See . - -The default is 15. - - - - - - - -See . - -The default is 120. - - - - - - - -These options control the behavior of &tdm; when attempting to open a -connection to an &X-Server;. is the length -of the pause (in seconds) between successive attempts, - is the number of attempts to make and - is the amount of time to spend on a -connection attempt. After attempts have been -made, or if seconds elapse in any particular -connection attempt, the start attempt is considered failed. - -The default is 5. - - - - - - - -How many times &tdm; should attempt to start a foreign -display listed in before giving up -and disabling it. -Local displays are attempted only once, and &XDMCP; displays are retried -indefinitely by the client (unless the option -was given to the &X-Server;). - -The default is 4. - - - - - - - -How many times &tdm; should attempt to start up a local &X-Server;. -Starting up includes executing it and waiting for it to come up. - -The default is 1. - - - - - - - -How many seconds &tdm; should wait for a local &X-Server; to come up. - -The default is 15. - - - - - - - -The command line to start the &X-Server;, without display number and VT spec. -This string is subject to word splitting. - -The default is something reasonable for the system on which &tdm; was built, -like /usr/X11R6/bin/X. - - - - - - - - -Additional arguments for the &X-Server;s for local sessions. -This string is subject to word splitting. - -Empty by default. - - - - - - - -Additional arguments for the &X-Server;s for remote sessions. -This string is subject to word splitting. - -Empty by default. - - - - - - - -The VT the &X-Server; should run on. - should be used instead of this option. -Leave it zero to let &tdm; assign a VT automatically. -Set it to -1 to avoid assigning a VT -alltogether - this is required for setups with multiple physical consoles. -Currently Linux only. - - - - - - - - -This option is for OSs without support for -VTs, either by &tdm; or the OS itself. -Currently this applies to all OSs but Linux. - -When &tdm; switches to console mode, it starts monitoring this -TTY line (specified without the leading -/dev/) for activity. If the line is not used for some time, -&tdm; switches back to the X login. - -Empty by default. - - - - - - - -See . - -The default is 5. - - - - - - - -To discover when remote displays disappear, &tdm; -regularly pings them. - specifies the time (in minutes) between the -pings and specifies the maximum amount of -time (in minutes) to wait for the terminal to respond to the request. If -the terminal does not respond, the session is declared dead and terminated. - -If you frequently use X terminals which can become isolated from -the managing host, you may wish to increase the timeout. The only worry -is that sessions will continue to exist after the terminal has been -accidentally disabled. - -The default is 5. - - - - - - - -Whether &tdm; should restart the local &X-Server; after session exit instead -of resetting it. Use this if the &X-Server; leaks memory or crashes the system -on reset attempts. - -The default is false. - - - - - - - -The signal number to use to reset the local &X-Server;. - -The default is 1 (SIGHUP). - - - - - - - -The signal number to use to terminate the local &X-Server;. - -The default is 15 (SIGTERM). - - - - - - - -Controls whether &tdm; generates and uses authorization for -local &X-Server; connections. -For &XDMCP; displays the authorization requested by the display is used; -foreign non-&XDMCP; displays do not support authorization at all. - -The default is true. - - - - - - - -If is true, use the authorization mechanisms -listed herein. The MIT-MAGIC-COOKIE-1 authorization is always available; -XDM-AUTHORIZATION-1, SUN-DES-1 and MIT-KERBEROS-5 might be available as well, -depending on the build configuration. - -The default is DEF_AUTH_NAME. - - - - - - - -Some old &X-Server;s re-read the authorization file -at &X-Server; reset time, instead of when checking the initial connection. -As &tdm; generates the authorization information just before connecting to -the display, an old &X-Server; would not get up-to-date authorization -information. This option causes &tdm; to send SIGHUP to the &X-Server; -after setting up the file, causing an additional &X-Server; reset to occur, -during which time the new authorization information will be read. - -The default is false. - - - - - - - -This file is used to communicate the authorization data from &tdm; to -the &X-Server;, using the &X-Server; command line -option. It should be kept in a directory which is not world-writable -as it could easily be removed, disabling the authorization mechanism in -the &X-Server;. If not specified, a random name is generated from - and the name of the display. - -Empty by default. - - - - - - - -This option specifies the name of the file to be loaded by -xrdb as the resource database onto the root window -of screen 0 of the display. KDE programs generally do not use -X-resources, so this option is only needed if the -program needs some X-resources. - -Empty by default. - - - - - - - -The xrdb program to use to read the X-resources file -specified in . -The command is subject to word splitting. - -The default is ${x_bindir}/xrdb. - - - - - - - -This string is subject to word splitting. -It specifies a program which is run (as -root) before offering the -greeter window. This may be used to change the appearance of the screen -around the greeter window or to put up other windows (e.g., you may want -to run xconsole here). -The conventional name for a program used here is Xsetup. -See . - -Empty by default. - - - - - - - -This string is subject to word splitting. -It specifies a program which is run (as -root) after the user -authentication process succeeds. -The conventional name for a program used here is Xstartup. -See . - -Empty by default. - - - - - - - -This string is subject to word splitting. -It specifies a program which is run (as -root) after the session -terminates. -The conventional name for a program used here is Xreset. -See . - -Empty by default. - - - - - - - -This string is subject to word splitting. -It specifies the session program to be executed (as the user owning -the session). -The conventional name for a program used here is Xsession. -See . - -The default is ${x_bindir}/xterm -ls -T. - - - - - - - -If the program fails to execute, &tdm; will -fall back to this program. This program is executed with no arguments, -but executes using the same environment variables as the session would -have had (see ). - -The default is ${x_bindir}/xterm. - - - - - - - -The PATH environment variable for -non-root s. - -The default depends on the system &tdm; was built on. - - - - - - - - -The PATH environment variable for all programs but -non-root -s. Note that it is good practice not to include -. (the current directory) into this entry. - -The default depends on the system &tdm; was built on. - - - - - - - - -The SHELL environment variable for all programs but the -. - -The default is /bin/sh. - - - - - - - -When &tdm; is unable to write to the usual user authorization file -($HOME/.Xauthority), it creates a unique file name in this -directory and points the environment variable XAUTHORITY -at the created file. - -The default is /tmp. - - - - - - - -If enabled, &tdm; will automatically restart a session after an &X-Server; -crash (or if it is killed by Alt-Ctrl-BackSpace). Note that enabling this -feature opens a security hole: a secured display lock can be circumvented -(unless &kde;'s built-in screen locker is used). - -The default is false. - - - - - - - -If disabled, do not allow root -(and any other user with UID = 0) to log in directly. - -The default is true. - - - - - - - -If disabled, only users that have passwords assigned can log in. - -The default is true. - - - - - - - -Who is allowed to shut down the system. This applies both to the -greeter and to the command FiFo. - - - -None -no Shutdown... menu entry is shown at all - - -Root -the root password must be entered to shut down - - -All -everybody can shut down the machine - - -The default is All. - - - - - - - -Who is allowed to abort active sessions when shutting down. - - - -None -no forced shutdown is allowed at all - - -Root -the root password must be entered to shut down forcibly - - -All -everybody can shut down the machine forcibly - - -The default is All. - - - - - - - -The default choice for the shutdown condition/timing. - - - -Schedule -shut down after all active sessions exit (possibly at once) - - -TryNow -shut down, if no active sessions are open; otherwise, do nothing - - -ForceNow -shut down unconditionally - - -The default is Schedule. - - - - - - - -How to offer shutdown scheduling options: - - - -Never -not at all - - -Optional -as a button in the simple shutdown dialogs - - -Always -instead of the simple shutdown dialogs - - -The default is Never. - - - - - - - -Enable password-less logins on this display. Use with extreme care! - -The default is false. - - - - - - - -The users that do not need to provide a password to log in. -Items which are prefixed with @ represent all users in the -user group named by that item. -* means all users but -root -(and any other user with UID = 0). -Never list root. - -Empty by default. - - - - - - - -Enable automatic login. Use with extreme care! - -The default is false. - - - - - - - -If true, auto-login after logout. If false, auto-login is performed only -when a display session starts up. - -The default is false. - - - - - - - -The delay in seconds before automatic login kicks in. This is also known as -Timed Login. - - - - - - - - -The user to log in automatically. Never specify root! - -Empty by default. - - - - - - - -The password for the user to log in automatically. This is not required -unless the user is logged into a NIS or Kerberos domain. If you use this -option, you should chmod  tdmrc for obvious reasons. - -Empty by default. - - - - - - - -Immediately lock the automatically started session. This works only with -KDE sessions. - -The default is false. - - - - - - - -A list of directories containing session type definitions. - -The default is ${kde_datadir}/tdm/sessions. - - - - - - - -The file (relative to the user's home directory) to redirect the session -output to. One occurrence of %s in this string will be -substituted with the display name. Use %% to obtain a -literal %. - -The default is .xsession-errors. - - - - - - - -Specify whether &tdm;'s built-in utmp/wtmp/lastlog registration should -be used. If it is not, the tool sessreg should be used -in the and scripts, or, -alternatively, the pam_lastlog module should be used on -PAM-enabled systems. - -The default is true. - - - - - - - - -The [X-*-Greeter] section class of &tdmrc; - - -This section class contains options concerning the configuration -of the &tdm; frontend (greeter). - - - - - - - - -Specify the widget style for the greeter. Empty means to use the -built-in default which currently is Plastik. - -Empty by default. - - - - - - - -Specify the widget color scheme for the greeter. Empty means to use -the built-in default which currently is yellowish grey with some light -blue and yellow elements. - -Empty by default. - - - - - - - -What should be shown in the greeter righthand of the input lines (if - is disabled) or above them (if - is enabled): - - - -None -nothing - - -Logo -the image specified by - - -Clock -a neat analog clock - - -The default is Clock. - - - - - - - -The image to show in the greeter if is -Logo. - -Empty by default. - - - - - - - -The relative coordinates (percentages of the screen size; X,Y) at which -the center of the greeter is put. &tdm; aligns the greeter to the edges -of the screen it would cross otherwise. - -The default is 50,50. - - - - - - - -The screen the greeter should be displayed on in multi-headed and Xinerama -setups. The numbering starts with 0. For Xinerama, it corresponds to the -listing order in the active ServerLayout section of XF86Config; -1 means -to use the upper-left screen, -2 means to use the upper-right screen. - - - - - - - - -The headline in the greeter. An empty greeting means none at all. - -The following character pairs are replaced by their value: - - -%d -name of the current display - - -%h -local host name, possibly with the - domain name - - -%n -local node name, most probably the host name without the - domain name - - -%s -operating system - - -%r -operating system version - - -%m -machine (hardware) type - - -%% -a single % - - - -The default is Welcome to %s at %n. - - - - - - - -Whether the fonts used in the greeter should be antialiased. - -The default is false. - - - - - - - -The font for the greeter headline. - -The default is Serif,20,bold. - - - - - - - -The normal font used in the greeter. - -The default is Sans Serif,10. - - - - - - - -The font used for the Login Failed message. - -The default is Sans Serif,10,bold. - - - - - - - -What to do with the Num Lock modifier for the time the greeter is running: - - - -Off -turn off - - -On -turn on - - -Keep -do not change the state - - -The default is Keep. - - - - - - - -Language and locale to use in the greeter, encoded like $LC_LANG. - -The default is en_US. - - - - - - - -Enable autocompletion in the username line edit. - -The default is false. - - - - - - - -Show a user list with unix login names, real names, and images in the greeter. - -The default is true. - - - - - - - -This option controls which users will be shown in the user view -() and/or offered for autocompletion -(). -If it is Selected, contains -the final list of users. -If it is NotHidden, the initial user list contains all users -found on the system. Users contained in are -removed from the list, just like all users with a UID greater than specified -in and users with a non-zero UID less than -specified in . -Items in and -which are prefixed with @ represent all users in the -user group named by that item. -Finally, the user list will be sorted alphabetically, if - is enabled. - -The default is NotHidden. - - - - - - - -See . - -Empty by default. - - - - - - - -See . - -Empty by default. - - - - - - - -See . - - - - - - - - -See . - -The default is 65535. - - - - - - - -See . - -The default is true. - - - - - - - -If is enabled, this specifies where &tdm; gets the -images from: - - - -AdminOnly -from <>/$USER.face[.icon] - - -PreferAdmin -prefer <>, fallback on $HOME - - -PreferUser -... and the other way round - - -UserOnly -from the user's $HOME/.face[.icon] - - - - -The images can be in any format Qt recognizes, but the filename -must match &tdm;'s expectations: .face.icon should be a -48x48 icon, while .face should be a 300x300 image. -Currently the big image is used only as a fallback and is scaled down, -but in the future it might be displayed full-size in the logo area or a -tooltip. - -The default is AdminOnly. - - - - - - - -See . - -The default is ${kde_datadir}/tdm/faces. - - - - - - - -Specify, if/which user should be preselected for log in: - - - -None -do not preselect any user - - -Previous -the user which successfully logged in last time - - -Default -the user specified in the option - - - - -If is enabled and a user was preselected, -the cursor is placed in the password input field automatically. - -Enabling user preselection can be considered a security hole, -as it presents a valid login name to a potential attacker, so he -only needs to guess the password. On the other hand, -one could set to a fake login name. - - -The default is None. - - - - - - - -See . - -Empty by default. - - - - - - - -See . - -The default is false. - - - - - - - -The password input fields cloak the typed in text. Specify, how to do it: - - - -OneStar -* is shown for every typed -character - - -ThreeStars -*** is shown for every typed -character - - -NoEcho -nothing is shown at all, the cursor does not move - - -The default is OneStar. - - - - - - - -If enabled, &tdm; will automatically start the krootimage -program to set up the background; otherwise, the -program is responsible for the background. - -The default is true. - - - - - - - -The configuration file to be used by krootimage. -It contains a section named [Desktop0] like -kdesktoprc does. Its options are not described -herein; guess their meanings or use the control center. - -The default is ${kde_confdir}/tdm/backgroundrc. - - - - - - - -To improve security, the greeter grabs the &X-Server; and then the keyboard -when it starts up. This option specifies if the &X-Server; grab should be held -for the duration of the name/password reading. When disabled, the &X-Server; -is ungrabbed after the keyboard grab succeeds; otherwise, the &X-Server; is -grabbed until just before the session begins. - -Enabling this option disables and -. - - -The default is false. - - - - - - - -This option specifies the maximum time &tdm; will wait for the grabs to -succeed. A grab may fail if some other X-client has the &X-Server; or the -keyboard grabbed, or possibly if the network latencies are very high. You -should be cautious when raising the timeout, as a user can be spoofed by -a look-alike window on the display. If a grab fails, &tdm; kills and -restarts the &X-Server; (if possible) and the session. - -The default is 3. - - - - - - - -Warn, if a display has no X-authorization. This will be the case if - - - the authorization file for a local &X-Server; could not be created, - - - a remote display from &XDMCP; did not request any authorization or - - - the display is a foreign display specified in - . - - - -The default is true. - - - - - - - -Specify whether the greeter of local displays should start up in host chooser -(remote) or login (local) mode and whether it is allowed to switch to the -other mode. - - - -LocalOnly -only local login possible - - -DefaultLocal -start up in local mode, but allow switching to remote mode - - -DefaultRemote -... and the other way round - - -RemoteOnly -only choice of remote host possible - - -The default is LocalOnly. - - - - - - - -A list of hosts to be automatically added to the remote login menu. -The special name * means broadcast. -Has no effect if is LocalOnly. - -The default is *. - - - - - - - -Use this number as a random seed when forging saved session types, etc. of -unknown users. This is used to avoid telling an attacker about existing users -by reverse conclusion. This value should be random but constant across the -login domain. - - - - - - - - -Enable &tdm;'s built-in xconsole. -Note that this can be enabled for only one display at a time. -This option is available only if &tdm; was configured -with . - -The default is false. - - - - - - - -The data source for &tdm;'s built-in xconsole. -If empty, a console log redirection is requested from -/dev/console. -Has no effect if is disabled. - -Empty by default. - - - - - - - -Specify conversation plugins for the login dialog; the first in the list -is selected initially. -Each plugin can be specified as a base name (which expands to -$kde_modulesdir/kgreet_base) -or as a full pathname. - -Conversation plugins are modules for the greeter which obtain authentication -data from the user. Currently only the classic plugin is -shipped with &kde;; it presents the well-known username and password form. - -The default is classic. - - - - - - - -Same as , but for the shutdown dialog. - -The default is classic. - - - - - - - -A list of options of the form -Key=Value. -The conversation plugins can query these settings; it is up to them what -possible keys are. - -Empty by default. - - - - - - - -Show the Console Login action in the greeter (if / -is configured). - -The default is true. - - - - - - - -Show the Restart X Server/Close Connection action in the greeter. - -The default is true. - - - - - - - -A program to run while the greeter is visible. It is supposed to preload -as much as possible of the session that is going to be started (most -probably). - -Empty by default. - - - - - - - -Whether the greeter should be themed. - -The default is false. - - - - - - - -The theme to use for the greeter. Can point to either a directory or an XML -file. - -Empty by default. - - - - - - - - - - - -Specifying permanent &X-Server;s - -Each entry in the list indicates a -display which should constantly be -managed and which is not using &XDMCP;. This method is typically used only for -local &X-Server;s that are started by &tdm;, but &tdm; can manage externally -started (foreign) &X-Server;s as well, may they run on the -local machine or rather remotely. - -The formal syntax of a specification is - -display name [_display class] - -for all &X-Server;s. Foreign displays differ in having -a host name in the display name, may it be localhost. - -The display name must be something that can -be passed in the option to an X program. This string -is used to generate the display-specific section names, so be careful to match -the names. -The display name of &XDMCP; displays is derived from the display's address by -reverse host name resolution. For configuration purposes, the -localhost prefix from locally running &XDMCP; displays is -not stripped to make them distinguishable from local -&X-Server;s started by &tdm;. - -The display class portion is also used in the -display-specific sections. This is useful if you have a large collection of -similar displays (such as a corral of X terminals) and would like to set -options for groups of them. -When using &XDMCP;, the display is required to specify the display class, -so the manual for your particular X terminal should document the display -class string for your device. If it does not, you can run &tdm; in debug -mode and grep the log for class. - -The displays specified in will not be -started when &tdm; starts up, but when it is explicitly requested via -the command socket (or FiFo). -If reserve displays are specified, the &kde; menu will have a -Start New Session item near the bottom; use that to -activate a reserve display with a new login session. The monitor will switch -to the new display, and you will have a minute to login. If there are no more -reserve displays available, the menu item will be disabled. - -When &tdm; starts a session, it sets up authorization data for the -&X-Server;. For local servers, &tdm; passes - filename -on the &X-Server;'s command line to point it at its authorization data. -For &XDMCP; displays, &tdm; passes the authorization data to the &X-Server; -via the Accept &XDMCP; message. - - - - -&XDMCP; access control - -The file specified by the option provides -information which &tdm; uses to control access from displays requesting service -via &XDMCP;. -The file contains four types of entries: entries which control the response -to Direct and Broadcast queries, entries which -control the response to Indirect queries, macro definitions for -Indirect entries, and entries which control on which network -interfaces &tdm; listens for &XDMCP; queries. -Blank lines are ignored, # is treated as a comment -delimiter causing the rest of that line to be ignored, and \ -causes an immediately following newline to be ignored, allowing indirect host -lists to span multiple lines. - - -The format of the Direct entries is simple, either a -host name or a pattern, which is compared against the host name of the display -device. -Patterns are distinguished from host names by the inclusion of one or more -meta characters; * matches any sequence of 0 or more -characters, and ? matches any single character. -If the entry is a host name, all comparisons are done using network addresses, -so any name which converts to the correct network address may be used. Note -that only the first network address returned for a host name is used. -For patterns, only canonical host names are used in the comparison, so ensure -that you do not attempt to match aliases. -Host names from &XDMCP; queries always contain the local domain name -even if the reverse lookup returns a short name, so you can use -patterns for the local domain. -Preceding the entry with a ! character causes hosts which -match that entry to be excluded. -To only respond to Direct queries for a host or pattern, -it can be followed by the optional NOBROADCAST keyword. -This can be used to prevent a &tdm; server from appearing on menus based on -Broadcast queries. - -An Indirect entry also contains a host name or pattern, -but follows it with a list of host names or macros to which the queries -should be forwarded. Indirect entries can be excluding as well, -in which case a (valid) dummy host name must be supplied to make the entry -distinguishable from a Direct entry. -If compiled with IPv6 support, multicast address groups may also be included -in the list of addresses the queries are forwarded to. - -If the indirect host list contains the keyword CHOOSER, -Indirect queries are not forwarded, but instead a host chooser -dialog is displayed by &tdm;. The chooser will send a Direct -query to each of the remaining host names in the list and offer a menu of -all the hosts that respond. The host list may contain the keyword -BROADCAST, to make the chooser send a -Broadcast query as well; note that on some operating systems, -UDP packets cannot be broadcast, so this feature will not work. - - -When checking access for a particular display host, each entry is scanned -in turn and the first matching entry determines the response. -Direct and Broadcast entries are ignored when -scanning for an Indirect entry and vice-versa. - -A macro definition contains a macro name and a list of host names and -other macros that the macro expands to. To distinguish macros from hostnames, -macro names start with a % character. - -The last entry type is the LISTEN directive. -The formal syntax is - - LISTEN [interface [multicast list]] - -If one or more LISTEN lines are specified, &tdm; listens -for &XDMCP; requests only on the specified interfaces. -interface may be a hostname or IP address -representing a network interface on this machine, or the wildcard -* to represent all available network interfaces. -If multicast group addresses are listed on a LISTEN line, -&tdm; joins the multicast groups on the given interface. For IPv6 multicasts, -the IANA has assigned ff0X:0:0:0:0:0:0:12b as the -permanently assigned range of multicast addresses for &XDMCP;. The -X in the prefix may be replaced by any valid scope -identifier, such as 1 for Node-Local, 2 for Link-Local, 5 for Site-Local, and -so on (see IETF RFC 2373 or its replacement for further details and scope -definitions). &tdm; defaults to listening on the Link-Local scope address -ff02:0:0:0:0:0:0:12b to most closely match the IPv4 subnet broadcast behavior. -If no LISTEN lines are given, &tdm; listens on all -interfaces and joins the default &XDMCP; IPv6 multicast group (when -compiled with IPv6 support). -To disable listening for &XDMCP; requests altogether, a -LISTEN line with no addresses may be specified, but using -the [Xdmcp] option is preferred. - - - - - -Supplementary programs - - -The following programs are run by &tdm; at various stages of a session. -They typically are shell scripts. - - - -The Setup, Startup and Reset programs are run as -root, so they should be careful -about security. -Their first argument is auto if the session results -from an automatic login; otherwise, no arguments are passed to them. - - - -Setup program - - -The Xsetup program is run after the &X-Server; is -started or reset, but before the greeter is offered. -This is the place to change the root background (if - is disabled) or bring up other windows that -should appear on the screen along with the greeter. - - - -In addition to any specified by , -the following environment variables are passed: - - - DISPLAY - the associated display name - - - PATH - the value of - - - SHELL - the value of - - - XAUTHORITY - may be set to an authority file - - - DM_CONTROL - the value of - - - - Note that since &tdm; grabs the keyboard, any other windows will not be -able to receive keyboard input. They will be able to interact with the mouse, -however; beware of potential security holes here. If -is set, Xsetup will not be able to connect to the display -at all. Resources for this program can be put into the file named by -. - - - - - -Startup program - -The Xstartup program is run as -root when the user logs in. -This is the place to put commands which add entries to -utmp (the sessreg program -may be useful here), mount users' home directories from file servers, -or abort the session if some requirements are not met (but note that on -modern systems, many of these tasks are already taken care of by -PAM modules). - -In addition to any specified by , -the following environment variables are passed: - - - DISPLAY - the associated display name - - - HOME - the initial working directory of the user - - - LOGNAME - the username - - - USER - the username - - - PATH - the value of - - - SHELL - the value of - - - XAUTHORITY - may be set to an authority file - - - DM_CONTROL - the value of - - - -&tdm; waits until this program exits before starting the user session. -If the exit value of this program is non-zero, &tdm; discontinues the session -and starts another authentication cycle. - - - - -Session program - -The Xsession program is the command which is run -as the user's session. It is run with the permissions of the authorized user. -One of the keywords failsafe, default -or custom, or a string to eval by a -Bourne-compatible shell is passed as the first argument. - -In addition to any specified by , -the following environment variables are passed: - - - DISPLAY - the associated display name - - - HOME - the initial working directory of the user - - - LOGNAME - the username - - - USER - the username - - - PATH - the value of - (or for - root user sessions) - - - - SHELL - the user's default shell - - - XAUTHORITY - may be set to a non-standard authority file - - - KRBTKFILE - may be set to a Kerberos4 credentials cache name - - - - KRB5CCNAME - may be set to a Kerberos5 credentials cache name - - - - DM_CONTROL - the value of - - - XDM_MANAGED - will contain a comma-separated list of parameters the - session might find interesting, like the location of the command - FiFo and its capabilities, and which conversation - plugin was used for the login - - - - DESKTOP_SESSION - the name of the session the user has chosen to run - - - - - - - -Reset program - -Symmetrical with Xstartup, the -Xreset program is run after the user session has -terminated. Run as root, it should -contain commands that undo the effects of commands in -Xstartup, removing entries from utmp -or unmounting directories from file servers. - -The environment variables that were passed to -Xstartup are also passed to Xreset. - - - - - - - diff --git a/doc/tdm/CMakeLists.txt b/doc/tdm/CMakeLists.txt new file mode 100644 index 000000000..9a29fa8f8 --- /dev/null +++ b/doc/tdm/CMakeLists.txt @@ -0,0 +1,12 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +tde_create_handbook( DESTINATION tdm ) diff --git a/doc/tdm/Makefile.am b/doc/tdm/Makefile.am new file mode 100644 index 000000000..3db537e3f --- /dev/null +++ b/doc/tdm/Makefile.am @@ -0,0 +1,6 @@ +conf_def = $(top_srcdir)/tdm/config.def +ref: $(conf_def) $(top_srcdir)/tdm/confproc.pl + $(PERL) -w $(top_srcdir)/tdm/confproc.pl --doc $(conf_def) tdmrc-ref.docbook + +KDE_LANG = en +KDE_DOCS = AUTO diff --git a/doc/tdm/index.docbook b/doc/tdm/index.docbook new file mode 100644 index 000000000..dde535328 --- /dev/null +++ b/doc/tdm/index.docbook @@ -0,0 +1,1472 @@ + + + + tdmrc"> + ksmserver"> + kdesktop"> + XDMCP"> + xdm"> + + + +]> + + + +The &tdm; Handbook + + + +&Oswald.Buddenhagen; &Oswald.Buddenhagen.mail; + + + + + + + +2000 +&Neal.Crook; + + + +2002 +&Oswald.Buddenhagen; + + + +2003 +&Lauri.Watts; + + +2003-03-01 +0.05.02 + + +This document describes &tdm; the &kde; Display Manager. &tdm; +is also known as the Login Manager. + + + +KDE +tdm +xdm +display manager +login manager + + + + + +Introduction + +&tdm; provides a graphical interface that allows you to log in to a +system. It prompts for login (username) and password, authenticates the user +and starts a session. &tdm; is superior to &xdm;, the X +Display Manager, in a number of ways. + + + + + + + +Quick Start Guide + +This is a quick start guide for users who fit the following +pattern: + + + +X is configured and works with the command +startx from the commandline. + + +Each user will generally only use a single window manager or +desktop environment, and does not change this choice very +often, or is comfortable editing a single text file in order to change +their choice. + + + +This scenario will be sufficient for many environments where a single +user or several users normally boot the computer and log into their +preferred environment. + + +Setting up a Default Session + +Create or open the file ~/.xinitrc +If you already have a working ~/.xinitrc, go to +the next step + + +If one does not already exist, add a line to the +~/.xinitrc to start your preferred window manager +or desktop environment. +For &kde; you should enter: +starttde +For other window managers or desktop environments, you should +look in their documentation for the correct command. + +Make a link as follows: +ln ~/.xinitrc ~/.xsession + + + +At this point, typing startx +on the commandline should start X, with a &kde; session. The next task is +to try &tdm;. + +As root, type +tdm at the prompt. + +You should see a login window, which is described more fully in . + +Typing your normal username and password in the fields provided, and +leaving selected as the session type should now +open a &kde; session for your user. + +If you have other users to configure, you should repeat the procedure +above for each of them. + + +This is a quick guide to getting up and running only. You probably +will want to customize &tdm; further, for example, to hide the names of the +system accounts, to allow further sessions, and much more. Please read +through the rest of this manual to find out how to do these things. + + + + + +The Login Window + + The user interface to &tdm; consists of two dialog boxes. The main +dialog box has these controls: + + + +A Username: field for you to enter your +username. + + + +A Password: field for you to enter your +password. + + + +(Optionally) a graphical image of each user (for example, a digitized +photograph). Clicking on an image is equivalent to typing the associated +username into the Username: field. (This feature is an +imitation of the login box on &IRIX;). + + + +A Menu drop down box that allows &tdm; to be used +to start sessions with various different window managers or desktop +environments installed on the system. + + + +(Optionally) a region to the right of the +Username:, Password: and +Session Type: fields which can be used to display +either a static image or an analog clock. + + + +A Login button that validates the +username/password combination and attempts to start a session of the +selected type. + + + +A Clear button that clears the text from +the Login and Pass +fields. + + + +A Menu button that opens an action menu +with the following items: + + + +(On local displays) A Restart X Server item +that terminates the currently running &X-Server;, starts a new one and +displays the login dialog again. You can use this if the display content +seems to be broken somehow. + + + +(On remote displays) A Close Connection +item that closes the connection to the &XDMCP; server you are currently +connected to. If you got to this server through a host chooser, this will +bring you back to the chooser, otherwise it will only reset the &X-Server; +and bring up the login dialog again. + + + +(Optionally on local displays) A Console +Mode item that terminates the currently running &X-Server; and +leaves you alone with a console login. &tdm; will resume the graphical login +if nobody is logged in at the console for some time. + + + + + +(Optionally) A Shutdown button that displays +the Shutdown dialog box. + + + +The Shutdown dialog box presents a set of +radio buttons that allow one of these options to be selected: + + + +Shutdown + +Shut the system down in a controlled manner, ready for +power-down. + + + +Restart + +Shut the system down and reboot. For systems that use +Lilo, an optional drop down box allows you to +select a particular operating-system kernel to be used for the +reboot. + + + +Restart X Server + +Stop and then restart the X-server. Typically, you might need to use +this option if you have changed your X11 configuration in some way. + + + +Console Mode + +Stop the &X-Server; and return the system to console mode. This is +achieved by bringing the system down to runlevel 3. Typically, the system +manager might need to use this option before upgrading or re-configuring X11 +software. + + + + +Pressing the OK button initiates the selected +action; pressing the Cancel button returns to the +main &tdm; dialog box. + + + + + +Configuring &tdm; + +This chapter assumes that &tdm; is already up and running on your +system, and that you simply want to change its behavior in some way. + +When &tdm; starts up, it reads its configuration from the folder +$TDEDIR/share/config/tdm/ (this may +be /etc/trinity/tdm/ or something else +on your system). + +The main configuration file is &tdmrc;; all other files are +referenced from there and could be stored under any name anywhere on +the system - but usually that would not make much sense for obvious +reasons (one particular exception is referencing configuration files +of an already installed &xdm; - however when a new &tdm; is installed, +it will import settings from those files if it finds an already installed +&xdm;). + +Since &tdm; must run before any user is logged in, it is not +associated with any particular user. Therefore, it is not possible to have +user-specific configuration files; all users share the common &tdmrc;. It +follows from this that the configuration of &tdm; can only be altered by +those users that have write access to +$TDEDIR/share/config/tdm/tdmrc (normally +restricted to system administrators logged in as root). + +You can view the &tdmrc; file currently in use on your system, and you +can configure &tdm; by editing this file. Alternatively, you can use the +graphical configuration tool provided by the &kcontrolcenter; (under +System AdministrationLogin +Manager), which is described in the &kcontrolcenter; help files. + + +The remainder of this chapter describes configuration of &tdm; +via the &kcontrolcenter; module, and the next +chapter describes the options available in &tdmrc; itself. If +you only need to configure for local users, the &kcontrolcenter; module +should be sufficient for your needs. If you need to configure remote +logins, or have multiple &tdm; sessions running, you will need to read +on. + + + + +&Thomas.Tanghus; &Thomas.Tanghus.mail; +&Steffen.Hansen; &Steffen.Hansen.mail; +&Mike.McBride; &Mike.McBride.mail; + + + +The Login Manager &kcontrolcenter; Module + +Using this module, you can configure the &kde; graphical login +manager, &tdm;. You can change how the login screen looks, who has +access using the login manager and who can shutdown the +computer. + +All settings will be written to the configuration file +&tdmrc;, which in its original state has many comments to help you +configure &tdm;. Using this &kcontrolcenter; module will strip these +comments from the file. All available options in &tdmrc; are covered +in . + +The options listed in this chapter are cross referenced with +their equivalents in &tdmrc;. All options available in the &kcontrol; +module are also available directly in &tdmrc; but the reverse is not +true. + +In order to organize all of these options, this module is +divided into several sections: Appearance, +Font, Background, +Shutdown, +Users and +Convenience. + +You can switch between the sections using the tabs at the top of +the window. + +If you are not currently logged in as a superuser, you +will need to click the Administrator Mode... +Button. You will then be asked for a superuser password. Entering a +correct password will allow you to modify the settings of this +module. + + +Appearance + +From this page you can change the visual appearance of &tdm;, +&kde;'s graphical login manager. + +The Greeting: is the title of the login + screen. Setting this is especially useful if you have many servers users + may log in to. You may use various placeholders, which are described + along with the corresponding key + + in &tdmrc;. + + +You can then choose to show either the current system time, a logo or +nothing special in the login box. Make your choice in the radio buttons +labeled Logo area:. This corresponds to in &tdmrc; + +If you chose Show logo you can now choose a +logo: + + + +Drop an image file on the image button. + + +Click on the image button and select a new image from the image chooser +dialog. + + + +If you do not specify a logo the default +$TDEDIR/share/apps/tdm/pics/kdelogo.xpm +will be displayed. + +Normally the login box is centered on the screen. Use the +Position: options if you want it to appear +elsewhere on the screen. You can specify the relative position +(percentage of the screen size) for the center of the login window, +relative to the top left of the display, in the fields labeled +X: and Y: respectively. +These correspond to the key + +in &tdmrc;. + +While &kde;'s style depends on the settings of the user logged +in, the style used by &tdm; can be configured using the GUI +Style: and Color Scheme: options. +These correspond to the keys and in +&tdmrc; respectively. + +Below that, you have a drop down box to choose the language for +your login box, corresponding to setting in +&tdmrc;. + + + + +Font + +From this section of the module you can change the fonts used in the +login window. Only fonts available to all users are available here, not +fonts you have installed on a per user basis. + +You can select three different font styles from the drop down box +(General:, Failures:, +Greeting:). When you click on the +Choose... button a dialog appears from which you can +select the new characteristics for the font style. + + + +The General: font is used in all other places in the +login window. + + +The Failures: font is used when a login +fails. + + +The Greeting: font is the font used for the title +(Greeting String). + + + +You can also check the box labeled Use anti-aliasing for +fonts if you want smoothed fonts in the login dialog. + + + + +Background + +Here you can change the desktop background which will be displayed +before a user logs in. You can have a single color or an image as a +background. If you have an image as the background and select center, the +selected background color will be used around the image if it is not +large enough to cover the entire desktop. + +The background colors and effects are controlled by the options on +the tab labeled Background and you select a +background image and its placement from the options on the tab labeled +Wallpaper. + +To change the default background color(s) simply click either of +the color buttons and select a new color. + +The drop down box above the color buttons provides you with several +different blend effects. Choose one from the list, and it will be +previewed on the small monitor at the top of the window. Your choices +are: + + + +Flat +By choosing this mode, you select one color (using the color +button labeled Color 1), and the entire background is +covered with this one color. + + +Pattern +By choosing this mode, you select two colors (using both color +buttons). You then select a pattern by clicking +Setup. This opens a new dialog window, which gives you +the opportunity to select a pattern. Simply click once on the pattern of your +choice, then click on OK, and &kde; will render the pattern +you selected using the two colors you selected. For more on patterns, see the +section Background: Adding, Removing and Modifying +Patterns. + + +Background Program +By selecting this option, you can have &kde; use an external +program to determine the background. This can be any program of your choosing. +For more information on this option, see the section entitled Background: Using an external program. + + +Horizontal Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the color selected by Color +1 on the left edge of the screen, and slowly transform into the +color selected by Color 2 by the time it gets to the +right edge of the screen. + + +Vertical Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the color selected by Color +1 on the top edge of the screen, and slowly transform into the color +selected by Color 2 as it moves to the bottom of the +screen. + + +Pyramid Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the color selected by Color +1 in each corner of the screen, and slowly transform into the color +selected by Color 2 as it moves to the center of the +screen. + + +Pipecross Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the color selected by Color +1 in each corner of the screen, and slowly transform into the color +selected by Color 2 as it moves to the center of the +screen. The shape of this gradient is different then the pyramid +gradient. + + +Elliptic Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the color selected by Color +2 in the center of the screen, and slowly transform into the color +selected by Color 1 as it moves to the edges, in an +elliptical pattern. + + + +The setup button is only needed for if you select Background +program or Patterns. In these instances, +another window will appear to configure the specifics. +Wallpaper +To select a new background image first, click on the +Wallpapers tab, then you can either select an image from the drop down list labeled Wallpaper or select +Browse... and select an image file from a file +selector. + +The image can be displayed in six different ways: + + +No wallpaper +No image is displayed. Just the background colors. + + +Centered +The image will be centered on the screen. The background colors +will be present anywhere the image does not cover. + + +Tiled +The image will be duplicated until it fills the entire +desktop. The first image will be placed in the upper left corner of the screen, +and duplicated downward and to the right. + + +Center Tiled +The image will be duplicated until it fills the entire +desktop. The first image will be placed in the center of the screen, and +duplicated upward, downward to the right, and to the left. + + +Centered Maxpect +The image will be placed in the center of the screen. It will +be scaled to fit the desktop, but it will not change the aspect ratio of the +original image. This will provide you with an image that is not distorted. + + + +Scaled +The image will be scaled to fit the desktop. It will be +stretched to fit all four corners. + + + + + + +<guilabel>Shutdown</guilabel> + +Allow Shutdown +Use this drop down box to choose who is allowed to shut down: + + +Nobody: No one can shutdown the computer using +&tdm;. You must be logged in, and execute a command. + + +Everybody: Everyone can shutdown the computer using +&tdm;. + +Only Root: &tdm; requires that the +root password be entered before shutting down the +computer. + + +You can independently configure who is allowed to issue a +shutdown command for the Local: and +Remote: users. + +Commands Use these text fields to +define the exact shutdown command. The +Halt: command defaults to +/sbin/halt. The Restart: command +defaults to +/sbin/reboot. + +When Show boot options is enabled, &tdm; +will on reboot offer you options for the lilo boot manager. For this +feature to work, you will need to supply the correct paths to your +lilo command and to lilo's map file. Note that this +option is not available on all operating systems. + + + + +Users + +From here you can change the way users are represented in the +login window. + +You may disable the user list in &tdm; entirely in the +Show Users section. You can choose from: + + + +Show List + +Only show users you have specifically enabled in the list +alongside +If you do not check this box, no list will be shown. This is the most secure setting, since an +attacker would then have to guess a valid login name as well as a +password. It's also the preferred option if you have more than a +handful of users to list, or the list itself would become +unwieldy. + + + +Inverse selection + +Allows you to intead select a list of users that should +not be shown, and all other users will be +listed. + + + + +Independently of the users you specify by name, you can use the +System UIDs to specify a range of valid +UIDs that are shown in the list. By default user +id's under 1000, which are often system or daemon users, and user id's +over 65000, are not shown. + +You can also enable the Sort users +checkbox, to have the user list sorted alphabetically. If this is +disabled, users will appear in the order they are listed in the +password file. &tdm; will also autocomplete user names if you enable the +Autocompletion option. + +If you choose to show users, then the login window will show +images (which you select), of a list of users. When someone is ready +to login, they may select their user name/image, enter their password, +and they are granted access. + +If you permit a user image, then you can configure the source +for those images. + +You can configure the admin picture here, for each user on the +system. Depending on the order selected above, users may be able to +override your selection. + +If you choose not to show users, then the login window will be +more traditional. Users will need to type their username and password +to gain entrance. This is the preferred way if you have many users on +this terminal. + + + + +Convenience + +In the convenience tab you can configure +some options that make life easier for lazy people, like automatic +login or disabling passwords. + +Please think more than twice before using these +options. Every option in the Convenience tab is +well-suited to seriously compromise your system security. Practically, +these options are only to be used in a completely non-critical +environment, ⪚ a private computer at home. + + +Automatic Login + +Automatic login will give anyone access to a certain account on +your system without doing any authentication. You can enable it using +the option Enable Auto-login. + +You can choose the account to be used for automatic login from +the list labeled User:. + + + + +<guilabel>Password-Less Login</guilabel> + +Using this feature, you can allow certain users to login without +having to provide their password. Enable this feature using the +Enable Password-less logins option. + +Below this option you'll see a list of users on the system. +Enable password-less login for specific users by checking the checkbox +next to the login names. By default, this feature is disabled for +all users. + +Again, this option should only be used in a safe +environment. If you enable it on a rather public system you should +take care that only users with heavy access restrictions are granted +password-less login, ⪚ +guest. + +You can also choose which user is preselected +when &tdm; starts. The default is None, but you +can choose Previous to have &tdm; default to the +last successfully logged in user, or you can +Specify a particular user to always be selected +from the list. You can also have &tdm; set the focus to the password +field, so that when you reach the &tdm; login screen, you can type the +password immediately. + +The Automatically login after X server crash +option allows you to skip the authentication procedure when your X +server accidentally crashed. + + + + + + + + + +&tdmrc-ref; + + + +Configuring your system to use &tdm; + +This chapter assumes that your system is already configured to +run the &X-Window;, and that you only need to reconfigure it to +allow graphical login. + + +Setting up &tdm; + +The fundamental thing that controls whether your computer boots to a +terminal prompt (console mode) or a graphical login prompt is the default +runlevel. The runlevel is set by the program /sbin/init under the control of the +configuration file /etc/inittab. The default runlevels +used by different &UNIX; systems (and different &Linux; distributions) vary, +but if you look at /etc/inittab the start of it should +be something like this: + +# Default runlevel. The runlevels used by RHS are: +# 0 - halt (Do NOT set initdefault to this) +# 1 - Single user mode +# 2 - Multiuser, without NFS +# 3 - Full multiuser mode +# 4 - unused +# 5 - X11 +# 6 - reboot (Do NOT set initdefault to this) + +id:3:initdefault: + + +All but the last line of this extract are comments. The comments +show that runlevel 5 is used for X11 and that runlevel 3 is used for +multi-user mode without X11 (console mode). The final line specifies +that the default runlevel of the system is 3 (console mode). If your +system currently uses graphical login (for example, using &xdm;) its +default runlevel will match the runlevel specified for X11. + +The runlevel with graphical login (&xdm;) for some common &Linux; +distributions is: + + +5 for &RedHat; 3.x and later, and for &Mandrake; +4 for Slackware +3 for &SuSE;. 4.x and 5.x + + +The first step in configuring your system is to ensure that you +can start &tdm; from the command line. Once this is working, you can +change your system configuration so that &tdm; starts automatically +each time you reboot your system. + +To test &tdm;, you must first bring your system to a runlevel +that does not run &xdm;. To do so, issue a command like this: + +/sbin/init + +Instead of the number you should specify the +appropriate runlevel for console mode on your system. + +If your system uses Pluggable Authentication Modules +(PAM), which is normal with recent &Linux; and &Solaris; +systems, you should check that your PAM configuration permits +login through the service named kde. If you previously used +&xdm; successfully, you should not need to make any +changes to your PAM configuration in order to use +&tdm;. /etc/pam.conf or +/etc/pam.d/kde. Information on configuring +PAM is beyond the scope of this handbook, but +PAM comes with comprehensive documentation (try looking in +/usr/share/doc/*pam*/html/). + +Now it's time for you to test &tdm; by issuing the following +command: + +tdm + + +If you get a &tdm; login dialog and you are able to log in, +things are going well. The main thing that can go wrong here is that +the run-time linker might not find the shared &Qt; or &kde; libraries. +If you have a binary distribution of the &kde; libraries, make sure +&tdm; is installed where the libraries believe &kde; is installed and +try setting some environment variables to point to your &kde; and &Qt; +libraries. + +For example: + +export + +export + +export + +export + + + +If you are still unsuccessful, try starting &xdm; instead, to +make sure that you are not suffering from a more serious X +configuration problem. + +When you are able to start &tdm; successfully, you can start to +replace &xdm; by &tdm;. Again, this is distribution-dependent. + + + +For &RedHat;, edit /etc/inittab, look for this + line: +x:5:respawn:/usr/X11/bin/xdm -nodaemon +and replace with: +x:5:respawn:/opt/kde/bin/tdm +This tells init(8) to respawn &tdm; when the +system is in run level 5. Note that &tdm; does not need the + option. + + +For &Mandrake;, the X11 runlevel in +/etc/inittab invokes the shell script +/etc/X11/prefdm, which is set up to select from +amongst several display managers, including &tdm;. Make sure that all +the paths are correct for your installation. + + +For &SuSE;, edit /sbin/init.d/xdm to add a +first line: + +. /etc/rc.config +DISPLAYMANAGER=tdm +export DISPLAYMANAGER + +For FreeBSD, edit /etc/ttys and find +the line like this: +ttyv8 "/usr/X11R6/bin/xdm -nodaemon" xterm off secure +and edit it to this: +ttyv8 "/usr/local/bin/tdm" xterm on secure + + +Most other distributions are a variation of one of +these. + + +At this stage, you can test &tdm; again by bringing your system +to the runlevel that should now run &tdm;. To do so, issue a command +like this: + +/sbin/init + + +Instead of the number you should specify the +appropriate runlevel for running X11 on your system. + +The final step is to edit the initdefault +entry in /etc/inittab to specify the appropriate +runlevel for X11. + +Before you make this change, ensure that you have a way +to reboot your system if a problem occurs. This might be a +rescue floppy-disk provided by your operating system +distribution or a specially-designed rescue +floppy-disk, such as tomsrtbt. Ignore this advice +at your peril. + +This usually involves changing the line: +id:3:initdefault: +to +id:5:initdefault: + +When you reboot your system, you should end up with the +graphical &tdm; login dialog. + +If this step is unsuccessful the most likely problem is that the +environment used at boot time differs from the environment that you used for +testing at the command line. If you are trying to get two versions of &kde; +to co-exist, be particularly careful that the settings you use for your +PATH and LD_LIBRARY_PATH environment variables +are consistent, and that the startup scripts are not over-riding them in +some way. + + + + + + +Supporting multiple window managers + +&tdm; detects most available window manager and desktop environments when +it is run. Installing a new one should make it automatically available in +the &tdm; main dialog Session Type:. + +If you have a very new window manager, or something that &tdm; does +not support, the first thing you should check is that the application to be +run is in the PATH and has not been renamed during the +install into something unexpected. + +If the case is that the application is too new and not yet supported +by &tdm;, you can quite simply add a new session. + +The sessions are defined in .desktop files in +$TDEDIR/share/apps/tdm/sessions. +You can simply add an appropriately named .desktop file in this directory. The fields +are: + +[Desktop Entry] +Encoding=UTF-8 This is fixed to and +may be omitted +Type=XSession This is fixed to and +may be omitted +Exec=executable name Passed to +eval exec in a Bourne shell +TryExec=executable name Supported +but not required +Name=name to show in the &tdm; session list + +There are also three magic: + + + +default + + +The default session for &tdm; is normally &kde; but can be configured by the +system administrator. + + + + +custom + + +The Custom session will run the users ~/.xsession if it exists. + + + + +failsafe + + +Failsafe will run a very plain session, and is useful only for debugging +purposes. + + + + + +To override a session type, copy the .desktop file from the data dir +to the config dir and edit it at will. Removing the shipped session types +can be accomplished by shadowing them with .desktop files +containing Hidden=true. For the magic session types no .desktop files exist +by default, but &tdm; pretends they would, so you can override them like any +other type. I guess you already know how to add a new session type by +now. ;-) + + + + +Using &tdm; for Remote Logins (&XDMCP;) + +&XDMCP; is the Open Group standard, the X Display Manager +Control Protocol. This is used to set up connections between +remote systems over the network. + +&XDMCP; is useful in multiuser situations where there are users +with workstations and a more powerful server that can provide the +resources to run multiple X sessions. For example, &XDMCP; is a good +way to reuse old computers - a Pentium or even 486 computer with 16 Mb +RAM is sufficient to run X itself, and using &XDMCP; such a computer can +run a full modern &kde; session from a server. For the server part, +once a single &kde; (or other environment) session is running, running +another one requires very few extra resources. + +However, allowing another method of login to your machine +obviously has security implications. You should run this service only +if you need to allow remote X Servers to start login sessions on your +system. Users with a single &UNIX; computer should not need to run +this. + + + + +Advanced Topics + + +Command Sockets + +This is a feature you can use to remote-control &tdm;. It's mostly +intended for use by &ksmserver; and &kdesktop; from a running session, but +other applications are possible as well. + +The sockets are &UNIX; domain sockets which live in subdirectories of the +directory specified by =. The subdir is the key to +addressing and security; the sockets all have the file name +socket and file permissions +rw-rw-rw- (0666). This is because some systems don't care +for the file permission of the socket files. + +There are two types of sockets: the global one (dmctl) and the +per-display ones (dmctl-<display>). + +The global one's subdir is owned by root, the subdirs of the per-display +ones' are owned by the user currently owning the session (root or the +logged in user). Group ownership of the subdirs can be set via FifoGroup=, +otherwise it is root. The file permissions of the subdirs are rwxr-x--- +(0750). + +The fields of a command are separated by tabs (\t), the +fields of a list are separated by spaces, literal spaces in list fields are +denoted by \s. + +The command is terminated by a newline (\n). + +The same applies to replies. The reply on success is +ok, possibly followed by the requested +information. The reply on error is an errno-style word (⪚ +perm, noent, &etc;) +followed by a longer explanation. + + +Global commands: + +login +(now | schedule) user password +[session_arguments] + +login user at specified display. if now is +specified, a possibly running session is killed, otherwise the login is done +after the session exits. session_arguments are printf-like escaped contents +for .dmrc. Unlisted keys will default to previously saved values. + + + + + +Per-display commands: + +lock + +The display is marked as locked. If the &X-Server; crashes in this +state, no auto-relogin will be performed even if the option is on. + + + +unlock + +Reverse the effect of lock, and re-enable +auto-relogin. + + + +suicide + +The currently running session is forcibly terminated. No auto-relogin +is attempted, but a scheduled "login" command will be executed. + + + + + +Commands for all sockets + +caps + +Returns a list of this socket's capabilities: + + + +&tdm; + +identifies &tdm;, in case some other DM implements this protocol, +too + + + +list, lock, +suicide, login + +The respective command is supported + + + +bootoptions + +The listbootoptions command and the + to shutdown are supported + + + +shutdown <list> + +shutdown is supported and allowed for the listed +users (a comma separated list.) * means all +authenticated users. + + + +nuke <list> + +Forced shutdown may be performed by the listed users. + + + +nuke + +Forced shutdown may be performed by everybody + + + +reserve <number> + +Reserve displays are configured, and number +are available at this time + + + + +list [all | +alllocal] + +Return a list of running sessions. By default all active sessions are +listed. if all is specified, passive sessions are +listed as well. If alllocal is specified, passive +sessions are listed as well, but all incoming remote sessions are +skipped. +Each session entry is a comma separated tuple of: + +Display or TTY name +VT name for local sessions +Logged in user's name, empty for passive sessions and +outgoing remote sessions (local chooser mode) +Session type or <remote> for outgoing +remote sessions, empty for passive sessions. +A Flag field: +* for the display belonging +to the requesting socket. +! for sessions that cannot be killed by the +reqeusting socket. + + + +New fields may be added in the future. + + + + +reserve [timeout in +seconds] + +Start a reserve login screen. If nobody logs in within the specified +amount of time (one minute by default), the display is removed again. When +the session on the display exits, the display is removed, too. +Permitted only on sockets of local displays and the global +socket. + + + + +activate +(vt|display) + +Switch to a particular VT (virtual terminal). The VT may be specified +either directly (⪚ vt3) or by a display using it +(eg; :2). +Permitted only on sockets of local displays and the global +socket. + + + + +listbootoptions + +List available boot options. + + + + + +shutdown (reboot | +halt) +[=bootchoice] +(ask|trynow|forcenow|schedule|start +(-1|end +(force|forcemy|cancel)))) + +Request a system shutdown, either a reboot or a halt/poweroff. +An OS choice for the next boot may be specified from the list returned +by listbootoptions +Shutdowns requested from per-display sockets are executed when the +current sessino on that display exits. Such a request may pop up a dialog +asking for confirmation and/or authentication +start is the time for which the shutdown is +scheduled. If it starts with a plus-sign, the current time is added. Zero +means immediately. +end is the latest time at which the shutdown +should be performed if active sessions are still running. If it starts with +a plus-sign, the start time is added. -1 means wait infinitely. If end is +through and active sessions are still running, &tdm; can do one of the +following: + +cancel - give up the +shutdown +force - shut down +nonetheless +forcemy - shut down nonetheless if +all active sessions belong to the requesting user. Only for per-display sockets. + +start and end are +specified in seconds since the &UNIX; epoch. +trynow is a synonym for 0 0 +cancel, forcenow for 0 0 +force and schedule for 0 +-1. +ask attempts an immediate shutdown and +interacts with the user if active sessions are still running. Only for +per-display sockets. + + + + +shutdown cancel +[local|global} + +Cancel a scheduled shutdown. The global socket always cancels the +currently pending shutdown, while per-display sockets default to cancelling +their queued request. + + + + +shutdown status + +Return a list with information about shutdowns. +The entries are a comma-separated tuples of: + + +(global|local) - +pending vs. queued shutdown. A local entry can be returned only by a +per-display socket. + +(halt|reboot) +start +end +("ask"|"force"|"forcemy"|"cancel") +Numeric user ID of the requesting user, -1 for the global +socket. +The next boot OS choice or "-" for none. + +New fields might be added later + + + + + + +There are two ways of using the sockets: + + +Connecting them directly. FifoDir is exported as +$DM_CONTROL; the name of per-display sockets can be derived +from $DISPLAY. + + +By using the tdmctl command (⪚ from within a +shell script). Try tdmctl to find out +more. + + + +Here is an example bash script reboot into FreeBSD: + +if tdmctl | grep -q shutdown; then + IFS=$'\t' + set -- `tdmctl listbootoptions` + if [ "$1" = ok ]; then + fbsd=$(echo "$2" | tr ' ' '\n' | sed -ne 's,\\s, ,g;/freebsd/I{p;q}') + if [ -n "$fbsd" ]; then + tdmctl shutdown reboot "=$fbsd" ask > /dev/null + else + echo "FreeBSD boot unavailable." + fi + else + echo "Boot options unavailable." + fi +else + echo "Cannot reboot system." +fi + + + + + + +Other sources of information + +Since &tdm; is descended from &xdm;, the &xdm; man page may provide useful background +information. For X-related problems try the man pages X and startx. If you have +questions about &tdm; that are not answered by this handbook, take advantage of +the fact the &tdm; is provided under the terms of the &GNU; +General Public License: look at the source code. + + + + + +Credits and License + +&tdm; is derived from, and includes code from, +&xdm; (C) Keith Packard, MIT X Consortium. + +&tdm; 0.1 was written by &Matthias.Ettrich;. Later versions till &kde; +2.0.x were written by &Steffen.Hansen;. Some new features for &kde; 2.1.x and +a major rewrite for &kde; 2.2.x made by &Oswald.Buddenhagen;. + +Other parts of the &tdm; code are copyright by the authors, and +licensed under the terms of the &GNU; +GPL. Anyone is allowed to change &tdm; and redistribute the result +as long as the names of the authors are mentioned. + +&tdm; requires the &Qt; library, which is copyright Troll Tech AS. + +Documentation contributors: + + +Documentation written by &Steffen.Hansen; +stefh@dit.ou.dk + +Documentation extended by Gregor +Zumsteinzumstein@ssd.ethz.ch. Last update August 9, +1998 + +Documentation revised for &kde; 2 by &Neal.Crook; &Neal.Crook.mail;. Last update August 6, 2000 + +Documentation extended and revised for &kde; 2.2 by &Oswald.Buddenhagen; &Oswald.Buddenhagen.mail;. Last update August, +2001 + + + +Documentation copyright &Steffen.Hansen;, Gregor Zumstein, &Neal.Crook; +and &Oswald.Buddenhagen;. This document also includes large parts of the &xdm; +man page, which is © Keith Packard. + + + +&underFDL; +&underGPL; + + + + +Glossary + + +greeter +The greeter is the login dialog, &ie; the part of &tdm; +which the user sees. + + + + +entropy +The entropy of a system is the measure of its +unpredictability. This is used during the generation of random numbers. + + + + + + diff --git a/doc/tdm/tdmrc-ref.docbook b/doc/tdm/tdmrc-ref.docbook new file mode 100644 index 000000000..f2cfd2f0e --- /dev/null +++ b/doc/tdm/tdmrc-ref.docbook @@ -0,0 +1,2316 @@ + + + +The Files &tdm; Uses for Configuration + +This chapter documents the files that control &tdm;'s behavior. +Some of this can be also controlled from the &kcontrol; module, but +not all. + + +&tdmrc; - The &tdm; master configuration file + +The basic format of the file is INI-like. +Options are key/value pairs, placed in sections. +Everything in the file is case sensitive. +Syntactic errors and unrecognized key/section identifiers cause &tdm; to +issue non-fatal error messages. + +Lines beginning with # are comments; empty lines +are ignored as well. + +Sections are denoted by +[Name of Section]. + + +You can configure every X-display individually. +Every display has a display name, which consists of a host name +(which is empty for local displays specified in +or ), a colon, and a display number. +Additionally, a display belongs to a +display class (which can be ignored in most cases). + +Sections with display-specific settings have the formal syntax +[X- host [ : number [ _ class ] ] - sub-section ] + +All sections with the same sub-section +make up a section class. + +You can use the wildcard * (match any) for +host, number, +and class. You may omit trailing components; +they are assumed to be * then. The host part may be a +domain specification like .inf.tu-dresden.de +or the wildcard + (match non-empty). + +From which section a setting is actually taken is determined by +these rules: + + + +An exact match takes precedence over a partial match (for the +host part), which in turn takes precedence over a wildcard +(+ taking precendence over *). + + + +Precedence decreases from left to right for equally exact matches. + + + + + +Example: display name myhost.foo:0, class dpy + + + +[X-myhost.foo:0_dpy] precedes + + +[X-myhost.foo:0_*] (same as [X-myhost.foo:0]) precedes + + +[X-myhost.foo:*_dpy] precedes + + +[X-myhost.foo:*_*] (same as [X-myhost.foo]) precedes + + +[X-.foo:*_*] (same as [X-.foo]) precedes + + +[X-+:0_dpy] precedes + + +[X-*:0_dpy] precedes + + +[X-*:0_*] (same as [X-*:0]) precedes + + +[X-*:*_*] (same as [X-*]). + + +These sections do not match this display: +[X-hishost], [X-myhost.foo:0_dec], [X-*:1], [X-:*] + + + + + + + +Common sections are [X-*] (all displays), [X-:*] (all local displays) +and [X-:0] (the first local display). + +The format for all keys is + = value. +Keys are only valid in the section class they are defined for. +Some keys do not apply to particular displays, in which case they are ignored. + + +If a setting is not found in any matching section, the default +is used. + +Special characters need to be backslash-escaped (leading and trailing +spaces (\s), tab (\t), linefeed +(\n), carriage return (\r) and the +backslash itself (\\)). +In lists, fields are separated with commas without whitespace in between. + +Some command strings are subject to simplified sh-style word splitting: +single quotes (') and double quotes (") +have the usual meaning; the backslash quotes everything (not only special +characters). Note that the backslashes need to be doubled because of the +two levels of quoting. + +A pristine &tdmrc; is very thoroughly commented. +All comments will be lost if you change this file with the +kcontrol frontend. + + + +The [General] section of &tdmrc; + + +This section contains global options that do not fit into any specific section. + + + + + + + + +This option exists solely for the purpose of clean automatic upgrades. +Do not change it, you may interfere with future +upgrades and this could result in &tdm; failing to run. + + + + + + + + +List of displays (&X-Server;s) permanently managed by &tdm;. Displays with a +hostname are foreign displays which are expected to be already running, +the others are local displays for which &tdm; starts an own &X-Server;; +see . Each display may belong to a display class; +append it to the display name separated by an underscore. +See for the details. + +The default is :0. + + + + + + + +List of on-demand displays. See for syntax. + +Empty by default. + + + + + + + +List of Virtual Terminals to allocate to &X-Server;s. For negative numbers the +absolute value is used, and the VT will be allocated only +if the kernel says it is free. If &tdm; exhausts this list, it will allocate +free VTs greater than the absolute value of the last entry +in this list. +Currently Linux only. + +Empty by default. + + + + + + + +This option is for operating systems (OSs) with support +for virtual terminals (VTs), by both &tdm; and the +OSs itself. +Currently this applies only to Linux. + +When &tdm; switches to console mode, it starts monitoring all +TTY lines listed here (without the leading +/dev/). +If none of them is active for some time, &tdm; switches back to the X login. + +Empty by default. + + + + + + + +The filename specified will be created to contain an ASCII representation +of the process ID of the main &tdm; process; the PID will not be stored +if the filename is empty. + +Empty by default. + + + + + + + +This option controls whether &tdm; uses file locking to keep multiple +display managers from running onto each other. + +The default is true. + + + + + + + +This names a directory under which &tdm; stores &X-Server; authorization +files while initializing the session. &tdm; expects the system to clean up +this directory from stale files on reboot. + +The authorization file to be used for a particular display can be +specified with the option in [X-*-Core]. + +The default is /var/run/xauth. + + + + + + + +This boolean controls whether &tdm; automatically re-reads its +configuration files if it finds them to have changed. + +The default is true. + + + + + + + +Additional environment variables &tdm; should pass on to all programs it runs. +LD_LIBRARY_PATH and XCURSOR_THEME are good candidates; +otherwise, it should not be necessary very often. + +Empty by default. + + + + + + + +If the system has no native entropy source like /dev/urandom (see +) and no entropy daemon like EGD (see + and ) is running, +&tdm; will fall back to its own pseudo-random number generator +that will, among other things, successively checksum parts of this file +(which, obviously, should change frequently). + +This option does not exist on Linux and various BSDs. + +The default is /dev/mem. + + + + + + + +If the system has no native entropy source like /dev/urandom (see +), read random data from a Pseudo-Random +Number Generator Daemon, +like EGD (http://egd.sourceforge.net) via this UNIX domain socket. + +This option does not exist on Linux and various BSDs. + +Empty by default. + + + + + + + +Same as , only use a TCP socket on localhost. + + + + + + + + +The path to a character device which &tdm; should read random data from. +Empty means to use the system's preferred entropy device if there is one. + +This option does not exist on OpenBSD, as it uses the arc4_random +function instead. + +Empty by default. + + + + + + + +The directory in which the command FiFos should +be created; make it empty to disable them. + +The default is /var/run/xdmctl. + + + + + + + +The group to which the global command FiFo should belong; +can be either a name or a numerical ID. + + + + + + + + +The directory in which &tdm; should store persistent working data; such data +is, for example, the previous user that logged in on a particular display. + +The default is /var/lib/tdm. + + + + + + + +The directory in which &tdm; should store users' .dmrc files. This is only +needed if the home directories are not readable before actually logging in +(like with AFS). + +Empty by default. + + + + + + + + +The [Xdmcp] section of &tdmrc; + + +This section contains options that control &tdm;'s handling of +&XDMCP; requests. + + + + + + + + +Whether &tdm; should listen to incoming &XDMCP; requests. + +The default is true. + + + + + + + +This indicates the UDP port number which &tdm; uses to listen for incoming +&XDMCP; requests. Unless you need to debug the system, leave this with its +default value. + +The default is 177. + + + + + + + +XDM-AUTHENTICATION-1 style &XDMCP; authentication requires a private +key to be shared between &tdm; and the terminal. This option specifies +the file containing those values. Each entry in the file consists of a +display name and the shared key. + +Empty by default. + + + + + + + +To prevent unauthorized &XDMCP; service and to allow forwarding of &XDMCP; +IndirectQuery requests, this file contains a database of hostnames which +are either allowed direct access to this machine, or have a list of hosts +to which queries should be forwarded to. The format of this file is +described in . + +The default is ${kde_confdir}/tdm/Xaccess. + + + + + + + +Number of seconds to wait for the display to respond after the user has +selected a host from the chooser. If the display sends an &XDMCP; +IndirectQuery within this time, the request is forwarded to the chosen +host; otherwise, it is assumed to be from a new session and the chooser +is offered again. + +The default is 15. + + + + + + + +When computing the display name for &XDMCP; clients, the name resolver will +typically create a fully qualified host name for the terminal. As this is +sometimes confusing, &tdm; will remove the domain name portion of the host +name if it is the same as the domain name of the local host when this option +is enabled. + +The default is true. + + + + + + + +Use the numeric IP address of the incoming connection on multihomed hosts +instead of the host name. This is to avoid trying to connect on the wrong +interface which might be down at this time. + +The default is false. + + + + + + + +This specifies a program which is run (as +root) when an &XDMCP; +DirectQuery or BroadcastQuery is received and this host is configured +to offer &XDMCP; display management. The output of this program may be +displayed in a chooser window. If no program is specified, the string +Willing to manage is sent. + +Empty by default. + + + + + + + + +The [Shutdown] section of &tdmrc; + + +This section contains global options concerning system shutdown. + + + + + + + + +The command (subject to word splitting) to run to halt/poweroff the system. + +The default is something reasonable for the system on which &tdm; was built, like +/sbin/shutdown  now. + + + + + + + + +The command (subject to word splitting) to run to reboot the system. + +The default is something reasonable for the system &tdm; on which was built, like +/sbin/shutdown  now. + + + + + + + + +Whether it is allowed to shut down the system via the global command FiFo. + +The default is false. + + + + + + + +Whether it is allowed to abort active sessions when shutting down the +system via the global command FiFo. + +This will have no effect unless is enabled. + +The default is true. + + + + + + + +The boot manager &tdm; should use for offering boot options in the +shutdown dialog. + + + +None +no boot manager + + +Grub +Grub boot manager + + +Lilo +Lilo boot manager (Linux on i386 & x86-64 only) + + +The default is None. + + + + + + + + +The [X-*-Core] section class of &tdmrc; + + +This section class contains options concerning the configuration +of the &tdm; backend (core). + + + + + + + + +See . + +The default is 15. + + + + + + + +See . + +The default is 120. + + + + + + + +These options control the behavior of &tdm; when attempting to open a +connection to an &X-Server;. is the length +of the pause (in seconds) between successive attempts, + is the number of attempts to make and + is the amount of time to spend on a +connection attempt. After attempts have been +made, or if seconds elapse in any particular +connection attempt, the start attempt is considered failed. + +The default is 5. + + + + + + + +How many times &tdm; should attempt to start a foreign +display listed in before giving up +and disabling it. +Local displays are attempted only once, and &XDMCP; displays are retried +indefinitely by the client (unless the option +was given to the &X-Server;). + +The default is 4. + + + + + + + +How many times &tdm; should attempt to start up a local &X-Server;. +Starting up includes executing it and waiting for it to come up. + +The default is 1. + + + + + + + +How many seconds &tdm; should wait for a local &X-Server; to come up. + +The default is 15. + + + + + + + +The command line to start the &X-Server;, without display number and VT spec. +This string is subject to word splitting. + +The default is something reasonable for the system on which &tdm; was built, +like /usr/X11R6/bin/X. + + + + + + + + +Additional arguments for the &X-Server;s for local sessions. +This string is subject to word splitting. + +Empty by default. + + + + + + + +Additional arguments for the &X-Server;s for remote sessions. +This string is subject to word splitting. + +Empty by default. + + + + + + + +The VT the &X-Server; should run on. + should be used instead of this option. +Leave it zero to let &tdm; assign a VT automatically. +Set it to -1 to avoid assigning a VT +alltogether - this is required for setups with multiple physical consoles. +Currently Linux only. + + + + + + + + +This option is for OSs without support for +VTs, either by &tdm; or the OS itself. +Currently this applies to all OSs but Linux. + +When &tdm; switches to console mode, it starts monitoring this +TTY line (specified without the leading +/dev/) for activity. If the line is not used for some time, +&tdm; switches back to the X login. + +Empty by default. + + + + + + + +See . + +The default is 5. + + + + + + + +To discover when remote displays disappear, &tdm; +regularly pings them. + specifies the time (in minutes) between the +pings and specifies the maximum amount of +time (in minutes) to wait for the terminal to respond to the request. If +the terminal does not respond, the session is declared dead and terminated. + +If you frequently use X terminals which can become isolated from +the managing host, you may wish to increase the timeout. The only worry +is that sessions will continue to exist after the terminal has been +accidentally disabled. + +The default is 5. + + + + + + + +Whether &tdm; should restart the local &X-Server; after session exit instead +of resetting it. Use this if the &X-Server; leaks memory or crashes the system +on reset attempts. + +The default is false. + + + + + + + +The signal number to use to reset the local &X-Server;. + +The default is 1 (SIGHUP). + + + + + + + +The signal number to use to terminate the local &X-Server;. + +The default is 15 (SIGTERM). + + + + + + + +Controls whether &tdm; generates and uses authorization for +local &X-Server; connections. +For &XDMCP; displays the authorization requested by the display is used; +foreign non-&XDMCP; displays do not support authorization at all. + +The default is true. + + + + + + + +If is true, use the authorization mechanisms +listed herein. The MIT-MAGIC-COOKIE-1 authorization is always available; +XDM-AUTHORIZATION-1, SUN-DES-1 and MIT-KERBEROS-5 might be available as well, +depending on the build configuration. + +The default is DEF_AUTH_NAME. + + + + + + + +Some old &X-Server;s re-read the authorization file +at &X-Server; reset time, instead of when checking the initial connection. +As &tdm; generates the authorization information just before connecting to +the display, an old &X-Server; would not get up-to-date authorization +information. This option causes &tdm; to send SIGHUP to the &X-Server; +after setting up the file, causing an additional &X-Server; reset to occur, +during which time the new authorization information will be read. + +The default is false. + + + + + + + +This file is used to communicate the authorization data from &tdm; to +the &X-Server;, using the &X-Server; command line +option. It should be kept in a directory which is not world-writable +as it could easily be removed, disabling the authorization mechanism in +the &X-Server;. If not specified, a random name is generated from + and the name of the display. + +Empty by default. + + + + + + + +This option specifies the name of the file to be loaded by +xrdb as the resource database onto the root window +of screen 0 of the display. KDE programs generally do not use +X-resources, so this option is only needed if the +program needs some X-resources. + +Empty by default. + + + + + + + +The xrdb program to use to read the X-resources file +specified in . +The command is subject to word splitting. + +The default is ${x_bindir}/xrdb. + + + + + + + +This string is subject to word splitting. +It specifies a program which is run (as +root) before offering the +greeter window. This may be used to change the appearance of the screen +around the greeter window or to put up other windows (e.g., you may want +to run xconsole here). +The conventional name for a program used here is Xsetup. +See . + +Empty by default. + + + + + + + +This string is subject to word splitting. +It specifies a program which is run (as +root) after the user +authentication process succeeds. +The conventional name for a program used here is Xstartup. +See . + +Empty by default. + + + + + + + +This string is subject to word splitting. +It specifies a program which is run (as +root) after the session +terminates. +The conventional name for a program used here is Xreset. +See . + +Empty by default. + + + + + + + +This string is subject to word splitting. +It specifies the session program to be executed (as the user owning +the session). +The conventional name for a program used here is Xsession. +See . + +The default is ${x_bindir}/xterm -ls -T. + + + + + + + +If the program fails to execute, &tdm; will +fall back to this program. This program is executed with no arguments, +but executes using the same environment variables as the session would +have had (see ). + +The default is ${x_bindir}/xterm. + + + + + + + +The PATH environment variable for +non-root s. + +The default depends on the system &tdm; was built on. + + + + + + + + +The PATH environment variable for all programs but +non-root +s. Note that it is good practice not to include +. (the current directory) into this entry. + +The default depends on the system &tdm; was built on. + + + + + + + + +The SHELL environment variable for all programs but the +. + +The default is /bin/sh. + + + + + + + +When &tdm; is unable to write to the usual user authorization file +($HOME/.Xauthority), it creates a unique file name in this +directory and points the environment variable XAUTHORITY +at the created file. + +The default is /tmp. + + + + + + + +If enabled, &tdm; will automatically restart a session after an &X-Server; +crash (or if it is killed by Alt-Ctrl-BackSpace). Note that enabling this +feature opens a security hole: a secured display lock can be circumvented +(unless &kde;'s built-in screen locker is used). + +The default is false. + + + + + + + +If disabled, do not allow root +(and any other user with UID = 0) to log in directly. + +The default is true. + + + + + + + +If disabled, only users that have passwords assigned can log in. + +The default is true. + + + + + + + +Who is allowed to shut down the system. This applies both to the +greeter and to the command FiFo. + + + +None +no Shutdown... menu entry is shown at all + + +Root +the root password must be entered to shut down + + +All +everybody can shut down the machine + + +The default is All. + + + + + + + +Who is allowed to abort active sessions when shutting down. + + + +None +no forced shutdown is allowed at all + + +Root +the root password must be entered to shut down forcibly + + +All +everybody can shut down the machine forcibly + + +The default is All. + + + + + + + +The default choice for the shutdown condition/timing. + + + +Schedule +shut down after all active sessions exit (possibly at once) + + +TryNow +shut down, if no active sessions are open; otherwise, do nothing + + +ForceNow +shut down unconditionally + + +The default is Schedule. + + + + + + + +How to offer shutdown scheduling options: + + + +Never +not at all + + +Optional +as a button in the simple shutdown dialogs + + +Always +instead of the simple shutdown dialogs + + +The default is Never. + + + + + + + +Enable password-less logins on this display. Use with extreme care! + +The default is false. + + + + + + + +The users that do not need to provide a password to log in. +Items which are prefixed with @ represent all users in the +user group named by that item. +* means all users but +root +(and any other user with UID = 0). +Never list root. + +Empty by default. + + + + + + + +Enable automatic login. Use with extreme care! + +The default is false. + + + + + + + +If true, auto-login after logout. If false, auto-login is performed only +when a display session starts up. + +The default is false. + + + + + + + +The delay in seconds before automatic login kicks in. This is also known as +Timed Login. + + + + + + + + +The user to log in automatically. Never specify root! + +Empty by default. + + + + + + + +The password for the user to log in automatically. This is not required +unless the user is logged into a NIS or Kerberos domain. If you use this +option, you should chmod  tdmrc for obvious reasons. + +Empty by default. + + + + + + + +Immediately lock the automatically started session. This works only with +KDE sessions. + +The default is false. + + + + + + + +A list of directories containing session type definitions. + +The default is ${kde_datadir}/tdm/sessions. + + + + + + + +The file (relative to the user's home directory) to redirect the session +output to. One occurrence of %s in this string will be +substituted with the display name. Use %% to obtain a +literal %. + +The default is .xsession-errors. + + + + + + + +Specify whether &tdm;'s built-in utmp/wtmp/lastlog registration should +be used. If it is not, the tool sessreg should be used +in the and scripts, or, +alternatively, the pam_lastlog module should be used on +PAM-enabled systems. + +The default is true. + + + + + + + + +The [X-*-Greeter] section class of &tdmrc; + + +This section class contains options concerning the configuration +of the &tdm; frontend (greeter). + + + + + + + + +Specify the widget style for the greeter. Empty means to use the +built-in default which currently is Plastik. + +Empty by default. + + + + + + + +Specify the widget color scheme for the greeter. Empty means to use +the built-in default which currently is yellowish grey with some light +blue and yellow elements. + +Empty by default. + + + + + + + +What should be shown in the greeter righthand of the input lines (if + is disabled) or above them (if + is enabled): + + + +None +nothing + + +Logo +the image specified by + + +Clock +a neat analog clock + + +The default is Clock. + + + + + + + +The image to show in the greeter if is +Logo. + +Empty by default. + + + + + + + +The relative coordinates (percentages of the screen size; X,Y) at which +the center of the greeter is put. &tdm; aligns the greeter to the edges +of the screen it would cross otherwise. + +The default is 50,50. + + + + + + + +The screen the greeter should be displayed on in multi-headed and Xinerama +setups. The numbering starts with 0. For Xinerama, it corresponds to the +listing order in the active ServerLayout section of XF86Config; -1 means +to use the upper-left screen, -2 means to use the upper-right screen. + + + + + + + + +The headline in the greeter. An empty greeting means none at all. + +The following character pairs are replaced by their value: + + +%d +name of the current display + + +%h +local host name, possibly with the + domain name + + +%n +local node name, most probably the host name without the + domain name + + +%s +operating system + + +%r +operating system version + + +%m +machine (hardware) type + + +%% +a single % + + + +The default is Welcome to %s at %n. + + + + + + + +Whether the fonts used in the greeter should be antialiased. + +The default is false. + + + + + + + +The font for the greeter headline. + +The default is Serif,20,bold. + + + + + + + +The normal font used in the greeter. + +The default is Sans Serif,10. + + + + + + + +The font used for the Login Failed message. + +The default is Sans Serif,10,bold. + + + + + + + +What to do with the Num Lock modifier for the time the greeter is running: + + + +Off +turn off + + +On +turn on + + +Keep +do not change the state + + +The default is Keep. + + + + + + + +Language and locale to use in the greeter, encoded like $LC_LANG. + +The default is en_US. + + + + + + + +Enable autocompletion in the username line edit. + +The default is false. + + + + + + + +Show a user list with unix login names, real names, and images in the greeter. + +The default is true. + + + + + + + +This option controls which users will be shown in the user view +() and/or offered for autocompletion +(). +If it is Selected, contains +the final list of users. +If it is NotHidden, the initial user list contains all users +found on the system. Users contained in are +removed from the list, just like all users with a UID greater than specified +in and users with a non-zero UID less than +specified in . +Items in and +which are prefixed with @ represent all users in the +user group named by that item. +Finally, the user list will be sorted alphabetically, if + is enabled. + +The default is NotHidden. + + + + + + + +See . + +Empty by default. + + + + + + + +See . + +Empty by default. + + + + + + + +See . + + + + + + + + +See . + +The default is 65535. + + + + + + + +See . + +The default is true. + + + + + + + +If is enabled, this specifies where &tdm; gets the +images from: + + + +AdminOnly +from <>/$USER.face[.icon] + + +PreferAdmin +prefer <>, fallback on $HOME + + +PreferUser +... and the other way round + + +UserOnly +from the user's $HOME/.face[.icon] + + + + +The images can be in any format Qt recognizes, but the filename +must match &tdm;'s expectations: .face.icon should be a +48x48 icon, while .face should be a 300x300 image. +Currently the big image is used only as a fallback and is scaled down, +but in the future it might be displayed full-size in the logo area or a +tooltip. + +The default is AdminOnly. + + + + + + + +See . + +The default is ${kde_datadir}/tdm/faces. + + + + + + + +Specify, if/which user should be preselected for log in: + + + +None +do not preselect any user + + +Previous +the user which successfully logged in last time + + +Default +the user specified in the option + + + + +If is enabled and a user was preselected, +the cursor is placed in the password input field automatically. + +Enabling user preselection can be considered a security hole, +as it presents a valid login name to a potential attacker, so he +only needs to guess the password. On the other hand, +one could set to a fake login name. + + +The default is None. + + + + + + + +See . + +Empty by default. + + + + + + + +See . + +The default is false. + + + + + + + +The password input fields cloak the typed in text. Specify, how to do it: + + + +OneStar +* is shown for every typed +character + + +ThreeStars +*** is shown for every typed +character + + +NoEcho +nothing is shown at all, the cursor does not move + + +The default is OneStar. + + + + + + + +If enabled, &tdm; will automatically start the krootimage +program to set up the background; otherwise, the +program is responsible for the background. + +The default is true. + + + + + + + +The configuration file to be used by krootimage. +It contains a section named [Desktop0] like +kdesktoprc does. Its options are not described +herein; guess their meanings or use the control center. + +The default is ${kde_confdir}/tdm/backgroundrc. + + + + + + + +To improve security, the greeter grabs the &X-Server; and then the keyboard +when it starts up. This option specifies if the &X-Server; grab should be held +for the duration of the name/password reading. When disabled, the &X-Server; +is ungrabbed after the keyboard grab succeeds; otherwise, the &X-Server; is +grabbed until just before the session begins. + +Enabling this option disables and +. + + +The default is false. + + + + + + + +This option specifies the maximum time &tdm; will wait for the grabs to +succeed. A grab may fail if some other X-client has the &X-Server; or the +keyboard grabbed, or possibly if the network latencies are very high. You +should be cautious when raising the timeout, as a user can be spoofed by +a look-alike window on the display. If a grab fails, &tdm; kills and +restarts the &X-Server; (if possible) and the session. + +The default is 3. + + + + + + + +Warn, if a display has no X-authorization. This will be the case if + + + the authorization file for a local &X-Server; could not be created, + + + a remote display from &XDMCP; did not request any authorization or + + + the display is a foreign display specified in + . + + + +The default is true. + + + + + + + +Specify whether the greeter of local displays should start up in host chooser +(remote) or login (local) mode and whether it is allowed to switch to the +other mode. + + + +LocalOnly +only local login possible + + +DefaultLocal +start up in local mode, but allow switching to remote mode + + +DefaultRemote +... and the other way round + + +RemoteOnly +only choice of remote host possible + + +The default is LocalOnly. + + + + + + + +A list of hosts to be automatically added to the remote login menu. +The special name * means broadcast. +Has no effect if is LocalOnly. + +The default is *. + + + + + + + +Use this number as a random seed when forging saved session types, etc. of +unknown users. This is used to avoid telling an attacker about existing users +by reverse conclusion. This value should be random but constant across the +login domain. + + + + + + + + +Enable &tdm;'s built-in xconsole. +Note that this can be enabled for only one display at a time. +This option is available only if &tdm; was configured +with . + +The default is false. + + + + + + + +The data source for &tdm;'s built-in xconsole. +If empty, a console log redirection is requested from +/dev/console. +Has no effect if is disabled. + +Empty by default. + + + + + + + +Specify conversation plugins for the login dialog; the first in the list +is selected initially. +Each plugin can be specified as a base name (which expands to +$kde_modulesdir/kgreet_base) +or as a full pathname. + +Conversation plugins are modules for the greeter which obtain authentication +data from the user. Currently only the classic plugin is +shipped with &kde;; it presents the well-known username and password form. + +The default is classic. + + + + + + + +Same as , but for the shutdown dialog. + +The default is classic. + + + + + + + +A list of options of the form +Key=Value. +The conversation plugins can query these settings; it is up to them what +possible keys are. + +Empty by default. + + + + + + + +Show the Console Login action in the greeter (if / +is configured). + +The default is true. + + + + + + + +Show the Restart X Server/Close Connection action in the greeter. + +The default is true. + + + + + + + +A program to run while the greeter is visible. It is supposed to preload +as much as possible of the session that is going to be started (most +probably). + +Empty by default. + + + + + + + +Whether the greeter should be themed. + +The default is false. + + + + + + + +The theme to use for the greeter. Can point to either a directory or an XML +file. + +Empty by default. + + + + + + + + + + + +Specifying permanent &X-Server;s + +Each entry in the list indicates a +display which should constantly be +managed and which is not using &XDMCP;. This method is typically used only for +local &X-Server;s that are started by &tdm;, but &tdm; can manage externally +started (foreign) &X-Server;s as well, may they run on the +local machine or rather remotely. + +The formal syntax of a specification is + +display name [_display class] + +for all &X-Server;s. Foreign displays differ in having +a host name in the display name, may it be localhost. + +The display name must be something that can +be passed in the option to an X program. This string +is used to generate the display-specific section names, so be careful to match +the names. +The display name of &XDMCP; displays is derived from the display's address by +reverse host name resolution. For configuration purposes, the +localhost prefix from locally running &XDMCP; displays is +not stripped to make them distinguishable from local +&X-Server;s started by &tdm;. + +The display class portion is also used in the +display-specific sections. This is useful if you have a large collection of +similar displays (such as a corral of X terminals) and would like to set +options for groups of them. +When using &XDMCP;, the display is required to specify the display class, +so the manual for your particular X terminal should document the display +class string for your device. If it does not, you can run &tdm; in debug +mode and grep the log for class. + +The displays specified in will not be +started when &tdm; starts up, but when it is explicitly requested via +the command socket (or FiFo). +If reserve displays are specified, the &kde; menu will have a +Start New Session item near the bottom; use that to +activate a reserve display with a new login session. The monitor will switch +to the new display, and you will have a minute to login. If there are no more +reserve displays available, the menu item will be disabled. + +When &tdm; starts a session, it sets up authorization data for the +&X-Server;. For local servers, &tdm; passes + filename +on the &X-Server;'s command line to point it at its authorization data. +For &XDMCP; displays, &tdm; passes the authorization data to the &X-Server; +via the Accept &XDMCP; message. + + + + +&XDMCP; access control + +The file specified by the option provides +information which &tdm; uses to control access from displays requesting service +via &XDMCP;. +The file contains four types of entries: entries which control the response +to Direct and Broadcast queries, entries which +control the response to Indirect queries, macro definitions for +Indirect entries, and entries which control on which network +interfaces &tdm; listens for &XDMCP; queries. +Blank lines are ignored, # is treated as a comment +delimiter causing the rest of that line to be ignored, and \ +causes an immediately following newline to be ignored, allowing indirect host +lists to span multiple lines. + + +The format of the Direct entries is simple, either a +host name or a pattern, which is compared against the host name of the display +device. +Patterns are distinguished from host names by the inclusion of one or more +meta characters; * matches any sequence of 0 or more +characters, and ? matches any single character. +If the entry is a host name, all comparisons are done using network addresses, +so any name which converts to the correct network address may be used. Note +that only the first network address returned for a host name is used. +For patterns, only canonical host names are used in the comparison, so ensure +that you do not attempt to match aliases. +Host names from &XDMCP; queries always contain the local domain name +even if the reverse lookup returns a short name, so you can use +patterns for the local domain. +Preceding the entry with a ! character causes hosts which +match that entry to be excluded. +To only respond to Direct queries for a host or pattern, +it can be followed by the optional NOBROADCAST keyword. +This can be used to prevent a &tdm; server from appearing on menus based on +Broadcast queries. + +An Indirect entry also contains a host name or pattern, +but follows it with a list of host names or macros to which the queries +should be forwarded. Indirect entries can be excluding as well, +in which case a (valid) dummy host name must be supplied to make the entry +distinguishable from a Direct entry. +If compiled with IPv6 support, multicast address groups may also be included +in the list of addresses the queries are forwarded to. + +If the indirect host list contains the keyword CHOOSER, +Indirect queries are not forwarded, but instead a host chooser +dialog is displayed by &tdm;. The chooser will send a Direct +query to each of the remaining host names in the list and offer a menu of +all the hosts that respond. The host list may contain the keyword +BROADCAST, to make the chooser send a +Broadcast query as well; note that on some operating systems, +UDP packets cannot be broadcast, so this feature will not work. + + +When checking access for a particular display host, each entry is scanned +in turn and the first matching entry determines the response. +Direct and Broadcast entries are ignored when +scanning for an Indirect entry and vice-versa. + +A macro definition contains a macro name and a list of host names and +other macros that the macro expands to. To distinguish macros from hostnames, +macro names start with a % character. + +The last entry type is the LISTEN directive. +The formal syntax is + + LISTEN [interface [multicast list]] + +If one or more LISTEN lines are specified, &tdm; listens +for &XDMCP; requests only on the specified interfaces. +interface may be a hostname or IP address +representing a network interface on this machine, or the wildcard +* to represent all available network interfaces. +If multicast group addresses are listed on a LISTEN line, +&tdm; joins the multicast groups on the given interface. For IPv6 multicasts, +the IANA has assigned ff0X:0:0:0:0:0:0:12b as the +permanently assigned range of multicast addresses for &XDMCP;. The +X in the prefix may be replaced by any valid scope +identifier, such as 1 for Node-Local, 2 for Link-Local, 5 for Site-Local, and +so on (see IETF RFC 2373 or its replacement for further details and scope +definitions). &tdm; defaults to listening on the Link-Local scope address +ff02:0:0:0:0:0:0:12b to most closely match the IPv4 subnet broadcast behavior. +If no LISTEN lines are given, &tdm; listens on all +interfaces and joins the default &XDMCP; IPv6 multicast group (when +compiled with IPv6 support). +To disable listening for &XDMCP; requests altogether, a +LISTEN line with no addresses may be specified, but using +the [Xdmcp] option is preferred. + + + + + +Supplementary programs + + +The following programs are run by &tdm; at various stages of a session. +They typically are shell scripts. + + + +The Setup, Startup and Reset programs are run as +root, so they should be careful +about security. +Their first argument is auto if the session results +from an automatic login; otherwise, no arguments are passed to them. + + + +Setup program + + +The Xsetup program is run after the &X-Server; is +started or reset, but before the greeter is offered. +This is the place to change the root background (if + is disabled) or bring up other windows that +should appear on the screen along with the greeter. + + + +In addition to any specified by , +the following environment variables are passed: + + + DISPLAY + the associated display name + + + PATH + the value of + + + SHELL + the value of + + + XAUTHORITY + may be set to an authority file + + + DM_CONTROL + the value of + + + + Note that since &tdm; grabs the keyboard, any other windows will not be +able to receive keyboard input. They will be able to interact with the mouse, +however; beware of potential security holes here. If +is set, Xsetup will not be able to connect to the display +at all. Resources for this program can be put into the file named by +. + + + + + +Startup program + +The Xstartup program is run as +root when the user logs in. +This is the place to put commands which add entries to +utmp (the sessreg program +may be useful here), mount users' home directories from file servers, +or abort the session if some requirements are not met (but note that on +modern systems, many of these tasks are already taken care of by +PAM modules). + +In addition to any specified by , +the following environment variables are passed: + + + DISPLAY + the associated display name + + + HOME + the initial working directory of the user + + + LOGNAME + the username + + + USER + the username + + + PATH + the value of + + + SHELL + the value of + + + XAUTHORITY + may be set to an authority file + + + DM_CONTROL + the value of + + + +&tdm; waits until this program exits before starting the user session. +If the exit value of this program is non-zero, &tdm; discontinues the session +and starts another authentication cycle. + + + + +Session program + +The Xsession program is the command which is run +as the user's session. It is run with the permissions of the authorized user. +One of the keywords failsafe, default +or custom, or a string to eval by a +Bourne-compatible shell is passed as the first argument. + +In addition to any specified by , +the following environment variables are passed: + + + DISPLAY + the associated display name + + + HOME + the initial working directory of the user + + + LOGNAME + the username + + + USER + the username + + + PATH + the value of + (or for + root user sessions) + + + + SHELL + the user's default shell + + + XAUTHORITY + may be set to a non-standard authority file + + + KRBTKFILE + may be set to a Kerberos4 credentials cache name + + + + KRB5CCNAME + may be set to a Kerberos5 credentials cache name + + + + DM_CONTROL + the value of + + + XDM_MANAGED + will contain a comma-separated list of parameters the + session might find interesting, like the location of the command + FiFo and its capabilities, and which conversation + plugin was used for the login + + + + DESKTOP_SESSION + the name of the session the user has chosen to run + + + + + + + +Reset program + +Symmetrical with Xstartup, the +Xreset program is run after the user session has +terminated. Run as root, it should +contain commands that undo the effects of commands in +Xstartup, removing entries from utmp +or unmounting directories from file servers. + +The environment variables that were passed to +Xstartup are also passed to Xreset. + + + + + + + diff --git a/kcontrol/kdm/AUTHORS b/kcontrol/kdm/AUTHORS deleted file mode 100644 index 3b7927243..000000000 --- a/kcontrol/kdm/AUTHORS +++ /dev/null @@ -1,6 +0,0 @@ -TDM - The KDE Display Manager - written by Steffen Hansen - -The KDE Display Manager Configuration module - -written by Thomas Tanghus - -Currently maintend by Oswald Buddenhagen diff --git a/kcontrol/kdm/CMakeLists.txt b/kcontrol/kdm/CMakeLists.txt deleted file mode 100644 index 004282250..000000000 --- a/kcontrol/kdm/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_BINARY_DIR}/kcontrol/background - ${CMAKE_BINARY_DIR} - ${TDE_INCLUDE_DIR} - ${TQT_INCLUDE_DIRS} -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - -##### other data ################################ - -install( FILES tdm.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) - - -##### kcm_tdm (module) ########################## - -set_source_files_properties( background.cpp PROPERTIES COMPILE_FLAGS -DKDE_CONFDIR=\\"${TDE_CONFIG_DIR}\\" ) -set_source_files_properties( main.cpp PROPERTIES COMPILE_FLAGS -DKDE_CONFDIR=\\"${TDE_CONFIG_DIR}\\" ) - -tde_add_kpart( kcm_tdm AUTOMOC - SOURCES - background.cpp tdm-appear.cpp tdm-font.cpp tdm-shut.cpp - tdm-users.cpp tdm-conv.cpp main.cpp kbackedcombobox.cpp - LINK kcmbgnd-static bgnd-static knewstuff-shared - DESTINATION ${PLUGIN_INSTALL_DIR} -) diff --git a/kcontrol/kdm/ChangeLog b/kcontrol/kdm/ChangeLog deleted file mode 100644 index d49bb2548..000000000 --- a/kcontrol/kdm/ChangeLog +++ /dev/null @@ -1,16 +0,0 @@ -2002-07-11 Oswald Buddenhagen - * Reworked "Users" and "Convenience" tabs - -2001-01-15 Oswald Buddenhagen - * Several new fields in different tabs for some new features - -2000-12-06 Oswald Buddenhagen - * New "Convenience" tab supporting the new automation features - * Some changes to the "Users" tab - * Few bug fixes - -1998-04-28 Thomas Tanghus - * Improved geometry management. - -1998-05-14 Thomas Tanghus - * Fixed bug with "ShutDownButton=...". diff --git a/kcontrol/kdm/Makefile.am b/kcontrol/kdm/Makefile.am deleted file mode 100644 index e6193d7df..000000000 --- a/kcontrol/kdm/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -kde_module_LTLIBRARIES = kcm_tdm.la - -# _don't_ add a theme configurator!! -kcm_tdm_la_SOURCES = background.cpp tdm-appear.cpp tdm-font.cpp tdm-shut.cpp \ - tdm-users.cpp tdm-conv.cpp main.cpp kbackedcombobox.cpp - -kcm_tdm_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -module -avoid-version -no-undefined -kcm_tdm_la_LIBADD = $(top_builddir)/kcontrol/background/libkcmbgnd.la $(top_builddir)/kcontrol/background/libbgnd.la $(LIB_KIO) $(LIB_KNEWSTUFF) - -AM_CPPFLAGS= -I$(top_builddir)/kcontrol/background \ - -I$(top_srcdir)/kcontrol/background \ - -I$(top_srcdir)/kdesktop $(all_includes) - -METASOURCES = AUTO - -messages: - $(XGETTEXT) $(kcm_tdm_la_SOURCES) -o $(podir)/tdmconfig.pot - -xdg_apps_DATA = tdm.desktop diff --git a/kcontrol/kdm/background.cpp b/kcontrol/kdm/background.cpp deleted file mode 100644 index 4078bd393..000000000 --- a/kcontrol/kdm/background.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * This file is part of the KDE project, module kcmdisplay. - * Copyright (C) 1999 Geert Jansen - * - * Modified 2000.07.14 by Brad Hughes - * Improve layout and consistency with KDesktop's background selection - * - * Based on old backgnd.cpp: - * - * Copyright (c) Martin R. Jones 1996 - * Converted to a kcc module by Matthias Hoelzer 1997 - * Gradient backgrounds by Mark Donohoe 1997 - * Pattern backgrounds by Stephan Kulow 1998 - * Randomizing & dnd & new display modes by Matej Koss 1998 - * - * You can Freely distribute this program under the GNU General Public - * License. See the file "COPYING" for the exact licensing terms. - */ - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include "../background/bgsettings.h" -#include "../background/bgdialog.h" -#include "background.h" -#include -#include -#include - -extern KSimpleConfig *config; - -KBackground::KBackground(TQWidget *parent, const char *name) - : TQWidget(parent, name) -{ - - // Enabling checkbox - m_pCBEnable = new TQCheckBox( i18n("E&nable background"), this ); - TQWhatsThis::add( m_pCBEnable, - i18n("If this is checked, TDM will use the settings below for the background." - " If it is disabled, you have to look after the background yourself." - " This is done by running some program (possibly xsetroot) in the script" - " specified in the Setup= option in tdmrc (usually Xsetup).") ); - config->setGroup( "X-*-Greeter" ); - m_simpleConf=new KSimpleConfig(config->readEntry( "BackgroundCfg",KDE_CONFDIR "/tdm/backgroundrc" ) ); - m_background = new BGDialog( this, m_simpleConf, false ); - - connect(m_background, TQT_SIGNAL(changed(bool)), TQT_SIGNAL(changed(bool))); - - // Top layout - TQVBoxLayout *top = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint() ); - top->addWidget(m_pCBEnable); - top->addWidget(m_background); - top->addStretch(); - connect( m_pCBEnable, TQT_SIGNAL(toggled( bool )), TQT_SLOT(slotEnableChanged()) ); -} - -KBackground::~KBackground() -{ - delete m_simpleConf; -} - -void KBackground::slotEnableChanged() -{ - bool en = m_pCBEnable->isChecked(); - m_background->setEnabled( en ); - emit changed ( true ); -} - -void KBackground::makeReadOnly() -{ - m_pCBEnable->setEnabled(false); - m_background->makeReadOnly(); -} - -void KBackground::load() -{ - m_pCBEnable->setChecked( config->readBoolEntry( "UseBackground", true ) ); - m_background->load(false); - slotEnableChanged(); - emit changed(false); -} - - -void KBackground::save() -{ - kdDebug() << "Saving stuff..." << endl; - config->writeEntry( "UseBackground", m_pCBEnable->isChecked() ); - m_background->save(); - emit changed(false); -} - - -void KBackground::defaults() -{ - m_pCBEnable->setChecked( true ); - slotEnableChanged(); - m_background->defaults(); - emit changed(true); -} - -#include "background.moc" diff --git a/kcontrol/kdm/background.h b/kcontrol/kdm/background.h deleted file mode 100644 index 2e5182b16..000000000 --- a/kcontrol/kdm/background.h +++ /dev/null @@ -1,50 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * This file is part of the KDE project, module kcmdisplay. - * Copyright (C) 1999 Geert Jansen - * - * You can Freely distribute this program under the GNU General Public - * License. See the file "COPYING" for the exact licensing terms. - */ - -#ifndef __Bgnd_h_Included__ -#define __Bgnd_h_Included__ - -#include -#include - - -class KSimpleConfig; -class BGDialog; -class KGlobalBackgroundSettings; -class TQCheckBox; -class TQLabel; - -class KBackground: public TQWidget -{ - Q_OBJECT -public: - KBackground(TQWidget *parent=0, const char *name=0); - ~KBackground(); - - void load(); - void save(); - void defaults(); - void makeReadOnly(); -signals: - void changed(bool); - -private slots: - void slotEnableChanged(); -private: - void init(); - void apply(); - - TQCheckBox *m_pCBEnable; - TQLabel *m_pMLabel; - KSimpleConfig *m_simpleConf; - BGDialog *m_background; -}; - - -#endif // __Bgnd_h_Included__ diff --git a/kcontrol/kdm/kbackedcombobox.cpp b/kcontrol/kdm/kbackedcombobox.cpp deleted file mode 100644 index 1ba598e49..000000000 --- a/kcontrol/kdm/kbackedcombobox.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* This file is part of the KDE Display Manager Configuration package - Copyright (C) 2004-2005 Oswald Buddenhagen - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kbackedcombobox.h" - -void KBackedComboBox::insertItem( const TQString &id, const TQString &name ) -{ - id2name[id] = name; - name2id[name] = id; - KComboBox::insertItem( name ); -} - -void KBackedComboBox::setCurrentId( const TQString &id ) -{ - if (id2name.contains( id )) - setCurrentItem( id2name[id] ); - else - setCurrentItem( 0 ); -} - -const TQString &KBackedComboBox::currentId() const -{ - return name2id[currentText()]; -} diff --git a/kcontrol/kdm/kbackedcombobox.h b/kcontrol/kdm/kbackedcombobox.h deleted file mode 100644 index 1ec1d2a72..000000000 --- a/kcontrol/kdm/kbackedcombobox.h +++ /dev/null @@ -1,38 +0,0 @@ -/* This file is part of the KDE Display Manager Configuration package - Copyright (C) 2004-2005 Oswald Buddenhagen - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KBACKEDCOMBOBOX_H -#define KBACKEDCOMBOBOX_H - -#include - -class KBackedComboBox : public KComboBox { - -public: - KBackedComboBox( TQWidget *parent ) : KComboBox( false, parent ) {} - void insertItem( const TQString &id, const TQString &name ); - void setCurrentId( const TQString &id ); - const TQString ¤tId() const; - -private: - TQMap id2name, name2id; - -}; - -#endif // KBACKEDCOMBOBOX_H diff --git a/kcontrol/kdm/kdm-appear.cpp b/kcontrol/kdm/kdm-appear.cpp deleted file mode 100644 index cdd5f2fc9..000000000 --- a/kcontrol/kdm/kdm-appear.cpp +++ /dev/null @@ -1,554 +0,0 @@ -/* - This file is part of the KDE Display Manager Configuration package - Copyright (C) 1997-1998 Thomas Tanghus (tanghus@earthling.net) - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - - -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tdm-appear.h" -#include "kbackedcombobox.h" - -extern KSimpleConfig *config; - - -TDMAppearanceWidget::TDMAppearanceWidget(TQWidget *parent, const char *name) - : TQWidget(parent, name) -{ - TQString wtstr; - - TQVBoxLayout *vbox = new TQVBoxLayout(this, KDialog::marginHint(), - KDialog::spacingHint(), "vbox"); - TQGroupBox *group = new TQGroupBox(i18n("Appearance"), this); - vbox->addWidget(group); - - TQGridLayout *grid = new TQGridLayout( group, 5, 2, KDialog::marginHint(), - KDialog::spacingHint(), "grid"); - grid->addRowSpacing(0, group->fontMetrics().height()); - grid->setColStretch(0, 1); - grid->setColStretch(1, 1); - - TQHBoxLayout *hlay = new TQHBoxLayout( KDialog::spacingHint() ); - grid->addMultiCellLayout(hlay, 1,1, 0,1); - greetstr_lined = new KLineEdit(group); - TQLabel *label = new TQLabel(greetstr_lined, i18n("&Greeting:"), group); - hlay->addWidget(label); - connect(greetstr_lined, TQT_SIGNAL(textChanged(const TQString&)), - TQT_SLOT(changed())); - hlay->addWidget(greetstr_lined); - wtstr = i18n("This is the \"headline\" for TDM's login window. You may want to " - "put some nice greeting or information about the operating system here.

" - "TDM will substitute the following character pairs with the " - "respective contents:

    " - "
  • %d -> current display
  • " - "
  • %h -> host name, possibly with domain name
  • " - "
  • %n -> node name, most probably the host name without domain name
  • " - "
  • %s -> the operating system
  • " - "
  • %r -> the operating system's version
  • " - "
  • %m -> the machine (hardware) type
  • " - "
  • %% -> a single %
  • " - "
" ); - TQWhatsThis::add( label, wtstr ); - TQWhatsThis::add( greetstr_lined, wtstr ); - - - TQGridLayout *hglay = new TQGridLayout( 3, 4, KDialog::spacingHint() ); - grid->addMultiCellLayout(hglay, 2,4, 0,0); - - label = new TQLabel(i18n("Logo area:"), group); - hglay->addWidget(label, 0, 0); - TQVBoxLayout *vlay = new TQVBoxLayout( KDialog::spacingHint() ); - hglay->addMultiCellLayout(vlay, 0,0, 1,2); - noneRadio = new TQRadioButton( i18n("logo area", "&None"), group ); - clockRadio = new TQRadioButton( i18n("Show cloc&k"), group ); - logoRadio = new TQRadioButton( i18n("Sho&w logo"), group ); - TQButtonGroup *buttonGroup = new TQButtonGroup( group ); - label->setBuddy( buttonGroup ); - connect( buttonGroup, TQT_SIGNAL(clicked(int)), TQT_SLOT(slotAreaRadioClicked(int)) ); - connect( buttonGroup, TQT_SIGNAL(clicked(int)), TQT_SLOT(changed()) ); - buttonGroup->hide(); - buttonGroup->insert(noneRadio, KdmNone); - buttonGroup->insert(clockRadio, KdmClock); - buttonGroup->insert(logoRadio, KdmLogo); - vlay->addWidget(noneRadio); - vlay->addWidget(clockRadio); - vlay->addWidget(logoRadio); - wtstr = i18n("You can choose to display a custom logo (see below), a clock or no logo at all."); - TQWhatsThis::add( label, wtstr ); - TQWhatsThis::add( noneRadio, wtstr ); - TQWhatsThis::add( logoRadio, wtstr ); - TQWhatsThis::add( clockRadio, wtstr ); - - logoLabel = new TQLabel(i18n("&Logo:"), group); - logobutton = new TQPushButton(group); - logoLabel->setBuddy( logobutton ); - logobutton->setAutoDefault(false); - logobutton->setAcceptDrops(true); - logobutton->installEventFilter(this); // for drag and drop - connect(logobutton, TQT_SIGNAL(clicked()), TQT_SLOT(slotLogoButtonClicked())); - hglay->addWidget(logoLabel, 1, 0); - hglay->addWidget(logobutton, 1, 1, Qt::AlignCenter); - hglay->addRowSpacing(1, 110); - wtstr = i18n("Click here to choose an image that TDM will display. " - "You can also drag and drop an image onto this button " - "(e.g. from Konqueror)."); - TQWhatsThis::add( logoLabel, wtstr ); - TQWhatsThis::add( logobutton, wtstr ); - hglay->addRowSpacing( 2, KDialog::spacingHint()); - hglay->setColStretch( 3, 1); - - - hglay = new TQGridLayout( 2, 3, KDialog::spacingHint() ); - grid->addLayout(hglay, 2, 1); - - label = new TQLabel(i18n("Position:"), group); - hglay->addMultiCellWidget(label, 0,1, 0,0, Qt::AlignVCenter); - TQValidator *posValidator = new TQIntValidator(0, 100, TQT_TQOBJECT(group)); - TQLabel *xLineLabel = new TQLabel(i18n("&X:"), group); - hglay->addWidget(xLineLabel, 0, 1); - xLineEdit = new TQLineEdit (group); - connect( xLineEdit, TQT_SIGNAL( textChanged(const TQString&) ), TQT_SLOT( changed() )); - hglay->addWidget(xLineEdit, 0, 2); - xLineLabel->setBuddy(xLineEdit); - xLineEdit->setValidator(posValidator); - TQLabel *yLineLabel = new TQLabel(i18n("&Y:"), group); - hglay->addWidget(yLineLabel, 1, 1); - yLineEdit = new TQLineEdit (group); - connect( yLineEdit, TQT_SIGNAL( textChanged(const TQString&) ), TQT_SLOT( changed() )); - hglay->addWidget(yLineEdit, 1, 2); - yLineLabel->setBuddy(yLineEdit); - yLineEdit->setValidator(posValidator); - wtstr = i18n("Here you specify the relative coordinates (in percent) of the login dialog's center."); - TQWhatsThis::add( label, wtstr ); - TQWhatsThis::add( xLineLabel, wtstr ); - TQWhatsThis::add( xLineEdit, wtstr ); - TQWhatsThis::add( yLineLabel, wtstr ); - TQWhatsThis::add( yLineEdit, wtstr ); - hglay->setColStretch( 3, 1); - hglay->setRowStretch( 2, 1); - - - hglay = new TQGridLayout( 2, 3, KDialog::spacingHint() ); - grid->addLayout(hglay, 3, 1); - hglay->setColStretch(3, 1); - - compositorcombo = new KBackedComboBox(group); - compositorcombo->insertItem( "", i18n("None") ); - compositorcombo->insertItem( "kompmgr", i18n("Trinity compositor") ); - label = new TQLabel(compositorcombo, i18n("Compositor:"), group); - connect(compositorcombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); - hglay->addWidget(label, 0, 0); - hglay->addWidget(compositorcombo, 0, 1); - wtstr = i18n("Choose a compositor to be used in TDM. Note that the chosen compositor will continue to run after login."); - TQWhatsThis::add( label, wtstr ); - TQWhatsThis::add( compositorcombo, wtstr ); - - guicombo = new KBackedComboBox(group); - guicombo->insertItem( "", i18n("") ); - loadGuiStyles(guicombo); - guicombo->listBox()->sort(); - label = new TQLabel(guicombo, i18n("GUI s&tyle:"), group); - connect(guicombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); - hglay->addWidget(label, 1, 0); - hglay->addWidget(guicombo, 1, 1); - wtstr = i18n("You can choose a basic GUI style here that will be " - "used by TDM only."); - TQWhatsThis::add( label, wtstr ); - TQWhatsThis::add( guicombo, wtstr ); - - colcombo = new KBackedComboBox(group); - colcombo->insertItem( "", i18n("") ); - loadColorSchemes(colcombo); - colcombo->listBox()->sort(); - label = new TQLabel(colcombo, i18n("&Color scheme:"), group); - connect(colcombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); - hglay->addWidget(label, 2, 0); - hglay->addWidget(colcombo, 2, 1); - wtstr = i18n("You can choose a basic Color Scheme here that will be " - "used by TDM only."); - TQWhatsThis::add( label, wtstr ); - TQWhatsThis::add( colcombo, wtstr ); - - echocombo = new KBackedComboBox(group); - echocombo->insertItem("NoEcho", i18n("No Echo")); - echocombo->insertItem("OneStar", i18n("One Star")); - echocombo->insertItem("ThreeStars", i18n("Three Stars")); - label = new TQLabel(echocombo, i18n("Echo &mode:"), group); - connect(echocombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); - hglay->addWidget(label, 3, 0); - hglay->addWidget(echocombo, 3, 1); - wtstr = i18n("You can choose whether and how TDM shows your password when you type it."); - TQWhatsThis::add( label, wtstr ); - TQWhatsThis::add( echocombo, wtstr ); - - - // The Language group box - group = new TQGroupBox(0, Qt::Vertical, i18n("Locale"), this); - vbox->addWidget(group); - - langcombo = new KLanguageButton(group); - loadLanguageList(langcombo); - connect(langcombo, TQT_SIGNAL(activated(const TQString &)), TQT_SLOT(changed())); - label = new TQLabel(langcombo, i18n("Languag&e:"), group); - TQGridLayout *hbox = new TQGridLayout( group->layout(), 2, 2, KDialog::spacingHint() ); - hbox->setColStretch(1, 1); - hbox->addWidget(label, 1, 0); - hbox->addWidget(langcombo, 1, 1); - wtstr = i18n("Here you can choose the language used by TDM. This setting does not affect" - " a user's personal settings; that will take effect after login."); - TQWhatsThis::add( label, wtstr ); - TQWhatsThis::add( langcombo, wtstr ); - - - // The SAK group box - group = new TQGroupBox(0, Qt::Vertical, i18n("Secure Attention Key"), this); - vbox->addWidget(group); - - sakbox = new TQCheckBox( i18n("Enable Secure Attention Key"), group ); - connect( sakbox, TQT_SIGNAL(toggled(bool)), TQT_SLOT(changed()) ); - TQGridLayout *hbox2 = new TQGridLayout( group->layout(), 2, 2, KDialog::spacingHint() ); - hbox2->setColStretch(1, 1); - hbox2->addWidget(sakbox, 1, 0); - wtstr = i18n("Here you can enable or disable the Secure Attention Key [SAK] anti-spoofing measure."); - TQWhatsThis::add( sakbox, wtstr ); - - - vbox->addStretch(1); - -} - -void TDMAppearanceWidget::makeReadOnly() -{ - disconnect( logobutton, TQT_SIGNAL(clicked()), - this, TQT_SLOT(slotLogoButtonClicked()) ); - logobutton->setAcceptDrops(false); - greetstr_lined->setReadOnly(true); - noneRadio->setEnabled(false); - clockRadio->setEnabled(false); - logoRadio->setEnabled(false); - xLineEdit->setEnabled(false); - yLineEdit->setEnabled(false); - compositorcombo->setEnabled(false); - guicombo->setEnabled(false); - colcombo->setEnabled(false); - echocombo->setEnabled(false); - langcombo->setEnabled(false); - sakbox->setEnabled(false); -} - -void TDMAppearanceWidget::loadLanguageList(KLanguageButton *combo) -{ - TQStringList langlist = KGlobal::dirs()->findAllResources("locale", - TQString::fromLatin1("*/entry.desktop")); - langlist.sort(); - for ( TQStringList::ConstIterator it = langlist.begin(); - it != langlist.end(); ++it ) - { - TQString fpath = (*it).left((*it).length() - 14); - int index = fpath.findRev('/'); - TQString nid = fpath.mid(index + 1); - - KSimpleConfig entry(*it); - entry.setGroup(TQString::fromLatin1("KCM Locale")); - TQString name = entry.readEntry(TQString::fromLatin1("Name"), i18n("without name")); - combo->insertLanguage(nid, name, TQString::fromLatin1("l10n/"), TQString::null); - } -} - -void TDMAppearanceWidget::loadColorSchemes(KBackedComboBox *combo) -{ - // XXX: Global + local schemes - TQStringList list = KGlobal::dirs()-> - findAllResources("data", "kdisplay/color-schemes/*.kcsrc", false, true); - for (TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it) - { - KSimpleConfig config(*it, true); - config.setGroup("Color Scheme"); - - TQString str; - if (!(str = config.readEntry("Name")).isEmpty() || - !(str = config.readEntry("name")).isEmpty()) - { - TQString str2 = (*it).mid( (*it).findRev( '/' ) + 1 ); // strip off path - str2.setLength( str2.length() - 6 ); // strip off ".kcsrc - combo->insertItem( str2, str ); - } - } -} - -void TDMAppearanceWidget::loadGuiStyles(KBackedComboBox *combo) -{ - // XXX: Global + local schemes - TQStringList list = KGlobal::dirs()-> - findAllResources("data", "kstyle/themes/*.themerc", false, true); - for (TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it) - { - KSimpleConfig config(*it, true); - - if (!(config.hasGroup("KDE") && config.hasGroup("Misc"))) - continue; - - config.setGroup("Desktop Entry"); - if (config.readBoolEntry("Hidden", false)) - continue; - - config.setGroup("KDE"); - TQString str2 = config.readEntry("WidgetStyle"); - if (str2.isNull()) - continue; - - config.setGroup("Misc"); - combo->insertItem( str2, config.readEntry("Name") ); - } -} - -bool TDMAppearanceWidget::setLogo(TQString logo) -{ - TQString flogo = logo.isEmpty() ? - locate("data", TQString::fromLatin1("tdm/pics/kdelogo.png") ) : - logo; - TQImage p(flogo); - if (p.isNull()) - return false; - if (p.width() > 100 || p.height() > 100) - p = p.smoothScale(100, 100, TQ_ScaleMin); - logobutton->setPixmap(p); - uint bd = style().pixelMetric( TQStyle::PM_ButtonMargin ) * 2; - logobutton->setFixedSize(p.width() + bd, p.height() + bd); - logopath = logo; - return true; -} - - -void TDMAppearanceWidget::slotLogoButtonClicked() -{ - KImageIO::registerFormats(); - KFileDialog dialogue(locate("data", TQString::fromLatin1("tdm/pics/")), - KImageIO::pattern( KImageIO::Reading ), - this, 0, true); - dialogue.setOperationMode( KFileDialog::Opening ); - dialogue.setMode( KFile::File | KFile::LocalOnly ); - - KImageFilePreview* imagePreview = new KImageFilePreview( &dialogue ); - dialogue.setPreviewWidget( imagePreview ); - if (dialogue.exec() == TQDialog::Accepted) { - if ( setLogo(dialogue.selectedFile()) ) { - changed(); - } - } -} - - -void TDMAppearanceWidget::slotAreaRadioClicked(int id) -{ - logobutton->setEnabled( id == KdmLogo ); - logoLabel->setEnabled( id == KdmLogo ); -} - - -bool TDMAppearanceWidget::eventFilter(TQObject *, TQEvent *e) -{ - if (e->type() == TQEvent::DragEnter) { - iconLoaderDragEnterEvent((TQDragEnterEvent *) e); - return true; - } - - if (e->type() == TQEvent::Drop) { - iconLoaderDropEvent((TQDropEvent *) e); - return true; - } - - return false; -} - -void TDMAppearanceWidget::iconLoaderDragEnterEvent(TQDragEnterEvent *e) -{ - e->accept(KURLDrag::canDecode(e)); -} - - -KURL *decodeImgDrop(TQDropEvent *e, TQWidget *wdg); - -void TDMAppearanceWidget::iconLoaderDropEvent(TQDropEvent *e) -{ - KURL pixurl; - bool istmp; - - KURL *url = decodeImgDrop(e, this); - if (url) { - - // we gotta check if it is a non-local file and make a tmp copy at the hd. - if(!url->isLocalFile()) { - pixurl.setPath(KGlobal::dirs()->resourceDirs("data").last() + - "tdm/pics/" + url->fileName()); - KIO::NetAccess::copy(*url, pixurl, parentWidget()); - istmp = true; - } else { - pixurl = *url; - istmp = false; - } - - // By now url should be "file:/..." - if (!setLogo(pixurl.path())) { - KIO::NetAccess::del(pixurl, parentWidget()); - TQString msg = i18n("There was an error loading the image:\n" - "%1\n" - "It will not be saved.") - .arg(pixurl.path()); - KMessageBox::sorry(this, msg); - } - - delete url; - } -} - - -void TDMAppearanceWidget::save() -{ - config->setGroup("X-*-Greeter"); - - config->writeEntry("GreetString", greetstr_lined->text()); - - config->writeEntry("LogoArea", noneRadio->isChecked() ? "None" : - logoRadio->isChecked() ? "Logo" : "Clock" ); - - config->writeEntry("LogoPixmap", KGlobal::iconLoader()->iconPath(logopath, KIcon::Desktop, true)); - - config->writeEntry("Compositor", compositorcombo->currentId()); - - config->writeEntry("GUIStyle", guicombo->currentId()); - - config->writeEntry("ColorScheme", colcombo->currentId()); - - config->writeEntry("EchoMode", echocombo->currentId()); - - config->writeEntry("GreeterPos", xLineEdit->text() + ',' + yLineEdit->text()); - - config->writeEntry("Language", langcombo->current()); - - config->writeEntry("UseSAK", sakbox->isChecked()); -} - - -void TDMAppearanceWidget::load() -{ - config->setGroup("X-*-Greeter"); - - // Read the greeting string - greetstr_lined->setText(config->readEntry("GreetString", i18n("Welcome to %n"))); - - // Regular logo or clock - TQString logoArea = config->readEntry("LogoArea", "Logo" ); - if (logoArea == "Clock") { - clockRadio->setChecked(true); - slotAreaRadioClicked(KdmClock); - } else if (logoArea == "Logo") { - logoRadio->setChecked(true); - slotAreaRadioClicked(KdmLogo); - } else { - noneRadio->setChecked(true); - slotAreaRadioClicked(KdmNone); - } - - // See if we use alternate logo - setLogo(config->readEntry("LogoPixmap")); - - // Check the current compositor type - compositorcombo->setCurrentId(config->readEntry("Compositor")); - - // Check the GUI type - guicombo->setCurrentId(config->readEntry("GUIStyle")); - - // Check the Color Scheme - colcombo->setCurrentId(config->readEntry("ColorScheme")); - - // Check the echo mode - echocombo->setCurrentId(config->readEntry("EchoMode", "OneStar")); - - TQStringList sl = config->readListEntry( "GreeterPos" ); - if (sl.count() != 2) { - xLineEdit->setText( "50" ); - yLineEdit->setText( "50" ); - } else { - xLineEdit->setText( sl.first() ); - yLineEdit->setText( sl.last() ); - } - - // get the language - langcombo->setCurrentItem(config->readEntry("Language", "C")); - - // See if the SAK is enabled - sakbox->setChecked(config->readBoolEntry("UseSAK", true)); -} - - -void TDMAppearanceWidget::defaults() -{ - greetstr_lined->setText( i18n("Welcome to %n") ); - logoRadio->setChecked( true ); - slotAreaRadioClicked( KdmLogo ); - setLogo( "" ); - compositorcombo->setCurrentId( "" ); - guicombo->setCurrentId( "" ); - colcombo->setCurrentId( "" ); - echocombo->setCurrentItem( "OneStar" ); - - xLineEdit->setText( "50" ); - yLineEdit->setText( "50" ); - - langcombo->setCurrentItem( "en_US" ); -} - -TQString TDMAppearanceWidget::quickHelp() const -{ - return i18n("

TDM - Appearance

Here you can configure the basic appearance" - " of the TDM login manager, i.e. a greeting string, an icon etc.

" - " For further refinement of TDM's appearance, see the \"Font\" and \"Background\" " - " tabs."); -} - - -void TDMAppearanceWidget::changed() -{ - emit changed(true); -} - -#include "tdm-appear.moc" diff --git a/kcontrol/kdm/kdm-appear.h b/kcontrol/kdm/kdm-appear.h deleted file mode 100644 index 0d4047e10..000000000 --- a/kcontrol/kdm/kdm-appear.h +++ /dev/null @@ -1,97 +0,0 @@ -/* This file is part of the KDE Display Manager Configuration package - Copyright (C) 1997 Thomas Tanghus (tanghus@earthling.net) - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - - -#ifndef __TDMAPPEAR_H__ -#define __TDMAPPEAR_H__ - - -#include -#include -#include -#include - -#include -#include -#include - - -#include "klanguagebutton.h" - -class TQComboBox; -class KBackedComboBox; -class TQLabel; -class TQRadioButton; -class TQLineEdit; -class KLineEdit; - - -class TDMAppearanceWidget : public TQWidget -{ - Q_OBJECT - -public: - TDMAppearanceWidget(TQWidget *parent, const char *name=0); - - void load(); - void save(); - void defaults(); - void makeReadOnly(); - TQString quickHelp() const; - - void loadColorSchemes(KBackedComboBox *combo); - void loadGuiStyles(KBackedComboBox *combo); - void loadLanguageList(KLanguageButton *combo); - - bool eventFilter(TQObject *, TQEvent *); - -signals: - void changed( bool state ); - -protected: - void iconLoaderDragEnterEvent(TQDragEnterEvent *event); - void iconLoaderDropEvent(TQDropEvent *event); - bool setLogo(TQString logo); - -private slots: - void slotAreaRadioClicked(int id); - void slotLogoButtonClicked(); - void changed(); - -private: - enum { KdmNone, KdmClock, KdmLogo }; - TQLabel *logoLabel; - TQPushButton *logobutton; - KLineEdit *greetstr_lined; - TQString logopath; - TQRadioButton *noneRadio; - TQRadioButton *clockRadio; - TQRadioButton *logoRadio; - TQLineEdit *xLineEdit; - TQLineEdit *yLineEdit; - KBackedComboBox *compositorcombo; - KBackedComboBox *guicombo; - KBackedComboBox *colcombo; - KBackedComboBox *echocombo; - KLanguageButton *langcombo; - TQCheckBox *sakbox; - -}; - -#endif diff --git a/kcontrol/kdm/kdm-conv.cpp b/kcontrol/kdm/kdm-conv.cpp deleted file mode 100644 index 64b8b9727..000000000 --- a/kcontrol/kdm/kdm-conv.cpp +++ /dev/null @@ -1,362 +0,0 @@ -/* This file is part of the KDE Display Manager Configuration package - - Copyright (C) 2000 Oswald Buddenhagen - Based on several other files. - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include -#include - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tdm-conv.h" - -extern KSimpleConfig *config; - -TDMConvenienceWidget::TDMConvenienceWidget(TQWidget *parent, const char *name) - : TQWidget(parent, name) -{ - TQString wtstr; - - TQLabel *paranoia = new TQLabel( i18n("

Attention!
Read help!
"), this ); - - TQSizePolicy vpref( TQSizePolicy::Minimum, TQSizePolicy::Fixed ); - - alGroup = new TQVGroupBox( i18n("Enable Au&to-Login"), this ); - alGroup->setCheckable( true ); - alGroup->setSizePolicy( vpref ); - - TQWhatsThis::add( alGroup, i18n("Turn on the auto-login feature." - " This applies only to TDM's graphical login." - " Think twice before enabling this!") ); - connect(alGroup, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChanged())); - - TQWidget *hlpw1 = new TQWidget( alGroup ); - userlb = new KComboBox( hlpw1 ); - u_label = new TQLabel( userlb, i18n("Use&r:"), hlpw1 ); - TQGridLayout *hlpl1 = new TQGridLayout(hlpw1, 2, 2, 0, KDialog::spacingHint()); - hlpl1->setColStretch(2, 1); - hlpl1->addWidget(u_label, 0, 0); - hlpl1->addWidget(userlb, 0, 1); - connect(userlb, TQT_SIGNAL(highlighted(int)), TQT_SLOT(slotChanged())); - wtstr = i18n("Select the user to be logged in automatically."); - TQWhatsThis::add( u_label, wtstr ); - TQWhatsThis::add( userlb, wtstr ); - delaysb = new TQSpinBox( 0, 3600, 5, hlpw1 ); - delaysb->setSpecialValueText( i18n("delay", "none") ); - delaysb->setSuffix( i18n("seconds", " s") ); - d_label = new TQLabel( delaysb, i18n("D&elay:"), hlpw1 ); - hlpl1->addWidget(d_label, 1, 0); - hlpl1->addWidget(delaysb, 1, 1); - connect(delaysb, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(slotChanged())); - wtstr = i18n("The delay (in seconds) before the automatic login kicks in. " - "This feature is also known as \"timed login\"."); - TQWhatsThis::add( d_label, wtstr ); - TQWhatsThis::add( delaysb, wtstr ); - againcb = new TQCheckBox( i18n("P&ersistent"), alGroup ); - connect( againcb, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChanged()) ); - TQWhatsThis::add( againcb, i18n("Normally, automatic login is performed only " - "when TDM starts up. If this is checked, automatic login will kick in " - "after finishing a session as well.") ); - autoLockCheck = new TQCheckBox( i18n("Loc&k session"), alGroup ); - connect( autoLockCheck, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChanged()) ); - TQWhatsThis::add( autoLockCheck, i18n("If checked, the automatically started session " - "will be locked immediately (provided it is a KDE session). This can " - "be used to obtain a super-fast login restricted to one user.") ); - - - puGroup = new TQVButtonGroup(i18n("Preselect User"), this ); - puGroup->setSizePolicy( vpref ); - - connect(puGroup, TQT_SIGNAL(clicked(int)), TQT_SLOT(slotPresChanged())); - connect(puGroup, TQT_SIGNAL(clicked(int)), TQT_SLOT(slotChanged())); - npRadio = new TQRadioButton(i18n("preselected user", "&None"), puGroup); - ppRadio = new TQRadioButton(i18n("Prev&ious"), puGroup); - TQWhatsThis::add( ppRadio, i18n("Preselect the user that logged in previously. " - "Use this if this computer is usually used several consecutive times by one user.") ); - spRadio = new TQRadioButton(i18n("Specif&y"), puGroup); - TQWhatsThis::add( spRadio, i18n("Preselect the user specified in the combo box below. " - "Use this if this computer is predominantly used by a certain user.") ); - TQWidget *hlpw = new TQWidget(puGroup); - puserlb = new KComboBox(true, hlpw); - pu_label = new TQLabel(puserlb, i18n("Us&er:"), hlpw); - connect(puserlb, TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(slotChanged())); - wtstr = i18n("Select the user to be preselected for login. " - "This box is editable, so you can specify an arbitrary non-existent " - "user to mislead possible attackers."); - TQWhatsThis::add( pu_label, wtstr ); - TQWhatsThis::add( puserlb, wtstr ); - TQBoxLayout *hlpl = new TQHBoxLayout(hlpw, 0, KDialog::spacingHint()); - hlpl->addWidget(pu_label); - hlpl->addWidget(puserlb); - hlpl->addStretch( 1 ); - cbjumppw = new TQCheckBox(i18n("Focus pass&word"), puGroup); - TQWhatsThis::add( cbjumppw, i18n("When this option is on, TDM will place the cursor " - "in the password field instead of the user field after preselecting a user. " - "Use this to save one key press per login, if the preselection usually does not need to " - "be changed.") ); - connect(cbjumppw, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChanged())); - - npGroup = new TQVGroupBox(i18n("Enable Password-&Less Logins"), this ); - npGroup->setCheckable( true ); - - TQWhatsThis::add( npGroup, i18n("When this option is checked, the checked users from" - " the list below will be allowed to log in without entering their" - " password. This applies only to TDM's graphical login." - " Think twice before enabling this!") ); - - connect(npGroup, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChanged())); - - pl_label = new TQLabel(i18n("No password re&quired for:"), npGroup); - npuserlv = new KListView(npGroup); - pl_label->setBuddy(npuserlv); - npuserlv->addColumn(TQString::null); - npuserlv->header()->hide(); - npuserlv->setResizeMode(TQListView::LastColumn); - TQWhatsThis::add(npuserlv, i18n("Check all users you want to allow a password-less login for." - " Entries denoted with '@' are user groups. Checking a group is like checking all users in that group.")); - connect( npuserlv, TQT_SIGNAL(clicked( TQListViewItem * )), - TQT_SLOT(slotChanged()) ); - - btGroup = new TQVGroupBox( i18n("Miscellaneous"), this ); - - cbarlen = new TQCheckBox(i18n("Automatically log in again after &X server crash"), btGroup); - TQWhatsThis::add( cbarlen, i18n("When this option is on, a user will be" - " logged in again automatically when their session is interrupted by an" - " X server crash; note that this can open a security hole: if you use" - " a screen locker than KDE's integrated one, this will make" - " circumventing a password-secured screen lock possible.") ); - connect(cbarlen, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChanged())); - - TQGridLayout *main = new TQGridLayout(this, 5, 2, 10); - main->addWidget(paranoia, 0, 0); - main->addWidget(alGroup, 1, 0); - main->addWidget(puGroup, 2, 0); - main->addMultiCellWidget(npGroup, 0,3, 1,1); - main->addMultiCellWidget(btGroup, 4,4, 0,1); - main->setColStretch(0, 1); - main->setColStretch(1, 2); - main->setRowStretch(3, 1); - - connect( userlb, TQT_SIGNAL(activated( const TQString & )), - TQT_SLOT(slotSetAutoUser( const TQString & )) ); - connect( puserlb, TQT_SIGNAL(textChanged( const TQString & )), - TQT_SLOT(slotSetPreselUser( const TQString & )) ); - connect( npuserlv, TQT_SIGNAL(clicked( TQListViewItem * )), - TQT_SLOT(slotUpdateNoPassUser( TQListViewItem * )) ); - -} - -void TDMConvenienceWidget::makeReadOnly() -{ - ((TQWidget*)alGroup->child("qt_groupbox_checkbox"))->setEnabled(false); - userlb->setEnabled(false); - delaysb->setEnabled(false); - againcb->setEnabled(false); - autoLockCheck->setEnabled(false); - ((TQWidget*)npGroup->child("qt_groupbox_checkbox"))->setEnabled(false); - npuserlv->setEnabled(false); - cbarlen->setEnabled(false); - npRadio->setEnabled(false); - ppRadio->setEnabled(false); - spRadio->setEnabled(false); - puserlb->setEnabled(false); - cbjumppw->setEnabled(false); -} - -void TDMConvenienceWidget::slotPresChanged() -{ - bool en = spRadio->isChecked(); - pu_label->setEnabled(en); - puserlb->setEnabled(en); - cbjumppw->setEnabled(!npRadio->isChecked()); -} - -void TDMConvenienceWidget::save() -{ - config->setGroup("X-:0-Core"); - config->writeEntry( "AutoLoginEnable", alGroup->isChecked() ); - config->writeEntry( "AutoLoginUser", userlb->currentText() ); - config->writeEntry( "AutoLoginDelay", delaysb->value() ); - config->writeEntry( "AutoLoginAgain", againcb->isChecked() ); - config->writeEntry( "AutoLoginLocked", autoLockCheck->isChecked() ); - - config->setGroup("X-:*-Core"); - config->writeEntry( "NoPassEnable", npGroup->isChecked() ); - config->writeEntry( "NoPassUsers", noPassUsers ); - - config->setGroup("X-*-Core"); - config->writeEntry( "AutoReLogin", cbarlen->isChecked() ); - - config->setGroup("X-:*-Greeter"); - config->writeEntry( "PreselectUser", npRadio->isChecked() ? "None" : - ppRadio->isChecked() ? "Previous" : - "Default" ); - config->writeEntry( "DefaultUser", puserlb->currentText() ); - config->writeEntry( "FocusPasswd", cbjumppw->isChecked() ); -} - - -void TDMConvenienceWidget::load() -{ - config->setGroup("X-:0-Core"); - bool alenable = config->readBoolEntry( "AutoLoginEnable", false); - autoUser = config->readEntry( "AutoLoginUser" ); - delaysb->setValue( config->readNumEntry( "AutoLoginDelay", 0 ) ); - againcb->setChecked( config->readBoolEntry( "AutoLoginAgain", false ) ); - autoLockCheck->setChecked( config->readBoolEntry( "AutoLoginLocked", false ) ); - if (autoUser.isEmpty()) - alenable=false; - alGroup->setChecked( alenable ); - - config->setGroup("X-:*-Core"); - npGroup->setChecked(config->readBoolEntry( "NoPassEnable", false) ); - noPassUsers = config->readListEntry( "NoPassUsers"); - - config->setGroup("X-*-Core"); - cbarlen->setChecked(config->readBoolEntry( "AutoReLogin", false) ); - - config->setGroup("X-:*-Greeter"); - TQString presstr = config->readEntry( "PreselectUser", "None" ); - if (presstr == "Previous") - ppRadio->setChecked(true); - else if (presstr == "Default") - spRadio->setChecked(true); - else - npRadio->setChecked(true); - preselUser = config->readEntry( "DefaultUser" ); - cbjumppw->setChecked(config->readBoolEntry( "FocusPasswd", false) ); - - slotPresChanged(); -} - - -void TDMConvenienceWidget::defaults() -{ - alGroup->setChecked(false); - delaysb->setValue(0); - againcb->setChecked(false); - autoLockCheck->setChecked(false); - npRadio->setChecked(true); - npGroup->setChecked(false); - cbarlen->setChecked(false); - cbjumppw->setChecked(false); - autoUser = ""; - preselUser = ""; - noPassUsers.clear(); - - slotPresChanged(); -} - - -void TDMConvenienceWidget::slotChanged() -{ - emit changed(true); -} - -void TDMConvenienceWidget::slotSetAutoUser( const TQString &user ) -{ - autoUser = user; -} - -void TDMConvenienceWidget::slotSetPreselUser( const TQString &user ) -{ - preselUser = user; -} - -void TDMConvenienceWidget::slotUpdateNoPassUser( TQListViewItem *item ) -{ - if ( !item ) - return; - TQCheckListItem *itm = (TQCheckListItem *)item; - TQStringList::iterator it = noPassUsers.find( itm->text() ); - if (itm->isOn()) { - if (it == noPassUsers.end()) - noPassUsers.append( itm->text() ); - } else { - if (it != noPassUsers.end()) - noPassUsers.remove( it ); - } -} - -void TDMConvenienceWidget::slotClearUsers() -{ - userlb->clear(); - puserlb->clear(); - npuserlv->clear(); - if (!autoUser.isEmpty()) - userlb->insertItem(autoUser); - if (!preselUser.isEmpty()) - puserlb->insertItem(preselUser); -} - -void TDMConvenienceWidget::slotAddUsers(const TQMap &users) -{ - TQMapConstIterator it; - for (it = users.begin(); it != users.end(); ++it) { - if (it.data() > 0) { - if (it.key() != autoUser) - userlb->insertItem(it.key()); - if (it.key() != preselUser) - puserlb->insertItem(it.key()); - } - if (it.data() != 0) - (new TQCheckListItem(npuserlv, it.key(), TQCheckListItem::CheckBox))-> - setOn(noPassUsers.find(it.key()) != noPassUsers.end()); - } - - if (userlb->listBox()) - userlb->listBox()->sort(); - - if (puserlb->listBox()) - puserlb->listBox()->sort(); - - npuserlv->sort(); - userlb->setCurrentItem(autoUser); - puserlb->setCurrentItem(preselUser); -} - -void TDMConvenienceWidget::slotDelUsers(const TQMap &users) -{ - TQMapConstIterator it; - for (it = users.begin(); it != users.end(); ++it) { - if (it.data() > 0) { - if (it.key() != autoUser && userlb->listBox()) - delete userlb->listBox()-> - findItem( it.key(), ExactMatch | CaseSensitive ); - if (it.key() != preselUser && puserlb->listBox()) - delete puserlb->listBox()-> - findItem( it.key(), ExactMatch | CaseSensitive ); - } - if (it.data() != 0) - delete npuserlv->findItem( it.key(), 0 ); - } -} - -#include "tdm-conv.moc" diff --git a/kcontrol/kdm/kdm-conv.h b/kcontrol/kdm/kdm-conv.h deleted file mode 100644 index 3f8dda974..000000000 --- a/kcontrol/kdm/kdm-conv.h +++ /dev/null @@ -1,84 +0,0 @@ -/* This file is part of the KDE Display Manager Configuration package - - Copyright (C) 2000 Oswald Buddenhagen - Based on several other files. - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __TDMCONV_H__ -#define __TDMCONV_H__ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - - -class TDMConvenienceWidget : public TQWidget -{ - Q_OBJECT - -public: - TDMConvenienceWidget(TQWidget *parent=0, const char *name=0); - - void load(); - void save(); - void defaults(); - void makeReadOnly(); - -public slots: - void slotClearUsers(); - void slotAddUsers(const TQMap &); - void slotDelUsers(const TQMap &); - - -signals: - void changed( bool state ); - -private slots: - void slotPresChanged(); - void slotChanged(); - void slotSetAutoUser( const TQString &user ); - void slotSetPreselUser( const TQString &user ); - void slotUpdateNoPassUser( TQListViewItem *item ); - -private: - TQGroupBox *alGroup, *puGroup, *npGroup, *btGroup; - TQCheckBox *againcb, *cbarlen, *cbjumppw, *autoLockCheck; - TQRadioButton *npRadio, *ppRadio, *spRadio; - KComboBox *userlb, *puserlb; - TQSpinBox *delaysb; - KListView *npuserlv; - TQLabel *u_label, *d_label, *pu_label, *w_label, *n_label, *pl_label; - TQString autoUser, preselUser; - TQStringList noPassUsers; -}; - -#endif - - diff --git a/kcontrol/kdm/kdm-font.cpp b/kcontrol/kdm/kdm-font.cpp deleted file mode 100644 index 9947101c1..000000000 --- a/kcontrol/kdm/kdm-font.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* This file is part of the KDE Display Manager Configuration package - Copyright (C) 1997 Thomas Tanghus (tanghus@earthling.net) - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include -#include - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "tdm-font.h" - - -extern KSimpleConfig *config; - -TDMFontWidget::TDMFontWidget(TQWidget *parent, const char *name) - : TQWidget(parent, name) -{ - TQGridLayout *ml = new TQGridLayout(this, 5, 2, KDialog::marginHint(), KDialog::spacingHint()); - TQLabel *label = new TQLabel(i18n("&General:"), this); - stdFontChooser = new KFontRequester(this); - label->setBuddy(stdFontChooser); - TQWhatsThis::add( stdFontChooser, i18n("This changes the font which is used for all the text in the login manager except for the greeting and failure messages.") ); - connect(stdFontChooser, TQT_SIGNAL(fontSelected(const TQFont&)),this,TQT_SLOT(configChanged())); - ml->addWidget(label, 1, 0); - ml->addWidget(stdFontChooser, 1, 1); - - label = new TQLabel(i18n("&Failures:"), this); - failFontChooser = new KFontRequester(this); - label->setBuddy(failFontChooser); - TQWhatsThis::add( failFontChooser, i18n("This changes the font which is used for failure messages in the login manager.") ); - connect(failFontChooser, TQT_SIGNAL(fontSelected(const TQFont&)),this,TQT_SLOT(configChanged())); - ml->addWidget(label, 2, 0); - ml->addWidget(failFontChooser, 2, 1); - - label = new TQLabel(i18n("Gree&ting:"), this); - greetingFontChooser = new KFontRequester(this); - label->setBuddy(greetingFontChooser); - TQWhatsThis::add( greetingFontChooser, i18n("This changes the font which is used for the login manager's greeting.") ); - connect(greetingFontChooser, TQT_SIGNAL(fontSelected(const TQFont&)),this,TQT_SLOT(configChanged())); - ml->addWidget(label, 3, 0); - ml->addWidget(greetingFontChooser, 3, 1); - - aacb = new TQCheckBox (i18n("Use anti-aliasing for fonts"), this); - TQWhatsThis::add( aacb, i18n("If you check this box and your X-Server has the Xft extension, " - "fonts will be antialiased (smoothed) in the login dialog.") ); - connect(aacb, TQT_SIGNAL(toggled ( bool )),this,TQT_SLOT(configChanged())); - ml->addMultiCellWidget(aacb, 4, 4, 0, 1); - ml->setRowStretch(5, 10); -} - -void TDMFontWidget::makeReadOnly() -{ - stdFontChooser->button()->setEnabled(false); - failFontChooser->button()->setEnabled(false); - greetingFontChooser->button()->setEnabled(false); - aacb->setEnabled(false); -} - -void TDMFontWidget::configChanged() -{ - emit changed(true); -} - -void TDMFontWidget::set_def() -{ - stdFontChooser->setFont(TQFont("Sans Serif", 10)); - failFontChooser->setFont(TQFont("Sans Serif", 10, TQFont::Bold)); - greetingFontChooser->setFont(TQFont("Sans Serif", 22)); -} - -void TDMFontWidget::save() -{ - config->setGroup("X-*-Greeter"); - - // write font - config->writeEntry("StdFont", stdFontChooser->font()); - config->writeEntry("GreetFont", greetingFontChooser->font()); - config->writeEntry("FailFont", failFontChooser->font()); - config->writeEntry("AntiAliasing", aacb->isChecked()); -} - - -void TDMFontWidget::load() -{ - set_def(); - - config->setGroup("X-*-Greeter"); - - // Read the fonts - TQFont font = stdFontChooser->font(); - stdFontChooser->setFont(config->readFontEntry("StdFont", &font)); - font = failFontChooser->font(); - failFontChooser->setFont(config->readFontEntry("FailFont", &font)); - font = greetingFontChooser->font(); - greetingFontChooser->setFont(config->readFontEntry("GreetFont", &font)); - - aacb->setChecked(config->readBoolEntry("AntiAliasing")); -} - - -void TDMFontWidget::defaults() -{ - set_def(); - aacb->setChecked(true); -} - -#include "tdm-font.moc" diff --git a/kcontrol/kdm/kdm-font.h b/kcontrol/kdm/kdm-font.h deleted file mode 100644 index 67b2c864d..000000000 --- a/kcontrol/kdm/kdm-font.h +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of the KDE Display Manager Configuration package - Copyright (C) 1997 Thomas Tanghus (tanghus@earthling.net) - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __TDMFONT_H__ -#define __TDMFONT_H__ - -#include - -class KFontRequester; -class TQCheckBox; - -class TDMFontWidget : public TQWidget -{ - Q_OBJECT - -public: - TDMFontWidget(TQWidget *parent=0, const char *name=0); - - void load(); - void save(); - void defaults(); - void makeReadOnly(); - -signals: - void changed( bool state ); - -protected slots: - void configChanged(); - void set_def(); - -private: - TQCheckBox *aacb; - KFontRequester *greetingFontChooser; - KFontRequester *failFontChooser; - KFontRequester *stdFontChooser; -}; - - -#endif - - diff --git a/kcontrol/kdm/kdm-shut.cpp b/kcontrol/kdm/kdm-shut.cpp deleted file mode 100644 index 434b55ae2..000000000 --- a/kcontrol/kdm/kdm-shut.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* This file is part of the KDE Display Manager Configuration package - Copyright (C) 1997-1998 Thomas Tanghus (tanghus@earthling.net) - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include -#include - - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "tdm-shut.h" -#include "kbackedcombobox.h" - -extern KSimpleConfig *config; - - -TDMSessionsWidget::TDMSessionsWidget(TQWidget *parent, const char *name) - : TQWidget(parent, name) -{ - TQString wtstr; - - - TQGroupBox *group0 = new TQGroupBox( i18n("Allow Shutdown"), this ); - - sdlcombo = new TQComboBox( FALSE, group0 ); - sdllabel = new TQLabel (sdlcombo, i18n ("&Local:"), group0); - sdlcombo->insertItem(i18n("Everybody"), SdAll); - sdlcombo->insertItem(i18n("Only Root"), SdRoot); - sdlcombo->insertItem(i18n("Nobody"), SdNone); - connect(sdlcombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); - sdrcombo = new TQComboBox( FALSE, group0 ); - sdrlabel = new TQLabel (sdrcombo, i18n ("&Remote:"), group0); - sdrcombo->insertItem(i18n("Everybody"), SdAll); - sdrcombo->insertItem(i18n("Only Root"), SdRoot); - sdrcombo->insertItem(i18n("Nobody"), SdNone); - connect(sdrcombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); - TQWhatsThis::add( group0, i18n("Here you can select who is allowed to shutdown" - " the computer using TDM. You can specify different values for local (console) and remote displays. " - "Possible values are:
    " - "
  • Everybody: everybody can shutdown the computer using TDM
  • " - "
  • Only root: TDM will only allow shutdown after the user has entered the root password
  • " - "
  • Nobody: nobody can shutdown the computer using TDM
") ); - - - TQGroupBox *group1 = new TQGroupBox( i18n("Commands"), this ); - - shutdown_lined = new KURLRequester(group1); - TQLabel *shutdown_label = new TQLabel(shutdown_lined, i18n("H&alt:"), group1); - connect(shutdown_lined, TQT_SIGNAL(textChanged(const TQString&)), - TQT_SLOT(changed())); - wtstr = i18n("Command to initiate the system halt. Typical value: /sbin/halt"); - TQWhatsThis::add( shutdown_label, wtstr ); - TQWhatsThis::add( shutdown_lined, wtstr ); - - restart_lined = new KURLRequester(group1); - TQLabel *restart_label = new TQLabel(restart_lined, i18n("Reb&oot:"), group1); - connect(restart_lined, TQT_SIGNAL(textChanged(const TQString&)), - TQT_SLOT(changed())); - wtstr = i18n("Command to initiate the system reboot. Typical value: /sbin/reboot"); - TQWhatsThis::add( restart_label, wtstr ); - TQWhatsThis::add( restart_lined, wtstr ); - - - TQGroupBox *group4 = new TQGroupBox( i18n("Miscellaneous"), this ); - - bm_combo = new KBackedComboBox( group4 ); - bm_combo->insertItem("None", i18n("boot manager", "None")); - bm_combo->insertItem("Grub", i18n("Grub")); -#if defined(__linux__) && ( defined(__i386__) || defined(__amd64__) ) - bm_combo->insertItem("Lilo", i18n("Lilo")); -#endif - TQLabel *bm_label = new TQLabel( bm_combo, i18n("Boot manager:"), group4 ); - connect(bm_combo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); - wtstr = i18n("Enable boot options in the \"Shutdown...\" dialog."); - TQWhatsThis::add( bm_label, wtstr ); - TQWhatsThis::add( bm_combo, wtstr ); - - TQBoxLayout *main = new TQVBoxLayout( this, 10 ); - TQGridLayout *lgroup0 = new TQGridLayout( group0, 1, 1, 10); - TQGridLayout *lgroup1 = new TQGridLayout( group1, 1, 1, 10); - TQGridLayout *lgroup4 = new TQGridLayout( group4, 1, 1, 10); - - main->addWidget(group0); - main->addWidget(group1); - main->addWidget(group4); - main->addStretch(); - - lgroup0->addRowSpacing(0, group0->fontMetrics().height()/2); - lgroup0->addColSpacing(2, KDialog::spacingHint() * 2); - lgroup0->setColStretch(1, 1); - lgroup0->setColStretch(4, 1); - lgroup0->addWidget(sdllabel, 1, 0); - lgroup0->addWidget(sdlcombo, 1, 1); - lgroup0->addWidget(sdrlabel, 1, 3); - lgroup0->addWidget(sdrcombo, 1, 4); - - lgroup1->addRowSpacing(0, group1->fontMetrics().height()/2); - lgroup1->addColSpacing(2, KDialog::spacingHint() * 2); - lgroup1->setColStretch(1, 1); - lgroup1->setColStretch(4, 1); - lgroup1->addWidget(shutdown_label, 1, 0); - lgroup1->addWidget(shutdown_lined, 1, 1); - lgroup1->addWidget(restart_label, 1, 3); - lgroup1->addWidget(restart_lined, 1, 4); - - lgroup4->addRowSpacing(0, group4->fontMetrics().height()/2); - lgroup4->addWidget(bm_label, 1, 0); - lgroup4->addWidget(bm_combo, 1, 1); - lgroup4->setColStretch(2, 1); - - main->activate(); - -} - -void TDMSessionsWidget::makeReadOnly() -{ - sdlcombo->setEnabled(false); - sdrcombo->setEnabled(false); - - restart_lined->lineEdit()->setReadOnly(true); - restart_lined->button()->setEnabled(false); - shutdown_lined->lineEdit()->setReadOnly(true); - shutdown_lined->button()->setEnabled(false); - - bm_combo->setEnabled(false); -} - -void TDMSessionsWidget::writeSD(TQComboBox *combo) -{ - TQString what; - switch (combo->currentItem()) { - case SdAll: what = "All"; break; - case SdRoot: what = "Root"; break; - default: what = "None"; break; - } - config->writeEntry( "AllowShutdown", what); -} - -void TDMSessionsWidget::save() -{ - config->setGroup("X-:*-Core"); - writeSD(sdlcombo); - - config->setGroup("X-*-Core"); - writeSD(sdrcombo); - - config->setGroup("Shutdown"); - config->writeEntry("HaltCmd", shutdown_lined->url(), true); - config->writeEntry("RebootCmd", restart_lined->url(), true); - - config->writeEntry("BootManager", bm_combo->currentId()); -} - -void TDMSessionsWidget::readSD(TQComboBox *combo, TQString def) -{ - TQString str = config->readEntry("AllowShutdown", def); - SdModes sdMode; - if(str == "All") - sdMode = SdAll; - else if(str == "Root") - sdMode = SdRoot; - else - sdMode = SdNone; - combo->setCurrentItem(sdMode); -} - -void TDMSessionsWidget::load() -{ - config->setGroup("X-:*-Core"); - readSD(sdlcombo, "All"); - - config->setGroup("X-*-Core"); - readSD(sdrcombo, "Root"); - - config->setGroup("Shutdown"); - restart_lined->setURL(config->readEntry("RebootCmd", "/sbin/reboot")); - shutdown_lined->setURL(config->readEntry("HaltCmd", "/sbin/poweroff")); - - bm_combo->setCurrentId(config->readEntry("BootManager", "None")); -} - - - -void TDMSessionsWidget::defaults() -{ - restart_lined->setURL("/sbin/reboot"); - shutdown_lined->setURL("/sbin/poweroff"); - - sdlcombo->setCurrentItem(SdAll); - sdrcombo->setCurrentItem(SdRoot); - - bm_combo->setCurrentId("None"); -} - - -void TDMSessionsWidget::changed() -{ - emit changed(true); -} - -#include "tdm-shut.moc" diff --git a/kcontrol/kdm/kdm-shut.h b/kcontrol/kdm/kdm-shut.h deleted file mode 100644 index bbc6fdc29..000000000 --- a/kcontrol/kdm/kdm-shut.h +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of the KDE Display Manager Configuration package - Copyright (C) 1997 Thomas Tanghus (tanghus@earthling.net) - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __TDMSESS_H__ -#define __TDMSESS_H__ - - -#include - -class TQComboBox; -class TQCheckBox; -class KURLRequester; -class KBackedComboBox; - -class TDMSessionsWidget : public TQWidget -{ - Q_OBJECT - -public: - TDMSessionsWidget(TQWidget *parent=0, const char *name=0); - - void load(); - void save(); - void defaults(); - void makeReadOnly(); - - enum SdModes { SdAll, SdRoot, SdNone }; - -signals: - void changed( bool state ); - -protected slots: - void changed(); - -private: - void readSD (TQComboBox *, TQString); - void writeSD (TQComboBox *); - - TQComboBox *sdlcombo, *sdrcombo; - TQLabel *sdllabel, *sdrlabel; - KURLRequester *restart_lined, *shutdown_lined; - KBackedComboBox *bm_combo; -}; - - -#endif - - diff --git a/kcontrol/kdm/kdm-users.cpp b/kcontrol/kdm/kdm-users.cpp deleted file mode 100644 index f4b48b9a6..000000000 --- a/kcontrol/kdm/kdm-users.cpp +++ /dev/null @@ -1,500 +0,0 @@ -/* This file is part of the KDE Display Manager Configuration package - Copyright (C) 1997 Thomas Tanghus (tanghus@earthling.net) - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tdm-users.h" - -#include - - -extern KSimpleConfig *config; - -TDMUsersWidget::TDMUsersWidget(TQWidget *parent, const char *name) - : TQWidget(parent, name) -{ -#ifdef __linux__ - struct stat st; - if (!stat( "/etc/debian_version", &st )) { /* debian */ - defminuid = "1000"; - defmaxuid = "29999"; - } else if (!stat( "/usr/portage", &st )) { /* gentoo */ - defminuid = "1000"; - defmaxuid = "65000"; - } else if (!stat( "/etc/mandrake-release", &st )) { /* mandrake - check before redhat! */ - defminuid = "500"; - defmaxuid = "65000"; - } else if (!stat( "/etc/redhat-release", &st )) { /* redhat */ - defminuid = "100"; - defmaxuid = "65000"; - } else /* if (!stat( "/etc/SuSE-release", &st )) */ { /* suse */ - defminuid = "500"; - defmaxuid = "65000"; - } -#else - defminuid = "1000"; - defmaxuid = "65000"; -#endif - - // We assume that $kde_datadir/tdm exists, but better check for pics/ and pics/users, - // and create them if necessary. - config->setGroup( "X-*-Greeter" ); - m_userPixDir = config->readEntry( "FaceDir", KGlobal::dirs()->resourceDirs("data").last() + "tdm/faces" ) + '/'; - m_notFirst = false; - TQDir testDir( m_userPixDir ); - if ( !testDir.exists() && !testDir.mkdir( testDir.absPath() ) && !geteuid() ) - KMessageBox::sorry( this, i18n("Unable to create folder %1").arg( testDir.absPath() ) ); - chmod( TQFile::encodeName( m_userPixDir ), 0755 ); - - m_defaultText = i18n(""); - - TQString wtstr; - - minGroup = new TQGroupBox( 2, Qt::Horizontal, i18n("System U&IDs"), this ); - TQWhatsThis::add( minGroup, i18n("Users with a UID (numerical user identification) outside this range will not be listed by TDM and this setup dialog." - " Note that users with the UID 0 (typically root) are not affected by this and must be" - " explicitly hidden in \"Not hidden\" mode.")); - TQSizePolicy sp_ign_fix( TQSizePolicy::Ignored, TQSizePolicy::Fixed ); - TQValidator *valid = new TQIntValidator( 0, 999999, TQT_TQOBJECT(minGroup) ); - TQLabel *minlab = new TQLabel( i18n("Below:"), minGroup ); - leminuid = new KLineEdit( minGroup ); - minlab->setBuddy( leminuid ); - leminuid->setSizePolicy( sp_ign_fix ); - leminuid->setValidator( valid ); - connect( leminuid, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotChanged()) ); - connect( leminuid, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotMinMaxChanged()) ); - TQLabel *maxlab = new TQLabel( i18n("Above:"), minGroup ); - lemaxuid = new KLineEdit( minGroup ); - maxlab->setBuddy( lemaxuid ); - lemaxuid->setSizePolicy( sp_ign_fix ); - lemaxuid->setValidator( valid ); - connect(lemaxuid, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotChanged()) ); - connect(lemaxuid, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotMinMaxChanged()) ); - - usrGroup = new TQButtonGroup( 5, Qt::Vertical, i18n("Users"), this ); - connect( usrGroup, TQT_SIGNAL(clicked( int )), TQT_SLOT(slotShowOpts()) ); - connect( usrGroup, TQT_SIGNAL(clicked( int )), TQT_SLOT(slotChanged()) ); - cbshowlist = new TQCheckBox( i18n("Show list"), usrGroup ); - TQWhatsThis::add( cbshowlist, i18n("If this option is checked, TDM will show a list of users," - " so users can click on their name or image rather than typing in their login.") ); - cbcomplete = new TQCheckBox( i18n("Autocompletion"), usrGroup ); - TQWhatsThis::add( cbcomplete, i18n("If this option is checked, TDM will automatically complete" - " user names while they are typed in the line edit.") ); - cbinverted = new TQCheckBox( i18n("Inverse selection"), usrGroup ); - TQWhatsThis::add( cbinverted, i18n("This option specifies how the users for \"Show list\" and \"Autocompletion\"" - " are selected in the \"Select users and groups\" list: " - "If not checked, select only the checked users. " - "If checked, select all non-system users, except the checked ones.")); - cbusrsrt = new TQCheckBox( i18n("Sor&t users"), usrGroup ); - connect( cbusrsrt, TQT_SIGNAL(toggled( bool )), TQT_SLOT(slotChanged()) ); - TQWhatsThis::add( cbusrsrt, i18n("If this is checked, TDM will alphabetically sort the user list." - " Otherwise users are listed in the order they appear in the password file.") ); - - wstack = new TQWidgetStack( this ); - s_label = new TQLabel( wstack, i18n("S&elect users and groups:"), this ); - optinlv = new KListView( this ); - optinlv->addColumn( i18n("Selected Users") ); - optinlv->setResizeMode( TQListView::LastColumn ); - TQWhatsThis::add( optinlv, i18n("TDM will show all checked users. Entries denoted with '@' are user groups. Checking a group is like checking all users in that group.") ); - wstack->addWidget( optinlv ); - connect( optinlv, TQT_SIGNAL(clicked( TQListViewItem * )), - TQT_SLOT(slotUpdateOptIn( TQListViewItem * )) ); - connect( optinlv, TQT_SIGNAL(clicked( TQListViewItem * )), - TQT_SLOT(slotChanged()) ); - optoutlv = new KListView( this ); - optoutlv->addColumn( i18n("Hidden Users") ); - optoutlv->setResizeMode( TQListView::LastColumn ); - TQWhatsThis::add( optoutlv, i18n("TDM will show all non-checked non-system users. Entries denoted with '@' are user groups. Checking a group is like checking all users in that group.") ); - wstack->addWidget( optoutlv ); - connect( optoutlv, TQT_SIGNAL(clicked( TQListViewItem * )), - TQT_SLOT(slotUpdateOptOut( TQListViewItem * )) ); - connect( optoutlv, TQT_SIGNAL(clicked( TQListViewItem * )), - TQT_SLOT(slotChanged()) ); - - faceGroup = new TQButtonGroup( 5, Qt::Vertical, i18n("User Image Source"), this ); - TQWhatsThis::add( faceGroup, i18n("Here you can specify where TDM will obtain the images that represent users." - " \"Admin\" represents the global folder; these are the pictures you can set below." - " \"User\" means that TDM should read the user's $HOME/.face.icon file." - " The two selections in the middle define the order of preference if both sources are available.") ); - connect( faceGroup, TQT_SIGNAL(clicked( int )), TQT_SLOT(slotFaceOpts()) ); - connect( faceGroup, TQT_SIGNAL(clicked( int )), TQT_SLOT(slotChanged()) ); - rbadmonly = new TQRadioButton( i18n("Admin"), faceGroup ); - rbprefadm = new TQRadioButton( i18n("Admin, user"), faceGroup ); - rbprefusr = new TQRadioButton( i18n("User, admin"), faceGroup ); - rbusronly = new TQRadioButton( i18n("User"), faceGroup ); - - TQGroupBox *picGroup = new TQVGroupBox( i18n("User Images"), this ); - TQWidget *hlpw = new TQWidget( picGroup ); - usercombo = new KComboBox( hlpw ); - TQWhatsThis::add( usercombo, i18n("The user the image below belongs to.") ); - connect( usercombo, TQT_SIGNAL(activated( int )), - TQT_SLOT(slotUserSelected()) ); - TQLabel *userlabel = new TQLabel( usercombo, i18n("User:"), hlpw ); - userbutton = new TQPushButton( hlpw ); - userbutton->setAcceptDrops( true ); - userbutton->installEventFilter( this ); // for drag and drop - uint sz = style().pixelMetric( TQStyle::PM_ButtonMargin ) * 2 + 48; - userbutton->setFixedSize( sz, sz ); - connect( userbutton, TQT_SIGNAL(clicked()), - TQT_SLOT(slotUserButtonClicked()) ); - TQToolTip::add( userbutton, i18n("Click or drop an image here") ); - TQWhatsThis::add( userbutton, i18n("Here you can see the image assigned to the user selected in the combo box above. Click on the image button to select from a list" - " of images or drag and drop your own image on to the button (e.g. from Konqueror).") ); - rstuserbutton = new TQPushButton( i18n("Unset"), hlpw ); - TQWhatsThis::add( rstuserbutton, i18n("Click this button to make TDM use the default image for the selected user.") ); - connect( rstuserbutton, TQT_SIGNAL(clicked()), - TQT_SLOT(slotUnsetUserPix()) ); - TQGridLayout *hlpl = new TQGridLayout( hlpw, 3, 2, 0, KDialog::spacingHint() ); - hlpl->addWidget( userlabel, 0, 0 ); -// hlpl->addSpacing( KDialog::spacingHint() ); - hlpl->addWidget( usercombo, 0, 1 ); - hlpl->addMultiCellWidget( userbutton, 1,1, 0,1, Qt::AlignHCenter ); - hlpl->addMultiCellWidget( rstuserbutton, 2,2, 0,1, Qt::AlignHCenter ); - - TQHBoxLayout *main = new TQHBoxLayout( this, 10 ); - - TQVBoxLayout *lLayout = new TQVBoxLayout( main, 10 ); - lLayout->addWidget( minGroup ); - lLayout->addWidget( usrGroup ); - lLayout->addStretch( 1 ); - - TQVBoxLayout *mLayout = new TQVBoxLayout( main, 10 ); - mLayout->addWidget( s_label ); - mLayout->addWidget( wstack ); - mLayout->setStretchFactor( wstack, 1 ); - main->setStretchFactor( mLayout, 1 ); - - TQVBoxLayout *rLayout = new TQVBoxLayout( main, 10 ); - rLayout->addWidget( faceGroup ); - rLayout->addWidget( picGroup ); - rLayout->addStretch( 1 ); - -} - -void TDMUsersWidget::makeReadOnly() -{ - leminuid->setReadOnly(true); - lemaxuid->setReadOnly(true); - cbshowlist->setEnabled(false); - cbcomplete->setEnabled(false); - cbinverted->setEnabled(false); - cbusrsrt->setEnabled(false); - rbadmonly->setEnabled(false); - rbprefadm->setEnabled(false); - rbprefusr->setEnabled(false); - rbusronly->setEnabled(false); - wstack->setEnabled(false); - disconnect( userbutton, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotUserButtonClicked()) ); - userbutton->setAcceptDrops(false); - rstuserbutton->setEnabled(false); -} - -void TDMUsersWidget::slotShowOpts() -{ - bool en = cbshowlist->isChecked() || cbcomplete->isChecked(); - cbinverted->setEnabled( en ); - cbusrsrt->setEnabled( en ); - wstack->setEnabled( en ); - wstack->raiseWidget( cbinverted->isChecked() ? optoutlv : optinlv ); - en = cbshowlist->isChecked(); - faceGroup->setEnabled( en ); - if (!en) { - usercombo->setEnabled( false ); - userbutton->setEnabled( false ); - rstuserbutton->setEnabled( false ); - } else - slotFaceOpts(); -} - -void TDMUsersWidget::slotFaceOpts() -{ - bool en = !rbusronly->isChecked(); - usercombo->setEnabled( en ); - userbutton->setEnabled( en ); - if (en) - slotUserSelected(); - else - rstuserbutton->setEnabled( false ); -} - -void TDMUsersWidget::slotUserSelected() -{ - TQString user = usercombo->currentText(); - TQImage p; - if (user != m_defaultText && - p.load( m_userPixDir + user + ".face.icon" )) { - rstuserbutton->setEnabled( !getuid() ); - } else { - p.load( m_userPixDir + ".default.face.icon" ); - rstuserbutton->setEnabled( false ); - } - userbutton->setPixmap( p.smoothScale( 48, 48, TQ_ScaleMin ) ); -} - - -void TDMUsersWidget::changeUserPix(const TQString &pix) -{ - TQString user( usercombo->currentText() ); - if (user == m_defaultText) - { - user = ".default"; - if (KMessageBox::questionYesNo(this, i18n("Save image as default image?"),TQString::null,KStdGuiItem::save(),KStdGuiItem::cancel()) - != KMessageBox::Yes) - return; - } - - TQImage p( pix ); - if (p.isNull()) { - KMessageBox::sorry( this, - i18n("There was an error loading the image\n" - "%1").arg( pix ) ); - return; - } - - p = p.smoothScale( 48, 48, TQ_ScaleMin ); - TQString userpix = m_userPixDir + user + ".face.icon"; - if (!p.save( userpix, "PNG" )) - KMessageBox::sorry(this, - i18n("There was an error saving the image:\n%1") - .arg( userpix ) ); - else - chmod( TQFile::encodeName( userpix ), 0644 ); - - slotUserSelected(); -} - -void TDMUsersWidget::slotUserButtonClicked() -{ - KFileDialog dlg(m_notFirst ? TQString::null : - KGlobal::dirs()->resourceDirs("data").last() + "tdm/pics/users", - KImageIO::pattern( KImageIO::Reading ), - this, 0, true); - dlg.setOperationMode( KFileDialog::Opening ); - dlg.setCaption( i18n("Choose Image") ); - dlg.setMode( KFile::File | KFile::LocalOnly ); - - KImageFilePreview *ip = new KImageFilePreview( &dlg ); - dlg.setPreviewWidget( ip ); - if (dlg.exec() != TQDialog::Accepted) - return; - m_notFirst = true; - - changeUserPix( dlg.selectedFile() ); -} - -void TDMUsersWidget::slotUnsetUserPix() -{ - TQFile::remove( m_userPixDir + usercombo->currentText() + ".face.icon" ); - slotUserSelected(); -} - -bool TDMUsersWidget::eventFilter(TQObject *, TQEvent *e) -{ - if (e->type() == TQEvent::DragEnter) { - TQDragEnterEvent *ee = (TQDragEnterEvent *) e; - ee->accept( KURLDrag::canDecode(ee) ); - return true; - } - - if (e->type() == TQEvent::Drop) { - userButtonDropEvent((TQDropEvent *) e); - return true; - } - - return false; -} - -KURL *decodeImgDrop(TQDropEvent *e, TQWidget *wdg); - -void TDMUsersWidget::userButtonDropEvent(TQDropEvent *e) -{ - KURL *url = decodeImgDrop(e, this); - if (url) { - TQString pixpath; - KIO::NetAccess::download(*url, pixpath, parentWidget()); - changeUserPix( pixpath ); - KIO::NetAccess::removeTempFile(pixpath); - delete url; - } -} - -void TDMUsersWidget::save() -{ - config->setGroup( "X-*-Greeter" ); - - config->writeEntry( "MinShowUID", leminuid->text() ); - config->writeEntry( "MaxShowUID", lemaxuid->text() ); - - config->writeEntry( "UserList", cbshowlist->isChecked() ); - config->writeEntry( "UserCompletion", cbcomplete->isChecked() ); - config->writeEntry( "ShowUsers", - cbinverted->isChecked() ? "NotHidden" : "Selected" ); - config->writeEntry( "SortUsers", cbusrsrt->isChecked() ); - - config->writeEntry( "HiddenUsers", hiddenUsers ); - config->writeEntry( "SelectedUsers", selectedUsers ); - - config->writeEntry( "FaceSource", - rbadmonly->isChecked() ? "AdminOnly" : - rbprefadm->isChecked() ? "PreferAdmin" : - rbprefusr->isChecked() ? "PreferUser" : "UserOnly" ); -} - - -void TDMUsersWidget::updateOptList( TQListViewItem *item, TQStringList &list ) -{ - if ( !item ) - return; - TQCheckListItem *itm = (TQCheckListItem *)item; - TQStringList::iterator it = list.find( itm->text() ); - if (itm->isOn()) { - if (it == list.end()) - list.append( itm->text() ); - } else { - if (it != list.end()) - list.remove( it ); - } -} - -void TDMUsersWidget::slotUpdateOptIn( TQListViewItem *item ) -{ - updateOptList( item, selectedUsers ); -} - -void TDMUsersWidget::slotUpdateOptOut( TQListViewItem *item ) -{ - updateOptList( item, hiddenUsers ); -} - -void TDMUsersWidget::slotClearUsers() -{ - optinlv->clear(); - optoutlv->clear(); - usercombo->clear(); - usercombo->insertItem( m_defaultText ); -} - -void TDMUsersWidget::slotAddUsers(const TQMap &users) -{ - TQMapConstIterator it; - for (it = users.begin(); it != users.end(); ++it) { - const TQString *name = &it.key(); - (new TQCheckListItem(optinlv, *name, TQCheckListItem::CheckBox))-> - setOn(selectedUsers.find(*name) != selectedUsers.end()); - (new TQCheckListItem(optoutlv, *name, TQCheckListItem::CheckBox))-> - setOn(hiddenUsers.find(*name) != hiddenUsers.end()); - if ((*name)[0] != '@') - usercombo->insertItem(*name); - } - optinlv->sort(); - optoutlv->sort(); - if (usercombo->listBox()) - usercombo->listBox()->sort(); -} - -void TDMUsersWidget::slotDelUsers(const TQMap &users) -{ - TQMapConstIterator it; - for (it = users.begin(); it != users.end(); ++it) { - const TQString *name = &it.key(); - if (usercombo->listBox()) - delete usercombo->listBox()->findItem( *name, ExactMatch | CaseSensitive ); - delete optinlv->findItem( *name, 0 ); - delete optoutlv->findItem( *name, 0 ); - } -} - -void TDMUsersWidget::load() -{ - TQString str; - - config->setGroup("X-*-Greeter"); - - selectedUsers = config->readListEntry( "SelectedUsers"); - hiddenUsers = config->readListEntry( "HiddenUsers"); - - leminuid->setText(config->readEntry("MinShowUID", defminuid)); - lemaxuid->setText(config->readEntry("MaxShowUID", defmaxuid)); - - cbshowlist->setChecked( config->readBoolEntry( "UserList", true ) ); - cbcomplete->setChecked( config->readBoolEntry( "UserCompletion", false ) ); - cbinverted->setChecked( config->readEntry( "ShowUsers" ) != "Selected" ); - cbusrsrt->setChecked(config->readBoolEntry("SortUsers", true)); - - TQString ps = config->readEntry( "FaceSource" ); - if (ps == TQString::fromLatin1("UserOnly")) - rbusronly->setChecked(true); - else if (ps == TQString::fromLatin1("PreferUser")) - rbprefusr->setChecked(true); - else if (ps == TQString::fromLatin1("PreferAdmin")) - rbprefadm->setChecked(true); - else - rbadmonly->setChecked(true); - - slotUserSelected(); - - slotShowOpts(); - slotFaceOpts(); -} - -void TDMUsersWidget::defaults() -{ - leminuid->setText( defminuid ); - lemaxuid->setText( defmaxuid ); - cbshowlist->setChecked( true ); - cbcomplete->setChecked( false ); - cbinverted->setChecked( true ); - cbusrsrt->setChecked( true ); - rbadmonly->setChecked( true ); - hiddenUsers.clear(); - selectedUsers.clear(); - slotShowOpts(); - slotFaceOpts(); -} - -void TDMUsersWidget::slotMinMaxChanged() -{ - emit setMinMaxUID( leminuid->text().toInt(), lemaxuid->text().toInt() ); -} - -void TDMUsersWidget::slotChanged() -{ - emit changed(true); -} - -#include "tdm-users.moc" diff --git a/kcontrol/kdm/kdm-users.h b/kcontrol/kdm/kdm-users.h deleted file mode 100644 index 8a87c28dd..000000000 --- a/kcontrol/kdm/kdm-users.h +++ /dev/null @@ -1,106 +0,0 @@ -/* This file is part of the KDE Display Manager Configuration package - Copyright (C) 1997 Thomas Tanghus (tanghus@earthling.net) - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __TDMUSERS_H__ -#define __TDMUSERS_H__ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - - -class TDMUsersWidget : public TQWidget -{ - Q_OBJECT - -public: - TDMUsersWidget( TQWidget *parent = 0, const char *name = 0 ); - - void load(); - void save(); - void defaults(); - void makeReadOnly(); - - bool eventFilter( TQObject *o, TQEvent *e ); - -public slots: - void slotClearUsers(); - void slotAddUsers( const TQMap & ); - void slotDelUsers( const TQMap & ); - -signals: - void changed( bool state ); - void setMinMaxUID( int, int ); - -private slots: - void slotMinMaxChanged(); - void slotShowOpts(); - void slotUpdateOptIn( TQListViewItem *item ); - void slotUpdateOptOut( TQListViewItem *item ); - void slotUserSelected(); - void slotUnsetUserPix(); - void slotFaceOpts(); - void slotUserButtonClicked(); - void slotChanged(); - -private: - void updateOptList( TQListViewItem *item, TQStringList &list ); - void userButtonDropEvent( TQDropEvent *e ); - void changeUserPix( const TQString & ); - - TQGroupBox *minGroup; // top left - TQLineEdit *leminuid, *lemaxuid; - - TQButtonGroup *usrGroup; // right below - TQCheckBox *cbshowlist, *cbcomplete, *cbinverted, *cbusrsrt; - - TQLabel *s_label; // middle - TQWidgetStack *wstack; - KListView *optoutlv, *optinlv; - - TQButtonGroup *faceGroup; // right - TQRadioButton *rbadmonly, *rbprefadm, *rbprefusr, *rbusronly; - - KComboBox *usercombo; // right below - TQPushButton *userbutton; - TQPushButton *rstuserbutton; - - TQString m_userPixDir; - TQString m_defaultText; - TQStringList hiddenUsers, selectedUsers; - TQString defminuid, defmaxuid; - - bool m_notFirst; -}; - -#endif - - diff --git a/kcontrol/kdm/kdm.desktop b/kcontrol/kdm/kdm.desktop deleted file mode 100644 index 978918ec4..000000000 --- a/kcontrol/kdm/kdm.desktop +++ /dev/null @@ -1,243 +0,0 @@ -[Desktop Entry] -Exec=kcmshell tdm -Icon=tdmconfig -Type=Application -DocPath=tdm/index.html#configuring-tdm - -X-KDE-SubstituteUID=true - -X-KDE-Library=tdm -X-KDE-RootOnly=true - -X-KDE-ParentApp=kcontrol - -Name=Login Manager -Name[af]=Aanteken Bestuurder -Name[ar]=مسيير تسجيل الدخول -Name[az]=İclas Açma İdarəcisi -Name[be]=Кіраўнік уваходу -Name[bg]=Вход в системата -Name[bn]=লগ-ইন ম্যানেজার -Name[br]=Merour ereañ -Name[bs]=Login menadžer -Name[ca]=Gestor d'accés -Name[cs]=Správce přihlášení -Name[csb]=Menedżer logòwaniô -Name[cy]=Rheolydd Mewngofnodi -Name[da]=Login-håndtering -Name[de]=Anmeldungsmanager -Name[el]=Διαχειριστής σύνδεσης -Name[eo]=Salutilo -Name[es]=Gestor de acceso -Name[et]=Sisselogimise haldur -Name[eu]=Saio-hasieraren kudeatzailea -Name[fa]=مدیر ورود -Name[fi]=Sisäänkirjautumisasetukset -Name[fr]=Gestionnaire de connexion -Name[fy]=Oanmeldskerm -Name[ga]=Bainisteoir Logála Isteach -Name[gl]=Xestor de Login -Name[he]=מנהל הכניסה למערכת -Name[hi]=लॉगइन प्रबंधक -Name[hr]=Upravljanje prijavljivanjem -Name[hu]=Bejelentkező felület (TDM) -Name[id]=Manajer Login -Name[is]=Innstimplunarstjóri -Name[it]=Gestione degli accessi -Name[ja]=ログインマネージャ -Name[ka]=შესვლის მენეჯერი -Name[kk]=Жүйеге кіруді басқару -Name[km]=កម្មវិធី​គ្រប់គ្រង​ការ​ចូល -Name[ko]=로그인 관리자 -Name[lo]=ຈັດການລັອກອິນ -Name[lt]=Registravimosi tvarkyklė -Name[lv]=Pieteikšanās Menedžeris -Name[mk]=Менаџер на најави -Name[mn]=Нэвтрэлт удирдагч -Name[ms]=Pengurus Login -Name[mt]=Manager tal-Login -Name[nb]=Innloggingsbehandler -Name[nds]=Anmellen-Schirm -Name[ne]=लगइन प्रबन्धक -Name[nl]=Aanmeldscherm -Name[nn]=Innloggingshandsamar -Name[nso]=Molaodi wa Tseno -Name[oc]=Gestionari de connexion -Name[pa]=ਲਾਗ ਮੈਨੇਜਰ -Name[pl]=Menedżer logowania -Name[pt]=Gestor de Autenticação -Name[pt_BR]=Gerenciador de Login -Name[ro]=Managerul de logare -Name[ru]=Менеджер входа в систему -Name[rw]=Mugenga w'Ifashayinjira -Name[se]=Sisačálihangieđahalli -Name[sk]=Správca prihlásenia -Name[sl]=Upravitelj prijav -Name[sr]=Менаџер пријављивања -Name[sr@Latn]=Menadžer prijavljivanja -Name[sv]=Inloggningshanterare -Name[ta]=நுழைவு மேலாளர் -Name[te]=లాగిన్ అభికర్త -Name[tg]=Мудири вуруд -Name[th]=ตัวจัดการการล็อกอิน -Name[tr]=Giriş Yöneticisi -Name[tt]=Kerü İdäçese -Name[uk]=Менеджер реєстрації -Name[uz]=Kirish boshqaruvchisi -Name[uz@cyrillic]=Кириш бошқарувчиси -Name[ven]=Mulanguli wa u loga -Name[vi]=Trình quản lí Đăng nhập -Name[wa]=Manaedjeu d' elodjaedje -Name[xh]=Umphathi Wegama elithile -Name[zh_CN]=登录管理器 -Name[zh_TW]=登錄管理程式 -Name[zu]=Imenenja yokungena ngaphakathi - -Comment=Configure the login manager (TDM) -Comment[af]=Konfigureer die aanteken bestuurder (Kdm) -Comment[ar]=إعداد مسيير الدخول (TDM) -Comment[az]=Giriş İdarəçisi (TDM) Qurğuları -Comment[be]=Настаўленні кіраўніка ўваходу (TDM) -Comment[bg]=Настройване на графичната системата за вход -Comment[bn]=লগ-ইন ম্যানেজার কনফিগার করুন -Comment[br]=Kefluniañ ar merour ereañ (TDM) -Comment[bs]=Podesite menadžer prijavom (TDM) -Comment[ca]=Configura el gestor d'accés (TDM) -Comment[cs]=Nastavení správce přihlášení (TDM) -Comment[csb]=Kònfigùracëjô menedżera logòwaniô (TDM) -Comment[cy]=Ffurfweddu y rheolydd mewngofnodi (TDM) -Comment[da]=Indstil indlogningshåndtering (TDM) -Comment[de]=Anmeldungsmanager TDM einrichten -Comment[el]=Ρυθμίστε το διαχειριστή σύνδεσης (TDM) -Comment[eo]=Agordu la salutadminstrilon (TDM) -Comment[es]=Configura el gestor de acceso (TDM) -Comment[et]=Sisselogimise halduri seadistamine (TDM) -Comment[eu]=Konfiguratu saio-hasieraren kudeatzailea (TDM) -Comment[fa]=پیکربندی مدیر ورود (TDM) -Comment[fi]=Sisäänkirjautumisasetukset -Comment[fr]=Configuration du gestionnaire de connexion (TDM) -Comment[fy]=Hjir kinne jo it oanmeldskerm ynstelle (TDM) -Comment[ga]=Cumraigh an bainisteoir logála isteach (TDM) -Comment[gl]=Configurar o xestor de início (TDM) -Comment[he]=שינוי הגדרות מנהל הכניסה למערכת (TDM) -Comment[hi]=लॉगइन प्रबंधक कॉन्फ़िगर करें (केडीएम) -Comment[hr]=Konfiguriranje upravljanja prijavljivanja (TDM) -Comment[hu]=A KDE grafikus bejelentkező felületének beállításai -Comment[is]=Stilla innstimplunarstjórann (TDM) -Comment[it]=Configurazione della gestione degli accessi (TDM) -Comment[ja]=ログインマネージャ (TDM) の設定 -Comment[ka]=შევლის მენეჯერის კონფიგურირება (TDM) -Comment[kk]=Жүйеге кіруді басқаруын (TDM) баптау -Comment[km]=កំណត់​រចនាសម្ព័ន្ធ​កម្មវិធី​គ្រប់គ្រង​ការ​ចូល (TDM) -Comment[ko]=로그인 관리자 TDM 설정 -Comment[lo]=ປັບແຕ່ງປລັກອິນແລະການເຊື່ອມ ຕໍ່ສຳລັບລະບົບ KDB -Comment[lt]=Konfigūruoti registravimos tvarkyklę (TDM) -Comment[lv]=Konfigure pieteiksanās menedžeri TDM -Comment[mk]=Конфигурирајте го менаџерот на најави (TDM) -Comment[mn]=Нэвтрэлт удирдагч TDM тохируулах -Comment[ms]=Konfigur pengurus login (TDM) -Comment[mt]=Ikkonfigura l-manager tal-logins (TDM) -Comment[nb]=Tilpass innlogin­gsbehandler (TDM) -Comment[nds]=Den Anmellen-Schirm instellen (TDM) -Comment[ne]=लगइन प्रबन्धक (TDM) कन्फिगर गर्नुहोस् -Comment[nl]=Hier kunt u het aanmeldscherm (TDM) instellen -Comment[nn]=Set opp innloggingshandsamaren (TDM) -Comment[nso]=Beakanya molaodoi wa tseno (TDM) -Comment[pa]=ਲਾਗਆਨ ਮੈਨੇਜਰ ਸੰਰਚਨਾ(TDM) -Comment[pl]=Konfiguracja menedżera logowania (TDM) -Comment[pt]=Configuração do gestor de autenticação (TDM) -Comment[pt_BR]=Configura o gerenciador de login (TDM) -Comment[ro]=Configurează managerul de logare grafică (TDM) -Comment[ru]=Настройка менеджера входа в систему (TDM) -Comment[rw]=Kuboneza mugenga w'ifashayinjira (TDM) -Comment[se]=Heivet sisačálihangieđahalli (TDM) -Comment[sk]=Nastavenie správcu prihlásenia (TDM) -Comment[sl]=Nastavitve upravitelja prijav (TDM) -Comment[sr]=Подешавање менаџера за пријављивање (TDM) -Comment[sr@Latn]=Podešavanje menadžera za prijavljivanje (TDM) -Comment[sv]=Anpassa inloggningshanteraren (TDM) -Comment[ta]=புகுபதிகை மேலாளரை அமை (TDM) -Comment[tg]=Танзими мудири вуруд (TDM) -Comment[th]=ปรับแต่งเครื่องมือจัดการการล็อกอิน (TDM) -Comment[tr]=Giriş yöneticisini yapılandır (TDM) -Comment[tt]=Kerü idäräçen caylaw urını (TDM) -Comment[uk]=Налаштування менеджера реєстрації (TDM) -Comment[uz]=Tizimga kirish boshqaruvchisini (TDM) moslash -Comment[uz@cyrillic]=Тизимга кириш бошқарувчисини (TDM) мослаш -Comment[ven]=Ni nga dzudzanya mulanguli wau loga (TDM) -Comment[vi]=Cấu hình trình đăng nhập (TDM) -Comment[wa]=Apontyî l' manaedjeu d' elodjaedje (TDM) -Comment[xh]=Qwalasela umphathi wegama elithile (TDM) -Comment[zh_CN]=配置登录管理器(TDM) -Comment[zh_TW]=設定登入管理程式 (TDM) -Comment[zu]=Hlanganisela imenenja yokungena ngaphakathi (TDM) - -Keywords=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart -Keywords[ar]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,مدير العرض,المستخدمون مستخدمون,المستخدمين,مستخدمين,دخول,الدخول,تحية,التحية,اللغة,المظهر, البلد,الخطوط,الخط,خطوط,خط,خلفية,ورق حائط,جلسات,اغلاق,اعادة تشغيل -Keywords[az]=tdm,görünüş idarəçi,xdm,istifadəçilər,iclas açma,qarşılama,loqo,tərzlər,dil,ölkə,yazı növləri,arxa plan,divar kağızları,iclaslar,qapat,təkrar başlat -Keywords[be]=кіраўнік дысплея,кіраўнік уваходу,карыстальнікі,уваход,запрашэнне,лагатып,стылі,стыль,мова,краіна,шрыфты,фон,шпалеры,сесіі,сесія,выключэнне,перазагрузка,tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart -Keywords[bg]=графична, система, вход, влизане, включване, потребител, tdm, display manager, xdm, users, login, greeting, Logo, styles, language, country, fonts, background, wallpapers, sessions, shutdown, restart -Keywords[ca]=tdm,administrador de la pantalla,xdm,usuaris,accés,salutació,Logo,estils,llengua,país,lletres,fons,tapissos,sessions,apagar,reiniciar -Keywords[cs]=tdm,Správce obrazovky,xdm,Uživatelé,Přihlášení,Uvítání,Logo,Styly,Jazyk,Země,Písma,pozadí,Tapety,Relace,Sezení,Vypnutí,Restart -Keywords[csb]=tdm,menedżer ekranu,xdm,brëkòwnicë,logòwanié,przëwitanié,Logò,sztéle,jãzëk,kraj,fòntë,spódk,tapetë,spòdlë,sesëje,zamkniãce systemë,resztart,zôczãce robòtë -Keywords[cy]=tdm,rheolydd y dangosydd,xdm,defnyddwyr,mewngofnodi,cyfarchiad,Logo,arddulliau,iaith,gwlad,ffontiau,cefndir,papurau wal,sesiynau,cau,ailgychwyn -Keywords[da]=tdm,skærmhåndtering,xdm,brugere,login,hilsen,Logo,stil, sprog,land,skrifttyper,baggrund,tapeter,sessioner,luk ned,genstart -Keywords[de]=Kdm,Display Manager,Xdm,Benutzer,Login,Logo,Stile,Sprachen,Länder,Schriften,Hintergründe,Hintergrundbilder,Beenden,Neustart -Keywords[el]=tdm,διαχειριστής οθόνης,xdm,χρήστες,σύνδεση,χαιρετισμός,Λογότυπο,στυλ,γλώσσα,χώρα,γραμματοσειρές,φόντο,ταπετσαρίες,συνεδρίες,τερματισμός,επανεκκίνηση -Keywords[eo]=tdm,ekrano,,xdm,uzantoj,saluto,emblemo,stilo,lingvo,lando,tiparo,fono,tapeto,seanco,adaiaŭo,relanĉo -Keywords[es]=tdm,gestor de pantalla,xdm,usuarios,entrada,acceso,saludo,Logo,estilos,idioma,país,tipos de letra,fondo,tapices,sesiones,apagar,reiniciar -Keywords[et]=tdm,ekraanihaldur,xdm,kasutajad,sisselogimine,tervitus,logo,stiil,keel,riik,fondid,taust,taustapilt,seansid,töö lõpetamine,taaskäivitamine -Keywords[eu]=tdm,pantaila kudeatzailea,xdm,erabiltzaileak,Saio hasiera,agurra,Logoa,estiloak,hizkuntza, herrialdea,letra-tipoak,atzeko planoa,horma-irudiak,saioak,itzali,berrabiarazi -Keywords[fa]=tdm، مدیر نمایش، xdm، کاربران، ورود، تبریک، آرمِ، سبک، زبان، کشور، قلمها، زمینه، کاغذهای دیواری، نشستها، تعطیل، بازآغازی -Keywords[fi]=tdm,näytönhallinta ,xdm,käyttäjät,sisäänkirjautuminen,tervehdys,Logo,tyylit,kieli,maa,kirjasimet,tausta,istunnot,sammutus,uudelleenkäynnistys -Keywords[fr]=tdm,gestionnaire d'affichage,xdm,utilisateurs,login,connexion,bienvenue,message de bienvenue,Logo,styles,langue,pays,style,police,fond d'écran,papier peint,session,arrêt,logout,redémarrage,reboot -Keywords[fy]=tdm,display manager,xdm,users,login,begroeting,oanmelde,brûkers,Oanmeldbehearder,logo,stylen,taal,language,country,lân,fonts,lettertypen,eftergrûn,wallpapers,behang,sesjes,shutdown,restart,ôfslute,opnij begjinne,oanmelde -Keywords[ga]=tdm,bainisteoir scáileáin,xdm,úsáideoirí,logáil isteach,fáilte,Lógó,stíleanna,teanga,tír,clónna,clófhoirne,cúlra,cúlbhrait,seisiúin,múchadh,atosú -Keywords[gl]=tdm,xestor de entrada,xdm,usuarios,identificación,Logo,estilos,lingua,país,fontes,fondo,papeis tapiz,sesións,apagado,reinício -Keywords[he]=משתמשים,כניסה למערכת,כניסה,לוגו,סגנונות,שפה,מדינה,גופנים,רקע,טפטים,הפעלות,כיבוי,הפעלה,מחדש,מנהל,תצוגה,display,manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart -Keywords[hi]=केडीएम,प्रकटन प्रबंधक,एक्स-डीएम,उपयोक्ता,लॉगइन,शुभकामनाएँ,लोगो,पृष्ठभूमि,वालपेपर्स,सत्र,बन्द, फिर से चालू -Keywords[hr]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,upravljanje zaslona,korisnici,prijava,pozdrav,stilovi,jezik,država,zemlja,fontovi,pozadina,pozadina radne površine,sesije,gašenje,ponovno pokretanje -Keywords[hu]=tdm,képernyőkezelő,xdm,felhasználók,bejelentkezés,üdvözlés,embléma,stílusok,nyelv,ország,betűtípusok,háttér,tapéták,munkafolyamatok,leállítás,újraindítás -Keywords[is]=tdm,skjár,gluggastjóri,innskráning,innstimplun,snið,tungumál,land,letur,bakgrunnur,bakgrunnar,veggfóður,setur,slökkva,endurræsa -Keywords[it]=tdm,display manager,gestione degli utenti,xdm,utenti,login,accesso,benvenuto,logo,stile,lingua,stato,paese,tipi di carattere,sfondo,immagine di sfondo,sessioni,riavvio,spegnimento,gestione degli accessi -Keywords[ja]=tdm,ディスプレイマネージャ,xdm,ユーザ,ログイン,あいさつ,ロゴ,スタイル,言語,国,フォント,背景,壁紙,セッション,シャットダウン,再起動 -Keywords[km]=tdm,កម្មវិធី​គ្រប់គ្រង​ការ​បង្ហាញ,xdm,អ្នក​ប្រើ,ចូល,ស្វាគមន៍,រូបសញ្ញា,រចនាប័ទ្ម,ភាសា,ប្រទេស,ពុម្ពអក្សរ,ផ្ទៃ​ខាង​ក្រោយ,ក្រដាស​បិទ​ជញ្ជាំង,សម័យ,បិទ,ចាប់ផ្ដើម​ឡើង​វិញ -Keywords[lt]=tdm,display manager,ekrano tvarkyklė,xdm,users,naudotojai,login,registracija,greeting,pasveikinimas,Logo, styles,stiliai,language,country,fonts,background,wallpapers,sessions, shutdown,restart -Keywords[lv]=tdm,displeja menedžeris,xdm,lietotāji,pieteikšanās,apsveikums,Logo,stili,valoda,valsts,fonti,fons,tapetes,sesijas,nošaut,pārstartēt -Keywords[mk]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,менаџер на екран,корисници,најава,поздрав,Лого,стилови,јазик,земја,фонтови,подлога,позадина,сесии,исклучување,рестартирање -Keywords[mn]=Kdm,Display Manager,Xdm,Хэрэглэгч,Login,Logo,Хэлбэр,Хэл,Улс,Бичиг,Дэвсгэр,Дэвсгэр зураг,Дуусгах,Шинээр эхлүүлэх -Keywords[mt]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,merħba,lingwa,pajjiż,sfond,itfi,irristartja -Keywords[nb]=tdm,skjermbehandler,xdm,brukere,innlogging,velkomst,logo,stiler,språk,land,skrifttyper,bakgrunn,bakgrunnsbilde,økter,skru av,slå av,omstart -Keywords[nds]=tdm,Startschirm,xdm,Bruker,anmellen,greeting,Logo,Stilen,Spraak,Land,Schriftoorden,Achtergrund,Tapeten,Törns,Utmaken,Nieg starten -Keywords[ne]=tdm, प्रदर्शन प्रबन्धक, xdm, प्रयोगकर्ताहरू, लगइन, अभिवादन, परिचायक चिन्ह, शैलीहरू, भाषा, देश, फन्टहरू, पृष्ठभूमि,वालपेपरहरू, सत्र, बन्द गर्नुहोस्, फेरि सुरु गर्नुहोस् -Keywords[nl]=tdm,display manager,xdm,users,login,begroeting,inloggen,gebruikers,loginbeheerder,logo,stijlen,taal,language,country,land,fonts,lettertypen,achtergrond,wallpapers,behang,sessies,shutdown,restart,afsluiten,herstarten,aanmelden,opstarten -Keywords[nn]=tdm,xdm,brukarar,innlogging,helsing,logo,stil,språk,land,skrifttypar,bakgrunn,bakgrunnsbilete,økt,avslutt,slå av,omstart -Keywords[nso]=tdm,molaodi wa pontsho,xdm,badirisi,tseno,madume,Logo,mekgwa,leleme,naga,difonto,bokamorago,di-wallpaper,ditiragalo,timo,thomaleswa -Keywords[pa]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart, ਲੋਗੋ, ਭਾਸ਼ਾ, ਦੇਸ਼, ਫੋਂਟ, ਲਾਗਿੰਨ, ਉਪਭੋਗੀ,ਸ਼ੈਸ਼ਨ -Keywords[pl]=tdm,menedżer ekranu,xdm,użytkownicy,logowanie,powitanie,Logo,style,jezyk,kraj,czcionki,tło,tapety,sesje,zamknięcie systemu,restart,rozpoczęcie pracy -Keywords[pt]=tdm,gestor de 'logins',xdm,utilizadores,saudação,logótipo,estilos,língua,país,tipos de letra,fundo,papéis de parede,sessões,terminar,reiniciar -Keywords[pt_BR]=tdm,gerenciador de tela, xdm,usuários,login,saudação,Logo,estilos,linguagem,país,fontes, papéis de parede,sessões,desligar,reiniciar -Keywords[ro]=tdm,manager de ecran,xdm,utilizatori,logare,întîmpinare,logo,stiluri,limbaj,țară,fonturi,fundal,imagini de fundal,sesiuni,oprire,restartare -Keywords[ru]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,перезагрузка,сеанс,шрифты,страна,фон,стили,обои -Keywords[rw]=tdm,kwerekana umuyobozi,xdm,abakoresha,ifashayinjira,gusuhuza,ikirango,imisusire,ururimi,igihugu,imyandikire,mbuganyuma,impapurorukuta,imikoro,kuzimya,kongera gutangiza -Keywords[se]=tdm,xdm,geavaheaddjit,sisačáliheapmi,dearvvuođat,logo,stiila,giella,riika, fonttat,duogáš,duogášgovva,bargovuorut,heaittihit,časkit eret,ođđasit álggahit -Keywords[sk]=tdm,správca obrazovky,Login manažér,správca prihlásenia,xdm,používatelia,prihlásenie,login,privítanie,logo,štýly,jazyk,krajina,pozadie,tapety,sedenia,vypnutie,reset,reštart -Keywords[sl]=tdm,upravitelj zaslona,upravljalnik,xdm,uporabniki,prijava,login,pozdrav,logo,slogi,jezik,država,pisave,ozadje,tapete,seje,ugasnitev,vnovičen zagon -Keywords[sr]=tdm,display manager,xdm,users,login,greeting,Лого,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,менаџер,пријављивање,стил,језик,земља,фонтови,позадина,сесије,гашење -Keywords[sr@Latn]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,menadžer,prijavljivanje,stil,jezik,zemlja,fontovi,pozadina,sesije,gašenje -Keywords[sv]=tdm,display manager,xdm,användare,inloggning,välkomsttext,Logo,stilar,språk,land,teckensnitt,bakgrund,skrivbordsunderlägg,sessioner,stäng av,starta om -Keywords[ta]=கேடிஎம்,காட்சி மேலாளர்,xdm,பயன்படுத்துபவர்,உள்நுழை,வாழ்த்து,சின்னம்,பாணிகள்,மொழி,நாடு,எழுத்துருக்கள்,பின்னணி,வால்பேப்பர்கள்,பகுதிகள்,முடித்தல்,தொடங்குதல் -Keywords[th]=tdm,ตัวจัดการจอแสดงผล,xdm,ผู้ใช้,ล็อกอิน, ทักทาย,โลโก้,รูปแบบ,ภาษา,ประเทศ,แบบอักษร,พื้นหลัง, วอลล์เปเปอร์,วาระ,ปิด,เริ่มการทำงานใหม่ -Keywords[tr]=tdm,görüntü yönetici,xdm,kullanıcılar,oturum açma,karşılama,logo,stiller,dil,ülke,yazı tipleri,artalan,duvar kağıtları,oturumlar,kapat,tekrar başlat -Keywords[uk]=tdm,менеджер дисплеїв,xdm,користувачі,реєстрація,привітання,логотип,стилі,мова,країна,шрифти,тло,шпалери,сеанси,вимикання,перезапуск -Keywords[uz]=tdm,kirish boshqaruvchisi,xdm,foydalanuvchilar,kirish,salomlashish,Belgi,uslublar,til,davlat,shriftlar,orqa fon,seanslar,oʻchirish,oʻchirib-yoqish -Keywords[uz@cyrillic]=tdm,кириш бошқарувчиси,xdm,фойдаланувчилар,кириш,саломлашиш,Белги,услублар,тил,давлат,шрифтлар,орқа фон,сеанслар,ўчириш,ўчириб-ёқиш -Keywords[ven]=tdm,mulanguli wau vhonisa,xdm,vhashumisi,u loga,dzindumeliso,logo,zwitaela,luambo,shango,fontu,murahu,mabammbiri a luvhondoni,tshitenwa,thutha,thomolosa -Keywords[vi]=tdm,quản lý hiển thị,xdm,người dùng,đăng nhập,chào hỏi,Biểu trưng,kiểu,ngôn ngữ,quốc gia,phông chữ,nền,ảnh nền,phiên đăng nhập,tắt máy,khởi động lại -Keywords[wa]=tdm,manaedjeu d' håynaedje,xdm,uzeus,login,wilikom,greeting,Logo,styles,stîles,lingaedje,payi,fontes,fond,fond del waitroûle,sessions,distinde,dislodjî,elodjî,s' elodjî,renonder -Keywords[xh]=tdm,umphathi womboniso,xdm,abasebenzisi,igama elithile,umbuliso,ilogo,iintlobo,ulwimi,ilizwe,ubungakanani bamagama, imvelaphi,amaphepha odonga,iintlanganiso,vala,qala kwakhona -Keywords[zh_CN]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,显示管理器,用户,登录,欢迎辞,标志,风格,语言,国家,字体,背景,墙纸,会话,关机,重启动 -Keywords[zh_TW]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,顯示管理程式,使用者,登入,歡迎,風格,語言,國家,字型,背景,底圖,工作階段,關機,重新啟動 -Keywords[zu]=tdm,Imenenja yokuveza,xdm,abasebenzisi,ukungena ngaphakathi,isibingelelo,Isiqubulo,izitayela,ulimi,izwe,izinhlobo zamagama, inkundla yangemuva,emaphepha ezindonga,iziqendu,vala,phinda uqale - -Categories=Qt;KDE;X-KDE-settings-system; diff --git a/kcontrol/kdm/main.cpp b/kcontrol/kdm/main.cpp deleted file mode 100644 index de4ea0fc7..000000000 --- a/kcontrol/kdm/main.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* - * main.cpp - * - * Copyright (c) 1999 Matthias Hoelzer-Kluepfel - * - * 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 - -#include - -#include -#include -#include -#include -#include - -#include "tdm-appear.h" -#include "tdm-font.h" -#include "tdm-users.h" -#include "tdm-shut.h" -#include "tdm-conv.h" - -#include "main.h" -#include "background.h" - -#include -#include -#include -#include -#include -#include - -typedef KGenericFactory TDMFactory; -K_EXPORT_COMPONENT_FACTORY( kcm_tdm, TDMFactory("tdmconfig") ) - -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; - -TDModule::TDModule(TQWidget *parent, const char *name, const TQStringList &) - : KCModule(TDMFactory::instance(), parent, name) - , minshowuid(0) - , maxshowuid(0) - , updateOK(false) -{ - KAboutData *about = - new KAboutData(I18N_NOOP("kcmtdm"), I18N_NOOP("KDE Login Manager Config Module"), - 0, 0, KAboutData::License_GPL, - I18N_NOOP("(c) 1996 - 2005 The TDM 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( "

Login Manager

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 Modify button to acquire " - "superuser rights. You will be asked for the superuser password." - "

Appearance

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." - "

Font

Here you can choose the fonts that the Login Manager should use " - "for various purposes like greetings and user names. " - "

Background

If you want to set a special background for the login " - "screen, this is where to do it." - "

Shutdown

Here you can specify who is allowed to shutdown/reboot the machine " - "and whether a boot manager should be used." - "

Users

On this tab page, you can select which users the Login Manager " - "will offer you for logging in." - "

Convenience

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.
" - "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 tgmap; - TQMap::Iterator tgmapi; - TQMap::ConstIterator tgmapci; - TQMap >::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( 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 "/tdm/tdmdistrc" ,&st ) == 0) { - config = new KSimpleConfig( TQString::fromLatin1( KDE_CONFDIR "/tdm/tdmdistrc" )); - } - else { - config = new KSimpleConfig( TQString::fromLatin1( KDE_CONFDIR "/tdm/tdmrc" )); - } - - TQVBoxLayout *top = new TQVBoxLayout(this); - tab = new TQTabWidget(this); - - // ***** - // _don't_ add a theme configurator until the theming engine is _really_ done!! - // ***** - - appearance = new TDMAppearanceWidget(this); - tab->addTab(appearance, i18n("A&ppearance")); - connect(appearance, TQT_SIGNAL(changed(bool)), TQT_SIGNAL( changed(bool))); - - font = new TDMFontWidget(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 TDMSessionsWidget(this); - tab->addTab(sessions, i18n("&Shutdown")); - connect(sessions, TQT_SIGNAL(changed(bool)), TQT_SIGNAL(changed(bool))); - - users = new TDMUsersWidget(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 &)), users, TQT_SLOT(slotAddUsers(const TQMap &))); - connect(this, TQT_SIGNAL(delUsers(const TQMap &)), users, TQT_SLOT(slotDelUsers(const TQMap &))); - connect(this, TQT_SIGNAL(clearUsers()), users, TQT_SLOT(slotClearUsers())); - - convenience = new TDMConvenienceWidget(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 &)), convenience, TQT_SLOT(slotAddUsers(const TQMap &))); - connect(this, TQT_SIGNAL(delUsers(const TQMap &)), convenience, TQT_SLOT(slotDelUsers(const TQMap &))); - 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); -} - -TDModule::~TDModule() -{ - delete config; -} - -void TDModule::load() -{ - appearance->load(); - font->load(); - background->load(); - users->load(); - sessions->load(); - convenience->load(); - propagateUsers(); -} - - -void TDModule::save() -{ - appearance->save(); - font->save(); - background->save(); - users->save(); - sessions->save(); - convenience->save(); - config->sync(); -} - - -void TDModule::defaults() -{ - if ( getuid() == 0 ) - { - appearance->defaults(); - font->defaults(); - background->defaults(); - users->defaults(); - sessions->defaults(); - convenience->defaults(); - propagateUsers(); - } -} - -void TDModule::propagateUsers() -{ - groupmap.clear(); - emit clearUsers(); - TQMap lusers; - TQMapConstIterator > it; - TQStringList::ConstIterator jt; - TQMap::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 TDModule::slotMinMaxUID(int min, int max) -{ - if (updateOK) { - TQMap alusers, dlusers; - TQMapConstIterator > it; - TQStringList::ConstIterator jt; - TQMap::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" diff --git a/kcontrol/kdm/main.h b/kcontrol/kdm/main.h deleted file mode 100644 index d613f9c4e..000000000 --- a/kcontrol/kdm/main.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * main.h - * - * Copyright (c) 1999 Matthias Hoelzer-Kluepfel - * - * 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. - */ - -#ifndef __tdm_main_h -#define __tdm_main_h - -#include -#include - -#include - -class TDMAppearanceWidget; -class TDMFontWidget; -class TDMSessionsWidget; -class TDMUsersWidget; -class TDMConvenienceWidget; -class KBackground; - -class TDModule : public KCModule -{ - Q_OBJECT - -public: - - TDModule(TQWidget *parent, const char *name, const TQStringList &); - ~TDModule(); - - void load(); - void save(); - void defaults(); - -public slots: - - void slotMinMaxUID(int min, int max); - -signals: - - void clearUsers(); - void addUsers(const TQMap &); - void delUsers(const TQMap &); - -private: - - TQTabWidget *tab; - - TDMAppearanceWidget *appearance; - KBackground *background; - TDMFontWidget *font; - TDMSessionsWidget *sessions; - TDMUsersWidget *users; - TDMConvenienceWidget *convenience; - - TQMap > usermap; - TQMap groupmap; - int minshowuid, maxshowuid; - bool updateOK; - - void propagateUsers(); - -}; - -#endif - diff --git a/kcontrol/pics/cr128-app-kdmconfig.png b/kcontrol/pics/cr128-app-kdmconfig.png deleted file mode 100644 index f28f704f7..000000000 Binary files a/kcontrol/pics/cr128-app-kdmconfig.png and /dev/null differ diff --git a/kcontrol/pics/cr128-app-tdmconfig.png b/kcontrol/pics/cr128-app-tdmconfig.png new file mode 100644 index 000000000..f28f704f7 Binary files /dev/null and b/kcontrol/pics/cr128-app-tdmconfig.png differ diff --git a/kcontrol/pics/cr16-app-kdmconfig.png b/kcontrol/pics/cr16-app-kdmconfig.png deleted file mode 100644 index 8f69e2b99..000000000 Binary files a/kcontrol/pics/cr16-app-kdmconfig.png and /dev/null differ diff --git a/kcontrol/pics/cr16-app-tdmconfig.png b/kcontrol/pics/cr16-app-tdmconfig.png new file mode 100644 index 000000000..8f69e2b99 Binary files /dev/null and b/kcontrol/pics/cr16-app-tdmconfig.png differ diff --git a/kcontrol/pics/cr22-app-kdmconfig.png b/kcontrol/pics/cr22-app-kdmconfig.png deleted file mode 100644 index 399978a99..000000000 Binary files a/kcontrol/pics/cr22-app-kdmconfig.png and /dev/null differ diff --git a/kcontrol/pics/cr22-app-tdmconfig.png b/kcontrol/pics/cr22-app-tdmconfig.png new file mode 100644 index 000000000..399978a99 Binary files /dev/null and b/kcontrol/pics/cr22-app-tdmconfig.png differ diff --git a/kcontrol/pics/cr32-app-kdmconfig.png b/kcontrol/pics/cr32-app-kdmconfig.png deleted file mode 100644 index a5cbf22d3..000000000 Binary files a/kcontrol/pics/cr32-app-kdmconfig.png and /dev/null differ diff --git a/kcontrol/pics/cr32-app-tdmconfig.png b/kcontrol/pics/cr32-app-tdmconfig.png new file mode 100644 index 000000000..a5cbf22d3 Binary files /dev/null and b/kcontrol/pics/cr32-app-tdmconfig.png differ diff --git a/kcontrol/pics/cr48-app-kdmconfig.png b/kcontrol/pics/cr48-app-kdmconfig.png deleted file mode 100644 index d8b241ca9..000000000 Binary files a/kcontrol/pics/cr48-app-kdmconfig.png and /dev/null differ diff --git a/kcontrol/pics/cr48-app-tdmconfig.png b/kcontrol/pics/cr48-app-tdmconfig.png new file mode 100644 index 000000000..d8b241ca9 Binary files /dev/null and b/kcontrol/pics/cr48-app-tdmconfig.png differ diff --git a/kcontrol/pics/cr64-app-kdmconfig.png b/kcontrol/pics/cr64-app-kdmconfig.png deleted file mode 100644 index 57c5726d0..000000000 Binary files a/kcontrol/pics/cr64-app-kdmconfig.png and /dev/null differ diff --git a/kcontrol/pics/cr64-app-tdmconfig.png b/kcontrol/pics/cr64-app-tdmconfig.png new file mode 100644 index 000000000..57c5726d0 Binary files /dev/null and b/kcontrol/pics/cr64-app-tdmconfig.png differ diff --git a/kcontrol/tdm/AUTHORS b/kcontrol/tdm/AUTHORS new file mode 100644 index 000000000..3b7927243 --- /dev/null +++ b/kcontrol/tdm/AUTHORS @@ -0,0 +1,6 @@ +TDM - The KDE Display Manager - written by Steffen Hansen + +The KDE Display Manager Configuration module - +written by Thomas Tanghus + +Currently maintend by Oswald Buddenhagen diff --git a/kcontrol/tdm/CMakeLists.txt b/kcontrol/tdm/CMakeLists.txt new file mode 100644 index 000000000..004282250 --- /dev/null +++ b/kcontrol/tdm/CMakeLists.txt @@ -0,0 +1,40 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR}/kcontrol/background + ${CMAKE_BINARY_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + +##### other data ################################ + +install( FILES tdm.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) + + +##### kcm_tdm (module) ########################## + +set_source_files_properties( background.cpp PROPERTIES COMPILE_FLAGS -DKDE_CONFDIR=\\"${TDE_CONFIG_DIR}\\" ) +set_source_files_properties( main.cpp PROPERTIES COMPILE_FLAGS -DKDE_CONFDIR=\\"${TDE_CONFIG_DIR}\\" ) + +tde_add_kpart( kcm_tdm AUTOMOC + SOURCES + background.cpp tdm-appear.cpp tdm-font.cpp tdm-shut.cpp + tdm-users.cpp tdm-conv.cpp main.cpp kbackedcombobox.cpp + LINK kcmbgnd-static bgnd-static knewstuff-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) diff --git a/kcontrol/tdm/ChangeLog b/kcontrol/tdm/ChangeLog new file mode 100644 index 000000000..d49bb2548 --- /dev/null +++ b/kcontrol/tdm/ChangeLog @@ -0,0 +1,16 @@ +2002-07-11 Oswald Buddenhagen + * Reworked "Users" and "Convenience" tabs + +2001-01-15 Oswald Buddenhagen + * Several new fields in different tabs for some new features + +2000-12-06 Oswald Buddenhagen + * New "Convenience" tab supporting the new automation features + * Some changes to the "Users" tab + * Few bug fixes + +1998-04-28 Thomas Tanghus + * Improved geometry management. + +1998-05-14 Thomas Tanghus + * Fixed bug with "ShutDownButton=...". diff --git a/kcontrol/tdm/Makefile.am b/kcontrol/tdm/Makefile.am new file mode 100644 index 000000000..e6193d7df --- /dev/null +++ b/kcontrol/tdm/Makefile.am @@ -0,0 +1,19 @@ +kde_module_LTLIBRARIES = kcm_tdm.la + +# _don't_ add a theme configurator!! +kcm_tdm_la_SOURCES = background.cpp tdm-appear.cpp tdm-font.cpp tdm-shut.cpp \ + tdm-users.cpp tdm-conv.cpp main.cpp kbackedcombobox.cpp + +kcm_tdm_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -module -avoid-version -no-undefined +kcm_tdm_la_LIBADD = $(top_builddir)/kcontrol/background/libkcmbgnd.la $(top_builddir)/kcontrol/background/libbgnd.la $(LIB_KIO) $(LIB_KNEWSTUFF) + +AM_CPPFLAGS= -I$(top_builddir)/kcontrol/background \ + -I$(top_srcdir)/kcontrol/background \ + -I$(top_srcdir)/kdesktop $(all_includes) + +METASOURCES = AUTO + +messages: + $(XGETTEXT) $(kcm_tdm_la_SOURCES) -o $(podir)/tdmconfig.pot + +xdg_apps_DATA = tdm.desktop diff --git a/kcontrol/tdm/background.cpp b/kcontrol/tdm/background.cpp new file mode 100644 index 000000000..4078bd393 --- /dev/null +++ b/kcontrol/tdm/background.cpp @@ -0,0 +1,111 @@ +/* vi: ts=8 sts=4 sw=4 + * + * This file is part of the KDE project, module kcmdisplay. + * Copyright (C) 1999 Geert Jansen + * + * Modified 2000.07.14 by Brad Hughes + * Improve layout and consistency with KDesktop's background selection + * + * Based on old backgnd.cpp: + * + * Copyright (c) Martin R. Jones 1996 + * Converted to a kcc module by Matthias Hoelzer 1997 + * Gradient backgrounds by Mark Donohoe 1997 + * Pattern backgrounds by Stephan Kulow 1998 + * Randomizing & dnd & new display modes by Matej Koss 1998 + * + * You can Freely distribute this program under the GNU General Public + * License. See the file "COPYING" for the exact licensing terms. + */ + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include "../background/bgsettings.h" +#include "../background/bgdialog.h" +#include "background.h" +#include +#include +#include + +extern KSimpleConfig *config; + +KBackground::KBackground(TQWidget *parent, const char *name) + : TQWidget(parent, name) +{ + + // Enabling checkbox + m_pCBEnable = new TQCheckBox( i18n("E&nable background"), this ); + TQWhatsThis::add( m_pCBEnable, + i18n("If this is checked, TDM will use the settings below for the background." + " If it is disabled, you have to look after the background yourself." + " This is done by running some program (possibly xsetroot) in the script" + " specified in the Setup= option in tdmrc (usually Xsetup).") ); + config->setGroup( "X-*-Greeter" ); + m_simpleConf=new KSimpleConfig(config->readEntry( "BackgroundCfg",KDE_CONFDIR "/tdm/backgroundrc" ) ); + m_background = new BGDialog( this, m_simpleConf, false ); + + connect(m_background, TQT_SIGNAL(changed(bool)), TQT_SIGNAL(changed(bool))); + + // Top layout + TQVBoxLayout *top = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint() ); + top->addWidget(m_pCBEnable); + top->addWidget(m_background); + top->addStretch(); + connect( m_pCBEnable, TQT_SIGNAL(toggled( bool )), TQT_SLOT(slotEnableChanged()) ); +} + +KBackground::~KBackground() +{ + delete m_simpleConf; +} + +void KBackground::slotEnableChanged() +{ + bool en = m_pCBEnable->isChecked(); + m_background->setEnabled( en ); + emit changed ( true ); +} + +void KBackground::makeReadOnly() +{ + m_pCBEnable->setEnabled(false); + m_background->makeReadOnly(); +} + +void KBackground::load() +{ + m_pCBEnable->setChecked( config->readBoolEntry( "UseBackground", true ) ); + m_background->load(false); + slotEnableChanged(); + emit changed(false); +} + + +void KBackground::save() +{ + kdDebug() << "Saving stuff..." << endl; + config->writeEntry( "UseBackground", m_pCBEnable->isChecked() ); + m_background->save(); + emit changed(false); +} + + +void KBackground::defaults() +{ + m_pCBEnable->setChecked( true ); + slotEnableChanged(); + m_background->defaults(); + emit changed(true); +} + +#include "background.moc" diff --git a/kcontrol/tdm/background.h b/kcontrol/tdm/background.h new file mode 100644 index 000000000..2e5182b16 --- /dev/null +++ b/kcontrol/tdm/background.h @@ -0,0 +1,50 @@ +/* vi: ts=8 sts=4 sw=4 + * + * This file is part of the KDE project, module kcmdisplay. + * Copyright (C) 1999 Geert Jansen + * + * You can Freely distribute this program under the GNU General Public + * License. See the file "COPYING" for the exact licensing terms. + */ + +#ifndef __Bgnd_h_Included__ +#define __Bgnd_h_Included__ + +#include +#include + + +class KSimpleConfig; +class BGDialog; +class KGlobalBackgroundSettings; +class TQCheckBox; +class TQLabel; + +class KBackground: public TQWidget +{ + Q_OBJECT +public: + KBackground(TQWidget *parent=0, const char *name=0); + ~KBackground(); + + void load(); + void save(); + void defaults(); + void makeReadOnly(); +signals: + void changed(bool); + +private slots: + void slotEnableChanged(); +private: + void init(); + void apply(); + + TQCheckBox *m_pCBEnable; + TQLabel *m_pMLabel; + KSimpleConfig *m_simpleConf; + BGDialog *m_background; +}; + + +#endif // __Bgnd_h_Included__ diff --git a/kcontrol/tdm/kbackedcombobox.cpp b/kcontrol/tdm/kbackedcombobox.cpp new file mode 100644 index 000000000..1ba598e49 --- /dev/null +++ b/kcontrol/tdm/kbackedcombobox.cpp @@ -0,0 +1,40 @@ +/* This file is part of the KDE Display Manager Configuration package + Copyright (C) 2004-2005 Oswald Buddenhagen + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kbackedcombobox.h" + +void KBackedComboBox::insertItem( const TQString &id, const TQString &name ) +{ + id2name[id] = name; + name2id[name] = id; + KComboBox::insertItem( name ); +} + +void KBackedComboBox::setCurrentId( const TQString &id ) +{ + if (id2name.contains( id )) + setCurrentItem( id2name[id] ); + else + setCurrentItem( 0 ); +} + +const TQString &KBackedComboBox::currentId() const +{ + return name2id[currentText()]; +} diff --git a/kcontrol/tdm/kbackedcombobox.h b/kcontrol/tdm/kbackedcombobox.h new file mode 100644 index 000000000..1ec1d2a72 --- /dev/null +++ b/kcontrol/tdm/kbackedcombobox.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE Display Manager Configuration package + Copyright (C) 2004-2005 Oswald Buddenhagen + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KBACKEDCOMBOBOX_H +#define KBACKEDCOMBOBOX_H + +#include + +class KBackedComboBox : public KComboBox { + +public: + KBackedComboBox( TQWidget *parent ) : KComboBox( false, parent ) {} + void insertItem( const TQString &id, const TQString &name ); + void setCurrentId( const TQString &id ); + const TQString ¤tId() const; + +private: + TQMap id2name, name2id; + +}; + +#endif // KBACKEDCOMBOBOX_H diff --git a/kcontrol/tdm/main.cpp b/kcontrol/tdm/main.cpp new file mode 100644 index 000000000..de4ea0fc7 --- /dev/null +++ b/kcontrol/tdm/main.cpp @@ -0,0 +1,342 @@ +/* + * main.cpp + * + * Copyright (c) 1999 Matthias Hoelzer-Kluepfel + * + * 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 + +#include + +#include +#include +#include +#include +#include + +#include "tdm-appear.h" +#include "tdm-font.h" +#include "tdm-users.h" +#include "tdm-shut.h" +#include "tdm-conv.h" + +#include "main.h" +#include "background.h" + +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory TDMFactory; +K_EXPORT_COMPONENT_FACTORY( kcm_tdm, TDMFactory("tdmconfig") ) + +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; + +TDModule::TDModule(TQWidget *parent, const char *name, const TQStringList &) + : KCModule(TDMFactory::instance(), parent, name) + , minshowuid(0) + , maxshowuid(0) + , updateOK(false) +{ + KAboutData *about = + new KAboutData(I18N_NOOP("kcmtdm"), I18N_NOOP("KDE Login Manager Config Module"), + 0, 0, KAboutData::License_GPL, + I18N_NOOP("(c) 1996 - 2005 The TDM 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( "

Login Manager

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 Modify button to acquire " + "superuser rights. You will be asked for the superuser password." + "

Appearance

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." + "

Font

Here you can choose the fonts that the Login Manager should use " + "for various purposes like greetings and user names. " + "

Background

If you want to set a special background for the login " + "screen, this is where to do it." + "

Shutdown

Here you can specify who is allowed to shutdown/reboot the machine " + "and whether a boot manager should be used." + "

Users

On this tab page, you can select which users the Login Manager " + "will offer you for logging in." + "

Convenience

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.
" + "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 tgmap; + TQMap::Iterator tgmapi; + TQMap::ConstIterator tgmapci; + TQMap >::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( 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 "/tdm/tdmdistrc" ,&st ) == 0) { + config = new KSimpleConfig( TQString::fromLatin1( KDE_CONFDIR "/tdm/tdmdistrc" )); + } + else { + config = new KSimpleConfig( TQString::fromLatin1( KDE_CONFDIR "/tdm/tdmrc" )); + } + + TQVBoxLayout *top = new TQVBoxLayout(this); + tab = new TQTabWidget(this); + + // ***** + // _don't_ add a theme configurator until the theming engine is _really_ done!! + // ***** + + appearance = new TDMAppearanceWidget(this); + tab->addTab(appearance, i18n("A&ppearance")); + connect(appearance, TQT_SIGNAL(changed(bool)), TQT_SIGNAL( changed(bool))); + + font = new TDMFontWidget(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 TDMSessionsWidget(this); + tab->addTab(sessions, i18n("&Shutdown")); + connect(sessions, TQT_SIGNAL(changed(bool)), TQT_SIGNAL(changed(bool))); + + users = new TDMUsersWidget(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 &)), users, TQT_SLOT(slotAddUsers(const TQMap &))); + connect(this, TQT_SIGNAL(delUsers(const TQMap &)), users, TQT_SLOT(slotDelUsers(const TQMap &))); + connect(this, TQT_SIGNAL(clearUsers()), users, TQT_SLOT(slotClearUsers())); + + convenience = new TDMConvenienceWidget(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 &)), convenience, TQT_SLOT(slotAddUsers(const TQMap &))); + connect(this, TQT_SIGNAL(delUsers(const TQMap &)), convenience, TQT_SLOT(slotDelUsers(const TQMap &))); + 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); +} + +TDModule::~TDModule() +{ + delete config; +} + +void TDModule::load() +{ + appearance->load(); + font->load(); + background->load(); + users->load(); + sessions->load(); + convenience->load(); + propagateUsers(); +} + + +void TDModule::save() +{ + appearance->save(); + font->save(); + background->save(); + users->save(); + sessions->save(); + convenience->save(); + config->sync(); +} + + +void TDModule::defaults() +{ + if ( getuid() == 0 ) + { + appearance->defaults(); + font->defaults(); + background->defaults(); + users->defaults(); + sessions->defaults(); + convenience->defaults(); + propagateUsers(); + } +} + +void TDModule::propagateUsers() +{ + groupmap.clear(); + emit clearUsers(); + TQMap lusers; + TQMapConstIterator > it; + TQStringList::ConstIterator jt; + TQMap::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 TDModule::slotMinMaxUID(int min, int max) +{ + if (updateOK) { + TQMap alusers, dlusers; + TQMapConstIterator > it; + TQStringList::ConstIterator jt; + TQMap::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" diff --git a/kcontrol/tdm/main.h b/kcontrol/tdm/main.h new file mode 100644 index 000000000..d613f9c4e --- /dev/null +++ b/kcontrol/tdm/main.h @@ -0,0 +1,83 @@ +/* + * main.h + * + * Copyright (c) 1999 Matthias Hoelzer-Kluepfel + * + * 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. + */ + +#ifndef __tdm_main_h +#define __tdm_main_h + +#include +#include + +#include + +class TDMAppearanceWidget; +class TDMFontWidget; +class TDMSessionsWidget; +class TDMUsersWidget; +class TDMConvenienceWidget; +class KBackground; + +class TDModule : public KCModule +{ + Q_OBJECT + +public: + + TDModule(TQWidget *parent, const char *name, const TQStringList &); + ~TDModule(); + + void load(); + void save(); + void defaults(); + +public slots: + + void slotMinMaxUID(int min, int max); + +signals: + + void clearUsers(); + void addUsers(const TQMap &); + void delUsers(const TQMap &); + +private: + + TQTabWidget *tab; + + TDMAppearanceWidget *appearance; + KBackground *background; + TDMFontWidget *font; + TDMSessionsWidget *sessions; + TDMUsersWidget *users; + TDMConvenienceWidget *convenience; + + TQMap > usermap; + TQMap groupmap; + int minshowuid, maxshowuid; + bool updateOK; + + void propagateUsers(); + +}; + +#endif + diff --git a/kcontrol/tdm/tdm-appear.cpp b/kcontrol/tdm/tdm-appear.cpp new file mode 100644 index 000000000..cdd5f2fc9 --- /dev/null +++ b/kcontrol/tdm/tdm-appear.cpp @@ -0,0 +1,554 @@ +/* + This file is part of the KDE Display Manager Configuration package + Copyright (C) 1997-1998 Thomas Tanghus (tanghus@earthling.net) + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tdm-appear.h" +#include "kbackedcombobox.h" + +extern KSimpleConfig *config; + + +TDMAppearanceWidget::TDMAppearanceWidget(TQWidget *parent, const char *name) + : TQWidget(parent, name) +{ + TQString wtstr; + + TQVBoxLayout *vbox = new TQVBoxLayout(this, KDialog::marginHint(), + KDialog::spacingHint(), "vbox"); + TQGroupBox *group = new TQGroupBox(i18n("Appearance"), this); + vbox->addWidget(group); + + TQGridLayout *grid = new TQGridLayout( group, 5, 2, KDialog::marginHint(), + KDialog::spacingHint(), "grid"); + grid->addRowSpacing(0, group->fontMetrics().height()); + grid->setColStretch(0, 1); + grid->setColStretch(1, 1); + + TQHBoxLayout *hlay = new TQHBoxLayout( KDialog::spacingHint() ); + grid->addMultiCellLayout(hlay, 1,1, 0,1); + greetstr_lined = new KLineEdit(group); + TQLabel *label = new TQLabel(greetstr_lined, i18n("&Greeting:"), group); + hlay->addWidget(label); + connect(greetstr_lined, TQT_SIGNAL(textChanged(const TQString&)), + TQT_SLOT(changed())); + hlay->addWidget(greetstr_lined); + wtstr = i18n("This is the \"headline\" for TDM's login window. You may want to " + "put some nice greeting or information about the operating system here.

" + "TDM will substitute the following character pairs with the " + "respective contents:

    " + "
  • %d -> current display
  • " + "
  • %h -> host name, possibly with domain name
  • " + "
  • %n -> node name, most probably the host name without domain name
  • " + "
  • %s -> the operating system
  • " + "
  • %r -> the operating system's version
  • " + "
  • %m -> the machine (hardware) type
  • " + "
  • %% -> a single %
  • " + "
" ); + TQWhatsThis::add( label, wtstr ); + TQWhatsThis::add( greetstr_lined, wtstr ); + + + TQGridLayout *hglay = new TQGridLayout( 3, 4, KDialog::spacingHint() ); + grid->addMultiCellLayout(hglay, 2,4, 0,0); + + label = new TQLabel(i18n("Logo area:"), group); + hglay->addWidget(label, 0, 0); + TQVBoxLayout *vlay = new TQVBoxLayout( KDialog::spacingHint() ); + hglay->addMultiCellLayout(vlay, 0,0, 1,2); + noneRadio = new TQRadioButton( i18n("logo area", "&None"), group ); + clockRadio = new TQRadioButton( i18n("Show cloc&k"), group ); + logoRadio = new TQRadioButton( i18n("Sho&w logo"), group ); + TQButtonGroup *buttonGroup = new TQButtonGroup( group ); + label->setBuddy( buttonGroup ); + connect( buttonGroup, TQT_SIGNAL(clicked(int)), TQT_SLOT(slotAreaRadioClicked(int)) ); + connect( buttonGroup, TQT_SIGNAL(clicked(int)), TQT_SLOT(changed()) ); + buttonGroup->hide(); + buttonGroup->insert(noneRadio, KdmNone); + buttonGroup->insert(clockRadio, KdmClock); + buttonGroup->insert(logoRadio, KdmLogo); + vlay->addWidget(noneRadio); + vlay->addWidget(clockRadio); + vlay->addWidget(logoRadio); + wtstr = i18n("You can choose to display a custom logo (see below), a clock or no logo at all."); + TQWhatsThis::add( label, wtstr ); + TQWhatsThis::add( noneRadio, wtstr ); + TQWhatsThis::add( logoRadio, wtstr ); + TQWhatsThis::add( clockRadio, wtstr ); + + logoLabel = new TQLabel(i18n("&Logo:"), group); + logobutton = new TQPushButton(group); + logoLabel->setBuddy( logobutton ); + logobutton->setAutoDefault(false); + logobutton->setAcceptDrops(true); + logobutton->installEventFilter(this); // for drag and drop + connect(logobutton, TQT_SIGNAL(clicked()), TQT_SLOT(slotLogoButtonClicked())); + hglay->addWidget(logoLabel, 1, 0); + hglay->addWidget(logobutton, 1, 1, Qt::AlignCenter); + hglay->addRowSpacing(1, 110); + wtstr = i18n("Click here to choose an image that TDM will display. " + "You can also drag and drop an image onto this button " + "(e.g. from Konqueror)."); + TQWhatsThis::add( logoLabel, wtstr ); + TQWhatsThis::add( logobutton, wtstr ); + hglay->addRowSpacing( 2, KDialog::spacingHint()); + hglay->setColStretch( 3, 1); + + + hglay = new TQGridLayout( 2, 3, KDialog::spacingHint() ); + grid->addLayout(hglay, 2, 1); + + label = new TQLabel(i18n("Position:"), group); + hglay->addMultiCellWidget(label, 0,1, 0,0, Qt::AlignVCenter); + TQValidator *posValidator = new TQIntValidator(0, 100, TQT_TQOBJECT(group)); + TQLabel *xLineLabel = new TQLabel(i18n("&X:"), group); + hglay->addWidget(xLineLabel, 0, 1); + xLineEdit = new TQLineEdit (group); + connect( xLineEdit, TQT_SIGNAL( textChanged(const TQString&) ), TQT_SLOT( changed() )); + hglay->addWidget(xLineEdit, 0, 2); + xLineLabel->setBuddy(xLineEdit); + xLineEdit->setValidator(posValidator); + TQLabel *yLineLabel = new TQLabel(i18n("&Y:"), group); + hglay->addWidget(yLineLabel, 1, 1); + yLineEdit = new TQLineEdit (group); + connect( yLineEdit, TQT_SIGNAL( textChanged(const TQString&) ), TQT_SLOT( changed() )); + hglay->addWidget(yLineEdit, 1, 2); + yLineLabel->setBuddy(yLineEdit); + yLineEdit->setValidator(posValidator); + wtstr = i18n("Here you specify the relative coordinates (in percent) of the login dialog's center."); + TQWhatsThis::add( label, wtstr ); + TQWhatsThis::add( xLineLabel, wtstr ); + TQWhatsThis::add( xLineEdit, wtstr ); + TQWhatsThis::add( yLineLabel, wtstr ); + TQWhatsThis::add( yLineEdit, wtstr ); + hglay->setColStretch( 3, 1); + hglay->setRowStretch( 2, 1); + + + hglay = new TQGridLayout( 2, 3, KDialog::spacingHint() ); + grid->addLayout(hglay, 3, 1); + hglay->setColStretch(3, 1); + + compositorcombo = new KBackedComboBox(group); + compositorcombo->insertItem( "", i18n("None") ); + compositorcombo->insertItem( "kompmgr", i18n("Trinity compositor") ); + label = new TQLabel(compositorcombo, i18n("Compositor:"), group); + connect(compositorcombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); + hglay->addWidget(label, 0, 0); + hglay->addWidget(compositorcombo, 0, 1); + wtstr = i18n("Choose a compositor to be used in TDM. Note that the chosen compositor will continue to run after login."); + TQWhatsThis::add( label, wtstr ); + TQWhatsThis::add( compositorcombo, wtstr ); + + guicombo = new KBackedComboBox(group); + guicombo->insertItem( "", i18n("") ); + loadGuiStyles(guicombo); + guicombo->listBox()->sort(); + label = new TQLabel(guicombo, i18n("GUI s&tyle:"), group); + connect(guicombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); + hglay->addWidget(label, 1, 0); + hglay->addWidget(guicombo, 1, 1); + wtstr = i18n("You can choose a basic GUI style here that will be " + "used by TDM only."); + TQWhatsThis::add( label, wtstr ); + TQWhatsThis::add( guicombo, wtstr ); + + colcombo = new KBackedComboBox(group); + colcombo->insertItem( "", i18n("") ); + loadColorSchemes(colcombo); + colcombo->listBox()->sort(); + label = new TQLabel(colcombo, i18n("&Color scheme:"), group); + connect(colcombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); + hglay->addWidget(label, 2, 0); + hglay->addWidget(colcombo, 2, 1); + wtstr = i18n("You can choose a basic Color Scheme here that will be " + "used by TDM only."); + TQWhatsThis::add( label, wtstr ); + TQWhatsThis::add( colcombo, wtstr ); + + echocombo = new KBackedComboBox(group); + echocombo->insertItem("NoEcho", i18n("No Echo")); + echocombo->insertItem("OneStar", i18n("One Star")); + echocombo->insertItem("ThreeStars", i18n("Three Stars")); + label = new TQLabel(echocombo, i18n("Echo &mode:"), group); + connect(echocombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); + hglay->addWidget(label, 3, 0); + hglay->addWidget(echocombo, 3, 1); + wtstr = i18n("You can choose whether and how TDM shows your password when you type it."); + TQWhatsThis::add( label, wtstr ); + TQWhatsThis::add( echocombo, wtstr ); + + + // The Language group box + group = new TQGroupBox(0, Qt::Vertical, i18n("Locale"), this); + vbox->addWidget(group); + + langcombo = new KLanguageButton(group); + loadLanguageList(langcombo); + connect(langcombo, TQT_SIGNAL(activated(const TQString &)), TQT_SLOT(changed())); + label = new TQLabel(langcombo, i18n("Languag&e:"), group); + TQGridLayout *hbox = new TQGridLayout( group->layout(), 2, 2, KDialog::spacingHint() ); + hbox->setColStretch(1, 1); + hbox->addWidget(label, 1, 0); + hbox->addWidget(langcombo, 1, 1); + wtstr = i18n("Here you can choose the language used by TDM. This setting does not affect" + " a user's personal settings; that will take effect after login."); + TQWhatsThis::add( label, wtstr ); + TQWhatsThis::add( langcombo, wtstr ); + + + // The SAK group box + group = new TQGroupBox(0, Qt::Vertical, i18n("Secure Attention Key"), this); + vbox->addWidget(group); + + sakbox = new TQCheckBox( i18n("Enable Secure Attention Key"), group ); + connect( sakbox, TQT_SIGNAL(toggled(bool)), TQT_SLOT(changed()) ); + TQGridLayout *hbox2 = new TQGridLayout( group->layout(), 2, 2, KDialog::spacingHint() ); + hbox2->setColStretch(1, 1); + hbox2->addWidget(sakbox, 1, 0); + wtstr = i18n("Here you can enable or disable the Secure Attention Key [SAK] anti-spoofing measure."); + TQWhatsThis::add( sakbox, wtstr ); + + + vbox->addStretch(1); + +} + +void TDMAppearanceWidget::makeReadOnly() +{ + disconnect( logobutton, TQT_SIGNAL(clicked()), + this, TQT_SLOT(slotLogoButtonClicked()) ); + logobutton->setAcceptDrops(false); + greetstr_lined->setReadOnly(true); + noneRadio->setEnabled(false); + clockRadio->setEnabled(false); + logoRadio->setEnabled(false); + xLineEdit->setEnabled(false); + yLineEdit->setEnabled(false); + compositorcombo->setEnabled(false); + guicombo->setEnabled(false); + colcombo->setEnabled(false); + echocombo->setEnabled(false); + langcombo->setEnabled(false); + sakbox->setEnabled(false); +} + +void TDMAppearanceWidget::loadLanguageList(KLanguageButton *combo) +{ + TQStringList langlist = KGlobal::dirs()->findAllResources("locale", + TQString::fromLatin1("*/entry.desktop")); + langlist.sort(); + for ( TQStringList::ConstIterator it = langlist.begin(); + it != langlist.end(); ++it ) + { + TQString fpath = (*it).left((*it).length() - 14); + int index = fpath.findRev('/'); + TQString nid = fpath.mid(index + 1); + + KSimpleConfig entry(*it); + entry.setGroup(TQString::fromLatin1("KCM Locale")); + TQString name = entry.readEntry(TQString::fromLatin1("Name"), i18n("without name")); + combo->insertLanguage(nid, name, TQString::fromLatin1("l10n/"), TQString::null); + } +} + +void TDMAppearanceWidget::loadColorSchemes(KBackedComboBox *combo) +{ + // XXX: Global + local schemes + TQStringList list = KGlobal::dirs()-> + findAllResources("data", "kdisplay/color-schemes/*.kcsrc", false, true); + for (TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it) + { + KSimpleConfig config(*it, true); + config.setGroup("Color Scheme"); + + TQString str; + if (!(str = config.readEntry("Name")).isEmpty() || + !(str = config.readEntry("name")).isEmpty()) + { + TQString str2 = (*it).mid( (*it).findRev( '/' ) + 1 ); // strip off path + str2.setLength( str2.length() - 6 ); // strip off ".kcsrc + combo->insertItem( str2, str ); + } + } +} + +void TDMAppearanceWidget::loadGuiStyles(KBackedComboBox *combo) +{ + // XXX: Global + local schemes + TQStringList list = KGlobal::dirs()-> + findAllResources("data", "kstyle/themes/*.themerc", false, true); + for (TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it) + { + KSimpleConfig config(*it, true); + + if (!(config.hasGroup("KDE") && config.hasGroup("Misc"))) + continue; + + config.setGroup("Desktop Entry"); + if (config.readBoolEntry("Hidden", false)) + continue; + + config.setGroup("KDE"); + TQString str2 = config.readEntry("WidgetStyle"); + if (str2.isNull()) + continue; + + config.setGroup("Misc"); + combo->insertItem( str2, config.readEntry("Name") ); + } +} + +bool TDMAppearanceWidget::setLogo(TQString logo) +{ + TQString flogo = logo.isEmpty() ? + locate("data", TQString::fromLatin1("tdm/pics/kdelogo.png") ) : + logo; + TQImage p(flogo); + if (p.isNull()) + return false; + if (p.width() > 100 || p.height() > 100) + p = p.smoothScale(100, 100, TQ_ScaleMin); + logobutton->setPixmap(p); + uint bd = style().pixelMetric( TQStyle::PM_ButtonMargin ) * 2; + logobutton->setFixedSize(p.width() + bd, p.height() + bd); + logopath = logo; + return true; +} + + +void TDMAppearanceWidget::slotLogoButtonClicked() +{ + KImageIO::registerFormats(); + KFileDialog dialogue(locate("data", TQString::fromLatin1("tdm/pics/")), + KImageIO::pattern( KImageIO::Reading ), + this, 0, true); + dialogue.setOperationMode( KFileDialog::Opening ); + dialogue.setMode( KFile::File | KFile::LocalOnly ); + + KImageFilePreview* imagePreview = new KImageFilePreview( &dialogue ); + dialogue.setPreviewWidget( imagePreview ); + if (dialogue.exec() == TQDialog::Accepted) { + if ( setLogo(dialogue.selectedFile()) ) { + changed(); + } + } +} + + +void TDMAppearanceWidget::slotAreaRadioClicked(int id) +{ + logobutton->setEnabled( id == KdmLogo ); + logoLabel->setEnabled( id == KdmLogo ); +} + + +bool TDMAppearanceWidget::eventFilter(TQObject *, TQEvent *e) +{ + if (e->type() == TQEvent::DragEnter) { + iconLoaderDragEnterEvent((TQDragEnterEvent *) e); + return true; + } + + if (e->type() == TQEvent::Drop) { + iconLoaderDropEvent((TQDropEvent *) e); + return true; + } + + return false; +} + +void TDMAppearanceWidget::iconLoaderDragEnterEvent(TQDragEnterEvent *e) +{ + e->accept(KURLDrag::canDecode(e)); +} + + +KURL *decodeImgDrop(TQDropEvent *e, TQWidget *wdg); + +void TDMAppearanceWidget::iconLoaderDropEvent(TQDropEvent *e) +{ + KURL pixurl; + bool istmp; + + KURL *url = decodeImgDrop(e, this); + if (url) { + + // we gotta check if it is a non-local file and make a tmp copy at the hd. + if(!url->isLocalFile()) { + pixurl.setPath(KGlobal::dirs()->resourceDirs("data").last() + + "tdm/pics/" + url->fileName()); + KIO::NetAccess::copy(*url, pixurl, parentWidget()); + istmp = true; + } else { + pixurl = *url; + istmp = false; + } + + // By now url should be "file:/..." + if (!setLogo(pixurl.path())) { + KIO::NetAccess::del(pixurl, parentWidget()); + TQString msg = i18n("There was an error loading the image:\n" + "%1\n" + "It will not be saved.") + .arg(pixurl.path()); + KMessageBox::sorry(this, msg); + } + + delete url; + } +} + + +void TDMAppearanceWidget::save() +{ + config->setGroup("X-*-Greeter"); + + config->writeEntry("GreetString", greetstr_lined->text()); + + config->writeEntry("LogoArea", noneRadio->isChecked() ? "None" : + logoRadio->isChecked() ? "Logo" : "Clock" ); + + config->writeEntry("LogoPixmap", KGlobal::iconLoader()->iconPath(logopath, KIcon::Desktop, true)); + + config->writeEntry("Compositor", compositorcombo->currentId()); + + config->writeEntry("GUIStyle", guicombo->currentId()); + + config->writeEntry("ColorScheme", colcombo->currentId()); + + config->writeEntry("EchoMode", echocombo->currentId()); + + config->writeEntry("GreeterPos", xLineEdit->text() + ',' + yLineEdit->text()); + + config->writeEntry("Language", langcombo->current()); + + config->writeEntry("UseSAK", sakbox->isChecked()); +} + + +void TDMAppearanceWidget::load() +{ + config->setGroup("X-*-Greeter"); + + // Read the greeting string + greetstr_lined->setText(config->readEntry("GreetString", i18n("Welcome to %n"))); + + // Regular logo or clock + TQString logoArea = config->readEntry("LogoArea", "Logo" ); + if (logoArea == "Clock") { + clockRadio->setChecked(true); + slotAreaRadioClicked(KdmClock); + } else if (logoArea == "Logo") { + logoRadio->setChecked(true); + slotAreaRadioClicked(KdmLogo); + } else { + noneRadio->setChecked(true); + slotAreaRadioClicked(KdmNone); + } + + // See if we use alternate logo + setLogo(config->readEntry("LogoPixmap")); + + // Check the current compositor type + compositorcombo->setCurrentId(config->readEntry("Compositor")); + + // Check the GUI type + guicombo->setCurrentId(config->readEntry("GUIStyle")); + + // Check the Color Scheme + colcombo->setCurrentId(config->readEntry("ColorScheme")); + + // Check the echo mode + echocombo->setCurrentId(config->readEntry("EchoMode", "OneStar")); + + TQStringList sl = config->readListEntry( "GreeterPos" ); + if (sl.count() != 2) { + xLineEdit->setText( "50" ); + yLineEdit->setText( "50" ); + } else { + xLineEdit->setText( sl.first() ); + yLineEdit->setText( sl.last() ); + } + + // get the language + langcombo->setCurrentItem(config->readEntry("Language", "C")); + + // See if the SAK is enabled + sakbox->setChecked(config->readBoolEntry("UseSAK", true)); +} + + +void TDMAppearanceWidget::defaults() +{ + greetstr_lined->setText( i18n("Welcome to %n") ); + logoRadio->setChecked( true ); + slotAreaRadioClicked( KdmLogo ); + setLogo( "" ); + compositorcombo->setCurrentId( "" ); + guicombo->setCurrentId( "" ); + colcombo->setCurrentId( "" ); + echocombo->setCurrentItem( "OneStar" ); + + xLineEdit->setText( "50" ); + yLineEdit->setText( "50" ); + + langcombo->setCurrentItem( "en_US" ); +} + +TQString TDMAppearanceWidget::quickHelp() const +{ + return i18n("

TDM - Appearance

Here you can configure the basic appearance" + " of the TDM login manager, i.e. a greeting string, an icon etc.

" + " For further refinement of TDM's appearance, see the \"Font\" and \"Background\" " + " tabs."); +} + + +void TDMAppearanceWidget::changed() +{ + emit changed(true); +} + +#include "tdm-appear.moc" diff --git a/kcontrol/tdm/tdm-appear.h b/kcontrol/tdm/tdm-appear.h new file mode 100644 index 000000000..0d4047e10 --- /dev/null +++ b/kcontrol/tdm/tdm-appear.h @@ -0,0 +1,97 @@ +/* This file is part of the KDE Display Manager Configuration package + Copyright (C) 1997 Thomas Tanghus (tanghus@earthling.net) + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#ifndef __TDMAPPEAR_H__ +#define __TDMAPPEAR_H__ + + +#include +#include +#include +#include + +#include +#include +#include + + +#include "klanguagebutton.h" + +class TQComboBox; +class KBackedComboBox; +class TQLabel; +class TQRadioButton; +class TQLineEdit; +class KLineEdit; + + +class TDMAppearanceWidget : public TQWidget +{ + Q_OBJECT + +public: + TDMAppearanceWidget(TQWidget *parent, const char *name=0); + + void load(); + void save(); + void defaults(); + void makeReadOnly(); + TQString quickHelp() const; + + void loadColorSchemes(KBackedComboBox *combo); + void loadGuiStyles(KBackedComboBox *combo); + void loadLanguageList(KLanguageButton *combo); + + bool eventFilter(TQObject *, TQEvent *); + +signals: + void changed( bool state ); + +protected: + void iconLoaderDragEnterEvent(TQDragEnterEvent *event); + void iconLoaderDropEvent(TQDropEvent *event); + bool setLogo(TQString logo); + +private slots: + void slotAreaRadioClicked(int id); + void slotLogoButtonClicked(); + void changed(); + +private: + enum { KdmNone, KdmClock, KdmLogo }; + TQLabel *logoLabel; + TQPushButton *logobutton; + KLineEdit *greetstr_lined; + TQString logopath; + TQRadioButton *noneRadio; + TQRadioButton *clockRadio; + TQRadioButton *logoRadio; + TQLineEdit *xLineEdit; + TQLineEdit *yLineEdit; + KBackedComboBox *compositorcombo; + KBackedComboBox *guicombo; + KBackedComboBox *colcombo; + KBackedComboBox *echocombo; + KLanguageButton *langcombo; + TQCheckBox *sakbox; + +}; + +#endif diff --git a/kcontrol/tdm/tdm-conv.cpp b/kcontrol/tdm/tdm-conv.cpp new file mode 100644 index 000000000..64b8b9727 --- /dev/null +++ b/kcontrol/tdm/tdm-conv.cpp @@ -0,0 +1,362 @@ +/* This file is part of the KDE Display Manager Configuration package + + Copyright (C) 2000 Oswald Buddenhagen + Based on several other files. + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tdm-conv.h" + +extern KSimpleConfig *config; + +TDMConvenienceWidget::TDMConvenienceWidget(TQWidget *parent, const char *name) + : TQWidget(parent, name) +{ + TQString wtstr; + + TQLabel *paranoia = new TQLabel( i18n("

Attention!
Read help!
"), this ); + + TQSizePolicy vpref( TQSizePolicy::Minimum, TQSizePolicy::Fixed ); + + alGroup = new TQVGroupBox( i18n("Enable Au&to-Login"), this ); + alGroup->setCheckable( true ); + alGroup->setSizePolicy( vpref ); + + TQWhatsThis::add( alGroup, i18n("Turn on the auto-login feature." + " This applies only to TDM's graphical login." + " Think twice before enabling this!") ); + connect(alGroup, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChanged())); + + TQWidget *hlpw1 = new TQWidget( alGroup ); + userlb = new KComboBox( hlpw1 ); + u_label = new TQLabel( userlb, i18n("Use&r:"), hlpw1 ); + TQGridLayout *hlpl1 = new TQGridLayout(hlpw1, 2, 2, 0, KDialog::spacingHint()); + hlpl1->setColStretch(2, 1); + hlpl1->addWidget(u_label, 0, 0); + hlpl1->addWidget(userlb, 0, 1); + connect(userlb, TQT_SIGNAL(highlighted(int)), TQT_SLOT(slotChanged())); + wtstr = i18n("Select the user to be logged in automatically."); + TQWhatsThis::add( u_label, wtstr ); + TQWhatsThis::add( userlb, wtstr ); + delaysb = new TQSpinBox( 0, 3600, 5, hlpw1 ); + delaysb->setSpecialValueText( i18n("delay", "none") ); + delaysb->setSuffix( i18n("seconds", " s") ); + d_label = new TQLabel( delaysb, i18n("D&elay:"), hlpw1 ); + hlpl1->addWidget(d_label, 1, 0); + hlpl1->addWidget(delaysb, 1, 1); + connect(delaysb, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(slotChanged())); + wtstr = i18n("The delay (in seconds) before the automatic login kicks in. " + "This feature is also known as \"timed login\"."); + TQWhatsThis::add( d_label, wtstr ); + TQWhatsThis::add( delaysb, wtstr ); + againcb = new TQCheckBox( i18n("P&ersistent"), alGroup ); + connect( againcb, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChanged()) ); + TQWhatsThis::add( againcb, i18n("Normally, automatic login is performed only " + "when TDM starts up. If this is checked, automatic login will kick in " + "after finishing a session as well.") ); + autoLockCheck = new TQCheckBox( i18n("Loc&k session"), alGroup ); + connect( autoLockCheck, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChanged()) ); + TQWhatsThis::add( autoLockCheck, i18n("If checked, the automatically started session " + "will be locked immediately (provided it is a KDE session). This can " + "be used to obtain a super-fast login restricted to one user.") ); + + + puGroup = new TQVButtonGroup(i18n("Preselect User"), this ); + puGroup->setSizePolicy( vpref ); + + connect(puGroup, TQT_SIGNAL(clicked(int)), TQT_SLOT(slotPresChanged())); + connect(puGroup, TQT_SIGNAL(clicked(int)), TQT_SLOT(slotChanged())); + npRadio = new TQRadioButton(i18n("preselected user", "&None"), puGroup); + ppRadio = new TQRadioButton(i18n("Prev&ious"), puGroup); + TQWhatsThis::add( ppRadio, i18n("Preselect the user that logged in previously. " + "Use this if this computer is usually used several consecutive times by one user.") ); + spRadio = new TQRadioButton(i18n("Specif&y"), puGroup); + TQWhatsThis::add( spRadio, i18n("Preselect the user specified in the combo box below. " + "Use this if this computer is predominantly used by a certain user.") ); + TQWidget *hlpw = new TQWidget(puGroup); + puserlb = new KComboBox(true, hlpw); + pu_label = new TQLabel(puserlb, i18n("Us&er:"), hlpw); + connect(puserlb, TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(slotChanged())); + wtstr = i18n("Select the user to be preselected for login. " + "This box is editable, so you can specify an arbitrary non-existent " + "user to mislead possible attackers."); + TQWhatsThis::add( pu_label, wtstr ); + TQWhatsThis::add( puserlb, wtstr ); + TQBoxLayout *hlpl = new TQHBoxLayout(hlpw, 0, KDialog::spacingHint()); + hlpl->addWidget(pu_label); + hlpl->addWidget(puserlb); + hlpl->addStretch( 1 ); + cbjumppw = new TQCheckBox(i18n("Focus pass&word"), puGroup); + TQWhatsThis::add( cbjumppw, i18n("When this option is on, TDM will place the cursor " + "in the password field instead of the user field after preselecting a user. " + "Use this to save one key press per login, if the preselection usually does not need to " + "be changed.") ); + connect(cbjumppw, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChanged())); + + npGroup = new TQVGroupBox(i18n("Enable Password-&Less Logins"), this ); + npGroup->setCheckable( true ); + + TQWhatsThis::add( npGroup, i18n("When this option is checked, the checked users from" + " the list below will be allowed to log in without entering their" + " password. This applies only to TDM's graphical login." + " Think twice before enabling this!") ); + + connect(npGroup, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChanged())); + + pl_label = new TQLabel(i18n("No password re&quired for:"), npGroup); + npuserlv = new KListView(npGroup); + pl_label->setBuddy(npuserlv); + npuserlv->addColumn(TQString::null); + npuserlv->header()->hide(); + npuserlv->setResizeMode(TQListView::LastColumn); + TQWhatsThis::add(npuserlv, i18n("Check all users you want to allow a password-less login for." + " Entries denoted with '@' are user groups. Checking a group is like checking all users in that group.")); + connect( npuserlv, TQT_SIGNAL(clicked( TQListViewItem * )), + TQT_SLOT(slotChanged()) ); + + btGroup = new TQVGroupBox( i18n("Miscellaneous"), this ); + + cbarlen = new TQCheckBox(i18n("Automatically log in again after &X server crash"), btGroup); + TQWhatsThis::add( cbarlen, i18n("When this option is on, a user will be" + " logged in again automatically when their session is interrupted by an" + " X server crash; note that this can open a security hole: if you use" + " a screen locker than KDE's integrated one, this will make" + " circumventing a password-secured screen lock possible.") ); + connect(cbarlen, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChanged())); + + TQGridLayout *main = new TQGridLayout(this, 5, 2, 10); + main->addWidget(paranoia, 0, 0); + main->addWidget(alGroup, 1, 0); + main->addWidget(puGroup, 2, 0); + main->addMultiCellWidget(npGroup, 0,3, 1,1); + main->addMultiCellWidget(btGroup, 4,4, 0,1); + main->setColStretch(0, 1); + main->setColStretch(1, 2); + main->setRowStretch(3, 1); + + connect( userlb, TQT_SIGNAL(activated( const TQString & )), + TQT_SLOT(slotSetAutoUser( const TQString & )) ); + connect( puserlb, TQT_SIGNAL(textChanged( const TQString & )), + TQT_SLOT(slotSetPreselUser( const TQString & )) ); + connect( npuserlv, TQT_SIGNAL(clicked( TQListViewItem * )), + TQT_SLOT(slotUpdateNoPassUser( TQListViewItem * )) ); + +} + +void TDMConvenienceWidget::makeReadOnly() +{ + ((TQWidget*)alGroup->child("qt_groupbox_checkbox"))->setEnabled(false); + userlb->setEnabled(false); + delaysb->setEnabled(false); + againcb->setEnabled(false); + autoLockCheck->setEnabled(false); + ((TQWidget*)npGroup->child("qt_groupbox_checkbox"))->setEnabled(false); + npuserlv->setEnabled(false); + cbarlen->setEnabled(false); + npRadio->setEnabled(false); + ppRadio->setEnabled(false); + spRadio->setEnabled(false); + puserlb->setEnabled(false); + cbjumppw->setEnabled(false); +} + +void TDMConvenienceWidget::slotPresChanged() +{ + bool en = spRadio->isChecked(); + pu_label->setEnabled(en); + puserlb->setEnabled(en); + cbjumppw->setEnabled(!npRadio->isChecked()); +} + +void TDMConvenienceWidget::save() +{ + config->setGroup("X-:0-Core"); + config->writeEntry( "AutoLoginEnable", alGroup->isChecked() ); + config->writeEntry( "AutoLoginUser", userlb->currentText() ); + config->writeEntry( "AutoLoginDelay", delaysb->value() ); + config->writeEntry( "AutoLoginAgain", againcb->isChecked() ); + config->writeEntry( "AutoLoginLocked", autoLockCheck->isChecked() ); + + config->setGroup("X-:*-Core"); + config->writeEntry( "NoPassEnable", npGroup->isChecked() ); + config->writeEntry( "NoPassUsers", noPassUsers ); + + config->setGroup("X-*-Core"); + config->writeEntry( "AutoReLogin", cbarlen->isChecked() ); + + config->setGroup("X-:*-Greeter"); + config->writeEntry( "PreselectUser", npRadio->isChecked() ? "None" : + ppRadio->isChecked() ? "Previous" : + "Default" ); + config->writeEntry( "DefaultUser", puserlb->currentText() ); + config->writeEntry( "FocusPasswd", cbjumppw->isChecked() ); +} + + +void TDMConvenienceWidget::load() +{ + config->setGroup("X-:0-Core"); + bool alenable = config->readBoolEntry( "AutoLoginEnable", false); + autoUser = config->readEntry( "AutoLoginUser" ); + delaysb->setValue( config->readNumEntry( "AutoLoginDelay", 0 ) ); + againcb->setChecked( config->readBoolEntry( "AutoLoginAgain", false ) ); + autoLockCheck->setChecked( config->readBoolEntry( "AutoLoginLocked", false ) ); + if (autoUser.isEmpty()) + alenable=false; + alGroup->setChecked( alenable ); + + config->setGroup("X-:*-Core"); + npGroup->setChecked(config->readBoolEntry( "NoPassEnable", false) ); + noPassUsers = config->readListEntry( "NoPassUsers"); + + config->setGroup("X-*-Core"); + cbarlen->setChecked(config->readBoolEntry( "AutoReLogin", false) ); + + config->setGroup("X-:*-Greeter"); + TQString presstr = config->readEntry( "PreselectUser", "None" ); + if (presstr == "Previous") + ppRadio->setChecked(true); + else if (presstr == "Default") + spRadio->setChecked(true); + else + npRadio->setChecked(true); + preselUser = config->readEntry( "DefaultUser" ); + cbjumppw->setChecked(config->readBoolEntry( "FocusPasswd", false) ); + + slotPresChanged(); +} + + +void TDMConvenienceWidget::defaults() +{ + alGroup->setChecked(false); + delaysb->setValue(0); + againcb->setChecked(false); + autoLockCheck->setChecked(false); + npRadio->setChecked(true); + npGroup->setChecked(false); + cbarlen->setChecked(false); + cbjumppw->setChecked(false); + autoUser = ""; + preselUser = ""; + noPassUsers.clear(); + + slotPresChanged(); +} + + +void TDMConvenienceWidget::slotChanged() +{ + emit changed(true); +} + +void TDMConvenienceWidget::slotSetAutoUser( const TQString &user ) +{ + autoUser = user; +} + +void TDMConvenienceWidget::slotSetPreselUser( const TQString &user ) +{ + preselUser = user; +} + +void TDMConvenienceWidget::slotUpdateNoPassUser( TQListViewItem *item ) +{ + if ( !item ) + return; + TQCheckListItem *itm = (TQCheckListItem *)item; + TQStringList::iterator it = noPassUsers.find( itm->text() ); + if (itm->isOn()) { + if (it == noPassUsers.end()) + noPassUsers.append( itm->text() ); + } else { + if (it != noPassUsers.end()) + noPassUsers.remove( it ); + } +} + +void TDMConvenienceWidget::slotClearUsers() +{ + userlb->clear(); + puserlb->clear(); + npuserlv->clear(); + if (!autoUser.isEmpty()) + userlb->insertItem(autoUser); + if (!preselUser.isEmpty()) + puserlb->insertItem(preselUser); +} + +void TDMConvenienceWidget::slotAddUsers(const TQMap &users) +{ + TQMapConstIterator it; + for (it = users.begin(); it != users.end(); ++it) { + if (it.data() > 0) { + if (it.key() != autoUser) + userlb->insertItem(it.key()); + if (it.key() != preselUser) + puserlb->insertItem(it.key()); + } + if (it.data() != 0) + (new TQCheckListItem(npuserlv, it.key(), TQCheckListItem::CheckBox))-> + setOn(noPassUsers.find(it.key()) != noPassUsers.end()); + } + + if (userlb->listBox()) + userlb->listBox()->sort(); + + if (puserlb->listBox()) + puserlb->listBox()->sort(); + + npuserlv->sort(); + userlb->setCurrentItem(autoUser); + puserlb->setCurrentItem(preselUser); +} + +void TDMConvenienceWidget::slotDelUsers(const TQMap &users) +{ + TQMapConstIterator it; + for (it = users.begin(); it != users.end(); ++it) { + if (it.data() > 0) { + if (it.key() != autoUser && userlb->listBox()) + delete userlb->listBox()-> + findItem( it.key(), ExactMatch | CaseSensitive ); + if (it.key() != preselUser && puserlb->listBox()) + delete puserlb->listBox()-> + findItem( it.key(), ExactMatch | CaseSensitive ); + } + if (it.data() != 0) + delete npuserlv->findItem( it.key(), 0 ); + } +} + +#include "tdm-conv.moc" diff --git a/kcontrol/tdm/tdm-conv.h b/kcontrol/tdm/tdm-conv.h new file mode 100644 index 000000000..3f8dda974 --- /dev/null +++ b/kcontrol/tdm/tdm-conv.h @@ -0,0 +1,84 @@ +/* This file is part of the KDE Display Manager Configuration package + + Copyright (C) 2000 Oswald Buddenhagen + Based on several other files. + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __TDMCONV_H__ +#define __TDMCONV_H__ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + + +class TDMConvenienceWidget : public TQWidget +{ + Q_OBJECT + +public: + TDMConvenienceWidget(TQWidget *parent=0, const char *name=0); + + void load(); + void save(); + void defaults(); + void makeReadOnly(); + +public slots: + void slotClearUsers(); + void slotAddUsers(const TQMap &); + void slotDelUsers(const TQMap &); + + +signals: + void changed( bool state ); + +private slots: + void slotPresChanged(); + void slotChanged(); + void slotSetAutoUser( const TQString &user ); + void slotSetPreselUser( const TQString &user ); + void slotUpdateNoPassUser( TQListViewItem *item ); + +private: + TQGroupBox *alGroup, *puGroup, *npGroup, *btGroup; + TQCheckBox *againcb, *cbarlen, *cbjumppw, *autoLockCheck; + TQRadioButton *npRadio, *ppRadio, *spRadio; + KComboBox *userlb, *puserlb; + TQSpinBox *delaysb; + KListView *npuserlv; + TQLabel *u_label, *d_label, *pu_label, *w_label, *n_label, *pl_label; + TQString autoUser, preselUser; + TQStringList noPassUsers; +}; + +#endif + + diff --git a/kcontrol/tdm/tdm-font.cpp b/kcontrol/tdm/tdm-font.cpp new file mode 100644 index 000000000..9947101c1 --- /dev/null +++ b/kcontrol/tdm/tdm-font.cpp @@ -0,0 +1,134 @@ +/* This file is part of the KDE Display Manager Configuration package + Copyright (C) 1997 Thomas Tanghus (tanghus@earthling.net) + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tdm-font.h" + + +extern KSimpleConfig *config; + +TDMFontWidget::TDMFontWidget(TQWidget *parent, const char *name) + : TQWidget(parent, name) +{ + TQGridLayout *ml = new TQGridLayout(this, 5, 2, KDialog::marginHint(), KDialog::spacingHint()); + TQLabel *label = new TQLabel(i18n("&General:"), this); + stdFontChooser = new KFontRequester(this); + label->setBuddy(stdFontChooser); + TQWhatsThis::add( stdFontChooser, i18n("This changes the font which is used for all the text in the login manager except for the greeting and failure messages.") ); + connect(stdFontChooser, TQT_SIGNAL(fontSelected(const TQFont&)),this,TQT_SLOT(configChanged())); + ml->addWidget(label, 1, 0); + ml->addWidget(stdFontChooser, 1, 1); + + label = new TQLabel(i18n("&Failures:"), this); + failFontChooser = new KFontRequester(this); + label->setBuddy(failFontChooser); + TQWhatsThis::add( failFontChooser, i18n("This changes the font which is used for failure messages in the login manager.") ); + connect(failFontChooser, TQT_SIGNAL(fontSelected(const TQFont&)),this,TQT_SLOT(configChanged())); + ml->addWidget(label, 2, 0); + ml->addWidget(failFontChooser, 2, 1); + + label = new TQLabel(i18n("Gree&ting:"), this); + greetingFontChooser = new KFontRequester(this); + label->setBuddy(greetingFontChooser); + TQWhatsThis::add( greetingFontChooser, i18n("This changes the font which is used for the login manager's greeting.") ); + connect(greetingFontChooser, TQT_SIGNAL(fontSelected(const TQFont&)),this,TQT_SLOT(configChanged())); + ml->addWidget(label, 3, 0); + ml->addWidget(greetingFontChooser, 3, 1); + + aacb = new TQCheckBox (i18n("Use anti-aliasing for fonts"), this); + TQWhatsThis::add( aacb, i18n("If you check this box and your X-Server has the Xft extension, " + "fonts will be antialiased (smoothed) in the login dialog.") ); + connect(aacb, TQT_SIGNAL(toggled ( bool )),this,TQT_SLOT(configChanged())); + ml->addMultiCellWidget(aacb, 4, 4, 0, 1); + ml->setRowStretch(5, 10); +} + +void TDMFontWidget::makeReadOnly() +{ + stdFontChooser->button()->setEnabled(false); + failFontChooser->button()->setEnabled(false); + greetingFontChooser->button()->setEnabled(false); + aacb->setEnabled(false); +} + +void TDMFontWidget::configChanged() +{ + emit changed(true); +} + +void TDMFontWidget::set_def() +{ + stdFontChooser->setFont(TQFont("Sans Serif", 10)); + failFontChooser->setFont(TQFont("Sans Serif", 10, TQFont::Bold)); + greetingFontChooser->setFont(TQFont("Sans Serif", 22)); +} + +void TDMFontWidget::save() +{ + config->setGroup("X-*-Greeter"); + + // write font + config->writeEntry("StdFont", stdFontChooser->font()); + config->writeEntry("GreetFont", greetingFontChooser->font()); + config->writeEntry("FailFont", failFontChooser->font()); + config->writeEntry("AntiAliasing", aacb->isChecked()); +} + + +void TDMFontWidget::load() +{ + set_def(); + + config->setGroup("X-*-Greeter"); + + // Read the fonts + TQFont font = stdFontChooser->font(); + stdFontChooser->setFont(config->readFontEntry("StdFont", &font)); + font = failFontChooser->font(); + failFontChooser->setFont(config->readFontEntry("FailFont", &font)); + font = greetingFontChooser->font(); + greetingFontChooser->setFont(config->readFontEntry("GreetFont", &font)); + + aacb->setChecked(config->readBoolEntry("AntiAliasing")); +} + + +void TDMFontWidget::defaults() +{ + set_def(); + aacb->setChecked(true); +} + +#include "tdm-font.moc" diff --git a/kcontrol/tdm/tdm-font.h b/kcontrol/tdm/tdm-font.h new file mode 100644 index 000000000..67b2c864d --- /dev/null +++ b/kcontrol/tdm/tdm-font.h @@ -0,0 +1,57 @@ +/* This file is part of the KDE Display Manager Configuration package + Copyright (C) 1997 Thomas Tanghus (tanghus@earthling.net) + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __TDMFONT_H__ +#define __TDMFONT_H__ + +#include + +class KFontRequester; +class TQCheckBox; + +class TDMFontWidget : public TQWidget +{ + Q_OBJECT + +public: + TDMFontWidget(TQWidget *parent=0, const char *name=0); + + void load(); + void save(); + void defaults(); + void makeReadOnly(); + +signals: + void changed( bool state ); + +protected slots: + void configChanged(); + void set_def(); + +private: + TQCheckBox *aacb; + KFontRequester *greetingFontChooser; + KFontRequester *failFontChooser; + KFontRequester *stdFontChooser; +}; + + +#endif + + diff --git a/kcontrol/tdm/tdm-shut.cpp b/kcontrol/tdm/tdm-shut.cpp new file mode 100644 index 000000000..434b55ae2 --- /dev/null +++ b/kcontrol/tdm/tdm-shut.cpp @@ -0,0 +1,227 @@ +/* This file is part of the KDE Display Manager Configuration package + Copyright (C) 1997-1998 Thomas Tanghus (tanghus@earthling.net) + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "tdm-shut.h" +#include "kbackedcombobox.h" + +extern KSimpleConfig *config; + + +TDMSessionsWidget::TDMSessionsWidget(TQWidget *parent, const char *name) + : TQWidget(parent, name) +{ + TQString wtstr; + + + TQGroupBox *group0 = new TQGroupBox( i18n("Allow Shutdown"), this ); + + sdlcombo = new TQComboBox( FALSE, group0 ); + sdllabel = new TQLabel (sdlcombo, i18n ("&Local:"), group0); + sdlcombo->insertItem(i18n("Everybody"), SdAll); + sdlcombo->insertItem(i18n("Only Root"), SdRoot); + sdlcombo->insertItem(i18n("Nobody"), SdNone); + connect(sdlcombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); + sdrcombo = new TQComboBox( FALSE, group0 ); + sdrlabel = new TQLabel (sdrcombo, i18n ("&Remote:"), group0); + sdrcombo->insertItem(i18n("Everybody"), SdAll); + sdrcombo->insertItem(i18n("Only Root"), SdRoot); + sdrcombo->insertItem(i18n("Nobody"), SdNone); + connect(sdrcombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); + TQWhatsThis::add( group0, i18n("Here you can select who is allowed to shutdown" + " the computer using TDM. You can specify different values for local (console) and remote displays. " + "Possible values are:
    " + "
  • Everybody: everybody can shutdown the computer using TDM
  • " + "
  • Only root: TDM will only allow shutdown after the user has entered the root password
  • " + "
  • Nobody: nobody can shutdown the computer using TDM
") ); + + + TQGroupBox *group1 = new TQGroupBox( i18n("Commands"), this ); + + shutdown_lined = new KURLRequester(group1); + TQLabel *shutdown_label = new TQLabel(shutdown_lined, i18n("H&alt:"), group1); + connect(shutdown_lined, TQT_SIGNAL(textChanged(const TQString&)), + TQT_SLOT(changed())); + wtstr = i18n("Command to initiate the system halt. Typical value: /sbin/halt"); + TQWhatsThis::add( shutdown_label, wtstr ); + TQWhatsThis::add( shutdown_lined, wtstr ); + + restart_lined = new KURLRequester(group1); + TQLabel *restart_label = new TQLabel(restart_lined, i18n("Reb&oot:"), group1); + connect(restart_lined, TQT_SIGNAL(textChanged(const TQString&)), + TQT_SLOT(changed())); + wtstr = i18n("Command to initiate the system reboot. Typical value: /sbin/reboot"); + TQWhatsThis::add( restart_label, wtstr ); + TQWhatsThis::add( restart_lined, wtstr ); + + + TQGroupBox *group4 = new TQGroupBox( i18n("Miscellaneous"), this ); + + bm_combo = new KBackedComboBox( group4 ); + bm_combo->insertItem("None", i18n("boot manager", "None")); + bm_combo->insertItem("Grub", i18n("Grub")); +#if defined(__linux__) && ( defined(__i386__) || defined(__amd64__) ) + bm_combo->insertItem("Lilo", i18n("Lilo")); +#endif + TQLabel *bm_label = new TQLabel( bm_combo, i18n("Boot manager:"), group4 ); + connect(bm_combo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); + wtstr = i18n("Enable boot options in the \"Shutdown...\" dialog."); + TQWhatsThis::add( bm_label, wtstr ); + TQWhatsThis::add( bm_combo, wtstr ); + + TQBoxLayout *main = new TQVBoxLayout( this, 10 ); + TQGridLayout *lgroup0 = new TQGridLayout( group0, 1, 1, 10); + TQGridLayout *lgroup1 = new TQGridLayout( group1, 1, 1, 10); + TQGridLayout *lgroup4 = new TQGridLayout( group4, 1, 1, 10); + + main->addWidget(group0); + main->addWidget(group1); + main->addWidget(group4); + main->addStretch(); + + lgroup0->addRowSpacing(0, group0->fontMetrics().height()/2); + lgroup0->addColSpacing(2, KDialog::spacingHint() * 2); + lgroup0->setColStretch(1, 1); + lgroup0->setColStretch(4, 1); + lgroup0->addWidget(sdllabel, 1, 0); + lgroup0->addWidget(sdlcombo, 1, 1); + lgroup0->addWidget(sdrlabel, 1, 3); + lgroup0->addWidget(sdrcombo, 1, 4); + + lgroup1->addRowSpacing(0, group1->fontMetrics().height()/2); + lgroup1->addColSpacing(2, KDialog::spacingHint() * 2); + lgroup1->setColStretch(1, 1); + lgroup1->setColStretch(4, 1); + lgroup1->addWidget(shutdown_label, 1, 0); + lgroup1->addWidget(shutdown_lined, 1, 1); + lgroup1->addWidget(restart_label, 1, 3); + lgroup1->addWidget(restart_lined, 1, 4); + + lgroup4->addRowSpacing(0, group4->fontMetrics().height()/2); + lgroup4->addWidget(bm_label, 1, 0); + lgroup4->addWidget(bm_combo, 1, 1); + lgroup4->setColStretch(2, 1); + + main->activate(); + +} + +void TDMSessionsWidget::makeReadOnly() +{ + sdlcombo->setEnabled(false); + sdrcombo->setEnabled(false); + + restart_lined->lineEdit()->setReadOnly(true); + restart_lined->button()->setEnabled(false); + shutdown_lined->lineEdit()->setReadOnly(true); + shutdown_lined->button()->setEnabled(false); + + bm_combo->setEnabled(false); +} + +void TDMSessionsWidget::writeSD(TQComboBox *combo) +{ + TQString what; + switch (combo->currentItem()) { + case SdAll: what = "All"; break; + case SdRoot: what = "Root"; break; + default: what = "None"; break; + } + config->writeEntry( "AllowShutdown", what); +} + +void TDMSessionsWidget::save() +{ + config->setGroup("X-:*-Core"); + writeSD(sdlcombo); + + config->setGroup("X-*-Core"); + writeSD(sdrcombo); + + config->setGroup("Shutdown"); + config->writeEntry("HaltCmd", shutdown_lined->url(), true); + config->writeEntry("RebootCmd", restart_lined->url(), true); + + config->writeEntry("BootManager", bm_combo->currentId()); +} + +void TDMSessionsWidget::readSD(TQComboBox *combo, TQString def) +{ + TQString str = config->readEntry("AllowShutdown", def); + SdModes sdMode; + if(str == "All") + sdMode = SdAll; + else if(str == "Root") + sdMode = SdRoot; + else + sdMode = SdNone; + combo->setCurrentItem(sdMode); +} + +void TDMSessionsWidget::load() +{ + config->setGroup("X-:*-Core"); + readSD(sdlcombo, "All"); + + config->setGroup("X-*-Core"); + readSD(sdrcombo, "Root"); + + config->setGroup("Shutdown"); + restart_lined->setURL(config->readEntry("RebootCmd", "/sbin/reboot")); + shutdown_lined->setURL(config->readEntry("HaltCmd", "/sbin/poweroff")); + + bm_combo->setCurrentId(config->readEntry("BootManager", "None")); +} + + + +void TDMSessionsWidget::defaults() +{ + restart_lined->setURL("/sbin/reboot"); + shutdown_lined->setURL("/sbin/poweroff"); + + sdlcombo->setCurrentItem(SdAll); + sdrcombo->setCurrentItem(SdRoot); + + bm_combo->setCurrentId("None"); +} + + +void TDMSessionsWidget::changed() +{ + emit changed(true); +} + +#include "tdm-shut.moc" diff --git a/kcontrol/tdm/tdm-shut.h b/kcontrol/tdm/tdm-shut.h new file mode 100644 index 000000000..bbc6fdc29 --- /dev/null +++ b/kcontrol/tdm/tdm-shut.h @@ -0,0 +1,64 @@ +/* This file is part of the KDE Display Manager Configuration package + Copyright (C) 1997 Thomas Tanghus (tanghus@earthling.net) + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __TDMSESS_H__ +#define __TDMSESS_H__ + + +#include + +class TQComboBox; +class TQCheckBox; +class KURLRequester; +class KBackedComboBox; + +class TDMSessionsWidget : public TQWidget +{ + Q_OBJECT + +public: + TDMSessionsWidget(TQWidget *parent=0, const char *name=0); + + void load(); + void save(); + void defaults(); + void makeReadOnly(); + + enum SdModes { SdAll, SdRoot, SdNone }; + +signals: + void changed( bool state ); + +protected slots: + void changed(); + +private: + void readSD (TQComboBox *, TQString); + void writeSD (TQComboBox *); + + TQComboBox *sdlcombo, *sdrcombo; + TQLabel *sdllabel, *sdrlabel; + KURLRequester *restart_lined, *shutdown_lined; + KBackedComboBox *bm_combo; +}; + + +#endif + + diff --git a/kcontrol/tdm/tdm-users.cpp b/kcontrol/tdm/tdm-users.cpp new file mode 100644 index 000000000..f4b48b9a6 --- /dev/null +++ b/kcontrol/tdm/tdm-users.cpp @@ -0,0 +1,500 @@ +/* This file is part of the KDE Display Manager Configuration package + Copyright (C) 1997 Thomas Tanghus (tanghus@earthling.net) + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tdm-users.h" + +#include + + +extern KSimpleConfig *config; + +TDMUsersWidget::TDMUsersWidget(TQWidget *parent, const char *name) + : TQWidget(parent, name) +{ +#ifdef __linux__ + struct stat st; + if (!stat( "/etc/debian_version", &st )) { /* debian */ + defminuid = "1000"; + defmaxuid = "29999"; + } else if (!stat( "/usr/portage", &st )) { /* gentoo */ + defminuid = "1000"; + defmaxuid = "65000"; + } else if (!stat( "/etc/mandrake-release", &st )) { /* mandrake - check before redhat! */ + defminuid = "500"; + defmaxuid = "65000"; + } else if (!stat( "/etc/redhat-release", &st )) { /* redhat */ + defminuid = "100"; + defmaxuid = "65000"; + } else /* if (!stat( "/etc/SuSE-release", &st )) */ { /* suse */ + defminuid = "500"; + defmaxuid = "65000"; + } +#else + defminuid = "1000"; + defmaxuid = "65000"; +#endif + + // We assume that $kde_datadir/tdm exists, but better check for pics/ and pics/users, + // and create them if necessary. + config->setGroup( "X-*-Greeter" ); + m_userPixDir = config->readEntry( "FaceDir", KGlobal::dirs()->resourceDirs("data").last() + "tdm/faces" ) + '/'; + m_notFirst = false; + TQDir testDir( m_userPixDir ); + if ( !testDir.exists() && !testDir.mkdir( testDir.absPath() ) && !geteuid() ) + KMessageBox::sorry( this, i18n("Unable to create folder %1").arg( testDir.absPath() ) ); + chmod( TQFile::encodeName( m_userPixDir ), 0755 ); + + m_defaultText = i18n(""); + + TQString wtstr; + + minGroup = new TQGroupBox( 2, Qt::Horizontal, i18n("System U&IDs"), this ); + TQWhatsThis::add( minGroup, i18n("Users with a UID (numerical user identification) outside this range will not be listed by TDM and this setup dialog." + " Note that users with the UID 0 (typically root) are not affected by this and must be" + " explicitly hidden in \"Not hidden\" mode.")); + TQSizePolicy sp_ign_fix( TQSizePolicy::Ignored, TQSizePolicy::Fixed ); + TQValidator *valid = new TQIntValidator( 0, 999999, TQT_TQOBJECT(minGroup) ); + TQLabel *minlab = new TQLabel( i18n("Below:"), minGroup ); + leminuid = new KLineEdit( minGroup ); + minlab->setBuddy( leminuid ); + leminuid->setSizePolicy( sp_ign_fix ); + leminuid->setValidator( valid ); + connect( leminuid, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotChanged()) ); + connect( leminuid, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotMinMaxChanged()) ); + TQLabel *maxlab = new TQLabel( i18n("Above:"), minGroup ); + lemaxuid = new KLineEdit( minGroup ); + maxlab->setBuddy( lemaxuid ); + lemaxuid->setSizePolicy( sp_ign_fix ); + lemaxuid->setValidator( valid ); + connect(lemaxuid, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotChanged()) ); + connect(lemaxuid, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotMinMaxChanged()) ); + + usrGroup = new TQButtonGroup( 5, Qt::Vertical, i18n("Users"), this ); + connect( usrGroup, TQT_SIGNAL(clicked( int )), TQT_SLOT(slotShowOpts()) ); + connect( usrGroup, TQT_SIGNAL(clicked( int )), TQT_SLOT(slotChanged()) ); + cbshowlist = new TQCheckBox( i18n("Show list"), usrGroup ); + TQWhatsThis::add( cbshowlist, i18n("If this option is checked, TDM will show a list of users," + " so users can click on their name or image rather than typing in their login.") ); + cbcomplete = new TQCheckBox( i18n("Autocompletion"), usrGroup ); + TQWhatsThis::add( cbcomplete, i18n("If this option is checked, TDM will automatically complete" + " user names while they are typed in the line edit.") ); + cbinverted = new TQCheckBox( i18n("Inverse selection"), usrGroup ); + TQWhatsThis::add( cbinverted, i18n("This option specifies how the users for \"Show list\" and \"Autocompletion\"" + " are selected in the \"Select users and groups\" list: " + "If not checked, select only the checked users. " + "If checked, select all non-system users, except the checked ones.")); + cbusrsrt = new TQCheckBox( i18n("Sor&t users"), usrGroup ); + connect( cbusrsrt, TQT_SIGNAL(toggled( bool )), TQT_SLOT(slotChanged()) ); + TQWhatsThis::add( cbusrsrt, i18n("If this is checked, TDM will alphabetically sort the user list." + " Otherwise users are listed in the order they appear in the password file.") ); + + wstack = new TQWidgetStack( this ); + s_label = new TQLabel( wstack, i18n("S&elect users and groups:"), this ); + optinlv = new KListView( this ); + optinlv->addColumn( i18n("Selected Users") ); + optinlv->setResizeMode( TQListView::LastColumn ); + TQWhatsThis::add( optinlv, i18n("TDM will show all checked users. Entries denoted with '@' are user groups. Checking a group is like checking all users in that group.") ); + wstack->addWidget( optinlv ); + connect( optinlv, TQT_SIGNAL(clicked( TQListViewItem * )), + TQT_SLOT(slotUpdateOptIn( TQListViewItem * )) ); + connect( optinlv, TQT_SIGNAL(clicked( TQListViewItem * )), + TQT_SLOT(slotChanged()) ); + optoutlv = new KListView( this ); + optoutlv->addColumn( i18n("Hidden Users") ); + optoutlv->setResizeMode( TQListView::LastColumn ); + TQWhatsThis::add( optoutlv, i18n("TDM will show all non-checked non-system users. Entries denoted with '@' are user groups. Checking a group is like checking all users in that group.") ); + wstack->addWidget( optoutlv ); + connect( optoutlv, TQT_SIGNAL(clicked( TQListViewItem * )), + TQT_SLOT(slotUpdateOptOut( TQListViewItem * )) ); + connect( optoutlv, TQT_SIGNAL(clicked( TQListViewItem * )), + TQT_SLOT(slotChanged()) ); + + faceGroup = new TQButtonGroup( 5, Qt::Vertical, i18n("User Image Source"), this ); + TQWhatsThis::add( faceGroup, i18n("Here you can specify where TDM will obtain the images that represent users." + " \"Admin\" represents the global folder; these are the pictures you can set below." + " \"User\" means that TDM should read the user's $HOME/.face.icon file." + " The two selections in the middle define the order of preference if both sources are available.") ); + connect( faceGroup, TQT_SIGNAL(clicked( int )), TQT_SLOT(slotFaceOpts()) ); + connect( faceGroup, TQT_SIGNAL(clicked( int )), TQT_SLOT(slotChanged()) ); + rbadmonly = new TQRadioButton( i18n("Admin"), faceGroup ); + rbprefadm = new TQRadioButton( i18n("Admin, user"), faceGroup ); + rbprefusr = new TQRadioButton( i18n("User, admin"), faceGroup ); + rbusronly = new TQRadioButton( i18n("User"), faceGroup ); + + TQGroupBox *picGroup = new TQVGroupBox( i18n("User Images"), this ); + TQWidget *hlpw = new TQWidget( picGroup ); + usercombo = new KComboBox( hlpw ); + TQWhatsThis::add( usercombo, i18n("The user the image below belongs to.") ); + connect( usercombo, TQT_SIGNAL(activated( int )), + TQT_SLOT(slotUserSelected()) ); + TQLabel *userlabel = new TQLabel( usercombo, i18n("User:"), hlpw ); + userbutton = new TQPushButton( hlpw ); + userbutton->setAcceptDrops( true ); + userbutton->installEventFilter( this ); // for drag and drop + uint sz = style().pixelMetric( TQStyle::PM_ButtonMargin ) * 2 + 48; + userbutton->setFixedSize( sz, sz ); + connect( userbutton, TQT_SIGNAL(clicked()), + TQT_SLOT(slotUserButtonClicked()) ); + TQToolTip::add( userbutton, i18n("Click or drop an image here") ); + TQWhatsThis::add( userbutton, i18n("Here you can see the image assigned to the user selected in the combo box above. Click on the image button to select from a list" + " of images or drag and drop your own image on to the button (e.g. from Konqueror).") ); + rstuserbutton = new TQPushButton( i18n("Unset"), hlpw ); + TQWhatsThis::add( rstuserbutton, i18n("Click this button to make TDM use the default image for the selected user.") ); + connect( rstuserbutton, TQT_SIGNAL(clicked()), + TQT_SLOT(slotUnsetUserPix()) ); + TQGridLayout *hlpl = new TQGridLayout( hlpw, 3, 2, 0, KDialog::spacingHint() ); + hlpl->addWidget( userlabel, 0, 0 ); +// hlpl->addSpacing( KDialog::spacingHint() ); + hlpl->addWidget( usercombo, 0, 1 ); + hlpl->addMultiCellWidget( userbutton, 1,1, 0,1, Qt::AlignHCenter ); + hlpl->addMultiCellWidget( rstuserbutton, 2,2, 0,1, Qt::AlignHCenter ); + + TQHBoxLayout *main = new TQHBoxLayout( this, 10 ); + + TQVBoxLayout *lLayout = new TQVBoxLayout( main, 10 ); + lLayout->addWidget( minGroup ); + lLayout->addWidget( usrGroup ); + lLayout->addStretch( 1 ); + + TQVBoxLayout *mLayout = new TQVBoxLayout( main, 10 ); + mLayout->addWidget( s_label ); + mLayout->addWidget( wstack ); + mLayout->setStretchFactor( wstack, 1 ); + main->setStretchFactor( mLayout, 1 ); + + TQVBoxLayout *rLayout = new TQVBoxLayout( main, 10 ); + rLayout->addWidget( faceGroup ); + rLayout->addWidget( picGroup ); + rLayout->addStretch( 1 ); + +} + +void TDMUsersWidget::makeReadOnly() +{ + leminuid->setReadOnly(true); + lemaxuid->setReadOnly(true); + cbshowlist->setEnabled(false); + cbcomplete->setEnabled(false); + cbinverted->setEnabled(false); + cbusrsrt->setEnabled(false); + rbadmonly->setEnabled(false); + rbprefadm->setEnabled(false); + rbprefusr->setEnabled(false); + rbusronly->setEnabled(false); + wstack->setEnabled(false); + disconnect( userbutton, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotUserButtonClicked()) ); + userbutton->setAcceptDrops(false); + rstuserbutton->setEnabled(false); +} + +void TDMUsersWidget::slotShowOpts() +{ + bool en = cbshowlist->isChecked() || cbcomplete->isChecked(); + cbinverted->setEnabled( en ); + cbusrsrt->setEnabled( en ); + wstack->setEnabled( en ); + wstack->raiseWidget( cbinverted->isChecked() ? optoutlv : optinlv ); + en = cbshowlist->isChecked(); + faceGroup->setEnabled( en ); + if (!en) { + usercombo->setEnabled( false ); + userbutton->setEnabled( false ); + rstuserbutton->setEnabled( false ); + } else + slotFaceOpts(); +} + +void TDMUsersWidget::slotFaceOpts() +{ + bool en = !rbusronly->isChecked(); + usercombo->setEnabled( en ); + userbutton->setEnabled( en ); + if (en) + slotUserSelected(); + else + rstuserbutton->setEnabled( false ); +} + +void TDMUsersWidget::slotUserSelected() +{ + TQString user = usercombo->currentText(); + TQImage p; + if (user != m_defaultText && + p.load( m_userPixDir + user + ".face.icon" )) { + rstuserbutton->setEnabled( !getuid() ); + } else { + p.load( m_userPixDir + ".default.face.icon" ); + rstuserbutton->setEnabled( false ); + } + userbutton->setPixmap( p.smoothScale( 48, 48, TQ_ScaleMin ) ); +} + + +void TDMUsersWidget::changeUserPix(const TQString &pix) +{ + TQString user( usercombo->currentText() ); + if (user == m_defaultText) + { + user = ".default"; + if (KMessageBox::questionYesNo(this, i18n("Save image as default image?"),TQString::null,KStdGuiItem::save(),KStdGuiItem::cancel()) + != KMessageBox::Yes) + return; + } + + TQImage p( pix ); + if (p.isNull()) { + KMessageBox::sorry( this, + i18n("There was an error loading the image\n" + "%1").arg( pix ) ); + return; + } + + p = p.smoothScale( 48, 48, TQ_ScaleMin ); + TQString userpix = m_userPixDir + user + ".face.icon"; + if (!p.save( userpix, "PNG" )) + KMessageBox::sorry(this, + i18n("There was an error saving the image:\n%1") + .arg( userpix ) ); + else + chmod( TQFile::encodeName( userpix ), 0644 ); + + slotUserSelected(); +} + +void TDMUsersWidget::slotUserButtonClicked() +{ + KFileDialog dlg(m_notFirst ? TQString::null : + KGlobal::dirs()->resourceDirs("data").last() + "tdm/pics/users", + KImageIO::pattern( KImageIO::Reading ), + this, 0, true); + dlg.setOperationMode( KFileDialog::Opening ); + dlg.setCaption( i18n("Choose Image") ); + dlg.setMode( KFile::File | KFile::LocalOnly ); + + KImageFilePreview *ip = new KImageFilePreview( &dlg ); + dlg.setPreviewWidget( ip ); + if (dlg.exec() != TQDialog::Accepted) + return; + m_notFirst = true; + + changeUserPix( dlg.selectedFile() ); +} + +void TDMUsersWidget::slotUnsetUserPix() +{ + TQFile::remove( m_userPixDir + usercombo->currentText() + ".face.icon" ); + slotUserSelected(); +} + +bool TDMUsersWidget::eventFilter(TQObject *, TQEvent *e) +{ + if (e->type() == TQEvent::DragEnter) { + TQDragEnterEvent *ee = (TQDragEnterEvent *) e; + ee->accept( KURLDrag::canDecode(ee) ); + return true; + } + + if (e->type() == TQEvent::Drop) { + userButtonDropEvent((TQDropEvent *) e); + return true; + } + + return false; +} + +KURL *decodeImgDrop(TQDropEvent *e, TQWidget *wdg); + +void TDMUsersWidget::userButtonDropEvent(TQDropEvent *e) +{ + KURL *url = decodeImgDrop(e, this); + if (url) { + TQString pixpath; + KIO::NetAccess::download(*url, pixpath, parentWidget()); + changeUserPix( pixpath ); + KIO::NetAccess::removeTempFile(pixpath); + delete url; + } +} + +void TDMUsersWidget::save() +{ + config->setGroup( "X-*-Greeter" ); + + config->writeEntry( "MinShowUID", leminuid->text() ); + config->writeEntry( "MaxShowUID", lemaxuid->text() ); + + config->writeEntry( "UserList", cbshowlist->isChecked() ); + config->writeEntry( "UserCompletion", cbcomplete->isChecked() ); + config->writeEntry( "ShowUsers", + cbinverted->isChecked() ? "NotHidden" : "Selected" ); + config->writeEntry( "SortUsers", cbusrsrt->isChecked() ); + + config->writeEntry( "HiddenUsers", hiddenUsers ); + config->writeEntry( "SelectedUsers", selectedUsers ); + + config->writeEntry( "FaceSource", + rbadmonly->isChecked() ? "AdminOnly" : + rbprefadm->isChecked() ? "PreferAdmin" : + rbprefusr->isChecked() ? "PreferUser" : "UserOnly" ); +} + + +void TDMUsersWidget::updateOptList( TQListViewItem *item, TQStringList &list ) +{ + if ( !item ) + return; + TQCheckListItem *itm = (TQCheckListItem *)item; + TQStringList::iterator it = list.find( itm->text() ); + if (itm->isOn()) { + if (it == list.end()) + list.append( itm->text() ); + } else { + if (it != list.end()) + list.remove( it ); + } +} + +void TDMUsersWidget::slotUpdateOptIn( TQListViewItem *item ) +{ + updateOptList( item, selectedUsers ); +} + +void TDMUsersWidget::slotUpdateOptOut( TQListViewItem *item ) +{ + updateOptList( item, hiddenUsers ); +} + +void TDMUsersWidget::slotClearUsers() +{ + optinlv->clear(); + optoutlv->clear(); + usercombo->clear(); + usercombo->insertItem( m_defaultText ); +} + +void TDMUsersWidget::slotAddUsers(const TQMap &users) +{ + TQMapConstIterator it; + for (it = users.begin(); it != users.end(); ++it) { + const TQString *name = &it.key(); + (new TQCheckListItem(optinlv, *name, TQCheckListItem::CheckBox))-> + setOn(selectedUsers.find(*name) != selectedUsers.end()); + (new TQCheckListItem(optoutlv, *name, TQCheckListItem::CheckBox))-> + setOn(hiddenUsers.find(*name) != hiddenUsers.end()); + if ((*name)[0] != '@') + usercombo->insertItem(*name); + } + optinlv->sort(); + optoutlv->sort(); + if (usercombo->listBox()) + usercombo->listBox()->sort(); +} + +void TDMUsersWidget::slotDelUsers(const TQMap &users) +{ + TQMapConstIterator it; + for (it = users.begin(); it != users.end(); ++it) { + const TQString *name = &it.key(); + if (usercombo->listBox()) + delete usercombo->listBox()->findItem( *name, ExactMatch | CaseSensitive ); + delete optinlv->findItem( *name, 0 ); + delete optoutlv->findItem( *name, 0 ); + } +} + +void TDMUsersWidget::load() +{ + TQString str; + + config->setGroup("X-*-Greeter"); + + selectedUsers = config->readListEntry( "SelectedUsers"); + hiddenUsers = config->readListEntry( "HiddenUsers"); + + leminuid->setText(config->readEntry("MinShowUID", defminuid)); + lemaxuid->setText(config->readEntry("MaxShowUID", defmaxuid)); + + cbshowlist->setChecked( config->readBoolEntry( "UserList", true ) ); + cbcomplete->setChecked( config->readBoolEntry( "UserCompletion", false ) ); + cbinverted->setChecked( config->readEntry( "ShowUsers" ) != "Selected" ); + cbusrsrt->setChecked(config->readBoolEntry("SortUsers", true)); + + TQString ps = config->readEntry( "FaceSource" ); + if (ps == TQString::fromLatin1("UserOnly")) + rbusronly->setChecked(true); + else if (ps == TQString::fromLatin1("PreferUser")) + rbprefusr->setChecked(true); + else if (ps == TQString::fromLatin1("PreferAdmin")) + rbprefadm->setChecked(true); + else + rbadmonly->setChecked(true); + + slotUserSelected(); + + slotShowOpts(); + slotFaceOpts(); +} + +void TDMUsersWidget::defaults() +{ + leminuid->setText( defminuid ); + lemaxuid->setText( defmaxuid ); + cbshowlist->setChecked( true ); + cbcomplete->setChecked( false ); + cbinverted->setChecked( true ); + cbusrsrt->setChecked( true ); + rbadmonly->setChecked( true ); + hiddenUsers.clear(); + selectedUsers.clear(); + slotShowOpts(); + slotFaceOpts(); +} + +void TDMUsersWidget::slotMinMaxChanged() +{ + emit setMinMaxUID( leminuid->text().toInt(), lemaxuid->text().toInt() ); +} + +void TDMUsersWidget::slotChanged() +{ + emit changed(true); +} + +#include "tdm-users.moc" diff --git a/kcontrol/tdm/tdm-users.h b/kcontrol/tdm/tdm-users.h new file mode 100644 index 000000000..8a87c28dd --- /dev/null +++ b/kcontrol/tdm/tdm-users.h @@ -0,0 +1,106 @@ +/* This file is part of the KDE Display Manager Configuration package + Copyright (C) 1997 Thomas Tanghus (tanghus@earthling.net) + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __TDMUSERS_H__ +#define __TDMUSERS_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + + +class TDMUsersWidget : public TQWidget +{ + Q_OBJECT + +public: + TDMUsersWidget( TQWidget *parent = 0, const char *name = 0 ); + + void load(); + void save(); + void defaults(); + void makeReadOnly(); + + bool eventFilter( TQObject *o, TQEvent *e ); + +public slots: + void slotClearUsers(); + void slotAddUsers( const TQMap & ); + void slotDelUsers( const TQMap & ); + +signals: + void changed( bool state ); + void setMinMaxUID( int, int ); + +private slots: + void slotMinMaxChanged(); + void slotShowOpts(); + void slotUpdateOptIn( TQListViewItem *item ); + void slotUpdateOptOut( TQListViewItem *item ); + void slotUserSelected(); + void slotUnsetUserPix(); + void slotFaceOpts(); + void slotUserButtonClicked(); + void slotChanged(); + +private: + void updateOptList( TQListViewItem *item, TQStringList &list ); + void userButtonDropEvent( TQDropEvent *e ); + void changeUserPix( const TQString & ); + + TQGroupBox *minGroup; // top left + TQLineEdit *leminuid, *lemaxuid; + + TQButtonGroup *usrGroup; // right below + TQCheckBox *cbshowlist, *cbcomplete, *cbinverted, *cbusrsrt; + + TQLabel *s_label; // middle + TQWidgetStack *wstack; + KListView *optoutlv, *optinlv; + + TQButtonGroup *faceGroup; // right + TQRadioButton *rbadmonly, *rbprefadm, *rbprefusr, *rbusronly; + + KComboBox *usercombo; // right below + TQPushButton *userbutton; + TQPushButton *rstuserbutton; + + TQString m_userPixDir; + TQString m_defaultText; + TQStringList hiddenUsers, selectedUsers; + TQString defminuid, defmaxuid; + + bool m_notFirst; +}; + +#endif + + diff --git a/kcontrol/tdm/tdm.desktop b/kcontrol/tdm/tdm.desktop new file mode 100644 index 000000000..978918ec4 --- /dev/null +++ b/kcontrol/tdm/tdm.desktop @@ -0,0 +1,243 @@ +[Desktop Entry] +Exec=kcmshell tdm +Icon=tdmconfig +Type=Application +DocPath=tdm/index.html#configuring-tdm + +X-KDE-SubstituteUID=true + +X-KDE-Library=tdm +X-KDE-RootOnly=true + +X-KDE-ParentApp=kcontrol + +Name=Login Manager +Name[af]=Aanteken Bestuurder +Name[ar]=مسيير تسجيل الدخول +Name[az]=İclas Açma İdarəcisi +Name[be]=Кіраўнік уваходу +Name[bg]=Вход в системата +Name[bn]=লগ-ইন ম্যানেজার +Name[br]=Merour ereañ +Name[bs]=Login menadžer +Name[ca]=Gestor d'accés +Name[cs]=Správce přihlášení +Name[csb]=Menedżer logòwaniô +Name[cy]=Rheolydd Mewngofnodi +Name[da]=Login-håndtering +Name[de]=Anmeldungsmanager +Name[el]=Διαχειριστής σύνδεσης +Name[eo]=Salutilo +Name[es]=Gestor de acceso +Name[et]=Sisselogimise haldur +Name[eu]=Saio-hasieraren kudeatzailea +Name[fa]=مدیر ورود +Name[fi]=Sisäänkirjautumisasetukset +Name[fr]=Gestionnaire de connexion +Name[fy]=Oanmeldskerm +Name[ga]=Bainisteoir Logála Isteach +Name[gl]=Xestor de Login +Name[he]=מנהל הכניסה למערכת +Name[hi]=लॉगइन प्रबंधक +Name[hr]=Upravljanje prijavljivanjem +Name[hu]=Bejelentkező felület (TDM) +Name[id]=Manajer Login +Name[is]=Innstimplunarstjóri +Name[it]=Gestione degli accessi +Name[ja]=ログインマネージャ +Name[ka]=შესვლის მენეჯერი +Name[kk]=Жүйеге кіруді басқару +Name[km]=កម្មវិធី​គ្រប់គ្រង​ការ​ចូល +Name[ko]=로그인 관리자 +Name[lo]=ຈັດການລັອກອິນ +Name[lt]=Registravimosi tvarkyklė +Name[lv]=Pieteikšanās Menedžeris +Name[mk]=Менаџер на најави +Name[mn]=Нэвтрэлт удирдагч +Name[ms]=Pengurus Login +Name[mt]=Manager tal-Login +Name[nb]=Innloggingsbehandler +Name[nds]=Anmellen-Schirm +Name[ne]=लगइन प्रबन्धक +Name[nl]=Aanmeldscherm +Name[nn]=Innloggingshandsamar +Name[nso]=Molaodi wa Tseno +Name[oc]=Gestionari de connexion +Name[pa]=ਲਾਗ ਮੈਨੇਜਰ +Name[pl]=Menedżer logowania +Name[pt]=Gestor de Autenticação +Name[pt_BR]=Gerenciador de Login +Name[ro]=Managerul de logare +Name[ru]=Менеджер входа в систему +Name[rw]=Mugenga w'Ifashayinjira +Name[se]=Sisačálihangieđahalli +Name[sk]=Správca prihlásenia +Name[sl]=Upravitelj prijav +Name[sr]=Менаџер пријављивања +Name[sr@Latn]=Menadžer prijavljivanja +Name[sv]=Inloggningshanterare +Name[ta]=நுழைவு மேலாளர் +Name[te]=లాగిన్ అభికర్త +Name[tg]=Мудири вуруд +Name[th]=ตัวจัดการการล็อกอิน +Name[tr]=Giriş Yöneticisi +Name[tt]=Kerü İdäçese +Name[uk]=Менеджер реєстрації +Name[uz]=Kirish boshqaruvchisi +Name[uz@cyrillic]=Кириш бошқарувчиси +Name[ven]=Mulanguli wa u loga +Name[vi]=Trình quản lí Đăng nhập +Name[wa]=Manaedjeu d' elodjaedje +Name[xh]=Umphathi Wegama elithile +Name[zh_CN]=登录管理器 +Name[zh_TW]=登錄管理程式 +Name[zu]=Imenenja yokungena ngaphakathi + +Comment=Configure the login manager (TDM) +Comment[af]=Konfigureer die aanteken bestuurder (Kdm) +Comment[ar]=إعداد مسيير الدخول (TDM) +Comment[az]=Giriş İdarəçisi (TDM) Qurğuları +Comment[be]=Настаўленні кіраўніка ўваходу (TDM) +Comment[bg]=Настройване на графичната системата за вход +Comment[bn]=লগ-ইন ম্যানেজার কনফিগার করুন +Comment[br]=Kefluniañ ar merour ereañ (TDM) +Comment[bs]=Podesite menadžer prijavom (TDM) +Comment[ca]=Configura el gestor d'accés (TDM) +Comment[cs]=Nastavení správce přihlášení (TDM) +Comment[csb]=Kònfigùracëjô menedżera logòwaniô (TDM) +Comment[cy]=Ffurfweddu y rheolydd mewngofnodi (TDM) +Comment[da]=Indstil indlogningshåndtering (TDM) +Comment[de]=Anmeldungsmanager TDM einrichten +Comment[el]=Ρυθμίστε το διαχειριστή σύνδεσης (TDM) +Comment[eo]=Agordu la salutadminstrilon (TDM) +Comment[es]=Configura el gestor de acceso (TDM) +Comment[et]=Sisselogimise halduri seadistamine (TDM) +Comment[eu]=Konfiguratu saio-hasieraren kudeatzailea (TDM) +Comment[fa]=پیکربندی مدیر ورود (TDM) +Comment[fi]=Sisäänkirjautumisasetukset +Comment[fr]=Configuration du gestionnaire de connexion (TDM) +Comment[fy]=Hjir kinne jo it oanmeldskerm ynstelle (TDM) +Comment[ga]=Cumraigh an bainisteoir logála isteach (TDM) +Comment[gl]=Configurar o xestor de início (TDM) +Comment[he]=שינוי הגדרות מנהל הכניסה למערכת (TDM) +Comment[hi]=लॉगइन प्रबंधक कॉन्फ़िगर करें (केडीएम) +Comment[hr]=Konfiguriranje upravljanja prijavljivanja (TDM) +Comment[hu]=A KDE grafikus bejelentkező felületének beállításai +Comment[is]=Stilla innstimplunarstjórann (TDM) +Comment[it]=Configurazione della gestione degli accessi (TDM) +Comment[ja]=ログインマネージャ (TDM) の設定 +Comment[ka]=შევლის მენეჯერის კონფიგურირება (TDM) +Comment[kk]=Жүйеге кіруді басқаруын (TDM) баптау +Comment[km]=កំណត់​រចនាសម្ព័ន្ធ​កម្មវិធី​គ្រប់គ្រង​ការ​ចូល (TDM) +Comment[ko]=로그인 관리자 TDM 설정 +Comment[lo]=ປັບແຕ່ງປລັກອິນແລະການເຊື່ອມ ຕໍ່ສຳລັບລະບົບ KDB +Comment[lt]=Konfigūruoti registravimos tvarkyklę (TDM) +Comment[lv]=Konfigure pieteiksanās menedžeri TDM +Comment[mk]=Конфигурирајте го менаџерот на најави (TDM) +Comment[mn]=Нэвтрэлт удирдагч TDM тохируулах +Comment[ms]=Konfigur pengurus login (TDM) +Comment[mt]=Ikkonfigura l-manager tal-logins (TDM) +Comment[nb]=Tilpass innlogin­gsbehandler (TDM) +Comment[nds]=Den Anmellen-Schirm instellen (TDM) +Comment[ne]=लगइन प्रबन्धक (TDM) कन्फिगर गर्नुहोस् +Comment[nl]=Hier kunt u het aanmeldscherm (TDM) instellen +Comment[nn]=Set opp innloggingshandsamaren (TDM) +Comment[nso]=Beakanya molaodoi wa tseno (TDM) +Comment[pa]=ਲਾਗਆਨ ਮੈਨੇਜਰ ਸੰਰਚਨਾ(TDM) +Comment[pl]=Konfiguracja menedżera logowania (TDM) +Comment[pt]=Configuração do gestor de autenticação (TDM) +Comment[pt_BR]=Configura o gerenciador de login (TDM) +Comment[ro]=Configurează managerul de logare grafică (TDM) +Comment[ru]=Настройка менеджера входа в систему (TDM) +Comment[rw]=Kuboneza mugenga w'ifashayinjira (TDM) +Comment[se]=Heivet sisačálihangieđahalli (TDM) +Comment[sk]=Nastavenie správcu prihlásenia (TDM) +Comment[sl]=Nastavitve upravitelja prijav (TDM) +Comment[sr]=Подешавање менаџера за пријављивање (TDM) +Comment[sr@Latn]=Podešavanje menadžera za prijavljivanje (TDM) +Comment[sv]=Anpassa inloggningshanteraren (TDM) +Comment[ta]=புகுபதிகை மேலாளரை அமை (TDM) +Comment[tg]=Танзими мудири вуруд (TDM) +Comment[th]=ปรับแต่งเครื่องมือจัดการการล็อกอิน (TDM) +Comment[tr]=Giriş yöneticisini yapılandır (TDM) +Comment[tt]=Kerü idäräçen caylaw urını (TDM) +Comment[uk]=Налаштування менеджера реєстрації (TDM) +Comment[uz]=Tizimga kirish boshqaruvchisini (TDM) moslash +Comment[uz@cyrillic]=Тизимга кириш бошқарувчисини (TDM) мослаш +Comment[ven]=Ni nga dzudzanya mulanguli wau loga (TDM) +Comment[vi]=Cấu hình trình đăng nhập (TDM) +Comment[wa]=Apontyî l' manaedjeu d' elodjaedje (TDM) +Comment[xh]=Qwalasela umphathi wegama elithile (TDM) +Comment[zh_CN]=配置登录管理器(TDM) +Comment[zh_TW]=設定登入管理程式 (TDM) +Comment[zu]=Hlanganisela imenenja yokungena ngaphakathi (TDM) + +Keywords=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart +Keywords[ar]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,مدير العرض,المستخدمون مستخدمون,المستخدمين,مستخدمين,دخول,الدخول,تحية,التحية,اللغة,المظهر, البلد,الخطوط,الخط,خطوط,خط,خلفية,ورق حائط,جلسات,اغلاق,اعادة تشغيل +Keywords[az]=tdm,görünüş idarəçi,xdm,istifadəçilər,iclas açma,qarşılama,loqo,tərzlər,dil,ölkə,yazı növləri,arxa plan,divar kağızları,iclaslar,qapat,təkrar başlat +Keywords[be]=кіраўнік дысплея,кіраўнік уваходу,карыстальнікі,уваход,запрашэнне,лагатып,стылі,стыль,мова,краіна,шрыфты,фон,шпалеры,сесіі,сесія,выключэнне,перазагрузка,tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart +Keywords[bg]=графична, система, вход, влизане, включване, потребител, tdm, display manager, xdm, users, login, greeting, Logo, styles, language, country, fonts, background, wallpapers, sessions, shutdown, restart +Keywords[ca]=tdm,administrador de la pantalla,xdm,usuaris,accés,salutació,Logo,estils,llengua,país,lletres,fons,tapissos,sessions,apagar,reiniciar +Keywords[cs]=tdm,Správce obrazovky,xdm,Uživatelé,Přihlášení,Uvítání,Logo,Styly,Jazyk,Země,Písma,pozadí,Tapety,Relace,Sezení,Vypnutí,Restart +Keywords[csb]=tdm,menedżer ekranu,xdm,brëkòwnicë,logòwanié,przëwitanié,Logò,sztéle,jãzëk,kraj,fòntë,spódk,tapetë,spòdlë,sesëje,zamkniãce systemë,resztart,zôczãce robòtë +Keywords[cy]=tdm,rheolydd y dangosydd,xdm,defnyddwyr,mewngofnodi,cyfarchiad,Logo,arddulliau,iaith,gwlad,ffontiau,cefndir,papurau wal,sesiynau,cau,ailgychwyn +Keywords[da]=tdm,skærmhåndtering,xdm,brugere,login,hilsen,Logo,stil, sprog,land,skrifttyper,baggrund,tapeter,sessioner,luk ned,genstart +Keywords[de]=Kdm,Display Manager,Xdm,Benutzer,Login,Logo,Stile,Sprachen,Länder,Schriften,Hintergründe,Hintergrundbilder,Beenden,Neustart +Keywords[el]=tdm,διαχειριστής οθόνης,xdm,χρήστες,σύνδεση,χαιρετισμός,Λογότυπο,στυλ,γλώσσα,χώρα,γραμματοσειρές,φόντο,ταπετσαρίες,συνεδρίες,τερματισμός,επανεκκίνηση +Keywords[eo]=tdm,ekrano,,xdm,uzantoj,saluto,emblemo,stilo,lingvo,lando,tiparo,fono,tapeto,seanco,adaiaŭo,relanĉo +Keywords[es]=tdm,gestor de pantalla,xdm,usuarios,entrada,acceso,saludo,Logo,estilos,idioma,país,tipos de letra,fondo,tapices,sesiones,apagar,reiniciar +Keywords[et]=tdm,ekraanihaldur,xdm,kasutajad,sisselogimine,tervitus,logo,stiil,keel,riik,fondid,taust,taustapilt,seansid,töö lõpetamine,taaskäivitamine +Keywords[eu]=tdm,pantaila kudeatzailea,xdm,erabiltzaileak,Saio hasiera,agurra,Logoa,estiloak,hizkuntza, herrialdea,letra-tipoak,atzeko planoa,horma-irudiak,saioak,itzali,berrabiarazi +Keywords[fa]=tdm، مدیر نمایش، xdm، کاربران، ورود، تبریک، آرمِ، سبک، زبان، کشور، قلمها، زمینه، کاغذهای دیواری، نشستها، تعطیل، بازآغازی +Keywords[fi]=tdm,näytönhallinta ,xdm,käyttäjät,sisäänkirjautuminen,tervehdys,Logo,tyylit,kieli,maa,kirjasimet,tausta,istunnot,sammutus,uudelleenkäynnistys +Keywords[fr]=tdm,gestionnaire d'affichage,xdm,utilisateurs,login,connexion,bienvenue,message de bienvenue,Logo,styles,langue,pays,style,police,fond d'écran,papier peint,session,arrêt,logout,redémarrage,reboot +Keywords[fy]=tdm,display manager,xdm,users,login,begroeting,oanmelde,brûkers,Oanmeldbehearder,logo,stylen,taal,language,country,lân,fonts,lettertypen,eftergrûn,wallpapers,behang,sesjes,shutdown,restart,ôfslute,opnij begjinne,oanmelde +Keywords[ga]=tdm,bainisteoir scáileáin,xdm,úsáideoirí,logáil isteach,fáilte,Lógó,stíleanna,teanga,tír,clónna,clófhoirne,cúlra,cúlbhrait,seisiúin,múchadh,atosú +Keywords[gl]=tdm,xestor de entrada,xdm,usuarios,identificación,Logo,estilos,lingua,país,fontes,fondo,papeis tapiz,sesións,apagado,reinício +Keywords[he]=משתמשים,כניסה למערכת,כניסה,לוגו,סגנונות,שפה,מדינה,גופנים,רקע,טפטים,הפעלות,כיבוי,הפעלה,מחדש,מנהל,תצוגה,display,manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart +Keywords[hi]=केडीएम,प्रकटन प्रबंधक,एक्स-डीएम,उपयोक्ता,लॉगइन,शुभकामनाएँ,लोगो,पृष्ठभूमि,वालपेपर्स,सत्र,बन्द, फिर से चालू +Keywords[hr]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,upravljanje zaslona,korisnici,prijava,pozdrav,stilovi,jezik,država,zemlja,fontovi,pozadina,pozadina radne površine,sesije,gašenje,ponovno pokretanje +Keywords[hu]=tdm,képernyőkezelő,xdm,felhasználók,bejelentkezés,üdvözlés,embléma,stílusok,nyelv,ország,betűtípusok,háttér,tapéták,munkafolyamatok,leállítás,újraindítás +Keywords[is]=tdm,skjár,gluggastjóri,innskráning,innstimplun,snið,tungumál,land,letur,bakgrunnur,bakgrunnar,veggfóður,setur,slökkva,endurræsa +Keywords[it]=tdm,display manager,gestione degli utenti,xdm,utenti,login,accesso,benvenuto,logo,stile,lingua,stato,paese,tipi di carattere,sfondo,immagine di sfondo,sessioni,riavvio,spegnimento,gestione degli accessi +Keywords[ja]=tdm,ディスプレイマネージャ,xdm,ユーザ,ログイン,あいさつ,ロゴ,スタイル,言語,国,フォント,背景,壁紙,セッション,シャットダウン,再起動 +Keywords[km]=tdm,កម្មវិធី​គ្រប់គ្រង​ការ​បង្ហាញ,xdm,អ្នក​ប្រើ,ចូល,ស្វាគមន៍,រូបសញ្ញា,រចនាប័ទ្ម,ភាសា,ប្រទេស,ពុម្ពអក្សរ,ផ្ទៃ​ខាង​ក្រោយ,ក្រដាស​បិទ​ជញ្ជាំង,សម័យ,បិទ,ចាប់ផ្ដើម​ឡើង​វិញ +Keywords[lt]=tdm,display manager,ekrano tvarkyklė,xdm,users,naudotojai,login,registracija,greeting,pasveikinimas,Logo, styles,stiliai,language,country,fonts,background,wallpapers,sessions, shutdown,restart +Keywords[lv]=tdm,displeja menedžeris,xdm,lietotāji,pieteikšanās,apsveikums,Logo,stili,valoda,valsts,fonti,fons,tapetes,sesijas,nošaut,pārstartēt +Keywords[mk]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,менаџер на екран,корисници,најава,поздрав,Лого,стилови,јазик,земја,фонтови,подлога,позадина,сесии,исклучување,рестартирање +Keywords[mn]=Kdm,Display Manager,Xdm,Хэрэглэгч,Login,Logo,Хэлбэр,Хэл,Улс,Бичиг,Дэвсгэр,Дэвсгэр зураг,Дуусгах,Шинээр эхлүүлэх +Keywords[mt]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,merħba,lingwa,pajjiż,sfond,itfi,irristartja +Keywords[nb]=tdm,skjermbehandler,xdm,brukere,innlogging,velkomst,logo,stiler,språk,land,skrifttyper,bakgrunn,bakgrunnsbilde,økter,skru av,slå av,omstart +Keywords[nds]=tdm,Startschirm,xdm,Bruker,anmellen,greeting,Logo,Stilen,Spraak,Land,Schriftoorden,Achtergrund,Tapeten,Törns,Utmaken,Nieg starten +Keywords[ne]=tdm, प्रदर्शन प्रबन्धक, xdm, प्रयोगकर्ताहरू, लगइन, अभिवादन, परिचायक चिन्ह, शैलीहरू, भाषा, देश, फन्टहरू, पृष्ठभूमि,वालपेपरहरू, सत्र, बन्द गर्नुहोस्, फेरि सुरु गर्नुहोस् +Keywords[nl]=tdm,display manager,xdm,users,login,begroeting,inloggen,gebruikers,loginbeheerder,logo,stijlen,taal,language,country,land,fonts,lettertypen,achtergrond,wallpapers,behang,sessies,shutdown,restart,afsluiten,herstarten,aanmelden,opstarten +Keywords[nn]=tdm,xdm,brukarar,innlogging,helsing,logo,stil,språk,land,skrifttypar,bakgrunn,bakgrunnsbilete,økt,avslutt,slå av,omstart +Keywords[nso]=tdm,molaodi wa pontsho,xdm,badirisi,tseno,madume,Logo,mekgwa,leleme,naga,difonto,bokamorago,di-wallpaper,ditiragalo,timo,thomaleswa +Keywords[pa]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart, ਲੋਗੋ, ਭਾਸ਼ਾ, ਦੇਸ਼, ਫੋਂਟ, ਲਾਗਿੰਨ, ਉਪਭੋਗੀ,ਸ਼ੈਸ਼ਨ +Keywords[pl]=tdm,menedżer ekranu,xdm,użytkownicy,logowanie,powitanie,Logo,style,jezyk,kraj,czcionki,tło,tapety,sesje,zamknięcie systemu,restart,rozpoczęcie pracy +Keywords[pt]=tdm,gestor de 'logins',xdm,utilizadores,saudação,logótipo,estilos,língua,país,tipos de letra,fundo,papéis de parede,sessões,terminar,reiniciar +Keywords[pt_BR]=tdm,gerenciador de tela, xdm,usuários,login,saudação,Logo,estilos,linguagem,país,fontes, papéis de parede,sessões,desligar,reiniciar +Keywords[ro]=tdm,manager de ecran,xdm,utilizatori,logare,întîmpinare,logo,stiluri,limbaj,țară,fonturi,fundal,imagini de fundal,sesiuni,oprire,restartare +Keywords[ru]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,перезагрузка,сеанс,шрифты,страна,фон,стили,обои +Keywords[rw]=tdm,kwerekana umuyobozi,xdm,abakoresha,ifashayinjira,gusuhuza,ikirango,imisusire,ururimi,igihugu,imyandikire,mbuganyuma,impapurorukuta,imikoro,kuzimya,kongera gutangiza +Keywords[se]=tdm,xdm,geavaheaddjit,sisačáliheapmi,dearvvuođat,logo,stiila,giella,riika, fonttat,duogáš,duogášgovva,bargovuorut,heaittihit,časkit eret,ođđasit álggahit +Keywords[sk]=tdm,správca obrazovky,Login manažér,správca prihlásenia,xdm,používatelia,prihlásenie,login,privítanie,logo,štýly,jazyk,krajina,pozadie,tapety,sedenia,vypnutie,reset,reštart +Keywords[sl]=tdm,upravitelj zaslona,upravljalnik,xdm,uporabniki,prijava,login,pozdrav,logo,slogi,jezik,država,pisave,ozadje,tapete,seje,ugasnitev,vnovičen zagon +Keywords[sr]=tdm,display manager,xdm,users,login,greeting,Лого,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,менаџер,пријављивање,стил,језик,земља,фонтови,позадина,сесије,гашење +Keywords[sr@Latn]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,menadžer,prijavljivanje,stil,jezik,zemlja,fontovi,pozadina,sesije,gašenje +Keywords[sv]=tdm,display manager,xdm,användare,inloggning,välkomsttext,Logo,stilar,språk,land,teckensnitt,bakgrund,skrivbordsunderlägg,sessioner,stäng av,starta om +Keywords[ta]=கேடிஎம்,காட்சி மேலாளர்,xdm,பயன்படுத்துபவர்,உள்நுழை,வாழ்த்து,சின்னம்,பாணிகள்,மொழி,நாடு,எழுத்துருக்கள்,பின்னணி,வால்பேப்பர்கள்,பகுதிகள்,முடித்தல்,தொடங்குதல் +Keywords[th]=tdm,ตัวจัดการจอแสดงผล,xdm,ผู้ใช้,ล็อกอิน, ทักทาย,โลโก้,รูปแบบ,ภาษา,ประเทศ,แบบอักษร,พื้นหลัง, วอลล์เปเปอร์,วาระ,ปิด,เริ่มการทำงานใหม่ +Keywords[tr]=tdm,görüntü yönetici,xdm,kullanıcılar,oturum açma,karşılama,logo,stiller,dil,ülke,yazı tipleri,artalan,duvar kağıtları,oturumlar,kapat,tekrar başlat +Keywords[uk]=tdm,менеджер дисплеїв,xdm,користувачі,реєстрація,привітання,логотип,стилі,мова,країна,шрифти,тло,шпалери,сеанси,вимикання,перезапуск +Keywords[uz]=tdm,kirish boshqaruvchisi,xdm,foydalanuvchilar,kirish,salomlashish,Belgi,uslublar,til,davlat,shriftlar,orqa fon,seanslar,oʻchirish,oʻchirib-yoqish +Keywords[uz@cyrillic]=tdm,кириш бошқарувчиси,xdm,фойдаланувчилар,кириш,саломлашиш,Белги,услублар,тил,давлат,шрифтлар,орқа фон,сеанслар,ўчириш,ўчириб-ёқиш +Keywords[ven]=tdm,mulanguli wau vhonisa,xdm,vhashumisi,u loga,dzindumeliso,logo,zwitaela,luambo,shango,fontu,murahu,mabammbiri a luvhondoni,tshitenwa,thutha,thomolosa +Keywords[vi]=tdm,quản lý hiển thị,xdm,người dùng,đăng nhập,chào hỏi,Biểu trưng,kiểu,ngôn ngữ,quốc gia,phông chữ,nền,ảnh nền,phiên đăng nhập,tắt máy,khởi động lại +Keywords[wa]=tdm,manaedjeu d' håynaedje,xdm,uzeus,login,wilikom,greeting,Logo,styles,stîles,lingaedje,payi,fontes,fond,fond del waitroûle,sessions,distinde,dislodjî,elodjî,s' elodjî,renonder +Keywords[xh]=tdm,umphathi womboniso,xdm,abasebenzisi,igama elithile,umbuliso,ilogo,iintlobo,ulwimi,ilizwe,ubungakanani bamagama, imvelaphi,amaphepha odonga,iintlanganiso,vala,qala kwakhona +Keywords[zh_CN]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,显示管理器,用户,登录,欢迎辞,标志,风格,语言,国家,字体,背景,墙纸,会话,关机,重启动 +Keywords[zh_TW]=tdm,display manager,xdm,users,login,greeting,Logo,styles,language,country,fonts,background,wallpapers,sessions,shutdown,restart,顯示管理程式,使用者,登入,歡迎,風格,語言,國家,字型,背景,底圖,工作階段,關機,重新啟動 +Keywords[zu]=tdm,Imenenja yokuveza,xdm,abasebenzisi,ukungena ngaphakathi,isibingelelo,Isiqubulo,izitayela,ulimi,izwe,izinhlobo zamagama, inkundla yangemuva,emaphepha ezindonga,iziqendu,vala,phinda uqale + +Categories=Qt;KDE;X-KDE-settings-system; diff --git a/kdm/CMakeLists.txt b/kdm/CMakeLists.txt deleted file mode 100644 index 08096f84c..000000000 --- a/kdm/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -# FIXME initial work, only PAM -# FIXME needs more checks (for kerberos, etc) -# FIXME Xsession need some improvements - -if( NOT DEFINED TDM_PAM_SERVICE ) - set( TDM_PAM_SERVICE "kde" CACHE INTERNAL "" ) -endif( ) - -include( ConfigureChecks.cmake ) - -add_subdirectory( backend ) -add_subdirectory( kfrontend ) diff --git a/kdm/ChangeLog b/kdm/ChangeLog deleted file mode 100644 index 58a3014f6..000000000 --- a/kdm/ChangeLog +++ /dev/null @@ -1,540 +0,0 @@ -This change log contains only changes relevant to the TDM configuration, -startup and packaging. Bug fixes are not listed, and feature changes only -if they affect the configuration. - -2005-08-21 Oswald Buddenhagen - - * Added timed login. Option AutoLoginDelay. - * Added persistent auto-login. Option AutoLoginAgain. - -2005-02-01 Oswald Buddenhagen - - * Made the word splitter more sh-like. Affects HaltCmd, RebootCmd, - Setup, Startup, Reset, Session and Xrdb. - * Replaced option Xservers with StaticServers, ReserveServers, - ServerCmd, ServerArgsLocal, ServerArgsRemote, ServerVT and ServerTTY. - -2005-01-31 Oswald Buddenhagen - - * Added console mode that is suitable for systems with VTs (Linux). - Option ConsoleTTYs. The @tty spec in Xservers is irrelevant on - those systems now. - -2005-01-23 Oswald Buddenhagen - - * Added Grub support to boot options. Option UseLilo replaced - with BootManager { None, Grub, Lilo }. Removed options LiloCmd - and LiloMap. - -2005-01-09 Oswald Buddenhagen - - * Merged sessreg into tdm. Option UseSessReg. - -2004-08-14 Oswald Buddenhagen - - * Replaced dysfunct InteractiveSd with working - ScheduledSd { Never, Optional, Always } - -2004-07-28 Oswald Buddenhagen - - * Added control sockets. Control FiFos are now obsolete. - Added control socket command line client 'tdmctl'. - * The Setup program is now run even for automatic logins. - Setup, Startup and Reset have the arg "auto" for automatic logins. - -2004-07-23 Oswald Buddenhagen - - * Dynamic VT allocation added; option ServerVTs; no need to specify - vtX in Xservers any more. - -2004-07-10 Oswald Buddenhagen - - * GreeterPosX, GreeterPosY and GreeterPosFixed replaced with - single GreeterPos which is a pair of relative coordinates - -2004-07-01 Oswald Buddenhagen - - * The greeter can now run a "session preloader"; option Preloader - -2004-04-15 Oswald Buddenhagen - - * Merge from XDM: - - IPv6 support - - LISTEN keyword in Xaccess - - Changes to Enable and Port in [Xdmcp] now take effect when HUPed - - Support for EGD/PRNGD; options PrngdPort and PrngdSocket - -2004-04-14 Oswald Buddenhagen - - * -debug now groks additional bits for stracing and valgrinding - helper processes and disabling syslog usage. - -2004-04-09 Oswald Buddenhagen - - * NoPassUsers now accepts an asterisk ("*") meaning all users - -2004-04-08 Oswald Buddenhagen - - * Changes to FifoDir and FifoGroup now take effect on the global - command FiFo when HUPed. - -2004-03-16 Oswald Buddenhagen - - * Changed AllowClose default to true; only the default tdmrc - disables it for local display now. - -2004-03-11 Chris Cheney - - * Sanitized UserPath and SystemPath defaults. - -2004-03-07 Oswald Buddenhagen - - * Add user name autocompletion to greeter; option UserCompletion. - As a side effect, "None" is gone from ShowUsers and UserList - appeared; ShowUsers & SortUsers affect both the user list and - the completion list. - -2004-02-28 Oswald Buddenhagen - - * The default Xsession no longer tries to merge tdm's PATH into the - one set up by the shell startup scripts. Instead, kde.desktop - contains a full pathname and starttde fixes up PATH if necessary. - * The default Xsession will emulate the startup behaviour of more - shells, in particular bash, zsh and csh/tcsh. - * Setting up the session log is now done by tdm, not the Session - script; option ClientLogFile. - -2004-01-25 Oswald Buddenhagen - - * Add support for specifying groups in SelectedUsers, HiddenUsers and - NoPassUsers. Prefix group names with a @. - -2003-12-17 Oswald Buddenhagen - - * XDMCP initiated local displays are now treated as remote displays - (on localhost) by the config reader. - -2003-11-09 Oswald Buddenhagen - - * Sanitized display restart behaviour; option StartInterval is gone. - -2003-11-04 Oswald Buddenhagen - - * Conversation plugins can be configured now; option PluginOptions. - * The "Restart X Server"/"Close Connection" action can be configured - away; option AllowClose. - * The "Console Login" action can be configured away without touching - Xservers; option AllowConsole. - -2003-10-27 Oswald Buddenhagen - - * TDM now complies with the input model of PAM. The greeter has an - interface for conversation plugins, so alternative authentication - mechanisms can be handled; options PluginsLogin & PluginsShutdown. - * Password-less and automatic logins now use a separate PAM service - (${TDM_PAM_SERVICE}-np). - -2003-10-17 Oswald Buddenhagen - - * Add --with-tdm-xconsole configure switch. No need to patch - Makefile.am to enable the built-in xconsole anymore. - -2003-09-23 Oswald Buddenhagen - - * Session types are now defined with .desktop files; consequently the - SessionTypes option is gone and we got SessionsDirs instead. - * The default Xsession now hard-wires the session types - - "default" to starttde - - "custom" to ~/.xsession - * The previous session type choice is now saved in a different file - (~/.dmrc) in a different format (ini-file); the SessSaveFile option - is gone. Optionally TDM can be configured to store all .dmrc files - in a common directory (option DmrcDir); this can be useful for AFS - based installations. - * The location of the administratively set user faces is now specified - by the FaceDir option and the pictures have a .face.icon extension - (or .face for "natural" images, possibly photos). - - The spec for the above changes is shared with GDM, so packagers should - choose common directories. - - * The tdmsts file moved to /var/lib/tdm by default; option DataDir. - * Nuked the AutoLoginSession option; i don't think it was useful at all - and it can be emulated anyway. - -2003-09-03 Oswald Buddenhagen - - * Add option RandomDevice to override the OS specific default - entropy source. - -2003-08-26 Oswald Buddenhagen - - * Add random seed to forged "previous" session type calculation; - option ForgingSeed. - -2003-07-15 Malte Starostik - - * ColorScheme is now interpreted as the base name of the .kcsrc file, - not the contents of its Name field. - -2003-05-11 Oswald Buddenhagen - - * GUIStyle & ColorScheme now accept an empty string, meaning - "built-in default". Made defaults empty, consequently. - -2002-12-01 Oswald Buddenhagen - - * Integrated chooser into greeter; external 'chooser' executable - and the Chooser option are gone. - * The chooser can be started locally (without an XDMCP query); - options LoginMode and ChooserHosts. - * Added built-in xconsole to greeter; options ShowLog and LogSource. - This code is not built by default; uncomment the first three lines - in kfrontend/Makefile.am to enable it. - * The DaemonMode option is gone. The command line switches -daemon and - -nodaemon still exist, but are mostly unnecessary, as TDM can decide - what to do based on the parent process ID. - * The AutoLogin option and the -autolog/-noautolog switches are gone. - * The AutoLogin1st option is gone. - * The position of the -debug and -logfile command line options is - irrelevant again. The -xrm option is back, but is ignored by the - KDE frontend. - -2002-08-28 Oswald Buddenhagen - - * Made it possible to specify the color scheme for the greeter; - option ColorScheme - -2002-08-10 Oswald Buddenhagen - - * Renamed tdmdesktop to krootimage, moved it back into the TDM source - tree, and changed its command line - * krootimage will be automatically invoked by the greeter by default; - option UseBackground - * Chucked out the [Desktop0] section from tdmrc. Instead, the - location of the config file containing such a section is specified - with the BackgroundRc option. - * User images can now be optionally fetched from the users's home - directories; option FaceSource - * The default of the KeyFile option is now empty again - * GreeterScreen now groks -2, meaning upper-right screen - -2002-08-06 Oswald Buddenhagen - - * Automatically don't daemonize if started by init. - -2002-03-19 Oswald Buddenhagen - - * The default Xsession will emulate the startup behaviour of sh/ksh - by sourcing /etc/profile and ~/.profile. - -2002-03-10 Oswald Buddenhagen - - * Added InteractiveSd option. This is not really implemented yet, - so enabling it just makes TDM deny the existence of the shutdown - condition/timing options. - * The Setup script is now executed synchronously. Long-lasting - commands should be put in the background explicitly. - -2002-02-28 George Staikos - - * GreeterScreen now groks -1, meaning upper-left screen. - -2002-01-14 Oswald Buddenhagen - - * Added option NumLock {On,Off,Keep} to preset the NumLock modifier - state for the greeter - -2001-12-11 Oswald Buddenhagen - - * Added AntiAliasing option to disable antialiasing in the greeter - -2001-11-30 Oswald Buddenhagen - - * Added GreeterScreen option to put the greeter on a particular - screen in multi-headed setups. - * Changed the default of Language from "C" to "en_US" - -2001-11-22 Oswald Buddenhagen - - * The defaults of the options Xservers, Session, Setup, Startup, - Reset and PidFile are now back to the saner XDM defaults, - so TDM works even without config files. - * Changed option ShowUsers: All -> NotHidden - * Renamed the option Users to SelectedUsers and NoUsers to HiddenUsers. - * The GUIStyle option now groks all installed widget styles. - Note that Motif+ and KDE are now called MotifPlus resp. Default. - -2001-11-02 Oswald Buddenhagen - - * Added conditional/scheduled shutdown modes; options - DefaultSdMode and AllowSdForceNow; moved AllowShutdown from - [X--Greeter] to [X--Core]. - * Added reserve display support; extension to Xservers. - * Added command FiFo support (see README); options FifoDir, - FifoGroup, [ShutDown]/AllowFifo, and [ShutDown]/AllowFifoNow. - FiFo location and capabilities are exported in $XDM_MANAGED. - -2001-10-04 Oswald Buddenhagen - - * Xauth files are now created in AuthDir, not AuthDir/authdir. - Changed AuthDir default to /var/run/xauth. - -2001-07-12 Oswald Buddenhagen - - * Renamed the option Xwilling to Willing - * The RandomFile option is not recognized on Linux and OpenBSD any - longer, as they have better entropy sources - -2001-07-10 Oswald Buddenhagen - - * Added the tool 'gentdmconf'. It's supposed to create a suitable - configuration for TDM during 'make install' by merging new defaults - with a previous XDM/TDM config (if any is found). - -2001-07-03 Oswald Buddenhagen - - * Added counterpart to the MinShowUID option: MaxShowUID - -2001-06-23 Oswald Buddenhagen - - * Xauth files are now created in AuthDir/authfiles, not - AuthDir/authdir/authfiles - -2001-06-16 Oswald Buddenhagen - - * Optionally put the cursor right in the "Password" field when - a user is preselected in the "Login" field; option FocusPasswd - -2001-06-15 Oswald Buddenhagen - - * Replaced the ShutdownButton + ShutdownNeedsRoot option pair with - the AllowShutdown {None,Root,All} option - -2001-06-10 Oswald Buddenhagen - - * The source directory structure changed entirely - * The argument to the -debug command line option is now a bit field; - the DebugLevel resource is gone - * The ErrorLogFile resource is gone - * The greeter module libKdmGreet.so has been converted to an - executable named tdm_greet; the external config parser is now - named tdm_config. The resource GreeterLib and the command line - option -getcfg (and -cfg2get) are gone, as the locations of the - config parser and greeter are derived from the location of the - tdm executable - * The config files are all located in ${kde_confdir}/tdm now; the - defaults for Setup & Session were adapted to this. - * The keys in tdmrc were reorganized: - - [TDM]/ShutdownButton -> [X--Greeter]/(ShutdownButton & - ShutdownNeedsRoot) - - [TDM]/Shutdown -> [Shutdown]/HaltCmd - - [TDM]/Restart -> [Shutdown]/RebootCmd - - [TDM]/LogoArea -> [X-*-Greeter]/ {None,Logo,Clock} - - remaining keys from [TDM] -> [X-*-Greeter]/ - - [Lilo]/Lilo -> [Shutdown]/UseLilo - - [Lilo]/LiloCommand -> [Shutdown]/LiloCmd - - [Lilo]/LiloMap -> [Shutdown]/ - - [Locale]/Language -> [X-*-Greeter]/ (Country key dropped) - * TDM will no longer use tdm-config; most of its resources were - absorbed into tdmrc: - - Servers -> [General]/Xservers - - RequestPort -> [Xdmcp]/(Port & Enable) - - DaemonMode -> [General]/ - - PidFile -> [General]/ - - LockPidFile -> [General]/ - - AuthDir -> [General]/ - - AutoRescan -> [General]/ - - RemoveDomainname -> [Xdmcp]/ - - KeyFile -> [Xdmcp]/ - - AccessFile -> [Xdmcp]/Xaccess/ - - ExportList -> [General]/ - - RandomFile -> [General]/ - - ChoiceTimeout -> [Xdmcp]/ - - SourceAddress -> [Xdmcp]/ - - Willing -> [Xdmcp]/Xwilling - - AutoLogin -> [General]/ - - GrabServer -> [X--Greeter]/ - - GrabTimeout -> [X--Greeter]/ - - AuthComplain -> [X--Greeter]/ - - AuthName -> [X--Core]/AuthNames - - NoPassUsers -> [X--Core]/ & [X--Core]/NoPassEnable - - AutoUser -> [X--Core]/(AutoLoginUser & AutoLoginEnable) - - AutoPass -> [X--Core]/AutoLoginPass - - AutoString -> [X--Core]/AutoLoginSession - - remaining server & session resources -> [X--Core]/ - * In GreetString the HOSTNAME substitution was replaced with the - %%, %d, %h, %n, %s, %r & %m expandos - * EchoMode does not understand "NoStars" any more. Use "NoEcho". - * Defaults changed: AuthDir to /var/lib/tdm, KeyFile to - $tdm_confdir/tdmkeys, Xservers to $tdm_confdir/Xservers, Xaccess to - $tdm_confdir/Xaccess, Startup to $tdm_confdir/Xstartup, Reset to - $tdm_confdir/Xreset, removed kde2 from SessionTypes - * The previous user is now saved in $tdm_confdir/tdmsts, not tdmrc - * Added option SessSaveFile, defaulting to .wmrc - * Command line option changes: - - -server, -udpPort, -resources, -session and -xrm are gone - - -error is aliased to -logfile - - -debug and -error/-logfile must be specified first - - options are now accepted with both one and two leading dashes - * The default Xsession will now - - source ~/.xprofile if present - - try harder to determine what executable $1 corresponds to - - interpret "default" as ~/.xsession - -2001-03-19 Oswald Buddenhagen - - * %DMNAME% and %DMPATH% are expanded in string resources; - changed the defaults for PidFile and ConfigFile accordingly - - the latter resulting in TDM now using tdm-config, NOT xdm-config - * Use external config parser to merge platform-specific (that is, - KDE-like) configuration data into the XDM resources; command line - options -getcfg (default %DMPATH%_getcfg) and -cfg2get (no default, - meaning tdm_getcfg will use $kde_confdir/tdmrc). - * Changed "kde" to "kde2" in the default SessionTypes - * Stolen idea for console mode handling from dtlogin; options - ConsoleMode and AllowConsoleMode are gone; extension to Xservers - -2001-01-19 Oswald Buddenhagen - - * Added resources AllowRootLogin and AllowNullPasswd - -2001-01-15 Oswald Buddenhagen - - * Renamed UserIDLow option to MinShowUID - * The LogoArea option now accepts the value "None" - -2001-01-13 Oswald Buddenhagen - - * The GUIStyle option now works again and groks all of Qt's - built-in widget styles and the "KDE" style - -2001-01-11 Oswald Buddenhagen - - * Added placing of the greeter at fixed coordinates; options - GreeterPosFixed, GreeterPosX, and GreeterPosY. - * Added "default" to the default SessionTypes - -2000-01-06 Oswald Buddenhagen - - * Added option AllowConsoleMode - -2000-12-09 Oswald Buddenhagen - - * Added auto-login; options AutoLoginEnable, AutoLoginUser & - AutoLogin1st; resources AutoUser, AutoPass, AutoString & AutoLogin1st - * Added password-less login; options NoPassEnable & NoPassUsers; - resource NoPassUsers - * Added auto-re-login on XServer crash; resource & option AutoReLogin - - The tdmrc options and xdm-config resources are "ORed", i.e., if - either is enabled, the function is enabled. - The command line options -autolog/-noautolog and the resource AutoLogin - can be used to disable auto-login and password-less login at once. - - * Added displaying the previously logged in user in the "Login" - field; option ShowPrevious. The previous user is saved in tdmrc, - section [Previous]. - -2000-12-07 Oswald Buddenhagen - - * New XDM port from XFree86 4.0.1 - - new resources SourceAddress & Willing - - /authdir/authfiles is now automatically appended to AuthDir - * Default for PidFile and Setup changed back to empty - * Displays restarting too fast are disabled; resource StartInterval - * Option UserView, and NoUsers dependency on Users being empty - replaced with explicit option ShowUsers {All,Selected,None} - * Made the greeter dynamically loadable (libKdmGreet.so) - * Moved chooser and greeter to separate directories, - same for unused stuff (misc/) - - * Added half-baked support for command FiFos; resources - FifoCreate, FifoGroup, FifoMode. Replaced on 2001-11-02 - -2000-10-10 Steffen Hansen - - * Made tdmdesktop read the [Desktop0] section from tdmrc instead - of tdmdesktoprc. - -2000-09-07 Waldo Bastian - - * Make password echo mode configurable; - option EchoMode {OneStar,ThreeStars,NoEcho} - -2000-08-07 Christopher Molnar - - * The minimal user ID to show in the user view can be specified now; - option UserIDLow. - -2000-06-04 Espen Sand - - * The logo area can now display either a clock or a pixmap; - option LogoArea {KdmClock,KdmLogo} - -1999-12-12 Jaromir Dolecek - - * Use OS-specific defaults for Shutdown & Restart - * Make PidFile, UserPath & SystemPath defaults on NetBSD match FreeBSD - -1999-11-17 Harald Hoyer - - * Made kchooser - -1999-11-15 Matthias Hoelzer-Kluepfel - - * tdmdesktop replaced with ../kdesktop/tdmdesktop. Uses new config - file (tdmdesktoprc) with new options (all in section [Desktop0]): - -1999-07-01 Steffen Hansen - - * Xaccess now accepts NOBROADCAST - -1999-06-07 Matthias Hoelzer-Kluepfel - - * Added next boot OS selection via LiLo; options [Lilo] Lilo, - LiloCommand & LiloMap - * Added button to switch to console mode; option [TDM] ConsoleMode - -1999-03-01 Stephan Kulow - - * Option GUIStyle temporarily removed - -1998-10-08 Thomas Tanghus - - * [TDMDESKTOP] option changes: - - BackgroundPictureTile, BackgroundPictureCenter, FancyBackground -> - BackgroundPictureMode {None,Tile,Center,Scale, - TopLeft,TopRight,BottomLeft,BottomRight,Fancy} - - add BackGroundColorMode {Plain,Horizontal,Vertical} - - BackgroundColor -> BackGroundColor1, BackGroundColor2 - -1998-09-20 Hans Petter Bieker - - * Change defaults: - - Setup: "" -> XDMDIR/Xsetup - - PidFile: "" -> FreeBSD: /var/run/tdm.pid, others: XDMDIR/tdm-pid - - Session: "XBINDIR/xterm -ls" -> XDMDIR/Xsession - - UserPath & SystemPath: no /usr/ucb for Linux & FreeBSD - -1998-09-11 Hans Petter Bieker - - * Replace hard-coded paths with XBINDIR/XDMDIR in various defaults - -1998-09-06 Hans Petter Bieker - - * Default Xsession now searches $1 in PATH and execs it - -1998-03-26 Stephan Kulow - - * Nuke -tdedir cmdline option and Kdedir resource - -1997-09-09 Steffen Hansen - - * Change defaults: - - AuthDir: XDMDIR/authDir -> XDMDIR/authdir - -1997-09-04 kdecvs - - * Change defaults: - - AuthDir: XDMDIR -> XDMDIR/authDir diff --git a/kdm/ConfigureChecks.cmake b/kdm/ConfigureChecks.cmake deleted file mode 100644 index ae7ea8b6c..000000000 --- a/kdm/ConfigureChecks.cmake +++ /dev/null @@ -1,139 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -find_library( UTIL_LIBRARY util ) - -check_function_exists( getdomainname HAVE_GETDOMAINNAME ) -check_function_exists( initgroups HAVE_INITGROUPS ) -check_function_exists( mkstemp HAVE_MKSTEMP ) -check_function_exists( setproctitle HAVE_SETPROCTITLE ) -check_function_exists( sysinfo HAVE_SYSINFO ) -check_function_exists( strnlen HAVE_STRNLEN ) -check_function_exists( getifaddrs HAVE_GETIFADDRS ) - -tde_save( CMAKE_REQUIRED_LIBRARIES ) -set( CMAKE_REQUIRED_LIBRARIES ${UTIL_LIBRARY} ) -check_function_exists( setusercontext HAVE_SETUSERCONTEXT ) -check_function_exists( getusershell HAVE_GETUSERSHELL ) -check_function_exists( login_getclass HAVE_LOGIN_GETCLASS ) -check_function_exists( auth_timeok HAVE_AUTH_TIMEOK ) -tde_restore( CMAKE_REQUIRED_LIBRARIES ) - -check_function_exists( crypt LIBC_HAVE_CRYPT ) -if( LIBC_HAVE_CRYPT ) - set( HAVE_CRYPT 1 CACHE INTERNAL "" FORCE ) -else( ) - check_library_exists( crypt crypt "" HAVE_CRYPT ) - if( HAVE_CRYPT ) - set( CRYPT_LIBRARY crypt ) - endif( ) -endif( ) - -check_include_file( lastlog.h HAVE_LASTLOG_H ) -check_include_file( termio.h HAVE_TERMIO_H ) - -check_struct_has_member( "struct sockaddr_in" "sin_len" "sys/socket.h;netinet/in.h" HAVE_STRUCT_SOCKADDR_IN_SIN_LEN ) -check_struct_has_member( "struct passwd" "pw_expire" "pwd.h" HAVE_STRUCT_PASSWD_PW_EXPIRE ) -check_struct_has_member( "struct utmp" "ut_user" "utmp.h" HAVE_STRUCT_UTMP_UT_USER ) - -check_c_source_runs( " - #include - #include - int main() - { - setlogin(0); - return errno == ENOSYS; - } -" HAVE_SETLOGIN ) - -check_c_source_runs( " - #include - #include - #include - #include - #include - #include - #include - int main() - { - int fd, fd2; - struct sockaddr_un sa; - - if((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) - return 2; - sa.sun_family = AF_UNIX; - strcpy(sa.sun_path, \"testsock\"); - unlink(sa.sun_path); - if(bind(fd, (struct sockaddr *)&sa, sizeof(sa))) - return 2; - chmod(sa.sun_path, 0); - setuid(getuid() + 1000); - if((fd2 = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) - return 2; - connect(fd2, (struct sockaddr *)&sa, sizeof(sa)); - return errno != EACCES; - } -" HONORS_SOCKET_PERMS ) - -if( CMAKE_SYSTEM_NAME MATCHES Linux OR CMAKE_SYSTEM_NAME MATCHES Darwin OR CMAKE_SYSTEM_NAME MATCHES GNU/FreeBSD ) - unset( HAVE_UTMPX ) - unset( HAVE_LASTLOGX ) -else( ) - check_function_exists( getutxent HAVE_UTMPX ) - check_function_exists( updlastlogx HAVE_LASTLOGX ) -endif( ) - -unset( BSD_UTMP ) -if( NOT HAVE_UTMPX ) - check_function_exists( getutent have_getutent ) - if( NOT have_getutent ) - set( BSD_UTMP 1 ) - endif( ) -endif( ) - -check_function_exists( arc4random HAVE_ARC4RANDOM ) -if( NOT HAVE_ARC4RANDOM ) - # assume that /dev/random is non-blocking if /dev/urandom does not exist - if( EXISTS /dev/urandom ) - set( DEV_RANDOM "/dev/urandom" CACHE INTERNAL "" FORCE ) - elseif( EXISTS /dev/random ) - set( DEV_RANDOM "/dev/random" CACHE INTERNAL "" FORCE ) - endif( ) -endif (NOT HAVE_ARC4RANDOM) - -# Xau -pkg_search_module( XAU xau ) -if( NOT XAU_FOUND ) - tde_message_fatal( "Xau are required, but not found on your system" ) -endif() - - -# xdmcp -if( WITH_XDMCP ) - pkg_search_module( XDMCP xdmcp ) - if( XDMCP_FOUND ) - set( XDMCP 1 CACHE INTERNAL "" FORCE ) - else() - tde_message_fatal( "xdmcp is requested, but was not found on your system" ) - endif() -endif() - - -if( WITH_PAM ) - - set( USE_PAM 1 CACHE INTERNAL "" FORCE ) - -elseif( WITH_SHADOW ) - - set( HAVE_SHADOW 1 CACHE INTERNAL "" FORCE ) - set( USESHADOW 1 CACHE INTERNAL "" FORCE ) - -endif( ) diff --git a/kdm/Makefile.am b/kdm/Makefile.am deleted file mode 100644 index 0f038d4a7..000000000 --- a/kdm/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -SUBDIRS = . backend kfrontend - -PAM = @TDM_PAM_SERVICE@ - -noinst_DATA=config.ci - -tdmdocdir = $(datadir)/doc/tdm -tdmdoc_DATA = README - -install-data-local: - -@test -n "$(DESTDIR)" || test -z "$(PAM)" || { $(top_srcdir)/mkpamserv $(PAM) && $(top_srcdir)/mkpamserv -P $(PAM)-np; } - -config.ci: $(srcdir)/config.def $(srcdir)/confproc.pl - $(PERL) -w $(srcdir)/confproc.pl $(srcdir)/config.def $@ - -CLEANFILES = config.ci - -### this is *only* for the tdm home page maintainer! ### -hp: - scp README ChangeLog TODO devel-home:files/tdm diff --git a/kdm/README b/kdm/README deleted file mode 100644 index 6c0fce18b..000000000 --- a/kdm/README +++ /dev/null @@ -1,454 +0,0 @@ -This is the K Display Manager (TDM) for KDE 3.4, -the KDE replacement for the X Display Manager (XDM). - -Semi-official home page: http://devel-home.kde.org/~ossi/sw/tdm.html - - -configure options that affect TDM ---------------------------------- - ---with-pam[=service] - Compile TDM (and other parts of tdebase) with PAM support. The default - service is "kde". PAM is automatically used if found. - ---with-tdm-pam=service - Override the PAM service used specifically by TDM. Depends on --with-pam. - ---with-shadow - Compile TDM (and other parts of tdebase) with shadow password support. - Shadow passwords are automatically used if found. This affects TDM only - if PAM is not used. - ---with-krb4[=path] - Compile TDM (and the LDAP KIO slave) with KTH Kerberos 4 support. Note - that this does not work with the Kerberos 4 compatibility layer found in - MIT Kerberos 5. This affects TDM only if PAM is not used. - ---with-afs - Compile TDM with AFS support. Depends on --with-krb4. - ---with-krb5auth[=path] ---with-rpcauth - Compile TDM with Kerberos 5 resp. secure RPC support for X authorization - cookies. It's pretty pointless to enable this if you don't use an X server - that supports it. - - If you want user authentication against a Kerberos realm, compile TDM with - PAM support and use the appropriate module. - ---without-xdmcp - Compile TDM without XDMCP support. - ---with-tdm-xconsole - Compile TDM with a builtin "xconsole" replacement in the greeter. I don't - consider this too useful, but SuSE wanted it, so it's there. ;) - - -TDM's file system layout ------------------------- - -${kde_confdir} is usually ${prefix}/share/config -${kde_datadir} is usually ${prefix}/share/apps -The indented locations are envisioned for a configuration shared with GDM. - -${kde_confdir}/tdm/{tdmrc,Xservers,Xaccess,Xwilling,...} -${kde_datadir}/tdm/sessions/*.desktop - /etc/X11/sessions/,/usr/share/xsessions/ -${kde_datadir}/tdm/pics/users/ -${kde_datadir}/tdm/pics/ -${kde_datadir}/tdm/faces/*.face{,.icon} - /usr/share/faces/ -/var/run/xauth/A* -/var/run/xdmctl/xdmctl* -/var/run/tdm.pid -/var/lib/tdm/tdmsts -/*.dmrc -$HOME/.face{,.icon} -$HOME/.dmrc - - -How to setup TDM ----------------- - -TDM's config files are all located in ${kde_confdir}/tdm. -"make install" will create a probably working configuration, either by -deriving it from an already present TDM/XDM installation or by using -defaults if no previous installation is found. - -You can change the configuration from the KDE Control Center. You will -find the "Login Manager" module in the "System Administration" group. - -Have a look at README.pam in the tdebase top level directory if your -system uses PAM. - - -Configuring session types -------------------------- - -The way session types are configured changed drastically in KDE 3.2. -Session types are now represented by .desktop files in appropriate locations. -The format of the .desktop files is (not yet) defined in the FreeDesktop.org -desktop entry spec. Differences to "standard" .desktop files are: -- the Type is fixed to XSession and can be omitted -- the Encoding is fixed to UTF-8 and can be omitted -- the Exec field will be passed to "eval exec" in a bourne shell; no macro - expansion is performed on it. "default", "custom" and "failsafe" are magic - constants that cause special actions. -- Name, Comment, TryExec and Hidden are supported -- the remaining keys have no meaning currently -Session types are internally identified by filename (without extension); -that's what will be saved to ~/.dmrc and what DESKTOP_SESSION will be set to. -For every magic Exec constant a session type of the same name exists. - -Unless your system is configured differently already, you should create a -directory ${kde_confdir}/tdm/sessions and add this to tdmrc: - -[X-*-Core] -SessionsDirs=${kde_confdir}/tdm/sessions,${kde_datadir}/tdm/sessions - -(Note that you must use actual paths instead of variables, see the section -about TDM's file system layout.) -Do any changes only in the config directory - any changes in the data -directory will be lost after the next KDE update. - -To override a session type, copy the .desktop file from the data dir to the -config dir and edit it at will. Removing the shipped session types can be -accomplished by "shadowing" them with .desktop files containing Hidden=true. -For the magic session types no .desktop files exist by default, but TDM -pretends they would, so you can override them like any other type. -I guess you already know how to add a new session type by now. ;-) - - -Running TDM from init ---------------------- - -NOTE, that this description applies to RedHat 5.x and must be adapted for -other distributions/systems. Generally I'd advise _against_ starting TDM -directly from init - better use a proper init script, possibly by slightly -modifying the XDM init script shipped by your distribution. - - Edit (as root) /etc/inittab. - - Look for the line: - - x:5:respawn:/usr/X11/bin/xdm -nodaemon - - Replace it with: - - x:5:respawn:/opt/kde/bin/tdm - - This tells init(8) to respawn TDM, the KDE display manager, when - the system is in run level 5. - Note that TDM does not need the -nodaemon option. - - To start TDM, either run (as root) /sbin/telinit 5 (to switch to - run level 5), or (this is risky! don't do it until you _know_ you - want the system to boot into this every time!) edit /etc/inittab - and change the line: - - id:3:initdefault: - - to - - id:5:initdefault: - - If you do the latter step, then every time your system boots - successfully it will go into run level 5 and run TDM, - presenting you the exceedingly cute KDE login screen. - - -The command sockets -------------------- - -This is a feature you can use to remote-control TDM. It's mostly intended -for use by ksmserver and kdesktop from a running session, but other -applications are possible as well. - -The sockets are UNIX domain sockets which live in subdirectories of the -directory specified by FifoDir=. The subdir is the key to addressing and -security; the sockets all have the file name "socket" and file permissions -rw-rw-rw- (0666). This is because some systems don't care for the file -permissions of the socket files. -There are two types of sockets: the global one (dmctl) and the per-display -ones (dmctl-). -The global one's subdir is owned by root, the subdirs of the per-display -ones' are owned by the user currently owning the session (root or the -logged in user). Group ownership of the subdirs can be set via FifoGroup=, -otherwise it's root. The file permissions of the subdirs are rwxr-x--- (0750). - -The fields of a command are separated by tabs (\t), the fields of a list -are separated by spaces, literal spaces in list fields are denoted by "\s". -The command is terminated by a newline (\n). -The same applies to replies. The reply on success is "ok", possibly followed -by the requested information. The reply on error is an errno-style word (e.g., -"perm", "noent", etc.) followed by a longer explanation. - -Global commands: - -"login" display ("now"|"schedule") user password [session_arguments] - - login user at specified display. if "now" is specified, a possibly - running session is killed, otherwise the login is done after the - session exits. - session_arguments are printf-like escaped contents for .dmrc. Unlisted - keys will default to previously saved values. - -Per-display commands: - -"lock" - - The display is marked as locked. If the X-Server crashes in this state, - no auto-relogin will be performed even if the option is on. - -"unlock" - - Reverse the effect of "lock": re-enable auto-relogin. - -"suicide" - - The currently running session is forcibly terminated. No auto-relogin is - attempted, but a scheduled "login" command will be executed. - -Commands for all sockets: - -"caps" - - Returns a list this socket's capabilities: - "tdm" - identifies tdm, in case some other DM implements this protocol, too. - "list", "activate", "lock", "suicide", "login" - the respective command - is supported. - "bootoptions" - the "listbootoptions" command and the "=" option to - "shutdown" are supported. - "shutdown " - "shutdown" is supported and allowed to the listed users - (comma-separated). "*" means all authenticated users. - "shutdown" - "shutdown" is supported and allowed to everybody. - "nuke " - forced shutdown is allowed to the listed users. - "nuke" - forced shutdown is allowed to everybody. - "reserve " - reserve displays are configured and are - available at this time. - -"list" ["all"|"alllocal"] - - Return a list of running sessions. By default all active sessions are - listed. If "all" is specified, passive sessions are listed as well. If - "alllocal" is specified, passive sessions are listed as well, but all - incoming remote sessions are skipped. - Each session entry is a comma-separated tuple of: - - Display or TTY name - - VT name for local sessions - - Logged in user's name, empty for passive sessions and outgoing remote - sessions (local chooser mode) - - Session type or remote host for outgoing remote sessions, empty for - passive sessions - - A flag field: - - "t" for tty sessions - - "*" for the display belonging to the requesting socket - - "!" for sessions that cannot be killed by the requesting socket - - New flags might be added later - - New fields might be added later - -"reserve" [timeout in seconds] - - Start a reserve login screen. If nobody logs in within the specified amount - of time (one minute by default), the display is removed again. When the - session on the display exits, the display is removed, too. - - Permitted only on sockets of local displays and the global socket. - -"activate" (vt|display) - - Switch to a particular VT (virtual terminal). The VT may be specified - either directly (e.g., vt3) or by a display using it (e.g., :2). - - Permitted only on sockets of local displays and the global socket. - -"listbootoptions" - - List available boot options. - => "ok" list default current - default and current are indices into the list and are -1 if unset or - undeterminable. - -"shutdown" ("reboot"|"halt") ["="bootchoice] \ - ("ask"|"trynow"|"forcenow"|"schedule"|\ - start ("-1"|end ("force"|"forcemy"|"cancel"))) - - Request a system shutdown, either a reboot or a halt/poweroff. - - An OS choice for the next boot may be specified from the list returned by - "listbootoptions". - - Shutdowns requested from per-display sockets are executed when the current - session on that display exits. Such a request may pop up a dialog asking - for confirmation and/or authentication. - - start is the time for which the shutdown is scheduled. If it starts with - a plus-sign, the current time is added. Zero means immediately. - - end is the latest time at which the shutdown should be performed if active - sessions are still running. If it starts with a plus-sign, the start time - is added. Minus one means wait infinitely. If end is through and active - sessions are still running, TDM can do one of the following: - * "cancel" - give up the shutdown. - * "force" - shut down nonetheless. - * "forcemy" - shut down nonetheless if all active sessions belong to the - requesting user. Only for per-display sockets. - - start and end are specified in seconds since the UNIX epoch. - - "trynow" is a synonym for "0 0 cancel", "forcenow" for "0 0 force" and - "schedule" for "0 -1". - - "ask" attempts an immediate shutdown and interacts with the user if active - sessions are still running. Only for per-display sockets. - -"shutdown" "cancel" ["local"|"global"] - - Cancel a scheduled shutdown. The global socket always cancels the currently - pending shutdown, while per-display sockets default to cancelling their - queued request. - -"shutdown" "status" - - Return a list with information about shutdowns. - The entries are comma-separated tuples of: - - ("global"|"local") - pending vs. queued shutdown. A local entry can be - returned only by a per-display socket. - - ("halt"|"reboot") - - start - - end - - ("ask"|"force"|"forcemy"|"cancel") - - Numeric user ID of the requesting user, -1 for the global socket. - - The next boot OS choice or "-" for none. - - New fields might be added later. - -There are two ways of using the sockets: -- Connecting them directly. FifoDir is exported as $DM_CONTROL; the name - of per-display sockets can be derived from $DISPLAY. -- By using the tdmctl command (e.g., from within a shell script). - Try "tdmctl -h" to find out more. - -Here is an example bash script "reboot into FreeBSD": - -if tdmctl | grep -q shutdown; then - IFS=$'\t' - set -- `tdmctl listbootoptions` - if [ "$1" = ok ]; then - fbsd=$(echo "$2" | tr ' ' '\n' | sed -ne 's,\\s, ,g;/freebsd/I{p;q}') - if [ -n "$fbsd" ]; then - tdmctl shutdown reboot "=$fbsd" ask > /dev/null - else - echo "FreeBSD boot unavailable." - fi - else - echo "Boot options unavailable." - fi -else - echo "Cannot reboot system." -fi - - -"It doesn't work!!" -------------------- - -More input! ;-) - -TDM accepts two command line options related to logging: - - -debug - is a decimal or hexadecimal (prefix 0x) number. - The number is a bitfield, i.e., it is formed by summing up the - required values from this table: - 1 (0x1) - core debugging. Probably the most useful one. - 2 (0x2) - config reader debugging. - 4 (0x4) - greeter debugging. - 8 (0x8) - IPC debugging. This logs _all_ communication between the - core, the config reader and the greeter - including the - passwords you type, so edit the log before showing it to - somebody. - This attempts to synchronize the processes to interleave the - log messages optimally, but will probably fail unless you use - -debug 0x80 as well. - 16 (0x10) - wait after forking session sub-daemon. - 32 (0x20) - wait after starting config reader. - 64 (0x40) - wait after starting greeter. - The wait options are only useful if you need to attach a debugger - to a process, but it crashes before you are able to do so without - the delay. See below. - 128 (0x80) - don't use syslog for internally generated messages. - 256 (0x100) - core Xauth debugging. - 1024 (0x400) - run config reader and greeter through valgrind. - 2048 (0x800) - run config reader and greeter through strace. - - Logs from "-debug 7" are usually a good start. - - -logfile - is the file to log various messages to. The default log file is - /var/log/tdm.log. For internal reasons there is no option in tdmrc to - permanently specify the log file location. If you redirect TDM's - standard error output to a file, TDM will log there. - If TDM is configured to use syslog (and it _very_ probably is on any - modern system), all internally generated messages are logged to the - "daemon" facility. The log usually can be found in /var/log/debug.log - and /var/log/daemon.log; make sure that daemon.* is logged (look at - /etc/syslog.conf). - If you have problems logging in and your system uses PAM (also quite - probable on modern systems), the "auth" and "authpriv" syslog facilities - are interesting, too. - -Send me all the logs together with a detailed description of what you did -and what happened. If your problem is related to a specific configuration, -you should also attach a tar.gz archive of your TDM config directory. - -If I request a backtrace from you and TDM didn't create one yet via the -usual drkonqi procedure, you'll have to do that yourself. The keyphrase -is "attaching gdb". How exactly this is done depends on the part that -crashes: -- master daemon. Actually you should never need to attach to it, as - you can start it within the debugger already: - # gdb --args tdm -nodaemon -debug 7 - (gdb) run -- display subdaemon. Find (using ps) the process with a name like - "-:0" (where :0 is actually the display this process is for). This - process' PPID is the master daemon. Attach to it this way: - # gdb tdm - (gdb) cont - If the subdaemon crashes before you can attach, add 16 to the debug flags - when you start TDM. -- config reader. You will have to add 32 to the debug flags almost certainly. - The PPID will be the master daemon as well. - # gdb tdm_config $(pidof tdm_config) - (gdb) cont -- greeter. If it's too fast, add 64 to -debug. The PPID will be the subdaemon. - # gdb tdm_greet $(pidof tdm_greet) - (gdb) cont - The simplification with "pidof" works only if you have only one display, - otherwise you have to find the PID manually (by using ps -fx). -Once you got gdb attached to the offending process, do whatever is needed -to make it crash (probably nothing, if you had to use a delay parameter). -Once it crashed, gdb will tell you a signal name, like SIGSEGV - that's the -first interesting part for me. Then you have to create the actual backtrace: - (gdb) bt -The output of this command is interesting for me. -I might request a backtrace even if nothing crashes, but instead hangs. In -this case don't use "cont" after attaching, but use "bt" right away. If the -process is already running, interrupt it with ctrl-c. -For obvious reasons you have to run gdb on a different virtual terminal than -the X server. To get there, press alt-ctrl-f1 and log in as root. To -switch to the X server's vt, press alt-ctrl-f7 (the exact function key may -be different on your system). You may also use a remote login from a -second machine. In any case it is advantageous to have mouse support on the -debugging console for copying the backtrace. -Note that a backtrace is usually _much_ more useful if the binary contains -debugging info, so you should install from source with the --enable-debug -configure flag if at all possible. - - -Random rambings and license information ---------------------------------------- - -Version 0.1 of TDM is copyright - Matthias Ettrich -All later versions copyright: - (C) 1997-2000 Steffen Hansen -Since version 0.90 (KDE 2.1) copyright: - (C) 2000-2003 Oswald Buddenhagen - -The files in the backend directory are licensed under the X licence -(see http://www.x.org/Downloads_terms.html for more info). -The files in the kfrontend directory are licensed under the GNU GPL. - -Thanks to (in no particular order): -Michael Bach Jensen and Torsten Rahn for drawing icons. -Duncan Haldane for investigation of PAM issues. -Stephan Kulow for helping with the autoconf stuff. -Martin Baehr for intensive testing and writing the sample Xsession scripts. -Harald Hoyer for the (now obsoleted) chooser. -SuSE for employing me (ossi) for three months to work on tdm. -BasysKom for sponsoring my (ossi's) work on the conversation plugin stuff. -... and _many_ others ... - - --- -Have fun with it (and feel free to comment), - - Oswald Buddenhagen diff --git a/kdm/TODO b/kdm/TODO deleted file mode 100644 index 75518b779..000000000 --- a/kdm/TODO +++ /dev/null @@ -1,243 +0,0 @@ -theming (#37349): -- maybe add a Themable plugin flag. if not set and no talker, abort. -- minor: show QWidgets only when the layout is ready and the theme was painted. - but one can't hide the widgets in a QLayout, as they have no size then. -- add attribute inheritance. apply attributes extracted from particular - elements of the (hidden) talker. -- make plugin return a QDom instead of embedding a QLayoutItem (QLabels look - just awful in the themed greeter). big problem: there is no KdmGrid ... try - to (ab)use QLayout. -- extract background from theme. use explicit node-id "background", i think. -- automatic talker node detection/creation. same for background, possibly. - -- remote login can have the chosen host as the sessName -- popup menu grabs keyboard. that means it is ungrabbed afterwards ... -- error label uses fixed colors. red might be ok, but not black. - -- message after switching to text mode - -- handle non-linux VTs: - on systems without VT_GETSTATE, try activating all consoles in turn to - find free ones. wow, this sucks so much. - - BSD: 1st: pcvt, /dev/ttyC[0] (OpenBSD), /dev/ttyv[0] (other), - also emulated by wscons on /dev/ttyE. - 2nd: syscons, /dev/ttyv[0], fallback /dev/vga - - Lynx, /dev/atc[0] - - Solaris, /dev/vt[00] - - SVR4, /dev/vc[00] (ESIX), /dev/vt[00] (other) - - SCO, /dev/tty[00], query current with CONS_GETINFO, counts 0-based - ref: xorg/programs/Xserver/hw/xfree86/os-support/xf86_OSlib.h -- act on BSD_INIT -- before nuking X server on other vt, save current vt and restore it before - disallocating server vt. or just make the xserver not switch wildly. - -- possibly parse Xserver log to find failure cause. this is very hacky. - -- try harder to get rid of processes, see X servers failure cleanup path - -- make auto-re-login a per-user option; save in .dmrc. - -- add Xserver option set selection (#56329) -- add support for XRandR (#48602) -save these options to .dmrc? - -- per-display sections in .dmrc. read-only, as far as tdm is concerned, as - otherwise the GUI would become insanely complex. - -- make config position independent -- parse /etc/kderc? -- merge multiple tdmrcs in the style of kconfig. how to set section priorities? -- gentdmconf: treat backgroundrc as an ini file, not as a text blob -- add proper quoting and dequoting to gentdmconf ini parser & writer - -- write generic conversation plugin -- write modern conv plugin. or maybe this should be a parallel vs. serial - setting of the classic plugin? - -- actually implement the libpam_client support - -- check if pam works before trying to authenticate -- test whether nis, kerberos4 & kerberos5 work -- sync BSD_AUTH from xdm, sync osfc2 from kcheckpass - -- swap pam_setcred and pam_open_session order. -- check how the system specific functions like setpcred (AIX) and - setusercontext (BSD) combine with pam_setcred. - -- Move clock from greeter dialog to desktop -- add more clock types (#18178) -- add icons to action menu. icon theme selection! - -- Add XDMCP _client_ to core (for remote login like in dtlogin). - Currently this is done by simply restarting the x-server with -query. - -- add login restrictions for reserve displays (#59353) - -- possibly do the authentication for the reserve display on the display it - is launched from (relates #59353) - -- remote-accessible command sockets for remote shutdown, etc. - or maybe implement it as an xdmcp extension? -- LoginMode=DirectQuery - -- "XDMCP over FiFo" - or at least a "manage []" command -- the per-display sockets are in fact nonsense; gdm's approach is better - -- add bgset to XDM_MANAGED - add FiFo command "background\t{inprogress,aborted,done}" - -- lilo boot option , i.e., -R with no argument -- support lilo -A mode - -- support sleep/suspend in the shutdown menu. should this be really treated - like a shutdown? (#33839) - -- add language selection (export as LC_*). kde should respect this until the - language is explicitly configured. and later? option "use system setting"? - integrate with $KDE_LANG somehow. (#55379, #63804) -- add keymap selection (via xkb) (#51245, #64642) -for both, one would preset a list of available options and make one entry -the greeter's own setting. explicitly setting it sets it for both the greeter -and the session. .dmrc later affects only the session, not the greeter. - -- handle failsafe internally, take care of focus. see #32973 - -- TryExec for "custom" session type. always show the entry, but disable it - if it is unavailable for the selected user. - -- cursor theming support via Xcursor (#66829) - -- add screensaver (#41941) -- support DPMS (#18597) - -- add a minimalistic window manager to the greeter (#17716, #51039) - -- write a separate configurator application, as kcontrol does not scale well - enough to cover all of tdm's options. - -- Different logos for each session type (see #74500) -- User pictures in logo field -- display user's .plan/.project (or .person? .userinfo?) in the greeter? - text area/label would suck -> tooltip? - -- allow disabling full names or login names in userview (#54110) -- user list loading in the background (after first few to get a reasonable - width estimate) - -- faking session parameters (type, language, etc.) of nonexistent users based - on statistical analysis of actual users ... severe overkill!? - -- export password to the startup/session scripts. somehow ... (#35396) - -- maybe reset CapsLock in the greeter. there is some CapsLock vs. ShiftLock - confusion, though. - -- maybe add kiosk mode: the user and his options are preset and locked in - the greeter. i doubt it's usefulness, though. - -- make builtin xconsole hideable; it should free the device when invisible. - possibly auto-hide it on vt switch - see kdesktop_lock for the x event - handling. - -- ssh-agent/gpg-agent integration (#44177, #65709) - -- lbxproxy integration (tell ghakko) - -- in kcm_tdm, detach backgroundrc change status from tdmrc change status. - -- when a shutdown is scheduled, don't remove all login possibilities. - instead, display a warning in the greeter. use SIGUSR1 to notify already - running greeters about changes. -- user notification about scheduled shutdown (and cancelled forced shutdown): - - wall - - greeter popup - - d-bus message. this would be best, particularly because screen savers - would need no special handling then. -- maybe bomb DefaultSdMode, save in state file instead. compare with ksmserver. - -- gdm changelog indicates that PAM sometimes - - continues despite PAM_CONV_ERR - - asks user name twice -- gdm avoids the PAM_MESSAGE message box vs. prompt problem by displaying - everything in one "error area". all messages are simply appended; an empty - message clears the area. -- gdm stops cursor blinking on not used (remote) displays after 20 secs to - save bandwidth. - -internal stuff: -- improve signal handling in the subdaemon, it's incredibly racy (GOpen/GClose). - depends on proper main loop. - alternative extreme measure: launch greeter from master daemon? -- the process reaping from GClose should be in sync with the main loop. -- kill warning on AIX - see bug #13628 (really present?) -- implement auto-re-login by keeping the display subdaemon alive instead - of starting a new one and feeding it the old auth data. -- options for running the greeter and the core unprivileged. problem: xauth. -- rethink the coupling of the tdm components, particularily the config reader. - options: - - keep things basically as-is, make the Xaccess interface even more flexible, - add capability flags. - - as previous, but don't use #defines, but textual constants. even more - flexible, but slower, bigger, no compile-time checking, and the typing - system would have to be more core-based. keys in the rc are considered - invalid if they were not queried. - - completely opposite: no explicit queries, but hard-code everything. that - kills the idea of having one backend binary for multiple frontends, but - that's a BlueSkyDream anyway. - following that path, the config reader could be nuked at all. - -ralf says: -- put the kmenu sidebar image on the left of the greeter -- enable the clock by default - -thoughts (not really todo): -- PAM sucks. big time. - historically, it is completely incapable of operating in event-driven contexts - when it comes to non-console authentication schemes. the module just hangs in - pam_sm_authenticate() (pam_authenticate() to the outside), waiting for input - from its device. - then came linux-pam 0.58, introducing PAM_BINARY_{MSG,PROMPT} to the - conversation function interface. no conversation function could handle the - binary prompts generically, of course. so came linux-pam 0.63 with a client - library that would add another layer of indirection, so the conversation - function could simply call into it and it would do whatever was configured - by the admin. and everbody was happy, right? wrong! i've yet to see a single - module (except for the demo module in linux-pam, of course) that actually - uses this feature. not to mention the non-existing portability (you don't - seriously expect TOG to extend the PAM standard within the next decade, do - you?). so we're right where we started from. - this imposes problems in two use cases: - - cancelling authentication alltogether. this happens when the user changes - the authentication method or when the greeter exits for some reason. if - the process waits in the conversation function, it can simply return - PAM_CONV_ABORT. if the module hangs, we're screwed. - - suspending authentication. this is needed for shutdowns that need auth. - if the module hangs, we're screwed, of course. if we're waiting in the - conversation function, we have three options: 1) just abort the auth - cycle and start a new one. this is what is done currently. 2) just open - a second pam handle and authenticate with it, all from within the "outer" - pam_authenticate(). if we're lucky, no involved modules use static variables - and things work out. 3) linux-pam 0.65 introduced the following: the - conversation function can return PAM_CONV_AGAIN. this in turn makes the - module and consequently libpam return PAM_INCOMPLETE, requesting the - application to call the resp. libpam function again. in theory this - guarantees that authentication with a second pam handle is safe. of course, - PAM_INCOMPLETE is just as popular and thus useful as PAM_BINARY_PROMPT. - we could just longjmp() out of hanging modules from a signal handler. - however, this might lead to resource leaks and even leave us with an unstable - libpam. killing the hanging process seems like the most viable solution. - however, for this we first need to make the greeter a child of the master - daemon. also, the display sub-daemon (which happens to do the main auth.) - is responsible for keeping the initial X connection open. killing it would - terminate the session according to the XDMCP spec. other issues are probable. -- multiple conv. plugins could be used in a row, each serving a pam module. - the plugins would have to detect that it's their turn by filtering messages - and prompts. -- consider making the menu an actions-only menu again and put an "options >>" - button somewhere. relates #63401, #61492 -- pipe .xsession-errors through the daemon and put a size limit on it. - remove old logs in disk-full situation. -- set LC_ALL in the backend for i18n-capable PAM libs - does one exist? - - -last sync with XFree86 HEAD: 2004-04-02 diff --git a/kdm/backend/CMakeLists.txt b/kdm/backend/CMakeLists.txt deleted file mode 100644 index cd98b3a9c..000000000 --- a/kdm/backend/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -# FIXME this is far from complete!!! - -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_BINARY_DIR} - ${DBUS_TQT_INCLUDE_DIRS} -) - -link_directories( - ${DBUS_TQT_LIBRARY_DIRS} -) - -##### tdm (executable) ########################## - -add_custom_command( OUTPUT config.ci - COMMAND perl -w ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def config.ci - DEPENDS ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def ) - -set_property( SOURCE auth.c APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/config.ci ) - -if( WITH_XDMCP ) - set( XDMCP_LIBRARIES "Xdmcp" ) -else() - set( XDMCP_LIBRARIES "" ) -endif() - -tde_add_executable( tdm - SOURCES - access.c auth.c bootman.c choose.c client.c consolekit.c - ctrl.c daemon.c dm.c dpylist.c error.c genauth.c - inifile.c krb5auth.c mitauth.c netaddr.c policy.c - process.c protodpy.c reset.c resource.c rpcauth.c - server.c session.c sessreg.c socket.c streams.c - util.c xdmauth.c xdmcp.c - LINK X11 ${XAU_LIBRARIES} ${DBUS_TQT_LIBRARIES} ${CRYPT_LIBRARY} ${PAM_LIBRARY} ${XDMCP_LIBRARIES} - DESTINATION ${BIN_INSTALL_DIR} -) diff --git a/kdm/backend/Imakefile b/kdm/backend/Imakefile deleted file mode 100644 index f3b4e0050..000000000 --- a/kdm/backend/Imakefile +++ /dev/null @@ -1,203 +0,0 @@ -/* well, we have no subdirs ... -#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' -*/ - -#ifdef DEBUG -CDEBUGFLAGS := $(CDEBUGFLAGS) -g -#endif - -#ifndef BuildBoth -#define BuildBoth (defined(LinuxArchitecture) && !UseElfFormat) -#endif - -#ifndef LinuxShadowSuite -#define LinuxShadowSuite NO -#endif - -#if FSUseSyslog -LOG_DEFINES = -DUSE_SYSLOG -#endif - -#ifdef NoXDMCP -XDMCPLIB = -#else -XDMCP_DEFINES = -DXDMCP -#endif - -#if HasXdmAuth -XDMAUTH_DEFINES = -DHASXDMAUTH -XDMAUTHOBJS = xdmauth.o -XDMAUTHSRCS = xdmauth.c -#endif - -#if HasSecureRPC -RPC_DEFINES = -DSECURE_RPC -RPCOBJS = rpcauth.o -RPCSRCS = rpcauth.c -RPCLIB = -lrpcsvc -#endif - -#if HasKrbIV -#if NOAFS -KRBIV_DEFINES = KrbIVDefines -DNO_AFS -#else -KRBIV_DEFINES = KrbIVDefines -#endif -KRBIV_INCLUDES = KrbIVIncludes -KRBIVLIB = KrbIVLibraries -#endif - -#if HasKrb5 -KRB5_DEFINES = Krb5Defines -KRB5_INCLUDE = Krb5Includes -KRB5OBJS = krb5auth.o -KRB5SRCS = krb5auth.c -#endif - -/* This is correct for Linux and FreeBSD */ -#if HasPam -PAM_LIBRARIES = PamLibraries -PAM_DEFINES = -DUSE_PAM -#endif - -#if HasPam -#undef HasShadowPasswd -#define HasShadowPasswd NO -#undef HasLibCrypt -#define HasLibCrypt NO -#endif - -/* -#if HasBSDAuth -BSDAUTH_DEFINES = -DUSE_BSDAUTH -#endif -*/ - -#if SystemV4 || HasShadowPasswd - -#if !LinuxShadowSuite -PWD_DEFINES = -DUSESHADOW -#else -PWD_DEFINES = -DUSESHADOW -DSHADOWSUITE -#endif - -#if !defined(i386IscArchitecture) && !defined(i386ScoArchitecture) && !defined(LinuxArchitecture) && !defined(NTOArchitecture) && !defined(SGIArchitecture) -SYS_LIBRARIES3 = -lresolv -#endif -#if SystemV || defined(SequentArchitecture) -SYS_LIBRARIES1 = -lsec -#endif -#if defined(LinuxArchitecture) && (!UseElfFormat || LinuxShadowSuite) -SYS_LIBRARIES1 = -lshadow -#endif - -#endif - -#if defined(UltrixArchitecture) -SYS_LIBRARIES1 = -lauth -#endif - -#if (defined(AIXArchitecture) && (OSMajorVersion >= 3)) -SYS_LIBRARIES1 = -ls -#endif - -#if HasLibCrypt -#ifdef SpecialLibCrypt -CRYPT_LIBRARIES = SpecialLibCrypt -#else -CRYPT_LIBRARIES = -lcrypt -#if defined(LynxOSArchitecture) -CRYPT_DEFINES = -DHAS_CRYPT -#endif -#endif -#endif - -#if HasBSD44Sockets -SOCK_DEFINES = -DBSD44SOCKETS -#endif - -#if defined(i386Architecture) || defined(AmigaArchitecture) -FRAGILE_DEFINES = -DFRAGILE_DEV_MEM -#endif - -#ifdef RandomDefines -RANDOM_DEFINES = RandomDefines -#elif defined(OpenBSDArchitecture) -RANDOM_DEFINES = -DARC4_RANDOM -#elif defined(LinuxArchitecture) -RANDOM_DEFINES = -DDEV_RANDOM=\"/dev/urandom\" -#elif defined(NetBSDArchitecture) && \ - ((OSMajorVersion > 1) || \ - (OSMajorVersion == 1 && OSMinorVersion > 3)) -RANDOM_DEFINES = -DDEV_RANDOM=\"/dev/urandom\" -#endif - - -#if HasSetUserContext -USER_CONTEXT_DEFINES = -DHAS_SETUSERCONTEXT -# XXX - only FreeBSD has this in libutil -SYS_LIBRARIES1 = -lutil -#endif - -#if HasSetProcTitle -PROCTITLE_DEFINES = -DHAS_SETPROCTITLE -#endif - - SYS_LIBRARIES = $(SYS_LIBRARIES1) $(SYS_LIBRARIES2) $(SYS_LIBRARIES3) - - INCLUDES = $(KRB5_INCLUDE) - DEPLIBS = $(DEPXLIB) $(DEPXAUTHLIB) $(DEPXDMCPLIB) - LOCAL_LIBRARIES = $(XLIB) $(XAUTHLIB) \ - $(XDMCPLIB) $(RPCLIB) $(PAM_LIBRARIES) \ - $(CRYPT_LIBRARIES) $(KRBIVLIB) - - COMMSRCS = auth.c daemon.c server.c dpylist.c dm.c error.c \ - netaddr.c reset.c resource.c protodpy.c policy.c \ - session.c socket.c streams.c util.c xdmcp.c \ - process.c mitauth.c \ - genauth.c access.c choose.c consolekit.c \ - $(XDMAUTHSRCS) $(RPCSRCS) $(KRB5SRCS) - COMMOBJS = auth.o daemon.o server.o dpylist.o dm.o error.o \ - netaddr.o reset.o resource.o protodpy.o policy.o \ - session.o socket.o streams.o util.o xdmcp.o \ - process.o mitauth.o \ - genauth.o access.o choose.o consolekit.o \ - $(XDMAUTHOBJS) $(RPCOBJS) $(KRB5OBJS) - - SRCS1 = $(COMMSRCS) client.c - OBJS1 = $(COMMOBJS) client.o - -#if BuildBoth - SRCS2 = $(COMMSRCS) clientsh.c - OBJS2 = $(COMMOBJS) clientsh.o - - XDM_SHADOW = xdm-shadow -#endif - - PROGRAMS = xdm $(XDM_SHADOW) - - - OSMAJORVERSION = OSMajorVersion - OSMINORVERSION = OSMinorVersion - CONN_DEFINES = $(CONNECTION_FLAGS) - DEFINES = $(SIGNAL_DEFINES) $(LOG_DEFINES) \ - $(CRYPT_DEFINES)$(PWD_DEFINES) \ - $(BSDAUTH_DEFINES) $(PAM_DEFINES) $(USER_CONTEXT_DEFINES) \ - $(XDMAUTH_DEFINES) $(RPC_DEFINES) $(KRB5_DEFINES) \ - $(XDMCP_DEFINES) $(SOCK_DEFINES) $(CONN_DEFINES) \ - $(FRAGILE_DEFINES) $(RANDOM_DEFINES) $(PROCTITLE_DEFINES) \ - -DOSMAJORVERSION=$(OSMAJORVERSION) -DOSMINORVERSION=$(OSMINORVERSION) \ - -Dconst= - -ComplexProgramTarget_1(xdm,$(LOCAL_LIBRARIES),NullParameter) -#if BuildBoth -NormalProgramTarget(xdm-shadow,$(OBJS2),$(DEPLIBS),$(LOCAL_LIBRARIES),-lshadow) -InstallProgram(xdm-shadow,$(BINDIR)) -ObjectFromSpecialSource(clientsh,client,-DUSESHADOW) -#endif - -#if defined(FreeBSDArchitecture) && (OSMajorVersion < 2) -XCOMM only for daemon.c? it's used in some other places, too. -SpecialCObjectRule(daemon,$(ICONFIGFILES),-UCSRG_BASED) -#endif - diff --git a/kdm/backend/Makefile.am b/kdm/backend/Makefile.am deleted file mode 100644 index 6b5779d51..000000000 --- a/kdm/backend/Makefile.am +++ /dev/null @@ -1,47 +0,0 @@ -# forcibly remove thread-related defines & flags -AUTOMAKE_OPTIONS = foreign -CPPFLAGS = $(USER_INCLUDES) $(X_INCLUDES) $(KRB4_INCS) $(KRB5_INCS) $(DBUS_INCS) -I.. -I../.. -LDFLAGS = $(USER_LDFLAGS) $(X_LDFLAGS) $(X_RPATH) $(KRB4_RPATH) $(KRB5_RPATH) -LDADD = $(LIB_X11) -lXau $(LIBXDMCP) $(PASSWDLIBS) $(LIBSHADOW) $(LIBGEN) \ - $(LIB_LIBS) $(KRB4_LIBS) $(KRB5_LIBS) $(DBUS_LIBS) $(LIBSOCKET) $(LIBRESOLV) \ - $(LIBUCB) $(LIBUTIL) $(LIBPOSIX4) - -bin_PROGRAMS = tdm -tdm_SOURCES = \ - access.c \ - auth.c \ - bootman.c \ - choose.c \ - client.c \ - consolekit.c \ - ctrl.c \ - daemon.c \ - dm.c \ - dpylist.c \ - error.c \ - genauth.c \ - inifile.c \ - krb5auth.c \ - mitauth.c \ - netaddr.c \ - policy.c \ - process.c \ - protodpy.c \ - reset.c \ - resource.c \ - rpcauth.c \ - server.c \ - session.c \ - sessreg.c \ - socket.c \ - streams.c \ - util.c \ - xdmauth.c \ - xdmcp.c - -EXTRA_DIST = printf.c - -noinst_HEADERS = dm.h dm_socket.h dm_error.h dm_auth.h greet.h - -# for unsermake (automake is handled by SUBDIRS in ../) -tdm_COMPILE_FIRST = ../config.ci diff --git a/kdm/backend/access.c b/kdm/backend/access.c deleted file mode 100644 index 82736be57..000000000 --- a/kdm/backend/access.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - -Copyright 1990, 1998 The Open Group -Copyright 2001,2004 Oswald Buddenhagen -Copyright 2002 Sun Microsystems, Inc. All rights reserved. - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * Access control for XDMCP - keep a database of allowable display addresses - * and (potentially) a list of hosts to send ForwardQuery packets to - */ - -#include - -#ifdef XDMCP - -#include "dm.h" -#include "dm_error.h" -#include "dm_socket.h" - -#include -#include - -#include -#if defined(IPv6) && defined(AF_INET6) -# include -#endif - -typedef struct { - short int type; - union { - char *aliasPattern; - char *hostPattern; - struct _displayAddress { - CARD16 connectionType; - ARRAY8 hostAddress; - } displayAddress; - } entry; -} HostEntry; - -typedef struct { - short int iface; - short int mcasts; - short int nmcasts; -} ListenEntry; - -typedef struct { - char *name; - short int hosts; - short int nhosts; -} AliasEntry; - -typedef struct { - short int entries; - short int nentries; - short int hosts; - short int nhosts; - short int flags; -} AclEntry; - -typedef struct { - HostEntry *hostList; - ListenEntry *listenList; - AliasEntry *aliasList; - AclEntry *acList; - short int nHosts, nListens, nAliases, nAcls; - CfgDep dep; -} AccArr; - -static AccArr accData[1]; - - -static ARRAY8 localAddress; - -ARRAY8Ptr -getLocalAddress( void ) -{ - static int haveLocalAddress; - - if (!haveLocalAddress) { -#if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai; - - if (getaddrinfo( localHostname(), NULL, NULL, &ai )) { - XdmcpAllocARRAY8( &localAddress, 4 ); - localAddress.data[0] = 127; - localAddress.data[1] = 0; - localAddress.data[2] = 0; - localAddress.data[3] = 1; - } else { - if (ai->ai_family == AF_INET) { - XdmcpAllocARRAY8( &localAddress, sizeof(struct in_addr) ); - memcpy( localAddress.data, - &((struct sockaddr_in *)ai->ai_addr)->sin_addr, - sizeof(struct in_addr) ); - } else /* if (ai->ai_family == AF_INET6) */ { - XdmcpAllocARRAY8( &localAddress, sizeof(struct in6_addr) ); - memcpy( localAddress.data, - &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, - sizeof(struct in6_addr) ); - } - freeaddrinfo( ai ); -#else - struct hostent *hostent; - - if ((hostent = gethostbyname( localHostname() ))) { - XdmcpAllocARRAY8( &localAddress, hostent->h_length ); - memmove( localAddress.data, hostent->h_addr, hostent->h_length ); -#endif - haveLocalAddress = 1; - } - } - return &localAddress; -} - - -void -ScanAccessDatabase( int force ) -{ - struct _displayAddress *da; - char *cptr; - int nChars, i; - - Debug( "ScanAccessDatabase\n" ); - if (Setjmp( cnftalk.errjmp )) - return; /* may memleak */ - if (startConfig( GC_gXaccess, &accData->dep, force ) <= 0) - return; - if (accData->hostList) - free( accData->hostList ); - accData->nHosts = GRecvInt(); - accData->nListens = GRecvInt(); - accData->nAliases = GRecvInt(); - accData->nAcls = GRecvInt(); - nChars = GRecvInt(); - if (!(accData->hostList = (HostEntry *) - Malloc( accData->nHosts * sizeof(HostEntry) + - accData->nListens * sizeof(ListenEntry) + - accData->nAliases * sizeof(AliasEntry) + - accData->nAcls * sizeof(AclEntry) + - nChars ))) - { - CloseGetter(); - return; - } - accData->listenList = (ListenEntry *)(accData->hostList + accData->nHosts); - accData->aliasList = (AliasEntry *)(accData->listenList + accData->nListens); - accData->acList = (AclEntry *)(accData->aliasList + accData->nAliases); - cptr = (char *)(accData->acList + accData->nAcls); - for (i = 0; i < accData->nHosts; i++) { - switch ((accData->hostList[i].type = GRecvInt())) { - case HOST_ALIAS: - accData->hostList[i].entry.aliasPattern = cptr; - cptr += GRecvStrBuf( cptr ); - break; - case HOST_PATTERN: - accData->hostList[i].entry.hostPattern = cptr; - cptr += GRecvStrBuf( cptr ); - break; - case HOST_ADDRESS: - da = &accData->hostList[i].entry.displayAddress; - da->hostAddress.data = (unsigned char *)cptr; - cptr += (da->hostAddress.length = GRecvArrBuf( cptr )); - switch (GRecvInt()) - { -#ifdef AF_INET - case AF_INET: - da->connectionType = FamilyInternet; - break; -#endif -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - da->connectionType = FamilyInternet6; - break; -#endif -#ifdef AF_DECnet - case AF_DECnet: - da->connectionType = FamilyDECnet; - break; -#endif -/*#ifdef AF_UNIX - case AF_UNIX: -#endif*/ - default: - da->connectionType = FamilyLocal; - break; - } - break; - case HOST_BROADCAST: - break; - default: - LogError( "Received unknown host type %d from config reader\n", accData->hostList[i].type ); - return; - } - } - for (i = 0; i < accData->nListens; i++) { - accData->listenList[i].iface = GRecvInt(); - accData->listenList[i].mcasts = GRecvInt(); - accData->listenList[i].nmcasts = GRecvInt(); - } - for (i = 0; i < accData->nAliases; i++) { - accData->aliasList[i].name = cptr; - cptr += GRecvStrBuf( cptr ); - accData->aliasList[i].hosts = GRecvInt(); - accData->aliasList[i].nhosts = GRecvInt(); - } - for (i = 0; i < accData->nAcls; i++) { - accData->acList[i].entries = GRecvInt(); - accData->acList[i].nentries = GRecvInt(); - accData->acList[i].hosts = GRecvInt(); - accData->acList[i].nhosts = GRecvInt(); - accData->acList[i].flags = GRecvInt(); - } -} - - -/* Returns non-0 if string is matched by pattern. Does case folding. - */ -static int -patternMatch( const char *string, const char *pattern ) -{ - int p, s; - - if (!string) - string = ""; - - for (;;) { - s = *string++; - switch (p = *pattern++) { - case '*': - if (!*pattern) - return 1; - for (string--; *string; string++) - if (patternMatch( string, pattern )) - return 1; - return 0; - case '?': - if (s == '\0') - return 0; - break; - case '\0': - return s == '\0'; - case '\\': - p = *pattern++; - /* fall through */ - default: - if (tolower( p ) != tolower( s )) - return 0; - } - } -} - - -#define MAX_DEPTH 32 - -static void -scanHostlist( int fh, int nh, - ARRAY8Ptr clientAddress, CARD16 connectionType, - ChooserFunc function, char *closure, - int broadcast, int *haveLocalhost ) -{ - HostEntry *h; - AliasEntry *a; - int na; - - for (h = accData->hostList + fh; nh; nh--, h++) { - switch (h->type) { - case HOST_ALIAS: - for (a = accData->aliasList, na = accData->nAliases; na; na--, a++) - if (patternMatch( a->name, h->entry.aliasPattern )) /* XXX originally swapped, no wildcards in alias name matching */ - scanHostlist( a->hosts, a->nhosts, - clientAddress, connectionType, - function, closure, broadcast, - haveLocalhost ); - break; - case HOST_ADDRESS: - if (XdmcpARRAY8Equal( getLocalAddress(), &h->entry.displayAddress.hostAddress )) - *haveLocalhost = 1; - else if (function) - (*function)( connectionType, &h->entry.displayAddress.hostAddress, closure ); - break; - case HOST_BROADCAST: - if (broadcast && function) - (*function)( FamilyBroadcast, 0, closure ); - break; - default: - break; - } - } -} - -static int -scanEntrylist( int fh, int nh, - ARRAY8Ptr clientAddress, CARD16 connectionType, - char **clientName ) -{ - HostEntry *h; - AliasEntry *a; - int na; - - for (h = accData->hostList + fh; nh; nh--, h++) { - switch (h->type) { - case HOST_ALIAS: - for (a = accData->aliasList, na = accData->nAliases; na; na--, a++) - if (patternMatch( a->name, h->entry.aliasPattern )) - if (scanEntrylist( a->hosts, a->nhosts, - clientAddress, connectionType, - clientName )) - return 1; - break; - case HOST_PATTERN: - if (!*clientName) - *clientName = NetworkAddressToHostname( connectionType, - clientAddress ); - if (patternMatch( *clientName, h->entry.hostPattern )) - return 1; - break; - case HOST_ADDRESS: - if (h->entry.displayAddress.connectionType == connectionType && - XdmcpARRAY8Equal( &h->entry.displayAddress.hostAddress, - clientAddress )) - return 1; - break; - default: - break; - } - } - return 0; -} - -static AclEntry * -matchAclEntry( ARRAY8Ptr clientAddress, CARD16 connectionType, int direct ) -{ - AclEntry *e, *re; - char *clientName = 0; - int ne; - - for (e = accData->acList, ne = accData->nAcls, re = 0; ne; ne--, e++) - if (!e->nhosts == direct) - if (scanEntrylist( e->entries, e->nentries, - clientAddress, connectionType, - &clientName )) - { - re = e; - break; - } - if (clientName) - free( clientName ); - return re; -} - -/* - * calls the given function for each valid indirect entry. Returns TRUE if - * the local host exists on any of the lists, else FALSE - */ -int -ForEachMatchingIndirectHost( ARRAY8Ptr clientAddress, - CARD16 connectionType, - ChooserFunc function, char *closure ) -{ - AclEntry *e; - int haveLocalhost = 0; - - e = matchAclEntry( clientAddress, connectionType, 0 ); - if (e && !(e->flags & a_notAllowed)) { - if (e->flags & a_useChooser) { - ARRAY8Ptr choice; - - choice = IndirectChoice( clientAddress, connectionType ); - if (!choice || XdmcpARRAY8Equal( getLocalAddress(), choice )) - haveLocalhost = 1; - else - (*function)( connectionType, choice, closure ); - } else - scanHostlist( e->hosts, e->nhosts, clientAddress, connectionType, - function, closure, FALSE, &haveLocalhost ); - } - return haveLocalhost; -} - -int -UseChooser( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - AclEntry *e; - - e = matchAclEntry( clientAddress, connectionType, 0 ); - return e && !(e->flags & a_notAllowed) && (e->flags & a_useChooser) && - !IndirectChoice( clientAddress, connectionType ); -} - -void -ForEachChooserHost( ARRAY8Ptr clientAddress, CARD16 connectionType, - ChooserFunc function, char *closure ) -{ - AclEntry *e; - int haveLocalhost = 0; - - e = matchAclEntry( clientAddress, connectionType, 0 ); - if (e && !(e->flags & a_notAllowed) && (e->flags & a_useChooser)) - scanHostlist( e->hosts, e->nhosts, clientAddress, connectionType, - function, closure, TRUE, &haveLocalhost ); - if (haveLocalhost) - (*function)( connectionType, getLocalAddress(), closure ); -} - -/* - * returns TRUE if the given client is acceptable to the local host. The - * given display client is acceptable if it occurs without a host list. - */ -int -AcceptableDisplayAddress( ARRAY8Ptr clientAddress, CARD16 connectionType, - xdmOpCode type ) -{ - AclEntry *e; - - if (type == INDIRECT_QUERY) - return 1; - - e = matchAclEntry( clientAddress, connectionType, 1 ); - return e && !(e->flags & a_notAllowed) && - (type != BROADCAST_QUERY || !(e->flags & a_notBroadcast)); -} - -void -ForEachListenAddr( ListenFunc listenfunction, ListenFunc mcastfunction, - void **closure ) -{ - int i, j, ifc, mc, nmc; - - for (i = 0; i < accData->nListens; i++) { - ifc = accData->listenList[i].iface; - (*listenfunction)( ifc < 0 ? 0 : - &accData->hostList[ifc].entry.displayAddress.hostAddress, - closure ); - mc = accData->listenList[i].mcasts; - nmc = accData->listenList[i].nmcasts; - for (j = 0; j < nmc; j++, mc++) - (*mcastfunction)( &accData->hostList[mc].entry.displayAddress.hostAddress, - closure ); - } -} -#endif /* XDMCP */ diff --git a/kdm/backend/auth.c b/kdm/backend/auth.c deleted file mode 100644 index bd183142c..000000000 --- a/kdm/backend/auth.c +++ /dev/null @@ -1,1238 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2004 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * maintain the authorization generation daemon - */ - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include -#include -#include - -#include - -#include "dm_socket.h" -#ifdef DNETCONN -# include -#endif - -#if (defined(_POSIX_SOURCE) && !defined(_AIX) && !defined(__QNX__)) || defined(__hpux) || defined(__svr4__) /* XXX */ -# define NEED_UTSNAME -# include -#endif - -#ifdef __GNU__ -# include -# undef SIOCGIFCONF -#else /* __GNU__ */ -# include -# ifdef __svr4__ -# include -# include -# include -# endif -# ifdef __EMX__ -# define link rename -# define chown(a,b,c) -# include -# endif -#endif /* __GNU__ */ - -struct AuthProtocol { - unsigned short name_length; - const char *name; - void (*InitAuth)( unsigned short len, const char *name ); - Xauth *(*GetAuth)( unsigned short len, const char *name ); -#ifdef XDMCP - void (*GetXdmcpAuth)( struct protoDisplay *pdpy, - unsigned short authorizationNameLen, - const char *authorizationName ); -#endif - int inited; -}; - -#ifdef XDMCP -# define xdmcpauth(arg) , arg -#else -# define xdmcpauth(arg) -#endif - -static struct AuthProtocol AuthProtocols[] = { -{ (unsigned short)18, "MIT-MAGIC-COOKIE-1", - MitInitAuth, MitGetAuth xdmcpauth(NULL), 0 -}, -#ifdef HASXDMAUTH -{ (unsigned short)19, "XDM-AUTHORIZATION-1", - XdmInitAuth, XdmGetAuth xdmcpauth(XdmGetXdmcpAuth), 0 -}, -#endif -#ifdef SECURE_RPC -{ (unsigned short)9, "SUN-DES-1", - SecureRPCInitAuth, SecureRPCGetAuth xdmcpauth(NULL), 0 -}, -#endif -#ifdef K5AUTH -{ (unsigned short)14, "MIT-KERBEROS-5", - Krb5InitAuth, Krb5GetAuth xdmcpauth(NULL), 0 -}, -#endif -}; - -static struct AuthProtocol * -findProtocol( unsigned short name_length, const char *name ) -{ - unsigned i; - - for (i = 0; i < as(AuthProtocols); i++) - if (AuthProtocols[i].name_length == name_length && - memcmp( AuthProtocols[i].name, name, name_length ) == 0) - { - return &AuthProtocols[i]; - } - return (struct AuthProtocol *)0; -} - -int -ValidAuthorization( unsigned short name_length, const char *name ) -{ - if (findProtocol( name_length, name )) - return TRUE; - return FALSE; -} - -static Xauth * -GenerateAuthorization( unsigned short name_length, const char *name ) -{ - struct AuthProtocol *a; - Xauth *auth = 0; - - Debug( "GenerateAuthorization %s\n", name ); - if ((a = findProtocol( name_length, name ))) { - if (!a->inited) { - (*a->InitAuth)( name_length, name ); - a->inited = TRUE; - } - auth = (*a->GetAuth)( name_length, name ); - if (auth) { - Debug( "got %p (%d %.*s) %02[*hhx\n", auth, - auth->name_length, auth->name_length, auth->name, - auth->data_length, auth->data ); - } else - Debug( "got (null)\n" ); - } else - Debug( "unknown authorization %s\n", name ); - return auth; -} - -#ifdef XDMCP - -void -SetProtoDisplayAuthorization( struct protoDisplay *pdpy, - unsigned short authorizationNameLen, - const char *authorizationName ) -{ - struct AuthProtocol *a; - Xauth *auth; - - a = findProtocol( authorizationNameLen, authorizationName ); - pdpy->xdmcpAuthorization = pdpy->fileAuthorization = 0; - if (a) { - if (!a->inited) { - (*a->InitAuth)( authorizationNameLen, authorizationName ); - a->inited = TRUE; - } - if (a->GetXdmcpAuth) { - (*a->GetXdmcpAuth)( pdpy, authorizationNameLen, authorizationName ); - auth = pdpy->xdmcpAuthorization; - } else { - auth = (*a->GetAuth)( authorizationNameLen, authorizationName ); - pdpy->fileAuthorization = auth; - pdpy->xdmcpAuthorization = 0; - } - if (auth) - Debug( "got %p (%d %.*s)\n", auth, - auth->name_length, auth->name_length, auth->name ); - else - Debug( "got (null)\n" ); - } -} - -#endif /* XDMCP */ - -void -CleanUpFileName( const char *src, char *dst, int len ) -{ - while (*src) { - if (--len <= 0) - break; - switch (*src & 0x7f) { - case '/': - *dst++ = '_'; - break; - case '-': - *dst++ = '.'; - break; - default: - *dst++ = (*src & 0x7f); - } - ++src; - } - *dst = '\0'; -} - - -static FILE * -fdOpenW( int fd ) -{ - FILE *f; - - if (fd >= 0) { - if ((f = fdopen( fd, "w" ))) - return f; - close( fd ); - } - return 0; -} - -static FILE * -mkTempFile( char *nambuf, int namelen ) -{ - FILE *f; - int r; - - for (r = 0; r < 100; r++) { - randomStr( nambuf + namelen ); - if ((f = fdOpenW( open( nambuf, O_WRONLY | O_CREAT | O_EXCL, 0600 ) ))) - return f; - if (errno != EEXIST) - break; - } - return 0; -} - -#define NAMELEN 255 - -static FILE * -MakeServerAuthFile( struct display *d ) -{ - FILE *f; - int i; - char cleanname[NAMELEN], nambuf[NAMELEN+128]; - - /* - * Some paranoid, but still not sufficient (DoS was still possible) - * checks used to be here. I removed all this stuff because - * a) authDir is supposed to be /var/run/xauth (=safe) or similar and - * b) even if it's not (say, /tmp), we create files safely (hopefully). - */ - if (mkdir( authDir, 0755 ) < 0 && errno != EEXIST) - return 0; - CleanUpFileName( d->name, cleanname, NAMELEN - 8 ); - i = sprintf( nambuf, "%s/A%s-", authDir, cleanname ); - if ((f = mkTempFile( nambuf, i ))) { - StrDup( &d->authFile, nambuf ); - return f; - } - return 0; -} - -int -SaveServerAuthorizations( struct display *d, Xauth **auths, int count ) -{ - FILE *auth_file; - int i; - - if (!d->authFile && d->clientAuthFile && *d->clientAuthFile) - StrDup( &d->authFile, d->clientAuthFile ); - if (d->authFile) { - if (!(auth_file = fdOpenW( creat( d->authFile, 0600 ) ))) { - LogError( "Cannot open X server authorization file %s\n", d->authFile ); - free( d->authFile ); - d->authFile = NULL; - return FALSE; - } - } else { - if (!(auth_file = MakeServerAuthFile( d ))) { - LogError( "Cannot create X server authorization file\n" ); - return FALSE; - } - } - Debug( "file: %s auth: %p\n", d->authFile, auths ); - for (i = 0; i < count; i++) { - /* - * User-based auths may not have data until - * a user logs in. In which case don't write - * to the auth file so xrdb and setup programs don't fail. - */ - if (auths[i]->data_length > 0) - if (!XauWriteAuth( auth_file, auths[i] ) || - fflush( auth_file ) == EOF) - { - fclose( auth_file ); - LogError( "Cannot write X server authorization file %s\n", - d->authFile ); - free( d->authFile ); - d->authFile = NULL; - return FALSE; - } - } - fclose( auth_file ); - return TRUE; -} - -void -SetLocalAuthorization( struct display *d ) -{ - Xauth *auth, **auths; - int i, j; - - if (d->authorizations) - { - for (i = 0; i < d->authNum; i++) - XauDisposeAuth( d->authorizations[i] ); - free( (char *)d->authorizations ); - d->authorizations = (Xauth **)NULL; - d->authNum = 0; - } - Debug( "SetLocalAuthorization %s, auths %[s\n", d->name, d->authNames ); - if (!d->authNames) - return; - for (i = 0; d->authNames[i]; i++) - ; - d->authNameNum = i; - if (d->authNameLens) - free( (char *)d->authNameLens ); - d->authNameLens = (unsigned short *)Malloc( d->authNameNum * sizeof(unsigned short) ); - if (!d->authNameLens) - return; - for (i = 0; i < d->authNameNum; i++) - d->authNameLens[i] = strlen( d->authNames[i] ); - auths = (Xauth **)Malloc( d->authNameNum * sizeof(Xauth *) ); - if (!auths) - return; - j = 0; - for (i = 0; i < d->authNameNum; i++) { - auth = GenerateAuthorization( d->authNameLens[i], d->authNames[i] ); - if (auth) - auths[j++] = auth; - } - if (SaveServerAuthorizations( d, auths, j )) { - d->authorizations = auths; - d->authNum = j; - } else { - for (i = 0; i < j; i++) - XauDisposeAuth( auths[i] ); - free( (char *)auths ); - } -} - -/* - * Set the authorization to use for xdm's initial connection - * to the X server. Cannot use user-based authorizations - * because no one has logged in yet, so we don't have any - * user credentials. - * Well, actually we could use SUN-DES-1 because we tell the server - * to allow root in. This is bogus and should be fixed. - */ -void -SetAuthorization( struct display *d ) -{ - register Xauth **auth = d->authorizations; - int i; - - for (i = 0; i < d->authNum; i++) { - if (auth[i]->name_length == 9 && - memcmp( auth[i]->name, "SUN-DES-1", 9 ) == 0) - continue; - if (auth[i]->name_length == 14 && - memcmp( auth[i]->name, "MIT-KERBEROS-5", 14 ) == 0) - continue; - XSetAuthorization( auth[i]->name, (int)auth[i]->name_length, - auth[i]->data, (int)auth[i]->data_length ); - } -} - -static int -openFiles( const char *name, char *new_name, FILE **oldp, FILE **newp ) -{ - strcat( strcpy( new_name, name ), "-n" ); - if (!(*newp = - fdOpenW( creat( new_name, 0600 ) ))) { - Debug( "can't open new file %s\n", new_name ); - return 0; - } - *oldp = fopen( name, "r" ); - Debug( "opens succeeded %s %s\n", name, new_name ); - return 1; -} - -struct addrList { - struct addrList *next; - unsigned short family, address_length, number_length; - char data[1]; -}; - -static struct addrList *addrs; - -static void -initAddrs( void ) -{ - addrs = 0; -} - -static void -doneAddrs( void ) -{ - struct addrList *a, *n; - for (a = addrs; a; a = n) { - n = a->next; - free( a ); - } -} - -static void -saveEntry( Xauth *auth ) -{ - struct addrList *new; - - if (!(new = Malloc( offsetof(struct addrList, data) + - auth->address_length + auth->number_length ))) - return; - new->address_length = auth->address_length; - new->number_length = auth->number_length; - memcpy( new->data, auth->address, (int)auth->address_length ); - memcpy( new->data + (int)auth->address_length, - auth->number, (int)auth->number_length ); - new->family = auth->family; - new->next = addrs; - addrs = new; -} - -static int -checkEntry( Xauth *auth ) -{ - struct addrList *a; - - for (a = addrs; a; a = a->next) - if (a->family == auth->family && - a->address_length == auth->address_length && - !memcmp( a->data, auth->address, auth->address_length ) && - a->number_length == auth->number_length && - !memcmp( a->data + a->address_length, - auth->number, auth->number_length )) - return 1; - return 0; -} - -static void -writeAuth( FILE *file, Xauth *auth, int *ok ) -{ - if (debugLevel & DEBUG_AUTH) /* normally too verbose */ - Debug( "writeAuth: doWrite = %d\n" - "family: %d\n" - "addr: %02[*:hhx\n" - "number: %02[*:hhx\n" - "name: %02[*:hhx\n" - "data: %02[*:hhx\n", - ok != 0, auth->family, - auth->address_length, auth->address, - auth->number_length, auth->number, - auth->name_length, auth->name, - auth->data_length, auth->data ); - if (ok && !XauWriteAuth( file, auth )) - *ok = FALSE; -} - -static void -writeAddr( int family, int addr_length, char *addr, - FILE *file, Xauth *auth, int *ok ) -{ - auth->family = (unsigned short)family; - auth->address_length = addr_length; - auth->address = addr; - Debug( "writeAddr: writing and saving an entry\n" ); - writeAuth( file, auth, ok ); - if (!checkEntry( auth )) - saveEntry( auth ); -} - -static void -DefineLocal( FILE *file, Xauth *auth, int *ok ) -{ -#if !defined(NEED_UTSNAME) || defined(__hpux) - char displayname[100]; -#endif -#ifdef NEED_UTSNAME - struct utsname name; -#endif - - /* stolen from xinit.c */ - -/* Make sure this produces the same string as _XGetHostname in lib/X/XlibInt.c. - * Otherwise, Xau will not be able to find your cookies in the Xauthority file. - * - * Note: POSIX says that the ``nodename'' member of utsname does _not_ have - * to have sufficient information for interfacing to the network, - * and so, you may be better off using gethostname (if it exists). - */ - -#ifdef NEED_UTSNAME - - /* hpux: - * Why not use gethostname()? Well, at least on my system, I've had to - * make an ugly kernel patch to get a name longer than 8 characters, and - * uname() lets me access to the whole string (it smashes release, you - * see), whereas gethostname() kindly truncates it for me. - */ - uname( &name ); - writeAddr( FamilyLocal, strlen( name.nodename ), name.nodename, - file, auth, ok ); -#endif - -#if !defined(NEED_UTSNAME) || defined(__hpux) - /* _AIX: - * In _AIX, _POSIX_SOURCE is defined, but uname gives only first - * field of hostname. Thus, we use gethostname instead. - */ - - /* - * For HP-UX, HP's Xlib expects a fully-qualified domain name, which - * is achieved by using gethostname(). For compatability, we must - * also still create the entry using uname() above. - */ - displayname[0] = 0; - if (!gethostname( displayname, sizeof(displayname) )) - displayname[sizeof(displayname) - 1] = 0; - -# ifdef NEED_UTSNAME - /* - * If gethostname and uname both returned the same name, - * do not write a duplicate entry. - */ - if (strcmp( displayname, name.nodename )) -# endif - writeAddr( FamilyLocal, strlen( displayname ), displayname, - file, auth, ok ); -#endif -} - -#ifdef SYSV_SIOCGIFCONF - -/* Deal with different SIOCGIFCONF ioctl semantics on SYSV, SVR4 */ - -int -ifioctl (int fd, int cmd, char *arg) -{ - struct strioctl ioc; - int ret; - - bzero( (char *)&ioc, sizeof(ioc) ); - ioc.ic_cmd = cmd; - ioc.ic_timout = 0; - if (cmd == SIOCGIFCONF) { - ioc.ic_len = ((struct ifconf *)arg)->ifc_len; - ioc.ic_dp = ((struct ifconf *)arg)->ifc_buf; - } else { - ioc.ic_len = sizeof(struct ifreq); - ioc.ic_dp = arg; - } - ret = ioctl( fd, I_STR, (char *)&ioc ); - if (ret >= 0 && cmd == SIOCGIFCONF) - ((struct ifconf *)arg)->ifc_len = ioc.ic_len; - return (ret); -} - -#endif /* SYSV_SIOCGIFCONF */ - -#ifdef HAVE_GETIFADDRS -# include - -static void -DefineSelf( FILE *file, Xauth *auth, int *ok ) -{ - struct ifaddrs *ifap, *ifr; - char *addr; - int family, len; - - if (getifaddrs( &ifap ) < 0) - return; - for (ifr = ifap; ifr; ifr = ifr->ifa_next) { - if (!ifr->ifa_addr) - continue; - family = ConvertAddr( (char *)(ifr->ifa_addr), &len, &addr ); - if (family == -1 || family == FamilyLocal) - continue; - /* - * don't write out 'localhost' entries, as - * they may conflict with other local entries. - * DefineLocal will always be called to add - * the local entry anyway, so this one can - * be tossed. - */ - if (family == FamilyInternet && - addr[0] == 127 && addr[1] == 0 && addr[2] == 0 && addr[3] == 1) - { - Debug( "Skipping localhost address\n" ); - continue; - } -# if defined(IPv6) && defined(AF_INET6) - if (family == FamilyInternet6) { - if (IN6_IS_ADDR_LOOPBACK( ((struct in6_addr *)addr) )) { - Debug( "Skipping IPv6 localhost address\n" ); - continue; - } - /* Also skip XDM-AUTHORIZATION-1 */ - if (auth->name_length == 19 && - !memcmp( auth->name, "XDM-AUTHORIZATION-1", 19 )) { - Debug( "Skipping IPv6 XDM-AUTHORIZATION-1\n" ); - continue; - } - } -# endif - writeAddr( family, len, addr, file, auth, ok ); - } - freeifaddrs( ifap ); -} -#else /* GETIFADDRS */ - -#if defined(STREAMSCONN) && !defined(SYSV_SIOCGIFCONF) && !defined(WINTCP) - -#include - -/* Define this host for access control. Find all the hosts the OS knows about - * for this fd and add them to the selfhosts list. - * TLI version, written without sufficient documentation. - */ -static void -DefineSelf( int fd, FILE *file, Xauth *auth, int *ok ) -{ - struct netbuf netb; - char addrret[1024]; /* easier than t_alloc */ - - netb.maxlen = sizeof(addrret); - netb.buf = addrret; - if (t_getname( fd, &netb, LOCALNAME ) == -1) - t_error( "t_getname" ); - /* what a kludge */ - writeAddr( FamilyInternet, 4, netb.buf+4, file, auth, ok ); -} - -#else - -#ifdef WINTCP /* NCR with Wollongong TCP */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -static void -DefineSelf( int fd, FILE *file, Xauth *auth, int *ok ) -{ - /* - * The Wollongong drivers used by NCR SVR4/MP-RAS don't understand the - * socket IO calls that most other drivers seem to like. Because of - * this, this routine must be special cased for NCR. Eventually, - * this will be cleared up. - */ - - struct ipb ifnet; - struct in_ifaddr ifaddr; - struct strioctl str; - unsigned char *addr; - int len, ipfd; - - if ((ipfd = open( "/dev/ip", O_RDWR, 0 )) < 0) { - LogError( "Trouble getting interface configuration\n" ); - return; - } - - /* Indicate that we want to start at the begining */ - ifnet.ib_next = (struct ipb *)1; - - while (ifnet.ib_next) { - str.ic_cmd = IPIOC_GETIPB; - str.ic_timout = 0; - str.ic_len = sizeof(struct ipb); - str.ic_dp = (char *)&ifnet; - - if (ioctl( ipfd, (int)I_STR, (char *)&str ) < 0) { - close( ipfd ); - LogError( "Trouble getting interface configuration\n" ); - return; - } - - ifaddr.ia_next = (struct in_ifaddr *)ifnet.if_addrlist; - str.ic_cmd = IPIOC_GETINADDR; - str.ic_timout = 0; - str.ic_len = sizeof(struct in_ifaddr); - str.ic_dp = (char *)&ifaddr; - - if (ioctl( ipfd, (int)I_STR, (char *)&str ) < 0) { - close( ipfd ); - LogError( "Trouble getting interface configuration\n" ); - return; - } - - /* - * Ignore the 127.0.0.1 entry. - */ - if (IA_SIN( &ifaddr )->sin_addr.s_addr == htonl( 0x7f000001 ) ) - continue; - - writeAddr( FamilyInternet, 4, (char *)&(IA_SIN( &ifaddr )->sin_addr), - file, auth, ok ); - - } - close( ipfd ); -} - -#else /* WINTCP */ - -/* Solaris provides an extended interface SIOCGLIFCONF. Other systems - * may have this as well, but the code has only been tested on Solaris - * so far, so we only enable it there. Other platforms may be added as - * needed. - * - * Test for Solaris commented out -- TSI @ UQV 2003.06.13 - */ -#ifdef SIOCGLIFCONF -/* #if defined(sun) */ -# define USE_SIOCGLIFCONF -/* #endif */ -#endif - -#if defined(SIOCGIFCONF) || defined (USE_SIOCGLIFCONF) - -#if !defined(SYSV_SIOCGIFCONF) || defined(USE_SIOCGLIFCONF) -# define ifioctl ioctl -#endif - -#ifdef USE_SIOCGLIFCONF -# define ifr_type struct lifreq -#else -# define ifr_type struct ifreq -#endif - -/* Handle variable length ifreq in BNR2 and later */ -#ifdef VARIABLE_IFREQ -# define ifr_size(p) (sizeof(struct ifreq) + \ - (p->ifr_addr.sa_len > sizeof(p->ifr_addr) ? \ - p->ifr_addr.sa_len - sizeof(p->ifr_addr) : 0)) -#else -# define ifr_size(p) (sizeof(ifr_type)) -#endif - -#ifdef USE_SIOCGLIFCONF -# define IFC_IOCTL_REQ SIOCGLIFCONF -# define IFC_REQ(ifc) ifc.lifc_req -# define IFC_LEN(ifc) ifc.lifc_len -# define IFR_ADDR(ifr) ifr->lifr_addr -# define IFR_NAME(ifr) ifr->lifr_name -#else -# define IFC_IOCTL_REQ SIOCGIFCONF -# define IFC_REQ(ifc) ifc.ifc_req -# define IFC_LEN(ifc) ifc.ifc_len -# define IFR_ADDR(ifr) ifr->ifr_addr -# define IFR_NAME(ifr) ifr->ifr_name -#endif - -/* Define this host for access control. Find all the hosts the OS knows about - * for this fd and add them to the selfhosts list. - */ -static void -DefineSelf( int fd, FILE *file, Xauth *auth, int *ok ) -{ - char buf[2048], *cp, *cplim; - int len; - char *addr; - int family; - ifr_type *ifr; -#ifdef USE_SIOCGLIFCONF - int n; - void * bufptr = buf; - size_t buflen = sizeof(buf); - struct lifconf ifc; -# ifdef SIOCGLIFNUM - struct lifnum ifn; -# endif -#else - struct ifconf ifc; -#endif - -#if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF) - ifn.lifn_family = AF_UNSPEC; - ifn.lifn_flags = 0; - if (ioctl( fd, (int)SIOCGLIFNUM, (char *)&ifn ) < 0) - LogError( "Failed getting interface count\n" ); - if (buflen < (ifn.lifn_count * sizeof(struct lifreq))) { - buflen = ifn.lifn_count * sizeof(struct lifreq); - bufptr = Malloc( buflen ); - } -#endif - -#ifdef USE_SIOCGLIFCONF - ifc.lifc_family = AF_UNSPEC; - ifc.lifc_flags = 0; - ifc.lifc_len = buflen; - ifc.lifc_buf = bufptr; -#else - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; -#endif - if (ifioctl (fd, IFC_IOCTL_REQ, (char *)&ifc) < 0) { - LogError( "Trouble getting network interface configuration\n" ); -#if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF) - if (bufptr != buf) - free( bufptr ); -#endif - return; - } - - cplim = (char *)IFC_REQ( ifc ) + IFC_LEN( ifc ); - - for (cp = (char *)IFC_REQ( ifc ); cp < cplim; cp += ifr_size (ifr)) { - ifr = (ifr_type *) cp; -#ifdef DNETCONN - /* - * this is ugly but SIOCGIFCONF returns decnet addresses in - * a different form from other decnet calls - */ - if (IFR_ADDR( ifr ).sa_family == AF_DECnet) { - len = sizeof(struct dn_naddr); - addr = (char *)IFR_ADDR( ifr ).sa_data; - family = FamilyDECnet; - } else -#endif - { - family = ConvertAddr( (char *)&IFR_ADDR( ifr ), &len, &addr ); - if (family < 0) - continue; - - if (len == 0) { - Debug( "skipping zero length address\n" ); - continue; - } - /* - * don't write out 'localhost' entries, as - * they may conflict with other local entries. - * DefineLocal will always be called to add - * the local entry anyway, so this one can - * be tossed. - */ - if (family == FamilyInternet && - addr[0] == 127 && addr[1] == 0 && - addr[2] == 0 && addr[3] == 1) - { - Debug( "skipping localhost address\n" ); - continue; - } -#if defined(IPv6) && defined(AF_INET6) - if (family == FamilyInternet6) { - if (IN6_IS_ADDR_LOOPBACK( ((struct in6_addr *)addr) )) { - Debug( "Skipping IPv6 localhost address\n" ); - continue; - } - /* Also skip XDM-AUTHORIZATION-1 */ - if (auth->name_length == 19 && - !memcmp( auth->name, "XDM-AUTHORIZATION-1", 19 )) { - Debug( "Skipping IPv6 XDM-AUTHORIZATION-1\n" ); - continue; - } - } -#endif - } - Debug( "DefineSelf: write network address, length %d\n", len ); - writeAddr( family, len, addr, file, auth, ok ); - } -#if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF) - if (bufptr != buf) - free( bufptr ); -#endif -} - -#else /* SIOCGIFCONF */ - -/* Define this host for access control. Find all the hosts the OS knows about - * for this fd and add them to the selfhosts list. - */ -static void -DefineSelf( int fd, int file, int auth, int *ok ) -{ - int len; - caddr_t addr; - int family; - - struct utsname name; - register struct hostent *hp; - - union { - struct sockaddr sa; - struct sockaddr_in in; - } saddr; - - struct sockaddr_in *inetaddr; - - /* hpux: - * Why not use gethostname()? Well, at least on my system, I've had to - * make an ugly kernel patch to get a name longer than 8 characters, and - * uname() lets me access to the whole string (it smashes release, you - * see), whereas gethostname() kindly truncates it for me. - */ - uname( &name ); - if ((hp = gethostbyname( name.nodename ))) { - saddr.sa.sa_family = hp->h_addrtype; - inetaddr = (struct sockaddr_in *)(&(saddr.sa)); - memmove( (char *)&(inetaddr->sin_addr), (char *)hp->h_addr, - (int)hp->h_length ); - if ( (family = ConvertAddr( &(saddr.sa), &len, &addr )) >= 0) - writeAddr( FamilyInternet, sizeof(inetaddr->sin_addr), - (char *)(&inetaddr->sin_addr), file, auth, ok ); - } -} - -#endif /* SIOCGIFCONF else */ -#endif /* WINTCP else */ -#endif /* STREAMSCONN && !SYSV_SIOCGIFCONF else */ -#endif /* HAVE_GETIFADDRS */ - -static void -setAuthNumber( Xauth *auth, const char *name ) -{ - char *colon; - char *dot; - - Debug( "setAuthNumber %s\n", name ); - colon = strrchr( name, ':' ); - if (colon) { - ++colon; - dot = strchr( colon, '.' ); - if (dot) - auth->number_length = dot - colon; - else - auth->number_length = strlen( colon ); - if (!StrNDup( &auth->number, colon, auth->number_length )) - auth->number_length = 0; - Debug( "setAuthNumber: %s\n", auth->number ); - } -} - -static void -writeLocalAuth( FILE *file, Xauth *auth, const char *name, int *ok ) -{ -#if defined(STREAMSCONN) || !defined(HAVE_GETIFADDRS) - int fd; -#endif - - Debug( "writeLocalAuth: %s %.*s\n", name, auth->name_length, auth->name ); - setAuthNumber( auth, name ); -# ifdef STREAMSCONN - fd = t_open( "/dev/tcp", O_RDWR, 0 ); - t_bind( fd, NULL, NULL ); - DefineSelf( fd, file, auth, ok ); - t_unbind( fd ); - t_close( fd ); -# elif defined(HAVE_GETIFADDRS) - DefineSelf( file, auth, ok ); -# else -# ifdef TCPCONN -# if defined(IPv6) && defined(AF_INET6) - fd = socket( AF_INET6, SOCK_STREAM, 0 ); - if (fd < 0) -# endif - fd = socket( AF_INET, SOCK_STREAM, 0 ); - DefineSelf( fd, file, auth, ok ); - close( fd ); -# endif -# ifdef DNETCONN - fd = socket( AF_DECnet, SOCK_STREAM, 0 ); - DefineSelf( fd, file, auth, ok ); - close( fd ); -# endif -# endif /* HAVE_GETIFADDRS */ - DefineLocal( file, auth, ok ); -} - -#ifdef XDMCP - -/* - * Call ConvertAddr(), and if it returns an IPv4 localhost, convert it - * to a local display name. Meets the _XTransConvertAddress's localhost - * hack. - */ - -static int -ConvertAuthAddr( char *saddr, int *len, char **addr ) -{ - int ret = ConvertAddr( saddr, len, addr ); - if (ret == FamilyInternet && - ((struct in_addr *)*addr)->s_addr == htonl( 0x7F000001L )) - ret = FamilyLocal; - return ret; -} - -static void -writeRemoteAuth( FILE *file, Xauth *auth, XdmcpNetaddr peer, int peerlen, - const char *name, int *ok ) -{ - int family = FamilyLocal; - char *addr; - - Debug( "writeRemoteAuth: %s %.*s\n", name, auth->name_length, auth->name ); - if (!peer || peerlen < 2) - return; - setAuthNumber( auth, name ); - family = ConvertAuthAddr( peer, &peerlen, &addr ); - Debug( "writeRemoteAuth: family %d\n", family ); - if (family != FamilyLocal) { - Debug( "writeRemoteAuth: %d, %02[*:hhx\n", - family, peerlen, addr ); - writeAddr( family, peerlen, addr, file, auth, ok ); - } else - writeLocalAuth( file, auth, name, ok ); -} - -#endif /* XDMCP */ - -#define NBSIZE 1024 - -static void -startUserAuth( char *buf, char *nbuf, FILE **old, FILE **new ) -{ - const char *home; - int lockStatus; - - initAddrs(); - *new = 0; - if ((home = getEnv( userEnviron, "HOME" )) && strlen( home ) < NBSIZE - 12) { - sprintf( buf, "%s/.Xauthority", home ); - Debug( "XauLockAuth %s\n", buf ); - lockStatus = XauLockAuth( buf, 1, 2, 10 ); - Debug( "lock is %d\n", lockStatus ); - if (lockStatus == LOCK_SUCCESS) - if (!openFiles( buf, nbuf, old, new )) - XauUnlockAuth( buf ); - } - if (!*new) - LogWarn( "Can't update authorization file in home dir %s\n", home ); -} - -static int -endUserAuth( FILE *old, FILE *new, const char *nname, int ok ) -{ - Xauth *entry; - struct stat statb; - - if (old) { - if (fstat( fileno( old ), &statb ) != -1) - chmod( nname, (int)(statb.st_mode & 0777) ); - /*SUPPRESS 560*/ - while ((entry = XauReadAuth( old ))) { - if (!checkEntry( entry )) { - Debug( "writing an entry\n" ); - writeAuth( new, entry, &ok ); - } - XauDisposeAuth( entry ); - } - fclose( old ); - } - if (fclose( new ) == EOF) - ok = FALSE; - doneAddrs(); - return ok; -} - -static void -undoUserAuth( const char *name, const char *new_name ) -{ - LogWarn( "Can't save user authorization in home dir\n" ); - unlink( new_name ); - XauUnlockAuth( name ); -} - -static char * -moveUserAuth( const char *name, char *new_name, char *envname ) -{ - if (unlink( name )) - Debug( "unlink %s failed\n", name ); - if (link( new_name, name )) { - Debug( "link failed %s %s\n", new_name, name ); - LogError( "Can't move user authorization into place\n" ); - envname = new_name; - } else { - Debug( "new authorization moved into place\n" ); - unlink( new_name ); - } - XauUnlockAuth( name ); - return envname; -} - -void -SetUserAuthorization( struct display *d ) -{ - FILE *old, *new; - char *name; - char *envname; - Xauth **auths; - int i, ok; - int magicCookie; - int data_len; - char name_buf[NBSIZE], new_name[NBSIZE + 2]; - - Debug( "SetUserAuthorization\n" ); - auths = d->authorizations; - if (auths) { - startUserAuth( name_buf, new_name, &old, &new ); - if (new) { - envname = 0; - name = name_buf; - } else { - fallback: - if (strlen( d->userAuthDir ) >= NBSIZE - 13) - return; - /* - * Note, that we don't lock the auth file here, as it's - * temporary - we can assume, that we are the only ones - * knowing about this file anyway. - */ - i = sprintf( name_buf, "%s/.Xauth", d->userAuthDir ); - new = mkTempFile( name_buf, i ); - if (!new) { - LogError( "Can't create authorization file in %s\n", - d->userAuthDir ); - return; - } - name = 0; - envname = name_buf; - old = 0; - } - ok = TRUE; - Debug( "%d authorization protocols for %s\n", d->authNum, d->name ); - /* - * Write MIT-MAGIC-COOKIE-1 authorization first, so that - * R4 clients which only knew that, and used the first - * matching entry will continue to function - */ - magicCookie = -1; - for (i = 0; i < d->authNum; i++) { - if (auths[i]->name_length == 18 && - !memcmp( auths[i]->name, "MIT-MAGIC-COOKIE-1", 18 )) - { - magicCookie = i; - if ((d->displayType & d_location) == dLocal) - writeLocalAuth( new, auths[i], d->name, &ok ); -#ifdef XDMCP - else - writeRemoteAuth( new, auths[i], (XdmcpNetaddr)d->peer.data, - d->peer.length, d->name, &ok ); -#endif - break; - } - } - /* now write other authorizations */ - for (i = 0; i < d->authNum; i++) { - if (i != magicCookie) { - data_len = auths[i]->data_length; - /* client will just use default Kerberos cache, so don't - * even write cache info into the authority file. - */ - if (auths[i]->name_length == 14 && - !strncmp( auths[i]->name, "MIT-KERBEROS-5", 14 )) - auths[i]->data_length = 0; - if ((d->displayType & d_location) == dLocal) - writeLocalAuth( new, auths[i], d->name, &ok ); -#ifdef XDMCP - else - writeRemoteAuth( new, auths[i], (XdmcpNetaddr)d->peer.data, - d->peer.length, d->name, &ok ); -#endif - auths[i]->data_length = data_len; - } - } - if (!endUserAuth( old, new, new_name, ok )) { - if (!name) { - LogError( "Can't save user authorization\n" ); - return; - } - undoUserAuth( name, new_name ); - initAddrs(); - goto fallback; - } - if (name) - envname = moveUserAuth( name, new_name, envname ); - if (envname) { - userEnviron = setEnv( userEnviron, "XAUTHORITY", envname ); - systemEnviron = setEnv( systemEnviron, "XAUTHORITY", envname ); - } - /* a chown() used to be here, but this code runs as user anyway */ - } - Debug( "done SetUserAuthorization\n" ); -} - -void -RemoveUserAuthorization( struct display *d ) -{ - Xauth **auths; - FILE *old, *new; - int i; - char name[NBSIZE], new_name[NBSIZE + 2]; - - if (!(auths = d->authorizations)) - return; - Debug( "RemoveUserAuthorization\n" ); - startUserAuth( name, new_name, &old, &new ); - if (new) { - for (i = 0; i < d->authNum; i++) { - if ((d->displayType & d_location) == dLocal) - writeLocalAuth( new, auths[i], d->name, 0 ); -#ifdef XDMCP - else - writeRemoteAuth( new, auths[i], (XdmcpNetaddr)d->peer.data, - d->peer.length, d->name, 0 ); -#endif - } - if (endUserAuth( old, new, new_name, TRUE )) - (void)moveUserAuth( name, new_name, 0 ); - else - undoUserAuth( name, new_name ); - } - Debug( "done RemoveUserAuthorization\n" ); -} diff --git a/kdm/backend/bootman.c b/kdm/backend/bootman.c deleted file mode 100644 index 291164ea7..000000000 --- a/kdm/backend/bootman.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - -Copyright 2005 Stephan Kulow -Copyright 2005 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * Boot options - */ - -#include "dm.h" -#include "dm_error.h" - -#include -#include -#include -#include - -extern char **environ; - -static int -getNull( char ***opts ATTR_UNUSED, int *def ATTR_UNUSED, int *cur ATTR_UNUSED ) -{ - return BO_NOMAN; -} - -static int -setNull( const char *opt ATTR_UNUSED, SdRec *sdr ATTR_UNUSED ) -{ - return BO_NOMAN; -} - -static char * -match( char *obuf, int *blen, const char *key, int klen ) -{ - char *buf = obuf; - if (memcmp( buf, key, klen ) || !isspace( buf[klen] )) - return 0; - buf += klen + 1; - for (; isspace( *buf ); buf++); - if (!*buf) - return 0; - *blen -= buf - obuf; - return buf; -} - -#define GRUB_MENU "/boot/grub/menu.lst" - -static char *grub; - -static int -getGrub( char ***opts, int *def, int *cur ) -{ - FILE *f; - char *ptr, *linp; - int len; - char line[1000]; - - if (!grub && !(grub = locate( "grub-set-default" ))) - return BO_NOMAN; - - *def = 0; - *cur = -1; - *opts = initStrArr( 0 ); - - if (!(f = fopen( GRUB_MENU, "r" ))) - return errno == ENOENT ? BO_NOMAN : BO_IO; - while ((len = fGets( line, sizeof(line), f )) != -1) { - for (linp = line; isspace(*linp); linp++, len--); - if ((ptr = match( linp, &len, "default", 7 ))) - *def = atoi( ptr ); - else if ((ptr = match( linp, &len, "title", 5 ))) { - for (; isspace( ptr[len - 1] ); len--); - *opts = addStrArr( *opts, ptr, len ); - } - } - fclose( f ); - - return BO_OK; -} - -static int -setGrub( const char *opt, SdRec *sdr ) -{ - FILE *f; - char *ptr; - int len, i; - char line[1000]; - - if (!(f = fopen( GRUB_MENU, "r" ))) - return errno == ENOENT ? BO_NOMAN : BO_IO; - for (i = 0; (len = fGets( line, sizeof(line), f )) != -1; ) - if ((ptr = match( line, &len, "title", 5 ))) { - if (!strcmp( ptr, opt )) { - fclose( f ); - sdr->osindex = i; - sdr->bmstamp = mTime( GRUB_MENU ); - return BO_OK; - } - i++; - } - fclose( f ); - return BO_NOENT; -} - -static void -commitGrub( void ) -{ - char command[256]; - - if (sdRec.bmstamp != mTime( GRUB_MENU ) && - setGrub( sdRec.osname, &sdRec ) != BO_OK) - return; - - sprintf(command, "%s %d", grub, sdRec.osindex); - system(command); -} - -static char *lilo; - -static int -getLilo( char ***opts, int *def, int *cur ) -{ - FILE *f; - int cdef, pid, len, ret = BO_OK; - static const char *args[5] = { 0, "-w", "-v", "-q", 0 }; - char buf[256], next[256]; - - if (!lilo && !(lilo = locate( "lilo" ))) - return BO_NOMAN; - - args[0] = lilo; - if (!(f = pOpen( (char **)args, 'r', &pid ))) - return BO_IO; - *opts = 0; - next[0] = 0; - for (;;) { - if ((len = fGets( buf, sizeof(buf), f)) == -1) { - ret = BO_NOMAN; - goto out; - } - if (!memcmp( buf, "Images:", 7 )) - break; -#define Ldeflin " Default boot command line:" - if (!memcmp( buf, Ldeflin, strlen(Ldeflin) )) { - memcpy( next, buf + strlen(Ldeflin) + 2, len - strlen(Ldeflin) - 3 ); - next[len - strlen(Ldeflin) - 3] = 0; - } - } - cdef = *def = 0; - *cur = -1; - *opts = initStrArr( 0 ); - while ((len = fGets( buf, sizeof(buf), f)) != -1) - if (buf[0] == ' ' && buf[1] == ' ' && buf[2] != ' ') { - if (buf[len - 1] == '*') { - *def = cdef; - len--; - } - for (; buf[len - 1] == ' '; len--); - *opts = addStrArr( *opts, buf + 2, len - 2 ); - if (!strcmp( (*opts)[cdef], next )) - *cur = cdef; - cdef++; - } - out: - if (pClose( f, pid )) { - if (*opts) - freeStrArr( *opts ); - return BO_IO; - } - return ret; -} - -static int -setLilo( const char *opt, SdRec *sdr ATTR_UNUSED ) -{ - char **opts; - int def, cur, ret, i; - - if ((ret = getLilo( &opts, &def, &cur )) != BO_OK) - return ret; - if (!*opt) - opt = 0; - else { - for (i = 0; opts[i]; i++) - if (!strcmp( opts[i], opt )) - goto oke; - freeStrArr( opts ); - return BO_NOENT; - } - oke: - freeStrArr( opts ); - return BO_OK; -} - -static void -commitLilo( void ) -{ - static const char *args[5] = { 0, "-w", "-R", 0, 0 }; - - args[0] = lilo; - args[3] = sdRec.osname; - runAndWait( (char **)args, environ ); -} - -static struct { - int (*get)( char ***, int *, int * ); - int (*set)( const char *, SdRec * ); - void (*commit)( void ); -} bootOpts[] = { - { getNull, setNull, 0 }, - { getGrub, setGrub, commitGrub }, - { getLilo, setLilo, commitLilo }, -}; - -int -getBootOptions( char ***opts, int *def, int *cur ) -{ - return bootOpts[bootManager].get( opts, def, cur ); -} - -int -setBootOption( const char *opt, SdRec *sdr ) -{ - int ret; - - if (sdr->osname) { - free( sdr->osname ); - sdr->osname = 0; - } - if (opt) { - if ((ret = bootOpts[bootManager].set( opt, sdr )) != BO_OK) - return ret; - if (!StrDup( &sdr->osname, opt )) - return BO_IO; /* BO_NOMEM */ - } - return BO_OK; -} - -void -commitBootOption( void ) -{ - if (sdRec.osname) { - bootOpts[bootManager].commit(); -/* - free( sdRec.osname ); - sdRec.osname = 0; -*/ - } -} - diff --git a/kdm/backend/choose.c b/kdm/backend/choose.c deleted file mode 100644 index ead841228..000000000 --- a/kdm/backend/choose.c +++ /dev/null @@ -1,1051 +0,0 @@ -/* - -Copyright 1990, 1998 The Open Group -Copyright 2002-2004 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * chooser backend - */ - -#include - -#ifdef XDMCP - -#include "dm.h" -#include "dm_error.h" -#include "dm_socket.h" - -#include - -#ifdef __svr4__ -# include -#endif -#include - -#include -#ifdef STREAMSCONN -# ifdef WINTCP /* NCR with Wollongong TCP */ -# include -# endif -# include -# include -# include -# include -#endif - -#if !defined(__GNU__) && !defined(__hpux) /* XXX __hpux might be wrong */ -# include -#endif - -#include - -typedef struct _IndirectUsers { - struct _IndirectUsers *next; - ARRAY8 client; - CARD16 connectionType; -} IndirectUsersRec, *IndirectUsersPtr; - -static IndirectUsersPtr indirectUsers; - -int -RememberIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - IndirectUsersPtr i; - - for (i = indirectUsers; i; i = i->next) - if (XdmcpARRAY8Equal( clientAddress, &i->client ) && - connectionType == i->connectionType) - return 1; - if (!(i = (IndirectUsersPtr)Malloc( sizeof(IndirectUsersRec) ))) - return 0; - if (!XdmcpCopyARRAY8( clientAddress, &i->client )) { - free( (char *)i ); - return 0; - } - i->connectionType = connectionType; - i->next = indirectUsers; - indirectUsers = i; - return 1; -} - -void -ForgetIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - IndirectUsersPtr *i, ni; - - for (i = &indirectUsers; *i; i = &(*i)->next) - if (XdmcpARRAY8Equal( clientAddress, &(*i)->client ) && - connectionType == (*i)->connectionType) - { - ni = (*i)->next; - XdmcpDisposeARRAY8( &(*i)->client ); - free( (char *)(*i) ); - (*i) = ni; - break; - } -} - -int -IsIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - IndirectUsersPtr i; - - for (i = indirectUsers; i; i = i->next) - if (XdmcpARRAY8Equal( clientAddress, &i->client ) && - connectionType == i->connectionType) - return 1; - return 0; -} - -typedef struct _Choices { - struct _Choices *next; - ARRAY8 client; - CARD16 connectionType; - ARRAY8 choice; - Time_t time; -} ChoiceRec, *ChoicePtr; - -static ChoicePtr choices; - -ARRAY8Ptr -IndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - ChoicePtr c, next, prev; - - prev = 0; - for (c = choices; c; c = next) { - next = c->next; - Debug( "choice checking timeout: %ld >? %d\n", - (long)(now - c->time), choiceTimeout ); - if (now - c->time > (Time_t)choiceTimeout) { - Debug( "timeout choice %ld > %d\n", - (long)(now - c->time), choiceTimeout ); - if (prev) - prev->next = next; - else - choices = next; - XdmcpDisposeARRAY8( &c->client ); - XdmcpDisposeARRAY8( &c->choice ); - free( (char *)c ); - } else { - if (XdmcpARRAY8Equal( clientAddress, &c->client ) && - connectionType == c->connectionType) - return &c->choice; - prev = c; - } - } - return 0; -} - -int -RegisterIndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType, - ARRAY8Ptr choice ) -{ - ChoicePtr c; - int insert; -#if 0 - int found = 0; -#endif - - Debug( "got indirect choice back\n" ); - for (c = choices; c; c = c->next) { - if (XdmcpARRAY8Equal( clientAddress, &c->client ) && - connectionType == c->connectionType) { -#if 0 - found = 1; -#endif - break; - } - } -#if 0 - if (!found) - return 0; -#endif - - insert = 0; - if (!c) { - insert = 1; - c = (ChoicePtr)Malloc( sizeof(ChoiceRec) ); - if (!c) - return 0; - c->connectionType = connectionType; - if (!XdmcpCopyARRAY8( clientAddress, &c->client )) { - free( (char *)c ); - return 0; - } - } else - XdmcpDisposeARRAY8( &c->choice ); - if (!XdmcpCopyARRAY8( choice, &c->choice )) { - XdmcpDisposeARRAY8( &c->client ); - free( (char *)c ); - return 0; - } - if (insert) { - c->next = choices; - choices = c; - } - c->time = now; - return 1; -} - -#if 0 -static void -RemoveIndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - ChoicePtr c, prev; - - prev = 0; - for (c = choices; c; c = c->next) { - if (XdmcpARRAY8Equal( clientAddress, &c->client ) && - connectionType == c->connectionType) - { - if (prev) - prev->next = c->next; - else - choices = c->next; - XdmcpDisposeARRAY8( &c->client ); - XdmcpDisposeARRAY8( &c->choice ); - free( (char *)c ); - return; - } - prev = c; - } -} -#endif - - -/* ####################### */ - - -typedef struct _hostAddr { - struct _hostAddr *next; - struct sockaddr *addr; - int addrlen; - xdmOpCode type; -} HostAddr; - -static HostAddr *hostAddrdb; - -typedef struct _hostName { - struct _hostName *next; - unsigned willing:1, alive:1; - ARRAY8 hostname, status; - CARD16 connectionType; - ARRAY8 hostaddr; -} HostName; - -static HostName *hostNamedb; - -static XdmcpBuffer directBuffer, broadcastBuffer; -static XdmcpBuffer buffer; - -static int socketFD; -#if defined(IPv6) && defined(AF_INET6) -static int socket6FD; -#endif - - -static void -doPingHosts() -{ - HostAddr *hosts; - - for (hosts = hostAddrdb; hosts; hosts = hosts->next) -#if defined(IPv6) && defined(AF_INET6) - XdmcpFlush( hosts->addr->sa_family == AF_INET6 ? socket6FD : socketFD, -#else - XdmcpFlush( socketFD, -#endif - hosts->type == QUERY ? &directBuffer : &broadcastBuffer, - (XdmcpNetaddr)hosts->addr, hosts->addrlen ); -} - -static int -addHostname( ARRAY8Ptr hostname, ARRAY8Ptr status, - struct sockaddr *addr, int will ) -{ - HostName **names, *name; - ARRAY8 hostAddr; - CARD16 connectionType; - - switch (addr->sa_family) { - case AF_INET: - hostAddr.data = - (CARD8 *)& ((struct sockaddr_in *)addr)->sin_addr; - hostAddr.length = 4; - connectionType = FamilyInternet; - break; -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - hostAddr.data = - (CARD8 *)&((struct sockaddr_in6 *)addr)->sin6_addr; - hostAddr.length = 16; - connectionType = FamilyInternet6; - break; -#endif - default: - hostAddr.data = (CARD8 *)""; - hostAddr.length = 0; - connectionType = FamilyLocal; - break; - } - for (names = &hostNamedb; *names; names = &(*names)->next) { - name = *names; - if (connectionType == name->connectionType && - XdmcpARRAY8Equal( &hostAddr, &name->hostaddr )) - { - if (XdmcpARRAY8Equal( status, &name->status )) - return 0; - XdmcpDisposeARRAY8( &name->status ); - XdmcpDisposeARRAY8( hostname ); - - GSendInt( G_Ch_ChangeHost ); - goto gotold; - } - } - if (!(name = (HostName *)Malloc( sizeof(*name) ))) - return 0; - if (hostname->length) { - switch (addr->sa_family) { - case AF_INET: -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: -#endif - { - struct hostent *hostent; - char *host; - - hostent = gethostbyaddr( (char *)hostAddr.data, - hostAddr.length, addr->sa_family ); - if (hostent) { - XdmcpDisposeARRAY8( hostname ); - host = hostent->h_name; - XdmcpAllocARRAY8( hostname, strlen( host ) ); - memmove( hostname->data, host, hostname->length ); - } - } - } - } - if (!XdmcpAllocARRAY8( &name->hostaddr, hostAddr.length )) { - free( (char *)name ); - return 0; - } - memmove( name->hostaddr.data, hostAddr.data, hostAddr.length ); - name->connectionType = connectionType; - name->hostname = *hostname; - - *names = name; - name->next = 0; - - GSendInt( G_Ch_AddHost ); - gotold: - name->alive = 1; - name->willing = will; - name->status = *status; - - GSendInt( (int)name ); /* just an id */ - GSendNStr( (char *)name->hostname.data, name->hostname.length ); - GSendNStr( (char *)name->status.data, name->status.length ); - GSendInt( will ); - - return 1; -} - -static void -disposeHostname( HostName *host ) -{ - XdmcpDisposeARRAY8( &host->hostname ); - XdmcpDisposeARRAY8( &host->hostaddr ); - XdmcpDisposeARRAY8( &host->status ); - free( (char *)host ); -} - -static void -emptyHostnames( void ) -{ - HostName *host, *nhost; - - for (host = hostNamedb; host; host = nhost) { - nhost = host->next; - disposeHostname( host ); - } - hostNamedb = 0; -} - -static void -receivePacket( int sfd ) -{ - XdmcpHeader header; - ARRAY8 authenticationName; - ARRAY8 hostname; - ARRAY8 status; - int saveHostname = 0; -#if defined(IPv6) && defined(AF_INET6) - struct sockaddr_storage addr; -#else - struct sockaddr addr; -#endif - int addrlen; - - addrlen = sizeof(addr); - if (!XdmcpFill( sfd, &buffer, (XdmcpNetaddr)&addr, &addrlen )) - return; - if (!XdmcpReadHeader( &buffer, &header )) - return; - if (header.version != XDM_PROTOCOL_VERSION) - return; - hostname.data = 0; - status.data = 0; - authenticationName.data = 0; - switch (header.opcode) { - case WILLING: - if (XdmcpReadARRAY8( &buffer, &authenticationName ) && - XdmcpReadARRAY8( &buffer, &hostname ) && - XdmcpReadARRAY8( &buffer, &status )) { - if (header.length == 6 + authenticationName.length + - hostname.length + status.length) { - if (addHostname( &hostname, &status, - (struct sockaddr *)&addr, 1 )) - saveHostname = 1; - } - } - XdmcpDisposeARRAY8( &authenticationName ); - break; - case UNWILLING: - if (XdmcpReadARRAY8( &buffer, &hostname ) && - XdmcpReadARRAY8( &buffer, &status )) { - if (header.length == 4 + hostname.length + status.length) { - if (addHostname( &hostname, &status, - (struct sockaddr *)&addr, 0 )) - saveHostname = 1; - } - } - break; - default: - break; - } - if (!saveHostname) { - XdmcpDisposeARRAY8( &hostname ); - XdmcpDisposeARRAY8( &status ); - } -} - -static void -addHostaddr( HostAddr **hosts, struct sockaddr *addr, int len, xdmOpCode type ) -{ - HostAddr *host; - - Debug( "adding host %[*hhu, type %d\n", len, addr, type ); - for (host = *hosts; host; host = host->next) - if (host->type == type && host->addr->sa_family == addr->sa_family) - switch (addr->sa_family) { - case AF_INET: - { - struct sockaddr_in *na = (struct sockaddr_in *)addr; - struct sockaddr_in *oa = (struct sockaddr_in *)host->addr; - if (na->sin_port == oa->sin_port && - na->sin_addr.s_addr == oa->sin_addr.s_addr) - return; - break; - } -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - { - struct sockaddr_in6 *na = (struct sockaddr_in6 *)addr; - struct sockaddr_in6 *oa = (struct sockaddr_in6 *)host->addr; - if (na->sin6_port == oa->sin6_port && - !memcmp( &na->sin6_addr, &oa->sin6_addr, 16 )) - return; - break; - } -#endif - default: /* ... */ - break; - } - Debug( " not dupe\n" ); - if (!(host = (HostAddr *)Malloc( sizeof(*host) ))) - return; - if (!(host->addr = (struct sockaddr *)Malloc( len ))) { - free( (char *)host ); - return; - } - memcpy( (char *)host->addr, (char *)addr, len ); - host->addrlen = len; - host->type = type; - host->next = *hosts; - *hosts = host; -} - -static void -registerHostaddr( struct sockaddr *addr, int len, xdmOpCode type ) -{ - addHostaddr( &hostAddrdb, addr, len, type ); -} - -static void -emptyPingHosts( void ) -{ - HostAddr *host, *nhost; - - for (host = hostAddrdb; host; host = nhost) { - nhost = host->next; - free( host->addr ); - free( host ); - } - hostAddrdb = 0; -} - -/* Handle variable length ifreq in BNR2 and later */ -#ifdef VARIABLE_IFREQ -# define ifr_size(p) \ - (sizeof(struct ifreq) + \ - (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \ - p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0)) -#else -# define ifr_size(p) (sizeof(struct ifreq)) -#endif - -#define IFC_REQ(ifc) ifc.ifc_req - -#ifndef SYSV_SIOCGIFCONF -# define ifioctl ioctl -#endif - -static void -registerBroadcastForPing( void ) -{ - struct sockaddr_in in_addr; - -#ifdef __GNU__ - in_addr.sin_addr.s_addr = htonl( 0xFFFFFFFF ); - in_addr.sin_port = htons( XDM_UDP_PORT ); - registerHostaddr( (struct sockaddr *)&in_addr, sizeof(in_addr), - BROADCAST_QUERY ); -#else /* __GNU__ */ - struct ifconf ifc; - register struct ifreq *ifr; - struct sockaddr broad_addr; - char buf[2048], *cp, *cplim; -# ifdef WINTCP /* NCR with Wollongong TCP */ - int ipfd; - struct ifconf *ifcp; - struct strioctl ioc; - int n; - - ifcp = (struct ifconf *)buf; - ifcp->ifc_buf = buf + 4; - ifcp->ifc_len = sizeof(buf) - 4; - - if ((ipfd = open( "/dev/ip", O_RDONLY )) < 0) { - t_error( "RegisterBroadcastForPing() t_open(/dev/ip) failed" ); - return; - } - - ioc.ic_cmd = IPIOC_GETIFCONF; - ioc.ic_timout = 60; - ioc.ic_len = sizeof(buf); - ioc.ic_dp = (char *)ifcp; - - if (ioctl( ipfd, (int)I_STR, (char *)&ioc ) < 0) { - perror( "RegisterBroadcastForPing() ioctl(I_STR(IPIOC_GETIFCONF)) failed" ); - close( ipfd ); - return; - } - - for (ifr = ifcp->ifc_req, n = ifcp->ifc_len / sizeof(struct ifreq); - --n >= 0; ifr++) -# else /* WINTCP */ - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - if (ifioctl(socketFD, (int)SIOCGIFCONF, (char *)&ifc) < 0) - return; - - cplim = (char *)IFC_REQ( ifc ) + ifc.ifc_len; - - for (cp = (char *)IFC_REQ( ifc ); cp < cplim; cp += ifr_size(ifr)) -# endif /* WINTCP */ - { -# ifndef WINTCP - ifr = (struct ifreq *)cp; -# endif - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - - broad_addr = ifr->ifr_addr; - ((struct sockaddr_in *)&broad_addr)->sin_addr.s_addr = - htonl( INADDR_BROADCAST ); -# ifdef SIOCGIFBRDADDR - { - struct ifreq broad_req; - - broad_req = *ifr; -# ifdef WINTCP /* NCR with Wollongong TCP */ - ioc.ic_cmd = IPIOC_GETIFFLAGS; - ioc.ic_timout = 0; - ioc.ic_len = sizeof(broad_req); - ioc.ic_dp = (char *)&broad_req; - - if (ioctl (ipfd, I_STR, (char *) &ioc ) != -1 && -# else /* WINTCP */ - if (ifioctl( socketFD, SIOCGIFFLAGS, (char *)&broad_req ) != - -1 && -# endif /* WINTCP */ - (broad_req.ifr_flags & IFF_BROADCAST) && - (broad_req.ifr_flags & IFF_UP)) - { - broad_req = *ifr; -# ifdef WINTCP /* NCR with Wollongong TCP */ - ioc.ic_cmd = IPIOC_GETIFBRDADDR; - ioc.ic_timout = 0; - ioc.ic_len = sizeof(broad_req); - ioc.ic_dp = (char *)&broad_req; - - if (ioctl( ipfd, I_STR, (char *) &ioc) != -1 ) -# else /* WINTCP */ - if (ifioctl( socketFD, SIOCGIFBRDADDR, (char *)&broad_req ) - != -1) -# endif /* WINTCP */ - broad_addr = broad_req.ifr_addr; - else - continue; - } else - continue; - } -# endif - in_addr = *((struct sockaddr_in *)&broad_addr); - in_addr.sin_port = htons( XDM_UDP_PORT ); -# ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -# endif - registerHostaddr( (struct sockaddr *)&in_addr, sizeof(in_addr), - BROADCAST_QUERY ); - } -#endif -} - -static int -makeSockAddrs( const char *name, HostAddr **hosts ) -{ -#if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai, *nai, hints; - bzero( &hints, sizeof(hints) ); - hints.ai_socktype = SOCK_DGRAM; - if (getaddrinfo( name, stringify( XDM_UDP_PORT ), &hints, &ai )) - return 0; - for (nai = ai; nai; nai = nai->ai_next) - if ((nai->ai_family == AF_INET) || (nai->ai_family == AF_INET6)) - addHostaddr( hosts, nai->ai_addr, nai->ai_addrlen, - (nai->ai_family == AF_INET ? - IN_MULTICAST( ((struct sockaddr_in *)nai->ai_addr)->sin_addr.s_addr ) : - IN6_IS_ADDR_MULTICAST( &((struct sockaddr_in6 *)nai->ai_addr)->sin6_addr )) ? - BROADCAST_QUERY : QUERY ); -#else - struct sockaddr_in in_addr; - /* Per RFC 1123, check first for IP address in dotted-decimal form */ - if ((in_addr.sin_addr.s_addr = inet_addr( name )) == (unsigned)-1) { - struct hostent *hostent; - if (!(hostent = gethostbyname( name )) || - hostent->h_addrtype != AF_INET) - return 0; - memcpy( &in_addr.sin_addr, hostent->h_addr, 4 ); - } - in_addr.sin_family = AF_INET; - in_addr.sin_port = htons( XDM_UDP_PORT ); -# ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -# endif - addHostaddr( hosts, (struct sockaddr *)&in_addr, sizeof(in_addr), -# ifdef IN_MULTICAST - IN_MULTICAST( in_addr.sin_addr.s_addr ) ? - BROADCAST_QUERY : -# endif - QUERY ); -#endif - return 1; -} - -/* - * Register the address for this host. - * Called for interactively specified hosts. - * The special names "BROADCAST" and "*" look up all the broadcast - * addresses on the local host. - */ - -static int -registerForPing( const char *name ) -{ - Debug( "manual host registration: %s\n", name ); - if (!strcmp( name, "BROADCAST" ) || !strcmp( name, "*" )) - registerBroadcastForPing(); - else if (!makeSockAddrs( name, &hostAddrdb )) - return 0; - return 1; -} - -/*ARGSUSED*/ -static void -AddChooserHost( - CARD16 connectionType, - ARRAY8Ptr addr, - char *closure ATTR_UNUSED ) -{ - if (connectionType == FamilyBroadcast) { - registerBroadcastForPing(); - return; - } - Debug( "internal host registration: %[*hhu, family %hx\n", - addr->length, addr->data, connectionType ); - if (connectionType == FamilyInternet) { - struct sockaddr_in in_addr; - in_addr.sin_family = AF_INET; - memmove( &in_addr.sin_addr, addr->data, 4 ); - in_addr.sin_port = htons( XDM_UDP_PORT ); -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -#endif - registerHostaddr( (struct sockaddr *)&in_addr, sizeof(in_addr), -#ifdef IN_MULTICAST - IN_MULTICAST( in_addr.sin_addr.s_addr ) ? - BROADCAST_QUERY : -#endif - QUERY ); - } -#if defined(IPv6) && defined(AF_INET6) - else if (connectionType == FamilyInternet6) { - struct sockaddr_in6 in6_addr; - in6_addr.sin6_family = AF_INET6; - memmove( &in6_addr.sin6_addr, addr->data, 16 ); - in6_addr.sin6_port = htons( XDM_UDP_PORT ); -#ifdef SIN6_LEN - in6_addr.sin6_len = sizeof(in6_addr); -#endif - registerHostaddr( (struct sockaddr *)&in6_addr, sizeof(in6_addr), - IN6_IS_ADDR_MULTICAST( &in6_addr.sin6_addr ) ? - BROADCAST_QUERY : QUERY ); - } -#endif -} - -static ARRAYofARRAY8 AuthenticationNames; - -#if 0 -static void RegisterAuthenticationName( char *name, int namelen ) -{ - ARRAY8Ptr authName; - if (!XdmcpReallocARRAYofARRAY8( &AuthenticationNames, - AuthenticationNames.length + 1 )) - return; - authName = &AuthenticationNames.data[AuthenticationNames.length - 1]; - if (!XdmcpAllocARRAY8( authName, namelen )) - return; - memmove( authName->data, name, namelen ); -} -#endif - -static int -initXDMCP() -{ - XdmcpHeader header; -#if 0 - int i; -#endif -#ifndef STREAMSCONN -#ifdef SO_BROADCAST - int soopts; -#endif -#endif - - header.version = XDM_PROTOCOL_VERSION; - header.length = 1; -#if 0 - for (i = 0; i < (int)AuthenticationNames.length; i++) - header.length += 2 + AuthenticationNames.data[i].length; -#endif - - header.opcode = (CARD16)BROADCAST_QUERY; - XdmcpWriteHeader( &broadcastBuffer, &header ); - XdmcpWriteARRAYofARRAY8( &broadcastBuffer, &AuthenticationNames ); - - header.opcode = (CARD16)QUERY; - XdmcpWriteHeader( &directBuffer, &header ); - XdmcpWriteARRAYofARRAY8( &directBuffer, &AuthenticationNames ); - -#if defined(STREAMSCONN) - if ((socketFD = t_open( "/dev/udp", O_RDWR, 0 )) < 0) - return 0; - - if (t_bind( socketFD, NULL, NULL ) < 0) { - t_close( socketFD ); - return 0; - } - - /* - * This part of the code looks contrived. It will actually fit in nicely - * when the CLTS part of Xtrans is implemented. - */ - { - struct netconfig *nconf; - - if ((nconf = getnetconfigent( "udp" )) == NULL) { - t_unbind( socketFD ); - t_close( socketFD ); - return 0; - } - - if (netdir_options( nconf, ND_SET_BROADCAST, socketFD, NULL )) { - freenetconfigent( nconf ); - t_unbind( socketFD ); - t_close( socketFD ); - return 0; - } - - freenetconfigent( nconf ); - } -#else - if ((socketFD = socket( AF_INET, SOCK_DGRAM, 0 )) < 0) - return 0; -#if defined(IPv6) && defined(AF_INET6) - socket6FD = socket( AF_INET6, SOCK_DGRAM, 0 ); -#endif -# ifdef SO_BROADCAST - soopts = 1; - if (setsockopt( socketFD, SOL_SOCKET, SO_BROADCAST, (char *)&soopts, - sizeof(soopts) ) < 0) - perror( "setsockopt" ); -# endif -#endif - - return 1; -} - -static void ATTR_NORETURN -chooseHost( int hid ) -{ - HostName *h; -#if defined(IPv6) && defined(AF_INET6) - char addr[64]; -#endif - - for (h = hostNamedb; h; h = h->next) - if ((int)h == hid) { - /* XXX error handling */ - GSet( &mstrtalk ); - if ((td->displayType & d_location) == dLocal) { - GSendInt( D_RemoteHost ); -#if defined(IPv6) && defined(AF_INET6) - switch (h->connectionType) { - case FamilyInternet6: - inet_ntop( AF_INET6, h->hostaddr.data, addr, sizeof(addr) ); - break; - default: /* FamilyInternet */ - inet_ntop( AF_INET, h->hostaddr.data, addr, sizeof(addr) ); - break; - } - GSendStr( addr ); -#else - GSendStr( inet_ntoa( *(struct in_addr *)h->hostaddr.data ) ); -#endif - CloseGreeter( FALSE ); - SessionExit( EX_REMOTE ); - } else { - GSendInt( D_ChooseHost ); - GSendArr( td->clientAddr.length, (char *)td->clientAddr.data ); - GSendInt( td->connectionType ); - GSendArr( h->hostaddr.length, (char *)h->hostaddr.data ); - CloseGreeter( FALSE ); - goto bout; - } - break; - } -/* LogError( "Internal error: chose unexisting host\n" ); */ - bout: - SessionExit( EX_NORMAL ); -} - -static void -directChooseHost( const char *name ) -{ - HostAddr *hosts = 0; - - if (!makeSockAddrs( name, &hosts )) - return; - GSendInt( G_Ch_Exit ); - /* XXX error handling */ - GSet( &mstrtalk ); - if ((td->displayType & d_location) == dLocal) { - GSendInt( D_RemoteHost ); - GSendStr( name ); - CloseGreeter( FALSE ); - SessionExit( EX_REMOTE ); - } else { - GSendInt( D_ChooseHost ); - GSendArr( td->clientAddr.length, (char *)td->clientAddr.data ); - GSendInt( td->connectionType ); - GSendArr( hosts->addrlen, (char *)hosts->addr ); - CloseGreeter( FALSE ); - SessionExit( EX_NORMAL ); - } -} - -#define PING_TRIES 3 - -int -DoChoose() -{ - HostName **hp, *h; - char *host, **hostp; - struct timeval *to, tnow, nextPing; - int pingTry, n, cmd; - FD_TYPE rfds; - static int xdmcpInited; - - OpenGreeter(); - GSendInt( G_Choose ); - switch (cmd = CtrlGreeterWait( TRUE )) { - case G_Ready: - break; - default: /* error */ - return cmd; - } - - if (!xdmcpInited) { - if (!initXDMCP()) - SessionExit( EX_UNMANAGE_DPY ); - xdmcpInited = 1; - } - if ((td->displayType & d_location) == dLocal) { - /* XXX the config reader should do the lookup already */ - for (hostp = td->chooserHosts; *hostp; hostp++) - if (!registerForPing( *hostp )) - LogError( "Unkown host %\"s specified for local chooser preload of display %s\n", *hostp, td->name ); - } else - ForEachChooserHost( &td->clientAddr, td->connectionType, - AddChooserHost, 0 ); - - GSendInt( 0 ); /* entering async mode signal */ - - reping: - for (h = hostNamedb; h; h = h->next) - h->alive = 0; - pingTry = 0; - goto pingen; - - for (;;) { - to = 0; - if (pingTry <= PING_TRIES) { - gettimeofday( &tnow, 0 ); - if (nextPing.tv_sec < tnow.tv_sec || - (nextPing.tv_sec == tnow.tv_sec && - nextPing.tv_usec < tnow.tv_usec)) { - if (pingTry < PING_TRIES) { - pingen: - pingTry++; - doPingHosts(); - gettimeofday( &tnow, 0 ); - nextPing = tnow; - nextPing.tv_sec++; - } else { - for (hp = &hostNamedb; *hp; ) - if (!(*hp)->alive) { - h = (*hp)->next; - disposeHostname( *hp ); - GSendInt( G_Ch_RemoveHost ); - GSendInt( (int)*hp ); /* just an id */ - *hp = h; - } else - hp = &(*hp)->next; - goto noto; - } - } - to = &tnow; - tnow.tv_sec = nextPing.tv_sec - tnow.tv_sec; - tnow.tv_usec = nextPing.tv_usec - tnow.tv_usec; - if (tnow.tv_usec < 0) { - tnow.tv_usec += 1000000; - tnow.tv_sec--; - } - } - noto: - FD_ZERO( &rfds ); - FD_SET( grtproc.pipe.rfd, &rfds ); - FD_SET( socketFD, &rfds ); -#if defined(IPv6) && defined(AF_INET6) - if (socket6FD >= 0) - FD_SET( socket6FD, &rfds ); -#endif - n = grtproc.pipe.rfd; - if (socketFD > n) - n = socketFD; -#if defined(IPv6) && defined(AF_INET6) - if (socket6FD > n) - n = socket6FD; -#endif - if (select( n + 1, &rfds, 0, 0, to ) > 0) { - if (FD_ISSET( grtproc.pipe.rfd, &rfds )) - switch (cmd = CtrlGreeterWait( FALSE )) { - case -1: - break; - case G_Ch_Refresh: - goto reping; - case G_Ch_RegisterHost: - host = GRecvStr(); - if (!registerForPing( host )) { - GSendInt( G_Ch_BadHost ); - GSendStr( host ); - } - free( host ); - goto reping; - case G_Ch_DirectChoice: - host = GRecvStr(); - directChooseHost( host ); - GSendInt( G_Ch_BadHost ); - GSendStr( host ); - free( host ); - break; - case G_Ready: - chooseHost( GRecvInt() ); - /* NOTREACHED */ - default: - emptyHostnames(); - emptyPingHosts(); - return cmd; - } - if (FD_ISSET( socketFD, &rfds )) - receivePacket( socketFD ); -#if defined(IPv6) && defined(AF_INET6) - if (socket6FD >= 0 && FD_ISSET( socket6FD, &rfds )) - receivePacket( socket6FD ); -#endif - } - } - -} - -#endif /* XDMCP */ diff --git a/kdm/backend/client.c b/kdm/backend/client.c deleted file mode 100644 index 0cf4e216b..000000000 --- a/kdm/backend/client.c +++ /dev/null @@ -1,1865 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2004 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * user verification and session initiation. - */ - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include -#include -#include -#ifdef SECURE_RPC -# include -# include -extern int key_setnet( struct key_netstarg *arg ); -#endif -#ifdef K5AUTH -# include -#endif -#ifdef HAVE_SETUSERCONTEXT -# include -#endif -#ifdef USE_PAM -# ifdef HAVE_PAM_PAM_APPL_H -# include -# else -# include -# endif -#elif defined(_AIX) /* USE_PAM */ -# include -# include -extern int loginrestrictions( const char *Name, const int Mode, const char *Tty, char **Msg ); -extern int loginfailed( const char *User, const char *Host, const char *Tty ); -extern int loginsuccess( const char *User, const char *Host, const char *Tty, char **Msg ); -#else /* USE_PAM || _AIX */ -# ifdef KERBEROS -# include -# include -# ifndef NO_AFS -# include -# endif -# endif -/* for nologin */ -# include -# include -/* for expiration */ -# include -#endif /* USE_PAM || _AIX */ -#ifdef HAVE_SHADOW -# include -#endif -#include - -#ifdef WITH_CONSOLE_KIT -#include "consolekit.h" -#endif - -#define AU_FAILED 0 -#define AU_SUCCESS 1 -#ifdef HAVE_LIBAUDIT -#include -#else -#define log_to_audit_system(l,h,d,s) do { ; } while (0) -#endif - -#ifdef WITH_CONSOLE_KIT -#include "consolekit.h" -#endif - -/* - * Session data, mostly what struct verify_info was for - */ -char *curuser; -char *curpass; -char *curtype; -char *newpass; -char **userEnviron; -char **systemEnviron; -static int curuid; -static int curgid; -int cursource; - -char *dmrcuser; -char *curdmrc; -char *newdmrc; - -static struct passwd *p; -#ifdef HAVE_SETUSERCONTEXT -# ifdef HAVE_LOGIN_GETCLASS -login_cap_t *lc; -# else -struct login_cap *lc; -# endif -#endif -#ifdef USE_PAM -static pam_handle_t *pamh; -#elif defined(_AIX) -static char tty[16], hostname[100]; -#else -# ifdef USESHADOW -static struct spwd *sp; -# endif -# ifdef KERBEROS -static char krbtkfile[MAXPATHLEN]; -# endif -#endif - -#define V_RET_AUTH \ - do { \ - PrepErrorGreet (); \ - GSendInt (V_AUTH); \ - return 0; \ - } while(0) - -#define V_RET_FAIL(m) \ - do { \ - PrepErrorGreet (); \ - GSendInt (V_MSG_ERR); \ - GSendStr (m); \ - GSendInt (V_FAIL); \ - return 0; \ - } while(0) - -#ifdef USE_PAM - -# ifdef PAM_MESSAGE_NONCONST -typedef struct pam_message pam_message_type; -typedef void *pam_gi_type; -# else -typedef const struct pam_message pam_message_type; -typedef const void *pam_gi_type; -# endif - -struct pam_data { - GConvFunc gconv; - int usecur; - int abort; -}; - -static int -PAM_conv( int num_msg, - pam_message_type **msg, - struct pam_response **resp, - void *appdata_ptr ) -{ - int count; - struct pam_response *reply; - struct pam_data *pd = (struct pam_data *)appdata_ptr; - - if (!(reply = Calloc( num_msg, sizeof(*reply) ))) - return PAM_CONV_ERR; - - ReInitErrorLog(); - Debug( "PAM_conv\n" ); - for (count = 0; count < num_msg; count++) - switch (msg[count]->msg_style) { - case PAM_TEXT_INFO: - Debug( " PAM_TEXT_INFO: %s\n", msg[count]->msg ); - PrepErrorGreet(); - GSendInt( V_MSG_INFO ); - GSendStr( msg[count]->msg ); - continue; - case PAM_ERROR_MSG: - Debug( " PAM_ERROR_MSG: %s\n", msg[count]->msg ); - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( msg[count]->msg ); - continue; - default: - /* could do better error handling here, but see below ... */ - if (pd->usecur) { - switch (msg[count]->msg_style) { - /* case PAM_PROMPT_ECHO_ON: cannot happen */ - case PAM_PROMPT_ECHO_OFF: - Debug( " PAM_PROMPT_ECHO_OFF (usecur): %s\n", msg[count]->msg ); - if (!curpass) - pd->gconv( GCONV_PASS, 0 ); - StrDup( &reply[count].resp, curpass ); - break; - default: - LogError( "Unknown PAM message style <%d>\n", msg[count]->msg_style ); - goto conv_err; - } - } else { - switch (msg[count]->msg_style) { - case PAM_PROMPT_ECHO_ON: - Debug( " PAM_PROMPT_ECHO_ON: %s\n", msg[count]->msg ); - reply[count].resp = pd->gconv( GCONV_NORMAL, msg[count]->msg ); - break; - case PAM_PROMPT_ECHO_OFF: - Debug( " PAM_PROMPT_ECHO_OFF: %s\n", msg[count]->msg ); - reply[count].resp = pd->gconv( GCONV_HIDDEN, msg[count]->msg ); - break; -#ifdef PAM_BINARY_PROMPT - case PAM_BINARY_PROMPT: - Debug( " PAM_BINARY_PROMPT\n" ); - reply[count].resp = pd->gconv( GCONV_BINARY, msg[count]->msg ); - break; -#endif - default: - LogError( "Unknown PAM message style <%d>\n", msg[count]->msg_style ); - goto conv_err; - } - } - if (!reply[count].resp) { - Debug( " PAM_conv aborted\n" ); - pd->abort = TRUE; - goto conv_err; - } - reply[count].resp_retcode = PAM_SUCCESS; /* unused in linux-pam */ - } - Debug( " PAM_conv success\n" ); - *resp = reply; - return PAM_SUCCESS; - - conv_err: - for (; count >= 0; count--) - if (reply[count].resp) - switch (msg[count]->msg_style) { - case PAM_PROMPT_ECHO_ON: - case PAM_PROMPT_ECHO_OFF: /* could wipe ... */ -#ifdef PAM_BINARY_PROMPT - case PAM_BINARY_PROMPT: /* ... that too ... */ -#endif - free( reply[count].resp ); - break; - } - free( reply ); - return PAM_CONV_ERR; -} - -static int -PAM_conv_null( int num_msg, - pam_message_type **msg, - struct pam_response **resp, - void *appdata_ptr ATTR_UNUSED ) -{ - int count; - struct pam_response *reply; - - if (!(reply = Calloc( num_msg, sizeof(*reply) ))) - return PAM_CONV_ERR; - - ReInitErrorLog(); - Debug( "PAM_conv_null\n" ); - for (count = 0; count < num_msg; count++) { - switch (msg[count]->msg_style) { - case PAM_TEXT_INFO: - Debug( " PAM_TEXT_INFO: %s\n", msg[count]->msg ); - continue; - case PAM_ERROR_MSG: - LogError( "PAM error message: %s\n", msg[count]->msg ); - continue; - default: - /* unknown */ - Debug( " PAM_<%d>\n", msg[count]->msg_style ); - free( reply ); - return PAM_CONV_ERR; - } - reply[count].resp_retcode = PAM_SUCCESS; /* unused in linux-pam */ - } - Debug( " PAM_conv_null success\n" ); - *resp = reply; - return PAM_SUCCESS; -} - -# ifdef PAM_FAIL_DELAY -static void -fail_delay( int retval ATTR_UNUSED, unsigned usec_delay ATTR_UNUSED, - void *appdata_ptr ATTR_UNUSED ) -{} -# endif - - /** - * log_to_audit_system: - * @login: Name of user - * @hostname: Name of host machine - * @tty: Name of display - * @success: 1 for success, 0 for failure - * - * Logs the success or failure of the login attempt with the linux kernel - * audit system. The intent is to capture failed events where the user - * fails authentication or otherwise is not permitted to login. There are - * many other places where pam could potentially fail and cause login to - * fail, but these are system failures rather than the signs of an account - * being hacked. - * - * Returns nothing. - */ - -#ifdef HAVE_LIBAUDIT -static void -log_to_audit_system (const char *loginname, - const char *hostname, - const char *tty, - int success) -{ - struct passwd *pw; - char buf[64]; - int audit_fd; - - audit_fd = audit_open(); - if (loginname) - pw = getpwnam(loginname); - else { - loginname = "unknown"; - pw = NULL; - } - Debug("log_to_audit %p %s\n", pw, loginname); - - if (pw) { - snprintf(buf, sizeof(buf), "uid=%d", pw->pw_uid); - audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, - buf, hostname, NULL, tty, (int)success); - } else { - snprintf(buf, sizeof(buf), "acct=%s", loginname); - audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, - buf, hostname, NULL, tty, (int)success); - } - close(audit_fd); -} -#endif - -static int -doPAMAuth( const char *psrv, struct pam_data *pdata ) -{ - pam_gi_type pitem; - struct pam_conv pconv; - int pretc; - - pdata->abort = FALSE; - pconv.conv = PAM_conv; - pconv.appdata_ptr = (void *)pdata; - Debug( " PAM service %s\n", psrv ); - if ((pretc = pam_start( psrv, curuser, &pconv, &pamh )) != PAM_SUCCESS) - goto pam_bail2; - if ((pretc = pam_set_item( pamh, PAM_TTY, td->name )) != PAM_SUCCESS) { - pam_bail: - pam_end( pamh, pretc ); - pamh = 0; - pam_bail2: - ReInitErrorLog(); - LogError( "PAM error: %s\n", pam_strerror( 0, pretc ) ); - V_RET_FAIL( 0 ); - } - if ((td->displayType & d_location) == dForeign) { - char *cp = strchr( td->name, ':' ); - *cp = 0; - pretc = pam_set_item( pamh, PAM_RHOST, td->name ); - *cp = ':'; - if (pretc != PAM_SUCCESS) - goto pam_bail; - } -# ifdef __sun__ /* Only Solaris <= 9, but checking it does not seem worth it. */ - else if (pam_set_item( pamh, PAM_RHOST, 0 ) != PAM_SUCCESS) - goto pam_bail; -# endif -# ifdef PAM_FAIL_DELAY - pam_set_item( pamh, PAM_FAIL_DELAY, (void *)fail_delay ); -# endif - ReInitErrorLog(); - - Debug( " pam_authenticate() ...\n" ); - pretc = pam_authenticate( pamh, - td->allowNullPasswd ? 0 : PAM_DISALLOW_NULL_AUTHTOK ); - ReInitErrorLog(); - Debug( " pam_authenticate() returned: %s\n", pam_strerror( pamh, pretc ) ); - if (pdata->abort) { - pam_end( pamh, PAM_SUCCESS ); - pamh = 0; - return 0; - } - if (!curuser) { - Debug( " asking PAM for user ...\n" ); - pam_get_item( pamh, PAM_USER, &pitem ); - ReInitErrorLog(); - StrDup( &curuser, (const char *)pitem ); - GSendInt( V_PUT_USER ); - GSendStr( curuser ); - } - if (pretc != PAM_SUCCESS) { - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - switch (pretc) { - case PAM_USER_UNKNOWN: - case PAM_AUTH_ERR: - case PAM_MAXTRIES: /* should handle this better ... */ - case PAM_AUTHINFO_UNAVAIL: /* returned for unknown users ... bogus */ - pam_end( pamh, pretc ); - pamh = 0; - V_RET_AUTH; - default: - pam_end( pamh, pretc ); - pamh = 0; - V_RET_FAIL( 0 ); - } - } - return 1; -} - -#endif /* USE_PAM */ - -static int -#if defined(USE_PAM) || defined(_AIX) -AccNoPass( const char *un ) -{ - struct passwd *pw = 0; -# ifdef HAVE_SHADOW /* (sic!) - not USESHADOW */ - struct spwd *spw; -# endif -#else -AccNoPass( const char *un, struct passwd *pw ) -{ -#endif - struct group *gr; - char **fp; - int hg; - - if (!*un) - return 0; - - if (cursource != PWSRC_MANUAL) - return 1; - - for (hg = 0, fp = td->noPassUsers; *fp; fp++) - if (**fp == '@') - hg = 1; - else if (!strcmp( un, *fp )) - return 1; - else if (!strcmp( "*", *fp )) { -#if defined(USE_PAM) || defined(_AIX) - if (!(pw = getpwnam( un ))) - return 0; - if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*') - continue; -# ifdef HAVE_SHADOW /* (sic!) - not USESHADOW */ - if ((spw = getspnam( un )) && - (spw->sp_pwdp[0] == '!' || spw->sp_pwdp[0] == '*')) - continue; -# endif -#endif - if (pw->pw_uid) - return 1; - } - -#if defined(USE_PAM) || defined(_AIX) - if (hg && (pw || (pw = getpwnam( un )))) { -#else - if (hg) { -#endif - for (setgrent(); (gr = getgrent()); ) - for (fp = td->noPassUsers; *fp; fp++) - if (**fp == '@' && !strcmp( gr->gr_name, *fp + 1 )) { - if (pw->pw_gid == gr->gr_gid) { - endgrent(); - return 1; - } - for (; *gr->gr_mem; gr->gr_mem++) - if (!strcmp( un, *gr->gr_mem )) { - endgrent(); - return 1; - } - } - endgrent(); - } - - return 0; -} - -#if !defined(USE_PAM) && !defined(_AIX) && defined(HAVE_SETUSERCONTEXT) -# define LC_RET0 do { login_close(lc); return 0; } while(0) -#else -# define LC_RET0 return 0 -#endif - -int -Verify( GConvFunc gconv, int rootok ) -{ -#ifdef USE_PAM - const char *psrv; - struct pam_data pdata; - int pretc, pnopass; - char psrvb[64]; -#elif defined(_AIX) - char *msg, *curret; - int i, reenter; -#else - struct stat st; - const char *nolg; - char *buf; - int fd; -# ifdef HAVE_GETUSERSHELL - char *s; -# endif -# if defined(HAVE_STRUCT_PASSWD_PW_EXPIRE) || defined(USESHADOW) - int tim, expir, warntime, quietlog; -# endif -#endif - - Debug( "Verify ...\n" ); - -#ifdef USE_PAM - - pnopass = FALSE; - if (!strcmp( curtype, "classic" )) { - if (!gconv( GCONV_USER, 0 )) - return 0; - if (AccNoPass( curuser )) { - gconv( GCONV_PASS_ND, 0 ); - if (!*curpass) { - pnopass = TRUE; - sprintf( psrvb, "%.31s-np", PAMService ); - psrv = psrvb; - } else - psrv = PAMService; - } else - psrv = PAMService; - pdata.usecur = TRUE; - } else if (!strcmp( curtype, "pam" )) { - psrv = PAMService; - pdata.usecur = FALSE; - } else { - sprintf( psrvb, "%.31s-%.31s", PAMService, curtype ); - psrv = psrvb; - pdata.usecur = FALSE; - } - pdata.gconv = gconv; - if (!doPAMAuth( psrv, &pdata )) - return 0; - -#elif defined(_AIX) - - if ((td->displayType & d_location) == dForeign) { - char *tmpch; - strncpy( hostname, td->name, sizeof(hostname) - 1 ); - hostname[sizeof(hostname)-1] = '\0'; - if ((tmpch = strchr( hostname, ':' ))) - *tmpch = '\0'; - } else - hostname[0] = '\0'; - - /* tty names should only be 15 characters long */ -# if 0 - for (i = 0; i < 15 && td->name[i]; i++) { - if (td->name[i] == ':' || td->name[i] == '.') - tty[i] = '_'; - else - tty[i] = td->name[i]; - } - tty[i] = '\0'; -# else - memcpy( tty, "/dev/xdm/", 9 ); - for (i = 0; i < 6 && td->name[i]; i++) { - if (td->name[i] == ':' || td->name[i] == '.') - tty[9 + i] = '_'; - else - tty[9 + i] = td->name[i]; - } - tty[9 + i] = '\0'; -# endif - - if (!strcmp( curtype, "classic" )) { - if (!gconv( GCONV_USER, 0 )) - return 0; - if (AccNoPass( curuser )) { - gconv( GCONV_PASS_ND, 0 ); - if (!*curpass) { - Debug( "accepting despite empty password\n" ); - goto done; - } - } else - if (!gconv( GCONV_PASS, 0 )) - return 0; - enduserdb(); - msg = NULL; - if ((i = authenticate( curuser, curpass, &reenter, &msg ))) { - Debug( "authenticate() failed: %s\n", msg ); - if (msg) - free( msg ); - loginfailed( curuser, hostname, tty ); - if (i == ENOENT || i == ESAD) - V_RET_AUTH; - else - V_RET_FAIL( 0 ); - } - if (reenter) { - LogError( "authenticate() requests more data: %s\n", msg ); - free( msg ); - V_RET_FAIL( 0 ); - } - } else if (!strcmp( curtype, "generic" ) || !strcmp(curtype, "pam")) { - if (!gconv( GCONV_USER, 0 )) - return 0; - for (curret = 0;;) { - msg = NULL; - if ((i = authenticate( curuser, curret, &reenter, &msg ))) { - Debug( "authenticate() failed: %s\n", msg ); - if (msg) - free( msg ); - loginfailed( curuser, hostname, tty ); - if (i == ENOENT || i == ESAD) - V_RET_AUTH; - else - V_RET_FAIL( 0 ); - } - if (curret) - free( curret ); - if (!reenter) - break; - if (!(curret = gconv( GCONV_HIDDEN, msg ))) - return 0; - free( msg ); - } - } else { - LogError( "Unsupported authentication type %\"s requested\n", curtype ); - V_RET_FAIL( 0 ); - } - if (msg) { - PrepErrorGreet(); - GSendInt( V_MSG_INFO ); - GSendStr( msg ); - free( msg ); - } - - done: - -#else - - if (strcmp( curtype, "classic" )) { - LogError( "Unsupported authentication type %\"s requested\n", curtype ); - V_RET_FAIL( 0 ); - } - - if (!gconv( GCONV_USER, 0 )) - return 0; - - if (!(p = getpwnam( curuser ))) { - Debug( "getpwnam() failed.\n" ); - gconv( GCONV_PASS, 0 ); - V_RET_AUTH; - } - if (p->pw_passwd[0] == '!' || p->pw_passwd[0] == '*') { - Debug( "account is locked\n" ); - gconv( GCONV_PASS, 0 ); - V_RET_AUTH; - } - -# ifdef USESHADOW - if ((sp = getspnam( curuser ))) { - p->pw_passwd = sp->sp_pwdp; - if (p->pw_passwd[0] == '!' || p->pw_passwd[0] == '*') { - Debug( "account is locked\n" ); - gconv( GCONV_PASS, 0 ); - V_RET_AUTH; - } - } else - Debug( "getspnam() failed: %m. Are you root?\n" ); -# endif - - if (!*p->pw_passwd) { - if (!td->allowNullPasswd) { - Debug( "denying user with empty password\n" ); - gconv( GCONV_PASS, 0 ); - V_RET_AUTH; - } - goto nplogin; - } - - if (AccNoPass( curuser, p )) { - nplogin: - gconv( GCONV_PASS_ND, 0 ); - if (!*curpass) { - Debug( "accepting password-less login\n" ); - goto done; - } - } else - if (!gconv( GCONV_PASS, 0 )) - return 0; - -# ifdef KERBEROS - if (p->pw_uid) { - int ret; - char realm[REALM_SZ]; - - if (krb_get_lrealm( realm, 1 )) { - LogError( "Can't get KerberosIV realm.\n" ); - V_RET_FAIL( 0 ); - } - - sprintf( krbtkfile, "%s.%.*s", TKT_ROOT, MAXPATHLEN - strlen( TKT_ROOT ) - 2, td->name ); - krb_set_tkt_string( krbtkfile ); - unlink( krbtkfile ); - - ret = krb_verify_user( curuser, "", realm, curpass, 1, "rcmd" ); - if (ret == KSUCCESS) { - chown( krbtkfile, p->pw_uid, p->pw_gid ); - Debug( "KerberosIV verify succeeded\n" ); - goto done; - } else if (ret != KDC_PR_UNKNOWN && ret != SKDC_CANT) { - LogError( "KerberosIV verification failure %\"s for %s\n", - krb_get_err_text( ret ), curuser ); - krbtkfile[0] = '\0'; - V_RET_FAIL( 0 ); - } - Debug( "KerberosIV verify failed: %s\n", krb_get_err_text( ret ) ); - } - krbtkfile[0] = '\0'; -# endif /* KERBEROS */ - -# if defined(ultrix) || defined(__ultrix__) - if (authenticate_user( p, curpass, NULL ) < 0) -# elif defined(HAVE_CRYPT) - if (strcmp( crypt( curpass, p->pw_passwd ), p->pw_passwd )) -# else - if (strcmp( curpass, p->pw_passwd )) -# endif - { - Debug( "password verify failed\n" ); - V_RET_AUTH; - } - - done: - -#endif /* !defined(USE_PAM) && !defined(_AIX) */ - - Debug( "restrict %s ...\n", curuser ); - -#if defined(USE_PAM) || defined(_AIX) - if (!(p = getpwnam( curuser ))) { - LogError( "getpwnam(%s) failed.\n", curuser ); - V_RET_FAIL( 0 ); - } -#endif - if (!p->pw_uid) { - if (!rootok && !td->allowRootLogin) - V_RET_FAIL( "Root logins are not allowed" ); - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - return 1; /* don't deny root to log in */ - } - -#ifdef USE_PAM - - Debug( " pam_acct_mgmt() ...\n" ); - pretc = pam_acct_mgmt( pamh, 0 ); - ReInitErrorLog(); - Debug( " pam_acct_mgmt() returned: %s\n", pam_strerror( pamh, pretc ) ); - if (pretc == PAM_NEW_AUTHTOK_REQD) { - pdata.usecur = FALSE; - pdata.gconv = conv_interact; - /* pam will have output a message already, so no PrepErrorGreet () */ - if (gconv != conv_interact || pnopass) { - pam_end( pamh, PAM_SUCCESS ); - pamh = 0; - GSendInt( V_CHTOK_AUTH ); - /* this cannot auth the wrong user, as only classic auths get here */ - while (!doPAMAuth( PAMService, &pdata )) - if (pdata.abort) - return 0; - GSendInt( V_PRE_OK ); - } else - GSendInt( V_CHTOK ); - for (;;) { - Debug( " pam_chauthtok() ...\n" ); - pretc = pam_chauthtok( pamh, PAM_CHANGE_EXPIRED_AUTHTOK ); - ReInitErrorLog(); - Debug( " pam_chauthtok() returned: %s\n", pam_strerror( pamh, pretc ) ); - if (pdata.abort) { - pam_end( pamh, PAM_SUCCESS ); - pamh = 0; - return 0; - } - if (pretc == PAM_SUCCESS) - break; - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - /* effectively there is only PAM_AUTHTOK_ERR */ - GSendInt( V_FAIL ); - } - if (curpass) - free( curpass ); - curpass = newpass; - newpass = 0; - } else if (pretc != PAM_SUCCESS) { - pam_end( pamh, pretc ); - pamh = 0; - V_RET_AUTH; - } - -#elif defined(_AIX) /* USE_PAM */ - - msg = NULL; - if (loginrestrictions( curuser, - ((td->displayType & d_location) == dForeign) ? S_RLOGIN : S_LOGIN, - tty, &msg ) == -1) - { - Debug( "loginrestrictions() - %s\n", msg ? msg : "error" ); - loginfailed( curuser, hostname, tty ); - PrepErrorGreet(); - if (msg) { - GSendInt( V_MSG_ERR ); - GSendStr( msg ); - } - GSendInt( V_AUTH ); - return 0; - } - if (msg) - free( (void *)msg ); - -#endif /* USE_PAM || _AIX */ - -#ifndef _AIX - -# ifdef HAVE_SETUSERCONTEXT -# ifdef HAVE_LOGIN_GETCLASS - lc = login_getclass( p->pw_class ); -# else - lc = login_getpwclass( p ); -# endif - if (!lc) - V_RET_FAIL( 0 ); - - p->pw_shell = login_getcapstr( lc, "shell", p->pw_shell, p->pw_shell ); -# endif - -# ifndef USE_PAM - -/* restrict_expired */ -# if defined(HAVE_STRUCT_PASSWD_PW_EXPIRE) || defined(USESHADOW) - -# if !defined(HAVE_STRUCT_PASSWD_PW_EXPIRE) || (!defined(HAVE_SETUSERCONTEXT) && defined(USESHADOW)) - if (sp) -# endif - { - -# define DEFAULT_WARN (2L * 7L) /* Two weeks */ - - tim = time( NULL ) / 86400L; - -# ifdef HAVE_SETUSERCONTEXT - quietlog = login_getcapbool( lc, "hushlogin", 0 ); - warntime = login_getcaptime( lc, "warnexpire", - DEFAULT_WARN * 86400L, - DEFAULT_WARN * 86400L ) / 86400L; -# else - quietlog = 0; -# ifdef USESHADOW - warntime = sp->sp_warn != -1 ? sp->sp_warn : DEFAULT_WARN; -# else - warntime = DEFAULT_WARN; -# endif -# endif - -# ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE - if (p->pw_expire) { - expir = p->pw_expire / 86400L; -# else - if (sp->sp_expire != -1) { - expir = sp->sp_expire; -# endif - if (tim > expir) { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( "Your account has expired;" - " please contact your system administrator" ); - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - GSendInt( V_FAIL ); - LC_RET0; - } else if (tim > (expir - warntime) && !quietlog) { - ASPrintf( &buf, - "Warning: your account will expire in %d day(s)", - expir - tim ); - if (buf) { - PrepErrorGreet(); - GSendInt( V_MSG_INFO ); - GSendStr( buf ); - free( buf ); - } - } - } - -# ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE - if (p->pw_change) { - expir = p->pw_change / 86400L; -# else - if (!sp->sp_lstchg) { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( "You are required to change your password immediately" - " (root enforced)" ); - /* XXX todo password change */ - GSendInt( V_FAIL ); - LC_RET0; - } else if (sp->sp_max != -1) { - expir = sp->sp_lstchg + sp->sp_max; - if (sp->sp_inact != -1 && tim > expir + sp->sp_inact) { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( "Your account has expired;" - " please contact your system administrator" ); - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - GSendInt( V_FAIL ); - LC_RET0; - } -# endif - if (tim > expir) { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( "You are required to change your password immediately" - " (password aged)" ); - /* XXX todo password change */ - GSendInt( V_FAIL ); - LC_RET0; - } else if (tim > (expir - warntime) && !quietlog) { - ASPrintf( &buf, - "Warning: your password will expire in %d day(s)", - expir - tim ); - if (buf) { - PrepErrorGreet(); - GSendInt( V_MSG_INFO ); - GSendStr( buf ); - free( buf ); - } - } - } - - } - -# endif /* HAVE_STRUCT_PASSWD_PW_EXPIRE || USESHADOW */ - -/* restrict_nologin */ -# ifndef _PATH_NOLOGIN -# define _PATH_NOLOGIN "/etc/nologin" -# endif - - if (( -# ifdef HAVE_SETUSERCONTEXT - /* Do we ignore a nologin file? */ - !login_getcapbool( lc, "ignorenologin", 0 )) && - (!stat( (nolg = login_getcapstr( lc, "nologin", "", NULL )), &st ) || -# endif - !stat( (nolg = _PATH_NOLOGIN), &st ))) - { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - if (st.st_size && (fd = open( nolg, O_RDONLY )) >= 0) { - if ((buf = Malloc( st.st_size + 1 ))) { - if (read( fd, buf, st.st_size ) == st.st_size) { - buf[st.st_size] = 0; - GSendStr( buf ); - free( buf ); - close( fd ); - GSendInt( V_FAIL ); - LC_RET0; - } - free( buf ); - } - close( fd ); - } - GSendStr( "Logins are not allowed at the moment.\nTry again later" ); - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - GSendInt( V_FAIL ); - LC_RET0; - } - -/* restrict_time */ -# if defined(HAVE_SETUSERCONTEXT) && defined(HAVE_AUTH_TIMEOK) - if (!auth_timeok( lc, time( NULL ) )) { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( "You are not allowed to login at the moment" ); - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - GSendInt( V_FAIL ); - LC_RET0; - } -# endif - -# ifdef HAVE_GETUSERSHELL - for (;;) { - if (!(s = getusershell())) { - Debug( "shell not in /etc/shells\n" ); - endusershell(); - V_RET_FAIL( "Your login shell is not listed in /etc/shells" ); - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - } - if (!strcmp( s, p->pw_shell )) { - endusershell(); - break; - } - } -# endif - -# endif /* !USE_PAM */ - -/* restrict_nohome */ -# ifdef HAVE_SETUSERCONTEXT - if (login_getcapbool( lc, "requirehome", 0 )) { - struct stat st; - if (!*p->pw_dir || stat( p->pw_dir, &st ) || st.st_uid != p->pw_uid) { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( "Home folder not available" ); - GSendInt( V_FAIL ); - LC_RET0; - } - } -# endif - -#endif /* !_AIX */ - - return 1; - -} - - -static const char *envvars[] = { - "TZ", /* SYSV and SVR4, but never hurts */ -#ifdef _AIX - "AUTHSTATE", /* for kerberos */ -#endif - NULL -}; - - -#if defined(USE_PAM) && defined(HAVE_INITGROUPS) -static int num_saved_gids; -static gid_t *saved_gids; - -static int -saveGids( void ) -{ - num_saved_gids = getgroups( 0, 0 ); - if (!(saved_gids = Malloc( sizeof(gid_t) * num_saved_gids ))) - return 0; - if (getgroups( num_saved_gids, saved_gids ) < 0) { - LogError( "saving groups failed: %m\n" ); - return 0; - } - return 1; -} - -static int -restoreGids( void ) -{ - if (setgroups( num_saved_gids, saved_gids ) < 0) { - LogError( "restoring groups failed: %m\n" ); - return 0; - } - if (setgid( p->pw_gid ) < 0) { - LogError( "restoring gid failed: %m\n" ); - return 0; - } - return 1; -} -#endif /* USE_PAM && HAVE_INITGROUPS */ - -static int -resetGids( void ) -{ -#ifdef HAVE_INITGROUPS - if (setgroups( 0, &p->pw_gid /* anything */ ) < 0) { - LogError( "restoring groups failed: %m\n" ); - return 0; - } -#endif - if (setgid( 0 ) < 0) { - LogError( "restoring gid failed: %m\n" ); - return 0; - } - return 1; -} - -static int -SetGid( const char *name, int gid ) -{ - if (setgid( gid ) < 0) { - LogError( "setgid(%d) (user %s) failed: %m\n", gid, name ); - return 0; - } -#ifdef HAVE_INITGROUPS - if (initgroups( name, gid ) < 0) { - LogError( "initgroups for %s failed: %m\n", name ); - setgid( 0 ); - return 0; - } -#endif /* QNX4 doesn't support multi-groups, no initgroups() */ - return 1; -} - -static int -SetUid( const char *name, int uid ) -{ - if (setuid( uid ) < 0) { - LogError( "setuid(%d) (user %s) failed: %m\n", uid, name ); - return 0; - } - return 1; -} - -static int -SetUser( const char *name, int uid, int gid ) -{ - if (SetGid( name, gid )) { - if (SetUid( name, uid )) - return 1; - resetGids(); - } - return 0; -} - -#if defined(SECURE_RPC) || defined(K5AUTH) -static void -NukeAuth( int len, const char *name ) -{ - int i; - - for (i = 0; i < td->authNum; i++) - if (td->authorizations[i]->name_length == len && - !memcmp( td->authorizations[i]->name, name, len )) - { - memcpy( &td->authorizations[i], &td->authorizations[i+1], - sizeof(td->authorizations[i]) * (--td->authNum - i) ); - break; - } -} -#endif - -static void -mergeSessionArgs( int cansave ) -{ - char *mfname; - const char *fname; - int i, needsave; - - mfname = 0; - fname = ".dmrc"; - if ((!curdmrc || newdmrc) && *dmrcDir) - if (StrApp( &mfname, dmrcDir, "/", curuser, fname, (char *)0 )) - fname = mfname; - needsave = 0; - if (!curdmrc) { - curdmrc = iniLoad( fname ); - if (!curdmrc) { - StrDup( &curdmrc, "[Desktop]\nSession=default\n" ); - needsave = 1; - } - } - if (newdmrc) { - curdmrc = iniMerge( curdmrc, newdmrc ); - needsave = 1; - } - if (needsave && cansave) - if (!iniSave( curdmrc, fname ) && errno == ENOENT && mfname) { - for (i = 0; mfname[i]; i++) - if (mfname[i] == '/') { - mfname[i] = 0; - mkdir( mfname, 0755 ); - mfname[i] = '/'; - } - iniSave( curdmrc, mfname ); - } - if (mfname) - free( mfname ); -} - -static int removeAuth; -#ifdef USE_PAM -static int removeSession; -static int removeCreds; -#endif - -#ifdef WITH_CONSOLE_KIT -int -StartClient( const char *ck_session_cookie ) -#else -int -StartClient() -#endif -{ - const char *home, *sessargs, *desksess; - char **env, *xma; - char **argv, *fname, *str; -#ifdef USE_PAM - char **pam_env; -# ifdef _AIX - char **saved_env; -# endif - struct pam_conv pconv; - int pretc; -#else -# ifdef _AIX - char *msg; - char **theenv; - extern char **newenv; /* from libs.a, this is set up by setpenv */ -# endif -#endif -#ifdef HAVE_SETUSERCONTEXT - extern char **environ; -#endif - char *failsafeArgv[2], *lname; - int i, pid, lfd; - - if (StrCmp( dmrcuser, curuser )) { - if (curdmrc) { free( curdmrc ); curdmrc = 0; } - if (dmrcuser) { free( dmrcuser ); dmrcuser = 0; } - } - -#if defined(USE_PAM) || defined(_AIX) - if (!(p = getpwnam( curuser ))) { - LogError( "getpwnam(%s) failed.\n", curuser ); - return 0; - } -#endif - -#ifndef USE_PAM -# ifdef _AIX - msg = NULL; - loginsuccess( curuser, hostname, tty, &msg ); - if (msg) { - Debug( "loginsuccess() - %s\n", msg ); - free( (void *)msg ); - } -# else /* _AIX */ -# if defined(KERBEROS) && !defined(NO_AFS) - if (krbtkfile[0] != '\0') { - if (k_hasafs()) { - if (k_setpag() == -1) - LogError( "setpag() for %s failed\n", curuser ); - if ((ret = k_afsklog( NULL, NULL )) != KSUCCESS) - LogError( "AFS Warning: %s\n", krb_get_err_text( ret ) ); - } - } -# endif /* KERBEROS && AFS */ -# endif /* _AIX */ -#endif /* !PAM */ - - curuid = p->pw_uid; - curgid = p->pw_gid; - - env = baseEnv( curuser ); - xma = 0; - if (td->ctrl.fpath && StrDup( &xma, td->ctrl.fpath )) { - if ((td->allowShutdown == SHUT_ALL || - (td->allowShutdown == SHUT_ROOT && !curuser)) && - StrApp( &xma, ",maysd", (char *)0 )) - { - if (td->allowNuke == SHUT_ALL || - (td->allowNuke == SHUT_ROOT && !curuser)) - StrApp( &xma, ",mayfn", (char *)0 ); - StrApp( &xma, td->defSdMode == SHUT_FORCENOW ? ",fn" : - td->defSdMode == SHUT_TRYNOW ? ",tn" : ",sched", - (char *)0 ); - } - if ((td->displayType & d_location) == dLocal && AnyReserveDisplays()) - StrApp( &xma, ",rsvd", (char *)0 ); - } else - StrDup( &xma, "true" ); - StrApp( &xma, ",method=", curtype, (char *)0 ); - if (td_setup) - StrApp( &xma, ",auto", (char *)0 ); - if (xma) { - env = setEnv( env, "XDM_MANAGED", xma ); - free( xma ); - } - if (td->autoLock && cursource == PWSRC_AUTOLOGIN) - env = setEnv( env, "DESKTOP_LOCKED", "true" ); - env = setEnv( env, "PATH", curuid ? td->userPath : td->systemPath ); - env = setEnv( env, "SHELL", p->pw_shell ); - env = setEnv( env, "HOME", p->pw_dir ); - if (cursource == PWSRC_AUTOLOGIN) - env = setEnv (env, "TDM_AUTOLOGIN", curuser); -#if !defined(USE_PAM) && !defined(_AIX) && defined(KERBEROS) - if (krbtkfile[0] != '\0') - env = setEnv( env, "KRBTKFILE", krbtkfile ); -#endif -#ifdef WITH_CONSOLE_KIT - if (ck_session_cookie != NULL) { - env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie ); - } -#endif -#ifdef WITH_CONSOLE_KIT - if (ck_session_cookie != NULL) { - env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie ); - } -#endif - userEnviron = inheritEnv( env, envvars ); - env = systemEnv( p->pw_name ); - systemEnviron = setEnv( env, "HOME", p->pw_dir ); - Debug( "user environment:\n%[|''>'\n's" - "system environment:\n%[|''>'\n's" - "end of environments\n", - userEnviron, - systemEnviron ); - - /* - * for user-based authorization schemes, - * add the user to the server's allowed "hosts" list. - */ - for (i = 0; i < td->authNum; i++) { -#ifdef SECURE_RPC - if (td->authorizations[i]->name_length == 9 && - !memcmp( td->authorizations[i]->name, "SUN-DES-1", 9 )) - { - XHostAddress addr; - char netname[MAXNETNAMELEN+1]; - char domainname[MAXNETNAMELEN+1]; - - getdomainname( domainname, sizeof(domainname) ); - user2netname( netname, curuid, domainname ); - addr.family = FamilyNetname; - addr.length = strlen( netname ); - addr.address = netname; - XAddHost( dpy, &addr ); - } -#endif -#ifdef K5AUTH - if (td->authorizations[i]->name_length == 14 && - !memcmp( td->authorizations[i]->name, "MIT-KERBEROS-5", 14 )) - { - /* Update server's auth file with user-specific info. - * Don't need to AddHost because X server will do that - * automatically when it reads the cache we are about - * to point it at. - */ - XauDisposeAuth( td->authorizations[i] ); - td->authorizations[i] = - Krb5GetAuthFor( 14, "MIT-KERBEROS-5", td->name ); - SaveServerAuthorizations( td, td->authorizations, td->authNum ); - } -#endif - } - - if (*dmrcDir) - mergeSessionArgs( TRUE ); - - Debug( "now starting the session\n" ); - -#ifdef USE_PAM - /* the greeter is gone by now ... */ - pconv.conv = PAM_conv_null; - pconv.appdata_ptr = 0; - if ((pretc = pam_set_item( pamh, PAM_CONV, &pconv )) != PAM_SUCCESS) { - ReInitErrorLog(); - LogError( "pam_set_item() for %s failed: %s\n", - curuser, pam_strerror( pamh, pretc ) ); - return 0; - } - ReInitErrorLog(); -#endif - -#ifdef USE_PAM - -# ifdef HAVE_SETUSERCONTEXT - if (setusercontext( lc, p, p->pw_uid, LOGIN_SETGROUP )) { - LogError( "setusercontext(groups) for %s failed: %m\n", - curuser ); - return 0; - } -# else - if (!SetGid( curuser, curgid )) - return 0; -# endif - -# ifdef _AIX - if (!(pam_env = initStrArr( 0 ))) { - resetGids(); - return 0; - } - saved_env = environ; - environ = pam_env; -# endif - removeCreds = 1; /* set it first - i don't trust PAM's rollback */ - pretc = pam_setcred( pamh, 0 ); - ReInitErrorLog(); -# ifdef _AIX - pam_env = environ; - environ = saved_env; -# endif -# ifdef HAVE_INITGROUPS - /* This seems to be a strange place for it, but do it: - - after the initial groups are set - - after pam_setcred might have set something, even in the error case - - before pam_setcred(DELETE_CRED) might need it - */ - if (!saveGids()) - return 0; -# endif - if (pretc != PAM_SUCCESS) { - LogError( "pam_setcred() for %s failed: %s\n", - curuser, pam_strerror( pamh, pretc ) ); - resetGids(); - return 0; - } - - removeSession = 1; /* set it first - same as above */ - pretc = pam_open_session( pamh, 0 ); - ReInitErrorLog(); - if (pretc != PAM_SUCCESS) { - LogError( "pam_open_session() for %s failed: %s\n", - curuser, pam_strerror( pamh, pretc ) ); - resetGids(); - return 0; - } - - /* we don't want sessreg and the startup/reset scripts run with user - credentials. unfortunately, we can reset only the gids. */ - resetGids(); - -# define D_LOGIN_SETGROUP LOGIN_SETGROUP -#else /* USE_PAM */ -# define D_LOGIN_SETGROUP 0 -#endif /* USE_PAM */ - - /* Login succeeded */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_SUCCESS); - - removeAuth = 1; - chownCtrl( &td->ctrl, curuid ); - endpwent(); -#if !defined(USE_PAM) && defined(USESHADOW) && !defined(_AIX) - endspent(); -#endif - ClearCloseOnFork( mstrtalk.pipe->wfd ); - switch (pid = Fork()) { - case 0: - - sessreg( td, getpid(), curuser, curuid ); - - if (source( systemEnviron, td->startup, td_setup )) { - LogError( "Cannot execute startup script %\"s\n", td->startup ); - exit( 1 ); - } - - if (Setjmp( mstrtalk.errjmp )) - exit( 1 ); - GSet( &mstrtalk ); - - setsid(); - Signal( SIGINT, SIG_DFL ); - - /* Memory leaks are ok here as we exec() soon. */ - -#if defined(USE_PAM) || !defined(_AIX) - -# ifdef USE_PAM - /* pass in environment variables set by libpam and modules it called */ -# ifndef _AIX - pam_env = pam_getenvlist( pamh ); - ReInitErrorLog(); -# endif - if (pam_env) - for (; *pam_env; pam_env++) - userEnviron = putEnv( *pam_env, userEnviron ); -# endif - -# ifdef HAVE_SETLOGIN - if (setlogin( curuser ) < 0) { - LogError( "setlogin for %s failed: %m\n", curuser ); - exit( 1 ); - } -# define D_LOGIN_SETLOGIN LOGIN_SETLOGIN -# else -# define D_LOGIN_SETLOGIN 0 -# endif - -# if defined(USE_PAM) && defined(HAVE_INITGROUPS) - if (!restoreGids()) - exit( 1 ); -# endif - -# ifndef HAVE_SETUSERCONTEXT - -# ifdef USE_PAM - if (!SetUid( curuser, curuid )) - exit( 1 ); -# else - if (!SetUser( curuser, curuid, curgid )) - exit( 1 ); -# endif - -# else /* !HAVE_SETUSERCONTEXT */ - - /* - * Destroy environment. - * We need to do this before setusercontext() because that may - * set or reset some environment variables. - */ - if (!(environ = initStrArr( 0 ))) - exit( 1 ); - - /* - * Set the user's credentials: uid, gid, groups, - * environment variables, resource limits, and umask. - */ - if (setusercontext( lc, p, p->pw_uid, - LOGIN_SETALL & ~(D_LOGIN_SETGROUP|D_LOGIN_SETLOGIN) ) < 0) - { - LogError( "setusercontext for %s failed: %m\n", curuser ); - exit( 1 ); - } - - for (i = 0; environ[i]; i++) - userEnviron = putEnv( environ[i], userEnviron ); - -# endif /* !HAVE_SETUSERCONTEXT */ - -#else /* PAM || !_AIX */ - /* - * Set the user's credentials: uid, gid, groups, - * audit classes, user limits, and umask. - */ - if (setpcred( curuser, NULL ) == -1) { - LogError( "setpcred for %s failed: %m\n", curuser ); - exit( 1 ); - } - - /* - * Set the users process environment. Store protected variables and - * obtain updated user environment list. This call will initialize - * global 'newenv'. - */ - if (setpenv( curuser, PENV_INIT | PENV_ARGV | PENV_NOEXEC, - userEnviron, NULL ) != 0) - { - LogError( "Can't set %s's process environment\n", curuser ); - exit( 1 ); - } - userEnviron = newenv; - -#endif /* _AIX */ - - /* - * for user-based authorization schemes, - * use the password to get the user's credentials. - */ -#ifdef SECURE_RPC - /* do like "keylogin" program */ - if (!curpass[0]) - LogInfo( "No password for NIS provided.\n" ); - else { - char netname[MAXNETNAMELEN+1], secretkey[HEXKEYBYTES+1]; - int nameret, keyret; - int len; - int key_set_ok = 0; - struct key_netstarg netst; - - nameret = getnetname( netname ); - Debug( "user netname: %s\n", netname ); - len = strlen( curpass ); - if (len > 8) - bzero( curpass + 8, len - 8 ); - keyret = getsecretkey( netname, secretkey, curpass ); - Debug( "getsecretkey returns %d, key length %d\n", - keyret, strlen( secretkey ) ); - netst.st_netname = netname; - memcpy( netst.st_priv_key, secretkey, HEXKEYBYTES ); - memset( netst.st_pub_key, 0, HEXKEYBYTES ); - if (key_setnet( &netst ) < 0) - Debug( "Could not set secret key.\n" ); - /* is there a key, and do we have the right password? */ - if (keyret == 1) { - if (*secretkey) { - keyret = key_setsecret( secretkey ); - Debug( "key_setsecret returns %d\n", keyret ); - if (keyret == -1) - LogError( "Failed to set NIS secret key\n" ); - else - key_set_ok = 1; - } else { - /* found a key, but couldn't interpret it */ - LogError( "Password incorrect for NIS principal %s\n", - nameret ? netname : curuser ); - } - } - if (!key_set_ok) - NukeAuth( 9, "SUN-DES-1" ); - bzero( secretkey, strlen( secretkey ) ); - } -#endif -#ifdef K5AUTH - /* do like "kinit" program */ - if (!curpass[0]) - LogInfo( "No password for Kerberos5 provided.\n" ); - else - if ((str = Krb5Init( curuser, curpass, td->name ))) - userEnviron = setEnv( userEnviron, "KRB5CCNAME", str ); - else - NukeAuth( 14, "MIT-KERBEROS-5" ); -#endif /* K5AUTH */ - if (td->autoReLogin) { - GSendInt( D_ReLogin ); - GSendStr( curuser ); - GSendStr( curpass ); - GSendStr( newdmrc ); - } - if (curpass) - bzero( curpass, strlen( curpass ) ); - SetUserAuthorization( td ); - home = getEnv( userEnviron, "HOME" ); - if (home) { - if (chdir( home ) < 0) { - LogError( "Cannot chdir to %s's home %s: %m, using /\n", - curuser, home ); - home = 0; - userEnviron = setEnv( userEnviron, "HOME", "/" ); - goto cdroot; - } - ASPrintf( &lname, td->clientLogFile, td->name ); - if ((lfd = creat( lname, 0600 )) < 0) { - LogWarn( "Cannot create session log file %s: %m\n", lname ); - free( lname ); - goto tmperr; - } - } else { - cdroot: - chdir( "/" ); - tmperr: - ASPrintf( &lname, "/tmp/xerr-%s-%s", curuser, td->name ); - unlink( lname ); - if ((lfd = open( lname, O_WRONLY|O_CREAT|O_EXCL, 0600 )) < 0) { - LogError( "Cannot create fallback session log file %s: %m\n", - lname ); - goto logerr; - } - } - dup2( lfd, 1 ); - dup2( lfd, 2 ); - close( lfd ); - logerr: - free( lname ); - if (!*dmrcDir) - mergeSessionArgs( home != 0 ); - if (!(desksess = iniEntry( curdmrc, "Desktop", "Session", 0 ))) - desksess = "failsafe"; /* only due to OOM */ - GSendInt( D_User ); - GSendInt( curuid ); - GSendStr( curuser ); - GSendStr( desksess ); - close( mstrtalk.pipe->wfd ); - userEnviron = setEnv( userEnviron, "DESKTOP_SESSION", desksess ); - for (i = 0; td->sessionsDirs[i]; i++) { - fname = 0; - if (StrApp( &fname, td->sessionsDirs[i], "/", desksess, ".desktop", (char *)0 )) { - if ((str = iniLoad( fname ))) { - if (!StrCmp( iniEntry( str, "Desktop Entry", "Hidden", 0 ), "true" ) || - !(sessargs = iniEntry( str, "Desktop Entry", "Exec", 0 ))) - sessargs = ""; - free( str ); - free( fname ); - goto gotit; - } - free( fname ); - } - } - if (!strcmp( desksess, "failsafe" ) || - !strcmp( desksess, "default" ) || - !strcmp( desksess, "custom" )) - sessargs = desksess; - else - sessargs = ""; - gotit: - if (!(argv = parseArgs( (char **)0, td->session )) || - !(argv = addStrArr( argv, sessargs, -1 ))) - exit( 1 ); - if (argv[0] && *argv[0]) { - Debug( "executing session %\"[s\n", argv ); - execute( argv, userEnviron ); - LogError( "Session %\"s execution failed: %m\n", argv[0] ); - } else - LogError( "Session has no command/arguments\n" ); - failsafeArgv[0] = td->failsafeClient; - failsafeArgv[1] = 0; - execute( failsafeArgv, userEnviron ); - LogError( "Failsafe client %\"s execution failed: %m\n", - failsafeArgv[0] ); - exit( 1 ); - case -1: - RegisterCloseOnFork( mstrtalk.pipe->wfd ); - LogError( "Forking session on %s failed: %m\n", td->name ); - return 0; - default: - RegisterCloseOnFork( mstrtalk.pipe->wfd ); - Debug( "StartSession, fork succeeded %d\n", pid ); - return pid; - } -} - -void -SessionExit( int status ) -{ - int pid; -#ifdef USE_PAM - int pretc; -#endif - - Signal( SIGTERM, SIG_IGN ); - - if (removeAuth) { - if (source( systemEnviron, td->reset, td_setup )) - LogError( "Cannot execute reset script %\"s\n", td->reset ); - sessreg( td, 0, 0, 0 ); - - switch ((pid = Fork())) { - case 0: -#if defined(USE_PAM) && defined(HAVE_INITGROUPS) - if (restoreGids() && SetUid( curuser, curuid )) -#else - if (SetUser( curuser, curuid, curgid )) -#endif - - { - RemoveUserAuthorization( td ); -#ifdef K5AUTH - Krb5Destroy( td->name ); -#endif /* K5AUTH */ -#if !defined(USE_PAM) && !defined(_AIX) -# ifdef KERBEROS - if (krbtkfile[0]) { - (void)dest_tkt(); -# ifndef NO_AFS - if (k_hasafs()) - (void)k_unlog(); -# endif - } -# endif -#endif /* !USE_PAM && !_AIX*/ - } - exit( 0 ); - case -1: - LogError( "Cannot clean up session: fork() failed: %m" ); - break; - default: - Wait4( pid ); - break; - } - } - -#ifdef USE_PAM - if (removeCreds) { -# ifdef HAVE_INITGROUPS - restoreGids(); -# endif - if (removeSession) - if ((pretc = pam_close_session( pamh, 0 )) != PAM_SUCCESS) - LogError( "pam_close_session() failed: %s\n", - pam_strerror( pamh, pretc ) ); - if ((pretc = pam_setcred( pamh, PAM_DELETE_CRED )) != PAM_SUCCESS) - LogError( "pam_setcred(DELETE_CRED) failed: %s\n", - pam_strerror( pamh, pretc ) ); - resetGids(); - } - if (pamh) { - pam_end( pamh, PAM_SUCCESS ); - ReInitErrorLog(); - } -#endif - - /* make sure the server gets reset after the session is over */ - if (td->serverPid >= 2) { - if (!td->terminateServer && td->resetSignal) - TerminateProcess( td->serverPid, td->resetSignal ); - } else - ResetServer( td ); - Debug( "display %s exiting with status %d\n", td->name, status ); - exit( status ); -} - -int -ReadDmrc() -{ - char *data, *fname = 0; - int len, pid, pfd[2], err; - - if (!dmrcuser || !dmrcuser[0] || !(p = getpwnam( dmrcuser ))) - return GE_NoUser; - - if (*dmrcDir) { - if (!StrApp( &fname, dmrcDir, "/", dmrcuser, ".dmrc", (char *)0 )) - return GE_Error; - if (!(curdmrc = iniLoad( fname ))) { - free( fname ); - return GE_Ok; - } - free( fname ); - return GE_NoFile; - } - - if (!StrApp( &fname, p->pw_dir, "/.dmrc", (char *)0 )) - return GE_Error; - if (pipe( pfd )) - return GE_Error; - if ((pid = Fork()) < 0) { - close( pfd[0] ); - close( pfd[1] ); - return GE_Error; - } - if (!pid) { - if (!SetUser( p->pw_name, p->pw_uid, p->pw_gid )) - exit( 0 ); - if (!(data = iniLoad( fname ))) { - static const int m1 = -1; - write( pfd[1], &m1, sizeof(int) ); - exit( 0 ); - } - len = strlen( data ); - write( pfd[1], &len, sizeof(int) ); - write( pfd[1], data, len + 1 ); - exit( 0 ); - } - close( pfd[1] ); - free( fname ); - err = GE_Error; - if (Reader( pfd[0], &len, sizeof(int) ) == sizeof(int)) { - if (len == -1) - err = GE_Denied; - else if ((curdmrc = Malloc( len + 1 ))) { - if (Reader( pfd[0], curdmrc, len + 1 ) == len + 1) - err = GE_Ok; - else { - free( curdmrc ); - curdmrc = 0; - } - } - } - close( pfd[0] ); - (void)Wait4( pid ); - return err; -} diff --git a/kdm/backend/consolekit.c b/kdm/backend/consolekit.c deleted file mode 100644 index 61d0b165e..000000000 --- a/kdm/backend/consolekit.c +++ /dev/null @@ -1,557 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - - Copyright (C) 2006-2007 William Jon McCann - Copyright (C) 2007 Kevin Kofler - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - */ - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include -#include -#include - -#define DBUS_API_SUBJECT_TO_CHANGE -#include - -#include "consolekit.h" - - -#define CK_NAME "org.freedesktop.ConsoleKit" -#define CK_PATH "/org/freedesktop/ConsoleKit" -#define CK_INTERFACE "org.freedesktop.ConsoleKit" -#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" -#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" -#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" - -static DBusConnection *private_connection = NULL; - -static void -add_param_int (DBusMessageIter *iter_struct, - const char *key, - int value) -{ - DBusMessageIter iter_struct_entry; - DBusMessageIter iter_var; - - dbus_message_iter_open_container (iter_struct, - DBUS_TYPE_STRUCT, - NULL, - &iter_struct_entry); - - dbus_message_iter_append_basic (&iter_struct_entry, - DBUS_TYPE_STRING, - &key); - - dbus_message_iter_open_container (&iter_struct_entry, - DBUS_TYPE_VARIANT, - DBUS_TYPE_INT32_AS_STRING, - &iter_var); - - dbus_message_iter_append_basic (&iter_var, - DBUS_TYPE_INT32, - &value); - - dbus_message_iter_close_container (&iter_struct_entry, - &iter_var); - - dbus_message_iter_close_container (iter_struct, &iter_struct_entry); -} - -static void -add_param_boolean (DBusMessageIter *iter_struct, - const char *key, - int value) -{ - DBusMessageIter iter_struct_entry; - DBusMessageIter iter_var; - - dbus_message_iter_open_container (iter_struct, - DBUS_TYPE_STRUCT, - NULL, - &iter_struct_entry); - - dbus_message_iter_append_basic (&iter_struct_entry, - DBUS_TYPE_STRING, - &key); - - dbus_message_iter_open_container (&iter_struct_entry, - DBUS_TYPE_VARIANT, - DBUS_TYPE_BOOLEAN_AS_STRING, - &iter_var); - - dbus_message_iter_append_basic (&iter_var, - DBUS_TYPE_BOOLEAN, - &value); - - dbus_message_iter_close_container (&iter_struct_entry, - &iter_var); - - dbus_message_iter_close_container (iter_struct, &iter_struct_entry); -} - -static void -add_param_string (DBusMessageIter *iter_struct, - const char *key, - const char *value) -{ - DBusMessageIter iter_struct_entry; - DBusMessageIter iter_var; - - dbus_message_iter_open_container (iter_struct, - DBUS_TYPE_STRUCT, - NULL, - &iter_struct_entry); - - dbus_message_iter_append_basic (&iter_struct_entry, - DBUS_TYPE_STRING, - &key); - - dbus_message_iter_open_container (&iter_struct_entry, - DBUS_TYPE_VARIANT, - DBUS_TYPE_STRING_AS_STRING, - &iter_var); - - dbus_message_iter_append_basic (&iter_var, - DBUS_TYPE_STRING, - &value); - - dbus_message_iter_close_container (&iter_struct_entry, - &iter_var); - - dbus_message_iter_close_container (iter_struct, &iter_struct_entry); -} - -static int -session_get_x11_display (DBusConnection *connection, - const char *ssid, - char **str) -{ - DBusError error; - DBusMessage *message; - DBusMessage *reply; - DBusMessageIter iter; - const char *value; - - if (str != NULL) { - *str = NULL; - } - - message = dbus_message_new_method_call (CK_NAME, - ssid, - CK_SESSION_INTERFACE, - "GetX11Display"); - if (message == NULL) { - Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); - return FALSE; - } - - dbus_error_init (&error); - reply = dbus_connection_send_with_reply_and_block (connection, - message, - -1, &error); - if (dbus_error_is_set (&error)) { - Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); - reply = NULL; - } - - dbus_connection_flush (connection); - dbus_message_unref (message); - - if (reply == NULL) { - return FALSE; - } - - dbus_message_iter_init (reply, &iter); - dbus_message_iter_get_basic (&iter, &value); - if (str != NULL) { - *str = strdup (value); - } - dbus_message_unref (reply); - - return TRUE; -} - -static int -session_unlock (DBusConnection *connection, - const char *ssid) -{ - DBusError error; - DBusMessage *message; - DBusMessage *reply; - - Debug ("ConsoleKit: Unlocking session %s", ssid); - message = dbus_message_new_method_call (CK_NAME, - ssid, - CK_SESSION_INTERFACE, - "Unlock"); - if (message == NULL) { - Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); - return FALSE; - } - - dbus_error_init (&error); - reply = dbus_connection_send_with_reply_and_block (connection, - message, - -1, &error); - dbus_message_unref (message); - dbus_message_unref (reply); - dbus_connection_flush (connection); - - if (dbus_error_is_set (&error)) { - Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); - return FALSE; - } - - return TRUE; -} - -/* from libhal */ -static char ** -get_path_array_from_iter (DBusMessageIter *iter, - int *num_elements) -{ - int count; - char **buffer; - - count = 0; - buffer = (char **)malloc (sizeof (char *) * 8); - - if (buffer == NULL) - goto oom; - - buffer[0] = NULL; - while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_OBJECT_PATH) { - const char *value; - char *str; - - if ((count % 8) == 0 && count != 0) { - buffer = realloc (buffer, sizeof (char *) * (count + 8)); - if (buffer == NULL) - goto oom; - } - - dbus_message_iter_get_basic (iter, &value); - str = strdup (value); - if (str == NULL) - goto oom; - - buffer[count] = str; - - dbus_message_iter_next (iter); - count++; - } - - if ((count % 8) == 0) { - buffer = realloc (buffer, sizeof (char *) * (count + 1)); - if (buffer == NULL) - goto oom; - } - - buffer[count] = NULL; - if (num_elements != NULL) - *num_elements = count; - return buffer; - -oom: - LogWarn ("%s %d : error allocating memory\n", __FILE__, __LINE__); - return NULL; - -} - -static char ** -get_sessions_for_user (DBusConnection *connection, - const char *user, - const char *x11_display) -{ - DBusError error; - DBusMessage *message; - DBusMessage *reply; - DBusMessageIter iter; - DBusMessageIter iter_reply; - DBusMessageIter iter_array; - struct passwd *pwent; - char **sessions; - - sessions = NULL; - message = NULL; - reply = NULL; - - pwent = getpwnam (user); - - dbus_error_init (&error); - message = dbus_message_new_method_call (CK_NAME, - CK_MANAGER_PATH, - CK_MANAGER_INTERFACE, - "GetSessionsForUser"); - if (message == NULL) { - Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); - goto out; - } - - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, - DBUS_TYPE_UINT32, - &pwent->pw_uid); - - dbus_error_init (&error); - reply = dbus_connection_send_with_reply_and_block (connection, - message, - -1, &error); - dbus_connection_flush (connection); - - if (dbus_error_is_set (&error)) { - Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); - goto out; - } - - if (reply == NULL) { - Debug ("ConsoleKit: No reply for GetSessionsForUser"); - goto out; - } - - dbus_message_iter_init (reply, &iter_reply); - if (dbus_message_iter_get_arg_type (&iter_reply) != DBUS_TYPE_ARRAY) { - Debug ("ConsoleKit: Wrong reply for GetSessionsForUser - expecting an array."); - goto out; - } - - dbus_message_iter_recurse (&iter_reply, &iter_array); - sessions = get_path_array_from_iter (&iter_array, NULL); - - out: - if (message != NULL) { - dbus_message_unref (message); - } - if (reply != NULL) { - dbus_message_unref (reply); - } - - return sessions; -} - -void -unlock_ck_session (const char *user, - const char *x11_display) -{ - DBusError error; - DBusConnection *connection; - char **sessions; - int i; - - Debug ("ConsoleKit: Unlocking session for %s on %s", user, x11_display); - - dbus_error_init (&error); - connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); - if (connection == NULL) { - Debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message); - dbus_error_free (&error); - return; - } - - sessions = get_sessions_for_user (connection, user, x11_display); - if (sessions == NULL || sessions[0] == NULL) { - Debug ("ConsoleKit: no sessions found"); - return; - } - - for (i = 0; sessions[i] != NULL; i++) { - char *ssid; - char *xdisplay; - - ssid = sessions[i]; - session_get_x11_display (connection, ssid, &xdisplay); - Debug ("ConsoleKit: session %s has DISPLAY %s", ssid, xdisplay); - - if (xdisplay != NULL - && x11_display != NULL - && strcmp (xdisplay, x11_display) == 0) { - int res; - - res = session_unlock (connection, ssid); - if (! res) { - LogError ("ConsoleKit: Unable to unlock %s", ssid); - } - } - - free (xdisplay); - } - - freeStrArr (sessions); -} - -char * -open_ck_session (struct passwd *pwent, - struct display *d) -{ - DBusConnection *connection; - DBusError error; - DBusMessage *message; - DBusMessage *reply; - DBusMessageIter iter; - DBusMessageIter iter_struct; - char *cookie; - - cookie = NULL; - - if (pwent == NULL) { - Debug ("ConsoleKit: NULL user passed as parameter"); - return NULL; - } - - Debug ("ConsoleKit: Opening session for %s", pwent->pw_name); - - dbus_error_init (&error); - connection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error); - private_connection = connection; - - if (connection == NULL) { - Debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message); - dbus_error_free (&error); - return NULL; - } - - dbus_connection_set_exit_on_disconnect (connection, FALSE); - /* FIXME: What to do about these? - dbus_connection_set_watch_functions( connection, - dbusAddWatch, - dbusRemoveWatch, - dbusToggleWatch, - data, 0 ); - dbus_connection_set_timeout_functions( connection, - dbusAddTimeout, - dbusRemoveTimeout, - dbusToggleTimeout, - data, 0 ); - dbus_connection_set_wakeup_main_function( connection, - dbusWakeupMain, - data, 0 ); */ - - dbus_error_init (&error); - message = dbus_message_new_method_call (CK_NAME, - CK_MANAGER_PATH, - CK_MANAGER_INTERFACE, - "OpenSessionWithParameters"); - if (message == NULL) { - Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); - return NULL; - } - - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_open_container (&iter, - DBUS_TYPE_ARRAY, - DBUS_STRUCT_BEGIN_CHAR_AS_STRING - DBUS_TYPE_STRING_AS_STRING - DBUS_TYPE_VARIANT_AS_STRING - DBUS_STRUCT_END_CHAR_AS_STRING, - &iter_struct); - - add_param_int (&iter_struct, "user", pwent->pw_uid); - add_param_string (&iter_struct, "x11-display", d->name); - add_param_boolean (&iter_struct, "is-local", ((d->displayType & d_location) == dLocal)); -#ifdef XDMCP - if ((d->displayType & d_location) != dLocal) { - add_param_string (&iter_struct, "remote-host-name", d->remoteHost); - } -#endif - -#ifdef HAVE_VTS - if (d->serverVT > 0) { - char device[20]; - - /* FIXME: how does xorg construct this */ - sprintf(device, "/dev/tty%d", d->serverVT); - add_param_string (&iter_struct, "x11-display-device", device); - } -#endif - - dbus_message_iter_close_container (&iter, &iter_struct); - - reply = dbus_connection_send_with_reply_and_block (connection, - message, - -1, &error); - if (dbus_error_is_set (&error)) { - Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); - reply = NULL; - } - - dbus_connection_flush (connection); - - dbus_message_unref (message); - dbus_error_free (&error); - - if (reply != NULL) { - const char *value; - - dbus_message_iter_init (reply, &iter); - dbus_message_iter_get_basic (&iter, &value); - cookie = strdup (value); - dbus_message_unref (reply); - } - - return cookie; -} - -void -close_ck_session (const char *cookie) -{ - DBusError error; - DBusMessage *message; - DBusMessage *reply; - DBusMessageIter iter; - - if (cookie == NULL) { - return; - } - - if (private_connection == NULL) { - return; - } - - dbus_error_init (&error); - message = dbus_message_new_method_call (CK_NAME, - CK_MANAGER_PATH, - CK_MANAGER_INTERFACE, - "CloseSession"); - if (message == NULL) { - Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); - return; - } - - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, - DBUS_TYPE_STRING, - &cookie); - - reply = dbus_connection_send_with_reply_and_block (private_connection, - message, - -1, &error); - if (dbus_error_is_set (&error)) { - Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); - reply = NULL; - } - - dbus_connection_flush (private_connection); - - dbus_message_unref (message); - dbus_error_free (&error); - - dbus_connection_close (private_connection); - private_connection = NULL; -} diff --git a/kdm/backend/consolekit.h b/kdm/backend/consolekit.h deleted file mode 100644 index e385e3f91..000000000 --- a/kdm/backend/consolekit.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - - Copyright (C) 2006 William Jon McCann - Copyright (C) 2007 Kevin Kofler - - 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - */ - - -#ifndef __CONSOLE_KIT_H -#define __CONSOLE_KIT_H - -#include - -struct display; - -char * open_ck_session (struct passwd *pwent, - struct display *display); -void close_ck_session (const char *cookie); -void unlock_ck_session (const char *user, - const char *x11_display); - -#endif /* __CONSOLE_KIT_H */ diff --git a/kdm/backend/ctrl.c b/kdm/backend/ctrl.c deleted file mode 100644 index 622c9370d..000000000 --- a/kdm/backend/ctrl.c +++ /dev/null @@ -1,1015 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2001-2005 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * display manager - */ - -#include "dm.h" -#include "dm_socket.h" -#include "dm_error.h" - -#include -#include -#include - -static void -acceptSock( CtrlRec *cr ) -{ - struct cmdsock *cs; - int fd; - - if ((fd = accept( cr->fd, 0, 0 )) < 0) { - bust: - LogError( "Error accepting command connection\n" ); - return; - } - if (!(cs = Malloc( sizeof(*cs) ))) { - close( fd ); - goto bust; - } - cs->sock.fd = fd; - cs->sock.buffer = 0; - cs->sock.buflen = 0; - cs->next = cr->css; - cr->css = cs; - fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ); - RegisterCloseOnFork( fd ); - RegisterInput( fd ); -} - -static void -nukeSock( struct cmdsock *cs ) -{ - UnregisterInput( cs->sock.fd ); - CloseNClearCloseOnFork( cs->sock.fd ); - if (cs->sock.buffer) - free( cs->sock.buffer ); - free( cs ); -} - -#ifdef HONORS_SOCKET_PERMS -static CtrlRec ctrl = { 0, 0, -1, 0, 0, { -1, 0, 0 } }; -#else -static CtrlRec ctrl = { 0, 0, 0, -1, 0, 0, { -1, 0, 0 } }; - -static int mkTempDir( char *dir ) -{ - int i, l = strlen( dir ) - 6; - - for (i = 0; i < 100; i++) { - randomStr( dir + l ); - if (!mkdir( dir, 0700 )) - return True; - if (errno != EEXIST) - break; - } - return False; -} -#endif - -void -openCtrl( struct display *d ) -{ - CtrlRec *cr; - const char *dname; - char *sockdir; - struct sockaddr_un sa; - - if (!*fifoDir) - return; - if (d) { - cr = &d->ctrl, dname = d->name; - if (!memcmp( dname, "localhost:", 10 )) - dname += 9; - } else - cr = &ctrl, dname = 0; - if (cr->fifo.fd < 0) { - if (mkdir( fifoDir, 0755 )) { - if (errno != EEXIST) { - LogError( "mkdir %\"s failed; no control FiFos will be available\n", - fifoDir ); - return; - } - } else - chmod( fifoDir, 0755 ); /* override umask */ - StrApp( &cr->fpath, fifoDir, dname ? "/xdmctl-" : "/xdmctl", - dname, (char *)0 ); - if (cr->fpath) { - unlink( cr->fpath ); - if (mkfifo( cr->fpath, 0 ) < 0) - LogError( "Cannot create control FiFo %\"s\n", cr->fpath ); - else { - cr->gid = fifoGroup; - if (!d) - chown( cr->fpath, -1, fifoGroup ); - chmod( cr->fpath, 0620 ); - if ((cr->fifo.fd = open( cr->fpath, O_RDWR | O_NONBLOCK )) >= 0) { - RegisterCloseOnFork( cr->fifo.fd ); - RegisterInput( cr->fifo.fd ); - goto fifok; - } - unlink( cr->fpath ); - LogError( "Cannot open control FiFo %\"s\n", cr->fpath ); - } - free( cr->fpath ); - cr->fpath = 0; - } - } - fifok: - if (cr->fd < 0) { - /* fifoDir is created above already */ - sockdir = 0; - StrApp( &sockdir, fifoDir, dname ? "/dmctl-" : "/dmctl", - dname, (char *)0 ); - if (sockdir) { - StrApp( &cr->path, sockdir, "/socket", (char *)0 ); - if (cr->path) { - if (strlen( cr->path ) >= sizeof(sa.sun_path)) - LogError( "path %\"s too long; no control sockets will be available\n", - cr->path ); -#ifdef HONORS_SOCKET_PERMS - else if (mkdir( sockdir, 0700 ) && errno != EEXIST) - LogError( "mkdir %\"s failed; no control sockets will be available\n", - sockdir ); - else if (unlink( cr->path ) && errno != ENOENT) - LogError( "unlink %\"s failed: %m; control socket will not be available\n", - cr->path ); - else { -#else - else if (unlink( sockdir ) && errno != ENOENT) - LogError( "unlink %\"s failed: %m; control socket will not be available\n", - sockdir ); - else if (!StrApp( &cr->realdir, sockdir, "-XXXXXX", (char *)0)) - ; - else if (!mkTempDir( cr->realdir )) { - LogError( "mkdir %\"s failed: %m; control socket will not be available\n", - cr->realdir ); - free( cr->realdir ); - cr->realdir = 0; - } else if (symlink( cr->realdir, sockdir )) { - LogError( "symlink %\"s => %\"s failed: %m; control socket will not be available\n", - sockdir, cr->realdir ); - rmdir( cr->realdir ); - free( cr->realdir ); - cr->realdir = 0; - } else { - chown( sockdir, 0, d ? 0 : fifoGroup ); - chmod( sockdir, 0750 ); -#endif - if ((cr->fd = socket( PF_UNIX, SOCK_STREAM, 0 )) < 0) - LogError( "Cannot create control socket\n" ); - else { - sa.sun_family = AF_UNIX; - strcpy( sa.sun_path, cr->path ); - if (!bind( cr->fd, (struct sockaddr *)&sa, sizeof(sa) )) { - if (!listen( cr->fd, 5 )) { -#ifdef HONORS_SOCKET_PERMS - chmod( cr->path, 0660 ); - if (!d) - chown( cr->path, -1, fifoGroup ); - chmod( sockdir, 0755 ); -#else - chmod( cr->path, 0666 ); -#endif - RegisterCloseOnFork( cr->fd ); - RegisterInput( cr->fd ); - free( sockdir ); - return; - } - unlink( cr->path ); - LogError( "Cannot listen on control socket %\"s\n", - cr->path ); - } else - LogError( "Cannot bind control socket %\"s\n", - cr->path ); - close( cr->fd ); - cr->fd = -1; - } -#ifdef HONORS_SOCKET_PERMS - rmdir( sockdir ); -#else - unlink( sockdir ); - rmdir( cr->realdir ); - free( cr->realdir ); - cr->realdir = 0; -#endif - } - free( cr->path ); - cr->path = 0; - } - free( sockdir ); - } - } -} - -void -closeCtrl( struct display *d ) -{ - CtrlRec *cr = d ? &d->ctrl : &ctrl; - - if (cr->fd >= 0) { - UnregisterInput( cr->fd ); - CloseNClearCloseOnFork( cr->fd ); - cr->fd = -1; - unlink( cr->path ); - *strrchr( cr->path, '/' ) = 0; -#ifdef HONORS_SOCKET_PERMS - rmdir( cr->path ); -#else - unlink( cr->path ); - rmdir( cr->realdir ); - free( cr->realdir ); - cr->realdir = 0; -#endif - free( cr->path ); - cr->path = 0; - while (cr->css) { - struct cmdsock *cs = cr->css; - cr->css = cs->next; - nukeSock( cs ); - } - } - if (cr->fifo.fd >= 0) { - UnregisterInput( cr->fifo.fd ); - CloseNClearCloseOnFork( cr->fifo.fd ); - cr->fifo.fd = -1; - unlink( cr->fpath ); - free( cr->fpath ); - cr->fpath = 0; - if (cr->fifo.buffer) - free( cr->fifo.buffer ); - cr->fifo.buffer = 0; - cr->fifo.buflen = 0; - } -} - -void -chownCtrl( CtrlRec *cr, int uid ) -{ - if (cr->fpath) - chown( cr->fpath, uid, -1 ); - if (cr->path) -#ifdef HONORS_SOCKET_PERMS - chown( cr->path, uid, -1 ); -#else - chown( cr->realdir, uid, -1 ); -#endif -} - -void -updateCtrl( void ) -{ - unsigned ffl, slc; - - ffl = 0; - if (ctrl.path) - for (ffl = strlen( ctrl.path ), slc = 2; ;) - if (ctrl.path[--ffl] == '/') - if (!--slc) - break; - if (ffl != strlen( fifoDir ) || memcmp( fifoDir, ctrl.path, ffl ) || - ctrl.gid != fifoGroup) - { - closeCtrl( 0 ); - openCtrl( 0 ); - } -} - - -static void -fLog( struct display *d, int fd, const char *sts, const char *msg, ... ) -{ - char *fmsg, *otxt; - const char *what; - int olen; - va_list va; - - va_start( va, msg ); - VASPrintf( &fmsg, msg, va ); - va_end( va ); - if (!fmsg) - return; - if (fd >= 0) { - olen = ASPrintf( &otxt, "%s\t%\\s\n", sts, fmsg ); - if (otxt) { - Writer( fd, otxt, olen ); - free( otxt ); - } - what = "socket"; - } else - what = "FiFo"; - if (d) - Debug( "control %s for %s: %s - %s", what, d->name, sts, fmsg ); - else - Debug( "global control %s: %s - %s", what, sts, fmsg ); - free( fmsg ); -} - - -static char * -unQuote( const char *str ) -{ - char *ret, *adp; - - if (!(ret = Malloc( strlen( str ) + 1 ))) - return 0; - for (adp = ret; *str; str++, adp++) - if (*str == '\\') - switch (*++str) { - case 0: str--; /* fallthrough */ - case '\\': *adp = '\\'; break; - case 'n': *adp = '\n'; break; - case 't': *adp = '\t'; break; - default: *adp++ = '\\'; *adp = *str; break; - } - else - *adp = *str; - *adp = 0; - return ret; -} - -static void -str_cat_l( char **bp, const char *str, int max ) -{ - int dnl = StrNLen( str, max ); - memcpy( *bp, str, dnl ); - *bp += dnl; -} - -static void -str_cat( char **bp, const char *str ) -{ - int dnl = strlen( str ); - memcpy( *bp, str, dnl ); - *bp += dnl; -} - -static void -sd_cat( char **bp, SdRec *sdr ) -{ - if (sdr->how == SHUT_HALT) - str_cat( bp, "halt," ); - else - str_cat( bp, "reboot," ); - if (sdr->start == TO_INF) - str_cat( bp, "0," ); - else - *bp += sprintf( *bp, "%d,", sdr->start ); - if (sdr->timeout == TO_INF) - str_cat( bp, "-1," ); - else - *bp += sprintf( *bp, "%d,", sdr->timeout ); - if (sdr->force == SHUT_ASK) - str_cat( bp, "ask" ); - else if (sdr->force == SHUT_FORCE) - str_cat( bp, "force" ); - else if (sdr->force == SHUT_FORCEMY) - str_cat( bp, "forcemy" ); - else - str_cat( bp, "cancel" ); - *bp += sprintf( *bp, ",%d,%s", sdr->uid, sdr->osname ? sdr->osname : "-" ); -} - -static void -emitXSessC( struct display *di, struct display *d, void *ctx ) -{ - char *dname, *bp; - char cbuf[1024]; - - bp = cbuf; - *bp++ = '\t'; - dname = di->name; - if (!memcmp( dname, "localhost:", 10 )) - dname += 9; - str_cat_l( &bp, dname, sizeof(cbuf)/2 ); - *bp++ = ','; -#ifdef HAVE_VTS - if (di->serverVT) - bp += sprintf( bp, "vt%d", di->serverVT ); -#endif - *bp++ = ','; -#ifdef XDMCP - if (di->status == remoteLogin) { - *bp++ = ','; - str_cat_l( &bp, di->remoteHost, sizeof(cbuf)/3 ); - } else -#endif - { - if (di->userName) - str_cat_l( &bp, di->userName, sizeof(cbuf)/5 ); - *bp++ = ','; - if (di->sessName) - str_cat_l( &bp, di->sessName, sizeof(cbuf)/5 ); - } - *bp++ = ','; - if (di == d) - *bp++ = '*'; - if (di->userSess >= 0 && - (d ? (d->userSess != di->userSess && - (d->allowNuke == SHUT_NONE || - (d->allowNuke == SHUT_ROOT && d->userSess))) : - !fifoAllowNuke)) - *bp++ = '!'; - Writer( (int)ctx, cbuf, bp - cbuf ); -} - -static void -emitTTYSessC( STRUCTUTMP *ut, struct display *d, void *ctx ) -{ - struct passwd *pw; - char *bp; - int vt, l; - char cbuf[sizeof(ut->ut_line) + sizeof(ut->ut_user) + sizeof(ut->ut_host) + 16]; - char user[sizeof(ut->ut_user) + 1]; - -#ifndef BSD_UTMP - if (ut->ut_type != USER_PROCESS) - l = 0; - else -#endif - { - l = StrNLen( ut->ut_user, sizeof(ut->ut_user) ); - memcpy( user, ut->ut_user, l ); - } - user[l] = 0; - bp = cbuf; - *bp++ = '\t'; - str_cat_l( &bp, ut->ut_line, sizeof(ut->ut_line) ); - *bp++ = ','; - if (*ut->ut_host) { - *bp++ = '@'; - str_cat_l( &bp, ut->ut_host, sizeof(ut->ut_host) ); - } -#ifdef HAVE_VTS - else if ((vt = TTYtoVT( ut->ut_line ))) - bp += sprintf( bp, "vt%d", vt ); -#endif - *bp++ = ','; - str_cat( &bp, user ); - *bp++ = ','; - /* blank: session type unknown */ - *bp++ = ','; - /* blank: certainly not querying display */ - *bp++ = 't'; - if (*user && - (d ? ((d->allowNuke == SHUT_NONE || - (d->allowNuke == SHUT_ROOT && d->userSess)) && - (!(pw = getpwnam( user )) || d->userSess != (int)pw->pw_uid)) : - !fifoAllowNuke)) - *bp++ = '!'; - Writer( (int)ctx, cbuf, bp - cbuf ); -} - -static void -processCtrl( const char *string, int len, int fd, struct display *d ) -{ -#define Reply(t) Writer (fd, t, strlen (t)) - - struct display *di; - const char *word; - char **ar, **ap, *args, *bp; - SdRec sdr; - char cbuf[1024]; - - if (!(ar = initStrArr( 0 ))) - return; - for (word = string; ; string++, len--) - if (!len || *string == '\t') { - if (!(ar = addStrArr( ar, word, string - word ))) - return; - if (!len) - break; - word = string + 1; - } - word = fd >= 0 ? "socket" : "FiFo"; - if (d) - Debug( "control %s for %s received %'[s\n", word, d->name, ar ); - else - Debug( "global control %s received %'[s\n", word, ar ); - if (ar[0]) { - if (fd >= 0 && !strcmp( ar[0], "caps" )) { - if (ar[1]) - goto exce; - Reply( "ok\ttdm\tlist\t" ); - if (bootManager != BO_NONE) - Reply( "bootoptions\t" ); - if (d) { - if ((d->displayType & d_location) == dLocal) -#ifdef HAVE_VTS - Reply( "local\tactivate\t" ); -#else - Reply( "local\t" ); -#endif - if (d->allowShutdown != SHUT_NONE) { - if (d->allowShutdown == SHUT_ROOT && d->userSess) - Reply( "shutdown root\t" ); - else - Reply( "shutdown\t" ); - Reply( "shutdown ask\t" ); - if (d->allowNuke != SHUT_NONE) { - if (d->allowNuke == SHUT_ROOT && d->userSess) - Reply( "nuke root\t" ); - else - Reply( "nuke\t" ); - } - } - if ((d->displayType & d_location) == dLocal && - AnyReserveDisplays()) - Writer( fd, cbuf, sprintf( cbuf, "reserve %d\t", - idleReserveDisplays() ) ); - Reply( "lock\tsuicide\n" ); - } else { - if (fifoAllowShutdown) { - Reply( "shutdown\t" ); - if (fifoAllowNuke) - Reply( "nuke\t" ); - } - if (AnyReserveDisplays()) - Writer( fd, cbuf, sprintf( cbuf, "reserve %d\t", - idleReserveDisplays() ) ); -#ifdef HAVE_VTS - Reply( "login\tactivate\n" ); -#else - Reply( "login\n" ); -#endif - } - goto bust; - } else if (fd >= 0 && !strcmp( ar[0], "list" )) { - int flags = lstRemote | lstTTY; - if (ar[1]) { - if (!strcmp( ar[1], "all" )) - flags = lstRemote | lstPassive | lstTTY; - else if (!strcmp( ar[1], "alllocal" )) - flags = lstPassive | lstTTY; - else { - fLog( d, fd, "bad", "invalid list scope %\"s", ar[1] ); - goto bust; - } - if (ar[2]) - goto exce; - } - Reply( "ok" ); - ListSessions( flags, d, (void *)fd, emitXSessC, emitTTYSessC ); - Reply( "\n" ); - goto bust; - } else if (!strcmp( ar[0], "reserve" )) { - int lt = 60; /* XXX make default timeout configurable? */ - if (ar[1]) { - lt = strtol( ar[1], &bp, 10 ); - if (lt < 15 || *bp) { - fLog( d, fd, "bad", "invalid timeout %\"s", ar[1] ); - goto bust; - } - if (ar[2]) - goto exce; - } - if (d && (d->displayType & d_location) != dLocal) { - fLog( d, fd, "perm", "display is not local" ); - goto bust; - } - if (!StartReserveDisplay( lt )) { - fLog( d, fd, "noent", "no reserve display available" ); - goto bust; - } -#ifdef HAVE_VTS - } else if (!strcmp( ar[0], "activate" )) { - int vt; - if (!ar[1]) - goto miss; - if (ar[2]) - goto exce; - if (d && (d->displayType & d_location) != dLocal) { - fLog( d, fd, "perm", "display is not local" ); - goto bust; - } - if (ar[1][0] != 'v' || ar[1][1] != 't' || - (vt = atoi( ar[1] + 2 )) <= 0) - { - if (!(di = FindDisplayByName( ar[1] ))) { - fLog( d, fd, "noent", "display not found" ); - goto bust; - } - if ((di->displayType & d_location) != dLocal) { - fLog( d, fd, "inval", "target display is not local" ); - goto bust; - } - if (!di->serverVT) { - fLog( d, fd, "noent", "target display has no VT assigned" ); - goto bust; - } - vt = di->serverVT; - } - if (!activateVT( vt )) { - fLog( d, fd, "inval", "VT switch failed" ); - goto bust; - } -#endif - } else if (!strcmp( ar[0], "shutdown" )) { - ap = ar; - if (!*++ap) - goto miss; - sdr.force = SHUT_CANCEL; - sdr.osname = 0; - if (!strcmp( *ap, "status" )) { - if (fd < 0) - goto bust; - if (*++ap) - goto exce; - bp = cbuf; - *bp++ = 'o'; - *bp++ = 'k'; - if (sdRec.how) { - str_cat( &bp, "\tglobal," ); - sd_cat( &bp, &sdRec ); - } - if (d && d->hstent->sdRec.how) { - str_cat( &bp, "\tlocal," ); - sd_cat( &bp, &d->hstent->sdRec ); - } - *bp++ = '\n'; - Writer( fd, cbuf, bp - cbuf ); - goto bust; - } else if (!strcmp( *ap, "cancel" )) { - sdr.how = 0; - sdr.start = 0; - if (ap[1]) { - if (!d) - goto exce; - if (!strcmp( *++ap, "global" )) - sdr.start = TO_INF; - else if (strcmp( *ap, "local" )) { - fLog( d, fd, "bad", "invalid cancel scope %\"s", *ap ); - goto bust; - } - } - } else { - if (!strcmp( *ap, "reboot" )) - sdr.how = SHUT_REBOOT; - else if (!strcmp( *ap, "halt" )) - sdr.how = SHUT_HALT; - else { - fLog( d, fd, "bad", "invalid type %\"s", *ap ); - goto bust; - } - sdr.uid = -1; - if (!*++ap) - goto miss; - if (**ap == '=') { - switch (setBootOption( *ap + 1, &sdr )) { - case BO_NOMAN: - fLog( d, fd, "notsup", "boot options unavailable" ); - goto bust; - case BO_NOENT: - fLog( d, fd, "noent", "no such boot option" ); - goto bust; - case BO_IO: - fLog( d, fd, "io", "io error" ); - goto bust; - } - if (!*++ap) - goto miss; - } - sdr.start = strtol( *ap, &bp, 10 ); - if (bp != *ap && !*bp) { - if (**ap == '+') - sdr.start += now; - if (!*++ap) - goto miss; - sdr.timeout = strtol( *ap, &bp, 10 ); - if (bp == *ap || *bp) { - fLog( d, fd, "bad", "invalid timeout %\"s", ar[3] ); - goto bust; - } - if (**ap == '+') - sdr.timeout += sdr.start ? sdr.start : now; - if (sdr.timeout < 0) - sdr.timeout = TO_INF; - else { - if (!*++ap) - goto miss; - if (!strcmp( *ap, "force" )) - sdr.force = SHUT_FORCE; - else if (d && !strcmp( *ap, "forcemy" )) - sdr.force = SHUT_FORCEMY; - else if (strcmp( *ap, "cancel" )) { - fLog( d, fd, "bad", "invalid timeout action %\"s", - *ap ); - goto bust; - } - } - } else { - sdr.timeout = 0; - if (d && !strcmp( *ap, "ask" )) - sdr.force = SHUT_ASK; - else if (!strcmp( *ap, "forcenow" )) - sdr.force = SHUT_FORCE; - else if (!strcmp( *ap, "schedule" )) - sdr.timeout = TO_INF; - else if (strcmp( *ap, "trynow" )) { - fLog( d, fd, "bad", "invalid mode %\"s", *ap ); - goto bust; - } - } - } - if (*++ap) - goto exce; - if (d) { - sdr.uid = d->userSess >= 0 ? d->userSess : 0; - if (d->allowShutdown == SHUT_NONE || - (d->allowShutdown == SHUT_ROOT && sdr.uid && - sdr.force != SHUT_ASK)) - { - fLog( d, fd, "perm", "shutdown forbidden" ); - goto bust; - } - if (!sdr.how && !sdr.start) { - if (d->hstent->sdRec.osname) - free( d->hstent->sdRec.osname ); - d->hstent->sdRec = sdr; - } else { - if (sdRec.how && sdRec.force == SHUT_FORCE && - ((d->allowNuke == SHUT_NONE && sdRec.uid != sdr.uid) || - (d->allowNuke == SHUT_ROOT && sdr.uid))) - { - fLog( d, fd, "perm", "overriding forced shutdown forbidden" ); - goto bust; - } - if (sdr.force == SHUT_FORCE && - (d->allowNuke == SHUT_NONE || - (d->allowNuke == SHUT_ROOT && sdr.uid))) - { - fLog( d, fd, "perm", "forced shutdown forbidden" ); - goto bust; - } - if (!sdr.start) { - if (d->hstent->sdRec.osname) - free( d->hstent->sdRec.osname ); - d->hstent->sdRec = sdr; - } else { - if (!sdr.how) - cancelShutdown(); - else { - if (sdRec.osname) - free( sdRec.osname ); - sdRec = sdr; - } - } - } - } else { - if (!fifoAllowShutdown) { - fLog( d, fd, "perm", "shutdown forbidden" ); - goto bust; - } - if (sdRec.how && sdRec.force == SHUT_FORCE && - sdRec.uid != -1 && !fifoAllowNuke) - { - fLog( d, fd, "perm", "overriding forced shutdown forbidden" ); - goto bust; - } - if (!sdr.how) - cancelShutdown(); - else { - if (sdr.force != SHUT_CANCEL) { - if (!fifoAllowNuke) { - fLog( d, fd, "perm", "forced shutdown forbidden" ); - goto bust; - } - } else { - if (!sdr.start && !sdr.timeout && AnyActiveDisplays()) { - fLog( d, fd, "busy", "user sessions running" ); - goto bust; - } - } - sdr.uid = -1; - if (sdRec.osname) - free( sdRec.osname ); - sdRec = sdr; - } - } - } else if (fd >= 0 && !strcmp( ar[0], "listbootoptions" )) { - char **opts; - int def, cur, i, j; - - if (ar[1]) - goto exce; - switch (getBootOptions( &opts, &def, &cur )) { - case BO_NOMAN: - fLog( d, fd, "notsup", "boot options unavailable" ); - goto bust; - case BO_IO: - fLog( d, fd, "io", "io error" ); - goto bust; - } - Reply( "ok\t" ); - for (i = 0; opts[i]; i++) { - bp = cbuf; - if (i) - *bp++ = ' '; - for (j = 0; opts[i][j]; j++) - if (opts[i][j] == ' ') { - *bp++ = '\\'; - *bp++ = 's'; - } else - *bp++ = opts[i][j]; - Writer( fd, cbuf, bp - cbuf ); - } - freeStrArr( opts ); - Writer( fd, cbuf, sprintf( cbuf, "\t%d\t%d\n", def, cur ) ); - goto bust; - } else if (d) { - if (!strcmp( ar[0], "lock" )) { - if (ar[1]) - goto exce; - d->hstent->lock = 1; - } else if (!strcmp( ar[0], "unlock" )) { - if (ar[1]) - goto exce; - d->hstent->lock = 0; - } else if (!strcmp( ar[0], "suicide" )) { - if (ar[1]) - goto exce; - if (d->status == running && d->pid != -1) { - TerminateProcess( d->pid, SIGTERM ); - d->status = raiser; - } - } else { - fLog( d, fd, "nosys", "unknown command" ); - goto bust; - } - } else { - if (!strcmp( ar[0], "login" )) { - int nuke; - if (arrLen( ar ) < 5) { - miss: - fLog( d, fd, "bad", "missing argument(s)" ); - goto bust; - } - if (!(di = FindDisplayByName( ar[1] ))) { - fLog( d, fd, "noent", "display %s not found", ar[1] ); - goto bust; - } - if (ar[5]) { - if (!(args = unQuote( ar[5] ))) { - fLog( d, fd, "nomem", "out of memory" ); - goto bust; - } - if (ar[6]) { - free( args ); - exce: - fLog( d, fd, "bad", "excess argument(s)" ); - goto bust; - } - setNLogin( di, ar[3], ar[4], args, 2 ); - free( args ); - } else - setNLogin( di, ar[3], ar[4], 0, 2 ); - nuke = !strcmp( ar[2], "now" ); - switch (di->status) { - case running: - if (di->pid != -1 && (di->userSess < 0 || nuke)) { - TerminateProcess( di->pid, SIGTERM ); - di->status = raiser; - } - break; - case remoteLogin: - if (di->serverPid != -1 && nuke) - TerminateProcess( di->serverPid, di->termSignal ); - break; - case reserve: - di->status = notRunning; - break; - case textMode: -#ifndef HAVE_VTS - SwitchToX( di ); -#endif - break; - default: - break; - } - } else { - fLog( d, fd, "nosys", "unknown command" ); - goto bust; - } - } - if (fd >= 0) - Reply( "ok\n" ); - } - bust: - freeStrArr( ar ); -} - -static int -handleChan( struct display *d, struct bsock *cs, int fd, FD_TYPE *reads ) -{ - char *bufp, *nbuf, *obuf, *eol; - int len, bl, llen; - char buf[1024]; - - bl = cs->buflen; - obuf = cs->buffer; - if (bl <= 0 && FD_ISSET( cs->fd, reads )) { - FD_CLR( cs->fd, reads ); - bl = -bl; - memcpy( buf, obuf, bl ); - if ((len = Reader( cs->fd, buf + bl, sizeof(buf) - bl )) <= 0) - return -1; - bl += len; - bufp = buf; - } else { - len = 0; - bufp = obuf; - } - if (bl > 0) { - if ((eol = memchr( bufp, '\n', bl ))) { - llen = eol - bufp + 1; - bl -= llen; - if (bl) { - if (!(nbuf = Malloc( bl ))) - return -1; - memcpy( nbuf, bufp + llen, bl ); - } else - nbuf = 0; - cs->buffer = nbuf; - cs->buflen = bl; - processCtrl( bufp, llen - 1, fd, d ); - if (obuf) - free( obuf ); - return 1; - } else if (!len) { - if (fd >= 0) - cs->buflen = -bl; - else - fLog( d, -1, "bad", "unterminated command" ); - } - } - return 0; -} - -int -handleCtrl( FD_TYPE *reads, struct display *d ) -{ - CtrlRec *cr = d ? &d->ctrl : &ctrl; - struct cmdsock *cs, **csp; - - if (cr->fifo.fd >= 0) { - switch (handleChan( d, &cr->fifo, -1, reads )) { - case -1: - if (cr->fifo.buffer) - free( cr->fifo.buffer ); - cr->fifo.buflen = 0; - break; - case 1: - return 1; - default: - break; - } - } - if (cr->fd >= 0 && FD_ISSET( cr->fd, reads )) - acceptSock( cr ); - else { - for (csp = &cr->css; (cs = *csp); ) { - switch (handleChan( d, &cs->sock, cs->sock.fd, reads )) { - case -1: - *csp = cs->next; - nukeSock( cs ); - continue; - case 1: - return 1; - default: - break; - } - csp = &cs->next; - } - } - return 0; -} diff --git a/kdm/backend/daemon.c b/kdm/backend/daemon.c deleted file mode 100644 index 79d9e47ff..000000000 --- a/kdm/backend/daemon.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000,2001,2003 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - */ - -#include "dm.h" -#include "dm_error.h" - -void -BecomeDaemon( void ) -{ - int pfd[2]; - - /* - * fork so that the process goes into the background automatically. Also - * has a nice side effect of having the child process get inherited by - * init (pid 1). - * Create a pipe and block on it, so the parent knows when the child is - * done with detaching. This eliminates the possibility that the child - * might get killed when the init script that's running xdm exits. - */ - - if (pipe( pfd )) - pfd[0] = pfd[1] = -1; /* so what ...? */ - switch (fork ()) { - case 0: - /* child */ - break; - case -1: - /* error */ - LogError( "Daemon fork failed: %m\n" ); - break; - - default: - /* parent */ - close( pfd[1] ); - read( pfd[0], &pfd[1] /* dummy */, 1 ); - exit( 0 ); - } - - /* don't use daemon() - it doesn't buy us anything but an additional fork */ - - setsid(); - - close( pfd[0] ); - close( pfd[1] ); /* tell parent that we're done with detaching */ - - chdir( "/" ); -} diff --git a/kdm/backend/dm.c b/kdm/backend/dm.c deleted file mode 100644 index d372dd472..000000000 --- a/kdm/backend/dm.c +++ /dev/null @@ -1,1669 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2005 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * display manager - */ - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_VTS -# include -# include -#endif - -static void SigHandler( int n ); -static int ScanConfigs( int force ); -static void StartDisplays( void ); -#define XS_KEEP 0 -#define XS_RESTART 1 -#define XS_RETRY 2 -static void ExitDisplay( struct display *d, int endState, int serverCmd, int goodExit ); -static void rStopDisplay( struct display *d, int endState ); -static void MainLoop( void ); - -static int signalFds[2]; - -#if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE) -static char *Title; -static int TitleLen; -#endif - -static int StorePid( void ); - -static int Stopping; -SdRec sdRec = { 0, 0, 0, TO_INF, TO_INF, 0, 0, 0 }; - -time_t now; - -char *prog, *progpath; - -int -main( int argc, char **argv ) -{ - int oldpid, oldumask, fd, noDaemonMode; - char *pt, *errorLogFile, **opts; - - /* make sure at least world write access is disabled */ - if (((oldumask = umask( 022 )) & 002) == 002) - (void)umask( oldumask ); - - /* give /dev/null as stdin */ - if ((fd = open( "/dev/null", O_RDONLY )) > 0) { - dup2( fd, 0 ); - close( fd ); - } - if (fcntl( 1, F_GETFD ) < 0) - dup2( 0, 1 ); - if (fcntl( 2, F_GETFD ) < 0) - dup2( 0, 2 ); - - if (argv[0][0] == '/') { - if (!StrDup( &progpath, argv[0] )) - Panic( "Out of memory" ); - } else -#ifdef __linux__ - { - /* note that this will resolve symlinks ... */ - int len; - char fullpath[PATH_MAX]; - if ((len = readlink( "/proc/self/exe", fullpath, sizeof(fullpath) )) < 0) - Panic( "Invoke with full path specification or mount /proc" ); - if (!StrNDup( &progpath, fullpath, len )) - Panic( "Out of memory" ); - } -#else -# if 0 - Panic( "Must be invoked with full path specification" ); -# else - { - char directory[PATH_MAX+1]; - if (!getcwd( directory, sizeof(directory) )) - Panic( "Can't find myself (getcwd failed)" ); - if (strchr( argv[0], '/' )) - StrApp( &progpath, directory, "/", argv[0], (char *)0 ); - else { - int len; - char *path, *name, *thenam, nambuf[PATH_MAX+1]; - char *pathe; - - if (!(path = getenv( "PATH" ))) - Panic( "Can't find myself (no PATH)" ); - len = strlen( argv[0] ); - name = nambuf + PATH_MAX - len; - memcpy( name, argv[0], len + 1 ); - *--name = '/'; - do { - if (!(pathe = strchr( path, ':' ))) - pathe = path + strlen( path ); - len = pathe - path; - if (!len || (len == 1 && *path == '.')) { - len = strlen( directory ); - path = directory; - } - thenam = name - len; - if (thenam >= nambuf) { - memcpy( thenam, path, len ); - if (!access( thenam, X_OK )) - goto found; - } - path = pathe; - } while (*path++ != '\0'); - Panic( "Can't find myself (not in PATH)" ); - found: - if (!StrDup( &progpath, thenam )) - Panic( "Out of memory" ); - } - } -# endif -#endif - prog = strrchr( progpath, '/' ) + 1; - -#if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE) - Title = argv[0]; - TitleLen = (argv[argc - 1] + strlen( argv[argc - 1] )) - Title; -#endif - - /* - * Parse command line options - */ - noDaemonMode = getppid(); - errorLogFile = 0; - if (!(opts = Malloc( 2 * sizeof(char *) ))) - return 1; - opts[0] = (char *)""; - opts[1] = 0; - while (*++argv) { - if (**argv != '-') - break; - pt = *argv + 1; - if (*pt == '-') - pt++; - if (!strcmp( pt, "help" ) || !strcmp( pt, "h" )) { - printf( "Usage: %s [options] [tty]\n" -" -daemon\t - Daemonize even when started by init\n" -" -nodaemon\t - Don't daemonize even when started from command line\n" -" -config - Use alternative master configuration file\n" -" -xrm \t - Override frontend-specific resource\n" -" -error \t - Use alternative log file\n" -" -debug \t - Debug option bitfield:\n" -"\t\t\t0x1 - core log\n" -"\t\t\t0x2 - config reader log\n" -"\t\t\t0x4 - greeter log\n" -"\t\t\t0x8 - IPC log\n" -"\t\t\t0x10 - session sub-daemon post-fork delay\n" -"\t\t\t0x20 - config reader post-start delay\n" -"\t\t\t0x40 - greeter post-start delay\n" -"\t\t\t0x80 - don't use syslog\n" -"\t\t\t0x100 - core Xauth log\n" -"\t\t\t0x400 - valgrind config reader and greeter\n" -"\t\t\t0x800 - strace config reader and greeter\n" - , prog ); - exit( 0 ); - } else if (!strcmp( pt, "daemon" )) - noDaemonMode = 0; - else if (!strcmp( pt, "nodaemon" )) - noDaemonMode = 1; - else if (argv[1] && !strcmp( pt, "config" )) - StrDup( opts, *++argv ); - else if (argv[1] && !strcmp( pt, "xrm" )) - opts = addStrArr( opts, *++argv, -1 ); - else if (argv[1] && !strcmp( pt, "debug" )) - sscanf( *++argv, "%i", &debugLevel ); - else if (argv[1] && (!strcmp( pt, "error" ) || !strcmp( pt, "logfile" ))) - errorLogFile = *++argv; - else { - fprintf( stderr, "\"%s\" is an unknown option or is missing a parameter\n", *argv ); - exit( 1 ); - } - } - - /* - * Only allow root to run in non-debug mode to avoid problems - */ - if (!debugLevel && getuid()) { - fprintf( stderr, "Only root wants to run %s\n", prog ); - exit( 1 ); - } - - InitErrorLog( errorLogFile ); - - if (noDaemonMode != 1) - BecomeDaemon(); - - /* - * Step 1 - load configuration parameters - */ - if (!InitResources( opts ) || ScanConfigs( FALSE ) < 0) - LogPanic( "Config reader failed. Aborting ...\n" ); - - /* SUPPRESS 560 */ - if ((oldpid = StorePid())) { - if (oldpid == -1) - LogError( "Can't create/lock pid file %s\n", pidFile ); - else - LogError( "Can't lock pid file %s, another xdm is running (pid %d)\n", - pidFile, oldpid ); - exit( 1 ); - } - -#ifdef NEED_ENTROPY - AddOtherEntropy(); -#endif - - /* - * We used to clean up old authorization files here. As authDir is - * supposed to be /var/run/xauth or /tmp, we needn't to care for it. - */ - -#ifdef XDMCP - init_session_id(); -#else - Debug( "not compiled for XDMCP\n" ); -#endif - if (pipe( signalFds )) - LogPanic( "Unable to create signal notification pipe.\n" ); - RegisterInput( signalFds[0] ); - RegisterCloseOnFork( signalFds[0] ); - RegisterCloseOnFork( signalFds[1] ); - (void)Signal( SIGTERM, SigHandler ); - (void)Signal( SIGINT, SigHandler ); - (void)Signal( SIGHUP, SigHandler ); - (void)Signal( SIGCHLD, SigHandler ); - (void)Signal( SIGUSR1, SigHandler ); - - /* - * Step 2 - run a sub-daemon for each entry - */ -#ifdef XDMCP - UpdateListenSockets(); -#endif - openCtrl( 0 ); - MainLoop(); - closeCtrl( 0 ); - if (sdRec.how) { - commitBootOption(); - if (Fork() <= 0) { - char *cmd = sdRec.how == SHUT_HALT ? cmdHalt : cmdReboot; - execute( parseArgs( (char **)0, cmd ), (char **)0 ); - LogError( "Failed to execute shutdown command %\"s\n", cmd ); - exit( 1 ); - } else { - sigset_t mask; - sigemptyset( &mask ); - sigaddset( &mask, SIGCHLD ); - sigaddset( &mask, SIGHUP ); - sigsuspend( &mask ); - } - } - Debug( "nothing left to do, exiting\n" ); - return 0; -} - - -#ifdef HAVE_VTS -int -TTYtoVT( const char *tty ) -{ - return memcmp( tty, "tty", 3 ) ? 0 : atoi( tty + 3 ); -} - -int -activateVT( int vt ) -{ - int ret = 0; - int con = open( "/dev/console", O_RDONLY ); - if (con >= 0) { - if (!ioctl( con, VT_ACTIVATE, vt )) - ret = 1; - close( con ); - } - return ret; -} - - -static void -WakeDisplay( struct display *d ) -{ - if (d->status == textMode) - d->status = (d->displayType & d_lifetime) == dReserve ? reserve : notRunning; -} -#endif - -enum utState { UtDead, UtWait, UtActive }; - -struct utmps { - struct utmps *next; -#ifndef HAVE_VTS - struct display *d; -#endif - time_t time; - enum utState state; - int hadSess; -}; - -#define TIME_LOG 40 -#define TIME_RELOG 10 - -static struct utmps *utmpList; -static time_t utmpTimeout = TO_INF; - -static void -bombUtmp( void ) -{ - struct utmps *utp; - - while ((utp = utmpList)) { -#ifdef HAVE_VTS - ForEachDisplay( WakeDisplay ); -#else - utp->d->status = notRunning; -#endif - utmpList = utp->next; - free( utp ); - } -} - -static void -CheckUtmp( void ) -{ - static time_t modtim; - time_t nck; - time_t ends; - struct utmps *utp, **utpp; - struct stat st; -#ifdef BSD_UTMP - int fd; - struct utmp ut[1]; -#else - STRUCTUTMP *ut; -#endif - - if (!utmpList) - return; - if (stat( UTMP_FILE, &st )) { - LogError( UTMP_FILE " not found - cannot use console mode\n" ); - bombUtmp(); - return; - } - if (modtim != st.st_mtime) { - Debug( "rescanning " UTMP_FILE "\n" ); - for (utp = utmpList; utp; utp = utp->next) - utp->state = UtDead; -#ifdef BSD_UTMP - if ((fd = open( UTMP_FILE, O_RDONLY )) < 0) { - LogError( "Cannot open " UTMP_FILE " - cannot use console mode\n" ); - bombUtmp(); - return; - } - while (Reader( fd, ut, sizeof(ut[0]) ) == sizeof(ut[0])) -#else - SETUTENT(); - while ((ut = GETUTENT())) -#endif - { - for (utp = utmpList; utp; utp = utp->next) { -#ifdef HAVE_VTS - char **line; - for (line = consoleTTYs; *line; line++) - if (!strncmp( *line, ut->ut_line, sizeof(ut->ut_line) )) - goto hitlin; - continue; - hitlin: -#else - if (strncmp( utp->d->console, ut->ut_line, sizeof(ut->ut_line) )) - continue; -#endif -#ifdef BSD_UTMP - if (!*ut->ut_user) { -#else - if (ut->ut_type != USER_PROCESS) { -#endif -#ifdef HAVE_VTS - if (utp->state == UtActive) - break; -#endif - utp->state = UtWait; - } else { - utp->hadSess = 1; - utp->state = UtActive; - } - if (utp->time < ut->ut_time) /* theoretically superfluous */ - utp->time = ut->ut_time; - break; - } - } -#ifdef BSD_UTMP - close( fd ); -#else - ENDUTENT(); -#endif - modtim = st.st_mtime; - } - for (utpp = &utmpList; (utp = *utpp); ) { - if (utp->state != UtActive) { - if (utp->state == UtDead) /* shouldn't happen ... */ - utp->time = 0; - ends = utp->time + (utp->hadSess ? TIME_RELOG : TIME_LOG); - if (ends <= now) { -#ifdef HAVE_VTS - ForEachDisplay( WakeDisplay ); - Debug( "console login timed out\n" ); -#else - utp->d->status = notRunning; - Debug( "console login for %s at %s timed out\n", - utp->d->name, utp->d->console ); -#endif - *utpp = utp->next; - free( utp ); - continue; - } else - nck = ends; - } else - nck = TIME_RELOG + now; - if (nck < utmpTimeout) - utmpTimeout = nck; - utpp = &(*utpp)->next; - } -} - -static void -#ifdef HAVE_VTS -SwitchToTty( void ) -#else -SwitchToTty( struct display *d ) -#endif -{ - struct utmps *utp; -#ifdef HAVE_VTS - int vt; -#endif - - if (!(utp = Malloc( sizeof(*utp) ))) { -#ifdef HAVE_VTS - ForEachDisplay( WakeDisplay ); -#else - d->status = notRunning; -#endif - return; - } -#ifndef HAVE_VTS - d->status = textMode; - utp->d = d; -#endif - utp->time = now; - utp->hadSess = 0; - utp->next = utmpList; - utmpList = utp; - CheckUtmp(); - -#ifdef HAVE_VTS - if ((vt = TTYtoVT( *consoleTTYs ))) - activateVT( vt ); -#endif - - /* XXX output something useful here */ -} - -#ifdef HAVE_VTS -static void -StopToTTY( struct display *d ) -{ - if ((d->displayType & d_location) == dLocal) - switch (d->status) { - default: - rStopDisplay( d, DS_TEXTMODE | 0x100 ); - case reserve: - case textMode: - break; - } -} - -static void -CheckTTYMode( void ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if (d->status == zombie) - return; - - SwitchToTty(); -} - -#else - -void -SwitchToX( struct display *d ) -{ - struct utmps *utp, **utpp; - - for (utpp = &utmpList; (utp = *utpp); utpp = &(*utpp)->next) - if (utp->d == d) { - *utpp = utp->next; - free( utp ); - d->status = notRunning; - return; - } -} -#endif - -#ifdef XDMCP -static void -StartRemoteLogin( struct display *d ) -{ - char **argv; - int pid; - - Debug( "StartRemoteLogin for %s\n", d->name ); - /* HACK: omitting LoadDisplayResources( d ) here! */ - switch (pid = Fork()) { - case 0: - argv = PrepServerArgv( d, d->serverArgsRemote ); - if (!(argv = addStrArr( argv, "-once", 5 )) || - !(argv = addStrArr( argv, "-query", 6 )) || - !(argv = addStrArr( argv, d->remoteHost, -1 ))) - exit( 1 ); - Debug( "exec %\"[s\n", argv ); - (void)execv( argv[0], argv ); - LogError( "X server %\"s cannot be executed\n", argv[0] ); - - /* Let's try again with some standard paths */ - argv[0] = (char *)realloc(argv[0], strlen("/usr/X11R6/bin/X") + 1); - if (argv[0] != NULL) { - argv[0] = "/usr/X11R6/bin/X"; - Debug( "exec %\"[s\n", argv ); - (void)execv( argv[0], argv ); - LogError( "X server %\"s cannot be executed\n", argv[0] ); - - argv[0] = "/usr/bin/X"; /* Shorter than the previous file name */ - Debug( "exec %\"[s\n", argv ); - (void)execv( argv[0], argv ); - LogError( "X server %\"s cannot be executed\n", argv[0] ); - } - - exit( 1 ); - case -1: - LogError( "Forking X server for remote login failed: %m" ); - d->status = notRunning; - return; - default: - break; - } - Debug( "X server forked, pid %d\n", pid ); - d->serverPid = pid; - - d->status = remoteLogin; -} -#endif - - -static void -StopInactiveDisplay( struct display *d ) -{ - if (d->status != remoteLogin && d->userSess < 0) - StopDisplay( d ); -} - -static void -stoppen( int force ) -{ -#ifdef XDMCP - request_port = 0; - UpdateListenSockets(); -#endif - if (force) - ForEachDisplay( StopDisplay ); - else - ForEachDisplay( StopInactiveDisplay ); - Stopping = 1; -} - - -void -setNLogin( struct display *d, - const char *nuser, const char *npass, char *nargs, int rl ) -{ - struct disphist *he = d->hstent; - he->rLogin = - (ReStr( &he->nuser, nuser ) && - ReStr( &he->npass, npass ) && - ReStr( &he->nargs, nargs )) ? rl : 0; - Debug( "set next login for %s, level %d\n", nuser, rl ); -} - -static void -processDPipe( struct display *d ) -{ - char *user, *pass, *args; - int cmd; - GTalk dpytalk; -#ifdef XDMCP - int ct, len; - ARRAY8 ca, ha; -#endif - - dpytalk.pipe = &d->pipe; - if (Setjmp( dpytalk.errjmp )) { - StopDisplay( d ); - return; - } - GSet( &dpytalk ); - if (!GRecvCmd( &cmd )) { - /* process already exited */ - UnregisterInput( d->pipe.rfd ); - return; - } - switch (cmd) { - case D_User: - d->userSess = GRecvInt(); - d->userName = GRecvStr(); - d->sessName = GRecvStr(); - break; - case D_ReLogin: - user = GRecvStr(); - pass = GRecvStr(); - args = GRecvStr(); - setNLogin( d, user, pass, args, 1 ); - free( args ); - free( pass ); - free( user ); - break; -#ifdef XDMCP - case D_ChooseHost: - ca.data = (unsigned char *)GRecvArr( &len ); - ca.length = (CARD16)len; - ct = GRecvInt(); - ha.data = (unsigned char *)GRecvArr( &len ); - ha.length = (CARD16)len; - RegisterIndirectChoice( &ca, ct, &ha ); - XdmcpDisposeARRAY8( &ha ); - XdmcpDisposeARRAY8( &ca ); - break; - case D_RemoteHost: - if (d->remoteHost) - free( d->remoteHost ); - d->remoteHost = GRecvStr(); - break; -#endif - case D_XConnOk: - startingServer = 0; - break; - default: - LogError( "Internal error: unknown D_* command %d\n", cmd ); - StopDisplay( d ); - break; - } -} - -static void -emitXSessG( struct display *di, struct display *d, void *ctx ATTR_UNUSED ) -{ - GSendStr( di->name ); - GSendStr( "" ); -#ifdef HAVE_VTS - GSendInt( di->serverVT ); -#endif -#ifdef XDMCP - if (di->status == remoteLogin) { - GSendStr( "" ); - GSendStr( di->remoteHost ); - } else -#endif - { - GSendStr( di->userName ); - GSendStr( di->sessName ); - } - GSendInt( di == d ? isSelf : 0 ); -} - -static void -emitTTYSessG( STRUCTUTMP *ut, struct display *d ATTR_UNUSED, void *ctx ATTR_UNUSED ) -{ - GSendStrN( ut->ut_line, sizeof(ut->ut_line) ); - GSendStrN( ut->ut_host, sizeof(ut->ut_host) ); -#ifdef HAVE_VTS - GSendInt( TTYtoVT( ut->ut_line ) ); -#endif -#ifdef BSD_UTMP - GSendStrN( *ut->ut_user ? ut->ut_user : 0, sizeof(ut->ut_user) ); -#else - GSendStrN( ut->ut_type == USER_PROCESS ? ut->ut_user : 0, sizeof(ut->ut_user) ); -#endif - GSendStr( 0 ); /* session type unknown */ - GSendInt( isTTY ); -} - -static void -processGPipe( struct display *d ) -{ - char **opts, *option; - int cmd, ret, dflt, curr; - GTalk dpytalk; - - dpytalk.pipe = &d->gpipe; - if (Setjmp( dpytalk.errjmp )) { - StopDisplay( d ); - return; - } - GSet( &dpytalk ); - if (!GRecvCmd( &cmd )) { - /* process already exited */ - UnregisterInput( d->gpipe.rfd ); - return; - } - switch (cmd) { - case G_ListBootOpts: - ret = getBootOptions( &opts, &dflt, &curr ); - GSendInt( ret ); - if (ret == BO_OK) { - GSendArgv( opts ); - freeStrArr( opts ); - GSendInt( dflt ); - GSendInt( curr ); - } - break; - case G_Shutdown: - sdRec.how = GRecvInt(); - sdRec.start = GRecvInt(); - sdRec.timeout = GRecvInt(); - sdRec.force = GRecvInt(); - sdRec.uid = GRecvInt(); - option = GRecvStr(); - setBootOption( option, &sdRec ); - if (option) - free( option ); - break; - case G_QueryShutdown: - GSendInt( sdRec.how ); - GSendInt( sdRec.start ); - GSendInt( sdRec.timeout ); - GSendInt( sdRec.force ); - GSendInt( sdRec.uid ); - GSendStr( sdRec.osname ); - break; - case G_List: - ListSessions( GRecvInt(), d, 0, emitXSessG, emitTTYSessG ); - GSendInt( 0 ); - break; -#ifdef HAVE_VTS - case G_Activate: - activateVT( GRecvInt() ); - break; -#endif - case G_Console: -#ifdef HAVE_VTS - if (*consoleTTYs) { /* sanity check against greeter */ - ForEachDisplay( StopToTTY ); - CheckTTYMode(); - } -#else - if (*d->console) /* sanity check against greeter */ - rStopDisplay( d, DS_TEXTMODE ); -#endif - break; - default: - LogError( "Internal error: unknown G_* command %d\n", cmd ); - StopDisplay( d ); - break; - } -} - - -static int -ScanConfigs( int force ) -{ - int ret; - - if ((ret = LoadDMResources( force )) <= 0) - return ret; - ScanServers(); -#ifdef XDMCP - ScanAccessDatabase( force ); -#endif - return 1; -} - -static void -MarkDisplay( struct display *d ) -{ - d->stillThere = 0; -} - -static void -RescanConfigs( int force ) -{ - if (ScanConfigs( force ) > 0) { -#ifdef XDMCP - UpdateListenSockets(); -#endif - updateCtrl(); - } -} - -void -cancelShutdown( void ) -{ - sdRec.how = 0; - if (sdRec.osname) { - free( sdRec.osname ); - sdRec.osname = 0; - } - Stopping = 0; - RescanConfigs( TRUE ); -} - - -static void -ReapChildren( void ) -{ - int pid; - struct display *d; - waitType status; - - while ((pid = waitpid( -1, &status, WNOHANG )) > 0) - { - Debug( "manager wait returns pid %d sig %d core %d code %d\n", - pid, waitSig( status ), waitCore( status ), waitCode( status ) ); - /* SUPPRESS 560 */ - if ((d = FindDisplayByPid( pid ))) { - d->pid = -1; - UnregisterInput( d->pipe.rfd ); - GClosen (&d->pipe); - UnregisterInput( d->gpipe.rfd ); - GClosen (&d->gpipe); - closeCtrl( d ); - switch (waitVal( status )) { -#ifdef XDMCP - case EX_REMOTE: - Debug( "display exited with EX_REMOTE\n" ); - ExitDisplay( d, DS_REMOTE, 0, 0 ); - break; -#endif - case EX_NORMAL: - /* (any type of) session ended */ - Debug( "display exited with EX_NORMAL\n" ); - if ((d->displayType & d_lifetime) == dReserve) - ExitDisplay( d, DS_RESERVE, 0, 0 ); - else - ExitDisplay( d, DS_RESTART, XS_KEEP, TRUE ); - break; -#if 0 - case EX_REMANAGE_DPY: - /* user session ended */ - Debug( "display exited with EX_REMANAGE_DPY\n" ); - ExitDisplay( d, DS_RESTART, XS_KEEP, TRUE ); - break; -#endif - case EX_OPENFAILED_DPY: - /* WaitForServer() failed */ - LogError( "Display %s cannot be opened\n", d->name ); -#ifdef XDMCP - /* - * no display connection was ever made, tell the - * terminal that the open attempt failed - */ - if ((d->displayType & d_origin) == dFromXDMCP) - SendFailed( d, "cannot open display" ); -#endif - ExitDisplay( d, DS_RESTART, XS_RETRY, FALSE ); - break; - case waitCompose( SIGTERM,0,0 ): - /* killed before/during WaitForServer() - - local Xserver died - - display stopped (is zombie) - - "login now" and "suicide" pipe commands (is raiser) - */ - Debug( "display exited on SIGTERM\n" ); - ExitDisplay( d, DS_RESTART, XS_RETRY, FALSE ); - break; - case EX_AL_RESERVER_DPY: - /* - killed after WaitForServer() - - Xserver dead after remote session exit - */ - Debug( "display exited with EX_AL_RESERVER_DPY\n" ); - ExitDisplay( d, DS_RESTART, XS_RESTART, FALSE ); - break; - case EX_RESERVER_DPY: - /* induced by greeter: - - could not secure display - - requested by user - */ - Debug( "display exited with EX_RESERVER_DPY\n" ); - ExitDisplay( d, DS_RESTART, XS_RESTART, TRUE ); - break; - case EX_UNMANAGE_DPY: - /* some fatal error */ - Debug( "display exited with EX_UNMANAGE_DPY\n" ); - ExitDisplay( d, DS_REMOVE, 0, 0 ); - break; - default: - /* prolly crash */ - LogError( "Unknown session exit code %d (sig %d) from manager process\n", - waitCode( status ), waitSig( status ) ); - ExitDisplay( d, DS_REMOVE, 0, 0 ); - break; - } - } else if ((d = FindDisplayByServerPid( pid ))) { - d->serverPid = -1; - switch (d->status) { - case zombie: - Debug( "zombie X server for display %s reaped\n", d->name ); -#ifdef HAVE_VTS - if (d->serverVT && d->zstatus != DS_REMOTE) { - if (d->follower) { - d->follower->serverVT = d->serverVT; - d->follower = 0; - } else { - int con = open( "/dev/console", O_RDONLY ); - if (con >= 0) { - struct vt_stat vtstat; - ioctl( con, VT_GETSTATE, &vtstat ); - if (vtstat.v_active == d->serverVT) { - int vt = 1; - struct display *di; - for (di = displays; di; di = di->next) - if (di != d && di->serverVT) - vt = di->serverVT; - for (di = displays; di; di = di->next) - if (di != d && di->serverVT && - (di->userSess >= 0 || - di->status == remoteLogin)) - vt = di->serverVT; - ioctl( con, VT_ACTIVATE, vt ); - } - ioctl( con, VT_DISALLOCATE, d->serverVT ); - close( con ); - } - } - d->serverVT = 0; - } -#endif - rStopDisplay( d, d->zstatus ); - break; - case phoenix: - Debug( "phoenix X server arises, restarting display %s\n", - d->name ); - d->status = notRunning; - break; - case remoteLogin: - Debug( "remote login X server for display %s exited\n", - d->name ); - d->status = ((d->displayType & d_lifetime) == dReserve) ? - reserve : notRunning; - break; - case raiser: - LogError( "X server for display %s terminated unexpectedly\n", - d->name ); - /* don't kill again */ - break; - case running: - if (startingServer == d && d->serverStatus != ignore) { - if (d->serverStatus == starting && waitCode( status ) != 47) - LogError( "X server died during startup\n" ); - StartServerFailed(); - break; - } - LogError( "X server for display %s terminated unexpectedly\n", - d->name ); - if (d->pid != -1) { - Debug( "terminating session pid %d\n", d->pid ); - TerminateProcess( d->pid, SIGTERM ); - } - break; - case notRunning: - case textMode: - case reserve: - /* this cannot happen */ - Debug( "X server exited for passive (%d) session on display %s\n", - (int)d->status, d->name ); - break; - } - } else - Debug( "unknown child termination\n" ); - } -#ifdef NEED_ENTROPY - AddOtherEntropy(); -#endif -} - -static int -wouldShutdown( void ) -{ - struct display *d; - - if (sdRec.force != SHUT_CANCEL) { - if (sdRec.force == SHUT_FORCEMY) - for (d = displays; d; d = d->next) - if (d->status == remoteLogin || - (d->userSess >= 0 && d->userSess != sdRec.uid)) - return 0; - return 1; - } - return !AnyActiveDisplays(); -} - -FD_TYPE WellKnownSocketsMask; -int WellKnownSocketsMax; -int WellKnownSocketsCount; - -void -RegisterInput( int fd ) -{ - /* can be omited, as it is always called right after opening a socket - if (!FD_ISSET (fd, &WellKnownSocketsMask)) - */ - { - FD_SET( fd, &WellKnownSocketsMask ); - if (fd > WellKnownSocketsMax) - WellKnownSocketsMax = fd; - WellKnownSocketsCount++; - } -} - -void -UnregisterInput( int fd ) -{ - /* the check _is_ necessary, as some handles are unregistered before - the regular close sequence. - */ - if (FD_ISSET( fd, &WellKnownSocketsMask )) { - FD_CLR( fd, &WellKnownSocketsMask ); - WellKnownSocketsCount--; - } -} - -static void -SigHandler( int n ) -{ - int olderrno = errno; - char buf = (char)n; - /* Debug( "caught signal %d\n", n ); this hangs in syslog() */ - write( signalFds[1], &buf, 1 ); -#ifdef __EMX__ - (void)Signal( n, SigHandler ); -#endif - errno = olderrno; -} - -static void -MainLoop( void ) -{ - struct display *d; - struct timeval *tvp, tv; - time_t to; - int nready; - char buf; - FD_TYPE reads; - - Debug( "MainLoop\n" ); - time( &now ); - while ( -#ifdef XDMCP - AnyListenSockets() || -#endif - (Stopping ? AnyRunningDisplays() : AnyDisplaysLeft())) - { - if (!Stopping) - StartDisplays(); - to = TO_INF; - if (sdRec.how) { - if (sdRec.start != TO_INF && now < sdRec.start) { - /*if (sdRec.start < to)*/ - to = sdRec.start; - } else { - sdRec.start = TO_INF; - if (now >= sdRec.timeout) { - sdRec.timeout = TO_INF; - if (wouldShutdown()) - stoppen( TRUE ); - else - cancelShutdown(); - } else { - stoppen( FALSE ); - /*if (sdRec.timeout < to)*/ - to = sdRec.timeout; - } - } - } - if (serverTimeout < to) - to = serverTimeout; - if (utmpTimeout < to) - to = utmpTimeout; - if (to == TO_INF) - tvp = 0; - else { - to -= now; - if (to < 0) - to = 0; - tv.tv_sec = to; - tv.tv_usec = 0; - tvp = &tv; - } - reads = WellKnownSocketsMask; - nready = select( WellKnownSocketsMax + 1, &reads, 0, 0, tvp ); - Debug( "select returns %d\n", nready ); - time( &now ); -#ifdef NEED_ENTROPY - AddTimerEntropy(); -#endif - if (now >= serverTimeout) { - serverTimeout = TO_INF; - StartServerTimeout(); - } - if (now >= utmpTimeout) { - utmpTimeout = TO_INF; - CheckUtmp(); - } - if (nready > 0) { - /* - * we restart after the first handled fd, as - * a) it makes things simpler - * b) the probability that multiple fds trigger at once is - * ridiculously small. we handle it in the next iteration. - */ - /* XXX a cleaner solution would be a callback mechanism */ - if (FD_ISSET( signalFds[0], &reads )) { - if (read( signalFds[0], &buf, 1 ) != 1) - LogPanic( "Signal notification pipe broken.\n" ); - switch (buf) { - case SIGTERM: - case SIGINT: - Debug( "shutting down entire manager\n" ); - stoppen( TRUE ); - break; - case SIGHUP: - LogInfo( "Rescanning all config files\n" ); - ForEachDisplay( MarkDisplay ); - RescanConfigs( TRUE ); - break; - case SIGCHLD: - ReapChildren(); - if (!Stopping && autoRescan) - RescanConfigs( FALSE ); - break; - case SIGUSR1: - if (startingServer && - startingServer->serverStatus == starting) - StartServerSuccess(); - break; - } - continue; - } -#ifdef XDMCP - if (ProcessListenSockets( &reads )) - continue; -#endif /* XDMCP */ - if (handleCtrl( &reads, 0 )) - continue; - /* Must be last (because of the breaks)! */ - again: - for (d = displays; d; d = d->next) { - if (handleCtrl( &reads, d )) - goto again; - if (d->pipe.rfd >= 0 && FD_ISSET( d->pipe.rfd, &reads )) { - processDPipe( d ); - break; - } - if (d->gpipe.rfd >= 0 && FD_ISSET( d->gpipe.rfd, &reads )) { - processGPipe( d ); - break; - } - } - } - } -} - -static void -CheckDisplayStatus( struct display *d ) -{ - if ((d->displayType & d_origin) == dFromFile && !d->stillThere) - StopDisplay( d ); - else if ((d->displayType & d_lifetime) == dReserve && - d->status == running && d->userSess < 0 && !d->idleTimeout) - rStopDisplay( d, DS_RESERVE ); - else if (d->status == notRunning) - if (LoadDisplayResources( d ) < 0) { - LogError( "Unable to read configuration for display %s; " - "stopping it.\n", d->name ); - StopDisplay( d ); - return; - } -} - -static void -KickDisplay( struct display *d ) -{ - if (d->status == notRunning) - StartDisplay( d ); - if (d->serverStatus == awaiting && !startingServer) - StartServer( d ); -} - -#ifdef HAVE_VTS -static int active_vts; - -static int -GetBusyVTs( void ) -{ - struct vt_stat vtstat; - int con; - - if (active_vts == -1) { - vtstat.v_state = 0; - if ((con = open( "/dev/console", O_RDONLY )) >= 0) { - ioctl( con, VT_GETSTATE, &vtstat ); - close( con ); - } - active_vts = vtstat.v_state; - } - return active_vts; -} - -static void -AllocateVT( struct display *d ) -{ - struct display *cd; - int i, tvt, volun; - - if ((d->displayType & d_location) == dLocal && - d->status == notRunning && !d->serverVT && d->reqSrvVT >= 0) - { - if (d->reqSrvVT && d->reqSrvVT < 16) - d->serverVT = d->reqSrvVT; - else { - for (i = tvt = 0;;) { - if (serverVTs[i]) { - tvt = atoi( serverVTs[i++] ); - volun = 0; - if (tvt < 0) { - tvt = -tvt; - volun = 1; - } - if (!tvt || tvt >= 16) - continue; - } else { - if (++tvt >= 16) - break; - volun = 1; - } - for (cd = displays; cd; cd = cd->next) { - if (cd->reqSrvVT == tvt && /* protect from lusers */ - (cd->status != zombie || cd->zstatus != DS_REMOVE)) - goto next; - if (cd->serverVT == tvt) { - if (cd->status != zombie || cd->zstatus == DS_REMOTE) - goto next; - if (!cd->follower) { - d->serverVT = -1; - cd->follower = d; - return; - } - } - } - if (!volun || !((1 << tvt) & GetBusyVTs())) { - d->serverVT = tvt; - return; - } - next: ; - } - } - } -} -#endif - -static void -StartDisplays( void ) -{ - ForEachDisplay( CheckDisplayStatus ); - CloseGetter(); -#ifdef HAVE_VTS - active_vts = -1; - ForEachDisplayRev( AllocateVT ); -#endif - ForEachDisplay( KickDisplay ); -} - -void -StartDisplay( struct display *d ) -{ - if (Stopping) { - Debug( "stopping display %s because shutdown is scheduled\n", d->name ); - StopDisplay( d ); - return; - } - -#ifdef HAVE_VTS - if (d->serverVT < 0) - return; -#endif - - d->status = running; - if ((d->displayType & d_location) == dLocal) { - Debug( "StartDisplay %s\n", d->name ); - /* don't bother pinging local displays; we'll - * certainly notice when they exit - */ - d->pingInterval = 0; - if (d->authorize) { - SetLocalAuthorization( d ); - /* - * reset the server after writing the authorization information - * to make it read the file (for compatibility with old - * servers which read auth file only on reset instead of - * at first connection) - */ - if (d->serverPid != -1 && d->resetForAuth && d->resetSignal) - kill( d->serverPid, d->resetSignal ); - } - if (d->serverPid == -1) { - d->serverStatus = awaiting; - return; - } - } else { - Debug( "StartDisplay %s, try %d\n", d->name, d->startTries + 1 ); - /* this will only happen when using XDMCP */ - if (d->authorizations) - SaveServerAuthorizations( d, d->authorizations, d->authNum ); - } - StartDisplayP2( d ); -} - -void -StartDisplayP2( struct display *d ) -{ - char *cname, *cgname; - int pid; - - openCtrl( d ); - Debug( "forking session\n" ); - ASPrintf( &cname, "sub-daemon for display %s", d->name ); - ASPrintf( &cgname, "greeter for display %s", d->name ); - pid = GFork( &d->pipe, "master daemon", cname, - &d->gpipe, cgname ); - switch (pid) { - case 0: - SetTitle( d->name ); - if (debugLevel & DEBUG_WSESS) - sleep( 100 ); - mstrtalk.pipe = &d->pipe; - (void)Signal( SIGPIPE, SIG_IGN ); - SetAuthorization( d ); - WaitForServer( d ); - if ((d->displayType & d_location) == dLocal) { - GSet( &mstrtalk ); - GSendInt( D_XConnOk ); - } - ManageSession( d ); - /* NOTREACHED */ - case -1: - closeCtrl( d ); - d->status = notRunning; - break; - default: - Debug( "forked session, pid %d\n", pid ); - - /* (void) fcntl (d->pipe.rfd, F_SETFL, O_NONBLOCK); */ - /* (void) fcntl (d->gpipe.rfd, F_SETFL, O_NONBLOCK); */ - RegisterInput( d->pipe.rfd ); - RegisterInput( d->gpipe.rfd ); - - d->pid = pid; - d->hstent->lock = d->hstent->rLogin = d->hstent->goodExit = - d->hstent->sdRec.how = 0; - d->lastStart = now; - break; - } -} - -/* - * transition from running to zombie, textmode, reserve or deleted - */ - -static void -rStopDisplay( struct display *d, int endState ) -{ - Debug( "stopping display %s to state %d\n", d->name, endState ); - AbortStartServer( d ); - d->idleTimeout = 0; - if (d->serverPid != -1 || d->pid != -1) { - if (d->pid != -1) - TerminateProcess( d->pid, SIGTERM ); - if (d->serverPid != -1) - TerminateProcess( d->serverPid, d->termSignal ); - d->status = zombie; - d->zstatus = endState & 0xff; - Debug( " zombiefied\n" ); - } else if (endState == DS_TEXTMODE) { -#ifdef HAVE_VTS - d->status = textMode; - CheckTTYMode(); - } else if (endState == (DS_TEXTMODE | 0x100)) { - d->status = textMode; -#else - SwitchToTty( d ); -#endif - } else if (endState == DS_RESERVE) - d->status = reserve; -#ifdef XDMCP - else if (endState == DS_REMOTE) - StartRemoteLogin( d ); -#endif - else { -#ifndef HAVE_VTS - SwitchToX( d ); -#endif - RemoveDisplay( d ); - } -} - -void -StopDisplay( struct display *d ) -{ - rStopDisplay( d, DS_REMOVE ); -} - -static void -ExitDisplay( - struct display *d, - int endState, - int serverCmd, - int goodExit ) -{ - struct disphist *he; - - if (d->status == raiser) { - serverCmd = XS_KEEP; - goodExit = TRUE; - } - - Debug( "ExitDisplay %s, " - "endState = %d, serverCmd = %d, GoodExit = %d\n", - d->name, endState, serverCmd, goodExit ); - - d->userSess = -1; - if (d->userName) - free( d->userName ); - d->userName = 0; - if (d->sessName) - free( d->sessName ); - d->sessName = 0; - he = d->hstent; - he->lastExit = now; - he->goodExit = goodExit; - if (he->sdRec.how) { - if (he->sdRec.force == SHUT_ASK && - (AnyActiveDisplays() || d->allowShutdown == SHUT_ROOT)) - { - endState = DS_RESTART; - } else { - if (!sdRec.how || sdRec.force != SHUT_FORCE || - !((d->allowNuke == SHUT_NONE && sdRec.uid != he->sdRec.uid) || - (d->allowNuke == SHUT_ROOT && he->sdRec.uid))) - { - if (sdRec.osname) - free( sdRec.osname ); - sdRec = he->sdRec; - if (now < sdRec.timeout || wouldShutdown()) - endState = DS_REMOVE; - } else if (he->sdRec.osname) - free( he->sdRec.osname ); - he->sdRec.how = 0; - he->sdRec.osname = 0; - } - } - if (d->status == zombie) - rStopDisplay( d, d->zstatus ); - else { - if (Stopping) { - StopDisplay( d ); - return; - } - if (endState != DS_RESTART || - (d->displayType & d_origin) != dFromFile) - { - rStopDisplay( d, endState ); - } else { - if (serverCmd == XS_RETRY) { - if ((d->displayType & d_location) == dLocal) { - if (he->lastExit - d->lastStart < 120) { - LogError( "Unable to fire up local display %s;" - " disabling.\n", d->name ); - StopDisplay( d ); - return; - } - } else { - if (++d->startTries > d->startAttempts) { - LogError( "Disabling foreign display %s" - " (too many attempts)\n", d->name ); - StopDisplay( d ); - return; - } - } - } else - d->startTries = 0; - if (d->serverPid != -1 && - (serverCmd != XS_KEEP || d->terminateServer)) - { - Debug( "killing X server for %s\n", d->name ); - TerminateProcess( d->serverPid, d->termSignal ); - d->status = phoenix; - } else - d->status = notRunning; - } - } -} - - -static int pidFd; -static FILE *pidFilePtr; - -static int -StorePid( void ) -{ - int oldpid; - - if (pidFile[0] != '\0') { - pidFd = open( pidFile, O_RDWR ); - if (pidFd == -1 && errno == ENOENT) - pidFd = open( pidFile, O_RDWR|O_CREAT, 0666 ); - if (pidFd == -1 || !(pidFilePtr = fdopen( pidFd, "r+" ))) { - LogError( "process-id file %s cannot be opened\n", - pidFile ); - return -1; - } - if (fscanf( pidFilePtr, "%d\n", &oldpid ) != 1) - oldpid = -1; - fseek( pidFilePtr, 0l, 0 ); - if (lockPidFile) { -#ifdef F_SETLK -# ifndef SEEK_SET -# define SEEK_SET 0 -# endif - struct flock lock_data; - lock_data.l_type = F_WRLCK; - lock_data.l_whence = SEEK_SET; - lock_data.l_start = lock_data.l_len = 0; - if (fcntl( pidFd, F_SETLK, &lock_data ) == -1) { - if (errno == EAGAIN) - return oldpid; - else - return -1; - } -#else -# ifdef LOCK_EX - if (flock( pidFd, LOCK_EX|LOCK_NB ) == -1) { - if (errno == EWOULDBLOCK) - return oldpid; - else - return -1; - } -# else - if (lockf( pidFd, F_TLOCK, 0 ) == -1) { - if (errno == EACCES) - return oldpid; - else - return -1; - } -# endif -#endif - } - fprintf( pidFilePtr, "%ld\n", (long)getpid() ); - (void)fflush( pidFilePtr ); - RegisterCloseOnFork( pidFd ); - } - return 0; -} - -#if 0 -void -UnlockPidFile( void ) -{ - if (lockPidFile) -# ifdef F_SETLK - { - struct flock lock_data; - lock_data.l_type = F_UNLCK; - lock_data.l_whence = SEEK_SET; - lock_data.l_start = lock_data.l_len = 0; - (void)fcntl( pidFd, F_SETLK, &lock_data ); - } -# else -# ifdef F_ULOCK - lockf( pidFd, F_ULOCK, 0 ); -# else - flock( pidFd, LOCK_UN ); -# endif -# endif - close( pidFd ); - fclose( pidFilePtr ); -} -#endif - -void -SetTitle( const char *name ) -{ -#if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE) - char *p; - int left; -#endif - - ASPrintf( &prog, "%s: %s", prog, name ); - ReInitErrorLog(); -#ifdef HAVE_SETPROCTITLE - setproctitle( "%s", name ); -#elif !defined(NOXDMTITLE) - p = Title; - left = TitleLen; - - *p++ = '-'; - --left; - while (*name && left > 0) { - *p++ = *name++; - --left; - } - while (left > 0) { - *p++ = '\0'; - --left; - } -#endif -} diff --git a/kdm/backend/dm.h b/kdm/backend/dm.h deleted file mode 100644 index c05d4c865..000000000 --- a/kdm/backend/dm.h +++ /dev/null @@ -1,630 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2005 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * global xdm core declarations - */ - -#ifndef _DM_H_ -#define _DM_H_ 1 - -#define WITH_CONSOLE_KIT - -#include "greet.h" -#include - -#include /* FamilyInternet6 */ -#include -#include -#include -#include -#include - -#include -#ifdef HAVE_LIMITS_H -# include -#endif - -#include -#define Time_t time_t - -#include -#include - -#ifdef XDMCP -# if defined(__osf__) -/* someone somewhere defines QUERY under Tru64 which confuses Xdmcp.h */ -# undef QUERY -# endif -# include -#endif - -#ifndef PATH_MAX -# ifdef MAXPATHLEN -# define PATH_MAX MAXPATHLEN -# else -# define PATH_MAX 1024 -# endif -#endif - -#include -#define waitCode(w) (WIFEXITED(w) ? WEXITSTATUS(w) : 0) -#define waitSig(w) (WIFSIGNALED(w) ? WTERMSIG(w) : 0) -#ifdef WCOREDUMP -# define waitCore(w) (WCOREDUMP(w)) -#else -# define waitCore(w) 0 /* not in POSIX. so what? */ -#endif -typedef int waitType; - -#define waitCompose(sig,core,code) ((sig) * 256 + (core) * 128 + (code)) -#define waitVal(w) waitCompose(waitSig(w), waitCore(w), waitCode(w)) -#define WaitCode(w) ((w) & 0x7f) -#define WaitCore(w) (((w) >> 7) & 1) -#define WaitSig(w) (((w) >> 8) & 0xff) - -#include -#define FD_TYPE fd_set - -#include -#if defined(__EMX__) || (defined(__NetBSD__) && defined(__sparc__)) /* XXX netbsd? */ -# define Setjmp(e) setjmp(e) -# define Longjmp(e,v) longjmp(e,v) -# define Jmp_buf jmp_buf -#else -# define Setjmp(e) sigsetjmp(e,1) -# define Longjmp(e,v) siglongjmp(e,v) -# define Jmp_buf sigjmp_buf -#endif - -#include -#ifdef HAVE_UTMPX -# include -# define STRUCTUTMP struct utmpx -# define UTMPNAME utmpxname -# define SETUTENT setutxent -# define GETUTENT getutxent -# define PUTUTLINE pututxline -# define ENDUTENT endutxent -# define LASTLOG lastlogx -# define ut_time ut_tv.tv_sec -# define ll_time ll_tv.tv_sec -#else -# define STRUCTUTMP struct utmp -# define UTMPNAME utmpname -# define SETUTENT setutent -# define GETUTENT getutent -# define PUTUTLINE pututline -# define ENDUTENT endutent -# define LASTLOG lastlog -#endif -#ifndef HAVE_STRUCT_UTMP_UT_USER -# define ut_user ut_name -#endif -#ifndef WTMP_FILE -# ifdef _PATH_WTMPX -# define WTMP_FILE _PATH_WTMPX -# elif defined(_PATH_WTMP) -# define WTMP_FILE _PATH_WTMP -# else -# define WTMP_FILE "/usr/adm/wtmp" -# endif -#endif -#ifndef UTMP_FILE -# ifdef _PATH_UTMPX -# define UTMP_FILE _PATH_UTMPX -# elif defined(_PATH_UTMP) -# define UTMP_FILE _PATH_UTMP -# else -# define UTMP_FILE "/etc/utmp" -# endif -#endif - -#ifdef HAVE_NETCONFIG_H -# define STREAMSCONN -#else -# define UNIXCONN -# define TCPCONN -# ifdef FamilyInternet6 -# define IPv6 -# endif -# ifdef HAVE_NETDNET_DN_H -# define DNETCONN -# endif -#endif - -#if !defined(HAVE_ARC4RANDOM) && !defined(DEV_RANDOM) -# define NEED_ENTROPY -#endif - -typedef struct GPipe { - int wfd, rfd; - char *who; -} GPipe; - -typedef struct GTalk { - GPipe *pipe; - Jmp_buf errjmp; -} GTalk; - -typedef struct GProc { - GPipe pipe; - int pid; -} GProc; - -typedef enum displayStatus { notRunning = 0, running, zombie, phoenix, raiser, - textMode, reserve, remoteLogin } DisplayStatus; - -typedef enum serverStatus { ignore = 0, awaiting, starting, - terminated, killed, pausing } ServerStatus; - -typedef struct RcStr { - struct RcStr *next; - char *str; - int cnt; -} RcStr; - -typedef struct CfgDep { - RcStr *name; - long time; -} CfgDep; - -typedef struct CfgArr { - char *data; /* config value array; allocated */ - long *idx; /* config index array; alias */ - CfgDep dep; /* filestamp */ - int numCfgEnt; /* number of config entries */ -} CfgArr; - -struct bsock { - int fd; - int buflen; - char *buffer; -}; - -struct cmdsock { - struct cmdsock *next; - struct bsock sock; /* buffered fd of the socket */ -}; - -typedef struct { - struct cmdsock *css; /* open connections */ - - char *path; /* filename of the socket */ -#ifndef HONORS_SOCKET_PERMS - char *realdir; /* real dirname of the socket */ -#endif - int fd; /* fd of the socket */ - int gid; /* owner group of the socket */ - - char *fpath; /* filename of the fifo */ - struct bsock fifo; /* buffered fd of the fifo */ -} CtrlRec; - -struct display { - struct display *next; - struct disphist *hstent; /* display history entry */ - - /* basic display information */ - char *name; /* DISPLAY name -- also referenced in hstent */ - char *class2; /* display class (may be NULL) */ - int displayType; /* location/origin/lifetime */ - CfgArr cfg; /* config data array */ - - /* display state */ - DisplayStatus status; /* current status */ - int zstatus; /* substatus while zombie */ - int pid; /* process id of child */ - int serverPid; /* process id of server (-1 if none) */ -#ifdef HAVE_VTS - int serverVT; /* server VT (0 = none, -1 = pending) */ - struct display *follower; /* on exit, hand VT to this display */ -#endif - ServerStatus serverStatus; /* X server startup state */ - Time_t lastStart; /* time of last display start */ - int startTries; /* current start try */ - int stillThere; /* state during HUP processing */ - int userSess; /* -1=nobody, otherwise uid */ - char *userName; - char *sessName; - CtrlRec ctrl; /* command socket & fifo */ - GPipe pipe; /* comm master <-> slave */ - GPipe gpipe; /* comm master <-> greeter */ -#ifdef XDMCP - char *remoteHost; /* for X -query type remote login */ - /* XDMCP state */ - unsigned sessionID; /* ID of active session */ - ARRAY8 peer; /* display peer address */ - ARRAY8 from; /* XDMCP port of display */ - unsigned displayNumber; /* numerical part of name */ - int useChooser; /* Run the chooser for this display */ - ARRAY8 clientAddr; /* for chooser picking */ - unsigned connectionType; /* ... */ - int xdmcpFd; -#endif - - CONF_CORE_LOCAL_DEFS - - int idleTimeout; /* abort login after that time */ - - unsigned short *authNameLens; /* authorization protocol name lens */ - - /* information potentially derived from resources */ - int authNameNum; /* number of protocol names */ - Xauth **authorizations; /* authorization data */ - int authNum; /* number of authorizations */ - char *authFile; /* file to store authorization in */ -}; - -typedef struct { - unsigned how:2, /* 0=none 1=reboot 2=halt (SHUT_*) */ - force:2; - int uid; - int start; - int timeout; - char *osname; - time_t bmstamp; - int osindex; -} SdRec; - -struct disphist { - struct disphist *next; - char *name; - Time_t lastExit; /* time of last display exit */ - unsigned rLogin:2, /* 0=nothing 1=relogin 2=login */ - lock:1, /* screen locker running */ - goodExit:1; /* was the last exit "peaceful"? */ - SdRec sdRec; - char *nuser, *npass, *nargs; -}; - -#ifdef XDMCP - -#define PROTO_TIMEOUT (30 * 60) /* 30 minutes should be long enough */ - -struct protoDisplay { - struct protoDisplay *next; - XdmcpNetaddr address; /* UDP address */ - int addrlen; /* UDP address length */ - unsigned long date; /* creation date */ - CARD16 displayNumber; - CARD16 connectionType; - ARRAY8 connectionAddress; - CARD32 sessionID; - Xauth *fileAuthorization; - Xauth *xdmcpAuthorization; - ARRAY8 authenticationName; - ARRAY8 authenticationData; - XdmAuthKeyRec key; -}; -#endif /* XDMCP */ - -/* status code for RStopDisplay */ -#define DS_RESTART 0 -#define DS_TEXTMODE 1 -#define DS_RESERVE 2 -#define DS_REMOTE 3 -#define DS_REMOVE 4 - -/* command codes dpy process -> master process */ -#define D_User 1 -#define D_ReLogin 2 -#define D_ChooseHost 4 -#define D_RemoteHost 5 -#define D_XConnOk 6 - -extern int debugLevel; - -CONF_CORE_GLOBAL_DECLS - -/* in daemon.c */ -void BecomeDaemon( void ); - -/* in dm.c */ -extern char *prog, *progpath; -extern time_t now; -extern SdRec sdRec; -void StartDisplay( struct display *d ); -void StartDisplayP2( struct display *d ); -void StopDisplay( struct display *d ); -void SetTitle( const char *name ); -void SwitchToX( struct display *d ); -void setNLogin( struct display *d, - const char *nuser, const char *npass, char *nargs, - int rl ); -void cancelShutdown( void ); -int TTYtoVT( const char *tty ); -int activateVT( int vt ); - -/* in ctrl.c */ -void openCtrl( struct display *d ); -void closeCtrl( struct display *d ); -int handleCtrl( FD_TYPE *reads, struct display *d ); -void chownCtrl( CtrlRec *cr, int uid ); -void updateCtrl( void ); - -/* in dpylist.c */ -extern struct display *displays; /* that's ugly ... */ -int AnyDisplaysLeft( void ); -void ForEachDisplay( void (*f)( struct display * ) ); -#ifdef HAVE_VTS -void ForEachDisplayRev( void (*f)( struct display * ) ); -#endif -void RemoveDisplay( struct display *old ); -struct display - *FindDisplayByName( const char *name ), -#ifdef XDMCP - *FindDisplayBySessionID( CARD32 sessionID ), - *FindDisplayByAddress( XdmcpNetaddr addr, int addrlen, CARD16 displayNumber ), -#endif /* XDMCP */ - *FindDisplayByPid( int pid ), - *FindDisplayByServerPid( int serverPid ), - *NewDisplay( const char *name ); -int AnyActiveDisplays( void ); -int AnyRunningDisplays( void ); -int AnyReserveDisplays( void ); -int idleReserveDisplays( void ); -int AllLocalDisplaysLocked( struct display *dp ); -int StartReserveDisplay( int lt ); -void ReapReserveDisplays( void ); - -/* in reset.c */ -void pseudoReset( void ); - -/* in resource.c */ -char **FindCfgEnt( struct display *d, int id ); -int InitResources( char **argv ); -int LoadDMResources( int force ); -int LoadDisplayResources( struct display *d ); -void ScanServers( void ); -void CloseGetter( void ); -int startConfig( int what, CfgDep *dep, int force ); -RcStr *newStr( char *str ); -void delStr( RcStr *str ); -extern GTalk cnftalk; - -/* in session.c */ -extern struct display *td; -extern const char *td_setup; -char **baseEnv( const char *user ); -char **inheritEnv( char **env, const char **what ); -char **systemEnv( const char *user ); -int source( char **env, const char *file, const char *arg ); -void ManageSession( struct display *d ); - -extern GTalk mstrtalk, grttalk; -extern GProc grtproc; -void OpenGreeter( void ); -int CloseGreeter( int force ); -int CtrlGreeterWait( int wreply ); -void PrepErrorGreet( void ); -char *conv_interact( int what, const char *prompt ); - -/* process.c */ -typedef void (*SIGFUNC)( int ); -SIGFUNC Signal( int, SIGFUNC Handler ); - -void RegisterInput( int fd ); -void UnregisterInput( int fd ); -void RegisterCloseOnFork( int fd ); -void ClearCloseOnFork( int fd ); -void CloseNClearCloseOnFork( int fd ); -int Fork( void ); -int Wait4( int pid ); -void execute( char **argv, char **env ); -int runAndWait( char **args, char **env ); -FILE *pOpen( char **what, char m, int *pid ); -int pClose( FILE *f, int pid ); -char *locate( const char *exe ); -void TerminateProcess( int pid, int sig ); - -void GSet( GTalk *talk); /* call before GOpen! */ -int GFork( GPipe *pajp, const char *pname, char *cname, - GPipe *ogp, char *cgname ); -void GClosen( GPipe *pajp ); -int GOpen( GProc *proc, - char **argv, const char *what, char **env, char *cname, - GPipe *gp ); -int GClose( GProc *proc, GPipe *gp, int force ); - -void GSendInt( int val ); -int GRecvInt( void ); -int GRecvCmd( int *cmd ); -void GSendArr( int len, const char *data ); -char *GRecvArr( int *len ); -int GRecvStrBuf( char *buf ); -int GRecvArrBuf( char *buf ); -void GSendStr( const char *buf ); -void GSendNStr( const char *buf, int len ); /* exact len, buf != 0 */ -void GSendStrN( const char *buf, int len ); /* maximal len */ -char *GRecvStr( void ); -void GSendArgv( char **argv ); -void GSendStrArr( int len, char **data ); -char **GRecvStrArr( int *len ); -char **GRecvArgv( void ); - -/* client.c */ -#define GCONV_NORMAL 0 -#define GCONV_HIDDEN 1 -#define GCONV_USER 2 -#define GCONV_PASS 3 -#define GCONV_PASS_ND 4 -#define GCONV_BINARY 5 -typedef char *(*GConvFunc)( int what, const char *prompt ); -int Verify( GConvFunc gconv, int rootok ); -#ifdef WITH_CONSOLE_KIT -int StartClient( const char *ck_session_cookie ); -#else -int StartClient( void ); -#endif -void SessionExit( int status ) ATTR_NORETURN; -int ReadDmrc( void ); -extern char **userEnviron, **systemEnviron; -extern char *curuser, *curpass, *curtype, *newpass, - *dmrcuser, *curdmrc, *newdmrc; -extern int cursource; -#define PWSRC_MANUAL 0 -#define PWSRC_AUTOLOGIN 1 -#define PWSRC_RELOGIN 2 - -/* server.c */ -char **PrepServerArgv( struct display *d, const char *args ); -void StartServer( struct display *d ); -void AbortStartServer( struct display *d ); -void StartServerSuccess( void ); -void StartServerFailed( void ); -void StartServerTimeout( void ); -extern struct display *startingServer; -extern time_t serverTimeout; - -void WaitForServer( struct display *d ); -void ResetServer( struct display *d ); -int PingServer(struct display *d ); -extern Display *dpy; - -/* in util.c */ -void *Calloc( size_t nmemb, size_t size ); -void *Malloc( size_t size ); -void *Realloc( void *ptr, size_t size ); -void WipeStr( char *str ); -int StrCmp( const char *s1, const char *s2 ); -#ifdef HAVE_STRNLEN -# define StrNLen(s, m) strnlen(s, m) -#else -int StrNLen( const char *s, int max ); -#endif -int StrNDup( char **dst, const char *src, int len ); -int StrDup( char **dst, const char *src ); -int arrLen( char **arr ); -void freeStrArr( char **arr ); -char **initStrArr( char **arr ); -char **xCopyStrArr( int rn, char **arr ); -/* Note: the following functions free the old data even in case of failure */ -int ReStrN( char **dst, const char *src, int len ); -int ReStr( char **dst, const char *src ); -int StrApp( char **dst, ... ); -char **addStrArr( char **arr, const char *str, int len ); -char **parseArgs( char **argv, const char *string ); -/* End note */ -char **setEnv( char **e, const char *name, const char *value ); -char **putEnv( const char *string, char **env ); -const char *getEnv( char **e, const char *name ); -const char *localHostname( void ); -int Reader( int fd, void *buf, int len ); -int Writer( int fd, const void *buf, int len ); -int fGets( char *buf, int max, FILE *f ); -void randomStr( char *s ); -time_t mTime( const char *fn ); -void ListSessions( int flags, struct display *d, void *ctx, - void (*emitXSess)( struct display *, struct display *, void * ), - void (*emitTTYSess)( STRUCTUTMP *, struct display *, void * ) ); - -/* in inifile.c */ -char *iniLoad( const char *fname ); -int iniSave( const char *data, const char *fname ); -char *iniEntry( char *data, const char *section, const char *key, const char *value ); -char *iniMerge( char *data, const char *newdata ); - -/* in bootman.c */ -int getBootOptions( char ***opts, int *def, int *cur ); -int setBootOption( const char *opt, SdRec *sdr ); -void commitBootOption( void ); - -/* in netaddr.c */ -char *NetaddrAddress( char *netaddrp, int *lenp ); -char *NetaddrPort( char *netaddrp, int *lenp ); -int ConvertAddr( char *saddr, int *len, char **addr ); -int NetaddrFamily( char *netaddrp ); -int addressEqual( char *a1, int len1, char *a2, int len2 ); - -#ifdef XDMCP - -/* in xdmcp.c */ -char *NetworkAddressToHostname( CARD16 connectionType, ARRAY8Ptr connectionAddress ); -void SendFailed( struct display *d, const char *reason ); -void init_session_id( void ); - -/* in policy.c */ -struct sockaddr; -ARRAY8Ptr Accept( struct sockaddr *from, int fromlen, CARD16 displayNumber ); -ARRAY8Ptr ChooseAuthentication( ARRAYofARRAY8Ptr authenticationNames ); -int CheckAuthentication( struct protoDisplay *pdpy, ARRAY8Ptr displayID, ARRAY8Ptr name, ARRAY8Ptr data ); -int SelectAuthorizationTypeIndex( ARRAY8Ptr authenticationName, ARRAYofARRAY8Ptr authorizationNames ); -int SelectConnectionTypeIndex( ARRAY16Ptr connectionTypes, ARRAYofARRAY8Ptr connectionAddresses ); -int Willing( ARRAY8Ptr addr, CARD16 connectionType, ARRAY8Ptr authenticationName, ARRAY8Ptr status, xdmOpCode type ); - -/* in protodpy.c */ -void DisposeProtoDisplay( struct protoDisplay *pdpy ); - -struct protoDisplay *FindProtoDisplay( XdmcpNetaddr address, int addrlen, - CARD16 displayNumber ); -struct protoDisplay *NewProtoDisplay( XdmcpNetaddr address, int addrlen, - CARD16 displayNumber, - CARD16 connectionType, - ARRAY8Ptr connectionAddress, - CARD32 sessionID ); - -#define FamilyBroadcast 0xffff -typedef void (*ChooserFunc)( CARD16 connectionType, ARRAY8Ptr addr, char *closure ); -typedef void (*ListenFunc)( ARRAY8Ptr addr, void **closure ); - -/* in access.c */ -ARRAY8Ptr getLocalAddress( void ); -int AcceptableDisplayAddress( ARRAY8Ptr clientAddress, CARD16 connectionType, xdmOpCode type ); -int ForEachMatchingIndirectHost( ARRAY8Ptr clientAddress, CARD16 connectionType, ChooserFunc function, char *closure ); -void ScanAccessDatabase( int force ); -int UseChooser( ARRAY8Ptr clientAddress, CARD16 connectionType ); -void ForEachChooserHost( ARRAY8Ptr clientAddress, CARD16 connectionType, ChooserFunc function, char *closure ); -void ForEachListenAddr( ListenFunc listenfunction, ListenFunc mcastfcuntion, void **closure ); - -/* in choose.c */ -ARRAY8Ptr IndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType ); -int IsIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ); -int RememberIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ); -void ForgetIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ); -int RegisterIndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType, ARRAY8Ptr choice ); -int DoChoose( void ); - -/* socket.c or streams.c */ -void UpdateListenSockets( void ); -int AnyListenSockets( void ); -int ProcessListenSockets( FD_TYPE *reads ); - -/* in xdmcp.c */ -void ProcessRequestSocket( int fd ); - -#endif /* XDMCP */ - -/* in sessreg.c */ -void sessreg( struct display *d, int pid, const char *user, int uid ); - -#endif /* _DM_H_ */ diff --git a/kdm/backend/dm_auth.h b/kdm/backend/dm_auth.h deleted file mode 100644 index 28725ee8d..000000000 --- a/kdm/backend/dm_auth.h +++ /dev/null @@ -1,105 +0,0 @@ -/************************************************************ - -Copyright 1998 by Thomas E. Dickey - - All Rights Reserved - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name(s) of the above copyright -holders shall not be used in advertising or otherwise to promote the -sale, use or other dealings in this Software without prior written -authorization. - -********************************************************/ - -#ifndef _DM_AUTH_H_ -#define _DM_AUTH_H_ 1 - -#include "dm.h" - -void MitInitAuth( unsigned short name_len, const char *name ); -Xauth *MitGetAuth( unsigned short namelen, const char *name ); - -#ifdef HASXDMAUTH -void XdmInitAuth( unsigned short name_len, const char *name ); -Xauth *XdmGetAuth( unsigned short namelen, const char *name ); -# ifdef XDMCP -void XdmGetXdmcpAuth( struct protoDisplay *pdpy, - unsigned short authorizationNameLen, - const char *authorizationName ); -int XdmCheckAuthentication( struct protoDisplay *pdpy, - ARRAY8Ptr displayID, - ARRAY8Ptr authenticationName, - ARRAY8Ptr authenticationData ); -# else -# define XdmGetXdmcpAuth NULL -# endif -#endif - -#ifdef SECURE_RPC -void SecureRPCInitAuth( unsigned short name_len, const char *name ); -Xauth *SecureRPCGetAuth( unsigned short name_len, const char *name ); -#endif - -#ifdef K5AUTH -void Krb5InitAuth( unsigned short name_len, const char *name ); -Xauth *Krb5GetAuth( unsigned short name_len, const char *name ); - -Xauth *Krb5GetAuthFor( unsigned short name_len, const char *name, const char *dname ); -char *Krb5Init( const char *user, const char *passwd, const char *dname ); -void Krb5Destroy( const char *dname ); -#endif - -/* auth.c */ -int ValidAuthorization( unsigned short name_length, const char *name ); - - -#ifdef XDMCP - -void -SetProtoDisplayAuthorization( struct protoDisplay *pdpy, - unsigned short authorizationNameLen, - const char *authorizationName ); - -#endif /* XDMCP */ - -int SaveServerAuthorizations( struct display *d, Xauth **auths, int count ); -void CleanUpFileName( const char *src, char *dst, int len ); -void RemoveUserAuthorization( struct display *d ); -void SetAuthorization( struct display *d ); -void SetLocalAuthorization( struct display *d ); -void SetUserAuthorization( struct display *d ); - -/* genauth.c */ -int GenerateAuthData( char *auth, int len ); -#ifdef NEED_ENTROPY -void AddPreGetEntropy( void ); -void AddOtherEntropy( void ); -void AddTimerEntropy( void ); -#endif - -#ifdef HAVE_ARC4RANDOM -# define secureRandom() arc4random() -#else -int secureRandom( void ); -#endif - -#endif /* _DM_AUTH_H_ */ diff --git a/kdm/backend/dm_error.h b/kdm/backend/dm_error.h deleted file mode 100644 index 3570c18fc..000000000 --- a/kdm/backend/dm_error.h +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************ - -Copyright 1998 by Thomas E. Dickey - - All Rights Reserved - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name(s) of the above copyright -holders shall not be used in advertising or otherwise to promote the -sale, use or other dealings in this Software without prior written -authorization. - -********************************************************/ - - -#ifndef _DM_ERROR_H_ -#define _DM_ERROR_H_ 1 - -#include "greet.h" - -#include - -void GDebug( const char *fmt, ... ); -void Debug( const char *fmt, ... ); -void LogInfo( const char *fmt, ... ); -void LogWarn( const char *fmt, ... ); -void LogError( const char *fmt, ... ); -void LogPanic( const char *fmt, ... ) ATTR_NORETURN; -void LogOutOfMem( void ); -void Panic( const char *mesg ) ATTR_NORETURN; -void InitErrorLog( const char *errorLogFile ); -#ifdef USE_SYSLOG -void ReInitErrorLog( void ); -#else -# define ReInitErrorLog() while(0) -#endif -int ASPrintf( char **strp, const char *fmt, ... ); -int VASPrintf( char **strp, const char *fmt, va_list args ); - -#endif /* _DM_ERROR_H_ */ diff --git a/kdm/backend/dm_socket.h b/kdm/backend/dm_socket.h deleted file mode 100644 index 56a39fd0e..000000000 --- a/kdm/backend/dm_socket.h +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************ - -Copyright 1998 by Thomas E. Dickey -Copyright 2002-2004 Oswald Buddenhagen - - All Rights Reserved - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name(s) of the above copyright -holders shall not be used in advertising or otherwise to promote the -sale, use or other dealings in this Software without prior written -authorization. - -********************************************************/ - -#ifndef _DM_SOCKET_H_ -#define _DM_SOCKET_H_ 1 - -#ifndef __Lynx__ -# include -#else -# include -#endif - -#ifdef TCPCONN -# include -#endif - -#ifdef UNIXCONN -# ifndef __Lynx__ -# include -# else -# include -# endif -#endif - -#ifdef DNETCONN -# include -#endif - -#if (defined(__svr4__) && !defined(__sun__)) && defined(SIOCGIFCONF) -# define SYSV_SIOCGIFCONF -int ifioctl( int fd, int cmd, char *arg ); -#else -# define ifioctl ioctl -#endif - -#ifdef BSD -# if (BSD >= 199103) -# define VARIABLE_IFREQ -# endif -#endif - -#endif /* _DM_SOCKET_H_ */ diff --git a/kdm/backend/dpylist.c b/kdm/backend/dpylist.c deleted file mode 100644 index b512293f7..000000000 --- a/kdm/backend/dpylist.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2005 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * a simple linked list of known displays - */ - -#include "dm.h" -#include "dm_error.h" - -struct display *displays; -static struct disphist *disphist; - -int -AnyDisplaysLeft( void ) -{ - return displays != (struct display *)0; -} - -int -AnyActiveDisplays( void ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if (d->status == remoteLogin || d->userSess >= 0) - return 1; - return 0; -} - -int -AnyRunningDisplays( void ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - switch (d->status) { - case notRunning: - case textMode: - case reserve: - break; - default: - return 1; - } - return 0; -} - -int -AnyReserveDisplays( void ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if ((d->displayType & d_lifetime) == dReserve) - return 1; - return 0; -} - -int -idleReserveDisplays( void ) -{ - struct display *d; - int cnt = 0; - - for (d = displays; d; d = d->next) - if (d->status == reserve) - cnt++; - return cnt; -} - -int -StartReserveDisplay( int lt ) -{ - struct display *d, *rd; - - for (rd = 0, d = displays; d; d = d->next) - if (d->status == reserve) - rd = d; - if (rd) { - rd->idleTimeout = lt; - rd->status = notRunning; - return 1; - } - return 0; -} - -void -ForEachDisplay( void (*f)( struct display * ) ) -{ - struct display *d, *next; - - for (d = displays; d; d = next) { - next = d->next; - (*f)( d ); - } -} - -#ifdef HAVE_VTS -static void -_forEachDisplayRev( struct display *d, void (*f)( struct display * ) ) -{ - if (d) { - if (d->next) - _forEachDisplayRev( d->next, f ); - (*f)( d ); - } -} - -void -ForEachDisplayRev( void (*f)( struct display * ) ) -{ - _forEachDisplayRev( displays, f ); -} -#endif - -struct display * -FindDisplayByName( const char *name ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if (!strcmp( name, d->name )) - return d; - return 0; -} - -struct display * -FindDisplayByPid( int pid ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if (pid == d->pid) - return d; - return 0; -} - -struct display * -FindDisplayByServerPid( int serverPid ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if (serverPid == d->serverPid) - return d; - return 0; -} - -#ifdef XDMCP - -struct display * -FindDisplayBySessionID( CARD32 sessionID ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if (sessionID == d->sessionID) - return d; - return 0; -} - -struct display * -FindDisplayByAddress( XdmcpNetaddr addr, int addrlen, CARD16 displayNumber ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if ((d->displayType & d_origin) == dFromXDMCP && - d->displayNumber == displayNumber && - addressEqual( (XdmcpNetaddr)d->from.data, d->from.length, - addr, addrlen )) - return d; - return 0; -} - -#endif /* XDMCP */ - -#define IfFree(x) if (x) free( (char *)x ) - -void -RemoveDisplay( struct display *old ) -{ - struct display *d, **dp; - int i; - - for (dp = &displays; (d = *dp); dp = &(*dp)->next) { - if (d == old) { - Debug( "Removing display %s\n", d->name ); - *dp = d->next; - IfFree( d->class2 ); - IfFree( d->cfg.data ); - delStr( d->cfg.dep.name ); -#ifdef XDMCP - IfFree( d->remoteHost ); -#endif - if (d->authorizations) { - for (i = 0; i < d->authNum; i++) - XauDisposeAuth( d->authorizations[i] ); - free( (char *)d->authorizations ); - } - if (d->authFile) { - (void)unlink( d->authFile ); - free( d->authFile ); - } - IfFree( d->authNameLens ); -#ifdef XDMCP - XdmcpDisposeARRAY8( &d->peer ); - XdmcpDisposeARRAY8( &d->from ); - XdmcpDisposeARRAY8( &d->clientAddr ); -#endif - free( (char *)d ); - break; - } - } -} - -static struct disphist * -FindHist( const char *name ) -{ - struct disphist *hstent; - - for (hstent = disphist; hstent; hstent = hstent->next) - if (!strcmp( hstent->name, name )) - return hstent; - return 0; -} - -struct display * -NewDisplay( const char *name ) -{ - struct display *d; - struct disphist *hstent; - - if (!(hstent = FindHist( name ))) { - if (!(hstent = Calloc( 1, sizeof(*hstent) ))) - return 0; - if (!StrDup( &hstent->name, name )) { - free( hstent ); - return 0; - } - hstent->next = disphist; disphist = hstent; - } - - if (!(d = (struct display *)Calloc( 1, sizeof(*d) ))) - return 0; - d->next = displays; - d->hstent = hstent; - d->name = hstent->name; - /* initialize fields (others are 0) */ - d->pid = -1; - d->serverPid = -1; - d->ctrl.fd = -1; - d->ctrl.fifo.fd = -1; - d->pipe.rfd = -1; - d->pipe.wfd = -1; - d->gpipe.rfd = -1; - d->gpipe.wfd = -1; - d->userSess = -1; -#ifdef XDMCP - d->xdmcpFd = -1; -#endif - displays = d; - Debug( "created new display %s\n", d->name ); - return d; -} diff --git a/kdm/backend/error.c b/kdm/backend/error.c deleted file mode 100644 index 93ec40e70..000000000 --- a/kdm/backend/error.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2004 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * Log display manager errors to a file as - * we generally do not have a terminal to talk to - * or use syslog if it exists - */ - -#include "dm.h" -#include "dm_error.h" - -#include -#include - -#define PRINT_QUOTES -#define PRINT_ARRAYS -#define LOG_DEBUG_MASK DEBUG_CORE -#define LOG_PANIC_EXIT 1 -#define NEED_ASPRINTF -#define STATIC -#include "printf.c" - -void -GDebug( const char *fmt, ... ) -{ - va_list args; - - if (debugLevel & DEBUG_HLPCON) { - va_start( args, fmt ); - Logger( DM_DEBUG, fmt, args ); - va_end( args ); - } -} - -void -Panic( const char *mesg ) -{ - int fd = open( "/dev/console", O_WRONLY ); - write( fd, "xdm panic: ", 11 ); - write( fd, mesg, strlen( mesg ) ); - write( fd, "\n", 1 ); -#ifdef USE_SYSLOG - ReInitErrorLog(); - syslog( LOG_ALERT, "%s", mesg ); -#endif - exit( 1 ); -} - -#ifdef USE_SYSLOG -void -ReInitErrorLog() -{ - if (!(debugLevel & DEBUG_NOSYSLOG)) - InitLog(); -} -#endif - -void -InitErrorLog( const char *errorLogFile ) -{ - int fd; - char buf[128]; - -#ifdef USE_SYSLOG - ReInitErrorLog(); -#endif - /* We do this independently of using syslog, as we cannot redirect - * the output of external programs to syslog. - */ - if (!errorLogFile || strcmp( errorLogFile, "-" )) { - if (!errorLogFile) { - sprintf( buf, "/var/log/%s.log", prog ); - errorLogFile = buf; - } - if ((fd = open( errorLogFile, O_CREAT | O_APPEND | O_WRONLY, 0666 )) < 0) - LogError( "Cannot open log file %s\n", errorLogFile ); - else { -#ifdef USE_SYSLOG -# ifdef USE_PAM -# define PAMLOG " PAM logs messages related to authentication to authpriv.*." -# else -# define PAMLOG -# endif -# define WARNMSG \ - "********************************************************************************\n" \ - "Note that your system uses syslog. All of tdm's internally generated messages\n" \ - "(i.e., not from libraries and external programs/scripts it uses) go to the\n" \ - "daemon.* syslog facility; check your syslog configuration to find out to which\n" \ - "file(s) it is logged." PAMLOG "\n" \ - "********************************************************************************\n\n" - if (!lseek( fd, 0, SEEK_END )) - write( fd, WARNMSG, sizeof(WARNMSG) - 1 ); -#endif - dup2( fd, 1 ); - close( fd ); - dup2( 1, 2 ); - } - } -} - diff --git a/kdm/backend/genauth.c b/kdm/backend/genauth.c deleted file mode 100644 index 6da95cce0..000000000 --- a/kdm/backend/genauth.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2003-2004 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - */ - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#ifdef NEED_ENTROPY - -# include - -/* ####################################################################### */ - -/* - * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. - * Copyright (c) 2001-2002 Damien Miller. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "dm_socket.h" - -#include - -#ifndef INADDR_LOOPBACK -# define INADDR_LOOPBACK 0x7F000001U -#endif - -#ifndef offsetof -# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -#endif - -static int -getPrngdBytes( char *buf, int len, - unsigned short tcp_port, const char *socket_path ) -{ - int fd, addr_len, rval, errors; - char msg[2]; - struct sockaddr *addr; - struct sockaddr_in addr_in; - struct sockaddr_un addr_un; - int af; - SIGFUNC old_sigpipe; - - if (tcp_port) { - memset( &addr_in, 0, sizeof(addr_in) ); - af = addr_in.sin_family = AF_INET; - addr_in.sin_addr.s_addr = htonl( INADDR_LOOPBACK ); - addr_in.sin_port = htons( tcp_port ); - addr_len = sizeof(addr_in); - addr = (struct sockaddr *)&addr_in; - } else if (*socket_path) { - unsigned spl = strlen( socket_path ); - if (spl >= sizeof(addr_un.sun_path)) { - LogError( "get_random_prngd: " - "Random pool path is too long\n" ); - return -1; - } - af = addr_un.sun_family = AF_UNIX; - strncpy( addr_un.sun_path, socket_path, - sizeof(addr_un.sun_path) ); - addr_len = offsetof( struct sockaddr_un, sun_path ) + spl + 1; - addr = (struct sockaddr *)&addr_un; - } else - return -1; - - old_sigpipe = Signal( SIGPIPE, SIG_IGN ); - - errors = 0; - rval = -1; -reopen: - if ((fd = socket( af, SOCK_STREAM, 0 )) < 0) { - LogError( "Couldn't create socket: %m\n" ); - goto done; - } - - if (connect( fd, (struct sockaddr *)addr, addr_len )) { - if (af == AF_INET) - LogError( "Couldn't connect to PRNGD port %d: %m\n", - tcp_port ); - else - LogError( "Couldn't connect to PRNGD socket %\"s: %m\n", - socket_path ); - goto done; - } - - /* Send blocking read request to PRNGD */ - msg[0] = 0x02; - msg[1] = len; - - if (Writer( fd, msg, sizeof(msg) ) != sizeof(msg)) { - if (errno == EPIPE && errors < 10) { - close( fd ); - errors++; - goto reopen; - } - LogError( "Couldn't write to PRNGD socket: %m\n" ); - goto done; - } - - if (Reader( fd, buf, len ) != len) { - if (errno == EPIPE && errors < 10) { - close( fd ); - errors++; - goto reopen; - } - LogError( "Couldn't read from PRNGD socket: %m\n" ); - goto done; - } - - rval = 0; -done: - Signal( SIGPIPE, old_sigpipe ); - if (fd != -1) - close( fd ); - return rval; -} - -/* ####################################################################### */ - -/* - * Stolen from the Linux kernel. - * - * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All - * rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF - * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - */ - -static unsigned epool[32], erotate, eadd_ptr; - -static void -add_entropy( unsigned const *in, int nwords ) -{ - static unsigned const twist_table[8] = { - 0, 0x3b6e20c8, 0x76dc4190, 0x4db26158, - 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; - unsigned i, w; - int new_rotate; - - while (nwords--) { - w = *in++; - w = (w<>(32-erotate)) & 0xffffffff; - i = eadd_ptr = (eadd_ptr - 1) & 31; - new_rotate = erotate + 14; - if (i) - new_rotate = erotate + 7; - erotate = new_rotate & 31; - w ^= epool[(i + 26) & 31]; - w ^= epool[(i + 20) & 31]; - w ^= epool[(i + 14) & 31]; - w ^= epool[(i + 7) & 31]; - w ^= epool[(i + 1) & 31]; - w ^= epool[i]; - epool[i] = (w >> 3) ^ twist_table[w & 7]; - } -} - -/* ####################################################################### */ - -/* - * This code implements something close to the MD5 message-digest - * algorithm. This code is based on code written by Colin Plumb - * in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - */ - -/* The four core functions - F1 is optimized somewhat */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1 (z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define pmd5_step(f, w, x, y, z, data, s) \ - (w += (f(x, y, z) + data) & 0xffffffff, w = w<>(32-s), w += x) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. - */ -static void -pmd5_hash( unsigned *out, unsigned const in[16] ) -{ - unsigned a, b, c, d; - - a = out[0]; - b = out[1]; - c = out[2]; - d = out[3]; - - pmd5_step( F1, a, b, c, d, in[0] + 0xd76aa478, 7 ); - pmd5_step( F1, d, a, b, c, in[1] + 0xe8c7b756, 12 ); - pmd5_step( F1, c, d, a, b, in[2] + 0x242070db, 17 ); - pmd5_step( F1, b, c, d, a, in[3] + 0xc1bdceee, 22 ); - pmd5_step( F1, a, b, c, d, in[4] + 0xf57c0faf, 7 ); - pmd5_step( F1, d, a, b, c, in[5] + 0x4787c62a, 12 ); - pmd5_step( F1, c, d, a, b, in[6] + 0xa8304613, 17 ); - pmd5_step( F1, b, c, d, a, in[7] + 0xfd469501, 22 ); - pmd5_step( F1, a, b, c, d, in[8] + 0x698098d8, 7 ); - pmd5_step( F1, d, a, b, c, in[9] + 0x8b44f7af, 12 ); - pmd5_step( F1, c, d, a, b, in[10] + 0xffff5bb1, 17 ); - pmd5_step( F1, b, c, d, a, in[11] + 0x895cd7be, 22 ); - pmd5_step( F1, a, b, c, d, in[12] + 0x6b901122, 7 ); - pmd5_step( F1, d, a, b, c, in[13] + 0xfd987193, 12 ); - pmd5_step( F1, c, d, a, b, in[14] + 0xa679438e, 17 ); - pmd5_step( F1, b, c, d, a, in[15] + 0x49b40821, 22 ); - - pmd5_step( F2, a, b, c, d, in[1] + 0xf61e2562, 5 ); - pmd5_step( F2, d, a, b, c, in[6] + 0xc040b340, 9 ); - pmd5_step( F2, c, d, a, b, in[11] + 0x265e5a51, 14 ); - pmd5_step( F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20 ); - pmd5_step( F2, a, b, c, d, in[5] + 0xd62f105d, 5 ); - pmd5_step( F2, d, a, b, c, in[10] + 0x02441453, 9 ); - pmd5_step( F2, c, d, a, b, in[15] + 0xd8a1e681, 14 ); - pmd5_step( F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20 ); - pmd5_step( F2, a, b, c, d, in[9] + 0x21e1cde6, 5 ); - pmd5_step( F2, d, a, b, c, in[14] + 0xc33707d6, 9 ); - pmd5_step( F2, c, d, a, b, in[3] + 0xf4d50d87, 14 ); - pmd5_step( F2, b, c, d, a, in[8] + 0x455a14ed, 20 ); - pmd5_step( F2, a, b, c, d, in[13] + 0xa9e3e905, 5 ); - pmd5_step( F2, d, a, b, c, in[2] + 0xfcefa3f8, 9 ); - pmd5_step( F2, c, d, a, b, in[7] + 0x676f02d9, 14 ); - pmd5_step( F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20 ); - - pmd5_step( F3, a, b, c, d, in[5] + 0xfffa3942, 4 ); - pmd5_step( F3, d, a, b, c, in[8] + 0x8771f681, 11 ); - pmd5_step( F3, c, d, a, b, in[11] + 0x6d9d6122, 16 ); - pmd5_step( F3, b, c, d, a, in[14] + 0xfde5380c, 23 ); - pmd5_step( F3, a, b, c, d, in[1] + 0xa4beea44, 4 ); - pmd5_step( F3, d, a, b, c, in[4] + 0x4bdecfa9, 11 ); - pmd5_step( F3, c, d, a, b, in[7] + 0xf6bb4b60, 16 ); - pmd5_step( F3, b, c, d, a, in[10] + 0xbebfbc70, 23 ); - pmd5_step( F3, a, b, c, d, in[13] + 0x289b7ec6, 4 ); - pmd5_step( F3, d, a, b, c, in[0] + 0xeaa127fa, 11 ); - pmd5_step( F3, c, d, a, b, in[3] + 0xd4ef3085, 16 ); - pmd5_step( F3, b, c, d, a, in[6] + 0x04881d05, 23 ); - pmd5_step( F3, a, b, c, d, in[9] + 0xd9d4d039, 4 ); - pmd5_step( F3, d, a, b, c, in[12] + 0xe6db99e5, 11 ); - pmd5_step( F3, c, d, a, b, in[15] + 0x1fa27cf8, 16 ); - pmd5_step( F3, b, c, d, a, in[2] + 0xc4ac5665, 23 ); - - pmd5_step( F4, a, b, c, d, in[0] + 0xf4292244, 6 ); - pmd5_step( F4, d, a, b, c, in[7] + 0x432aff97, 10 ); - pmd5_step( F4, c, d, a, b, in[14] + 0xab9423a7, 15 ); - pmd5_step( F4, b, c, d, a, in[5] + 0xfc93a039, 21 ); - pmd5_step( F4, a, b, c, d, in[12] + 0x655b59c3, 6 ); - pmd5_step( F4, d, a, b, c, in[3] + 0x8f0ccc92, 10 ); - pmd5_step( F4, c, d, a, b, in[10] + 0xffeff47d, 15 ); - pmd5_step( F4, b, c, d, a, in[1] + 0x85845dd1, 21 ); - pmd5_step( F4, a, b, c, d, in[8] + 0x6fa87e4f, 6 ); - pmd5_step( F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10 ); - pmd5_step( F4, c, d, a, b, in[6] + 0xa3014314, 15 ); - pmd5_step( F4, b, c, d, a, in[13] + 0x4e0811a1, 21 ); - pmd5_step( F4, a, b, c, d, in[4] + 0xf7537e82, 6 ); - pmd5_step( F4, d, a, b, c, in[11] + 0xbd3af235, 10 ); - pmd5_step( F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15 ); - pmd5_step( F4, b, c, d, a, in[9] + 0xeb86d391, 21 ); - - out[0] += a; - out[1] += b; - out[2] += c; - out[3] += d; -} - -/* ####################################################################### */ - - -static int -sumFile( const char *name, int len, int whence, long offset ) -{ - int fd, i, cnt, readlen = 0; - unsigned char buf[0x1000]; - - if ((fd = open( name, O_RDONLY )) < 0) { - Debug( "cannot open entropy source %\"s: %m\n", name ); - return -1; - } - lseek( fd, offset, whence ); - while (readlen < len) { - if (!(cnt = read( fd, buf, sizeof(buf) ))) - break; - if (cnt < 0) { - close( fd ); - Debug( "cannot read entropy source %\"s: %m\n", name ); - return -1; - } - readlen += cnt; - if (sizeof(unsigned) == 4) - add_entropy( (unsigned *)buf, (cnt + 3) / 4 ); - else { - unsigned buf2[sizeof(buf) / 4]; - for (i = 0; i < cnt; i += 8) { - buf2[i / 4] = *(unsigned *)(buf + i) & 0xffffffff; - buf2[i / 4 + 1] = *(unsigned *)(buf + i) >> 32; - } - add_entropy( buf2, (cnt + 3) / 4 ); - } - } - close( fd ); - Debug( "read %d bytes from entropy source %\"s\n", readlen, name ); - return readlen; -} - -void -AddTimerEntropy( void ) -{ - struct timeval now; - gettimeofday( &now, 0 ); - add_entropy( (unsigned *)&now, sizeof(now)/sizeof(unsigned) ); -} - -#define BSIZ 0x10000 - -void -AddOtherEntropy( void ) -{ - AddTimerEntropy(); - /* XXX -- setup-specific ... use some common ones */ - sumFile( "/var/log/messages", 0x1000, SEEK_END, -0x1000 ); - sumFile( "/var/log/syslog", 0x1000, SEEK_END, -0x1000 ); - sumFile( "/var/log/debug", 0x1000, SEEK_END, -0x1000 ); - sumFile( "/var/log/kern.log", 0x1000, SEEK_END, -0x1000 ); - sumFile( "/var/log/daemon.log", 0x1000, SEEK_END, -0x1000 ); -/* root hardly ever has an own box ... maybe pick a random mailbox instead? eek ... - sumFile( "/var/spool/mail/root", 0x1000, SEEK_END, -0x1000 ); -*/ -} - -void -AddPreGetEntropy( void ) -{ - static long offset; - int readlen; - - AddTimerEntropy(); - if ((readlen = sumFile( randomFile, BSIZ, SEEK_SET, offset )) == BSIZ) { - offset += readlen; -#if defined(__i386__) || defined(amiga) - if (!strcmp( randomFile, "/dev/mem" )) { - if (offset == 0xa0000) /* skip 640kB-1MB ROM mappings */ - offset = 0x100000; - else if (offset == 0xf00000) /* skip 15-16MB memory hole */ - offset = 0x1000000; - } -#endif - return; - } else if (readlen >= 0 && offset) { - if ((offset = sumFile( randomFile, BSIZ, SEEK_SET, 0 )) == BSIZ) - return; - } - LogError( "Cannot read randomFile %\"s; " - "X cookies may be easily guessable\n", randomFile ); -} -#endif - -/* ONLY 8 or 16 bytes! */ -/* auth MUST be sizeof(unsigned)-aligned! */ -int -GenerateAuthData( char *auth, int len ) -{ -#ifdef HAVE_ARC4RANDOM - int i; - unsigned *rnd = (unsigned *)auth; - if (sizeof(unsigned) == 4) - for (i = 0; i < len; i += 4) - rnd[i / 4] = arc4random(); - else - for (i = 0; i < len; i += 8) - rnd[i / 8] = arc4random() | (arc4random() << 32); - return 1; -#else - int fd; - const char *rd = randomDevice; -# ifdef DEV_RANDOM - if (!*rd) - rd = DEV_RANDOM; -# else - if (*rd) { -# endif - if ((fd = open( rd, O_RDONLY )) >= 0) { - if (read( fd, auth, len ) == len) { - close( fd ); - return 1; - } - close( fd ); - LogError( "Cannot read randomDevice %\"s: %m\n", rd ); - } else - LogError( "Cannot open randomDevice %\"s: %m\n", rd ); -# ifdef DEV_RANDOM - return 0; -# else - } - - if (!getPrngdBytes( auth, len, prngdPort, prngdSocket )) - return 1; - - { - unsigned *rnd = (unsigned *)auth; - unsigned tmp[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; - AddPreGetEntropy(); - pmd5_hash( tmp, epool ); - add_entropy( tmp, 1 ); - pmd5_hash( tmp, epool + 16 ); - add_entropy( tmp + 2, 1 ); - if (sizeof(unsigned) == 4) - memcpy( auth, tmp, len ); - else { - int i; - for (i = 0; i < len; i += 8) - rnd[i / 8] = tmp[i / 4] | (tmp[i / 4 + 1] << 32); - } - } - return 1; -# endif -#endif -} - -#ifndef HAVE_ARC4RANDOM -int -secureRandom( void ) -{ - int rslt; - GenerateAuthData( (char *)&rslt, sizeof(int) ); - return rslt & 0x7fffffff; -} -#endif \ No newline at end of file diff --git a/kdm/backend/greet.h b/kdm/backend/greet.h deleted file mode 100644 index 985edc29c..000000000 --- a/kdm/backend/greet.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - -Copyright 2001-2005 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * interface to xdm's external greeter and config reader - */ - -#ifndef GREET_H -#define GREET_H - -#include - -#define DEBUG_CORE 0x01 -#define DEBUG_CONFIG 0x02 -#define DEBUG_GREET 0x04 -#define DEBUG_HLPCON 0x08 -#define DEBUG_WSESS 0x10 -#define DEBUG_WCONFIG 0x20 -#define DEBUG_WGREET 0x40 -#define DEBUG_NOSYSLOG 0x80 -#define DEBUG_AUTH 0x100 -#define DEBUG_VALGRIND 0x400 -#define DEBUG_STRACE 0x800 - -#ifndef TRUE -# define TRUE 1 -# define FALSE 0 -#endif - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) -# define ATTR_UNUSED __attribute__((unused)) -# define ATTR_NORETURN __attribute__((noreturn)) -# define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var))) -#else -# define ATTR_UNUSED -# define ATTR_NORETURN -# define ATTR_PRINTFLIKE(fmt,var) -#endif - -#define as(ar) ((int)(sizeof(ar)/sizeof(ar[0]))) - -#define __stringify(x) #x -#define stringify(x) __stringify(x) - -/* - * Exit codes for fork()ed session process, greeter, and config reader - */ -#define EX_NORMAL 30 /* do whatever seems appropriate */ -#define EX_REMANAGE_DPY 31 /* force remanage; same as EX_NORMAL, but cannot return to reserve mode immediately */ -#define EX_UNMANAGE_DPY 32 /* force deletion */ -#define EX_RESERVER_DPY 33 /* force server termination */ -#define EX_AL_RESERVER_DPY 34 /* reserver; maybe, auto-(re-)login */ -#define EX_OPENFAILED_DPY 35 /* XOpenDisplay failed, retry */ -#define EX_RESERVE 37 /* put in reserve mode */ -#ifdef XDMCP -#define EX_REMOTE 38 /* start -query-ing X-server */ -#define EX_MAX EX_REMOTE -#else -#define EX_MAX EX_RESERVE -#endif - -/* - * Command codes core -> greeter - */ -#define G_Greet 1 /* get login; bidi */ -#define G_ErrorGreet 2 /* print failed auto-login */ -#ifdef XDMCP -#define G_Choose 3 /* run chooser; bidi */ -# define G_Ch_AddHost 301 -# define G_Ch_ChangeHost 302 -# define G_Ch_RemoveHost 303 -# define G_Ch_BadHost 304 -# define G_Ch_Exit 305 -#endif -#define G_SessMan 4 /* start "session manager" */ -#define G_ConfShutdown 5 /* confirm forced shutdown */ -#define G_GreetTimed 6 /* get login; timed login permitted */ - -#ifdef XDMCP -#define G_Ch_Refresh 10 /* XXX change */ -#define G_Ch_RegisterHost 11 /* str name XXX change */ -#define G_Ch_DirectChoice 12 /* str name XXX change */ -#endif - -/* - * Status/command codes greeter -> core - */ -#define G_Ready 0 /* nop */ -#define G_Cancel 1 /* abort login, etc. */ - -#define G_DGreet 2 /* get login */ -#ifdef XDMCP -#define G_DChoose 3 /* run chooser */ -#endif - -#define G_Shutdown 101 /* 5*int, string; async */ -# define SHUT_REBOOT 1 /* how */ -# define SHUT_HALT 2 -# define SHUT_CONSOLE -1 /* pseudo-code */ -# define SHUT_SCHEDULE 0 /* when; config only */ -# define SHUT_TRYNOW 1 -# define SHUT_FORCENOW 2 -# define SHUT_CANCEL 0 /* force */ -# define SHUT_FORCEMY 1 -# define SHUT_FORCE 2 -# define SHUT_ASK 3 -# define TO_INF 0x7fffffff -#define G_SessionExit 102 /* int code; async */ -#define G_GetCfg 103 /* int what; int sts, */ -#define G_SetupDpy 104 /* ; int */ -#define G_ReadDmrc 105 /* str user; int sts - curdmrc */ -#define G_GetDmrc 106 /* str key; str value - curdmrc */ -/*#define G_ResetDmrc 107*/ /* ; async - newdmrc */ -#define G_PutDmrc 108 /* str key, str value; async - newdmrc */ -#define G_Verify 109 /* str type; ..., int V_ret */ -#define G_VerifyRootOK 110 /* str type; ..., int V_ret */ -#define G_List 111 /* int flags; ?*(str,str,[int,]str,str,int), int 0 */ -# define lstRemote 1 -# define lstPassive 2 -# define lstTTY 4 -# define isSelf 1 -# define isTTY 2 -#define G_QueryShutdown 112 /* ; 5*int; string */ -#define G_Activate 113 /* int vt; async */ -#define G_ListBootOpts 114 /* ; int sts, [argv opts, int dflt, int cur] */ -# define BO_OK 0 -# define BO_NOMAN -1 -# define BO_NOENT -2 -# define BO_IO -3 -#define G_Console 116 /* ; async */ -#define G_AutoLogin 117 /* ; async */ - -/* - * Command codes core -> config reader - */ -#define GC_Files 1 /* get file list */ -#define GC_GetConf 2 /* get a config group */ -# define GC_gGlobal 1 /* get global config array */ -#ifdef XDMCP -# define GC_gXaccess 3 /* get Xaccess equivalent */ -#endif -# define GC_gDisplay 4 /* get per-display config array */ - -/* - * Error code core -> greeter - */ -#define GE_Ok 0 -#define GE_NoFkt 1 /* no such function (only for extensions!) */ -#define GE_Error 2 /* internal error, like OOM */ -/* for config reading */ -#define GE_NoEnt 10 /* no such config entry */ -#define GE_BadType 11 /* unknown config entry type */ -/* for dmrc reading */ -#define GE_NoUser 20 /* no such user */ -#define GE_NoFile 21 /* no such file */ -#define GE_Denied 22 /* permission denied */ - -/* - * Log levels. - * Used independently in core, greeter & config reader. - */ -#define DM_DEBUG 0 -#define DM_INFO 1 -#define DM_WARN 2 -#define DM_ERR 3 -#define DM_PANIC 4 - -/* - * Status codes from Verify - */ -/* terminal status codes */ -#define V_OK 0 -#define V_FAIL 10 /* whatever, already reported with V_MSG_* */ -#define V_AUTH 11 /* authentication failed */ -/* non-terminal status codes */ -#define V_MSG_INFO 110 /* info message attached */ -#define V_MSG_ERR 111 /* error message attached (null for generic) */ -#define V_PUT_USER 112 /* user name attached; only with pam & no user send */ -#define V_CHTOK 113 /* password expired; change now */ -#define V_CHTOK_AUTH 114 /* password expired; change now, but authenticate first */ -#define V_PRE_OK 115 /* authentication succeeded, continue with password change */ -/* queries */ -#define V_GET_TEXT 200 /* str prompt, int echo, int ndelay; str return, int tag */ -# define V_IS_SECRET 1 -# define V_IS_USER 2 -# define V_IS_PASSWORD 4 -# define V_IS_OLDPASSWORD 8 -# define V_IS_NEWPASSWORD 16 -#define V_GET_BINARY 201 /* array prompt, int ndelay; array return */ - -/* - * Config/Runtime data keys - */ -#define C_WHO_MASK 0x00ff0000 /* Non-zero for proprietary extensions (see manufacturer table [to be written]) */ -#define C_TYPE_MASK 0x0f000000 /* Type of the value */ -# define C_TYPE_INT 0x00000000 /* Integer */ -# define C_TYPE_STR 0x01000000 /* String */ -# define C_TYPE_ARGV 0x02000000 /* 0-terminated Array of Strings */ -# define C_TYPE_ARR 0x03000000 /* Array (only when XDCMP is enabled) */ -#define C_PRIVATE 0xf0000000 /* Private, don't make it visible to interfaces! */ - -/* display variables */ -#define C_isLocal (C_TYPE_INT | 0x200) -#define C_hasConsole (C_TYPE_INT | 0x201) -#define C_isAuthorized (C_TYPE_INT | 0x202) - -/** - ** for struct display - **/ - -#define d_location 1 -#define dLocal 1 /* server runs on local host */ -#define dForeign 0 /* server runs on remote host */ - -#define d_lifetime 6 -#define dPermanent 4 /* display restarted when session exits */ -#define dReserve 2 /* display not restarted when session exits */ -#define dTransient 0 /* display removed when session exits */ - -#ifdef XDMCP -#define d_origin 8 -#else -#define d_origin 0 /* clever, huh? :) */ -#endif -#define dFromXDMCP 8 /* started with XDMCP */ -#define dFromFile 0 /* started via entry in servers file */ - -#ifdef XDMCP -/** - ** for xdmcp acls - **/ - -/* - * flags in acl entries - */ -#define a_notAllowed 1 /* both direct and indirect */ -#define a_notBroadcast 2 /* only direct */ -#define a_useChooser 2 /* only indirect */ - -/* - * type of host entries - */ -#define HOST_ALIAS 0 -#define HOST_ADDRESS 1 -#define HOST_PATTERN 2 -#define HOST_BROADCAST 3 - -#endif - -#endif /* GREET_H */ diff --git a/kdm/backend/inifile.c b/kdm/backend/inifile.c deleted file mode 100644 index b5426de75..000000000 --- a/kdm/backend/inifile.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - -Copyright 2003 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * load, save and manipulate ini-style config files - */ - -#include "dm.h" -#include "dm_error.h" - -#include -#include -#include -#include -#include -#include - -char * -iniLoad( const char *fname ) -{ - char *data; - int fd, len; - struct stat st; - - if ((fd = open( fname, O_RDONLY | O_NONBLOCK )) < 0) { - Debug( "cannot open ini-file %\"s: %m", fname ); - return 0; - } - if (fstat( fd, &st ) || !S_ISREG( st.st_mode )) { - LogWarn( "Ini-file %\"s is no regular file\n", fname ); - close( fd ); - return 0; - } - if (st.st_size >= 0x10000) { - LogWarn( "Ini-file %\"s is too big\n", fname ); - close( fd ); - return 0; - } - len = st.st_size; - if (!(data = Malloc( len + 2 ))) { - close( fd ); - return 0; - } - if (read( fd, data, len ) != len) { - Debug( "cannot read ini-file %\"s: %m", fname ); - free( data ); - close( fd ); - return 0; - } - close( fd ); - if (data[len - 1] != '\n') - data[len++] = '\n'; - data[len] = 0; - return data; -} - -int -iniSave( const char *data, const char *fname ) -{ - int fd, cnt, len; - - if ((fd = open( fname, O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, 0600 )) < 0) { - Debug( "cannot create ini-file %\"s: %m", fname ); - return 0; - } - len = strlen( data ); - if ((cnt = write( fd, data, len )) == len) { - close( fd ); - return 1; - } - if (cnt == -1) - Debug( "cannot write ini-file %\"s: %m", fname ); - else - Debug( "cannot write ini-file %\"s: partial write", fname ); - close( fd ); - return 0; -} - -#define apparr(d,s,n) do { memcpy (d, s, n); d += n; } while(0) -#define appbyte(d,b) *d++ = b - -char * -iniEntry( char *data, const char *section, const char *key, const char *value ) -{ - char *p = data, *secinsert = 0, *pastinsert = 0, *cb, *ce, *ndata; - const char *t; - int insect = 0, ll, sl, kl, vl, len, nlen; - - if (p) { - while (*p) { - for (; *p == ' ' || *p == '\t'; p++); - if (*p == '\n') { - p++; - continue; - } - if (*p == '[') { - for (t = section; *++p == *t; t++); - insect = !*t && *p == ']'; - } else if (insect) { - for (t = key; *p == *t; t++, p++); - for (; *p == ' ' || *p == '\t'; p++); - if (!*t && *p == '=') { - for (p++; *p == ' ' || *p == '\t'; p++); - cb = p; - while (*p++ != '\n'); - ce = p; - if (value) { - ll = sl = kl = 0; - len = (ce - data) + strlen( ce ); - goto insert; - } else { - for (ce--; ce != cb && (*(ce - 1) == ' ' || *(ce - 1) == '\t'); ce--); - if (!StrNDup( &p, cb, ce - cb )) - return 0; - return p; - } - } - } - for (; *p != '\n'; p++); - p++; - if (insect) - secinsert = p; - else - pastinsert = p; - } - } - if (!value) - return 0; - len = p - data; - if (secinsert) { - ce = cb = secinsert; - sl = ll = 0; - } else { - sl = strlen( section ) + 3; - if (pastinsert) { - ce = cb = pastinsert; - ll = 1; - } else { - ce = cb = data; - ll = 0; - } - } - kl = strlen( key ) + 1; - insert: - vl = strlen( value ); - nlen = len - (ce - cb) + ll + sl + kl + vl + 1; - if (!(p = ndata = Malloc( nlen + 1 ))) - return data; - apparr( p, data, cb - data ); - if (kl) { - if (sl) { - if (ll) - appbyte( p, '\n' ); - appbyte( p, '[' ); - apparr( p, section, sl - 3 ); - appbyte( p, ']' ); - appbyte( p, '\n' ); - } - apparr( p, key, kl - 1 ); - appbyte( p, '=' ); - } - apparr( p, value, vl ); - appbyte( p, '\n' ); - if (data) { - apparr( p, ce, len - (ce - data) ); - free( data ); - } - appbyte( p, 0 ); - return ndata; -} - -char * -iniMerge( char *data, const char *newdata ) -{ - const char *p, *cb, *ce; - char *section = 0, *key, *value; - - if (!newdata) - return data; - for (p = newdata;;) { - for (; *p == ' ' || *p == '\t'; p++); - if (!*p) - break; - if (*p == '\n') { - p++; - continue; - } - if (*p == '#') { - for (p++; *p != '\n'; p++) - if (!*p) - goto bail; - p++; - continue; - } - if (*p == '[') { - cb = ++p; - for (; *p != ']'; p++) - if (!*p || *p == '\n') /* missing ] */ - goto bail; - if (!ReStrN( §ion, cb, p - cb )) - break; - p++; - } else { - cb = p; - for (; *p != '='; p++) - if (!*p || *p == '\n') /* missing = */ - goto bail; - for (ce = p; ce != cb && (*(ce - 1) == ' ' || *(ce - 1) == '\t'); ce--); - if (!StrNDup( &key, cb, ce - cb )) - break; - for (p++; *p == ' ' || *p == '\t'; p++); - cb = p; - for (; *p && *p != '\n'; p++); - for (ce = p; ce != cb && (*(ce - 1) == ' ' || *(ce - 1) == '\t'); ce--); - if (!StrNDup( &value, cb, ce - cb )) - break; - if (section) - data = iniEntry( data, section, key, value ); - free( value ); - free( key ); - } - } - bail: - if (section) - free( section ); - return data; -} diff --git a/kdm/backend/krb5auth.c b/kdm/backend/krb5auth.c deleted file mode 100644 index 16b640a35..000000000 --- a/kdm/backend/krb5auth.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - -Copyright 1994, 1998 The Open Group -Copyright 2003 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Stephen Gildea, The Open Group - * - * generate Kerberos Version 5 authorization records - */ - -#include - -#ifdef K5AUTH - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include -#include - -#include - -static krb5_context ctx; - -/*ARGSUSED*/ -void -Krb5InitAuth( unsigned short name_len ATTR_UNUSED, const char *name ATTR_UNUSED ) -{ - if (krb5_init_context( &ctx )) - LogError( "Error while initializing Krb5 context\n" ); -} - -/* - * Returns malloc'ed string that is the credentials cache name. - * name should be freed by caller. - */ -static char * -Krb5CCacheName( const char *dname ) -{ - char *name; - const char *tmpdir; - int dnl, nl; - - tmpdir = getenv( "TMPDIR" ); - if (!tmpdir) - tmpdir = "/tmp"; - dnl = strlen( dname ); - name = Malloc( strlen( tmpdir ) + dnl + 20 ); - if (!name) - return NULL; - nl = sprintf( name, "FILE:%s/K5C", tmpdir ); - CleanUpFileName( dname, name + nl, dnl + 1 ); - return name; -} - -Xauth * -Krb5GetAuthFor( unsigned short namelen, const char *name, const char *dname ) -{ - Xauth *new; - char *filename; - - if (!(new = (Xauth *)Malloc( sizeof(*new) ))) - return (Xauth *)0; - new->family = FamilyWild; - new->address_length = 0; - new->address = 0; - new->number_length = 0; - new->number = 0; - - if (dname) { - if (!(filename = Krb5CCacheName( dname ))) { - free( (char *)new ); - return (Xauth *)0; - } - new->data = 0; - if (!StrApp( &new->data, "UU:", filename, (char *)0 )) { - free( filename ); - free( (char *)new ); - return (Xauth *)0; - } - free( filename ); - new->data_length = strlen( new->data ); - } else { - new->data = NULL; - new->data_length = 0; - } - - if (!(new->name = (char *)Malloc( namelen ))) { - free( (char *)new->data ); - free( (char *)new ); - return (Xauth *)0; - } - memmove( new->name, name, namelen ); - new->name_length = namelen; - return new; -} - - -Xauth * -Krb5GetAuth( unsigned short namelen, const char *name ) -{ - return Krb5GetAuthFor( namelen, name, NULL ); -} - - -static krb5_error_code -Krb5DisplayCCache( const char *dname, krb5_ccache *ccache_return, char **name ) -{ - char *ccname; - krb5_error_code code; - - if (!(ccname = Krb5CCacheName( dname ))) - return ENOMEM; - Debug( "resolving Kerberos cache %s\n", ccname ); - if ((code = krb5_cc_resolve( ctx, ccname, ccache_return )) || !name) - free( ccname ); - else - *name = ccname; - return code; -} - -char * -Krb5Init( const char *user, const char *passwd, const char *dname ) -{ - krb5_error_code code; - krb5_get_init_creds_opt options; - krb5_principal me; - krb5_creds my_creds; - krb5_ccache ccache; - char *ccname; - - if (!ctx) - return 0; - - if ((code = krb5_parse_name( ctx, user, &me ))) { - LogError( "%s while parsing Krb5 user %\"s\n", - error_message( code ), user ); - return 0; - } - - krb5_get_init_creds_opt_init( &options ); - /*krb5_get_init_creds_opt_set_tkt_life (&options, 60*60*8);*/ /* 8 hours */ - - if ((code = krb5_get_init_creds_password( ctx, &my_creds, - me, /* principal */ - (char * /* for MIT */) passwd, - 0, /* prompter */ - 0, /* prompter ctx */ - 0, /* start time delta */ - 0, /* service */ - &options ))) - { - char *my_name = NULL; - int code2 = krb5_unparse_name( ctx, me, &my_name ); - if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) - LogError( "Password incorrect for Krb5 principal %\"s\n", - code2 ? user : my_name ); - else - LogError( "%s while getting initial Krb5 credentials for %\"s\n", - error_message( code ), code2 ? user : my_name ); - if (my_name) - free( my_name ); - goto err3; - } - - if ((code = Krb5DisplayCCache( dname, &ccache, &ccname ))) { - LogError( "%s while getting Krb5 ccache for %\"s\n", - error_message( code ), dname ); - goto err2; - } - - if ((code = krb5_cc_initialize( ctx, ccache, me ))) { - LogError( "%s while initializing Krb5 cache %\"s\n", - error_message( code ), ccname ); - goto err1; - } - - if ((code = krb5_cc_store_cred( ctx, ccache, &my_creds ))) { - LogError( "%s while storing Krb5 credentials to cache %\"s\n", - error_message( code ), ccname ); - err1: - krb5_cc_close( ctx, ccache ); - free( ccname ); - err2: - krb5_free_cred_contents( ctx, &my_creds ); - err3: - krb5_free_principal( ctx, me ); - return 0; - } - - krb5_cc_close( ctx, ccache ); - krb5_free_cred_contents( ctx, &my_creds ); - krb5_free_principal( ctx, me ); - return ccname; -} - -void -Krb5Destroy( const char *dname ) -{ - krb5_error_code code; - krb5_ccache ccache; - - if (!ctx) - return; - - if ((code = Krb5DisplayCCache( dname, &ccache, 0 ))) - LogError( "%s while getting Krb5 ccache to destroy\n", - error_message( code ) ); - else { - if ((code = krb5_cc_destroy( ctx, ccache ))) { - if (code == KRB5_FCC_NOFILE) - Debug( "no Kerberos ccache file found to destroy\n" ); - else - LogError( "%s while destroying Krb5 credentials cache\n", - error_message( code ) ); - } else - Debug( "kerberos ccache destroyed\n" ); - } -} - -#endif diff --git a/kdm/backend/mitauth.c b/kdm/backend/mitauth.c deleted file mode 100644 index fd18d41df..000000000 --- a/kdm/backend/mitauth.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2003 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * generate authorization keys - * for MIT-MAGIC-COOKIE-1 type authorization - */ - -#include "dm.h" -#include "dm_auth.h" - -#define AUTH_DATA_LEN 16 /* bytes of authorization data */ -static char auth_name[256]; - -void -MitInitAuth( unsigned short name_len, const char *name ) -{ - if (name_len > 256) - name_len = 256; - memmove( auth_name, name, name_len ); -} - -Xauth * -MitGetAuth( unsigned short namelen, const char *name ) -{ - Xauth *new; - new = (Xauth *)Malloc( sizeof(Xauth) ); - - if (!new) - return (Xauth *)0; - new->family = FamilyWild; - new->address_length = 0; - new->address = 0; - new->number_length = 0; - new->number = 0; - - new->data = (char *)Malloc( AUTH_DATA_LEN ); - if (!new->data) { - free( (char *)new ); - return (Xauth *)0; - } - new->name = (char *)Malloc( namelen ); - if (!new->name) { - free( (char *)new->data ); - free( (char *)new ); - return (Xauth *)0; - } - memmove( (char *)new->name, name, namelen ); - new->name_length = namelen; - if (!GenerateAuthData( new->data, AUTH_DATA_LEN )) { - free( (char *)new->name ); - free( (char *)new->data ); - free( (char *)new ); - return (Xauth *)0; - } - new->data_length = AUTH_DATA_LEN; - return new; -} diff --git a/kdm/backend/netaddr.c b/kdm/backend/netaddr.c deleted file mode 100644 index 349a53528..000000000 --- a/kdm/backend/netaddr.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - -Copyright 1991, 1998 The Open Group -Copyright 2002 Sun Microsystems, Inc. All rights reserved. - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * netaddr.c - Interpretation of XdmcpNetaddr object. - */ - -#include "dm.h" -#include "dm_socket.h" -#include "dm_error.h" - -/* given an char *, returns the socket protocol family used, - e.g., AF_INET */ - -int -NetaddrFamily( char *netaddrp ) -{ -#ifdef STREAMSCONN - short family = *(short *)netaddrp; - return family; -#else - return ((struct sockaddr *)netaddrp)->sa_family; -#endif -} - - -/* given an char *, returns a pointer to the TCP/UDP port used - and sets *lenp to the length of the address - or 0 if not using TCP or UDP. */ - -char * -NetaddrPort( char *netaddrp, int *lenp ) -{ -#ifdef STREAMSCONN - *lenp = 2; - return netaddrp+2; -#else - switch (NetaddrFamily( netaddrp )) - { - case AF_INET: - *lenp = 2; - return (char *)&(((struct sockaddr_in *)netaddrp)->sin_port); -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - *lenp = 2; - return (char *)&(((struct sockaddr_in6 *)netaddrp)->sin6_port); -#endif - default: - *lenp = 0; - return NULL; - } -#endif -} - - -/* given an char *, returns a pointer to the network address - and sets *lenp to the length of the address */ - -char * -NetaddrAddress( char *netaddrp, int *lenp ) -{ -#ifdef STREAMSCONN - *lenp = 4; - return netaddrp+4; -#else - switch (NetaddrFamily( netaddrp )) { -#ifdef UNIXCONN - case AF_UNIX: - *lenp = strlen( ((struct sockaddr_un *)netaddrp)->sun_path ); - return (char *)(((struct sockaddr_un *)netaddrp)->sun_path); -#endif -#ifdef TCPCONN - case AF_INET: - *lenp = sizeof(struct in_addr); - return (char *)&(((struct sockaddr_in *)netaddrp)->sin_addr); -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - { - struct in6_addr *a = &(((struct sockaddr_in6 *)netaddrp)->sin6_addr); - if (IN6_IS_ADDR_V4MAPPED( a )) { - *lenp = sizeof(struct in_addr); - return ((char *)&(a->s6_addr))+12; - } else { - *lenp = sizeof(struct in6_addr); - return (char *)&(a->s6_addr); - } - } -#endif -#endif -#ifdef DNETCONN - case AF_DECnet: - *lenp = sizeof(struct dn_naddr); - return (char *)&(((struct sockaddr_dn *)netaddrp)->sdn_add); -#endif -#ifdef AF_CHAOS - case AF_CHAOS: -#endif - default: - *lenp = 0; - return NULL; - } -#endif /* STREAMSCONN else */ -} - - -/* given an char *, sets *addr to the network address used and - sets *len to the number of bytes in addr. - Returns the X protocol family used, e.g., FamilyInternet */ - -int -ConvertAddr( char *saddr, int *len, char **addr ) -{ - int retval; - - if (len == NULL) - return -1; - *addr = NetaddrAddress( saddr, len ); -#ifdef STREAMSCONN - /* kludge */ - if (NetaddrFamily( saddr ) == 2) - retval = FamilyInternet; -#else - switch (NetaddrFamily( saddr )) { -#ifdef AF_UNSPEC - case AF_UNSPEC: - retval = FamilyLocal; - break; -#endif -#ifdef AF_UNIX -#ifndef __hpux - case AF_UNIX: - retval = FamilyLocal; - break; -#endif -#endif -#ifdef TCPCONN - case AF_INET: - retval = FamilyInternet; - break; -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - if (*len == sizeof(struct in_addr)) - retval = FamilyInternet; - else - retval = FamilyInternet6; - break; -#endif -#endif -#ifdef DNETCONN - case AF_DECnet: - retval = FamilyDECnet; - break; -#endif -#ifdef AF_CHAOS - case AF_CHAOS: - retval = FamilyChaos; - break; -#endif - default: - retval = -1; - break; - } -#endif /* STREAMSCONN else */ - Debug( "ConvertAddr returning %d for family %d\n", retval, - NetaddrFamily( saddr ) ); - return retval; -} - -#ifdef XDMCP -int -addressEqual( char *a1, int len1, char *a2, int len2 ) -{ - int partlen1, partlen2; - char *part1, *part2; - - if (len1 != len2) - return FALSE; - if (NetaddrFamily( a1 ) != NetaddrFamily( a2 )) - return FALSE; - part1 = NetaddrPort( a1, &partlen1 ); - part2 = NetaddrPort( a2, &partlen2 ); - if (partlen1 != partlen2 || memcmp( part1, part2, partlen1 ) != 0) - return FALSE; - part1 = NetaddrAddress( a1, &partlen1 ); - part2 = NetaddrAddress( a2, &partlen2 ); - if (partlen1 != partlen2 || memcmp( part1, part2, partlen1 ) != 0) - return FALSE; - return TRUE; -} -#endif diff --git a/kdm/backend/policy.c b/kdm/backend/policy.c deleted file mode 100644 index cabee7088..000000000 --- a/kdm/backend/policy.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2001 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * policy.c. Implement site-dependent policy for XDMCP connections - */ - -#include - -#ifdef XDMCP - -#include "dm.h" -#include "dm_auth.h" -#include "dm_socket.h" - -static ARRAY8 noAuthentication = { (CARD16)0, (CARD8Ptr) 0 }; - -typedef struct _XdmAuth { - ARRAY8 authentication; - ARRAY8 authorization; -} XdmAuthRec, *XdmAuthPtr; - -static XdmAuthRec auth[] = { -#ifdef HASXDMAUTH -{ {(CARD16)20, (CARD8 *)"XDM-AUTHENTICATION-1"}, - {(CARD16)19, (CARD8 *)"XDM-AUTHORIZATION-1"}, -}, -#endif -{ {(CARD16)0, (CARD8 *)0}, - {(CARD16)0, (CARD8 *)0}, -} -}; - -#define NumAuth as(auth) - -ARRAY8Ptr -ChooseAuthentication( ARRAYofARRAY8Ptr authenticationNames ) -{ - int i, j; - - for (i = 0; i < (int)authenticationNames->length; i++) - for (j = 0; j < NumAuth; j++) - if (XdmcpARRAY8Equal( &authenticationNames->data[i], - &auth[j].authentication )) - return &authenticationNames->data[i]; - return &noAuthentication; -} - -int -CheckAuthentication( - struct protoDisplay *pdpy ATTR_UNUSED, - ARRAY8Ptr displayID ATTR_UNUSED, - ARRAY8Ptr name ATTR_UNUSED, - ARRAY8Ptr data ATTR_UNUSED ) -{ -#ifdef HASXDMAUTH - if (name->length && !memcmp( (char *)name->data, "XDM-AUTHENTICATION-1", 20 )) - return XdmCheckAuthentication( pdpy, displayID, name, data ); -#endif - return TRUE; -} - -int -SelectAuthorizationTypeIndex( ARRAY8Ptr authenticationName, - ARRAYofARRAY8Ptr authorizationNames ) -{ - int i, j; - - for (j = 0; j < NumAuth; j++) - if (XdmcpARRAY8Equal( authenticationName, - &auth[j].authentication )) - break; - if (j < NumAuth) - for (i = 0; i < (int)authorizationNames->length; i++) - if (XdmcpARRAY8Equal( &authorizationNames->data[i], - &auth[j].authorization )) - return i; - for (i = 0; i < (int)authorizationNames->length; i++) - if (ValidAuthorization( authorizationNames->data[i].length, - (char *)authorizationNames->data[i].data )) - return i; - return -1; -} - - -/*#define WILLING_INTERNAL*/ - -#ifdef WILLING_INTERNAL -/* Report the loadavg to chooser. Nice feature ... - * - * Wed Mar 10 1999 -- Steffen Hansen - */ -static void -Willing_msg( char *mbuf ) -{ -#ifdef __linux__ - int fd; - int numcpu; - const char *fail_msg = "Willing to manage"; - FILE *f; - float load[3]; - float mhz = 0.0; - char buf[1024]; - - fd = open( "/proc/loadavg", O_RDONLY ); - if (fd == -1) { - sprintf( mbuf, fail_msg ); - return; - } else if (read( fd, buf, 100 ) < 4) { - close( fd ); - sprintf( mbuf, fail_msg ); - return; - } - close( fd ); - - sscanf( buf, "%f %f %f", &load[0], &load[1], &load[2] ); - sprintf( mbuf, "Available (load: %0.2f, %0.2f, %0.2f)", - load[0], load[1], load[2] ); - - numcpu = 0; - - if (!(f = fopen( "/proc/cpuinfo", "r" ))) - return; - - while (fGets( buf, sizeof(buf), f ) != -1) { - float m; - if (sscanf( buf, "cpu MHz : %f", &m )) { - numcpu++; - mhz = m; - } - } - - fclose( f ); - - if (numcpu) { - if (numcpu > 1) - sprintf( buf, " %d*%0.0f MHz", numcpu, mhz ); - else - sprintf( buf, " %0.0f MHz", mhz ); - - strncat( mbuf, buf, 256 ); - - mbuf[255] = 0; - } -#elif HAVE_GETLOADAVG /* !__linux__ */ -#ifdef __GNUC__ -# warning This code is untested... -#endif - double load[3]; - getloadavg( load, 3 ); - sprintf( mbuf, "Available (load: %0.2f, %0.2f, %0.2f)", load[0], - load[1], load[2] ); -#else /* !__linux__ && !GETLOADAVG */ - strcpy( mbuf, "Willing to manage" ); -#endif -} -#endif - -/*ARGSUSED*/ -int -Willing( ARRAY8Ptr addr, CARD16 connectionType, - ARRAY8Ptr authenticationName ATTR_UNUSED, - ARRAY8Ptr status, xdmOpCode type ) -{ - int ret; - char statusBuf[256]; - static time_t lastscan; - - if (autoRescan && lastscan + 15 < now) { - lastscan = now; - ScanAccessDatabase( FALSE ); - } - ret = AcceptableDisplayAddress( addr, connectionType, type ); - if (!ret) - sprintf( statusBuf, "Display not authorized to connect" ); - else { - if (*willing) { - FILE *fd; - int len, ok = 0; - if ((fd = popen( willing, "r" ))) { - for (;;) { - if ((len = fGets( statusBuf, sizeof(statusBuf), fd )) != -1) { - if (len) { - ok = 1; - break; - } - } - if (feof( fd ) || errno != EINTR) - break; - } - pclose( fd ); - } - if (!ok) - sprintf( statusBuf, "Willing, but %.*s failed", - sizeof(statusBuf) - 21, willing ); - } else -#ifdef WILLING_INTERNAL - Willing_msg( statusBuf ); -#else - strcpy( statusBuf, "Willing to manage" ); -#endif - } - status->length = strlen( statusBuf ); - status->data = (CARD8Ptr) Malloc( status->length ); - if (!status->data) - status->length = 0; - else - memmove( status->data, statusBuf, status->length ); - return ret; -} - -/*ARGSUSED*/ -ARRAY8Ptr -Accept( struct sockaddr *from ATTR_UNUSED, int fromlen ATTR_UNUSED, - CARD16 displayNumber ATTR_UNUSED ) -{ - return 0; -} - -/*ARGSUSED*/ -int -SelectConnectionTypeIndex( ARRAY16Ptr connectionTypes, - ARRAYofARRAY8Ptr connectionAddresses ATTR_UNUSED ) -{ - int i; - - /* - * Select one supported connection type - */ - - for (i = 0; i < connectionTypes->length; i++) { - switch (connectionTypes->data[i]) { - case FamilyLocal: -#if defined(TCPCONN) - case FamilyInternet: -# if defined(IPv6) && defined(AF_INET6) - case FamilyInternet6: -# endif /* IPv6 */ -#endif /* TCPCONN */ -#if defined(DNETCONN) - case FamilyDECnet: -#endif /* DNETCONN */ - return i; - } - } /* for */ - return -1; -} - -#endif /* XDMCP */ diff --git a/kdm/backend/printf.c b/kdm/backend/printf.c deleted file mode 100644 index d7220642b..000000000 --- a/kdm/backend/printf.c +++ /dev/null @@ -1,872 +0,0 @@ -/* - -Copyright 2001,2002,2004 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * printf.c - working horse of error.c - */ - -/* - * NOTE: this file is meant to be included, not linked, - * so it can be used in the helper programs without much voodoo. - */ - -/* ########## printf core implementation with some extensions ########## */ -/* - * How to use the extensions: - * - put ' or " in the flags field to quote a string with this char and - * escape special characters (only available, if PRINT_QUOTES is defined) - * - put \\ in the flags field to quote special characters and leading and - * trailing spaces (only available, if PRINT_QUOTES is defined) - * - arrays (only available, if PRINT_ARRAYS is defined) - * - the array modifier [ comes after the maximal field width specifier - * - the array length can be specified literally, with the '*' modifier - * (in which case an argument is expected) or will be automatically - * determined (stop values are -1 for ints and 0 for strings) - * - these modifiers expect their argument to be an in-line string quoted - * with an arbitrary character: - * - (, ) -> array pre-/suf-fix; default "" - * - <, > -> element pre-/suf-fix; default "" - * - | -> element separator; default " " - * - these modifiers expect no argument: - * - : -> print ': ' before an array - * - , -> short for |',' - * - { -> short for ('{')' }'<' '|'' - * - the pointer to the array is the last argument to the format - * - the %m conversion from syslog() is supported - */ - -/************************************************************** - * Partially stolen from OpenSSH's OpenBSD compat directory. - * (C) Patrick Powell, Brandon Long, Thomas Roessler, - * Michael Elkins, Ben Lindstrom - **************************************************************/ - -#include -#include -#include - -/* format flags - Bits */ -#define DP_F_MINUS (1 << 0) -#define DP_F_PLUS (1 << 1) -#define DP_F_SPACE (1 << 2) -#define DP_F_NUM (1 << 3) -#define DP_F_ZERO (1 << 4) -#define DP_F_UPCASE (1 << 5) -#define DP_F_UNSIGNED (1 << 6) -#define DP_F_SQUOTE (1 << 7) -#define DP_F_DQUOTE (1 << 8) -#define DP_F_BACKSL (1 << 9) -#define DP_F_ARRAY (1 << 10) -#define DP_F_COLON (1 << 11) - -/* Conversion Flags */ -#define DP_C_INT 0 -#define DP_C_BYTE 1 -#define DP_C_SHORT 2 -#define DP_C_LONG 3 -#define DP_C_STR 10 - -typedef void (*OutCh)( void *bp, char c ); - - -static void -fmtint( OutCh dopr_outch, void *bp, - long value, int base, int min, int max, int flags ) -{ - const char *ctab; - unsigned long uvalue; - int signvalue = 0; - int place = 0; - int spadlen = 0; /* amount to space pad */ - int zpadlen = 0; /* amount to zero pad */ - char convert[20]; - - if (max < 0) - max = 0; - - uvalue = value; - - if (!(flags & DP_F_UNSIGNED)) { - if (value < 0) { - signvalue = '-'; - uvalue = -value; - } else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else if (flags & DP_F_SPACE) - signvalue = ' '; - } - - ctab = (flags & DP_F_UPCASE) ? "0123456789ABCDEF" : "0123456789abcdef"; - do { - convert[place++] = ctab[uvalue % (unsigned)base]; - uvalue = uvalue / (unsigned)base; - } while (uvalue); - - zpadlen = max - place; - spadlen = min - (max > place ? max : place) - - (signvalue ? 1 : 0) - ((flags & DP_F_NUM) ? 2 : 0); - if (zpadlen < 0) - zpadlen = 0; - if (spadlen < 0) - spadlen = 0; - if (flags & DP_F_ZERO) { - zpadlen = zpadlen > spadlen ? zpadlen : spadlen; - spadlen = 0; - } - if (flags & DP_F_MINUS) - spadlen = -spadlen; /* Left Justifty */ - - - /* Spaces */ - while (spadlen > 0) { - dopr_outch( bp, ' ' ); - --spadlen; - } - - /* Sign */ - if (signvalue) - dopr_outch( bp, signvalue ); - - /* Prefix */ - if (flags & DP_F_NUM) { - dopr_outch( bp, '0' ); - dopr_outch( bp, 'x' ); - } - - /* Zeros */ - if (zpadlen > 0) - while (zpadlen > 0) { - dopr_outch( bp, '0' ); - --zpadlen; - } - - /* Digits */ - while (place > 0) - dopr_outch( bp, convert[--place] ); - - /* Left Justified spaces */ - while (spadlen < 0) { - dopr_outch( bp, ' ' ); - ++spadlen; - } -} - -typedef struct { - const char *str; - size_t len; -} str_t; - -static void -putstr( OutCh dopr_outch, void *bp, str_t *st ) -{ - size_t pt; - - for (pt = 0; pt < st->len; pt++) - dopr_outch( bp, st->str[pt] ); -} - -static str_t _null_parents = { "(null)", 6 }; -#ifdef PRINT_ARRAYS -static str_t _null_dparents = { "((null))", 8 }; -#endif -#if defined(PRINT_QUOTES) || defined(PRINT_ARRAYS) -static str_t _null_caps = { "NULL", 4 }; -#endif - -static void -fmtstr( OutCh dopr_outch, void *bp, - const char *value, int flags, int min, int max ) -{ - int padlen, strln, curcol; -#ifdef PRINT_QUOTES - int lastcol; -#endif - char ch; - - if (!value) { -#ifdef PRINT_QUOTES - if (flags & (DP_F_SQUOTE | DP_F_DQUOTE)) - putstr( dopr_outch, bp, &_null_caps ); - else -#endif - putstr( dopr_outch, bp, &_null_parents ); - return; - } - - for (strln = 0; (unsigned)strln < (unsigned)max && value[strln]; strln++); - padlen = min - strln; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justify */ - - for (; padlen > 0; padlen--) - dopr_outch( bp, ' ' ); -#ifdef PRINT_QUOTES -# if 0 /* gcc's flow analyzer is not the smartest ... */ - lastcol = 0; -# endif - if (flags & DP_F_SQUOTE) - dopr_outch( bp, '\'' ); - else if (flags & DP_F_DQUOTE) - dopr_outch( bp, '"'); - else if (flags & DP_F_BACKSL) - for (lastcol = strln; lastcol && value[lastcol - 1] == ' '; lastcol--); -#endif - for (curcol = 0; curcol < strln; curcol++) { - ch = value[curcol]; -#ifdef PRINT_QUOTES - if (flags & (DP_F_SQUOTE | DP_F_DQUOTE | DP_F_BACKSL)) { - switch (ch) { - case '\r': ch = 'r'; break; - case '\n': ch = 'n'; break; - case '\t': ch = 't'; break; - case '\a': ch = 'a'; break; - case '\b': ch = 'b'; break; - case '\v': ch = 'v'; break; - case '\f': ch = 'f'; break; - default: - if (ch < 32 || - ((unsigned char)ch >= 0x7f && (unsigned char)ch < 0xa0)) - { - dopr_outch( bp, '\\' ); - fmtint( dopr_outch, bp, (unsigned char)ch, 8, 3, 3, DP_F_ZERO ); - continue; - } else { - if ((ch == '\'' && (flags & DP_F_SQUOTE)) || - (ch == '"' && (flags & DP_F_DQUOTE) ) || - (ch == ' ' && (flags & DP_F_BACKSL) && - (!curcol || curcol >= lastcol)) || - ch == '\\') - dopr_outch( bp, '\\' ); - dopr_outch( bp, ch ); - continue; - } - } - dopr_outch( bp, '\\' ); - } -#endif - dopr_outch( bp, ch ); - } -#ifdef PRINT_QUOTES - if (flags & DP_F_SQUOTE) - dopr_outch( bp, '\'' ); - else if (flags & DP_F_DQUOTE) - dopr_outch( bp, '"' ); -#endif - for (; padlen < 0; padlen++) - dopr_outch( bp, ' ' ); -} - -static void -DoPr( OutCh dopr_outch, void *bp, const char *format, va_list args ) -{ - const char *strvalue; -#ifdef PRINT_ARRAYS - str_t arpr, arsf, arepr, aresf, aresp, *arp; - void *arptr; -#endif - unsigned long value; - int radix, min, max, flags, cflags, errn; -#ifdef PRINT_ARRAYS - int arlen; - unsigned aridx; - char sch; -#endif - char ch; -#define NCHR if (!(ch = *format++)) return - -#if 0 /* gcc's flow analyzer is not the smartest ... */ -# ifdef PRINT_ARRAYS - arlen = 0; -# endif - radix = 0; -#endif - errn = errno; - for (;;) { - for (;;) { - NCHR; - if (ch == '%') - break; - dopr_outch (bp, ch); - } - flags = cflags = min = 0; - max = -1; - for (;;) { - NCHR; - switch (ch) { - case '#': flags |= DP_F_NUM; continue; - case '-': flags |= DP_F_MINUS; continue; - case '+': flags |= DP_F_PLUS; continue; - case ' ': flags |= DP_F_SPACE; continue; - case '0': flags |= DP_F_ZERO; continue; -#ifdef PRINT_QUOTES - case '"': flags |= DP_F_DQUOTE; continue; - case '\'': flags |= DP_F_SQUOTE; continue; - case '\\': flags |= DP_F_BACKSL; continue; -#endif - } - break; - } - for (;;) { - if (isdigit( (unsigned char)ch )) { - min = 10 * min + (ch - '0'); - NCHR; - continue; - } else if (ch == '*') { - min = va_arg( args, int ); - NCHR; - } - break; - } - if (ch == '.') { - max = 0; - for (;;) { - NCHR; - if (isdigit( (unsigned char)ch )) { - max = 10 * max + (ch - '0'); - continue; - } else if (ch == '*') { - max = va_arg( args, int ); - NCHR; - } - break; - } - } -#ifdef PRINT_ARRAYS - if (ch == '[') { - flags |= DP_F_ARRAY; - arlen = -1; - arpr.len = arsf.len = arepr.len = aresf.len = 0; - aresp.len = 1, aresp.str = " "; - for (;;) { - NCHR; - if (isdigit( (unsigned char)ch )) { - arlen = 0; - for (;;) { - arlen += (ch - '0'); - NCHR; - if (!isdigit( (unsigned char)ch )) - break; - arlen *= 10; - } - } - switch (ch) { - case ':': flags |= DP_F_COLON; continue; - case '*': arlen = va_arg( args, int ); continue; - case '(': arp = &arpr; goto rar; - case ')': arp = &arsf; goto rar; - case '<': arp = &arepr; goto rar; - case '>': arp = &aresf; goto rar; - case '|': arp = &aresp; - rar: - NCHR; - sch = ch; - arp->str = format; - do { - NCHR; - } while (ch != sch); - arp->len = format - arp->str - 1; - continue; - case ',': - aresp.len = 1, aresp.str = ","; - continue; - case '{': - aresp.len = 0, arpr.len = arepr.len = 1, arsf.len = 2; - arpr.str = "{", arepr.str = " ", arsf.str = " }"; - continue; - } - break; - } - } -#endif - for (;;) { - switch (ch) { - case 'h': - cflags = DP_C_SHORT; - NCHR; - if (ch == 'h') { - cflags = DP_C_BYTE; - NCHR; - } - continue; - case 'l': - cflags = DP_C_LONG; - NCHR; - continue; - } - break; - } - switch (ch) { - case '%': - dopr_outch( bp, ch ); - break; - case 'm': - fmtstr( dopr_outch, bp, strerror( errn ), flags, min, max ); - break; - case 'c': - dopr_outch( bp, va_arg( args, int ) ); - break; - case 's': -#ifdef PRINT_ARRAYS - cflags = DP_C_STR; - goto printit; -#else - strvalue = va_arg( args, char * ); - fmtstr( dopr_outch, bp, strvalue, flags, min, max ); - break; -#endif - case 'u': - flags |= DP_F_UNSIGNED; - case 'd': - case 'i': - radix = 10; - goto printit; - case 'X': - flags |= DP_F_UPCASE; - case 'x': - flags |= DP_F_UNSIGNED; - radix = 16; - printit: -#ifdef PRINT_ARRAYS - if (flags & DP_F_ARRAY) { - if (!(arptr = va_arg( args, void * ))) - putstr( dopr_outch, bp, - arpr.len ? &_null_caps : &_null_dparents ); - else { - if (arlen == -1) { - arlen = 0; - switch (cflags) { - case DP_C_STR: while (((char **)arptr)[arlen]) arlen++; break; - case DP_C_BYTE: while (((unsigned char *)arptr)[arlen] != (unsigned char)-1) arlen++; break; - case DP_C_SHORT: while (((unsigned short int *)arptr)[arlen] != (unsigned short int)-1) arlen++; break; - case DP_C_LONG: while (((unsigned long int *)arptr)[arlen] != (unsigned long int)-1) arlen++; break; - default: while (((unsigned int *)arptr)[arlen] != (unsigned int)-1) arlen++; break; - } - } - if (flags & DP_F_COLON) { - fmtint( dopr_outch, bp, (long)arlen, 10, 0, -1, DP_F_UNSIGNED ); - dopr_outch( bp, ':' ); - dopr_outch( bp, ' ' ); - } - putstr( dopr_outch, bp, &arpr ); - for (aridx = 0; aridx < (unsigned)arlen; aridx++) { - if (aridx) - putstr( dopr_outch, bp, &aresp ); - putstr( dopr_outch, bp, &arepr ); - if (cflags == DP_C_STR) { - strvalue = ((char **)arptr)[aridx]; - fmtstr( dopr_outch, bp, strvalue, flags, min, max ); - } else { - if (flags & DP_F_UNSIGNED) { - switch (cflags) { - case DP_C_BYTE: value = ((unsigned char *)arptr)[aridx]; break; - case DP_C_SHORT: value = ((unsigned short int *)arptr)[aridx]; break; - case DP_C_LONG: value = ((unsigned long int *)arptr)[aridx]; break; - default: value = ((unsigned int *)arptr)[aridx]; break; - } - } else { - switch (cflags) { - case DP_C_BYTE: value = ((signed char *)arptr)[aridx]; break; - case DP_C_SHORT: value = ((short int *)arptr)[aridx]; break; - case DP_C_LONG: value = ((long int *)arptr)[aridx]; break; - default: value = ((int *)arptr)[aridx]; break; - } - } - fmtint( dopr_outch, bp, value, radix, min, max, flags ); - } - putstr( dopr_outch, bp, &aresf ); - } - putstr( dopr_outch, bp, &arsf ); - } - } else { - if (cflags == DP_C_STR) { - strvalue = va_arg( args, char * ); - fmtstr( dopr_outch, bp, strvalue, flags, min, max ); - } else { -#endif - if (flags & DP_F_UNSIGNED) { - switch (cflags) { - case DP_C_LONG: value = va_arg( args, unsigned long int ); break; - default: value = va_arg( args, unsigned int ); break; - } - } else { - switch (cflags) { - case DP_C_LONG: value = va_arg( args, long int ); break; - default: value = va_arg( args, int ); break; - } - } - fmtint( dopr_outch, bp, value, radix, min, max, flags ); -#ifdef PRINT_ARRAYS - } - } -#endif - break; - case 'p': - value = (long)va_arg( args, void * ); - fmtint( dopr_outch, bp, value, 16, sizeof(long) * 2 + 2, - max, flags | DP_F_UNSIGNED | DP_F_ZERO | DP_F_NUM ); - break; - } - } -} - -/* ########## end of printf core implementation ########## */ - - -/* - * Logging function for xdm and helper programs. - */ -#ifndef NO_LOGGER - -#include -#include - -#ifdef USE_SYSLOG -# include -# ifdef LOG_NAME -# define InitLog() openlog(LOG_NAME, LOG_PID, LOG_DAEMON) -# else -# define InitLog() openlog(prog, LOG_PID, LOG_DAEMON) -# endif -static int lognums[] = { LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_CRIT }; -#else -# define InitLog() while(0) -#endif - -static const char *lognams[] = { "debug", "info", "warning", "error", "panic" }; - -static void -logTime( char *dbuf ) -{ - time_t tim; - (void)time( &tim ); - strftime( dbuf, 20, "%b %e %H:%M:%S", localtime( &tim ) ); -} - -#if defined(LOG_DEBUG_MASK) || defined(USE_SYSLOG) -STATIC int debugLevel; -#endif - -#define OOMSTR "Out of memory. Expect problems.\n" - -STATIC void -LogOutOfMem( void ) -{ - static time_t last; - time_t tnow; - - time( &tnow ); - if (last + 100 > tnow) { /* don't log bursts */ - last = tnow; - return; - } - last = tnow; -#ifdef USE_SYSLOG - if (!(debugLevel & DEBUG_NOSYSLOG)) - syslog( LOG_CRIT, OOMSTR ); - else -#endif - { - int el; - char dbuf[24], sbuf[128]; - logTime( dbuf ); - el = sprintf( sbuf, "%s " -#ifdef LOG_NAME - LOG_NAME "[%ld]: " OOMSTR, dbuf, -#else - "%s[%ld]: " OOMSTR, dbuf, prog, -#endif - (long)getpid() ); - write( 2, sbuf, el ); - } -} - -typedef struct { - char *buf; - int clen, blen, type; - char lmbuf[128]; -} OCLBuf; - -static void -OutChLFlush( OCLBuf *oclbp ) -{ - if (oclbp->clen) { -#ifdef USE_SYSLOG - if (!(debugLevel & DEBUG_NOSYSLOG)) - syslog( lognums[oclbp->type], "%.*s", oclbp->clen, oclbp->buf ); - else -#endif - { - oclbp->buf[oclbp->clen] = '\n'; - write( 2, oclbp->buf, oclbp->clen + 1 ); - } - oclbp->clen = 0; - } -} - -static void -OutChL( void *bp, char c ) -{ - OCLBuf *oclbp = (OCLBuf *)bp; - char *nbuf; - int nlen; - - if (c == '\n') - OutChLFlush( oclbp ); - else { - if (oclbp->clen >= oclbp->blen - 1) { - if (oclbp->buf == oclbp->lmbuf) { - OutChLFlush( oclbp ); - oclbp->buf = 0; - oclbp->blen = 0; - } - nlen = oclbp->blen * 3 / 2 + 128; - nbuf = Realloc( oclbp->buf, nlen ); - if (nbuf) { - oclbp->buf = nbuf; - oclbp->blen = nlen; - } else { - OutChLFlush( oclbp ); - oclbp->buf = oclbp->lmbuf; - oclbp->blen = sizeof(oclbp->lmbuf); - } - } -#ifdef USE_SYSLOG - if (!oclbp->clen && (debugLevel & DEBUG_NOSYSLOG)) { -#else - if (!oclbp->clen) { -#endif - char dbuf[24]; - logTime( dbuf ); - oclbp->clen = sprintf( oclbp->buf, "%s " -#ifdef LOG_NAME - LOG_NAME "[%ld] %s: ", dbuf, -#else - "%s[%ld] %s: ", dbuf, prog, -#endif - (long)getpid(), lognams[oclbp->type] ); - } - oclbp->buf[oclbp->clen++] = c; - } -} - -static void -Logger( int type, const char *fmt, va_list args ) -{ - OCLBuf oclb; - - oclb.buf = 0; - oclb.blen = oclb.clen = 0; - oclb.type = type; - DoPr( OutChL, &oclb, fmt, args ); - /* no flush, every message is supposed to be \n-terminated */ - if (oclb.buf && oclb.buf != oclb.lmbuf) - free( oclb.buf ); -} - -#ifdef LOG_DEBUG_MASK -STATIC void -Debug( const char *fmt, ... ) -{ - if (debugLevel & LOG_DEBUG_MASK) { - va_list args; - int olderrno = errno; - va_start( args, fmt ); - Logger( DM_DEBUG, fmt, args ); - va_end( args ); - errno = olderrno; - } -} -#endif - -#ifndef LOG_NO_INFO -STATIC void -LogInfo( const char *fmt, ... ) -{ - va_list args; - - va_start( args, fmt ); - Logger( DM_INFO, fmt, args ); - va_end( args ); -} -#endif - -#ifndef LOG_NO_WARN -STATIC void -LogWarn( const char *fmt, ... ) -{ - va_list args; - - va_start( args, fmt ); - Logger( DM_WARN, fmt, args ); - va_end( args ); -} -#endif - -#ifndef LOG_NO_ERROR -STATIC void -LogError( const char *fmt, ... ) -{ - va_list args; - - va_start( args, fmt ); - Logger( DM_ERR, fmt, args ); - va_end( args ); -} -#endif - -#ifdef LOG_PANIC_EXIT -STATIC void -LogPanic( const char *fmt, ... ) -{ - va_list args; - - va_start( args, fmt ); - Logger( DM_PANIC, fmt, args ); - va_end( args ); - exit( LOG_PANIC_EXIT ); -} -#endif - -#endif /* NO_LOGGER */ - -#ifdef NEED_FDPRINTF - -typedef struct { - char *buf; - int clen, blen, tlen; -} OCFBuf; - -static void -OutCh_OCF( void *bp, char c ) -{ - OCFBuf *ocfbp = (OCFBuf *)bp; - char *nbuf; - int nlen; - - ocfbp->tlen++; - if (ocfbp->clen >= ocfbp->blen) { - if (ocfbp->blen < 0) - return; - nlen = ocfbp->blen * 3 / 2 + 100; - nbuf = Realloc( ocfbp->buf, nlen ); - if (!nbuf) { - free( ocfbp->buf ); - ocfbp->blen = -1; - ocfbp->buf = 0; - ocfbp->clen = 0; - return; - } - ocfbp->blen = nlen; - ocfbp->buf = nbuf; - } - ocfbp->buf[ocfbp->clen++] = c; -} - -STATIC int -FdPrintf( int fd, const char *fmt, ... ) -{ - va_list args; - OCFBuf ocfb = { 0, 0, 0, -1 }; - - va_start( args, fmt ); - DoPr( OutCh_OCF, &ocfb, fmt, args ); - va_end( args ); - if (ocfb.buf) { - Debug( "FdPrintf %\".*s to %d\n", ocfb.clen, ocfb.buf, fd ); - (void)write( fd, ocfb.buf, ocfb.clen ); - free( ocfb.buf ); - } - return ocfb.tlen; -} - -#endif /* NEED_FDPRINTF */ - -#ifdef NEED_ASPRINTF - -typedef struct { - char *buf; - int clen, blen, tlen; -} OCABuf; - -static void -OutCh_OCA( void *bp, char c ) -{ - OCABuf *ocabp = (OCABuf *)bp; - char *nbuf; - int nlen; - - ocabp->tlen++; - if (ocabp->clen >= ocabp->blen) { - if (ocabp->blen < 0) - return; - nlen = ocabp->blen * 3 / 2 + 100; - nbuf = Realloc( ocabp->buf, nlen ); - if (!nbuf) { - free( ocabp->buf ); - ocabp->blen = -1; - ocabp->buf = 0; - ocabp->clen = 0; - return; - } - ocabp->blen = nlen; - ocabp->buf = nbuf; - } - ocabp->buf[ocabp->clen++] = c; -} - -STATIC int -VASPrintf( char **strp, const char *fmt, va_list args ) -{ - OCABuf ocab = { 0, 0, 0, -1 }; - - DoPr( OutCh_OCA, &ocab, fmt, args ); - OutCh_OCA( &ocab, 0 ); - *strp = Realloc( ocab.buf, ocab.clen ); - if (!*strp) - *strp = ocab.buf; - return ocab.tlen; -} - -STATIC int -ASPrintf( char **strp, const char *fmt, ... ) -{ - va_list args; - int len; - - va_start( args, fmt ); - len = VASPrintf( strp, fmt, args ); - va_end( args ); - return len; -} - -#endif /* NEED_ASPRINTF */ diff --git a/kdm/backend/process.c b/kdm/backend/process.c deleted file mode 100644 index f9d34fe7f..000000000 --- a/kdm/backend/process.c +++ /dev/null @@ -1,762 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2001-2004 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * subdaemon and external process management and communication - */ - -#include "dm.h" -#include "dm_error.h" - -#include -#include -#include -#include -#include -#ifdef _POSIX_PRIORITY_SCHEDULING -# include -#endif - -extern char **environ; - - -SIGFUNC Signal( int sig, SIGFUNC handler ) -{ -#ifndef __EMX__ - struct sigaction sigact, osigact; - sigact.sa_handler = handler; - sigemptyset( &sigact.sa_mask ); -# ifdef SA_RESTART - sigact.sa_flags = SA_RESTART; -# else - sigact.sa_flags = 0; -# endif - sigaction( sig, &sigact, &osigact ); - return osigact.sa_handler; -#else - return signal( sig, handler ); -#endif -} - - -void -TerminateProcess( int pid, int sig ) -{ - kill( pid, sig ); -#ifdef SIGCONT - kill( pid, SIGCONT ); -#endif -} - - -static FD_TYPE CloseMask; -static int max = -1; - -void -RegisterCloseOnFork( int fd ) -{ - FD_SET( fd, &CloseMask ); - if (fd > max) - max = fd; -} - -void -ClearCloseOnFork( int fd ) -{ - FD_CLR( fd, &CloseMask ); -} - -void -CloseNClearCloseOnFork( int fd ) -{ - close( fd ); - FD_CLR( fd, &CloseMask ); -} - -static void -CloseOnFork( void ) -{ - int fd; - - for (fd = 0; fd <= max; fd++) - if (FD_ISSET( fd, &CloseMask )) - close( fd ); - FD_ZERO( &CloseMask ); - max = -1; -} - -int -Fork() -{ - int pid; - - sigset_t ss, oss; - sigfillset( &ss ); - sigprocmask( SIG_SETMASK, &ss, &oss ); - - if (!(pid = fork())) { -#ifdef SIGCHLD - (void)Signal( SIGCHLD, SIG_DFL ); -#endif - (void)Signal( SIGTERM, SIG_DFL ); - (void)Signal( SIGINT, SIG_IGN ); /* for -nodaemon */ - (void)Signal( SIGPIPE, SIG_DFL ); - (void)Signal( SIGALRM, SIG_DFL ); - (void)Signal( SIGHUP, SIG_DFL ); - sigemptyset( &ss ); - sigprocmask( SIG_SETMASK, &ss, NULL ); - CloseOnFork(); - return 0; - } - - sigprocmask( SIG_SETMASK, &oss, 0 ); - - return pid; -} - -int -Wait4( int pid ) -{ - waitType result; - - while (waitpid( pid, &result, 0 ) < 0) - if (errno != EINTR) { - Debug( "Wait4(%d) failed: %m\n", pid ); - return 0; - } - return waitVal( result ); -} - - -void -execute( char **argv, char **env ) -{ - Debug( "execute: %[s ; %[s\n", argv, env ); - execve( argv[0], argv, env ); - /* - * In case this is a shell script which hasn't been - * made executable (or this is a SYSV box), do - * a reasonable thing - */ - if (errno != ENOENT) { - char **newargv; - FILE *f; - int nu; - char program[1024]; - - /* - * emulate BSD kernel behaviour -- read - * the first line; check if it starts - * with "#!", in which case it uses - * the rest of the line as the name of - * program to run. Else use "/bin/sh". - */ - if (!(f = fopen( argv[0], "r" ))) - return; - if (!fGets( program, sizeof(program), f )) { - fclose( f ); - return; - } - fclose( f ); - if (!strncmp( program, "#!", 2 )) - newargv = parseArgs( 0, program + 2 ); - else - newargv = addStrArr( 0, "/bin/sh", 7 ); - if (!newargv) - return; - nu = arrLen( newargv ); - if (!(argv = xCopyStrArr( nu, argv ))) - return; - memcpy( argv, newargv, sizeof(char *) * nu ); - Debug( "shell script execution: %[s\n", argv ); - execve( argv[0], argv, env ); - } -} - -int -runAndWait( char **args, char **env ) -{ - int pid, ret; - - switch (pid = Fork()) { - case 0: - execute( args, env ); - LogError( "Can't execute %\"s: %m\n", args[0] ); - exit( 127 ); - case -1: - LogError( "Can't fork to execute %\"s: %m\n", args[0] ); - return 1; - } - ret = Wait4( pid ); - return waitVal( ret ); -} - -FILE * -pOpen( char **what, char m, int *pid ) -{ - int dp[2]; - - if (pipe( dp )) - return 0; - switch ((*pid = Fork())) { - case 0: - if (m == 'r') - dup2( dp[1], 1 ); - else - dup2( dp[0], 0 ); - close( dp[0] ); - close( dp[1] ); - execute( what, environ ); - LogError( "Can't execute %\"s: %m\n", what[0] ); - exit( 127 ); - case -1: - close( dp[0] ); - close( dp[1] ); - LogError( "Can't fork to execute %\"s: %m\n", what[0] ); - return 0; - } - if (m == 'r') { - close( dp[1] ); - return fdopen( dp[0], "r" ); - } else { - close( dp[0] ); - return fdopen( dp[1], "w" ); - } -} - -int -pClose( FILE *f, int pid ) -{ - fclose( f ); - return Wait4( pid ); -} - -char * -locate( const char *exe ) -{ - int len; - char *path, *name, *thenam, nambuf[PATH_MAX+1]; - char *pathe; - - if (!(path = getenv( "PATH" ))) { - LogError( "Can't execute %'s: $PATH not set.\n", exe ); - return 0; - } - len = strlen( exe ); - name = nambuf + PATH_MAX - len; - memcpy( name, exe, len + 1 ); - *--name = '/'; - do { - if (!(pathe = strchr( path, ':' ))) - pathe = path + strlen( path ); - len = pathe - path; - if (len && !(len == 1 && *path == '.')) { - thenam = name - len; - if (thenam >= nambuf) { - memcpy( thenam, path, len ); - if (!access( thenam, X_OK )) { - StrDup( &name, thenam ); - return name; - } - } - } - path = pathe; - } while (*path++ != '\0'); - LogError( "Can't execute %'s: not in $PATH.\n", exe ); - return 0; -} - - -static GTalk *curtalk; - -void -GSet( GTalk *tlk ) -{ - curtalk = tlk; -} - -int -GFork( GPipe *pajp, const char *pname, char *cname, - GPipe *ogp, char *cgname ) -{ - int opipe[2], ipipe[2], ogpipe[2], igpipe[2], pid; - - if (pipe( opipe )) - goto badp1; - if (pipe( ipipe )) - goto badp2; - if (ogp) { - if (pipe( ogpipe )) - goto badp3; - if (pipe( igpipe )) { - close( ogpipe[0] ); - close( ogpipe[1] ); - badp3: - close( ipipe[0] ); - close( ipipe[1] ); - badp2: - close( opipe[0] ); - close( opipe[1] ); - badp1: - LogError( "Cannot start %s, pipe() failed", cname ); - if (cname) - free( cname ); - return -1; - } - } - RegisterCloseOnFork( opipe[1] ); - RegisterCloseOnFork( ipipe[0] ); - if (ogp) { - RegisterCloseOnFork( ogpipe[1] ); - RegisterCloseOnFork( igpipe[0] ); - } - switch (pid = Fork()) { - case -1: - close( opipe[0] ); - close( ipipe[1] ); - CloseNClearCloseOnFork( opipe[1] ); - CloseNClearCloseOnFork( ipipe[0] ); - if (ogp) { - close( ogpipe[0] ); - close( igpipe[1] ); - CloseNClearCloseOnFork( ogpipe[1] ); - CloseNClearCloseOnFork( igpipe[0] ); - } - LogError( "Cannot start %s, fork() failed\n", cname ); - if (cname) - free( cname ); - return -1; - case 0: - pajp->wfd = ipipe[1]; - RegisterCloseOnFork( ipipe[1] ); - pajp->rfd = opipe[0]; - RegisterCloseOnFork( opipe[0] ); - pajp->who = (char *)pname; - if (ogp) { - ogp->wfd = igpipe[1]; - RegisterCloseOnFork( igpipe[1] ); - ogp->rfd = ogpipe[0]; - RegisterCloseOnFork( ogpipe[0] ); - ogp->who = (char *)pname; - } - break; - default: - close( opipe[0] ); - close( ipipe[1] ); - pajp->rfd = ipipe[0]; - pajp->wfd = opipe[1]; - pajp->who = cname; - if (ogp) { - close( ogpipe[0] ); - close( igpipe[1] ); - ogp->rfd = igpipe[0]; - ogp->wfd = ogpipe[1]; - ogp->who = cgname; - } - break; - } - return pid; -} - -int -GOpen( GProc *proc, char **argv, const char *what, char **env, char *cname, - GPipe *gp ) -{ - char **margv; - int pip[2]; - char coninfo[32]; - -/* ### GSet (proc->pipe); */ - if (proc->pid) { - LogError( "%s already running\n", cname ); - if (cname) - free( cname ); - return -1; - } - if (!(margv = xCopyStrArr( 1, argv ))) { - if (cname) - free( cname ); - return -1; - } - if (!StrApp( margv, progpath, what, (char *)0 )) { - free( margv ); - if (cname) - free( cname ); - return -1; - } - if (pipe( pip )) { - LogError( "Cannot start %s, pipe() failed\n", cname ); - if (cname) - free( cname ); - goto fail; - } - if (gp) { - ClearCloseOnFork( gp->rfd ); - ClearCloseOnFork( gp->wfd ); - } - proc->pid = GFork( &proc->pipe, 0, cname, 0, 0 ); - if (proc->pid) { - close( pip[1] ); - if (gp) { - RegisterCloseOnFork( gp->rfd ); - RegisterCloseOnFork( gp->wfd ); - } - } - switch (proc->pid) { - case -1: - fail1: - close( pip[0] ); - fail: - free( margv[0] ); - free( margv ); - return -1; - case 0: - (void)Signal( SIGPIPE, SIG_IGN ); - close( pip[0] ); - fcntl( pip[1], F_SETFD, FD_CLOEXEC ); - if (gp) - sprintf( coninfo, "CONINFO=%d %d %d %d", - proc->pipe.rfd, proc->pipe.wfd, gp->rfd, gp->wfd ); - else - sprintf( coninfo, "CONINFO=%d %d", - proc->pipe.rfd, proc->pipe.wfd ); - env = putEnv( coninfo, env ); - if (debugLevel & DEBUG_VALGRIND) { - char **nmargv = xCopyStrArr( 1, margv ); - nmargv[0] = locate( "valgrind" ); - execute( nmargv, env ); - } else if (debugLevel & DEBUG_STRACE) { - char **nmargv = xCopyStrArr( 1, margv ); - nmargv[0] = locate( "strace" ); - execute( nmargv, env ); - } else - execute( margv, env ); - write( pip[1], "", 1 ); - exit( 1 ); - default: - (void)Signal( SIGPIPE, SIG_IGN ); - if (Reader( pip[0], coninfo, 1 )) { - Wait4( proc->pid ); - LogError( "Cannot execute %\"s (%s)\n", margv[0], cname ); - GClosen (&proc->pipe); - goto fail1; - } - close( pip[0] ); - Debug( "started %s (%\"s), pid %d\n", cname, margv[0], proc->pid ); - free( margv[0] ); - free( margv ); - GSendInt( debugLevel ); - return 0; - } -} - -static void -iGClosen( GPipe *pajp ) -{ - CloseNClearCloseOnFork( pajp->rfd ); - CloseNClearCloseOnFork( pajp->wfd ); - pajp->rfd = pajp->wfd = -1; -} - -void -GClosen (GPipe *pajp) -{ - iGClosen( pajp ); - if (pajp->who) - free( pajp->who ); - pajp->who = 0; -} - -int -GClose (GProc *proc, GPipe *gp, int force) -{ - int ret; - - if (!proc->pid) { - Debug( "whoops, GClose while helper not running\n" ); - return 0; - } - iGClosen( &proc->pipe ); - if (gp) - GClosen (gp); - if (force) - TerminateProcess( proc->pid, SIGTERM ); - ret = Wait4( proc->pid ); - proc->pid = 0; - if (WaitSig( ret ) ? WaitSig( ret ) != SIGTERM : - (WaitCode( ret ) < EX_NORMAL || WaitCode( ret ) > EX_MAX)) - LogError( "Abnormal termination of %s, code %d, signal %d\n", - proc->pipe.who, WaitCode( ret ), WaitSig( ret ) ); - Debug( "closed %s\n", proc->pipe.who ); - if (proc->pipe.who) - free( proc->pipe.who ); - proc->pipe.who = 0; - return ret; -} - -static void ATTR_NORETURN -GErr( void ) -{ - Longjmp( curtalk->errjmp, 1 ); -} - -static void -GRead( void *buf, int len ) -{ - if (Reader( curtalk->pipe->rfd, buf, len ) != len) { - LogError( "Cannot read from %s\n", curtalk->pipe->who ); - GErr(); - } -} - -static void -GWrite( const void *buf, int len ) -{ - if (Writer( curtalk->pipe->wfd, buf, len ) != len) { - LogError( "Cannot write to %s\n", curtalk->pipe->who ); - GErr(); - } -#ifdef _POSIX_PRIORITY_SCHEDULING - if ((debugLevel & DEBUG_HLPCON)) - sched_yield(); -#endif -} - -void -GSendInt( int val ) -{ - GDebug( "sending int %d (%#x) to %s\n", val, val, curtalk->pipe->who ); - GWrite( &val, sizeof(val) ); -} - -int -GRecvInt() -{ - int val; - - GDebug( "receiving int from %s ...\n", curtalk->pipe->who ); - GRead( &val, sizeof(val) ); - GDebug( " -> %d (%#x)\n", val, val ); - return val; -} - -int -GRecvCmd( int *cmd ) -{ - GDebug( "receiving command from %s ...\n", curtalk->pipe->who ); - if (Reader( curtalk->pipe->rfd, cmd, sizeof(*cmd) ) == sizeof(*cmd)) { - GDebug( " -> %d\n", *cmd ); - return 1; - } - GDebug( " -> no data\n" ); - return 0; -} - -void -GSendArr( int len, const char *data ) -{ - GDebug( "sending array[%d] %02[*{hhx to %s\n", - len, len, data, curtalk->pipe->who ); - GWrite( &len, sizeof(len) ); - GWrite( data, len ); -} - -static char * -iGRecvArr( int *rlen ) -{ - int len; - char *buf; - - GRead( &len, sizeof(len) ); - *rlen = len; - GDebug( " -> %d bytes\n", len ); - if (!len) - return (char *)0; - if (!(buf = Malloc( len ))) - GErr(); - GRead( buf, len ); - return buf; -} - -char * -GRecvArr( int *rlen ) -{ - char *buf; - - GDebug( "receiving array from %s ...\n", curtalk->pipe->who ); - buf = iGRecvArr( rlen ); - GDebug( " -> %02[*{hhx\n", *rlen, buf ); - return buf; -} - -static int -iGRecvArrBuf( char *buf ) -{ - int len; - - GRead( &len, sizeof(len) ); - GDebug( " -> %d bytes\n", len ); - if (len) - GRead( buf, len ); - return len; -} - -int -GRecvArrBuf( char *buf ) -{ - int len; - - GDebug( "receiving already allocated array from %s ...\n", - curtalk->pipe->who ); - len = iGRecvArrBuf( buf ); - GDebug( " -> %02[*{hhx\n", len, buf ); - return len; -} - -int -GRecvStrBuf( char *buf ) -{ - int len; - - GDebug( "receiving already allocated string from %s ...\n", - curtalk->pipe->who ); - len = iGRecvArrBuf( buf ); - GDebug( " -> %\".*s\n", len, buf ); - return len; -} - -void -GSendStr( const char *buf ) -{ - int len; - - GDebug( "sending string %\"s to %s\n", buf, curtalk->pipe->who ); - if (buf) { - len = strlen( buf ) + 1; - GWrite( &len, sizeof(len) ); - GWrite( buf, len ); - } else - GWrite( &buf, sizeof(int) ); -} - -void -GSendNStr( const char *buf, int len ) -{ - int tlen = len + 1; - GDebug( "sending string %\".*s to %s\n", len, buf, curtalk->pipe->who ); - GWrite( &tlen, sizeof(tlen) ); - GWrite( buf, len ); - GWrite( "", 1 ); -} - -void -GSendStrN( const char *buf, int len ) -{ - if (buf) - GSendNStr( buf, StrNLen( buf, len ) ); - else - GSendStr( buf ); -} - -char * -GRecvStr() -{ - int len; - char *buf; - - GDebug( "receiving string from %s ...\n", curtalk->pipe->who ); - buf = iGRecvArr( &len ); - GDebug( " -> %\".*s\n", len, buf ); - return buf; -} - -static void -iGSendStrArr( int num, char **data ) -{ - char **cdata; - - GWrite( &num, sizeof(num) ); - for (cdata = data; --num >= 0; cdata++) - GSendStr( *cdata ); -} - -/* -void -GSendStrArr (int num, char **data) -{ - GDebug( "sending string array[%d] to %s\n", num, curtalk->pipe->who ); - iGSendStrArr( num, data ); -} -*/ - -char ** -GRecvStrArr( int *rnum ) -{ - int num; - char **argv, **cargv; - - GDebug( "receiving string array from %s ...\n", curtalk->pipe->who ); - GRead( &num, sizeof(num) ); - GDebug( " -> %d strings\n", num ); - *rnum = num; - if (!num) - return (char **)0; - if (!(argv = Malloc( num * sizeof(char *) ))) - GErr(); - for (cargv = argv; --num >= 0; cargv++) - *cargv = GRecvStr(); - return argv; -} - -void -GSendArgv( char **argv ) -{ - int num; - - if (argv) { - for (num = 0; argv[num]; num++); - GDebug( "sending argv[%d] to %s ...\n", num, curtalk->pipe->who ); - iGSendStrArr( num + 1, argv ); - } else { - GDebug( "sending NULL argv to %s\n", curtalk->pipe->who ); - GWrite( &argv, sizeof(int) ); - } -} - -char ** -GRecvArgv() -{ - int num; - - return GRecvStrArr( &num ); -} - diff --git a/kdm/backend/protodpy.c b/kdm/backend/protodpy.c deleted file mode 100644 index 08c38fbd1..000000000 --- a/kdm/backend/protodpy.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * manage a collection of proto-displays. These are displays for - * which sessionID's have been generated, but no session has been - * started. - */ - -#include - -#ifdef XDMCP - -#include "dm.h" -#include "dm_error.h" - -static struct protoDisplay *protoDisplays; - -struct protoDisplay * -FindProtoDisplay( - XdmcpNetaddr address, - int addrlen, - CARD16 displayNumber ) -{ - struct protoDisplay *pdpy; - - Debug( "FindProtoDisplay\n" ); - for (pdpy = protoDisplays; pdpy; pdpy=pdpy->next) { - if (pdpy->displayNumber == displayNumber && - addressEqual( address, addrlen, pdpy->address, pdpy->addrlen )) - { - return pdpy; - } - } - return (struct protoDisplay *)0; -} - -static void -TimeoutProtoDisplays (void) -{ - struct protoDisplay *pdpy, *next; - - for (pdpy = protoDisplays; pdpy; pdpy = next) { - next = pdpy->next; - if (pdpy->date < (unsigned long)(now - PROTO_TIMEOUT)) - DisposeProtoDisplay( pdpy ); - } -} - -struct protoDisplay * -NewProtoDisplay( XdmcpNetaddr address, int addrlen, CARD16 displayNumber, - CARD16 connectionType, ARRAY8Ptr connectionAddress, - CARD32 sessionID ) -{ - struct protoDisplay *pdpy; - - Debug( "NewProtoDisplay\n" ); - TimeoutProtoDisplays (); - pdpy = (struct protoDisplay *)Malloc( sizeof(*pdpy) ); - if (!pdpy) - return NULL; - pdpy->address = (XdmcpNetaddr)Malloc( addrlen ); - if (!pdpy->address) { - free( (char *)pdpy ); - return NULL; - } - pdpy->addrlen = addrlen; - memmove( pdpy->address, address, addrlen ); - pdpy->displayNumber = displayNumber; - pdpy->connectionType = connectionType; - pdpy->date = now; - if (!XdmcpCopyARRAY8( connectionAddress, &pdpy->connectionAddress )) { - free( (char *)pdpy->address ); - free( (char *)pdpy ); - return NULL; - } - pdpy->sessionID = sessionID; - pdpy->fileAuthorization = (Xauth *)NULL; - pdpy->xdmcpAuthorization = (Xauth *)NULL; - pdpy->next = protoDisplays; - protoDisplays = pdpy; - return pdpy; -} - -void -DisposeProtoDisplay( pdpy ) - struct protoDisplay *pdpy; -{ - struct protoDisplay *p, *prev; - - prev = 0; - for (p = protoDisplays; p; p=p->next) { - if (p == pdpy) - break; - prev = p; - } - if (!p) - return; - if (prev) - prev->next = pdpy->next; - else - protoDisplays = pdpy->next; - bzero( &pdpy->key, sizeof(pdpy->key) ); - if (pdpy->fileAuthorization) - XauDisposeAuth( pdpy->fileAuthorization ); - if (pdpy->xdmcpAuthorization) - XauDisposeAuth( pdpy->xdmcpAuthorization ); - XdmcpDisposeARRAY8( &pdpy->connectionAddress ); - free( (char *)pdpy->address ); - free( (char *)pdpy ); -} - -#endif /* XDMCP */ diff --git a/kdm/backend/reset.c b/kdm/backend/reset.c deleted file mode 100644 index 2c2100870..000000000 --- a/kdm/backend/reset.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * pseudoReset -- pretend to reset the server by killing all clients - * with windows. It will reset the server most of the time, unless - * a client remains connected with no windows. - */ - -#include "dm.h" -#include "dm_error.h" - -#include - -#include - -/*ARGSUSED*/ -static int -ignoreErrors( Display *dspl ATTR_UNUSED, XErrorEvent *event ATTR_UNUSED ) -{ - Debug( "ignoring error\n" ); - return 0; -} - -/* - * this is mostly bogus -- but quite useful. I wish the protocol - * had some way of enumerating and identifying clients, that way - * this code wouldn't have to be this kludgy. - */ - -static void -killWindows( Window window ) -{ - Window root, parent, *children; - unsigned int child, nchildren = 0; - - while (XQueryTree( dpy, window, &root, &parent, &children, &nchildren ) - && nchildren > 0) - { - for (child = 0; child < nchildren; child++) { - Debug( "XKillClient %p\n", children[child] ); - XKillClient( dpy, children[child] ); - } - XFree( (char *)children ); - } -} - -static Jmp_buf resetJmp; - -/* ARGSUSED */ -static void -abortReset( int n ATTR_UNUSED ) -{ - Longjmp( resetJmp, 1 ); -} - -/* - * this display connection better not have any windows... - */ - -void -pseudoReset() -{ - int screen; - - if (Setjmp( resetJmp )) { - LogError( "pseudoReset timeout\n" ); - } else { - (void)Signal( SIGALRM, abortReset ); - (void)alarm( 30 ); - XSetErrorHandler( ignoreErrors ); - for (screen = 0; screen < ScreenCount (dpy); screen++) { - Debug( "pseudoReset screen %d\n", screen ); - killWindows( RootWindow( dpy, screen ) ); - } - Debug( "before XSync\n" ); - XSync( dpy, False ); - (void)alarm( 0 ); - } - Signal( SIGALRM, SIG_DFL ); - XSetErrorHandler( (XErrorHandler)0 ); - Debug( "pseudoReset done\n" ); -} diff --git a/kdm/backend/resource.c b/kdm/backend/resource.c deleted file mode 100644 index f17db78ec..000000000 --- a/kdm/backend/resource.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2005 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * obtain configuration data - */ - -#include "dm.h" -#include "dm_error.h" - -#include - - -static char **originalArgv; - -static GProc getter; -GTalk cnftalk; - -static void -OpenGetter() -{ - GSet( &cnftalk ); - if (!getter.pid) { - if (GOpen( &getter, - originalArgv, "_config", 0, strdup( "config reader" ), - 0 )) - LogPanic( "Cannot run config reader\n" ); - Debug( "getter now ready\n" ); - } -} - -void -CloseGetter() -{ - if (getter.pid) { - GSet( &cnftalk ); - (void)GClose (&getter, 0, 0); - Debug( "getter now closed\n" ); - } -} - -/* - * ref-counted, unique-instance strings - */ -static RcStr *strs; - -/* - * make a ref-counted string of the argument. the new string will - * have a ref-count of 1. the passed string pointer is no longer valid. - */ -RcStr * -newStr( char *str ) -{ - RcStr *cs; - - for (cs = strs; cs; cs = cs->next) - if (!strcmp( str, cs->str )) { - free( str ); - cs->cnt++; - return cs; - } - if (!(cs = Malloc( sizeof(*cs) ))) - return 0; - cs->cnt = 1; - cs->str = str; - cs->next = strs; - strs = cs; - return cs; -} - -/* - * decrement ref-count and delete string when count drops to 0. - */ -void -delStr( RcStr *str ) -{ - RcStr **cs; - - if (!str || --str->cnt) - return; - for (cs = &strs; *cs; cs = &((*cs)->next)) - if (str == *cs) { - *cs = (*cs)->next; - free( (*cs)->str ); - free( *cs ); - break; - } -} - - -typedef struct CfgFile { - RcStr *name; - int depidx; - long deptime; -} CfgFile; - -static int numCfgFiles; -static CfgFile *cfgFiles; - -static int cfgMapT[] = { - GC_gGlobal, - GC_gDisplay, -#ifdef XDMCP - GC_gXaccess, -#endif -}; -static int cfgMap[as(cfgMapT)]; - -static int -GetDeps() -{ - int ncf, i, dep, ret; - CfgFile *cf; - - OpenGetter(); - GSendInt( GC_Files ); - ncf = GRecvInt(); - if (!(cf = Malloc( ncf * sizeof(*cf) ))) { - CloseGetter(); - return 0; - } - for (i = 0; i < ncf; i++) { - cf[i].name = newStr( GRecvStr() ); - if ((dep = cf[i].depidx = GRecvInt()) != -1) - cf[i].deptime = mTime( cf[dep].name->str ); - } - if (cfgFiles) { - for (i = 0; i < numCfgFiles; i++) - delStr( cfgFiles[i].name ); - free( cfgFiles ); - } - ret = 1; - cfgFiles = cf; - numCfgFiles = ncf; - for (i = 0; i < as(cfgMapT); i++) { - GSendInt( cfgMapT[i] ); - if ((cfgMap[i] = GRecvInt()) < 0) { - LogError( "Config reader does not support config cathegory %#x\n", - cfgMapT[i] ); - ret = 0; - } - } - GSendInt( -1 ); - return ret; -} - -static int -checkDep( int idx ) -{ - int dep; - - if ((dep = cfgFiles[idx].depidx) == -1) - return 0; - if (checkDep( dep )) - return 1; - return mTime( cfgFiles[dep].name->str ) != cfgFiles[idx].deptime; -} - -static int -needsReScan( int what, CfgDep *dep ) -{ - int widx, idx; - long mt; - - for (widx = 0; cfgMapT[widx] != what; widx++); - idx = cfgMap[widx]; - if (checkDep( idx )) { - if (!GetDeps()) - return -1; - idx = cfgMap[widx]; - } - mt = mTime( cfgFiles[idx].name->str ); - if (dep->name != cfgFiles[idx].name) { - if (dep->name) - delStr( dep->name ); - dep->name = cfgFiles[idx].name; - dep->name->cnt++; - dep->time = mt; - return 1; - } else if (dep->time != mt) { - dep->time = mt; - return 1; - } else - return 0; -} - -int -startConfig( int what, CfgDep *dep, int force ) -{ - int ret; - - if ((ret = needsReScan( what, dep )) < 0 || (!ret && !force)) - return ret; - OpenGetter(); - GSendInt( GC_GetConf ); - GSendInt( what ); - GSendStr( dep->name->str ); - return 1; -} - -static void -LoadResources( CfgArr *conf ) -{ - char **vptr, **pptr, *cptr; - long *iptr, i, id, nu, j, nptr, nint, nchr; - - if (conf->data) - free( conf->data ); - conf->numCfgEnt = GRecvInt(); - nptr = GRecvInt(); - nint = GRecvInt(); - nchr = GRecvInt(); - if (!(conf->data = Malloc( conf->numCfgEnt * - (sizeof(long) + - sizeof(char *)) + - nptr * sizeof(char *) + - nint * sizeof(long) + - nchr ))) - { - CloseGetter(); - return; - } - vptr = (char **)conf->data; - pptr = vptr + conf->numCfgEnt; - conf->idx = (long *)(pptr + nptr); - iptr = conf->idx + conf->numCfgEnt; - cptr = (char *)(iptr + nint); - for (i = 0; i < conf->numCfgEnt; i++) { - id = GRecvInt(); - conf->idx[i] = id; - switch (id & C_TYPE_MASK) { - case C_TYPE_INT: - vptr[i] = (char *)((unsigned long)GRecvInt()); - break; - case C_TYPE_STR: - vptr[i] = cptr; - cptr += GRecvStrBuf( cptr ); - break; - case C_TYPE_ARGV: - nu = GRecvInt(); - vptr[i] = (char *)pptr; - for (j = 0; j < nu; j++) { - *pptr++ = cptr; - cptr += GRecvStrBuf( cptr ); - } - *pptr++ = (char *)0; - break; - default: - LogError( "Config reader supplied unknown data type in id %#x\n", - id ); - break; - } - } -} - -static void -ApplyResource( int id, char **src, char **dst ) -{ - switch (id & C_TYPE_MASK) { - case C_TYPE_INT: - *(int *)dst = *(long *)src; - break; - case C_TYPE_STR: - case C_TYPE_ARGV: - *dst = *src; - break; - } -} - - -#define boffset(f) XtOffsetOf(struct display, f) - -/* no global variables exported currently -struct globEnts { - int id; - char **off; -} globEnt[] = { -}; - */ - -/* no per-display variables exported currently -struct dpyEnts { - int id; - int off; -} dpyEnt[] = { -}; - */ - -CfgArr cfg; - -char ** -FindCfgEnt( struct display *d, int id ) -{ - int i; - -/* no global variables exported currently - for (i = 0; i < as(globEnt); i++) - if (globEnt[i].id == id) - return globEnt[i].off; - */ - for (i = 0; i < cfg.numCfgEnt; i++) - if (cfg.idx[i] == id) - return ((char **)cfg.data) + i; - if (d) { -/* no per-display variables exported currently - for (i = 0; i < as(dpyEnt); i++) - if (dpyEnt[i].id == id) - return (char **)(((char *)d) + dpyEnt[i].off); - */ - for (i = 0; i < d->cfg.numCfgEnt; i++) - if (d->cfg.idx[i] == id) - return ((char **)d->cfg.data) + i; - } - Debug( "unknown config entry %#x requested\n", id ); - return (char **)0; -} - - -CONF_CORE_GLOBAL_DEFS - -struct globVals { - int id; - char **off; -} globVal[] = { -CONF_CORE_GLOBALS -}; - -int -LoadDMResources( int force ) -{ - int i, ret; - char **ent; - - if (Setjmp( cnftalk.errjmp )) - return -1; /* may memleak, but we probably have to abort anyway */ - if ((ret = startConfig( GC_gGlobal, &cfg.dep, force )) <= 0) - return ret; - LoadResources( &cfg ); -/* Debug( "manager resources: %[*x\n", - cfg.numCfgEnt, ((char **)cfg.data) + cfg.numCfgEnt );*/ - ret = 1; - for (i = 0; i < as(globVal); i++) { - if (!(ent = FindCfgEnt( 0, globVal[i].id ))) - ret = -1; - else - ApplyResource( globVal[i].id, ent, globVal[i].off ); - } - if (ret < 0) - LogError( "Internal error: config reader supplied incomplete data\n" ); - return ret; -} - - -struct dpyVals { - int id; - int off; -} dpyVal[] = { -CONF_CORE_LOCALS -}; - -int -LoadDisplayResources( struct display *d ) -{ - int i, ret; - char **ent; - - if (Setjmp( cnftalk.errjmp )) - return -1; /* may memleak */ - if ((ret = startConfig( GC_gDisplay, &d->cfg.dep, FALSE )) <= 0) - return ret; - GSendStr( d->name ); - GSendStr( d->class2 ); - LoadResources( &d->cfg ); -/* Debug( "display(%s, %s) resources: %[*x\n", d->name, d->class2, - d->cfg.numCfgEnt, ((char **)d->cfg.data) + d->cfg.numCfgEnt );*/ - ret = 1; - for (i = 0; i < as(dpyVal); i++) { - if (!(ent = FindCfgEnt( d, dpyVal[i].id ))) - ret = -1; - else - ApplyResource( dpyVal[i].id, ent, - (char **)(((char *)d) + dpyVal[i].off) ); - } - if (ret < 0) - LogError( "Internal error: config reader supplied incomplete data\n" ); - return ret; -} - -int -InitResources( char **argv ) -{ - originalArgv = argv; - cnftalk.pipe = &getter.pipe; - if (Setjmp( cnftalk.errjmp )) - return 0; /* may memleak */ - return GetDeps(); -} - -static void -addServers( char **srv, int bType ) -{ - char *name, *class2; - const char *dtx, *cls; - struct display *d; - - for (; *srv; srv++) { - if ((cls = strchr( *srv, '_' ))) { - if (!StrNDup( &name, *srv, cls - *srv )) - return; - if (!StrDup( &class2, cls )) { - free( name ); - return; - } - } else { - if (!StrDup( &name, *srv )) - return; - class2 = 0; - } - if ((d = FindDisplayByName( name ))) { - if (d->class2) - free( d->class2 ); - dtx = "existing"; - } else { - if (!(d = NewDisplay( name ))) { - free( name ); - if (class2) - free( class2 ); - return; - } - dtx = "new"; - } - d->stillThere = 1; - d->class2 = class2; - d->displayType = (*name == ':' ? dLocal : dForeign) | bType; - if ((bType & d_lifetime) == dReserve) { - if (d->status == notRunning) - d->status = reserve; - } else { - if (d->status == reserve) - d->status = notRunning; - } - Debug( "found %s %s%s display: %s %s\n", dtx, - ((d->displayType & d_location) == dLocal) ? "local" : "foreign", - ((d->displayType & d_lifetime) == dReserve) ? " reserve" : "", - d->name, d->class2 ); - free( name ); - } -} - -void -ScanServers( void ) -{ - Debug( "ScanServers\n" ); - addServers( staticServers, dFromFile | dPermanent ); - addServers( reserveServers, dFromFile | dReserve ); -} - diff --git a/kdm/backend/rpcauth.c b/kdm/backend/rpcauth.c deleted file mode 100644 index 1186f72c2..000000000 --- a/kdm/backend/rpcauth.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * generate SecureRPC authorization records - */ - -#include - -#ifdef SECURE_RPC - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include -#include - -/*ARGSUSED*/ -void -SecureRPCInitAuth( unsigned short name_len ATTR_UNUSED, - const char *name ATTR_UNUSED ) -{ -} - -Xauth * -SecureRPCGetAuth( unsigned short namelen, const char *name ) -{ - Xauth *new; - char key[MAXNETNAMELEN+1]; - - new = (Xauth *)Malloc( sizeof(*new) ); - if (!new) - return (Xauth *)0; - new->family = FamilyWild; - new->address_length = 0; - new->address = 0; - new->number_length = 0; - new->number = 0; - - getnetname( key ); - Debug( "system netname %s\n", key ); - new->data_length = strlen( key ); - new->data = (char *)Malloc( new->data_length ); - if (!new->data) { - free( (char *)new ); - return (Xauth *)0; - } - new->name = (char *)Malloc( namelen ); - if (!new->name) { - free( (char *)new->data ); - free( (char *)new ); - return (Xauth *)0; - } - memmove( new->name, name, namelen ); - new->name_length = namelen; - memmove( new->data, key, new->data_length ); - return new; -} - -#endif diff --git a/kdm/backend/server.c b/kdm/backend/server.c deleted file mode 100644 index e78d8a66c..000000000 --- a/kdm/backend/server.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2001,2003,2005 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * server.c - manage the X server - */ - -#include "dm.h" -#include "dm_error.h" -#include "dm_socket.h" - -#include - -#include -#include -#include - - -struct display *startingServer; -time_t serverTimeout = TO_INF; - -char ** -PrepServerArgv( struct display *d, const char *args ) -{ - char **argv; -#ifdef HAVE_VTS - char vtstr[8]; -#endif - - if (!(argv = parseArgs( 0, d->serverCmd )) || - !(argv = parseArgs( argv, args )) || - !(argv = addStrArr( argv, d->name, -1 ))) - exit( 47 ); -#ifdef HAVE_VTS - if (d->serverVT && - !(argv = addStrArr( argv, vtstr, - sprintf( vtstr, "vt%d", d->serverVT ) ))) - exit( 47 ); -#endif - return argv; -} - -static void -StartServerOnce( void ) -{ - struct display *d = startingServer; - char **argv; - int pid; - - Debug( "StartServerOnce for %s, try %d\n", d->name, ++d->startTries ); - d->serverStatus = starting; - switch (pid = Fork()) { - case 0: - argv = PrepServerArgv( d, d->serverArgsLocal ); - if (d->authFile) { - if (!(argv = addStrArr( argv, "-auth", 5 )) || - !(argv = addStrArr( argv, d->authFile, -1 ))) - exit( 47 ); - } - Debug( "exec %\"[s\n", argv ); - /* - * give the server SIGUSR1 ignored, - * it will notice that and send SIGUSR1 - * when ready - */ - (void)Signal( SIGUSR1, SIG_IGN ); - (void)execv( argv[0], argv ); - LogError( "X server %\"s cannot be executed\n", argv[0] ); - - /* Let's try again with some standard paths */ - argv[0] = (char *)realloc(argv[0], strlen("/usr/X11R6/bin/X") + 1); - if (argv[0] != NULL) { - argv[0] = "/usr/X11R6/bin/X"; - Debug( "exec %\"[s\n", argv ); - (void)execv( argv[0], argv ); - LogError( "X server %\"s cannot be executed\n", argv[0] ); - - argv[0] = "/usr/bin/X"; /* Shorter than the previous file name */ - Debug( "exec %\"[s\n", argv ); - (void)execv( argv[0], argv ); - LogError( "X server %\"s cannot be executed\n", argv[0] ); - } - - exit( 47 ); - case -1: - LogError( "X server fork failed\n" ); - StartServerFailed(); - break; - default: - Debug( "X server forked, pid %d\n", pid ); - d->serverPid = pid; - serverTimeout = d->serverTimeout + now; - break; - } -} - -void -StartServer( struct display *d ) -{ - startingServer = d; - d->startTries = 0; - StartServerOnce(); -} - -void -AbortStartServer( struct display *d ) -{ - if (startingServer == d) - { - if (d->serverStatus != ignore) - { - d->serverStatus = ignore; - serverTimeout = TO_INF; - Debug( "aborting X server start\n" ); - } - startingServer = 0; - } -} - -void -StartServerSuccess() -{ - struct display *d = startingServer; - d->serverStatus = ignore; - serverTimeout = TO_INF; - Debug( "X server ready, starting session\n" ); - StartDisplayP2( d ); -} - -void -StartServerFailed() -{ - struct display *d = startingServer; - if (!d->serverAttempts || d->startTries < d->serverAttempts) { - d->serverStatus = pausing; - serverTimeout = d->openDelay + now; - } else { - d->serverStatus = ignore; - serverTimeout = TO_INF; - startingServer = 0; - LogError( "X server for display %s can't be started," - " session disabled\n", d->name ); - StopDisplay( d ); - } -} - -void -StartServerTimeout() -{ - struct display *d = startingServer; - switch (d->serverStatus) { - case ignore: - case awaiting: - break; /* cannot happen */ - case starting: - LogError( "X server startup timeout, terminating\n" ); - kill( d->serverPid, d->termSignal ); - d->serverStatus = d->termSignal == SIGKILL ? killed : terminated; - serverTimeout = d->serverTimeout + now; - break; - case terminated: - LogInfo( "X server termination timeout, killing\n" ); - kill( d->serverPid, SIGKILL ); - d->serverStatus = killed; - serverTimeout = 10 + now; - break; - case killed: - LogInfo( "X server is stuck in D state; leaving it alone\n" ); - StartServerFailed(); - break; - case pausing: - StartServerOnce(); - break; - } -} - - -Display *dpy; - -/* - * this code is complicated by some TCP failings. On - * many systems, the connect will occasionally hang forever, - * this trouble is avoided by setting up a timeout to Longjmp - * out of the connect (possibly leaving piles of garbage around - * inside Xlib) and give up, terminating the server. - */ - -static Jmp_buf openAbort; - -/* ARGSUSED */ -static void -abortOpen( int n ATTR_UNUSED ) -{ - Longjmp( openAbort, 1 ); -} - -#ifdef XDMCP - -#ifdef STREAMSCONN -# include -#endif - -static void -GetRemoteAddress( struct display *d, int fd ) -{ - char buf[512]; - int len = sizeof(buf); -#ifdef STREAMSCONN - struct netbuf netb; -#endif - - XdmcpDisposeARRAY8( &d->peer ); -#ifdef STREAMSCONN - netb.maxlen = sizeof(buf); - netb.buf = buf; - t_getname( fd, &netb, REMOTENAME ); - len = 8; - /* lucky for us, t_getname returns something that looks like a sockaddr */ -#else - getpeername( fd, (struct sockaddr *)buf, (void *)&len ); -#endif - if (len && XdmcpAllocARRAY8( &d->peer, len )) - memmove( (char *)d->peer.data, buf, len ); - Debug( "got remote address %s %d\n", d->name, d->peer.length ); -} - -#endif /* XDMCP */ - -static int -openErrorHandler( Display *dspl ATTR_UNUSED ) -{ - LogError( "IO Error in XOpenDisplay\n" ); - exit( EX_OPENFAILED_DPY ); - /*NOTREACHED*/ - return (0); -} - -void -WaitForServer( struct display *d ) -{ - volatile int i; - /* static int i; */ - - i = 0; - do { - (void)Signal( SIGALRM, abortOpen ); - (void)alarm( (unsigned)d->openTimeout ); - if (!Setjmp( openAbort )) { - Debug( "before XOpenDisplay(%s)\n", d->name ); - errno = 0; - (void)XSetIOErrorHandler( openErrorHandler ); - dpy = XOpenDisplay( d->name ); -#ifdef STREAMSCONN - { - /* For some reason, the next XOpenDisplay we do is - going to fail, so we might as well get that out - of the way. There is something broken here. */ - Display *bogusDpy = XOpenDisplay( d->name ); - Debug( "bogus XOpenDisplay %s\n", - bogusDpy ? "succeeded" : "failed" ); - if (bogusDpy) XCloseDisplay( bogusDpy ); /* just in case */ - } -#endif - (void)alarm( (unsigned)0 ); - (void)Signal( SIGALRM, SIG_DFL ); - (void)XSetIOErrorHandler( (int (*)( Display * )) 0 ); - Debug( "after XOpenDisplay(%s)\n", d->name ); - if (dpy) { -#ifdef XDMCP - if ((d->displayType & d_location) == dForeign) - GetRemoteAddress( d, ConnectionNumber( dpy ) ); -#endif - RegisterCloseOnFork( ConnectionNumber( dpy ) ); - return; - } - Debug( "OpenDisplay(%s) attempt %d failed: %m\n", d->name, i + 1 ); - sleep( (unsigned)d->openDelay ); - } else { - LogError( "Hung in XOpenDisplay(%s), aborting\n", d->name ); - (void)Signal( SIGALRM, SIG_DFL ); - break; - } - } while (++i < d->openRepeat); - LogError( "Cannot connect to %s, giving up\n", d->name ); - exit( EX_OPENFAILED_DPY ); -} - - -void -ResetServer( struct display *d ) -{ - if (dpy && (d->displayType & d_origin) != dFromXDMCP) - pseudoReset(); -} - - -static Jmp_buf pingTime; - -static void -PingLost( void ) -{ - Longjmp( pingTime, 1 ); -} - -/* ARGSUSED */ -static int -PingLostIOErr( Display *dspl ATTR_UNUSED ) -{ - PingLost(); - return 0; -} - -/* ARGSUSED */ -static void -PingLostSig( int n ATTR_UNUSED ) -{ - PingLost(); -} - -int -PingServer( struct display *d ) -{ - int (*oldError)( Display * ); - void (*oldSig)( int ); - int oldAlarm; - - oldError = XSetIOErrorHandler( PingLostIOErr ); - oldAlarm = alarm( 0 ); - oldSig = Signal( SIGALRM, PingLostSig ); - (void)alarm( d->pingTimeout * 60 ); - if (!Setjmp( pingTime )) { - Debug( "ping X server\n" ); - XSync( dpy, 0 ); - } else { - Debug( "X server dead\n" ); - (void)alarm( 0 ); - (void)Signal( SIGALRM, SIG_DFL ); - XSetIOErrorHandler( oldError ); - return 0; - } - (void)alarm( 0 ); - (void)Signal( SIGALRM, oldSig ); - (void)alarm( oldAlarm ); - Debug( "X server alive\n" ); - XSetIOErrorHandler( oldError ); - return 1; -} diff --git a/kdm/backend/session.c b/kdm/backend/session.c deleted file mode 100644 index 9a12ce312..000000000 --- a/kdm/backend/session.c +++ /dev/null @@ -1,813 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2004 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * subdaemon event loop, etc. - */ - -#include "dm.h" -#include "dm_error.h" - -#include -#include -#include - -#include -#include -#include - -#ifdef WITH_CONSOLE_KIT -#include "consolekit.h" -#endif - -struct display *td; -const char *td_setup = "auto"; - -static void DeleteXloginResources( void ); -static void LoadXloginResources( void ); -static void SetupDisplay( const char *arg ); - - -static Jmp_buf pingTime; - -/* ARGSUSED */ -static void -catchAlrm( int n ATTR_UNUSED ) -{ - Longjmp( pingTime, 1 ); -} - -static Jmp_buf tenaciousClient; - -/* ARGSUSED */ -static void -waitAbort( int n ATTR_UNUSED ) -{ - Longjmp( tenaciousClient, 1 ); -} - -static void -AbortClient( int pid ) -{ - int sig = SIGTERM; - volatile int i; - int retId; - - for (i = 0; i < 4; i++) { - if (kill( -pid, sig ) == -1) { - switch (errno) { - case EPERM: - LogError( "Can't kill client\n" ); - case EINVAL: - case ESRCH: - return; - } - } - if (!Setjmp( tenaciousClient )) { - (void)Signal( SIGALRM, waitAbort ); - (void)alarm( (unsigned)10 ); - retId = wait( (waitType *)0 ); - (void)alarm( (unsigned)0 ); - (void)Signal( SIGALRM, SIG_DFL ); - if (retId == pid) - break; - } else - (void)Signal( SIGALRM, SIG_DFL ); - sig = SIGKILL; - } -} - - -static char * -conv_auto( int what, const char *prompt ATTR_UNUSED ) -{ - switch (what) { - case GCONV_USER: - return curuser; - case GCONV_PASS: - case GCONV_PASS_ND: - return curpass; - default: - LogError( "Unknown authentication data type requested for autologin.\n" ); - return 0; - } -} - -static void -DoAutoLogon( void ) -{ - ReStr( &curuser, td->autoUser ); - ReStr( &curpass, td->autoPass ); - ReStr( &curtype, "classic" ); - cursource = PWSRC_AUTOLOGIN; -} - -static int -AutoLogon( Time_t tdiff ) -{ - Debug( "autoLogon, tdiff = %d, rLogin = %d, goodexit = %d, nuser = %s\n", - tdiff, td->hstent->rLogin, td->hstent->goodExit, td->hstent->nuser ); - if (td->hstent->rLogin == 2 || - (td->hstent->rLogin == 1 && - tdiff <= 0 && !td->hstent->goodExit && !td->hstent->lock)) - { - curuser = td->hstent->nuser; - td->hstent->nuser = 0; - curpass = td->hstent->npass; - td->hstent->npass = 0; - newdmrc = td->hstent->nargs; - td->hstent->nargs = 0; - ReStr( &curtype, "classic" ); - cursource = (td->hstent->rLogin == 1) ? PWSRC_RELOGIN : PWSRC_MANUAL; - return 1; - } else if (*td->autoUser && !td->autoDelay && - ((tdiff > 0 && ((td->displayType & d_lifetime) == dTransient || - !td->hstent->lastExit)) || - td->autoAgain)) - { - unsigned int lmask; - Window dummy1, dummy2; - int dummy3, dummy4, dummy5, dummy6; - XQueryPointer( dpy, DefaultRootWindow( dpy ), - &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, - &lmask ); - if (lmask & ShiftMask) - return 0; - DoAutoLogon(); - return 1; - } - return 0; -} - - -static const struct { - int vcode, echo, ndelay; -} grqs[] = { - { V_GET_TEXT, TRUE, FALSE }, - { V_GET_TEXT, FALSE, FALSE }, - { V_GET_TEXT, TRUE, FALSE }, - { V_GET_TEXT, FALSE, FALSE }, - { V_GET_TEXT, FALSE, TRUE }, - { V_GET_BINARY, 0, 0 } -}; - -char * -conv_interact( int what, const char *prompt ) -{ - char *ret; - int tag; - - GSendInt( grqs[what].vcode ); - if (what == GCONV_BINARY) { - unsigned const char *up = (unsigned const char *)prompt; - int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24); - GSendArr( len, prompt ); - GSendInt( FALSE ); /* ndelay */ - return GRecvArr( &len ); - } else { - GSendStr( prompt ); - GSendInt( grqs[what].echo ); - GSendInt( grqs[what].ndelay ); - ret = GRecvStr(); - if (ret) { - tag = GRecvInt(); - switch (what) { - case GCONV_USER: - /* assert(tag & V_IS_USER); */ - if (curuser) - free( curuser ); - curuser = ret; - break; - case GCONV_PASS: - case GCONV_PASS_ND: - /* assert(tag & V_IS_PASSWORD); */ - if (curpass) - free( curpass ); - curpass = ret; - break; - default: - if (tag & V_IS_USER) - ReStr( &curuser, ret ); - else if (tag & V_IS_PASSWORD) - ReStr( &curpass, ret ); - else if (tag & V_IS_NEWPASSWORD) - ReStr( &newpass, ret ); - else if (tag & V_IS_OLDPASSWORD) - ReStr( &ret, curpass ); - } - } - return ret; - } -} - -static int greeter; -GProc grtproc; -GTalk grttalk; - -GTalk mstrtalk; /* make static; see dm.c */ - -int -CtrlGreeterWait( int wreply ) -{ - int i, cmd, type, rootok; - char *name, *pass, **avptr; -#ifdef XDMCP - ARRAY8Ptr aptr; -#endif - - if (Setjmp( mstrtalk.errjmp )) { - CloseGreeter( TRUE ); - SessionExit( EX_UNMANAGE_DPY ); - } - - while (GRecvCmd( &cmd )) { - switch (cmd) - { - case G_Ready: - Debug( "G_Ready\n" ); - return 0; - case G_GetCfg: - /*Debug ("G_GetCfg\n");*/ - type = GRecvInt(); - /*Debug (" index %#x\n", type);*/ - if (type == C_isLocal) - i = (td->displayType & d_location) == dLocal; - else if (type == C_hasConsole) -#ifdef HAVE_VTS - i = *consoleTTYs != 0; -#else - i = td->console != 0; -#endif - else if (type == C_isAuthorized) - i = td->authorizations != 0; - else - goto normal; - GSendInt( GE_Ok ); - /*Debug (" -> bool %d\n", i);*/ - GSendInt( i ); - break; - normal: - if (!(avptr = FindCfgEnt( td, type ))) { - /*Debug (" -> not found\n");*/ - GSendInt( GE_NoEnt ); - break; - } - switch (type & C_TYPE_MASK) { - default: - /*Debug (" -> unknown type\n");*/ - GSendInt( GE_BadType ); - break; - case C_TYPE_INT: - case C_TYPE_STR: - case C_TYPE_ARGV: -#ifdef XDMCP - case C_TYPE_ARR: -#endif - GSendInt( GE_Ok ); - switch (type & C_TYPE_MASK) { - case C_TYPE_INT: - /*Debug (" -> int %#x (%d)\n", *(int *)avptr, *(int *)avptr);*/ - GSendInt( *(long *)avptr ); - break; - case C_TYPE_STR: - /*Debug (" -> string %\"s\n", *avptr);*/ - GSendStr( *avptr ); - break; - case C_TYPE_ARGV: - /*Debug (" -> sending argv %\"[{s\n", *(char ***)avptr);*/ - GSendArgv( *(char ***)avptr ); - break; -#ifdef XDMCP - case C_TYPE_ARR: - aptr = *(ARRAY8Ptr *)avptr; - /*Debug (" -> sending array %02[*:hhx\n", - aptr->length, aptr->data);*/ - GSendArr( aptr->length, (char *)aptr->data ); - break; -#endif - } - break; - } - break; - case G_ReadDmrc: - Debug( "G_ReadDmrc\n" ); - name = GRecvStr(); - Debug( " user %\"s\n", name ); - if (StrCmp( dmrcuser, name )) { - if (curdmrc) { free( curdmrc ); curdmrc = 0; } - if (dmrcuser) - free( dmrcuser ); - dmrcuser = name; - i = ReadDmrc(); - Debug( " -> status %d\n", i ); - GSendInt( i ); - Debug( " => %\"s\n", curdmrc ); - } else { - if (name) - free( name ); - Debug( " -> status " stringify( GE_Ok ) "\n" ); - GSendInt( GE_Ok ); - Debug( " => keeping old\n" ); - } - break; - case G_GetDmrc: - Debug( "G_GetDmrc\n" ); - name = GRecvStr(); - Debug( " key %\"s\n", name ); - pass = iniEntry( curdmrc, "Desktop", name, 0 ); - Debug( " -> %\"s\n", pass ); - GSendStr( pass ); - if (pass) - free( pass ); - free( name ); - break; -/* case G_ResetDmrc: - Debug ("G_ResetDmrc\n"); - if (newdmrc) { free (newdmrc); newdmrc = 0; } - break; */ - case G_PutDmrc: - Debug( "G_PutDmrc\n" ); - name = GRecvStr(); - Debug( " key %\"s\n", name ); - pass = GRecvStr(); - Debug( " value %\"s\n", pass ); - newdmrc = iniEntry( newdmrc, "Desktop", name, pass ); - free( pass ); - free( name ); - break; - case G_VerifyRootOK: - Debug( "G_VerifyRootOK\n" ); - rootok = TRUE; - goto doverify; - case G_Verify: - Debug( "G_Verify\n" ); - rootok = FALSE; - doverify: - if (curuser) { free( curuser ); curuser = 0; } - if (curpass) { free( curpass ); curpass = 0; } - if (curtype) free( curtype ); - curtype = GRecvStr(); - Debug( " type %\"s\n", curtype ); - cursource = PWSRC_MANUAL; - if (Verify( conv_interact, rootok )) { - Debug( " -> return success\n" ); - GSendInt( V_OK ); - } else - Debug( " -> failure returned\n" ); - break; - case G_AutoLogin: - Debug( "G_AutoLogin\n" ); - DoAutoLogon(); - if (Verify( conv_auto, FALSE )) { - Debug( " -> return success\n" ); - GSendInt( V_OK ); - } else - Debug( " -> failure returned\n" ); - break; - case G_SetupDpy: - Debug( "G_SetupDpy\n" ); - SetupDisplay( 0 ); - td_setup = 0; - GSendInt( 0 ); - break; - default: - return cmd; - } - if (!wreply) - return -1; - } - Debug( "lost connection to greeter\n" ); - return -2; -} - -void -OpenGreeter() -{ - char *name, **env; - static Time_t lastStart; - int cmd; - Cursor xcursor; - - GSet( &grttalk ); - if (greeter) - return; - if (time( 0 ) < lastStart + 10) /* XXX should use some readiness indicator instead */ - SessionExit( EX_UNMANAGE_DPY ); - greeter = 1; - ASPrintf( &name, "greeter for display %s", td->name ); - Debug( "starting %s\n", name ); - - /* Hourglass cursor */ - if ((xcursor = XCreateFontCursor( dpy, XC_watch ))) { - XDefineCursor( dpy, DefaultRootWindow( dpy ), xcursor ); - XFreeCursor( dpy, xcursor ); - } - XFlush( dpy ); - - /* Load system default Resources (if any) */ - LoadXloginResources(); - - grttalk.pipe = &grtproc.pipe; - env = systemEnv( (char *)0 ); - if (GOpen( &grtproc, (char **)0, "_greet", env, name, &td->gpipe )) - SessionExit( EX_UNMANAGE_DPY ); - freeStrArr( env ); - if ((cmd = CtrlGreeterWait( TRUE ))) { - if (cmd != -2) - LogError( "Received unknown or unexpected command %d from greeter\n", cmd ); - CloseGreeter( TRUE ); - SessionExit( EX_UNMANAGE_DPY ); - } - Debug( "%s ready\n", name ); - time( &lastStart ); -} - -int -CloseGreeter( int force ) -{ - int ret; - - if (!greeter) - return EX_NORMAL; - greeter = 0; - ret = GClose (&grtproc, 0, force); - Debug( "greeter for %s stopped\n", td->name ); - if (WaitCode( ret ) > EX_NORMAL && WaitCode( ret ) <= EX_MAX) { - Debug( "greeter-initiated session exit, code %d\n", WaitCode( ret ) ); - SessionExit( WaitCode( ret ) ); - } - return ret; -} - -void -PrepErrorGreet() -{ - if (!greeter) { - OpenGreeter(); - GSendInt( G_ErrorGreet ); - GSendStr( curuser ); - } -} - -static Jmp_buf idleTOJmp; - -/* ARGSUSED */ -static void -IdleTOJmp( int n ATTR_UNUSED ) -{ - Longjmp( idleTOJmp, 1 ); -} - - -static Jmp_buf abortSession; - -/* ARGSUSED */ -static void -catchTerm( int n ATTR_UNUSED ) -{ - Signal( SIGTERM, SIG_IGN ); - Longjmp( abortSession, EX_AL_RESERVER_DPY ); -} - -/* - * We need our own error handlers because we can't be sure what exit code Xlib - * will use, and our Xlib does exit(1) which matches EX_REMANAGE_DPY, which - * can cause a race condition leaving the display wedged. We need to use - * EX_RESERVER_DPY for IO errors, to ensure that the manager waits for the - * server to terminate. For other X errors, we should give up. - */ - -/*ARGSUSED*/ -static int -IOErrorHandler( Display *dspl ATTR_UNUSED ) -{ - LogError( "Fatal X server IO error: %m\n" ); - /* The only X interaction during the session are pings, and those - have an own IOErrorHandler -> not EX_AL_RESERVER_DPY */ - Longjmp( abortSession, EX_RESERVER_DPY ); - /*NOTREACHED*/ - return 0; -} - -/*ARGSUSED*/ -static int -ErrorHandler( Display *dspl ATTR_UNUSED, XErrorEvent *event ) -{ - LogError( "X error\n" ); - if (event->error_code == BadImplementation) - Longjmp( abortSession, EX_UNMANAGE_DPY ); - return 0; -} - -void -ManageSession( struct display *d ) -{ - int ex, cmd; - volatile int clientPid = 0; - volatile Time_t tdiff = 0; -#ifdef WITH_CONSOLE_KIT - char *ck_session_cookie; -#endif - - - td = d; - Debug( "ManageSession %s\n", d->name ); - if ((ex = Setjmp( abortSession ))) { - CloseGreeter( TRUE ); - if (clientPid) - AbortClient( clientPid ); - SessionExit( ex ); - /* NOTREACHED */ - } - (void)XSetIOErrorHandler( IOErrorHandler ); - (void)XSetErrorHandler( ErrorHandler ); - (void)Signal( SIGTERM, catchTerm ); - - (void)Signal( SIGHUP, SIG_IGN ); - - if (Setjmp( grttalk.errjmp )) - Longjmp( abortSession, EX_RESERVER_DPY ); /* EX_RETRY_ONCE */ - -#ifdef XDMCP - if (d->useChooser) - DoChoose(); - /* NOTREACHED */ -#endif - - if (d->hstent->sdRec.how) { - OpenGreeter(); - GSendInt( G_ConfShutdown ); - GSendInt( d->hstent->sdRec.how ); - GSendInt( d->hstent->sdRec.uid ); - GSendStr( d->hstent->sdRec.osname ); - if ((cmd = CtrlGreeterWait( TRUE )) != G_Ready) { - LogError( "Received unknown command %d from greeter\n", cmd ); - CloseGreeter( TRUE ); - } - goto regreet; - } - - tdiff = time( 0 ) - td->hstent->lastExit - td->openDelay; - if (AutoLogon( tdiff )) { - if (!Verify( conv_auto, FALSE )) - goto gcont; - if (greeter) - GSendInt( V_OK ); - } else { - regreet: - OpenGreeter(); - if (Setjmp( idleTOJmp )) { - CloseGreeter( TRUE ); - SessionExit( EX_NORMAL ); - } - Signal( SIGALRM, IdleTOJmp ); - alarm( td->idleTimeout ); -#ifdef XDMCP - if (((d->displayType & d_location) == dLocal) && - d->loginMode >= LOGIN_DEFAULT_REMOTE) - goto choose; -#endif - for (;;) { - Debug( "ManageSession, greeting, tdiff = %d\n", tdiff ); - GSendInt( (*td->autoUser && td->autoDelay && - (tdiff > 0 || td->autoAgain)) ? - G_GreetTimed : G_Greet ); - gcont: - cmd = CtrlGreeterWait( TRUE ); -#ifdef XDMCP - recmd: - if (cmd == G_DChoose) { - choose: - cmd = DoChoose(); - goto recmd; - } - if (cmd == G_DGreet) - continue; -#endif - alarm( 0 ); - if (cmd == G_Ready) - break; - if (cmd == -2) - CloseGreeter( FALSE ); - else { - LogError( "Received unknown command %d from greeter\n", cmd ); - CloseGreeter( TRUE ); - } - goto regreet; - } - } - - if (CloseGreeter( FALSE ) != EX_NORMAL) - goto regreet; - - DeleteXloginResources(); - - if (td_setup) - SetupDisplay( td_setup ); - -#ifdef WITH_CONSOLE_KIT - ck_session_cookie = open_ck_session (getpwnam(curuser), d); - if (!(clientPid = StartClient(ck_session_cookie))) { -#else - if (!(clientPid = StartClient())) { -#endif - LogError( "Client start failed\n" ); - SessionExit( EX_NORMAL ); /* XXX maybe EX_REMANAGE_DPY? -- enable in dm.c! */ - } - Debug( "client Started\n" ); - - /* - * Wait for session to end, - */ - for (;;) { - if (!Setjmp( pingTime )) { - (void)Signal( SIGALRM, catchAlrm ); - (void)alarm( d->pingInterval * 60 ); /* may be 0 */ - (void)Wait4( clientPid ); - (void)alarm( 0 ); - break; - } else { - (void)alarm( 0 ); - if (!PingServer( d )) - catchTerm( SIGTERM ); - } - } - -#ifdef WITH_CONSOLE_KIT - if (ck_session_cookie != NULL) { - close_ck_session (ck_session_cookie); - free (ck_session_cookie); - } -#endif - - /* - * Sometimes the Xsession somehow manages to exit before - * a server crash is noticed - so we sleep a bit and wait - * for being killed. - */ - if (!PingServer( d )) { - Debug( "X server dead upon session exit.\n" ); - if ((d->displayType & d_location) == dLocal) - sleep( 10 ); - SessionExit( EX_AL_RESERVER_DPY ); - } - SessionExit( EX_NORMAL ); /* XXX maybe EX_REMANAGE_DPY? -- enable in dm.c! */ -} - -static int xResLoaded; - -void -LoadXloginResources() -{ - char **args; - char **env; - - if (!xResLoaded && td->resources[0] && access( td->resources, 4 ) == 0) { - env = systemEnv( (char *)0 ); - if ((args = parseArgs( (char **)0, td->xrdb )) && - (args = addStrArr( args, td->resources, -1 ))) - { - Debug( "loading resource file: %s\n", td->resources ); - (void)runAndWait( args, env ); - freeStrArr( args ); - } - freeStrArr( env ); - xResLoaded = TRUE; - } -} - -void -SetupDisplay( const char *arg ) -{ - char **env; - - env = systemEnv( (char *)0 ); - (void)source( env, td->setup, arg ); - freeStrArr( env ); -} - -void -DeleteXloginResources() -{ - int i; - Atom prop; - - if (!xResLoaded) - return; - xResLoaded = FALSE; - prop = XInternAtom( dpy, "SCREEN_RESOURCES", True ); - XDeleteProperty( dpy, RootWindow( dpy, 0 ), XA_RESOURCE_MANAGER ); - if (prop) - for (i = ScreenCount(dpy); --i >= 0; ) - XDeleteProperty( dpy, RootWindow( dpy, i ), prop ); - XSync( dpy, 0 ); -} - - -int -source( char **env, const char *file, const char *arg ) -{ - char **args; - int ret; - - if (file && file[0]) { - Debug( "source %s\n", file ); - if (!(args = parseArgs( (char **)0, file ))) - return waitCompose( 0,0,3 ); - if (arg && !(args = addStrArr( args, arg, -1 ))) - return waitCompose( 0,0,3 ); - ret = runAndWait( args, env ); - freeStrArr( args ); - return ret; - } - return 0; -} - -char ** -inheritEnv( char **env, const char **what ) -{ - char *value; - - for (; *what; ++what) - if ((value = getenv( *what ))) - env = setEnv( env, *what, value ); - return env; -} - -char ** -baseEnv( const char *user ) -{ - char **env; - - env = 0; - -#ifdef _AIX - /* we need the tags SYSENVIRON: and USRENVIRON: in the call to setpenv() */ - env = setEnv( env, "SYSENVIRON:", 0 ); -#endif - - if (user) { - env = setEnv( env, "USER", user ); -#ifdef _AIX - env = setEnv( env, "LOGIN", user ); -#endif - env = setEnv( env, "LOGNAME", user ); - } - -#ifdef _AIX - env = setEnv( env, "USRENVIRON:", 0 ); -#endif - - env = inheritEnv( env, (const char **)exportList ); - - env = setEnv( env, "DISPLAY", - memcmp( td->name, "localhost:", 10 ) ? - td->name : td->name + 9 ); - - if (td->ctrl.path) - env = setEnv( env, "DM_CONTROL", fifoDir ); - - return env; -} - -char ** -systemEnv( const char *user ) -{ - char **env; - - env = baseEnv( user ); - if (td->authFile) - env = setEnv( env, "XAUTHORITY", td->authFile ); - env = setEnv( env, "PATH", td->systemPath ); - env = setEnv( env, "SHELL", td->systemShell ); - return env; -} diff --git a/kdm/backend/sessreg.c b/kdm/backend/sessreg.c deleted file mode 100644 index b507f8141..000000000 --- a/kdm/backend/sessreg.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - -Copyright 1990, 1998 The Open Group -Copyright 2005 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -*/ - -/* - - Author: Keith Packard, MIT X Consortium - Lastlog support and dynamic utmp entry allocation - by Andreas Stolcke - -*/ - -#define _FILE_OFFSET_BITS 64 -#include "dm.h" -#include "dm_error.h" - -#if defined(__svr4__) || defined(__Lynx__) || defined(__QNX__) || defined(__APPLE__) || defined(_SEQUENT_) /*|| defined(USE_PAM)*/ -# define NO_LASTLOG -#endif - -#ifndef NO_LASTLOG -# ifdef HAVE_LASTLOG_H -# include -# endif -# ifndef LLOG_FILE -# ifdef _PATH_LASTLOGX -# define LLOG_FILE _PATH_LASTLOGX -# elif defined(_PATH_LASTLOG) -# define LLOG_FILE _PATH_LASTLOG -# else -# define LLOG_FILE "/usr/adm/lastlog" -# endif -# endif -#endif - -#if !defined(__svr4__) && !defined(__QNX__) -# define SESSREG_HOST -#endif - -#ifdef BSD -# if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) -/* *BSD doesn't like a ':0' type entry in utmp */ -# define NO_UTMP -# endif -#endif - -#ifdef BSD_UTMP -# ifndef TTYS_FILE -# define TTYS_FILE "/etc/ttys" -# endif -#endif - -#ifdef _AIX -# define UTL_PFX "xdm/" -# define UTL_OFF strlen(UTL_PFX) -#else -# define UTL_OFF 0 -#endif - -#ifndef BSD_UTMP -static unsigned -crc32s( const unsigned char *str ) -{ - int b; - unsigned crc = 0xffffffff, by; - - for (; *str; str++) { - by = (crc & 255) ^ *str; - for (b = 0; b < 8; b++) - by = (by >> 1) ^ (-(by & 1) & 0xedb88320); - crc = (crc >> 8) ^ by; - } - return crc; -} -#endif - -void -sessreg( struct display *d, int pid, const char *user, int uid ) -{ - char *dot, *colon; - int left, clen; -#ifdef BSD_UTMP - FILE *ttys; - int utmp, slot, freeslot; - STRUCTUTMP entry; -#else - unsigned crc, i; -#endif - int wtmp, c; -#ifndef NO_LASTLOG - int llog; - struct LASTLOG ll; -#endif - STRUCTUTMP ut_ent; - - if (!d->useSessReg) - return; - - bzero( &ut_ent, sizeof(ut_ent) ); - - if (pid) { - strncpy( ut_ent.ut_user, user, sizeof(ut_ent.ut_user) ); -#ifndef BSD_UTMP - ut_ent.ut_pid = pid; - ut_ent.ut_type = USER_PROCESS; - } else { - ut_ent.ut_type = DEAD_PROCESS; -#endif - } - ut_ent.ut_time = time( 0 ); - - colon = strchr( d->name, ':' ); - clen = strlen( colon ); - if (clen > (int)(sizeof(ut_ent.ut_line) - UTL_OFF) - 2) - return; /* uhm, well ... */ - if (colon == d->name) { -#ifndef BSD_UTMP - strncpy( ut_ent.ut_id, d->name, sizeof(ut_ent.ut_id) ); -#endif - left = 0; - } else { -#ifdef SESSREG_HOST -# ifndef BSD_UTMP - if (pid) -# endif - { - if (colon - d->name > (int)sizeof(ut_ent.ut_host)) { - ut_ent.ut_host[0] = '~'; - memcpy( ut_ent.ut_host + 1, - colon - (sizeof(ut_ent.ut_host) - 1), - sizeof(ut_ent.ut_host) - 1 ); - } else - memcpy( ut_ent.ut_host, d->name, colon - d->name ); - } -#endif -#ifndef BSD_UTMP - crc = crc32s( d->name ); - ut_ent.ut_id[0] = crc % 26 + 'A'; - crc /= 26; - for (i = 1; i < sizeof(ut_ent.ut_id); i++) { - c = crc % 62; - crc /= 62; - ut_ent.ut_id[i] = c < 26 ? c + 'A' : - c < 52 ? c - 26 + 'a' : c - 52 + '0'; - } -#endif - left = sizeof(ut_ent.ut_line) - UTL_OFF - clen; - if (colon - d->name <= left) { - clen += colon - d->name; - colon = d->name; - left = 0; - } else { - dot = strchr( d->name, '.' ); - if (dot && dot - d->name < left) { - memcpy( ut_ent.ut_line + UTL_OFF, d->name, left - 1 ); - ut_ent.ut_line[UTL_OFF + left - 1] = '~'; - } else { - memcpy( ut_ent.ut_line + UTL_OFF, d->name, left/2 - 1 ); - ut_ent.ut_line[UTL_OFF + left/2 - 1] = '~'; - if (dot) { - memcpy( ut_ent.ut_line + UTL_OFF + left/2, - dot - (left - left/2 - 1), - left - left/2 - 1 ); - ut_ent.ut_line[UTL_OFF + left - 1] = '~'; - } else - memcpy( ut_ent.ut_line + UTL_OFF + left/2, - colon - (left - left/2), left - left/2 ); - } - } - } -#ifdef UTL_PFX - memcpy( ut_ent.ut_line, UTL_PFX, UTL_OFF ); -#endif - memcpy( ut_ent.ut_line + UTL_OFF + left, colon, clen ); - -#ifndef NO_UTMP -# ifdef BSD_UTMP - if ((utmp = open( UTMP_FILE, O_RDWR )) < 0) - Debug( "cannot open utmp file " UTMP_FILE ": %m\n" ); - else { - - slot = 1; - if (pid) { - if (!(ttys = fopen( TTYS_FILE, "r" ))) - LogWarn( "Cannot open tty file " TTYS_FILE ": %m\n" ); - else { - int column0 = 1; - while ((c = getc( ttys )) != EOF) - if (c == '\n') { - slot++; - column0 = 1; - } else - column0 = 0; - if (!column0) - slot++; - fclose( ttys ); - } - } - freeslot = -1; - lseek( utmp, slot * sizeof(entry), SEEK_SET ); - while (read( utmp, (char *)&entry, sizeof(entry) ) == sizeof(entry)) { - if (!strncmp( entry.ut_line, ut_ent.ut_line, - sizeof(entry.ut_line) )) -# ifdef SESSREG_HOST - if (!strncmp( entry.ut_host, ut_ent.ut_host, - sizeof(entry.ut_host) )) -# endif - goto found; - if (freeslot < 0 && *entry.ut_user == '\0') - freeslot = slot; - slot++; - } - if (!pid) { - Debug( "utmp entry for display %s vanished\n", d->name ); - goto skip; - } - if (freeslot >= 0) - slot = freeslot; - found: - -# ifdef SESSREG_HOST - if (!pid) - bzero( ut_ent.ut_host, sizeof(ut_ent.ut_host) ); -# endif - lseek( utmp, slot * sizeof(ut_ent), SEEK_SET ); - if (write( utmp, (char *)&ut_ent, sizeof(ut_ent) ) != sizeof(ut_ent)) - LogError( "Cannot write utmp file " UTMP_FILE ": %m\n" ); - skip: - close( utmp ); - } -# else - UTMPNAME( UTMP_FILE ); - SETUTENT(); - PUTUTLINE( &ut_ent ); - ENDUTENT(); -# endif -#endif - - if ((wtmp = open( WTMP_FILE, O_WRONLY|O_APPEND )) < 0) - Debug( "cannot open wtmp file " WTMP_FILE ": %m\n" ); - else { - if (write( wtmp, (char *)&ut_ent, sizeof(ut_ent) ) != sizeof(ut_ent)) - LogError( "Cannot write wtmp file " WTMP_FILE ": %m\n" ); - close( wtmp ); - } - -#ifndef NO_LASTLOG - if (pid) { - bzero( (char *)&ll, sizeof(ll) ); - ll.ll_time = ut_ent.ut_time; - memcpy( ll.ll_line, ut_ent.ut_line, sizeof(ll.ll_line) ); - memcpy( ll.ll_host, ut_ent.ut_host, sizeof(ll.ll_host) ); -# ifdef HAVE_UTMPX - updlastlogx( LLOG_FILE, uid, &ll ); -# else - if ((llog = open( LLOG_FILE, O_RDWR )) < 0) - Debug( "cannot open lastlog file " LLOG_FILE ": %m\n" ); - else { - lseek( llog, (off_t)uid * sizeof(ll), SEEK_SET ); - if (write( llog, (char *)&ll, sizeof(ll) ) != sizeof(ll)) - LogError( "Cannot write llog file " WTMP_FILE ": %m\n" ); - close( llog ); - } -# endif - } -#else - (void)uid; -#endif - -#ifdef UTL_PFX - { - char tmp[sizeof("/dev/") + sizeof(ut_ent.ut_line)]; - mkdir( "/dev/" UTL_PFX, 0755 ); - chmod( "/dev/" UTL_PFX, 0755 ); - sprintf( tmp, "/dev/%.*s", sizeof(ut_ent.ut_line), ut_ent.ut_line ); - if (pid) - close( creat( tmp, 0644 ) ); - else - unlink( tmp ); - } -#endif -} diff --git a/kdm/backend/socket.c b/kdm/backend/socket.c deleted file mode 100644 index 677a3d32f..000000000 --- a/kdm/backend/socket.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2002 Sun Microsystems, Inc. All rights reserved. -Copyright 2002,2004 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * socket.c - Support for BSD sockets - */ - -#include "dm.h" - -#if defined(XDMCP) && !defined(STREAMSCONN) - -#include "dm_error.h" -#include "dm_socket.h" - -#include -#include - -static int c_request_port; - -static int -CreateListeningSocket( struct sockaddr *sock_addr, int salen ) -{ - int fd; -#if defined(IPv6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) - int on = 0; -#endif - const char *addrstring = "unknown"; -#if defined(IPv6) && defined(AF_INET6) - char addrbuf[INET6_ADDRSTRLEN]; -#endif - - if (!request_port) - return -1; - - if (debugLevel & DEBUG_CORE) { -#if defined(IPv6) && defined(AF_INET6) - void *ipaddr; - if (sock_addr->sa_family == AF_INET6) - ipaddr = & ((struct sockaddr_in6 *)sock_addr)->sin6_addr; - else - ipaddr = & ((struct sockaddr_in *)sock_addr)->sin_addr; - addrstring = - inet_ntop( sock_addr->sa_family, ipaddr, addrbuf, sizeof(addrbuf) ); - -#else - addrstring = inet_ntoa( ((struct sockaddr_in *)sock_addr)->sin_addr ); -#endif - - Debug( "creating socket to listen on port %d of address %s\n", - request_port, addrstring ); - } - - if ((fd = socket( sock_addr->sa_family, SOCK_DGRAM, 0 )) == -1) { - LogError( "XDMCP socket creation failed, errno %d\n", errno ); - return -1; - } -#if defined(IPv6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) - setsockopt( fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on) ); -#endif - - if (bind( fd, sock_addr, salen ) == -1) { - LogError( "error %d binding socket address %d\n", errno, request_port ); - close( fd ); - return -1; - } - - RegisterCloseOnFork( fd ); - RegisterInput( fd ); - return fd; -} - -struct socklist { - struct socklist *next; - struct socklist *mcastgroups; - struct sockaddr *addr; - int salen; - int addrlen; - int fd; - int ref; /* referenced bit - see UpdateListenSockets */ -}; - -static struct socklist *listensocks; - -static void -DestroyListeningSocket( struct socklist *s ) -{ - struct socklist *g, *n; - - if (s->fd >= 0) { - CloseNClearCloseOnFork( s->fd ); - UnregisterInput( s->fd ); - s->fd = -1; - } - if (s->addr) { - free( s->addr ); - s->addr = NULL; - } - for (g = s->mcastgroups; g; g = n) { - n = g->next; - if (g->addr) - free( g->addr ); - free( g ); - } - s->mcastgroups = NULL; -} - -static struct socklist* -FindInList( struct socklist *list, ARRAY8Ptr addr ) -{ - struct socklist *s; - - for (s = list; s; s = s->next) { - if (s->addrlen == addr->length) { - char *addrdata; - - switch (s->addr->sa_family) { - case AF_INET: - addrdata = (char *) - &(((struct sockaddr_in *)s->addr)->sin_addr.s_addr); - break; -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - addrdata = (char *) - &(((struct sockaddr_in6 *)s->addr)->sin6_addr.s6_addr); - break; -#endif - default: - /* Unrecognized address family */ - continue; - } - if (!memcmp( addrdata, addr->data, addr->length )) - return s; - } - } - return NULL; -} - -static struct socklist * -CreateSocklistEntry( ARRAY8Ptr addr ) -{ - struct socklist *s; - - if (!(s = Calloc( 1, sizeof(struct socklist) ))) - return NULL; - - if (addr->length == 4) { /* IPv4 */ - struct sockaddr_in *sin4; - sin4 = Calloc( 1, sizeof(struct sockaddr_in) ); -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sin4->sin_len = sizeof(struct sockaddr_in); -#endif - s->addr = (struct sockaddr *)sin4; - s->salen = sizeof(struct sockaddr_in); - s->addrlen = sizeof(struct in_addr); - sin4->sin_family = AF_INET; - sin4->sin_port = htons( (short)request_port ); - memcpy( &sin4->sin_addr, addr->data, addr->length ); - } -#if defined(IPv6) && defined(AF_INET6) - else if (addr->length == 16) { /* IPv6 */ - struct sockaddr_in6 *sin6; - sin6 = Calloc( 1, sizeof(struct sockaddr_in6) ); -#ifdef SIN6_LEN - sin6->sin6_len = sizeof(struct sockaddr_in6); -#endif - s->addr = (struct sockaddr *)sin6; - s->salen = sizeof(struct sockaddr_in6); - s->addrlen = sizeof(struct in6_addr); - sin6->sin6_family = AF_INET6; - sin6->sin6_port = htons( (short)request_port ); - memcpy( &sin6->sin6_addr, addr->data, addr->length ); - } -#endif - else { - /* Unknown address type */ - free( s ); - s = NULL; - } - return s; -} - -static void -UpdateListener( ARRAY8Ptr addr, void **closure ) -{ - struct socklist *s; - - *closure = NULL; - - if (addr == NULL) { - ARRAY8 tmpaddr; - struct in_addr in; -#if defined(IPv6) && defined(AF_INET6) - struct in6_addr in6 = in6addr_any; - tmpaddr.length = sizeof(in6); - tmpaddr.data = (CARD8Ptr) &in6; - UpdateListener( &tmpaddr, closure ); - if (*closure) - return; -#endif - in.s_addr = htonl( INADDR_ANY ); - tmpaddr.length = sizeof(in); - tmpaddr.data = (CARD8Ptr) ∈ - UpdateListener( &tmpaddr, closure ); - return; - } - - if (c_request_port == request_port && - (s = FindInList( listensocks, addr ))) - { - *closure = (void *)s; - s->ref = 1; - return; - } - - if (!(s = CreateSocklistEntry( addr ))) - return; - - if ((s->fd = CreateListeningSocket( s->addr, s->salen )) < 0) { - free( s->addr ); - free( s ); - return; - } - s->ref = 1; - s->next = listensocks; - listensocks = s; - *closure = (void *)s; -} - -#define JOIN_MCAST_GROUP 0 -#define LEAVE_MCAST_GROUP 1 - -static void -ChangeMcastMembership( struct socklist *s, struct socklist *g, int op ) -{ - int sockopt; - - switch (s->addr->sa_family) - { - case AF_INET: - { - struct ip_mreq mreq; - memcpy( &mreq.imr_multiaddr, - &((struct sockaddr_in *)g->addr)->sin_addr, - sizeof(struct in_addr) ); - memcpy( &mreq.imr_interface, - &((struct sockaddr_in *)s->addr)->sin_addr, - sizeof(struct in_addr) ); - if (op == JOIN_MCAST_GROUP) - sockopt = IP_ADD_MEMBERSHIP; - else - sockopt = IP_DROP_MEMBERSHIP; - if (setsockopt( s->fd, IPPROTO_IP, sockopt, - &mreq, sizeof(mreq) ) < 0) { - LogError( "XDMCP socket multicast %s to %s failed, errno %d\n", - (op == JOIN_MCAST_GROUP) ? "join" : "drop", - inet_ntoa( ((struct sockaddr_in *)g->addr)->sin_addr ), - errno ); - } else if (debugLevel & DEBUG_CORE) { - Debug( "XDMCP socket multicast %s to %s succeeded\n", - (op == JOIN_MCAST_GROUP) ? "join" : "drop", - inet_ntoa( ((struct sockaddr_in *)g->addr)->sin_addr ) ); - } - return; - } -#if defined(IPv6) && defined(AF_INET6) -# ifndef IPV6_JOIN_GROUP -# define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP -# endif -# ifndef IPV6_LEAVE_GROUP -# define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP -# endif - case AF_INET6: - { - struct ipv6_mreq mreq6; - memcpy( &mreq6.ipv6mr_multiaddr, - &((struct sockaddr_in6 *)g->addr)->sin6_addr, - sizeof(struct in6_addr) ); - mreq6.ipv6mr_interface = 0; /* TODO: fix this */ - if (op == JOIN_MCAST_GROUP) - sockopt = IPV6_JOIN_GROUP; - else - sockopt = IPV6_LEAVE_GROUP; - if (setsockopt( s->fd, IPPROTO_IPV6, sockopt, - &mreq6, sizeof(mreq6) ) < 0) - { - int saveerr = errno; - char addrbuf[INET6_ADDRSTRLEN]; - - inet_ntop( s->addr->sa_family, - &((struct sockaddr_in6 *)g->addr)->sin6_addr, - addrbuf, sizeof(addrbuf) ); - - LogError( "XDMCP socket multicast %s to %s failed, errno %d\n", - (op == JOIN_MCAST_GROUP) ? "join" : "drop", addrbuf, - saveerr ); - } else if (debugLevel & DEBUG_CORE) { - char addrbuf[INET6_ADDRSTRLEN]; - - inet_ntop( s->addr->sa_family, - &((struct sockaddr_in6 *)g->addr)->sin6_addr, - addrbuf, sizeof(addrbuf) ); - - Debug( "XDMCP socket multicast %s to %s succeeded\n", - (op == JOIN_MCAST_GROUP) ? "join" : "drop", addrbuf ); - } - return; - } -#endif - } -} - -static void -UpdateMcastGroup( ARRAY8Ptr addr, void **closure ) -{ - struct socklist *s = (struct socklist *)*closure; - struct socklist *g; - - if (!s) - return; - - /* Already in the group, mark & continue */ - if ((g = FindInList( s->mcastgroups, addr ))) { - g->ref = 1; - return; - } - - /* Need to join the group */ - if (!(g = CreateSocklistEntry( addr ))) - return; - - ChangeMcastMembership( s, g, JOIN_MCAST_GROUP ); - free( g ); -} - -/* Open or close listening sockets to match the current settings read in - from the access database. */ -void -UpdateListenSockets( void ) -{ - struct socklist *s, *g, **ls, **lg; - void *tmpPtr = NULL; - - /* Clear Ref bits - any not marked by UpdateCallback will be closed */ - for (s = listensocks; s; s = s->next) { - s->ref = 0; - for (g = s->mcastgroups; g; g = g->next) - g->ref = 0; - } - ForEachListenAddr( UpdateListener, UpdateMcastGroup, &tmpPtr ); - c_request_port = request_port; - for (ls = &listensocks; (s = *ls); ) - if (!s->ref) { - DestroyListeningSocket( s ); - *ls = s->next; - free( s ); - } else { - ls = &s->next; - for (lg = &s->mcastgroups; (g = *lg); ) - if (!g->ref) { - ChangeMcastMembership( s, g, LEAVE_MCAST_GROUP ); - *lg = g->next; - free( g ); - } else - lg = &g->next; - } -} - -int -AnyListenSockets( void ) -{ - return listensocks != NULL; -} - -int -ProcessListenSockets( FD_TYPE *reads ) -{ - struct socklist *s; - int ret = 0; - - for (s = listensocks; s; s = s->next) - if (FD_ISSET( s->fd, reads )) { - ProcessRequestSocket( s->fd ); - ret = 1; - } - return ret; -} - -#endif /* !STREAMSCONN && XDMCP */ diff --git a/kdm/backend/streams.c b/kdm/backend/streams.c deleted file mode 100644 index f60fb955e..000000000 --- a/kdm/backend/streams.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2002,2004 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * streams.c - Support for STREAMS - */ - -#include "dm.h" - -#if defined(XDMCP) && defined(STREAMSCONN) - -#include "dm_error.h" - -#include -#include -#include -#include - -static int xdmcpFd = -1, c_request_port; - -void -UpdateListenSockets( void ) -{ - struct t_bind bind_addr; - struct netconfig *nconf; - struct nd_hostserv service; - struct nd_addrlist *servaddrs; - char bindbuf[15]; - int it; - - if (c_request_port == request_port) - return; - c_request_port = request_port; - - if (xdmcpFd != -1) { - CloseNClearCloseOnFork( xdmcpFd ); - UnregisterInput( xdmcpFd ); - xdmcpFd = -1; - } - - if (!request_port) - return; - - Debug( "creating UDP stream %d\n", request_port ); - - nconf = getnetconfigent( "udp" ); - if (!nconf) { - t_error( "getnetconfigent udp" ); - return; - } - - xdmcpFd = t_open( nconf->nc_device, O_RDWR, NULL ); - if (xdmcpFd == -1) { - LogError( "XDMCP stream creation failed\n" ); - t_error( "CreateWellKnownSockets(xdmcpFd): t_open failed" ); - return; - } - - service.h_host = HOST_SELF; - sprintf( bindbuf, "%d", request_port ); - service.h_serv = bindbuf; - netdir_getbyname( nconf, &service, &servaddrs ); - freenetconfigent( nconf ); - - bind_addr.qlen = 5; - bind_addr.addr.buf = servaddrs->n_addrs[0].buf; - bind_addr.addr.len = servaddrs->n_addrs[0].len; - bind_addr.addr.maxlen = servaddrs->n_addrs[0].len; - it = t_bind( xdmcpFd, &bind_addr, &bind_addr ); - netdir_free( (char *)servaddrs, ND_ADDRLIST ); - if (it < 0) { - LogError( "Error binding UDP port %d\n", request_port ); - t_error( "CreateWellKnownSockets(xdmcpFd): t_bind failed" ); - t_close( xdmcpFd ); - xdmcpFd = -1; - return; - } - RegisterCloseOnFork( xdmcpFd ); - RegisterInput( xdmcpFd ); -} - -int -AnyListenSockets( void ) -{ - return xdmcpFd != -1; -} - -int -ProcessRequestSockets( FD_TYPE *reads ) -{ - if (xdmcpFd >= 0 && FD_ISSET( xdmcpFd, reads )) { - ProcessRequestSocket( xdmcpFd ); - return 1; - } - return 0; -} - -#endif /* STREAMSCONN && XDMCP */ diff --git a/kdm/backend/util.c b/kdm/backend/util.c deleted file mode 100644 index 7dd58f031..000000000 --- a/kdm/backend/util.c +++ /dev/null @@ -1,637 +0,0 @@ -/* - -Copyright 1989, 1998 The Open Group -Copyright 2000-2005 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * various utility routines - */ - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include -#include -#include -#include -#include - -#if 0 /*def USG; this was hpux once upon a time */ -# define NEED_UTSNAME -#endif - -#ifdef NEED_UTSNAME -# include -#endif - -void * -Calloc( size_t nmemb, size_t size ) -{ - void *ret; - - if (!(ret = calloc( nmemb, size ))) - LogOutOfMem(); - return ret; -} - -void * -Malloc( size_t size ) -{ - void *ret; - - if (!(ret = malloc( size ))) - LogOutOfMem(); - return ret; -} - -void * -Realloc( void *ptr, size_t size ) -{ - void *ret; - - if (!(ret = realloc( ptr, size )) && size) - LogOutOfMem(); - return ret; -} - -int -StrCmp( const char *s1, const char *s2 ) -{ - if (s1 == s2) - return 0; - if (!s1) - return -1; - if (!s2) - return 1; - return strcmp( s1, s2 ); -} - -void -WipeStr( char *str ) -{ - if (str) { - bzero( str, strlen( str ) ); - free( str ); - } -} - -#ifndef HAVE_STRNLEN -int -StrNLen( const char *s, int max ) -{ - unsigned l; - - for (l = 0; l < (unsigned)max && s[l]; l++); - return l; -} -#endif - -/* duplicate src; wipe & free old dst string */ -int -ReStrN( char **dst, const char *src, int len ) -{ - char *ndst = 0; - - if (src) { - if (len < 0) - len = strlen( src ); - if (*dst && !memcmp( *dst, src, len ) && !(*dst)[len]) - return 1; - if (!(ndst = Malloc( len + 1 ))) { - WipeStr( *dst ); - *dst = 0; - return 0; - } - memcpy( ndst, src, len ); - ndst[len] = 0; - } - WipeStr( *dst ); /* make an option, if we should become heavily used */ - *dst = ndst; - return 2; -} - -int -ReStr( char **dst, const char *src ) -{ - return ReStrN( dst, src, -1 ); -} - -/* duplicate src */ -int -StrNDup( char **dst, const char *src, int len ) -{ - if (src) { - if (len < 0) - len = strlen( src ); - if (!(*dst = Malloc( len + 1 ))) - return 0; - memcpy( *dst, src, len ); - (*dst)[len] = 0; - } else - *dst = 0; - return 1; -} - -int -StrDup( char **dst, const char *src ) -{ - return StrNDup( dst, src, -1 ); -} - -/* append any number of strings to dst */ -int -StrApp( char **dst, ... ) -{ - int len; - char *bk, *pt, *dp; - va_list va; - - len = 1; - if (*dst) - len += strlen( *dst ); - va_start( va, dst ); - for (;;) { - pt = va_arg( va, char * ); - if (!pt) - break; - len += strlen( pt ); - } - va_end( va ); - if (!(bk = Malloc( len ))) { - if (*dst) { - free( *dst ); - *dst = 0; - } - return 0; - } - dp = bk; - if (*dst) { - len = strlen( *dst ); - memcpy( dp, *dst, len ); - dp += len; - free( *dst ); - } - va_start( va, dst ); - for (;;) { - pt = va_arg( va, char * ); - if (!pt) - break; - len = strlen( pt ); - memcpy( dp, pt, len ); - dp += len; - } - va_end( va ); - *dp = '\0'; - *dst = bk; - return 1; -} - - -char ** -initStrArr( char **arr ) -{ - if (!arr && (arr = Malloc( sizeof(char *) ))) - arr[0] = 0; - return arr; -} - -int -arrLen( char **arr ) -{ - int nu = 0; - if (arr) - for (; arr[nu]; nu++); - return nu; -} - -static char ** -extStrArr( char **arr, char ***strp ) -{ - char **rarr; - int nu; - - nu = arrLen( arr ); - if ((rarr = Realloc( arr, sizeof(char *) * (nu + 2) ))) { - rarr[nu + 1] = 0; - *strp = rarr + nu; - return rarr; - } - freeStrArr( arr ); - return 0; -} - -char ** -addStrArr( char **arr, const char *str, int len ) -{ - char **strp; - - if ((arr = extStrArr( arr, &strp ))) { - if (StrNDup( strp, str, len )) - return arr; - freeStrArr( arr ); - } - return 0; -} - -char ** -xCopyStrArr( int rn, char **arr ) -{ - char **rarr; - int nu; - - nu = arrLen( arr ); - if ((rarr = Calloc( sizeof(char *), nu + rn + 1 ))) - memcpy( rarr + rn, arr, sizeof(char *) * nu ); - return rarr; -} - -void -freeStrArr( char **arr ) -{ - char **a; - - if (arr) { - for (a = arr; *a; a++) - free( *a ); - free( arr ); - } -} - - -char ** -parseArgs( char **argv, const char *string ) -{ - const char *word; - char **strp, *str; - int wlen; - - if (!(argv = initStrArr( argv ))) - return 0; - while (*string) { - if (isspace( *string )) { - string++; - continue; - } - word = string; - wlen = 0; - do { - if (*string == '\\') { - if (!*++string) - string--; - wlen++; - } else if (*string == '\'') { - while (*++string != '\'' && *string) - wlen++; - } else if (*string == '"') { - while (*++string != '"' && *string) { - if (*string == '\\') { - if (!*++string) - string--; - } - wlen++; - } - } else - wlen++; - } while (*++string && !isspace( *string )); - if (!(argv = extStrArr( argv, &strp ))) - return 0; - if (!(*strp = str = Malloc( wlen + 1 ))) { - freeStrArr( argv ); - return 0; - } - do { - if (*word == '\\') { - if (!*++word) - word--; - *str++ = *word; - } else if (*word == '\'') { - while (*++word != '\'' && *word) - *str++ = *word; - } else if (*word == '"') { - while (*++word != '"' && *word) { - if (*word == '\\') { - if (!*++word) - word--; - } - *str++ = *word; - } - } else - *str++ = *word; - } while (*++word && !isspace( *word )); - *str = 0; - } - return argv; -} - - -const char * -getEnv( char **e, const char *name ) -{ - if (e) { - int l = strlen( name ); - for (; *e; e++) - if (!memcmp( *e, name, l ) && (*e)[l] == '=') - return (*e) + l + 1; - } - return 0; -} - -char ** -setEnv( char **e, const char *name, const char *value ) -{ - char **new, **old; - char *newe; - int envsize; - int l; - -#ifdef _AIX - /* setpenv() depends on "SYSENVIRON:", not "SYSENVIRON:=" */ - if (!value) { - if (!StrDup( &newe, name )) - return e; - } else -#endif - { - newe = 0; - if (!StrApp( &newe, name, "=", value, (char *)0 )) - return e; - } - envsize = 0; - if (e) { - l = strlen( name ); - for (old = e; *old; old++) - if (!memcmp( *old, name, l ) && ((*old)[l] == '=' || !(*old)[l])) - { - free( *old ); - *old = newe; - return e; - } - envsize = old - e; - } - if (!(new = (char **) - Realloc( (char *)e, (unsigned)((envsize + 2) * sizeof(char *)) ))) - { - free( newe ); - return e; - } - new[envsize] = newe; - new[envsize + 1] = 0; - return new; -} - -char ** -putEnv( const char *string, char **env ) -{ - char *n; - char *b; - - if (!(b = strchr( string, '=' ))) - return NULL; - if (!StrNDup( &n, string, b - string )) - return NULL; - env = setEnv( env, n, b + 1 ); - free( n ); - return env; -} - -static int -GetHostname( char *buf, int maxlen ) -{ - int len; - -#ifdef NEED_UTSNAME - /* - * same host name crock as in server and xinit. - */ - struct utsname name; - - uname( &name ); - len = strlen( name.nodename ); - if (len >= maxlen) len = maxlen - 1; - memcpy( buf, name.nodename, len ); - buf[len] = '\0'; -#else - buf[0] = '\0'; - (void)gethostname( buf, maxlen ); - buf[maxlen - 1] = '\0'; - len = strlen( buf ); -#endif /* NEED_UTSNAME */ - return len; -} - -static char localHostbuf[256]; -static int gotLocalHostname; - -const char * -localHostname( void ) -{ - if (!gotLocalHostname) - { - GetHostname( localHostbuf, sizeof(localHostbuf) - 1 ); - gotLocalHostname = 1; - } - return localHostbuf; -} - -static int -AtomicIO( ssize_t (*f)( int, void *, size_t ), int fd, void *buf, int count ) -{ - int ret, rlen; - - for (rlen = 0; rlen < count; ) { - dord: - ret = f( fd, (void *)((char *)buf + rlen), count - rlen ); - if (ret < 0) { - if (errno == EINTR) - goto dord; - if (errno == EAGAIN) - break; - return -1; - } - if (!ret) - break; - rlen += ret; - } - return rlen; -} - -int -Reader( int fd, void *buf, int count ) -{ - return AtomicIO( read, fd, buf, count ); -} - -int -Writer( int fd, const void *buf, int count ) -{ - return AtomicIO( (ssize_t(*)( int, void *, size_t ))write, - fd, (void *)buf, count ); -} - -int -fGets( char *buf, int max, FILE *f ) -{ - int len; - - if (!fgets( buf, max, f )) - return -1; - len = strlen( buf ); - if (len && buf[len - 1] == '\n') - buf[--len] = 0; - return len; -} - -time_t -mTime( const char *fn ) -{ - struct stat st; - - if (stat( fn, &st )) - return -1; - else - return st.st_mtime; -} - -void -randomStr( char *s ) -{ - static const char letters[] = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - unsigned i, rn = secureRandom(); - - for (i = 0; i < 6; i++) { - *s++ = letters[rn % 62]; - rn /= 62; - } - *s = 0; -} - -static int -StrNChrCnt( const char *s, int slen, char c ) -{ - int i, cnt; - - for (i = cnt = 0; i < slen && s[i]; i++) - if (s[i] == c) - cnt++; - return cnt; -} - -/* X -from ip6-addr does not work here, so i don't know whether this is needed. -#define IP6_MAGIC -*/ - -void -ListSessions( int flags, struct display *d, void *ctx, - void (*emitXSess)( struct display *, struct display *, void * ), - void (*emitTTYSess)( STRUCTUTMP *, struct display *, void * ) ) -{ - struct display *di; -#ifdef IP6_MAGIC - int le, dot; -#endif -#ifdef BSD_UTMP - int fd; - struct utmp ut[1]; -#else - STRUCTUTMP *ut; -#endif - - for (di = displays; di; di = di->next) - if (((flags & lstRemote) || (di->displayType & d_location) == dLocal) && - (di->status == remoteLogin || - ((flags & lstPassive) ? di->status == running : di->userSess >= 0))) - emitXSess( di, d, ctx ); - - if (!(flags & lstTTY)) - return; - -#ifdef BSD_UTMP - if ((fd = open( UTMP_FILE, O_RDONLY )) < 0) - return; - while (Reader( fd, ut, sizeof(ut[0]) ) == sizeof(ut[0])) { - if (*ut->ut_user) { /* no idea how to list passive TTYs on BSD */ -#else - SETUTENT(); - while ((ut = GETUTENT())) { - if (ut->ut_type == USER_PROCESS -# if 0 /* list passive TTYs at all? not too sensible, i think. */ - || ((flags & lstPassive) && ut->ut_type == LOGIN_PROCESS) -# endif - ) - { -#endif - if (*ut->ut_host) { /* from remote or x */ - if (!(flags & lstRemote)) - continue; - } else { - /* hack around broken konsole which does not set ut_host. */ - /* this check is probably linux-specific. */ - /* alternatively we could open the device and try VT_OPENQRY. */ - if (memcmp( ut->ut_line, "tty", 3 ) || - !isdigit( ut->ut_line[3] )) - continue; - } - if (StrNChrCnt( ut->ut_line, sizeof(ut->ut_line), ':' )) - continue; /* x login */ - switch (StrNChrCnt( ut->ut_host, sizeof(ut->ut_host), ':' )) { - case 1: /* x terminal */ - continue; - default: -#ifdef IP6_MAGIC - /* unknown - IPv6 makes things complicated */ - le = StrNLen( ut->ut_host, sizeof(ut->ut_host) ); - /* cut off screen number */ - for (dot = le; ut->ut_host[--dot] != ':'; ) - if (ut->ut_host[dot] == '.') { - le = dot; - break; - } - for (di = displays; di; di = di->next) - if (!memcmp( di->name, ut->ut_host, le ) && !di->name[le]) - goto cont; /* x terminal */ - break; - cont: - continue; - case 0: /* no x terminal */ -#endif - break; - } - emitTTYSess( ut, d, ctx ); - } - } -#ifdef BSD_UTMP - close( fd ); -#else - ENDUTENT(); -#endif -} - diff --git a/kdm/backend/xdmauth.c b/kdm/backend/xdmauth.c deleted file mode 100644 index 86257c651..000000000 --- a/kdm/backend/xdmauth.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2001,2003 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * generate authorization data for XDM-AUTHORIZATION-1 as per XDMCP spec - */ - -#include - -#ifdef HASXDMAUTH - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -static char auth_name[256]; -static int auth_name_len; - -void -XdmInitAuth( unsigned short name_len, const char *name ) -{ - if (name_len > 256) - name_len = 256; - auth_name_len = name_len; - memmove( auth_name, name, name_len ); -} - -/* - * Generate authorization for XDM-AUTHORIZATION-1 - * - * When being used with XDMCP, 8 bytes are generated for the session key - * (sigma), as the random number (rho) is already shared between xdm and - * the server. Otherwise, we'll prepend a random number to pass in the file - * between xdm and the server (16 bytes total) - */ - -static Xauth * -XdmGetAuthHelper( unsigned short namelen, const char *name, int includeRho ) -{ - Xauth *new; - - if (!(new = (Xauth *)Malloc( sizeof(Xauth) ))) - return (Xauth *)0; - new->family = FamilyWild; - new->address_length = 0; - new->address = 0; - new->number_length = 0; - new->number = 0; - if (includeRho) - new->data_length = 16; - else - new->data_length = 8; - - new->data = (char *)Malloc( new->data_length ); - if (!new->data) { - free( (char *)new ); - return (Xauth *)0; - } - new->name = (char *)Malloc( namelen ); - if (!new->name) { - free( (char *)new->data ); - free( (char *)new ); - return (Xauth *)0; - } - memmove( (char *)new->name, name, namelen ); - new->name_length = namelen; - if (!GenerateAuthData( (char *)new->data, new->data_length )) { - free( (char *)new->name ); - free( (char *)new->data ); - free( (char *)new ); - return (Xauth *)0; - } - /* - * set the first byte of the session key to zero as it - * is a DES key and only uses 56 bits - */ - ((char *)new->data)[new->data_length - 8] = '\0'; - Debug( "local server auth %02[*hhx\n", new->data_length, new->data ); - return new; -} - -Xauth * -XdmGetAuth( unsigned short namelen, const char *name ) -{ - return XdmGetAuthHelper( namelen, name, TRUE ); -} - -#ifdef XDMCP - -void -XdmGetXdmcpAuth( struct protoDisplay *pdpy, - unsigned short authorizationNameLen, - const char *authorizationName ) -{ - Xauth *fileauth, *xdmcpauth; - - if (pdpy->fileAuthorization && pdpy->xdmcpAuthorization) - return; - xdmcpauth = XdmGetAuthHelper( authorizationNameLen, authorizationName, - FALSE ); - if (!xdmcpauth) - return; - fileauth = (Xauth *)Malloc( sizeof(Xauth) ); - if (!fileauth) { - XauDisposeAuth( xdmcpauth ); - return; - } - /* build the file auth from the XDMCP auth */ - *fileauth = *xdmcpauth; - fileauth->name = Malloc( xdmcpauth->name_length ); - fileauth->data = Malloc( 16 ); - fileauth->data_length = 16; - if (!fileauth->name || !fileauth->data) { - XauDisposeAuth( xdmcpauth ); - if (fileauth->name) - free( (char *)fileauth->name ); - if (fileauth->data) - free( (char *)fileauth->data ); - free( (char *)fileauth ); - return; - } - /* - * for the file authorization, prepend the random number (rho) - * which is simply the number we've been passing back and - * forth via XDMCP - */ - memmove( fileauth->name, xdmcpauth->name, xdmcpauth->name_length ); - memmove( fileauth->data, pdpy->authenticationData.data, 8 ); - memmove( fileauth->data + 8, xdmcpauth->data, 8 ); - Debug( "accept packet auth %02[*hhx\nauth file auth %02[*hhx\n", - xdmcpauth->data_length, xdmcpauth->data, - fileauth->data_length, fileauth->data ); - /* encrypt the session key for its trip back to the server */ - XdmcpWrap( (unsigned char *)xdmcpauth->data, (unsigned char *)&pdpy->key, - (unsigned char *)xdmcpauth->data, 8 ); - pdpy->fileAuthorization = fileauth; - pdpy->xdmcpAuthorization = xdmcpauth; -} - -#define atox(c) ('0' <= c && c <= '9' ? c - '0' : \ - 'a' <= c && c <= 'f' ? c - 'a' + 10 : \ - 'A' <= c && c <= 'F' ? c - 'A' + 10 : -1) - -static int -HexToBinary( char *key ) -{ - char *out, *in; - int top, bottom; - - in = key + 2; - out= key; - while (in[0] && in[1]) { - top = atox( in[0] ); - if (top == -1) - return 0; - bottom = atox( in[1] ); - if (bottom == -1) - return 0; - *out++ = (top << 4) | bottom; - in += 2; - } - if (in[0]) - return 0; - *out++ = '\0'; - return 1; -} - -/* - * Search the Keys file for the entry matching this display. This - * routine accepts either plain ascii strings for keys, or hex-encoded numbers - */ - -static int -XdmGetKey( struct protoDisplay *pdpy, ARRAY8Ptr displayID ) -{ - FILE *keys; - char line[1024], id[1024], key[1024]; - int keylen; - - Debug( "lookup key for %.*s\n", displayID->length, displayID->data ); - keys = fopen( keyFile, "r" ); - if (!keys) - return FALSE; - while (fgets( line, sizeof(line), keys )) { - if (line[0] == '#' || sscanf( line, "%s %s", id, key ) != 2) - continue; - bzero( line, sizeof(line) ); - Debug( "key entry for %\"s %d bytes\n", id, strlen( key ) ); - if (strlen( id ) == displayID->length && - !strncmp( id, (char *)displayID->data, displayID->length )) - { - if (!strncmp( key, "0x", 2 ) || !strncmp( key, "0X", 2 )) - if (!HexToBinary( key )) - break; - keylen = strlen( key ); - while (keylen < 7) - key[keylen++] = '\0'; - pdpy->key.data[0] = '\0'; - memmove( pdpy->key.data + 1, key, 7 ); - bzero( key, sizeof(key) ); - fclose( keys ); - return TRUE; - } - } - bzero( line, sizeof(line) ); - bzero( key, sizeof(key) ); - fclose( keys ); - return FALSE; -} - -/*ARGSUSED*/ -int -XdmCheckAuthentication( struct protoDisplay *pdpy, - ARRAY8Ptr displayID, - ARRAY8Ptr authenticationName ATTR_UNUSED, - ARRAY8Ptr authenticationData ) -{ - XdmAuthKeyPtr incoming; - - if (!XdmGetKey( pdpy, displayID )) - return FALSE; - if (authenticationData->length != 8) - return FALSE; - XdmcpUnwrap( authenticationData->data, (unsigned char *)&pdpy->key, - authenticationData->data, 8 ); - Debug( "request packet auth %02[*hhx\n", - authenticationData->length, authenticationData->data ); - if (!XdmcpCopyARRAY8( authenticationData, &pdpy->authenticationData )) - return FALSE; - incoming = (XdmAuthKeyPtr)authenticationData->data; - XdmcpIncrementKey( incoming ); - XdmcpWrap( authenticationData->data, (unsigned char *)&pdpy->key, - authenticationData->data, 8 ); - return TRUE; -} - -#endif /* XDMCP */ -#endif /* HASXDMAUTH (covering the entire file) */ diff --git a/kdm/backend/xdmcp.c b/kdm/backend/xdmcp.c deleted file mode 100644 index 6abaf5fc8..000000000 --- a/kdm/backend/xdmcp.c +++ /dev/null @@ -1,1165 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2002 Sun Microsystems, Inc. All rights reserved. -Copyright 2001-2004 Oswald Buddenhagen - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * xdmcp.c - Support for XDMCP - */ - -#include - -#ifdef XDMCP - -#include "dm.h" -#include "dm_error.h" -#include "dm_auth.h" -#include "dm_socket.h" - -#include -#include - -#include -#if defined(IPv6) && defined(AF_INET6) -# include -#endif - -/* - * Forward reference - */ -static void broadcast_respond( struct sockaddr *from, int fromlen, int length, int fd ); -static void forward_respond (struct sockaddr *from, int fromlen, int length, int fd); -static void manage( struct sockaddr *from, int fromlen, int length, int fd ); -static void query_respond( struct sockaddr *from, int fromlen, int length, int fd ); -static void request_respond( struct sockaddr *from, int fromlen, int length, int fd ); -static void send_accept( struct sockaddr *to, int tolen, CARD32 sessionID, ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, ARRAY8Ptr authorizationName, ARRAY8Ptr authorizationData, int fd ); -static void send_alive( struct sockaddr *from, int fromlen, int length, int fd ); -static void send_decline( struct sockaddr *to, int tolen, ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, ARRAY8Ptr status, int fd ); -static void send_failed( struct sockaddr *from, int fromlen, const char *name, CARD32 sessionID, const char *reason, int fd ); -static void send_refuse( struct sockaddr *from, int fromlen, CARD32 sessionID, int fd ); -static void send_unwilling( struct sockaddr *from, int fromlen, ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd ); -static void send_willing( struct sockaddr *from, int fromlen, ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd ); - - -static XdmcpBuffer buffer; - -static void -sendForward( CARD16 connectionType, ARRAY8Ptr address, char *closure ) -{ -#ifdef AF_INET - struct sockaddr_in in_addr; -#endif -#if defined(IPv6) && defined(AF_INET6) - struct sockaddr_in6 in6_addr; -#endif -#ifdef AF_DECnet -#endif - struct sockaddr *addr; - int addrlen; - - switch (connectionType) { -#ifdef AF_INET - case FamilyInternet: - addr = (struct sockaddr *)&in_addr; - bzero( (char *)&in_addr, sizeof(in_addr) ); -# ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -# endif - in_addr.sin_family = AF_INET; - in_addr.sin_port = htons( (short)XDM_UDP_PORT ); - if (address->length != 4) - return; - memmove( (char *)&in_addr.sin_addr, address->data, address->length ); - addrlen = sizeof(struct sockaddr_in); - break; -#endif -#if defined(IPv6) && defined(AF_INET6) - case FamilyInternet6: - addr = (struct sockaddr *)&in6_addr; - bzero( (char *)&in6_addr, sizeof(in6_addr) ); -# ifdef SIN6_LEN - in6_addr.sin6_len = sizeof(in6_addr); -# endif - in6_addr.sin6_family = AF_INET6; - in6_addr.sin6_port = htons( (short)XDM_UDP_PORT ); - if (address->length != 16) - return; - memmove( (char *)&in6_addr.sin6_addr, address->data, address->length ); - addrlen = sizeof(struct sockaddr_in6); - break; -#endif -#ifdef AF_DECnet - case FamilyDECnet: -#endif - default: - return; - } - XdmcpFlush( (int)closure, &buffer, (XdmcpNetaddr)addr, addrlen ); - return; -} - -static void -ClientAddress( struct sockaddr *from, - ARRAY8Ptr addr, /* return */ - ARRAY8Ptr port, /* return */ - CARD16 *type ) /* return */ -{ - int length, family; - char *data; - - data = NetaddrPort( (XdmcpNetaddr)from, &length ); - XdmcpAllocARRAY8( port, length ); - memmove( port->data, data, length ); - port->length = length; - - family = ConvertAddr( (XdmcpNetaddr)from, &length, &data ); - XdmcpAllocARRAY8( addr, length ); - memmove( addr->data, data, length ); - addr->length = length; - - *type = family; -} - -static void -all_query_respond( struct sockaddr *from, int fromlen, - ARRAYofARRAY8Ptr authenticationNames, - xdmOpCode type, int fd ) -{ - ARRAY8Ptr authenticationName; - ARRAY8 status; - ARRAY8 addr; - CARD16 connectionType; - int family; - int length; - - family = ConvertAddr( (XdmcpNetaddr)from, &length, &(addr.data) ); - addr.length = length; /* convert int to short */ - Debug( "all_query_respond: conntype=%d, addr=%02[*:hhx\n", - family, addr.length, addr.data ); - if (family < 0) - return; - connectionType = family; - - if (type == INDIRECT_QUERY) - RememberIndirectClient( &addr, connectionType ); - else - ForgetIndirectClient( &addr, connectionType ); - - authenticationName = ChooseAuthentication( authenticationNames ); - if (Willing( &addr, connectionType, authenticationName, &status, type )) - send_willing( from, fromlen, authenticationName, &status, fd ); - else - if (type == QUERY) - send_unwilling( from, fromlen, authenticationName, &status, fd ); - XdmcpDisposeARRAY8( &status ); -} - -static void -indirect_respond( struct sockaddr *from, int fromlen, int length, int fd ) -{ - ARRAYofARRAY8 queryAuthenticationNames; - ARRAY8 clientAddress; - ARRAY8 clientPort; - CARD16 connectionType; - int expectedLen; - int i; - XdmcpHeader header; - int localHostAsWell; - - Debug( " respond %d\n", length ); - if (!XdmcpReadARRAYofARRAY8( &buffer, &queryAuthenticationNames )) - return; - expectedLen = 1; - for (i = 0; i < (int)queryAuthenticationNames.length; i++) - expectedLen += 2 + queryAuthenticationNames.data[i].length; - if (length == expectedLen) { - ClientAddress( from, &clientAddress, &clientPort, &connectionType ); - /* - * set up the forward query packet - */ - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)FORWARD_QUERY; - header.length = 0; - header.length += 2 + clientAddress.length; - header.length += 2 + clientPort.length; - header.length += 1; - for (i = 0; i < (int)queryAuthenticationNames.length; i++) - header.length += 2 + queryAuthenticationNames.data[i].length; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteARRAY8( &buffer, &clientAddress ); - XdmcpWriteARRAY8( &buffer, &clientPort ); - XdmcpWriteARRAYofARRAY8( &buffer, &queryAuthenticationNames ); - - localHostAsWell = - ForEachMatchingIndirectHost( &clientAddress, connectionType, - sendForward, (char *)fd ); - - XdmcpDisposeARRAY8( &clientAddress ); - XdmcpDisposeARRAY8( &clientPort ); - if (localHostAsWell) - all_query_respond( from, fromlen, &queryAuthenticationNames, - INDIRECT_QUERY, fd ); - } else - Debug( " length error got %d expect %d\n", - length, expectedLen ); - XdmcpDisposeARRAYofARRAY8( &queryAuthenticationNames ); -} - -void -ProcessRequestSocket( int fd ) -{ - XdmcpHeader header; -#if defined(IPv6) && defined(AF_INET6) - struct sockaddr_storage addr; -#else - struct sockaddr addr; -#endif - int addrlen = sizeof(addr); - - Debug( "ProcessRequestSocket\n" ); - bzero( (char *)&addr, sizeof(addr) ); - if (!XdmcpFill( fd, &buffer, (XdmcpNetaddr)&addr, &addrlen )) { - Debug( "XdmcpFill failed\n" ); - return; - } - if (!XdmcpReadHeader( &buffer, &header )) { - Debug( "XdmcpReadHeader failed\n" ); - return; - } - if (header.version != XDM_PROTOCOL_VERSION) { - Debug( "XDMCP header version read was %d, expected %d\n", - header.version, XDM_PROTOCOL_VERSION ); - return; - } - Debug( "header: %d %d %d\n", header.version, header.opcode, header.length ); - switch (header.opcode) { - case BROADCAST_QUERY: - broadcast_respond( (struct sockaddr *)&addr, addrlen, header.length, fd ); - break; - case QUERY: - query_respond( (struct sockaddr *)&addr, addrlen, header.length, fd ); - break; - case INDIRECT_QUERY: - indirect_respond( (struct sockaddr *)&addr, addrlen, header.length, fd ); - break; - case FORWARD_QUERY: - forward_respond ((struct sockaddr *)&addr, addrlen, header.length, fd); - break; - case REQUEST: - request_respond( (struct sockaddr *)&addr, addrlen, header.length, fd ); - break; - case MANAGE: - manage( (struct sockaddr *)&addr, addrlen, header.length, fd ); - break; - case KEEPALIVE: - send_alive( (struct sockaddr *)&addr, addrlen, header.length, fd ); - break; - } -} - -/* - * respond to a request on the UDP socket. - */ - -static void -direct_query_respond( struct sockaddr *from, int fromlen, - int length, xdmOpCode type, int fd ) -{ - ARRAYofARRAY8 queryAuthenticationNames; - int expectedLen; - int i; - - if (!XdmcpReadARRAYofARRAY8( &buffer, &queryAuthenticationNames )) - return; - expectedLen = 1; - for (i = 0; i < (int)queryAuthenticationNames.length; i++) - expectedLen += 2 + queryAuthenticationNames.data[i].length; - if (length == expectedLen) - all_query_respond( from, fromlen, &queryAuthenticationNames, type, fd ); - XdmcpDisposeARRAYofARRAY8( &queryAuthenticationNames ); -} - -static void -query_respond( struct sockaddr *from, int fromlen, int length, int fd ) -{ - Debug( " respond %d\n", length ); - direct_query_respond( from, fromlen, length, QUERY, fd ); -} - -static void -broadcast_respond( struct sockaddr *from, int fromlen, int length, int fd ) -{ - direct_query_respond( from, fromlen, length, BROADCAST_QUERY, fd ); -} - -/* computes an X display name */ - -static char * -NetworkAddressToName( CARD16 connectionType, ARRAY8Ptr connectionAddress, - struct sockaddr *originalAddress, CARD16 displayNumber ) -{ - switch (connectionType) { - case FamilyInternet: -#if defined(IPv6) && defined(AF_INET6) - case FamilyInternet6: -#endif - { - CARD8 *data; - struct hostent *hostent; - char *hostname = NULL; - char *name; - const char *localhost; - int multiHomed = 0; - int type; -#if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai = NULL, *nai, hints; - char dotted[INET6_ADDRSTRLEN]; - - if (connectionType == FamilyInternet6) - type = AF_INET6; - else -#endif - type = AF_INET; - - data = connectionAddress->data; - hostent = gethostbyaddr( (char *)data, - connectionAddress->length, type ); - if (hostent) { - if (sourceAddress) { -#if defined(IPv6) && defined(AF_INET6) - bzero( &hints, sizeof(hints) ); - hints.ai_flags = AI_CANONNAME; - if (!getaddrinfo( hostent->h_name, NULL, &hints, &ai )) { - hostname = ai->ai_canonname; - for (nai = ai->ai_next; nai; nai = nai->ai_next) - if (ai->ai_protocol == nai->ai_protocol && - memcmp( ai->ai_addr, nai->ai_addr, - ai->ai_addrlen )) - multiHomed = 1; - } -#else - hostent = gethostbyname( hostent->h_name ); - if (hostent && hostent->h_addrtype == AF_INET) { - multiHomed = hostent->h_addr_list[1] != NULL; - hostname = hostent->h_name; - } -#endif - } else - hostname = hostent->h_name; - } - - localhost = localHostname(); - - /* - * protect against bogus host names - */ - if (hostname && *hostname && *hostname != '.' && !multiHomed) { - if (!strcmp( localhost, hostname )) - ASPrintf( &name, "localhost:%d", displayNumber ); - else { - if (removeDomainname) { - char *remoteDot; - char *localDot; - - /* check for a common domain name. This - * could reduce names by recognising common - * super-domain names as well, but I don't think - * this is as useful, and will confuse more - * people - */ - if ((localDot = strchr( localhost, '.' )) && - (remoteDot = strchr( hostname, '.' ))) - { - /* smash the name in place; it won't - * be needed later. - */ - if (!strcmp( localDot+1, remoteDot+1 )) - *remoteDot = '\0'; - } - } - - ASPrintf( &name, "%s:%d", hostname, displayNumber ); - } - } else { -#if defined(IPv6) && defined(AF_INET6) - if (multiHomed) { - if (connectionType == FamilyInternet) { - data = (CARD8 *) - &((struct sockaddr_in *)originalAddress)->sin_addr; - } else { - data = (CARD8 *) - &((struct sockaddr_in6 *)originalAddress)->sin6_addr; - } - } - inet_ntop( type, data, dotted, sizeof(dotted) ); - ASPrintf( &name, "%s:%d", dotted, displayNumber ); -#else - if (multiHomed) - data = (CARD8 *) - &((struct sockaddr_in *)originalAddress)->sin_addr; - ASPrintf( &name, "%[4|'.'hhu:%d", data, displayNumber ); -#endif - } -#if defined(IPv6) && defined(AF_INET6) - if (ai) - freeaddrinfo( ai ); -#endif - return name; - } -#ifdef DNET - case FamilyDECnet: - return NULL; -#endif /* DNET */ - default: - return NULL; - } -} - -/*ARGSUSED*/ -static void -forward_respond ( struct sockaddr *from, int fromlen ATTR_UNUSED, - int length, int fd) -{ - ARRAY8 clientAddress; - ARRAY8 clientPort; - ARRAYofARRAY8 authenticationNames; - struct sockaddr *client; - int clientlen; - int expectedLen; - int i; - - Debug( " respond %d\n", length ); - clientAddress.length = 0; - clientAddress.data = 0; - clientPort.length = 0; - clientPort.data = 0; - authenticationNames.length = 0; - authenticationNames.data = 0; - if (XdmcpReadARRAY8( &buffer, &clientAddress ) && - XdmcpReadARRAY8( &buffer, &clientPort ) && - XdmcpReadARRAYofARRAY8( &buffer, &authenticationNames )) - { - expectedLen = 0; - expectedLen += 2 + clientAddress.length; - expectedLen += 2 + clientPort.length; - expectedLen += 1; /* authenticationNames */ - for (i = 0; i < (int)authenticationNames.length; i++) - expectedLen += 2 + authenticationNames.data[i].length; - if (length == expectedLen) { - int j; - - j = 0; - for (i = 0; i < (int)clientPort.length; i++) - j = j * 256 + clientPort.data[i]; - Debug( " client address (port %d) %[*hhu\n", j, - clientAddress.length, clientAddress.data ); - switch (from->sa_family) { -#ifdef AF_INET - case AF_INET: - { - struct sockaddr_in in_addr; - - if (clientAddress.length != 4 || clientPort.length != 2) - goto badAddress; - bzero( (char *)&in_addr, sizeof(in_addr) ); -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -#endif - in_addr.sin_family = AF_INET; - memmove( &in_addr.sin_addr, clientAddress.data, 4 ); - memmove( (char *)&in_addr.sin_port, clientPort.data, 2 ); - client = (struct sockaddr *)&in_addr; - clientlen = sizeof(in_addr); - all_query_respond( client, clientlen, &authenticationNames, - FORWARD_QUERY, fd ); - } - break; -#endif -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - { - struct sockaddr_in6 in6_addr; - - if (clientAddress.length != 16 || clientPort.length != 2) - goto badAddress; - bzero( (char *)&in6_addr, sizeof(in6_addr) ); -#ifdef SIN6_LEN - in6_addr.sin6_len = sizeof(in6_addr); -#endif - in6_addr.sin6_family = AF_INET6; - memmove( &in6_addr,clientAddress.data,clientAddress.length ); - memmove( (char *)&in6_addr.sin6_port, clientPort.data, 2 ); - client = (struct sockaddr *)&in6_addr; - clientlen = sizeof(in6_addr); - all_query_respond( client, clientlen, &authenticationNames, - FORWARD_QUERY, fd ); - } - break; -#endif -#ifdef AF_UNIX - case AF_UNIX: - { - struct sockaddr_un un_addr; - - if (clientAddress.length >= sizeof(un_addr.sun_path)) - goto badAddress; - bzero( (char *)&un_addr, sizeof(un_addr) ); - un_addr.sun_family = AF_UNIX; - memmove( un_addr.sun_path, clientAddress.data, clientAddress.length ); - un_addr.sun_path[clientAddress.length] = '\0'; - client = (struct sockaddr *)&un_addr; -#if defined(HAVE_STRUCT_SOCKADDR_IN_SIN_LEN) && !defined(__Lynx__) && defined(UNIXCONN) - un_addr.sun_len = strlen( un_addr.sun_path ); - clientlen = SUN_LEN( &un_addr ); -#else - clientlen = sizeof(un_addr); -#endif - all_query_respond( client, clientlen, &authenticationNames, - FORWARD_QUERY, fd ); - } - break; -#endif -#ifdef AF_CHAOS - case AF_CHAOS: - goto badAddress; -#endif -#ifdef AF_DECnet - case AF_DECnet: - goto badAddress; -#endif - } - } else - Debug( " length error got %d expect %d\n", length, expectedLen ); - } - badAddress: - XdmcpDisposeARRAY8( &clientAddress ); - XdmcpDisposeARRAY8( &clientPort ); - XdmcpDisposeARRAYofARRAY8( &authenticationNames ); -} - -static ARRAY8 Hostname; - -static void -send_willing( struct sockaddr *from, int fromlen, - ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd ) -{ - XdmcpHeader header; - - Debug( "send %.*s %.*s\n", authenticationName->length, - authenticationName->data, - status->length, - status->data ); - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)WILLING; - header.length = - 6 + authenticationName->length + Hostname.length + status->length; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteARRAY8( &buffer, authenticationName ); - XdmcpWriteARRAY8( &buffer, &Hostname ); - XdmcpWriteARRAY8( &buffer, status ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); -} - -static void -send_unwilling( struct sockaddr *from, int fromlen, - ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd ) -{ - XdmcpHeader header; - - Debug( "send %.*s %.*s\n", authenticationName->length, - authenticationName->data, - status->length, - status->data ); - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)UNWILLING; - header.length = 4 + Hostname.length + status->length; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteARRAY8( &buffer, &Hostname ); - XdmcpWriteARRAY8( &buffer, status ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); -} - -static unsigned long globalSessionID; - -#define NextSessionID() (++globalSessionID) - -void init_session_id( void ) -{ - /* Set randomly so we are unlikely to reuse id's from a previous - * incarnation so we don't say "Alive" to those displays. - * Start with low digits 0 to make debugging easier. - */ - globalSessionID = (time( (Time_t *)0 ) & 0x7fff) * 16000; - - Hostname.data = (char *)localHostname(); - Hostname.length = strlen( Hostname.data ); -} - -static ARRAY8 outOfMemory = { (CARD16)13, (CARD8Ptr)"Out of memory" }; -static ARRAY8 noValidAddr = { (CARD16)16, (CARD8Ptr)"No valid address" }; -static ARRAY8 noValidAuth = { (CARD16)22, (CARD8Ptr)"No valid authorization" }; -static ARRAY8 noAuthentic = { (CARD16)29, (CARD8Ptr)"XDM has no authentication key" }; - -static void -request_respond( struct sockaddr *from, int fromlen, int length, int fd ) -{ - CARD16 displayNumber; - ARRAY16 connectionTypes; - ARRAYofARRAY8 connectionAddresses; - ARRAY8 authenticationName; - ARRAY8 authenticationData; - ARRAYofARRAY8 authorizationNames; - ARRAY8 manufacturerDisplayID; - ARRAY8Ptr reason = 0; - int expectlen; - int i, j; - struct protoDisplay *pdpy; - ARRAY8 authorizationName, authorizationData; - ARRAY8Ptr connectionAddress; - - Debug( " respond %d\n", length ); - connectionTypes.data = 0; - connectionAddresses.data = 0; - authenticationName.data = 0; - authenticationData.data = 0; - authorizationNames.data = 0; - authorizationName.length = 0; - authorizationData.length = 0; - manufacturerDisplayID.data = 0; - if (XdmcpReadCARD16( &buffer, &displayNumber ) && - XdmcpReadARRAY16( &buffer, &connectionTypes ) && - XdmcpReadARRAYofARRAY8( &buffer, &connectionAddresses ) && - XdmcpReadARRAY8( &buffer, &authenticationName ) && - XdmcpReadARRAY8( &buffer, &authenticationData ) && - XdmcpReadARRAYofARRAY8( &buffer, &authorizationNames ) && - XdmcpReadARRAY8( &buffer, &manufacturerDisplayID )) - { - expectlen = 0; - expectlen += 2; /* displayNumber */ - expectlen += 1 + 2 * connectionTypes.length; /* connectionTypes */ - expectlen += 1; /* connectionAddresses */ - for (i = 0; i < (int)connectionAddresses.length; i++) - expectlen += 2 + connectionAddresses.data[i].length; - expectlen += 2 + authenticationName.length; /* authenticationName */ - expectlen += 2 + authenticationData.length; /* authenticationData */ - expectlen += 1; /* authoriationNames */ - for (i = 0; i < (int)authorizationNames.length; i++) - expectlen += 2 + authorizationNames.data[i].length; - expectlen += 2 + manufacturerDisplayID.length; /* displayID */ - if (expectlen != length) { - Debug( " length error got %d expect %d\n", - length, expectlen ); - goto abort; - } - if (connectionTypes.length == 0 || - connectionAddresses.length != connectionTypes.length) - { - reason = &noValidAddr; - pdpy = 0; - goto decline; - } - pdpy = FindProtoDisplay( (XdmcpNetaddr)from, fromlen, displayNumber ); - if (!pdpy) { - - /* Check this Display against the Manager's policy */ - reason = Accept( from, fromlen, displayNumber ); - if (reason) - goto decline; - - /* Check the Display's stream services against Manager's policy */ - i = SelectConnectionTypeIndex( &connectionTypes, - &connectionAddresses ); - if (i < 0) { - reason = &noValidAddr; - goto decline; - } - - /* The Manager considers this a new session */ - connectionAddress = &connectionAddresses.data[i]; - pdpy = NewProtoDisplay( (XdmcpNetaddr)from, fromlen, displayNumber, - connectionTypes.data[i], connectionAddress, - NextSessionID() ); - Debug( "NewProtoDisplay %p\n", pdpy ); - if (!pdpy) { - reason = &outOfMemory; - goto decline; - } - } - if (authorizationNames.length == 0) - j = 0; - else - j = SelectAuthorizationTypeIndex( &authenticationName, - &authorizationNames ); - if (j < 0) { - reason = &noValidAuth; - goto decline; - } - if (!CheckAuthentication( pdpy, - &manufacturerDisplayID, - &authenticationName, - &authenticationData )) - { - reason = &noAuthentic; - goto decline; - } - if (j < (int)authorizationNames.length) { - Xauth *auth; - SetProtoDisplayAuthorization( pdpy, - (unsigned short)authorizationNames.data[j].length, - (char *)authorizationNames.data[j].data ); - auth = pdpy->xdmcpAuthorization; - if (!auth) - auth = pdpy->fileAuthorization; - if (auth) { - authorizationName.length = auth->name_length; - authorizationName.data = (CARD8Ptr) auth->name; - authorizationData.length = auth->data_length; - authorizationData.data = (CARD8Ptr) auth->data; - } - } - if (pdpy) { - send_accept( from, fromlen, pdpy->sessionID, - &authenticationName, - &authenticationData, - &authorizationName, - &authorizationData, fd ); - } else { - decline: - send_decline( from, fromlen, &authenticationName, - &authenticationData, - reason, fd ); - if (pdpy) - DisposeProtoDisplay( pdpy ); - } - } - abort: - XdmcpDisposeARRAY16( &connectionTypes ); - XdmcpDisposeARRAYofARRAY8( &connectionAddresses ); - XdmcpDisposeARRAY8( &authenticationName ); - XdmcpDisposeARRAY8( &authenticationData ); - XdmcpDisposeARRAYofARRAY8( &authorizationNames ); - XdmcpDisposeARRAY8( &manufacturerDisplayID ); -} - -static void -send_accept( struct sockaddr *to, int tolen, CARD32 sessionID, - ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, - ARRAY8Ptr authorizationName, ARRAY8Ptr authorizationData, - int fd ) -{ - XdmcpHeader header; - - Debug( " session ID %ld\n", (long)sessionID ); - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)ACCEPT; - header.length = 4; /* session ID */ - header.length += 2 + authenticationName->length; - header.length += 2 + authenticationData->length; - header.length += 2 + authorizationName->length; - header.length += 2 + authorizationData->length; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteCARD32( &buffer, sessionID ); - XdmcpWriteARRAY8( &buffer, authenticationName ); - XdmcpWriteARRAY8( &buffer, authenticationData ); - XdmcpWriteARRAY8( &buffer, authorizationName ); - XdmcpWriteARRAY8( &buffer, authorizationData ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)to, tolen ); -} - -static void -send_decline( struct sockaddr *to, int tolen, - ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, - ARRAY8Ptr status, int fd ) -{ - XdmcpHeader header; - - Debug( " %.*s\n", status->length, status->data ); - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)DECLINE; - header.length = 0; - header.length += 2 + status->length; - header.length += 2 + authenticationName->length; - header.length += 2 + authenticationData->length; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteARRAY8( &buffer, status ); - XdmcpWriteARRAY8( &buffer, authenticationName ); - XdmcpWriteARRAY8( &buffer, authenticationData ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)to, tolen ); -} - -static void -manage( struct sockaddr *from, int fromlen, int length, int fd ) -{ - CARD32 sessionID; - CARD16 displayNumber; - ARRAY8 displayClass; - int expectlen; - struct protoDisplay *pdpy; - struct display *d; - char *name = NULL; - char *class2 = NULL; - XdmcpNetaddr from_save; - ARRAY8 clientAddress, clientPort; - CARD16 connectionType; - - Debug( " %d\n", length ); - displayClass.data = 0; - displayClass.length = 0; - if (XdmcpReadCARD32( &buffer, &sessionID ) && - XdmcpReadCARD16( &buffer, &displayNumber ) && - XdmcpReadARRAY8( &buffer, &displayClass )) - { - expectlen = 4 + /* session ID */ - 2 + /* displayNumber */ - 2 + displayClass.length; /* displayClass */ - if (expectlen != length) { - Debug( " length error got %d expect %d\n", length, expectlen ); - goto abort; - } - pdpy = FindProtoDisplay( (XdmcpNetaddr)from, fromlen, displayNumber ); - Debug( " session ID %ld, pdpy %p\n", (long)sessionID, pdpy ); - if (!pdpy || pdpy->sessionID != sessionID) { - /* - * We may have already started a session for this display - * but it hasn't seen the response in the form of an - * XOpenDisplay() yet. So check if it is in the list of active - * displays, and if so check that the session id's match. - * If all this is true, then we have a duplicate request that - * can be ignored. - */ - if (!pdpy && - (d = FindDisplayByAddress( (XdmcpNetaddr)from, fromlen, - displayNumber )) && - d->sessionID == sessionID) - { - Debug( "manage: got duplicate pkt, ignoring\n" ); - goto abort; - } - Debug( "session ID %ld refused\n", (long)sessionID ); - if (pdpy) - Debug( "existing session ID %ld\n", (long)pdpy->sessionID ); - send_refuse( from, fromlen, sessionID, fd ); - } else { - name = NetworkAddressToName( pdpy->connectionType, - &pdpy->connectionAddress, - from, - pdpy->displayNumber ); - if (!name) { - Debug( "could not compute display name\n" ); - send_failed( from, fromlen, "(no name)", sessionID, - "out of memory", fd ); - goto abort; - } - Debug( "computed display name: %s\n", name ); - if ((d = FindDisplayByName( name ))) { - Debug( "terminating active session for %s\n", d->name ); - StopDisplay( d ); - } - if (displayClass.length) { - if (!StrNDup( &class2, (char *)displayClass.data, - displayClass.length )) - { - send_failed( from, fromlen, name, sessionID, - "out of memory", fd ); - goto abort; - } - } - if (!(from_save = (XdmcpNetaddr)Malloc( fromlen ))) { - send_failed( from, fromlen, name, sessionID, - "out of memory", fd ); - goto abort; - } - memmove( from_save, from, fromlen ); - if (!(d = NewDisplay( name ))) { - free( (char *)from_save ); - send_failed( from, fromlen, name, sessionID, - "out of memory", fd ); - goto abort; - } - d->class2 = class2; - class2 = 0; - d->displayType = dForeign | dTransient | dFromXDMCP; - d->sessionID = pdpy->sessionID; - d->from.data = (unsigned char *)from_save; - d->from.length = fromlen; - d->displayNumber = pdpy->displayNumber; - ClientAddress( from, &clientAddress, &clientPort, - &connectionType ); - d->useChooser = 0; - d->xdmcpFd = fd; - if (IsIndirectClient( &clientAddress, connectionType )) { - Debug( "IsIndirectClient\n" ); - ForgetIndirectClient( &clientAddress, connectionType ); - if (UseChooser( &clientAddress, connectionType )) { - d->useChooser = 1; - Debug( "use chooser for %s\n", d->name ); - } - } - d->clientAddr = clientAddress; - d->connectionType = connectionType; - d->remoteHost = NetworkAddressToHostname (pdpy->connectionType, - &pdpy->connectionAddress); - - XdmcpDisposeARRAY8( &clientPort ); - if (pdpy->fileAuthorization) { - d->authorizations = (Xauth **)Malloc( sizeof(Xauth *) ); - if (!d->authorizations) { - free( (char *)from_save ); - free( (char *)d ); - send_failed( from, fromlen, name, sessionID, - "out of memory", fd ); - goto abort; - } - d->authorizations[0] = pdpy->fileAuthorization; - d->authNum = 1; - pdpy->fileAuthorization = 0; - } - DisposeProtoDisplay( pdpy ); - Debug( "starting display %s,%s\n", d->name, d->class2 ); - if (LoadDisplayResources( d ) < 0) { - LogError( "Unable to read configuration for display %s; " - "stopping it.\n", d->name ); - StopDisplay( d ); - } else - StartDisplay( d ); - CloseGetter(); - } - } -abort: - XdmcpDisposeARRAY8( &displayClass ); - if (name) - free( (char *)name ); - if (class2) - free( (char *)class2 ); -} - -void -SendFailed( struct display *d, const char *reason ) -{ - Debug( "display start failed, sending \n" ); - send_failed( (struct sockaddr *)(d->from.data), d->from.length, d->name, - d->sessionID, reason, d->xdmcpFd ); -} - -static void -send_failed( struct sockaddr *from, int fromlen, - const char *name, CARD32 sessionID, const char *reason, int fd ) -{ - char buf[360]; - XdmcpHeader header; - ARRAY8 status; - - sprintf( buf, "Session %ld failed for display %.260s: %s", - (long)sessionID, name, reason ); - Debug( "send_failed(%\"s)\n", buf ); - status.length = strlen( buf ); - status.data = (CARD8Ptr) buf; - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)FAILED; - header.length = 6 + status.length; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteCARD32( &buffer, sessionID ); - XdmcpWriteARRAY8( &buffer, &status ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); -} - -static void -send_refuse( struct sockaddr *from, int fromlen, CARD32 sessionID, int fd ) -{ - XdmcpHeader header; - - Debug( "send %ld\n", (long)sessionID ); - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)REFUSE; - header.length = 4; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteCARD32( &buffer, sessionID ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); -} - -static void -send_alive( struct sockaddr *from, int fromlen, int length, int fd ) -{ - CARD32 sessionID; - CARD16 displayNumber; - struct display *d; - XdmcpHeader header; - CARD8 sendRunning; - CARD32 sendSessionID; - - Debug( "send \n" ); - if (XdmcpReadCARD16( &buffer, &displayNumber ) && - XdmcpReadCARD32( &buffer, &sessionID )) - { - if (length == 6) { - if (!(d = FindDisplayBySessionID( sessionID ))) - d = FindDisplayByAddress( (XdmcpNetaddr)from, fromlen, - displayNumber ); - sendRunning = 0; - sendSessionID = 0; - if (d && d->status == running) { - if (d->sessionID == sessionID) - sendRunning = 1; - sendSessionID = d->sessionID; - } - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)ALIVE; - header.length = 5; - Debug( ": %d %ld\n", sendRunning, (long)sendSessionID ); - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteCARD8( &buffer, sendRunning ); - XdmcpWriteCARD32( &buffer, sendSessionID ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); - } - } -} - -char * -NetworkAddressToHostname( CARD16 connectionType, ARRAY8Ptr connectionAddress ) -{ - switch (connectionType) { - case FamilyInternet: -#if defined(IPv6) && defined(AF_INET6) - case FamilyInternet6: -#endif - { - struct hostent *he; - char *name, *lname; - char *myDot; - int af_type; -#if defined(IPv6) && defined(AF_INET6) - char dotted[INET6_ADDRSTRLEN]; - - if (connectionType == FamilyInternet6) - af_type = AF_INET6; - else -#endif - af_type = AF_INET; - - he = gethostbyaddr( (char *)connectionAddress->data, - connectionAddress->length, af_type ); - if (he) { -#if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai, *nai; - if (!getaddrinfo( he->h_name, NULL, NULL, &ai )) { - for (nai = ai; nai; nai = nai->ai_next) { - if (af_type == nai->ai_family && - !memcmp( nai->ai_family == AF_INET ? - (char *)&((struct sockaddr_in *)nai->ai_addr)->sin_addr : - (char *)&((struct sockaddr_in6 *)nai->ai_addr)->sin6_addr, - connectionAddress->data, - connectionAddress->length )) - { - freeaddrinfo( ai ); - goto oki; - } - } - freeaddrinfo( ai ); -#else - if ((he = gethostbyname( he->h_name )) && - he->h_addrtype == AF_INET) - { - int i; - for (i = 0; he->h_addr_list[i]; i++) - if (!memcmp( he->h_addr_list[i], - connectionAddress->data, 4 )) - goto oki; -#endif - LogError( "DNS spoof attempt or misconfigured resolver.\n" ); - } - goto gotnone; - oki: - if (StrDup( &name, he->h_name ) && - !strchr( name, '.' ) && - (myDot = strchr( localHostname(), '.' ))) - { - if (ASPrintf( &lname, "%s%s", name, myDot )) { -#if defined(IPv6) && defined(AF_INET6) - if (!getaddrinfo( lname, NULL, NULL, &ai )) { - for (nai = ai; nai; nai = nai->ai_next) { - if (af_type == nai->ai_family && - !memcmp( nai->ai_family == AF_INET ? - (char *)&((struct sockaddr_in *)nai->ai_addr)->sin_addr : - (char *)&((struct sockaddr_in6 *)nai->ai_addr)->sin6_addr, - connectionAddress->data, - connectionAddress->length )) - { - freeaddrinfo( ai ); - free( name ); - return lname; - } - } - freeaddrinfo( ai ); - } -#else - if ((he = gethostbyname( lname )) && - he->h_addrtype == AF_INET) - { - int i; - for (i = 0; he->h_addr_list[i]; i++) - if (!memcmp( he->h_addr_list[i], - connectionAddress->data, 4 )) - { - free( name ); - return lname; - } - } -#endif - free( lname ); - } - } - } else { - gotnone: - /* can't get name, so use emergency fallback */ -#if defined(IPv6) && defined(AF_INET6) - inet_ntop( af_type, connectionAddress->data, - dotted, sizeof(dotted) ); - StrDup( &name, dotted ); -#else - ASPrintf( &name, "%[4|'.'hhu", connectionAddress->data ); -#endif - LogWarn( "Cannot convert Internet address %s to host name\n", - name ); - } - return name; - } -#ifdef DNET - case FamilyDECnet: - break; -#endif /* DNET */ - default: - break; - } - return 0; -} - -#endif /* XDMCP */ - diff --git a/kdm/config.def b/kdm/config.def deleted file mode 100644 index a7ec59076..000000000 --- a/kdm/config.def +++ /dev/null @@ -1,2662 +0,0 @@ -# -# Copyright 2010 Timothy Pearson -# Copyright 2004-2005 Oswald Buddenhagen -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation. -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of a copyright holders shall -# not be used in advertising or otherwise to promote the sale, use or -# other dealings in this Software without prior written authorization -# from the copyright holders. -# - -# The contents of this section are copied into config.ci verbatim. - -#define RCVERMAJOR 2 -#define RCVERMINOR 3 - -#define TDMCONF KDE_CONFDIR "/tdm" -#define TDMDATA KDE_DATADIR "/tdm" - -#ifdef _AIX -# define HALT_CMD "/usr/sbin/shutdown -h now" -# define REBOOT_CMD "/usr/sbin/shutdown -r now" -#elif defined(BSD) -# define HALT_CMD "/sbin/shutdown -h now" -# define REBOOT_CMD "/sbin/shutdown -r now" -#elif defined(__SVR4) -# define HALT_CMD "/usr/sbin/halt" -# define REBOOT_CMD "/usr/sbin/reboot" -#else -# define HALT_CMD "/sbin/poweroff" -# define REBOOT_CMD "/sbin/reboot" -#endif - -#if defined(BSD) || defined(__linux__) -# define DEF_USER_PATH "/usr/local/bin:/opt/trinity/bin:/usr/bin:/bin:/opt/trinity/games:/usr/games" -# define DEF_SYSTEM_PATH "/usr/local/sbin:/usr/local/bin:/opt/trinity/sbin:/usr/sbin:/opt/trinity/bin:/usr/bin:/sbin:/bin" -#else -# define DEF_USER_PATH "/usr/local/bin:/opt/trinity/bin:/usr/bin:/bin:/opt/trinity/games:/usr/games:/usr/ucb" -# define DEF_SYSTEM_PATH "/usr/local/sbin:/usr/local/bin:/opt/trinity/sbin:/usr/sbin:/opt/trinity/bin:/usr/bin:/sbin:/bin:/etc:/usr/ucb" -#endif - -#if 0 /*def HASXDMAUTH*/ -# define DEF_AUTH_NAME "XDM-AUTHORIZATION-1,MIT-MAGIC-COOKIE-1" -#else -# define DEF_AUTH_NAME "MIT-MAGIC-COOKIE-1" -#endif - -#ifdef __linux__ -# define HAVE_VTS -#elif defined(__sun__) -# define DEF_SERVER_TTY "console" -#elif defined(_AIX) -# define DEF_SERVER_TTY "lft0" -#else -# define DEF_SERVER_TTY "" -#endif - -#ifdef _AIX -# define DEF_SERVER_CMD XBINDIR "/X -T -force" -#elif defined(__linux__) || defined(__GNU__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -/* we just assume that any free *nix installation has a recent xfree86/xorg */ -# define DEF_SERVER_CMD XBINDIR "/X -br" -#else -# define DEF_SERVER_CMD XBINDIR "/X" -#endif - - -# The contents of this section are copied mostly verbatim to the -# default/example configuration file. -# Everything indented with a space is considered a comment for the output; -# it is prefixed with a hash mark but otherwise copied verbatim (except -# for lines consisting of a single underscore, which generate empty comment -# lines). -# Section headers are "condensation seeds" for the Instance:s in the key -# definitions below. - - &tdm; master configuration file - _ - Please note: Settings in this file are sometimes ignored (overridden). - The default TDM startup script /etc/init.d/tdm looks in /etc/default/tdm.d - for theme-related settings which, if found, take precedence. The possibly - overridden settings are: UseBackground, BackgroundCfg, UseTheme, Theme. - See /usr/share/doc/tdm/README.Debian for details - _ - Definition: the greeter is the login dialog, i.e., the part of &tdm; - which the user sees. - _ - You can configure every X-display individually. - Every display has a display name, which consists of a host name - (which is empty for local displays specified in {Static|Reserve}Servers), - a colon, and a display number. Additionally, a display belongs to a - display class (which can be ignored in most cases; the control center - does not support this feature at all). - Sections with display-specific settings have the formal syntax - "[X-" host [":" number [ "_" class ]] "-" sub-section "]" - You can use the "*" wildcard for host, number, and class. You may omit - trailing components; they are assumed to be "*" then. - The host part may be a domain specification like ".inf.tu-dresden.de". - It may also be "+", which means non-empty, i.e. remote displays only. - From which section a setting is actually taken is determined by these - rules: - - an exact match takes precedence over a partial match (for the host part), - which in turn takes precedence over a wildcard ("+" taking precedence - over "*") - - precedence decreases from left to right for equally exact matches - Example: display name "myhost:0", class "dpy". - [X-myhost:0_dpy] precedes - [X-myhost:0_*] (same as [X-myhost:0]) precedes - [X-myhost:*_dpy] precedes - [X-myhost:*_*] (same as [X-myhost]) precedes - [X-+:0_dpy] precedes - [X-*:0_dpy] precedes - [X-*:0_*] (same as [X-*:0]) precedes - [X-*:*_*] (same as [X-*]) - These sections do NOT match this display: - [X-hishost], [X-myhost:0_dec], [X-*:1], [X-:*] - If a setting is not found in any matching section, the default is used. - _ - Every comment applies to the following section or key. Note that all - comments will be lost if you change this file with the kcontrol frontend. - The defaults refer to &tdm;'s built-in values, not anything set in this file. - _ - Special characters need to be backslash-escaped (leading and trailing - spaces (\\s), tab (\\t), linefeed (\\n), carriage return (\\r) and the - backslash itself (\\\\)). - In lists, fields are separated with commas without whitespace in between. - Some command strings are subject to simplified sh-style word splitting: - single quotes (') and double quotes (") have the usual meaning; the backslash - quotes everything (not only special characters). Note that the backslashes - need to be doubled because of the two levels of quoting. - -[General] - -[Xdmcp] - -[Shutdown] - - Rough estimations about how many seconds &tdm; will spend at most on - - opening a connection to the X-server (OpenTime) if the attempt - - times out: OpenTimeout - - is refused: OpenRepeat * OpenDelay - - starting a local X-server (ServerTime): - ServerAttempts * (ServerTimeout + OpenDelay) - - starting a display: - - local display: ServerTime + OpenTime - - foreign display: StartAttempts * OpenTime - - &XDMCP; display: OpenTime (repeated indefinitely by client) - - Core config for all displays -[X-*-Core] - - Greeter config for all displays -[X-*-Greeter] - - Core config for local displays -[X-:*-Core] - - Greeter config for local displays -[X-:*-Greeter] - - Core config for 1st local display -[X-:0-Core] - - Greeter config for 1st local display -[X-:0-Greeter] - - -# The contents of this section are copied into tdmrc-ref.docbook. -# The macro %REF% is replaced with the accumulated Description:s from the key -# definitions below. - - -The Files &tdm; Uses for Configuration - -This chapter documents the files that control &tdm;'s behavior. -Some of this can be also controlled from the &kcontrol; module, but -not all. - - -&tdmrc; - The &tdm; master configuration file - -The basic format of the file is INI-like. -Options are key/value pairs, placed in sections. -Everything in the file is case sensitive. -Syntactic errors and unrecognized key/section identifiers cause &tdm; to -issue non-fatal error messages. - -Lines beginning with # are comments; empty lines -are ignored as well. - -Sections are denoted by -[Name of Section]. - - -You can configure every X-display individually. -Every display has a display name, which consists of a host name -(which is empty for local displays specified in -or ), a colon, and a display number. -Additionally, a display belongs to a -display class (which can be ignored in most cases). - -Sections with display-specific settings have the formal syntax -[X- host [ : number [ _ class ] ] - sub-section ] - -All sections with the same sub-section -make up a section class. - -You can use the wildcard * (match any) for -host, number, -and class. You may omit trailing components; -they are assumed to be * then. The host part may be a -domain specification like .inf.tu-dresden.de -or the wildcard + (match non-empty). - -From which section a setting is actually taken is determined by -these rules: - - - -An exact match takes precedence over a partial match (for the -host part), which in turn takes precedence over a wildcard -(+ taking precendence over *). - - - -Precedence decreases from left to right for equally exact matches. - - - - - -Example: display name myhost.foo:0, class dpy - - - -[X-myhost.foo:0_dpy] precedes - - -[X-myhost.foo:0_*] (same as [X-myhost.foo:0]) precedes - - -[X-myhost.foo:*_dpy] precedes - - -[X-myhost.foo:*_*] (same as [X-myhost.foo]) precedes - - -[X-.foo:*_*] (same as [X-.foo]) precedes - - -[X-+:0_dpy] precedes - - -[X-*:0_dpy] precedes - - -[X-*:0_*] (same as [X-*:0]) precedes - - -[X-*:*_*] (same as [X-*]). - - -These sections do not match this display: -[X-hishost], [X-myhost.foo:0_dec], [X-*:1], [X-:*] - - - - - - - -Common sections are [X-*] (all displays), [X-:*] (all local displays) -and [X-:0] (the first local display). - -The format for all keys is - = value. -Keys are only valid in the section class they are defined for. -Some keys do not apply to particular displays, in which case they are ignored. - - -If a setting is not found in any matching section, the default -is used. - -Special characters need to be backslash-escaped (leading and trailing -spaces (\s), tab (\t), linefeed -(\n), carriage return (\r) and the -backslash itself (\\)). -In lists, fields are separated with commas without whitespace in between. - -Some command strings are subject to simplified sh-style word splitting: -single quotes (') and double quotes (") -have the usual meaning; the backslash quotes everything (not only special -characters). Note that the backslashes need to be doubled because of the -two levels of quoting. - -A pristine &tdmrc; is very thoroughly commented. -All comments will be lost if you change this file with the -kcontrol frontend. - -%REF% - - - - -Specifying permanent &X-Server;s - -Each entry in the list indicates a -display which should constantly be -managed and which is not using &XDMCP;. This method is typically used only for -local &X-Server;s that are started by &tdm;, but &tdm; can manage externally -started (foreign) &X-Server;s as well, may they run on the -local machine or rather remotely. - -The formal syntax of a specification is - -display name [_display class] - -for all &X-Server;s. Foreign displays differ in having -a host name in the display name, may it be localhost. - -The display name must be something that can -be passed in the option to an X program. This string -is used to generate the display-specific section names, so be careful to match -the names. -The display name of &XDMCP; displays is derived from the display's address by -reverse host name resolution. For configuration purposes, the -localhost prefix from locally running &XDMCP; displays is -not stripped to make them distinguishable from local -&X-Server;s started by &tdm;. - -The display class portion is also used in the -display-specific sections. This is useful if you have a large collection of -similar displays (such as a corral of X terminals) and would like to set -options for groups of them. -When using &XDMCP;, the display is required to specify the display class, -so the manual for your particular X terminal should document the display -class string for your device. If it does not, you can run &tdm; in debug -mode and grep the log for class. - -The displays specified in will not be -started when &tdm; starts up, but when it is explicitly requested via -the command socket (or FiFo). -If reserve displays are specified, the &kde; menu will have a -Start New Session item near the bottom; use that to -activate a reserve display with a new login session. The monitor will switch -to the new display, and you will have a minute to login. If there are no more -reserve displays available, the menu item will be disabled. - -When &tdm; starts a session, it sets up authorization data for the -&X-Server;. For local servers, &tdm; passes - filename -on the &X-Server;'s command line to point it at its authorization data. -For &XDMCP; displays, &tdm; passes the authorization data to the &X-Server; -via the Accept &XDMCP; message. - - - - -&XDMCP; access control - -The file specified by the option provides -information which &tdm; uses to control access from displays requesting service -via &XDMCP;. -The file contains four types of entries: entries which control the response -to Direct and Broadcast queries, entries which -control the response to Indirect queries, macro definitions for -Indirect entries, and entries which control on which network -interfaces &tdm; listens for &XDMCP; queries. -Blank lines are ignored, # is treated as a comment -delimiter causing the rest of that line to be ignored, and \ -causes an immediately following newline to be ignored, allowing indirect host -lists to span multiple lines. - - -The format of the Direct entries is simple, either a -host name or a pattern, which is compared against the host name of the display -device. -Patterns are distinguished from host names by the inclusion of one or more -meta characters; * matches any sequence of 0 or more -characters, and ? matches any single character. -If the entry is a host name, all comparisons are done using network addresses, -so any name which converts to the correct network address may be used. Note -that only the first network address returned for a host name is used. -For patterns, only canonical host names are used in the comparison, so ensure -that you do not attempt to match aliases. -Host names from &XDMCP; queries always contain the local domain name -even if the reverse lookup returns a short name, so you can use -patterns for the local domain. -Preceding the entry with a ! character causes hosts which -match that entry to be excluded. -To only respond to Direct queries for a host or pattern, -it can be followed by the optional NOBROADCAST keyword. -This can be used to prevent a &tdm; server from appearing on menus based on -Broadcast queries. - -An Indirect entry also contains a host name or pattern, -but follows it with a list of host names or macros to which the queries -should be forwarded. Indirect entries can be excluding as well, -in which case a (valid) dummy host name must be supplied to make the entry -distinguishable from a Direct entry. -If compiled with IPv6 support, multicast address groups may also be included -in the list of addresses the queries are forwarded to. - -If the indirect host list contains the keyword CHOOSER, -Indirect queries are not forwarded, but instead a host chooser -dialog is displayed by &tdm;. The chooser will send a Direct -query to each of the remaining host names in the list and offer a menu of -all the hosts that respond. The host list may contain the keyword -BROADCAST, to make the chooser send a -Broadcast query as well; note that on some operating systems, -UDP packets cannot be broadcast, so this feature will not work. - - -When checking access for a particular display host, each entry is scanned -in turn and the first matching entry determines the response. -Direct and Broadcast entries are ignored when -scanning for an Indirect entry and vice-versa. - -A macro definition contains a macro name and a list of host names and -other macros that the macro expands to. To distinguish macros from hostnames, -macro names start with a % character. - -The last entry type is the LISTEN directive. -The formal syntax is - - LISTEN [interface [multicast list]] - -If one or more LISTEN lines are specified, &tdm; listens -for &XDMCP; requests only on the specified interfaces. -interface may be a hostname or IP address -representing a network interface on this machine, or the wildcard -* to represent all available network interfaces. -If multicast group addresses are listed on a LISTEN line, -&tdm; joins the multicast groups on the given interface. For IPv6 multicasts, -the IANA has assigned ff0X:0:0:0:0:0:0:12b as the -permanently assigned range of multicast addresses for &XDMCP;. The -X in the prefix may be replaced by any valid scope -identifier, such as 1 for Node-Local, 2 for Link-Local, 5 for Site-Local, and -so on (see IETF RFC 2373 or its replacement for further details and scope -definitions). &tdm; defaults to listening on the Link-Local scope address -ff02:0:0:0:0:0:0:12b to most closely match the IPv4 subnet broadcast behavior. -If no LISTEN lines are given, &tdm; listens on all -interfaces and joins the default &XDMCP; IPv6 multicast group (when -compiled with IPv6 support). -To disable listening for &XDMCP; requests altogether, a -LISTEN line with no addresses may be specified, but using -the [Xdmcp] option is preferred. - - - - - -Supplementary programs - - -The following programs are run by &tdm; at various stages of a session. -They typically are shell scripts. - - - -The Setup, Startup and Reset programs are run as -root, so they should be careful -about security. -Their first argument is auto if the session results -from an automatic login; otherwise, no arguments are passed to them. - - - -Setup program - - -The Xsetup program is run after the &X-Server; is -started or reset, but before the greeter is offered. -This is the place to change the root background (if - is disabled) or bring up other windows that -should appear on the screen along with the greeter. - - - -In addition to any specified by , -the following environment variables are passed: - - - DISPLAY - the associated display name - - - PATH - the value of - - - SHELL - the value of - - - XAUTHORITY - may be set to an authority file - - - DM_CONTROL - the value of - - - - Note that since &tdm; grabs the keyboard, any other windows will not be -able to receive keyboard input. They will be able to interact with the mouse, -however; beware of potential security holes here. If -is set, Xsetup will not be able to connect to the display -at all. Resources for this program can be put into the file named by -. - - - - - -Startup program - -The Xstartup program is run as -root when the user logs in. -This is the place to put commands which add entries to -utmp (the sessreg program -may be useful here), mount users' home directories from file servers, -or abort the session if some requirements are not met (but note that on -modern systems, many of these tasks are already taken care of by -PAM modules). - -In addition to any specified by , -the following environment variables are passed: - - - DISPLAY - the associated display name - - - HOME - the initial working directory of the user - - - LOGNAME - the username - - - USER - the username - - - PATH - the value of - - - SHELL - the value of - - - XAUTHORITY - may be set to an authority file - - - DM_CONTROL - the value of - - - -&tdm; waits until this program exits before starting the user session. -If the exit value of this program is non-zero, &tdm; discontinues the session -and starts another authentication cycle. - - - - -Session program - -The Xsession program is the command which is run -as the user's session. It is run with the permissions of the authorized user. -One of the keywords failsafe, default -or custom, or a string to eval by a -Bourne-compatible shell is passed as the first argument. - -In addition to any specified by , -the following environment variables are passed: - - - DISPLAY - the associated display name - - - HOME - the initial working directory of the user - - - LOGNAME - the username - - - USER - the username - - - PATH - the value of - (or for - root user sessions) - - - - SHELL - the user's default shell - - - XAUTHORITY - may be set to a non-standard authority file - - - KRBTKFILE - may be set to a Kerberos4 credentials cache name - - - - KRB5CCNAME - may be set to a Kerberos5 credentials cache name - - - - DM_CONTROL - the value of - - - XDM_MANAGED - will contain a comma-separated list of parameters the - session might find interesting, like the location of the command - FiFo and its capabilities, and which conversation - plugin was used for the login - - - - DESKTOP_SESSION - the name of the session the user has chosen to run - - - - - - - -Reset program - -Symmetrical with Xstartup, the -Xreset program is run after the user session has -terminated. Run as root, it should -contain commands that undo the effects of commands in -Xstartup, removing entries from utmp -or unmounting directories from file servers. - -The environment variables that were passed to -Xstartup are also passed to Xreset. - - - - - - - - - - -# The rest of this file are section and key definitions for the options. -# The order of the keywords is fixed and everything is case sensitive. -# A keyword may expect supplementary data in the form of space-indented -# lines following it. Definitions are delimited by empty lines. -# -# Section definition: -# Section: -# Section name. Section classes start with a dash. -# If: -# C preprocessor conditional for supporting this section. -# If it evaluates to false, all keys in this section are disabled as well. -# Description: -# A docbook description of this section is expected in the next lines. -# The contents are automatically enclosed in . -# -# Option key definition: -# Key: -# Option name. -# If: -# C preprocessor conditional for supporting this option. -# Type: (int|bool|enum|group|string|path|list) -# The option's data type. -# If the type is enum, the element definitions follow in the next lines: -# [/]: -# Default: -# Default value. string, path and list are copied verbatim and therefore -# must be already quoted appropriately. The other types are auto-quoted. -# If the default value is prefixed with a "*", a c #define def_ is -# created. -# The default is automatically appended to the tdmrc comment and the -# documentation entry. -# CDefault: -# Append this instead of the real default to the two docs. The quoting -# rules are the same as for Default. -# DDefault: - -# If specified, the default value will not be appended to the documentation -# entry. The Description should mention the default then. Use this when -# the default is system-dependent. -# PostProc: -# A function to postprocess the read config value before using it. -# User: (dummy|(core|greeter|greeter-c|dep|config)[()][:font]) -# These entries specify which parts of tdm need the option in question: -# dummy: no user; entry is there only for syntactical correctness. -# dep: this option is an internal dependency for another option. -# config: this option configures the config reader itself. -# core: the tdm backend needs this option. -# greeter-c: the tdm frontend needs this option as a C data type. -# greeter: the tdm frontend needs this option as a C++/Qt data type. -# If a :font tag is appended, a string entry is converted to a QFont. -# If no variable name is specified, it will be derived from the Key by -# un-capitalizing it. -# Instance: (-|[#][/](!|)) -# These entries specify option instances for the default/example tdmrc. -# A "-" entry is a dummy for syntactical correctness. -# A prefixing hash mark will be copied to tdmrc. -# For options in a section class a display must be specified. -# For bool options "!" can be used as the value to specify the negation -# of the default. -# Update: [/] -# Call this function on each occurence of this option in gentdmconf. -# Options with higher numbers (default is 0) will be processed later. -# Merge: (xdm[:][()]|tdm:[
/][][]) -# Specify config options to merge from xdm and older tdm versions. -# Kdm options from the current version are automatically merged. -# When merging an xdm resource and no resource name is specified, it is -# derived from the Key by un-capitalizing it. -# When merging a tdm option, at least one of
and must -# be given; an unspecified entity defaults to the current Section/Key. -#
may be a dash-prefixed section class. -# A function to postprocess the read value can be specified. -# Comment: [&|-] -# A tdmrc comment for this option is expected in the next lines. -# If "-" is given to Comment, no comment is generated at all. -# If "&" is given, the comment is derived from the Description below by -# applying some simple docbook interpretation to it. Note that the -# Description must be preformatted in this case. Use -# sed -ne 's/^\(.\{79,\}\)$/\1/p' < tdmrc -# after running "make install" to see whether all lines still fit. -# If Type is enum, a list of the previously defined element/description -# pairs is appended; the descriptions undergo docbook interpretation. -# Finally, a sentence with the Default (or CDefault, if given) is appended. -# Description: [!|-] -# A docbook description of this option is expected in the next lines. -# The contents are automatically enclosed in . -# If "-" is given to Description, no comment is generated at all. -# If "!" is given, enums are not treated specially; otherwise, the macro -# %ENUM% is replaced with a list of the defined element/description pairs, -# or - if the macro is not present - the list is appended to the -# description. -# Finally, a sentence with the Default (or CDefault, if given) is appended, -# unless "DDefault: -" was specified. -# Each option entry generates an anchor named option-; -# it can be referenced in the main documentation. -# Do not forget to run "make ref" in tdebase/doc/tdm after changing -# Descriptions. - -Section: General -Description: - This section contains global options that do not fit into any specific section. - -Key: ConfigVersion -Type: string -Default: "" -CDefault: - -User: dummy -# will be overwritten -Instance: -Comment: - This option exists solely for the purpose of a clean automatic upgrade. - Do not even think about changing it! -Description: - This option exists solely for the purpose of clean automatic upgrades. - Do not change it, you may interfere with future - upgrades and this could result in &tdm; failing to run. - -Key: PAMService -If: defined(USE_PAM) -Type: string -Default: TDM_PAM_SERVICE -User: core -Instance: - -Comment: - -Description: - - - -Proc: absorb_xservers -# note: this can miss Xservers from tdm for kde 2.2 because of stupid default. -Source: tdm:General/Xservers -Source: xdm:servers - - -Key: StaticServers -Type: list -Default: ":0" -User: core -Instance: ":0" -Comment: - List of permanent displays. Displays with a hostname are foreign. A display - class may be specified separated by an underscore. -Description: - List of displays (&X-Server;s) permanently managed by &tdm;. Displays with a - hostname are foreign displays which are expected to be already running, - the others are local displays for which &tdm; starts an own &X-Server;; - see . Each display may belong to a display class; - append it to the display name separated by an underscore. - See for the details. - -Key: ReserveServers -Type: list -Default: "" -User: core -Instance: ":1,:2,:3" -Comment: & -Description: - List of on-demand displays. See for syntax. - -Key: ServerVTs -If: defined(HAVE_VTS) -Type: list -Default: "" -User: core -Instance: #"7,8,-9,-10" -Update: upd_servervts -Comment: - VTs to allocate to &X-Server;s. A negative number means that the VT will be - used only if it is free. If all VTs in this list are used up, the next free - one greater than the last one in this list will be allocated. -Description: - List of Virtual Terminals to allocate to &X-Server;s. For negative numbers the - absolute value is used, and the VT will be allocated only - if the kernel says it is free. If &tdm; exhausts this list, it will allocate - free VTs greater than the absolute value of the last entry - in this list. - Currently Linux only. - -Key: ConsoleTTYs -If: defined(HAVE_VTS) -Type: list -Default: "" -User: core -Instance: #"tty1,tty2,tty3,tty4,tty5,tty6" -Update: upd_consolettys -Comment: - TTYs (without /dev/) to monitor for activity while in console mode. -Description: - This option is for operating systems (OSs) with support - for virtual terminals (VTs), by both &tdm; and the - OSs itself. - Currently this applies only to Linux. - - When &tdm; switches to console mode, it starts monitoring all - TTY lines listed here (without the leading - /dev/). - If none of them is active for some time, &tdm; switches back to the X login. - -Key: PidFile -Type: string -Default: "" -User: core -Instance: "/var/run/tdm.pid" -Merge: xdm -Comment: - Where &tdm; should store its PID (do not store if empty). -Description: - The filename specified will be created to contain an ASCII representation - of the process ID of the main &tdm; process; the PID will not be stored - if the filename is empty. - -Key: LockPidFile -Type: bool -Default: true -User: core -Instance: #! -Merge: xdm -Comment: - Whether &tdm; should lock the PID file to prevent having multiple &tdm; - instances running at once. Do not change unless you are brave. -Description: - This option controls whether &tdm; uses file locking to keep multiple - display managers from running onto each other. - -Key: AuthDir -Type: path -# differs from XDM -Default: "/var/run/xauth" -User: core -Instance: #"/tmp" -Merge: xdm(P_authDir) -Comment: - Where to store authorization files. -Description: - This names a directory under which &tdm; stores &X-Server; authorization - files while initializing the session. &tdm; expects the system to clean up - this directory from stale files on reboot. - - The authorization file to be used for a particular display can be - specified with the option in [X-*-Core]. - -Key: AutoRescan -Type: bool -Default: true -User: core -Instance: #! -Merge: xdm -Comment: - Whether &tdm; should automatically re-read configuration files, if it - finds them having changed. -Description: - This boolean controls whether &tdm; automatically re-reads its - configuration files if it finds them to have changed. - -Key: ExportList -Type: list -Default: "" -User: core -Instance: #"LD_LIBRARY_PATH,ANOTHER_IMPORTANT_VAR" -Merge: xdm(P_List) -Comment: & -Description: - Additional environment variables &tdm; should pass on to all programs it runs. - LD_LIBRARY_PATH and XCURSOR_THEME are good candidates; - otherwise, it should not be necessary very often. - -Key: RandomFile -If: !defined(ARC4_RANDOM) && !defined(DEV_RANDOM) -Type: string -Default: "/dev/mem" -User: core -Instance: #"" -Merge: xdm -Comment: - A file &tdm; should read entropy from. -Description: - If the system has no native entropy source like /dev/urandom (see - ) and no entropy daemon like EGD (see - and ) is running, - &tdm; will fall back to its own pseudo-random number generator - that will, among other things, successively checksum parts of this file - (which, obviously, should change frequently). - - This option does not exist on Linux and various BSDs. - -Key: PrngdSocket -If: !defined(ARC4_RANDOM) && !defined(DEV_RANDOM) -Type: string -# differs from xdm! -Default: "" -User: core -Instance: #"/tmp/entropy" -Merge: xdm -Comment: - A UNIX domain socket &tdm; should read entropy from. -Description: - If the system has no native entropy source like /dev/urandom (see - ), read random data from a Pseudo-Random - Number Generator Daemon, - like EGD (http://egd.sourceforge.net) via this UNIX domain socket. - - This option does not exist on Linux and various BSDs. - -Key: PrngdPort -If: !defined(ARC4_RANDOM) && !defined(DEV_RANDOM) -Type: int -Default: 0 -User: core -Instance: #4840 -Merge: xdm -Comment: - A TCP socket on localhost &tdm; should read entropy from. -Description: - Same as , only use a TCP socket on localhost. - -Key: RandomDevice -If: !defined(ARC4_RANDOM) -Type: string -Default: "" -User: core -Instance: #"/dev/altrandom" -Merge: xdm -Comment: - A character device &tdm; should read entropy from. - Empty means use the system's preferred entropy device. -Description: - The path to a character device which &tdm; should read random data from. - Empty means to use the system's preferred entropy device if there is one. - - This option does not exist on OpenBSD, as it uses the arc4_random - function instead. - -Key: FifoDir -Type: path -Default: *"/var/run/xdmctl" -User: core -Instance: #"/tmp" -Update: upd_fifodir -Comment: - Where the command FiFos should be created; make it empty to disable - them. -Description: - The directory in which the command FiFos should - be created; make it empty to disable them. -# See for the details. - -Key: FifoGroup -Type: group -Default: 0 -User: core -Instance: #xdmctl -Comment: & -Description: - The group to which the global command FiFo should belong; - can be either a name or a numerical ID. - -Key: DataDir -Type: path -Default: *"/var/lib/tdm" -User: greeter -Instance: #"" -Update: upd_datadir -Comment: - The directory in which &tdm; should store persistent working data. -Description: - The directory in which &tdm; should store persistent working data; such data - is, for example, the previous user that logged in on a particular display. - -Key: DmrcDir -Type: path -Default: "" -User: core -Instance: #"/nfs-shared/var/dmrcs" -Comment: & -Description: - The directory in which &tdm; should store users' .dmrc files. This is only - needed if the home directories are not readable before actually logging in - (like with AFS). - - -Section: Xdmcp -If: defined(XDMCP) -Description: - This section contains options that control &tdm;'s handling of - &XDMCP; requests. -# See to find out what &XDMCP; is. - -Key: Enable -Type: bool -Default: true -User: dep(xdmcpEnable) -Instance: false -Comment: & -Description: - Whether &tdm; should listen to incoming &XDMCP; requests. - -Key: Port -Type: int -Default: 177 -PostProc: PrequestPort -User: core(request_port) -Instance: # -Merge: xdm:requestPort(P_requestPort) -Comment: - The UDP port on which &tdm; should listen for &XDMCP; requests. Do not change. -Description: - This indicates the UDP port number which &tdm; uses to listen for incoming - &XDMCP; requests. Unless you need to debug the system, leave this with its - default value. - -Key: KeyFile -Type: string -Default: "" -User: core -Instance: #TDMCONF "/tdmkeys" -Update: cp_keyfile -Merge: xdm -Comment: - File with the private keys of X-terminals. Required for XDM authentication. -Description: - XDM-AUTHENTICATION-1 style &XDMCP; authentication requires a private - key to be shared between &tdm; and the terminal. This option specifies - the file containing those values. Each entry in the file consists of a - display name and the shared key. - -Key: Xaccess -Type: string -# differs from xdm -Default: *TDMCONF "/Xaccess" -User: config(Xaccess) -Instance: #"" -Update: mk_xaccess -Merge: xdm:accessFile -Comment: - &XDMCP; access control file in the usual XDM-Xaccess format. -Description: - To prevent unauthorized &XDMCP; service and to allow forwarding of &XDMCP; - IndirectQuery requests, this file contains a database of hostnames which - are either allowed direct access to this machine, or have a list of hosts - to which queries should be forwarded to. The format of this file is - described in . - -Key: ChoiceTimeout -Type: int -Default: 15 -User: core -Instance: #10 -Merge: xdm -Comment: - Number of seconds to wait for display to respond after the user has - selected a host from the chooser. -Description: - Number of seconds to wait for the display to respond after the user has - selected a host from the chooser. If the display sends an &XDMCP; - IndirectQuery within this time, the request is forwarded to the chosen - host; otherwise, it is assumed to be from a new session and the chooser - is offered again. - -Key: RemoveDomainname -Type: bool -Default: true -User: core -Instance: #! -Merge: xdm -Comment: - Strip domain name from remote display names if it is equal to the local - domain. -Description: - When computing the display name for &XDMCP; clients, the name resolver will - typically create a fully qualified host name for the terminal. As this is - sometimes confusing, &tdm; will remove the domain name portion of the host - name if it is the same as the domain name of the local host when this option - is enabled. - -Key: SourceAddress -Type: bool -Default: false -User: core -Instance: #! -Merge: xdm -Comment: - Use the numeric IP address of the incoming connection on multihomed hosts - instead of the host name. -Description: - Use the numeric IP address of the incoming connection on multihomed hosts - instead of the host name. This is to avoid trying to connect on the wrong - interface which might be down at this time. - -Key: Willing -Type: string -Default: "" -User: core -# will be overwritten -Instance: # -Update: mk_willing -Merge: xdm -Merge: tdm:Xwilling -Comment: - The program which is invoked to dynamically generate replies to &XDMCP; - DirectQuery or BroadcastQuery requests. - If empty, no program is invoked and "Willing to manage" is sent. -Description: - This specifies a program which is run (as - root) when an &XDMCP; - DirectQuery or BroadcastQuery is received and this host is configured - to offer &XDMCP; display management. The output of this program may be - displayed in a chooser window. If no program is specified, the string - Willing to manage is sent. - - -Section: Shutdown -Description: - This section contains global options concerning system shutdown. - -Key: HaltCmd -Type: string -Default: HALT_CMD -DDefault: - -User: core(cmdHalt) -Instance: #"" -Comment: - The command (subject to word splitting) to run to halt the system. -Description: - The command (subject to word splitting) to run to halt/poweroff the system. - - The default is something reasonable for the system on which &tdm; was built, like - /sbin/shutdown  now. - -Key: RebootCmd -Type: string -Default: REBOOT_CMD -DDefault: - -User: core(cmdReboot) -Instance: #"" -Comment: - The command (subject to word splitting) to run to reboot the system. -Description: - The command (subject to word splitting) to run to reboot the system. - - The default is something reasonable for the system &tdm; on which was built, like - /sbin/shutdown  now. - -Key: AllowFifo -Type: bool -Default: false -User: core(fifoAllowShutdown) -Instance: #! -Comment: & -Description: - Whether it is allowed to shut down the system via the global command FiFo. - -Key: AllowFifoNow -Type: bool -Default: true -User: core(fifoAllowNuke) -Instance: #! -Comment: - Whether it is allowed to abort active sessions when shutting down the - system via the global command FiFo. -Description: - Whether it is allowed to abort active sessions when shutting down the - system via the global command FiFo. - - This will have no effect unless is enabled. - -Key: BootManager -Type: enum - None/BO_NONE: no boot manager - Grub/BO_GRUB: Grub boot manager - Lilo/BO_LILO: Lilo boot manager (Linux on i386 & x86-64 only) -Default: None -User: core -User: greeter -Instance: #Grub -Merge: tdm:UseLilo(P_UseLilo) -Comment: & -Description: - The boot manager &tdm; should use for offering boot options in the - shutdown dialog. - - -Section: -Core -Description: - This section class contains options concerning the configuration - of the &tdm; backend (core). - -Key: OpenDelay -Type: int -Default: 15 -User: core -Instance: #*/ -Merge: xdm(P_openDelay) -Comment: - How long to wait before retrying to connect a display. -Description: - See . - -Key: OpenTimeout -Type: int -Default: 120 -User: core -Instance: #*/ -Merge: xdm -Comment: - How long to wait before timing out a display connection attempt. -Description: - See . - -Key: OpenRepeat -Type: int -Default: 5 -User: core -Instance: #*/ -Merge: xdm -Comment: - How many connection attempts to make during a start attempt. Note that - a timeout aborts the entire start attempt. -Description: - These options control the behavior of &tdm; when attempting to open a - connection to an &X-Server;. is the length - of the pause (in seconds) between successive attempts, - is the number of attempts to make and - is the amount of time to spend on a - connection attempt. After attempts have been - made, or if seconds elapse in any particular - connection attempt, the start attempt is considered failed. - -Key: StartAttempts -Type: int -Default: 4 -User: core -Instance: #*/ -Merge: xdm -Comment: - Try at most that many times to start a display. If this fails, the display - is disabled. -Description: - How many times &tdm; should attempt to start a foreign - display listed in before giving up - and disabling it. - Local displays are attempted only once, and &XDMCP; displays are retried - indefinitely by the client (unless the option - was given to the &X-Server;). - -Key: ServerAttempts -Type: int -Default: 1 -User: core -Instance: #:*/ -Merge: xdm -Comment: - How often to try to run the &X-Server;. Running includes executing it and - waiting for it to come up. -Description: - How many times &tdm; should attempt to start up a local &X-Server;. - Starting up includes executing it and waiting for it to come up. - -Key: ServerTimeout -Type: int -Default: 15 -User: core -Instance: #:*/ -Comment: - How long to wait for a local &X-Server; to come up. -Description: - How many seconds &tdm; should wait for a local &X-Server; to come up. - -Key: ServerCmd -Type: string -Default: DEF_SERVER_CMD -DDefault: - -User: core -Instance: :*/DEF_SERVER_CMD -Comment: - The command line to start the &X-Server;, without display number and VT spec. - This string is subject to word splitting. -Description: - The command line to start the &X-Server;, without display number and VT spec. - This string is subject to word splitting. - - The default is something reasonable for the system on which &tdm; was built, - like /usr/bin/X. - -Key: ServerArgsLocal -Type: string -Default: "" -User: core -Instance: :*/"-nolisten tcp" -Comment: & -Description: - Additional arguments for the &X-Server;s for local sessions. - This string is subject to word splitting. - -Key: ServerArgsRemote -Type: string -Default: "" -User: core -Instance: #:*/"" -Comment: & -Description: - Additional arguments for the &X-Server;s for remote sessions. - This string is subject to word splitting. - -Key: ServerVT -If: defined(HAVE_VTS) -Type: int -Default: 0 -User: core(reqSrvVT) -Instance: #:0/7 -Comment: - The VT the &X-Server; should run on; auto-assign if zero, don't assign if -1. - Better leave it zero and use ServerVTs. -Description: - The VT the &X-Server; should run on. - should be used instead of this option. - Leave it zero to let &tdm; assign a VT automatically. - Set it to -1 to avoid assigning a VT - alltogether - this is required for setups with multiple physical consoles. - Currently Linux only. - -Key: ServerTTY -If: !defined(HAVE_VTS) -Type: string -Default: "" -User: core(console) -Instance: :0/DEF_SERVER_TTY -Comment: - The TTY line (without /dev/) the &X-Server; covers physically. -Description: - This option is for OSs without support for - VTs, either by &tdm; or the OS itself. - Currently this applies to all OSs but Linux. - - When &tdm; switches to console mode, it starts monitoring this - TTY line (specified without the leading - /dev/) for activity. If the line is not used for some time, - &tdm; switches back to the X login. - -Key: PingInterval -Type: int -Default: 5 -User: core -User: greeter -Instance: #*/ -Merge: xdm -Comment: - Ping remote display every that many minutes. -Description: - See . - -Key: PingTimeout -Type: int -Default: 5 -User: core -User: greeter -Instance: #*/ -Merge: xdm -Comment: - Wait for a Pong that many minutes. -Description: - To discover when remote displays disappear, &tdm; - regularly pings them. - specifies the time (in minutes) between the - pings and specifies the maximum amount of - time (in minutes) to wait for the terminal to respond to the request. If - the terminal does not respond, the session is declared dead and terminated. - - If you frequently use X terminals which can become isolated from - the managing host, you may wish to increase the timeout. The only worry - is that sessions will continue to exist after the terminal has been - accidentally disabled. - -Key: TerminateServer -Type: bool -Default: false -User: core -Instance: #:*/! -Merge: xdm -Comment: - Restart instead of resetting the local &X-Server; after session exit. - Use it if the server leaks memory etc. -Description: - Whether &tdm; should restart the local &X-Server; after session exit instead - of resetting it. Use this if the &X-Server; leaks memory or crashes the system - on reset attempts. - -Key: ResetSignal -Type: int -Default: 1 -CDefault: 1 (SIGHUP) -User: core -Instance: #:*/ -Merge: xdm -Comment: - The signal needed to reset the local &X-Server;. -Description: - The signal number to use to reset the local &X-Server;. - -Key: TermSignal -Type: int -Default: 15 -CDefault: 15 (SIGTERM) -User: core -Instance: #:*/ -Merge: xdm -Comment: - The signal needed to terminate the local &X-Server;. -Description: - The signal number to use to terminate the local &X-Server;. - -Key: Authorize -Type: bool -Default: true -User: core -Instance: #:*/! -Merge: xdm -Comment: - Create X-authorizations for local displays. -Description: - Controls whether &tdm; generates and uses authorization for - local &X-Server; connections. - For &XDMCP; displays the authorization requested by the display is used; - foreign non-&XDMCP; displays do not support authorization at all. - -Key: AuthNames -Type: list -Default: DEF_AUTH_NAME -User: core -Instance: #:*/"" -Merge: xdm:authName -Comment: - Which X-authorization mechanisms should be used. -Description: - If is true, use the authorization mechanisms - listed herein. The MIT-MAGIC-COOKIE-1 authorization is always available; - XDM-AUTHORIZATION-1, SUN-DES-1 and MIT-KERBEROS-5 might be available as well, - depending on the build configuration. - -Key: ResetForAuth -Type: bool -Default: false -User: core -Instance: #:*/! -Merge: xdm -Comment: - Need to reset the &X-Server; to make it read initial Xauth file. -Description: - Some old &X-Server;s re-read the authorization file - at &X-Server; reset time, instead of when checking the initial connection. - As &tdm; generates the authorization information just before connecting to - the display, an old &X-Server; would not get up-to-date authorization - information. This option causes &tdm; to send SIGHUP to the &X-Server; - after setting up the file, causing an additional &X-Server; reset to occur, - during which time the new authorization information will be read. - -Key: AuthFile -Type: string -Default: "" -User: core(clientAuthFile) -Instance: #*/"" -Merge: xdm -Comment: - The name of this &X-Server;'s Xauth file. - If empty, a random name in the AuthDir directory will be used. -Description: - This file is used to communicate the authorization data from &tdm; to - the &X-Server;, using the &X-Server; command line - option. It should be kept in a directory which is not world-writable - as it could easily be removed, disabling the authorization mechanism in - the &X-Server;. If not specified, a random name is generated from - and the name of the display. - -Key: Resources -# XXX strictly speaking this is supposed to be a string list, i think. -Type: string -Default: "" -User: core -Instance: #*/"" -Update: cp_resources -Merge: xdm -Comment: - Specify a file with X-resources for the greeter, chooser and background. - The KDE frontend does not use this file, so you do not need it unless you - use another background generator than krootimage. -Description: - This option specifies the name of the file to be loaded by - xrdb as the resource database onto the root window - of screen 0 of the display. KDE programs generally do not use - X-resources, so this option is only needed if the - program needs some X-resources. - -Key: Xrdb -Type: string -Default: XBINDIR "/xrdb" -User: core -Instance: #*/"" -Merge: xdm -Comment: - The xrdb program to use to read the above specified recources. - Subject to word splitting. -Description: - The xrdb program to use to read the X-resources file - specified in . - The command is subject to word splitting. - -Key: Setup -Type: string -Default: "" -User: core -# will be overwritten -Instance: #*/"" -Update: mk_setup -Merge: xdm -Comment: - A program to run before the greeter is shown. Can be used to start an - xconsole or an alternative background generator. Subject to word splitting. -Description: - This string is subject to word splitting. - It specifies a program which is run (as - root) before offering the - greeter window. This may be used to change the appearance of the screen - around the greeter window or to put up other windows (e.g., you may want - to run xconsole here). - The conventional name for a file used here is Xsetup. - See . - -Key: Startup -Type: string -Default: "" -User: core -# will be overwritten -Instance: #*/"" -Update: mk_startup -Merge: xdm -Comment: - A program to run before a user session starts. Subject to word splitting. -Description: - This string is subject to word splitting. - It specifies a program which is run (as - root) after the user - authentication process succeeds. - The conventional name for a file used here is Xstartup. - See . - -Key: Reset -Type: string -Default: "" -User: core -# will be overwritten -Instance: #*/"" -Update: mk_reset -Merge: xdm -Comment: - A program to run after a user session exits. Subject to word splitting. -Description: - This string is subject to word splitting. - It specifies a program which is run (as - root) after the session - terminates. - The conventional name for a file used here is Xreset. - See . - -Key: Session -Type: string -Default: XBINDIR "/xterm -ls -T" -#Merge: xdm - incompatible! -User: core -# will be overwritten -Instance: #*/"" -Update: mk_session -Comment: - The program which is run as the user which logs in. It is supposed to - interpret the session argument (see SessionsDirs) and start an appropriate - session according to it. Subject to word splitting. -Description: - This string is subject to word splitting. - It specifies the session program to be executed (as the user owning - the session). - The conventional name for a file used here is Xsession. - See . - -Key: FailsafeClient -Type: string -Default: XBINDIR "/xterm" -User: core -Instance: #*/"" -Merge: xdm -Comment: - The program to run if Session fails. -Description: - If the program fails to execute, &tdm; will - fall back to this program. This program is executed with no arguments, - but executes using the same environment variables as the session would - have had (see ). - -Key: UserPath -Type: string -Default: DEF_USER_PATH -DDefault: - -User: core -Instance: #*/"" -Merge: xdm -Comment: - The PATH for the Session program. -Description: - The PATH environment variable for - non-root s. - - The default depends on the system &tdm; was built on. - -Key: SystemPath -Type: string -Default: DEF_SYSTEM_PATH -DDefault: - -User: core -Instance: #*/"" -Merge: xdm -Comment: - The PATH for Setup, Startup and Reset, etc. -Description: - The PATH environment variable for all programs but - non-root - s. Note that it is good practice not to include - . (the current directory) into this entry. - - The default depends on the system &tdm; was built on. - -Key: SystemShell -Type: string -Default: "/bin/sh" -User: core -Instance: #*/"/bin/bash" -Merge: xdm -Comment: - The default system shell. -Description: - The SHELL environment variable for all programs but the - . - -Key: UserAuthDir -Type: path -Default: "/tmp" -User: core -Instance: #*/"" -Merge: xdm -Comment: - Where to put the user's &X-Server; authorization file if ~/.Xauthority - cannot be created. -Description: - When &tdm; is unable to write to the usual user authorization file - ($HOME/.Xauthority), it creates a unique file name in this - directory and points the environment variable XAUTHORITY - at the created file. - -Key: AutoReLogin -Type: bool -Default: false -User: core -Instance: #*/! -Merge: xdm -Comment: - Whether to automatically restart sessions after &X-Server; crashes. - Note that enabling this makes circumventing screen lockers other than - KDE's built-in one possible! -Description: - If enabled, &tdm; will automatically restart a session after an &X-Server; - crash (or if it is killed by Alt-Ctrl-BackSpace). Note that enabling this - feature opens a security hole: a secured display lock can be circumvented - (unless &kde;'s built-in screen locker is used). - -Key: AllowRootLogin -Type: bool -Default: true -User: core -User: greeter(showRoot) -Instance: */false -Merge: xdm -Comment: - Allow root logins? -Description: - If disabled, do not allow root - (and any other user with UID = 0) to log in directly. - -Key: AllowNullPasswd -Type: bool -Default: true -User: core -# sensible? -Instance: */false -Instance: :*/true -Merge: xdm -Comment: - Allow to log in, when user has set an empty password? -Description: - If disabled, only users that have passwords assigned can log in. - -Key: AllowShutdown -Type: enum - None/SHUT_NONE: no Shutdown... menu entry is shown at all - Root/SHUT_ROOT: the root password must be entered to shut down - All/SHUT_ALL: everybody can shut down the machine -Default: All -User: core -User: greeter -Instance: */Root -Instance: :*/All -Merge: tdm:-Greeter/ -Comment: & -Description: - Who is allowed to shut down the system. This applies both to the - greeter and to the command FiFo. - -Key: AllowSdForceNow -Type: enum - None: no forced shutdown is allowed at all - Root: the root password must be entered to shut down forcibly - All: everybody can shut down the machine forcibly -Default: All -User: core(allowNuke) -User: greeter(allowNuke) -Instance: #*/Root -Comment: & -Description: - Who is allowed to abort active sessions when shutting down. - -Key: DefaultSdMode -Type: enum - Schedule: shut down after all active sessions exit (possibly at once) - TryNow: shut down, if no active sessions are open; otherwise, do nothing - ForceNow: shut down unconditionally -Default: Schedule -User: core(defSdMode) -User: greeter(defSdMode) -Instance: #*/ForceNow -Comment: & -Description: - The default choice for the shutdown condition/timing. - -Key: ScheduledSd -Type: enum - Never/SHUT_NEVER: not at all - Optional/SHUT_OPTION: as a button in the simple shutdown dialogs - Always/SHUT_ALWAYS: instead of the simple shutdown dialogs -Default: Never -User: greeter -Instance: #*/Optional -Comment: & -Description: - How to offer shutdown scheduling options: - -Key: NoPassEnable -Type: bool -Default: false -User: dep -Instance: #:*/true -Comment: & -Description: - Enable password-less logins on this display. Use with extreme care! - -Key: NoPassUsers -Type: list -Default: "" -PostProc: PnoPassUsers -User: core -Instance: #:*/"fred,ethel" -Merge: xdm(P_noPassUsers) -Comment: - The users that do not need to provide a password to log in. NEVER list root! - "*" means all non-root users. @ means all users in that group. -Description: - The users that do not need to provide a password to log in. - Items which are prefixed with @ represent all users in the - user group named by that item. - * means all users but - root - (and any other user with UID = 0). - Never list root. - -Key: AutoLoginEnable -Type: bool -Default: false -User: dep -Instance: #:0/true -Comment: & -Description: - Enable automatic login. Use with extreme care! - -Key: AutoLoginAgain -Type: bool -Default: false -User: core(autoAgain) -User: greeter -Instance: #:0/true -Comment: & -Description: - If true, auto-login after logout. If false, auto-login is performed only - when a display session starts up. - -Key: AutoLoginDelay -Type: int -Default: 0 -User: core(autoDelay) -User: greeter -Instance: #:0/10 -Comment: - The delay in seconds before automatic login kicks in. -Description: - The delay in seconds before automatic login kicks in. This is also known as - Timed Login. - -Key: AutoLoginUser -Type: string -Default: "" -PostProc: PautoLoginX -User: core(autoUser) -User: greeter -Instance: #:0/"fred" -Merge: xdm:autoUser(P_autoUser) -Comment: & -Description: - The user to log in automatically. Never specify root! - -Key: AutoLoginPass -Type: string -Default: "" -PostProc: PautoLoginX -User: core(autoPass) -Instance: #:0/"secret!" -Merge: xdm:autoPass(P_autoPass) -Comment: & -Description: - The password for the user to log in automatically. This is not required - unless the user is logged into a NIS or Kerberos domain. If you use this - option, you should chmod  tdmrc for obvious reasons. - -Key: AutoLoginLocked -Type: bool -Default: false -User: core(autoLock) -Instance: #:0/! -Comment: & -Description: - Immediately lock the automatically started session. This works only with - KDE sessions. - -Key: SessionsDirs -Type: list -Default: "/usr/share/xsessions,/var/lib/menu-xdg/xsessions,/usr/share/apps/tdm/sessions" -User: core -User: greeter-c -Instance: #*/"/usr/share/xsessions,/var/lib/menu-xdg/xsessions,/usr/share/apps/tdm/sessions" -Comment: - The directories containing session type definitions in .desktop format. -Description: - A list of directories containing session type definitions. -# See for details. - -Key: ClientLogFile -Type: string -Default: ".xsession-errors" -User: core -Instance: */".xsession-errors-%s" -Instance: :0/".xsession-errors" -Comment: - The file (relative to $HOME) to redirect the session output to. This is - a printf format string; one %s will be replaced with the display name. -Description: - The file (relative to the user's home directory) to redirect the session - output to. One occurrence of %s in this string will be - substituted with the display name. Use %% to obtain a - literal %. - -Key: UseSessReg -Type: bool -Default: false -User: core -Instance: #*/! -Comment: - Whether &tdm;'s built-in utmp/wtmp/lastlog registration should be used. -Description: - Specify whether &tdm;'s built-in utmp/wtmp/lastlog registration should - be used. If it is not, the tool sessreg should be used - in the and scripts, or, - alternatively, the pam_lastlog module should be used on - PAM-enabled systems. - - -Section: -Greeter -Description: - This section class contains options concerning the configuration - of the &tdm; frontend (greeter). - -Key: GUIStyle -Type: string -Default: "" -User: greeter -Instance: #*/"Windows" -Update: upd_guistyle -Comment: - Widget style of the greeter. "" means the built-in default which currently - is "Plastik". -Description: - Specify the widget style for the greeter. Empty means to use the - built-in default which currently is Plastik. - -Key: Compositor -Type: string -Default: "" -User: greeter -Instance: #*/"" -Comment: - Compositor binary name, if compositing is desired. "" means no compositing support. -Description: - Specify the Xorg compositing manager. Currently only kompmgr is supported. - -Key: WindowManager -Type: string -Default: "twin" -User: greeter -Instance: #*/"" -Comment: - Window manager binary name, if window decorations are desired. "" means no window manager support. -Description: - Specify the Xorg window manager. Currently only twin is supported. - -Key: UseSAK -Type: bool -Default: true -User: greeter -Instance: #*/! -Comment: - SAK -Description: - If true then the SAK anti-spoofing dialog will be utilized - -Key: UseAdminSession -Type: bool -Default: false -User: greeter -Instance: #*/! -Comment: - Admin session -Description: - If given there will be a special button that requires root password - and starts the given session - -Key: ColorScheme -Type: string -Default: "" -User: greeter -Instance: #*/"Pumpkin" -Comment: - Widget color scheme of the greeter. "" means the built-in default which - currently is yellowish grey with some light blue and yellow elements. -Description: - Specify the widget color scheme for the greeter. Empty means to use - the built-in default which currently is yellowish grey with some light - blue and yellow elements. - -Key: LogoArea -Type: enum - None/LOGO_NONE: nothing - Logo/LOGO_LOGO: the image specified by - Clock/LOGO_CLOCK: a neat analog clock -Default: Clock -User: greeter -Instance: */Logo -Comment: - What should be shown in the greeter's logo are: -Description: - What should be shown in the greeter righthand of the input lines (if - is disabled) or above them (if - is enabled): - -Key: LogoPixmap -Type: string -Default: "" -User: greeter(logo) -Instance: */TDMDATA "/pics/kdelogo.png" -Comment: - The image to show when LogoArea=Logo. -Description: - The image to show in the greeter if is - Logo. - -Key: GreeterPos -Type: string -Default: "50,50" -User: greeter-c -Instance: #*/"30,40" -Comment: - The relative coordinates (X,Y in percent) of the center of the greeter. -Description: - The relative coordinates (percentages of the screen size; X,Y) at which - the center of the greeter is put. &tdm; aligns the greeter to the edges - of the screen it would cross otherwise. - -Key: GreeterScreen -Type: int -Default: 0 -User: greeter -Instance: #*/-1 -Comment: & -Description: - The screen the greeter should be displayed on in multi-headed and Xinerama - setups. The numbering starts with 0. For Xinerama, it corresponds to the - listing order in the active ServerLayout section of XF86Config; -1 means - to use the upper-left screen, -2 means to use the upper-right screen. - -Key: GreetString -Type: string -Default: "Welcome to Trinity at %n" -User: greeter -Instance: #*/"Welcome to Trinity at %n" -Comment: - The headline in the greeter. The following character pairs are replaced: - - %d -> current display - - %h -> host name, possibly with domain name - - %n -> node name, most probably the host name without domain name - - %s -> the operating system - - %r -> the operating system's version - - %m -> the machine (hardware) type - - %% -> a single % -Description: - The headline in the greeter. An empty greeting means none at all. - - The following character pairs are replaced by their value: - - - %d - name of the current display - - - %h - local host name, possibly with the - domain name - - - %n - local node name, most probably the host name without the - domain name - - - %s - operating system - - - %r - operating system version - - - %m - machine (hardware) type - - - %% - a single % - - - -# This needs to come _in front_ of the font settings to be effective! -Key: AntiAliasing -Type: bool -Default: true -User: greeter -Instance: */ -Comment: & -Description: - Whether the fonts used in the greeter should be antialiased. - -Key: GreetFont -Type: string -Default: "Sans Serif,22,5,0,50,0" -CDefault: "Serif,20,bold" -User: greeter:font -Instance: #*/"Sans Serif,22,5,0,50,0" -Comment: & -Description: - The font for the greeter headline. - -Key: StdFont -Type: string -Default: "Sans Serif,10,5,0,50,0" -CDefault: "Sans Serif,10" -User: greeter(normalFont):font -Instance: #*/"Sans Serif,10,5,0,50,0" -Comment: & -Description: - The normal font used in the greeter. - -Key: FailFont -Type: string -Default: "Sans Serif,10,5,0,75,0" -CDefault: "Sans Serif,10,bold" -User: greeter:font -Instance: #*/"Sans Serif,10,5,0,75,0" -Comment: & -Description: - The font used for the Login Failed message. - -Key: NumLock -Type: enum - Off: turn off - On: turn on - Keep: do not change the state -Default: Keep -User: greeter(numLockStatus) -Instance: #*/Off -Comment: & -Description: - What to do with the Num Lock modifier for the time the greeter is running: - -Key: Language -Type: string -Default: "en_US" -User: greeter-c -Instance: #*/"de_DE" -Update: upd_language -Comment: & -Description: - Language and locale to use in the greeter, encoded like $LC_LANG. - -Key: UserCompletion -Type: bool -Default: false -User: greeter -Instance: #*/! -Comment: & -Description: - Enable autocompletion in the username line edit. - -Key: UserList -Type: bool -Default: true -User: greeter -Instance: #*/! -Comment: - Enable user list (names along with images) in the greeter. -Description: - Show a user list with unix login names, real names, and images in the greeter. - -Key: ShowUsers -Type: enum - NotHidden/SHOW_ALL: all users except those listed in HiddenUsers - Selected/SHOW_SEL: only the users listed in SelectedUsers -Default: NotHidden -User: greeter -Instance: #*/Selected -Update: upd_showusers -Comment: - User selection for UserCompletion and UserList: -Description: ! - This option controls which users will be shown in the user view - () and/or offered for autocompletion - (). - If it is Selected, contains - the final list of users. - If it is NotHidden, the initial user list are all users - found on the system. Users contained in are - removed from the list, just like all users with a UID greater than specified - in and users with a non-zero UID less than - specified in . - Items in and - which are prefixed with @ represent all users in the - user group named by that item. - Finally, the user list will be sorted alphabetically, if - is enabled. - -Key: SelectedUsers -Type: list -Default: "" -User: greeter-c(users) -Instance: #*/"root,johndoe" -Merge: tdm:Users -Comment: - For ShowUsers=Selected. @ means all users in that group. -Description: - See . - -Key: HiddenUsers -Type: list -Default: "" -User: greeter-c(noUsers) -Instance: #*/"root" -# depends on {Min,Max}ShowUID -Update: upd_hiddenusers/1 -Merge: tdm:NoUsers -Comment: - For ShowUsers=NotHidden. @ means all users in that group. -Description: - See . - -Key: MinShowUID -Type: int -Default: 0 -User: greeter(lowUserId) -# will be overwritten -Instance: #*/ -Update: upd_minshowuid -Comment: - Special case of HiddenUsers: users with a non-zero UID less than this number - will not be shown as well. -Description: - See . - -Key: MaxShowUID -Type: int -Default: 65535 -User: greeter(highUserId) -# will be overwritten -Instance: #*/ -Update: upd_maxshowuid -Comment: - Complement to MinShowUID: users with a UID greater than this number will - not be shown as well. -Description: - See . - -Key: SortUsers -Type: bool -Default: true -User: greeter -Instance: #*/! -Comment: - If false, the users are listed in the order they appear in /etc/passwd. - If true, they are sorted alphabetically. -Description: - See . - -Key: FaceSource -Type: enum - AdminOnly/FACE_ADMIN_ONLY: from <>/$USER.face[.icon] - PreferAdmin/FACE_PREFER_ADMIN: prefer <>, fallback on $HOME - PreferUser/FACE_PREFER_USER: ... and the other way round - UserOnly/FACE_USER_ONLY: from the user's $HOME/.face[.icon] -Default: AdminOnly -User: greeter -Instance: #*/PreferUser -Comment: - Specify, where the users' pictures should be taken from. -Description: - If is enabled, this specifies where &tdm; gets the - images from: - - %ENUM% - - The images can be in any format Qt recognizes, but the filename - must match &tdm;'s expectations: .face.icon should be a - 48x48 icon, while .face should be a 300x300 image. - Currently the big image is used only as a fallback and is scaled down, - but in the future it might be displayed full-size in the logo area or a - tooltip. - -Key: FaceDir -Type: string -Default: *TDMDATA "/faces" -User: greeter -Instance: #*/"/usr/share/faces" -Update: upd_facedir -Comment: - The directory containing the user images if FaceSource is not UserOnly. -Description: - See . - -Key: PreselectUser -Type: enum - None/PRESEL_NONE: do not preselect any user - Previous/PRESEL_PREV: the user which successfully logged in last time - Default/PRESEL_DEFAULT: the user specified in the option -Default: None -User: greeter(preselUser) -Instance: #*/Previous -Instance: :*/Previous -Instance: #:0/Default -Comment: - Specify, if/which user should be preselected for log in. -Description: - Specify, if/which user should be preselected for log in: - - %ENUM% - - If is enabled and a user was preselected, - the cursor is placed in the password input field automatically. - - Enabling user preselection can be considered a security hole, - as it presents a valid login name to a potential attacker, so he - only needs to guess the password. On the other hand, - one could set to a fake login name. - - -Key: DefaultUser -Type: string -Default: "" -User: greeter -Instance: #:0/"johndoe" -Comment: - The user to preselect if PreselectUser=Default. -Description: - See . - -Key: FocusPasswd -Type: bool -Default: false -User: greeter -Instance: #*/! -Instance: :*/true -Comment: - If this is true, the password input line is focused automatically if - a user is preselected. -Description: - See . - -Key: EchoMode -Type: enum - OneStar: * is shown for every typed letter - ThreeStars: *** is shown for every typed letter - NoEcho: nothing is shown at all, the cursor does not move -# HACK! This must be in sync with KPasswordEdit::EchoModes (kpassdlg.h) -Default: OneStar -User: greeter -Instance: #*/NoEcho -Comment: & -Description: - The password input fields cloak the typed in text. Specify, how to do it: - -Key: UseBackground -Type: bool -Default: true -User: greeter -Instance: #*/! -Comment: - If true, krootimage will be automatically started by &tdm;; otherwise, the - Setup script should be used to setup the background. -Description: - If enabled, &tdm; will automatically start the krootimage - program to set up the background; otherwise, the - program is responsible for the background. - -Key: BackgroundCfg -Type: string -Default: *TDMCONF "/backgroundrc" -User: greeter-c -Instance: #*/"" -Update: handBgCfg -Comment: - The configuration file to be used by krootimage. -Description: - The configuration file to be used by krootimage. - It contains a section named [Desktop0] like - kdesktoprc does. Its options are not described - herein; guess their meanings or use the control center. - -Key: GrabServer -Type: bool -Default: false -User: greeter-c -Instance: #*/! -Comment: - Hold the &X-Server; grabbed the whole time the greeter is visible. This - may be more secure, but it will disable any background and other - X-clients started from the Setup script. -Description: - To improve security, the greeter grabs the &X-Server; and then the keyboard - when it starts up. This option specifies if the &X-Server; grab should be held - for the duration of the name/password reading. When disabled, the &X-Server; - is ungrabbed after the keyboard grab succeeds; otherwise, the &X-Server; is - grabbed until just before the session begins. - - Enabling this option disables and - . - - -Key: GrabTimeout -Type: int -Default: 3 -User: greeter -Instance: #*/ -Comment: - How many seconds to wait for grab to succeed. -Description: - This option specifies the maximum time &tdm; will wait for the grabs to - succeed. A grab may fail if some other X-client has the &X-Server; or the - keyboard grabbed, or possibly if the network latencies are very high. You - should be cautious when raising the timeout, as a user can be spoofed by - a look-alike window on the display. If a grab fails, &tdm; kills and - restarts the &X-Server; (if possible) and the session. - -Key: AuthComplain -Type: bool -Default: true -User: greeter -Instance: #*/! -Merge: xdm -Comment: - Warn, if display has no X-authorization (local auth cannot be created, - &XDMCP; display wants no auth, or display is foreign from StaticServers). -Description: - Warn, if a display has no X-authorization. This will be the case if - - - the authorization file for a local &X-Server; could not be created, - - - a remote display from &XDMCP; did not request any authorization or - - - the display is a foreign display specified in - . - - - -Key: LoginMode -If: defined(XDMCP) -Type: enum - LocalOnly/LOGIN_LOCAL_ONLY: only local login possible - DefaultLocal/LOGIN_DEFAULT_LOCAL: start up in local mode, but allow switching to remote mode - DefaultRemote/LOGIN_DEFAULT_REMOTE: ... and the other way round - RemoteOnly/LOGIN_REMOTE_ONLY: only choice of remote host possible -Default: LocalOnly -User: core -User: greeter -Instance: :*/DefaultLocal -# from make_it_cool branch and SuSE 8.1 -Merge: tdm:EnableChooser(P_EnableChooser) -Comment: & -Description: - Specify whether the greeter of local displays should start up in host chooser - (remote) or login (local) mode and whether it is allowed to switch to the - other mode. - -Key: ChooserHosts -If: defined(XDMCP) -Type: list -Default: "*" -User: core -Instance: #:*/"*,ugly,sky,dino,kiste.local,login.crap.com" -Comment: - A list of hosts to be automatically added to the remote login menu. The - special name "*" means broadcast. -Description: - A list of hosts to be automatically added to the remote login menu. - The special name * means broadcast. - Has no effect if is LocalOnly. - -Key: ForgingSeed -Type: int -Default: 0 -User: greeter -Instance: #*/ -Comment: - Random seed for forging saved session types, etc. of unknown users. - This value should be random but constant across the login domain. -Description: - Use this number as a random seed when forging saved session types, etc. of - unknown users. This is used to avoid telling an attacker about existing users - by reverse conclusion. This value should be random but constant across the - login domain. - -Key: ShowLog -If: defined(WITH_TDM_XCONSOLE) -Type: bool -Default: false -User: greeter -Instance: :0/true -Comment: - Enable &tdm;'s built-in xconsole. Note that this can be enabled for only - one display at a time. -Description: - Enable &tdm;'s built-in xconsole. - Note that this can be enabled for only one display at a time. - This option is available only if &tdm; was configured - with . - -Key: LogSource -If: defined(WITH_TDM_XCONSOLE) -Type: string -Default: "" -User: greeter-c -Instance: :0/"/dev/xconsole" -Comment: - The data source for &tdm;'s built-in xconsole. - If empty, a console log redirection is requested from /dev/console. -Description: - The data source for &tdm;'s built-in xconsole. - If empty, a console log redirection is requested from - /dev/console. - Has no effect if is disabled. - -Key: PluginsLogin -Type: list -Default: "classic" -User: greeter -Instance: #*/"sign" -Comment: - Specify conversation plugins for the login dialog. Each plugin can be - specified as a base name (which expands to $kde_modulesdir/kgreet_$base) - or as a full pathname. -Description: - Specify conversation plugins for the login dialog; the first in the list - is selected initially. - Each plugin can be specified as a base name (which expands to - $kde_modulesdir/kgreet_base) - or as a full pathname. - - Conversation plugins are modules for the greeter which obtain authentication - data from the user. Currently only the classic plugin is - shipped with &kde;; it presents the well-known username and password form. - -Key: PluginsShutdown -Type: list -Default: "classic" -User: greeter -Instance: #*/"modern" -Comment: & -Description: - Same as , but for the shutdown dialog. - -Key: PluginOptions -Type: list -Default: "" -User: greeter -Instance: #*/"SomeKey=randomvalue,Foo=bar" -Comment: - A list of options of the form Key=Value. The conversation plugins can query - these settings; it is up to them what possible keys are. -Description: - A list of options of the form - Key=Value. - The conversation plugins can query these settings; it is up to them what - possible keys are. - -Key: AllowConsole -Type: bool -Default: true -User: greeter(hasConsole) -Instance: #*/! -Comment: & -Description: - Show the Console Login action in the greeter (if / - is configured). - -Key: AllowClose -Type: bool -Default: true -User: greeter -Instance: :*/true -Comment: & -Description: - Show the Restart X Server/Close Connection action in the greeter. - -Key: Preloader -Type: string -Default: "" -User: greeter-c -Instance: */KDE_BINDIR "/preloadkde" -Comment: & -Description: - A program to run while the greeter is visible. It is supposed to preload - as much as possible of the session that is going to be started (most - probably). - -Key: UseTheme -Type: bool -Default: true -User: greeter -Instance: */true -Comment: & -Description: - Whether the greeter should be themed. - -Key: Theme -Type: string -Default: TDMDATA "/themes/o2_enterprise" -User: greeter -Instance: */TDMDATA "/themes/o2_enterprise" -Comment: & -Description: - The theme to use for the greeter. Can point to either a directory or an XML - file. diff --git a/kdm/configure.in.bot b/kdm/configure.in.bot deleted file mode 100644 index a0d238b29..000000000 --- a/kdm/configure.in.bot +++ /dev/null @@ -1,8 +0,0 @@ -if $tdm_no_Xau; then - AC_MSG_WARN([Cannot build TDM! Make sure that libXau.a is installed!]) -fi -if $tdm_no_Xdmcp; then - AC_MSG_WARN([Cannot build TDM! Make sure that libXdmcp.a and Xdmcp.h -are installed or use --without-xdmcp to disable XDMCP support!]) -fi - diff --git a/kdm/configure.in.in b/kdm/configure.in.in deleted file mode 100644 index 5422e5a99..000000000 --- a/kdm/configure.in.in +++ /dev/null @@ -1,361 +0,0 @@ -KDE_FIND_PATH(xmkmf, XMKMF, [], [AC_MSG_ERROR([xmkmf/imake not found. Please make sure it's in PATH!])]) - -dnl ask imake about various X settings -AC_MSG_CHECKING([X paths]) -imkv=8 -test "$kde_cv_defines_imake_version" = $imkv || unset kde_cv_defines_imake -AC_CACHE_VAL(kde_cv_defines_imake, [ - rm -fr conftestdir - if mkdir conftestdir; then - cd conftestdir - cat > Imakefile <<'EOF'[ - -acimake: - @echo "XBINDIR=\"/usr/bin\" XLIBDIR=\"$(LIBDIR)\"" - -]EOF - if imake -I/usr/lib/X11/config -DTOPDIR=/etc/X11 -DCURDIR=. /etc/X11 >&5 2>&1 && test -f Makefile; then - kde_cv_defines_imake=`${MAKE-make} acimake 2> /dev/null | grep -v "^make"` - kde_cv_defines_imake_version=$imkv - else - AC_MSG_RESULT([failed]) - AC_MSG_ERROR([$XMKMF (imake) failed. -Make sure you have all necessary X development packages installed. -On some systems a missing /lib/cpp symlink is at fault.]) - fi - cd .. - rm -fr conftestdir - else - AC_MSG_RESULT([failed]) - AC_MSG_ERROR([cannot create temporary directory]) - fi -]) -AC_MSG_RESULT([done]) -eval "$kde_cv_defines_imake" -AC_DEFINE_UNQUOTED(XBINDIR, "$XBINDIR", [X binaries directory]) -AC_DEFINE_UNQUOTED(XLIBDIR, "$XLIBDIR", [X libraries directory]) - -if test -f /etc/ttys; then - AC_DEFINE(BSD_INIT, 1, [Define if the system uses a BSD-style init]) -fi - -AC_CHECK_FUNCS([getttyent]) -case $host_os in - linux*) ac_cv_func_getutxent=no;; - darwin*) ac_cv_func_getutxent=no;; - kfreebsd*-gnu) ac_cv_func_getutxent=no;; - *) AC_CHECK_FUNC([getutxent]);; -esac -if test $ac_cv_func_getutxent = yes; then - AC_DEFINE(HAVE_UTMPX, 1, [Define if the system uses extended utmp]) -else - AC_CHECK_FUNC([getutent], , - [AC_DEFINE(BSD_UTMP, 1, [Define if the system has no getutent])]) -fi - -AC_CHECK_MEMBERS([struct utmp.ut_user], , , [#include ]) -AC_CHECK_MEMBERS([struct passwd.pw_expire], , , [#include ]) -AC_CHECK_MEMBERS([struct sockaddr_in.sin_len], , , [ -#include -#include -]) - -ac_save_libs=$LIBS -LIBS="$LIBS $LIBUTIL" -AC_CHECK_FUNCS([setlogin setusercontext getusershell login_getclass auth_timeok]) -LIBS=$ac_save_libs - -dnl is getifaddrs always available without additional libs? -AC_CHECK_FUNCS([mkstemp setproctitle sysinfo strnlen getifaddrs]) - -AC_CHECK_FUNCS([arc4random], , - [ -dnl assume that /dev/random is non-blocking if /dev/urandom does not exist -for i in urandom random; do - if test -c /dev/$i; then - AC_DEFINE_UNQUOTED(DEV_RANDOM, "/dev/$i", [Define the system's entropy device]) - break - fi -done - ]) - -AC_CHECK_FUNC(vsyslog, [ - AC_DEFINE(USE_SYSLOG, 1, [Define if tdm should be built with syslog support])]) - -tdm_no_Xau=false -tdm_no_Xdmcp=false - -AC_CHECK_LIB(Xau, main, [:], - [ - tdm_no_Xau=true - DO_NOT_COMPILE="$DO_NOT_COMPILE tdm" - ], - $X_LDFLAGS -lX11 $LIBSOCKET) - -AC_ARG_WITH(xdmcp, - AC_HELP_STRING([--without-xdmcp],[build tdm without xdmcp support [default=with xdmcp]]), , - [with_xdmcp=yes]) -if test "x$with_xdmcp" = xyes; then - AC_CHECK_LIB(Xdmcp, main, [LIBXDMCP="-lXdmcp"], , $X_LDFLAGS -lX11 $LIBSOCKET) - if test -n "$LIBXDMCP"; then - cppflags_safe=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $X_INCLUDES" - AC_CHECK_HEADER(X11/Xdmcp.h, [HAVE_X11_XDMCP_H=1], , [#include ]) - CPPFLAGS=$cppflags_safe - fi - if test -z "$HAVE_X11_XDMCP_H"; then - tdm_no_Xdmcp=true - DO_NOT_COMPILE="$DO_NOT_COMPILE tdm" - fi - AC_DEFINE(XDMCP, 1, [Define if tdm should be built with XDMCP support]) - ac_save_libs=$LIBS - LIBS="$LIBS $LIBXDMCP" - AC_CHECK_FUNC(XdmcpWrap, [ - AC_DEFINE(HASXDMAUTH, 1, [Define if tdm should be built with XDMAUTH support]) - ]) - LIBS=$ac_save_libs -fi -AC_SUBST(LIBXDMCP) - -KRB4_INCS= -KRB4_LIBS= -KRB4_RPATH= - -AC_MSG_CHECKING(whether to use Kerberos v4) -AC_ARG_WITH(krb4, -AC_HELP_STRING([--with-krb4=PATH],[Compile in Kerberos v4 support]), -[ test "x$with_krb4" = xyes && with_krb4=/usr/kerberos ], -[ with_krb4=no ] -) -case "$with_krb4" in -no) - AC_MSG_RESULT(no) - ;; -*) - AC_MSG_RESULT(yes) - AC_DEFINE_UNQUOTED(KRB4, 1, [define if you have Kerberos IV]) - KRB4_INCS="-I$with_krb4/include" - KRB4_LIBS="-L$with_krb4/lib -lkrb -ldes" - if test "$USE_RPATH" = "yes" ; then - KRB4_RPATH="-R $with_krb4/lib" - fi - AC_CHECK_LIB(resolv, dn_expand, KRB4_LIBS="$KRB4_LIBS -lresolv") - ;; -esac - -AC_MSG_CHECKING(whether to use AFS) -AC_ARG_WITH(afs, - AC_HELP_STRING([--with-afs],[Compile in AFS support (requires KTH krb4)]), , - [ with_afs=no ]) -if test "$with_afs" = no; then - AC_MSG_RESULT(no) -else - if test "$with_krb4" = no; then - AC_MSG_RESULT(no) - AC_MSG_WARN("AFS requires Kerberos v4 support.") - with_afs=no - else - AC_MSG_RESULT(yes) - AC_DEFINE_UNQUOTED(AFS, 1, [define if you have KTH Kerberos IV and AFS]) - KRB4_LIBS="$KRB4_LIBS -lkafs" - if test -n "$os_aix"; then - KRB4_LIBS="$KRB4_LIBS -lld" - fi - fi -fi - -AC_SUBST(KRB4_INCS) -AC_SUBST(KRB4_LIBS) -AC_SUBST(KRB4_RPATH) - -AC_CHECK_LIB(s, main, [LIB_LIBS="-ls"]) dnl for AIX -AC_SUBST(LIB_LIBS) - -AC_CHECK_LIB(posix4, sched_yield, [LIBPOSIX4=-lposix4]) -AC_SUBST(LIBPOSIX4) - -KRB5_INCS= -KRB5_LIBS= -KRB5_RPATH= - -AC_MSG_CHECKING([whether to use Kerberos5 for Xauth cookies in tdm]) -AC_ARG_WITH(krb5auth, - AC_HELP_STRING([--with-krb5auth=PATH],[Use Kerberos5 for Xauth cookies in tdm]), , - [ with_krb5auth=no ]) -if test "x$with_krb5auth" = xno; then - AC_MSG_RESULT(no) -else - AC_MSG_RESULT(yes) - if test "x$with_krb5auth" != xyes; then - KRB5_INCS="-I$with_krb5auth/include" - KRB5_LIBS="-L$with_krb5auth/lib" - if test "$USE_RPATH" = "yes" ; then - KRB5_RPATH="-R $with_krb5auth/lib" - fi - fi - KRB5_LIBS="$KRB5_LIBS -lkrb5" dnl -lk5crypto -lcom_err -lresolv - keepcflags=$CFLAGS - CFLAGS="$KRB5_INCS $CFLAGS" - AC_CHECK_HEADER(krb5/krb5.h, - [ AC_DEFINE(K5AUTH, 1, [Define if tdm should use Kerberos 5 for Xauth cookies.]) ], - [ AC_MSG_ERROR([--with-krb5auth requires Kerberos5 header files. -Due to a problem with X includes you probably have to run "ln -s . krb5" -in the directory where the krb5.h include resides to make things actually work.])]) - CFLAGS="$keepcflags" -fi - -AC_SUBST(KRB5_INCS) -AC_SUBST(KRB5_LIBS) -AC_SUBST(KRB5_RPATH) - -AC_MSG_CHECKING([whether to use Sun's secure RPC for Xauth cookies in tdm]) -AC_ARG_WITH(rpcauth, - AC_HELP_STRING([--with-rpcauth],[Use Sun's secure RPC for Xauth cookies in tdm.]), , - [ with_rpcauth=no ]) -if test "x$with_rpcauth" = xno; then - AC_MSG_RESULT(no) -else - AC_MSG_RESULT(yes) - AC_CHECK_HEADER(rpc/rpc.h, - [ AC_DEFINE(SECURE_RPC, 1, [Define if tdm should use Sun's secure RPC for Xauth cookies.]) ], - [ AC_MSG_ERROR([--with-rpcauth requires Sun RPC header files.])]) -fi - -if test "x$use_pam" = xyes; then - AC_DEFINE(USE_PAM, 1, [Define if tdm should use PAM]) -elif test "x$use_shadow" = xyes; then - AC_DEFINE(USESHADOW, 1, [Define if tdm should use shadow passwords]) -fi -if test "x$with_krb4" != xno; then - AC_DEFINE(KERBEROS, 1, [Define if tdm should use Kerberos IV]) - if test "x$with_afs" = xno; then - AC_DEFINE(NO_AFS, 1, [Define if tdm should not use AFS]) - fi -fi - -AC_ARG_WITH(tdm-xconsole, - AC_HELP_STRING([--with-tdm-xconsole],[build tdm with built-in xconsole [default=no]]), , - [with_tdm_xconsole=no]) -if test "x$with_tdm_xconsole" = xyes; then - AC_DEFINE(WITH_TDM_XCONSOLE, 1, [Build tdm with built-in xconsole]) -fi - -########### Check for DBus - - AC_MSG_CHECKING(for DBus) - - dbus_inc=NOTFOUND - dbus_lib=NOTFOUND - dbus=NOTFOUND - - search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0" - AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir) - - search_incs_arch_deps="$kde_includes $kde_extra_includes /usr/lib$tdelibsuff/dbus-1.0/include /usr/local/lib$tdelibsuff/dbus-1.0/include" - AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps) - - if test -r $dbus_incdir/dbus/dbus.h && test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h ; then - DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps" - dbus_inc=FOUND - fi - - search_libs="$kde_libraries $kde_extra_libs /usr/lib$tdelibsuff /usr/local/lib$tdelibsuff" - AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir) - - if test -r $dbus_libdir/libdbus-1.so ; then - DBUS_LIBS="-L$dbus_libdir -ldbus-1" - dbus_lib=FOUND - fi - - if test $dbus_inc != FOUND || test $dbus_lib != FOUND ; then - KDE_PKG_CHECK_MODULES( DBUS, "dbus-1", [ DBUS_INCS=$DBUS_CFLAGS; dbus_inc=FOUND; dbus_lib=FOUND; ] , AC_MSG_RESULT( Nothing found on PKG_CONFIG_PATH ) ) - fi - - dbus_bus_var=`pkg-config --variable=system_bus_default_address dbus-1 2>/dev/null` - if test -z "$dbus_bus_var"; then - dbus_bus_var="unix:path=/var/run/dbus/system_bus_socket" - fi - AC_DEFINE_UNQUOTED(DBUS_SYSTEM_BUS, "$dbus_bus_var", [Define the unix domain path for dbus system bus]) - - if test $dbus_inc = FOUND && test $dbus_lib = FOUND ; then - AC_MSG_RESULT(headers $DBUS_INCS libraries $DBUS_LIBS) - dbus=FOUND - else - AC_MSG_RESULT(searched but not found) - fi - - AC_SUBST(DBUS_INCS) - AC_SUBST(DBUS_LIBS) - -########### Check for DBus - - AC_MSG_CHECKING(for DBus) - - dbus_inc=NOTFOUND - dbus_lib=NOTFOUND - dbus=NOTFOUND - - search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0" - AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir) - - search_incs_arch_deps="$kde_includes $kde_extra_includes /usr/lib$tdelibsuff/dbus-1.0/include /usr/local/lib$tdelibsuff/dbus-1.0/include" - AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps) - - if test -r $dbus_incdir/dbus/dbus.h && test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h ; then - DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps" - dbus_inc=FOUND - fi - - search_libs="$kde_libraries $kde_extra_libs /usr/lib$tdelibsuff /usr/local/lib$tdelibsuff" - AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir) - - if test -r $dbus_libdir/libdbus-1.so ; then - DBUS_LIBS="-L$dbus_libdir -ldbus-1" - dbus_lib=FOUND - fi - - if test $dbus_inc != FOUND || test $dbus_lib != FOUND ; then - KDE_PKG_CHECK_MODULES( DBUS, "dbus-1", [ DBUS_INCS=$DBUS_CFLAGS; dbus_inc=FOUND; dbus_lib=FOUND; ] , AC_MSG_RESULT( Nothing found on PKG_CONFIG_PATH ) ) - fi - - dbus_bus_var=`pkg-config --variable=system_bus_default_address dbus-1 2>/dev/null` - if test -z "$dbus_bus_var"; then - dbus_bus_var="unix:path=/var/run/dbus/system_bus_socket" - fi - AC_DEFINE_UNQUOTED(DBUS_SYSTEM_BUS, "$dbus_bus_var", [Define the unix domain path for dbus system bus]) - - if test $dbus_inc = FOUND && test $dbus_lib = FOUND ; then - AC_MSG_RESULT(headers $DBUS_INCS libraries $DBUS_LIBS) - dbus=FOUND - else - AC_MSG_RESULT(searched but not found) - fi - - AC_SUBST(DBUS_INCS) - AC_SUBST(DBUS_LIBS) - -dnl AC_OUTPUT(tdm/kfrontend/sessions/kde.desktop) - - -AC_ARG_WITH(libaudit, - [ --with-libaudit=[auto/yes/no] Add Linux audit support [default=auto]],, - with_libaudit=auto) - -# Check for Linux auditing API -# -# libaudit detection -if test x$with_libaudit = xno ; then - have_libaudit=no; -else - # See if we have audit daemon library - AC_CHECK_LIB(audit, audit_log_user_message, - have_libaudit=yes, have_libaudit=no) -fi - -AM_CONDITIONAL(HAVE_LIBAUDIT, test x$have_libaudit = xyes) - -if test x$have_libaudit = xyes ; then - EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -laudit" - AC_DEFINE(HAVE_LIBAUDIT,1,[linux audit support]) -fi - diff --git a/kdm/confproc.pl b/kdm/confproc.pl deleted file mode 100755 index c187c88c0..000000000 --- a/kdm/confproc.pl +++ /dev/null @@ -1,838 +0,0 @@ -#! /usr/bin/perl -w -# -# Copyright 2004-2005 Oswald Buddenhagen -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation. -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of a copyright holders shall -# not be used in advertising or otherwise to promote the sale, use or -# other dealings in this Software without prior written authorization -# from the copyright holders. -# - -use strict; -use Cwd 'abs_path'; - -sub pegout($) -{ - print STDERR $_[0]."\n"; - exit 1; -} - -sub relpath($$) -{ - my @src = split(/\//, abs_path(shift)); - my @dst = split(/\//, abs_path(shift)); - pop @dst; - while (@src && @dst && $src[0] eq $dst[0]) { - shift @src; - shift @dst; - } - return "../"x@dst . join("/", @src); -} - -sub getl() -{ - while () { - next if (/^#/); - chop; -# print "read: ".$_."\n"; - return; - } - $_ = ""; -} - -sub dedb($) -{ - my $t = shift; - $t =~ s,,\",g; - $t =~ s,]+)?)>,,g; - $t =~ s,([^<]+),uc($1),ge; - $t =~ s, , ,g; - $t =~ s,<,<,g; - $t =~ s,>,>,g; - $t =~ s,&tdm;,TDM,g; - $t =~ s,&XDMCP;,XDMCP,g; - $t =~ s,&X-Server;,X-server,g; - return $t; -} - -sub mkvname($) -{ - my $v = shift; - if ($v !~ /^[A-Z]{2}/) { - $v = lcfirst $v; - } - return $v; -} - -sub emit_conds($) -{ - my $ret = ""; - for my $c (keys %{$_[0]}) { - my ($then, $else) = ("", ""); - for my $d (@{${$_[0]}{$c}}) { - my $bas = "# define ".$d->[0]; - if ($d->[1] =~ /\n/) { - $then .= $bas." \\\n".$d->[1]."\n"; - } else { - $then .= $bas." ".$d->[1]."\n"; - } - $else .= $bas."\n"; - } - $ret .= "#if ".$c."\n".$then."#else\n".$else."#endif\n\n"; - } - return $ret; -} - -sub add_cond($$$$) -{ - if ($_[0]) { - my $vn = uc($_[1]); - for my $i (@{$_[2]}) { - push @{${$_[3]}{$_[0]}}, [ $vn."_".$i->[1], $i->[0] ]; - $i->[0] = $vn."_".$i->[1]; - } - } -} - -my $do_doc = 0; -if ($ARGV[0] eq "--doc") { - $do_doc = 1; - shift @ARGV; -} - -@ARGV != 2 && pegout("usage: $0 [--doc] "); - -open (INFILE, $ARGV[0]) || pegout("$0: cannot open definition file ".$ARGV[0]); - -my %ex_conds = (); -my %ex_sects = (); # $name -> $index -my @ex_config = (); # ($name, $comment, $entries) - -my $raw_out = ""; - -my %ov_enum_conds = (); -my $ov_enums = ""; -my $ov_enum_defs = ""; - -my $ov_defaults = ""; - -my %arr_ov_vars = (); -my $ov_rd_sects = ""; -my $ov_rd_ents = ""; - -my $ov_gen_sects = ""; -my $ov_gen_ents = ""; -my $max_prio = 0; - -my %ov_sec_conds = (); -my %ov_ent_conds = (); -my $ov_sect_defs = ""; -my $ov_sect_refs = ""; - -my %ov_glob_conds = (); -my $ov_globs = ""; -my %ov_loc_conds = (); -my $ov_locs = ""; - -my %ov_glob_decl_conds = (); -my $ov_glob_decls = ""; -my %ov_glob_def_conds = (); -my %ov_glob_defs = (); -my %ov_loc_def_conds = (); -my %ov_loc_defs = (); - -my %ov_greet_conds = (); -my $ov_greet_init = ""; -my @ov_greet_decls = (); -my %ov_greet_defs = (); - -my %ov_xm_conds = (); -my @ov_xm = ("", ""); - -my %ov_km_conds = (); -my %ov_km = (); - -my %sect_names = (); -my $sect = ""; -my $sect_if; - -my $key_if; - -my %key_names; - -my $kid_seq = 0x1000; - -my $doc = ""; -my $doc_ref = ""; - -sub emit_section() -{ - my $ts = $sect; - $ts =~ s/-/_/; - my @oa = ( - ["static Ent ents".$ts."[] = { \\\n".$ov_rd_ents."};", "ENTS"], - ["static Ent ents".$ts."[] = { \\\n".$ov_gen_ents."};", "GENS"], - ["sec".$ts." = { \"".$sect."\", ents".$ts.", as(ents".$ts.") },", "SEC"], - ["&sec".$ts.",", "SECS"] - ); - $ov_rd_ents = ""; - $ov_gen_ents = ""; - add_cond($sect_if, $ts, \@oa, \%ov_sec_conds); - $ov_rd_sects .= " \\\n".$oa[0][0]." \\\n"; - $ov_gen_sects .= " \\\n".$oa[1][0]." \\\n"; - $ov_sect_defs .= " ".$oa[2][0]." \\\n"; - $ov_sect_refs .= "\t".$oa[3][0]." \\\n"; - $doc_ref .= "\n\n\n"; -} - -my %th = ( - "int" => [ "C_TYPE_INT", "", "int\t", "", "GetCfgInt", "" ], - "bool" => [ "C_TYPE_INT", " | C_BOOL", "int\t", "bool\t", "GetCfgInt", "GetCfgInt" ], - "enum" => [ "C_TYPE_INT", " | C_ENUM", "int\t", "", "GetCfgInt", "" ], - "group" => [ "C_TYPE_INT", " | C_GRP", "int\t", "", "GetCfgInt", "" ], - "string" => [ "C_TYPE_STR", "", "char\t*", "TQString\t", "GetCfgStr", "GetCfgQStr" ], - "path" => [ "C_TYPE_STR", " | C_PATH", "char\t*", "TQString\t", "GetCfgStr", "GetCfgQStr" ], - "list" => [ "C_TYPE_ARGV", "", "char\t**", "TQStringList\t", "GetCfgStrArr", "GetCfgQStrList" ] -); - -my @tl = ("TQFont\t", "TQStringList\t", "TQString\t", "char\t**", "char\t*", "int\t", "bool\t"); - -sub init_defs($) -{ - for my $t (@tl) { - $_[0]{$t} = ""; - } -} - -init_defs(\%ov_glob_defs); -init_defs(\%ov_loc_defs); -init_defs(\%ov_greet_defs); - -sub emit_defs($) -{ - my $ret = ""; - for my $t (@tl) { - $ret .= $_[0]{$t}; - } - return $ret; -} - -while () { - chop; - if (/^$/) { - while () { - last if (/^<\/code>\n$/); - $raw_out .= $_; - } - } elsif (/^$/) { - my $comm = ""; - while () { - last if (/^<\/tdmrc>\n$/); - chop; - if (/^\[(.*)\]$/) { - defined($ex_sects{$1}) && - pegout("redefinition of example section [$1]"); - push @ex_config, [$1, dedb($comm), "", ""]; - $ex_sects{$1} = $#ex_config; - $comm = ""; - } else { - if (!$_) { - $comm .= " \\\n\"\\n\""; - } elsif ($_ eq " _") { - $comm .= " \\\n\"#\\n\""; - } else { - s/"/\\"/g; - $comm .= " \\\n\"#".$_."\\n\""; - } - } - } - } elsif (/^$/) { - while () { - last if (/^<\/docu>\n$/); - $doc .= $_; - } - } elsif (/^$/) { - while () { - next if (/^($|#)/); - my ($proc, $kif); - if (/^If: (.+)$/) { - $kif = $1; - getl(); - } else { - $kif = ""; - } - if (/^Proc: (.+)$/) { - $proc = $1; - getl(); - } else { - pegout("expecting Proc keyword in legacy section"); - } - my $nsrc = 0; - my $mcnt = 0; - while (/^Source: (.+)$/) { - my $src = $1; - if ($src =~ /^xdm:(.*)$/) { - my $what = $1; - my $dsp = ($what =~ s/^\*\.//); - my @oa = ([ "{ \"".$what."\", (char *)-1, 0, ".$proc." },", "XMO" ]); - add_cond($kif, $what, \@oa, \%ov_xm_conds); - $ov_xm[$dsp] .= $oa[0][0]." \\\n"; - } elsif ($src =~ /^tdm:(.*)\/(.*)$/) { - my ($sec, $key) = ($1, $2); - my @oa = ([ "{ \"".$key."\", (char *)-1, 0, ".$proc." },", "KMO".($mcnt++) ]); - add_cond($kif, $key, \@oa, \%ov_km_conds); - $ov_km{$sec} .= $oa[0][0]." \\\n"; - } else { - pegout("invalid legacy option '$_'"); - } - $nsrc++; - getl(); - } - $nsrc || pegout("no sources for legacy processor ".$proc); - last if (/^<\/legacy>$/); - pegout("unidentified section body '".$_."' in legacy section") if ($_); - } - } else { - next if (/^($|#)/); - if (/^Key: (.+)$/) { - my $key = $1; - $sect || pegout("defining key ".$key." outside any section"); - defined($key_names{$key}) && - pegout("redefinition of key ".$key." in section [".$sect."]"); - $key_names{$key} = ""; - getl(); - if (/^If: (.+)$/) { - $key_if = $1; - getl(); - } else { - $key_if = ""; - } - my $kif = $sect_if ? - ($key_if ? "(".$sect_if.") && (".$key_if.")" : $sect_if) : $key_if; - my ($e_comm, $e_desc) = ("", ""); - my $type = ""; - if (/^Type: (.+)$/) { - $type = $1; - if ($type eq "enum") { - my $enum = "static const char *e".$key."[] = { "; - my $n_e_def = 0; - while (getl(), /^ ([A-Za-z]+)(\/([A-Z_]+))?: (.+)$/) { - my $e_nam = $1; - $enum .= "\"".$e_nam."\", "; - defined($3) && - ($ov_enum_defs .= "#define ".$3." ".($n_e_def++)."\n"); - my ($comm, $desc) = (dedb($4), $4); - $comm =~ s/\"/\\\"/g; - $e_comm .= " \\\n\"# \\\"".$e_nam."\\\" - ".$comm."\\n\""; - $e_desc .= - "\n". - "".$e_nam."\n". - "".$desc."\n". - "\n"; - } - $enum .= "0 };"; - my @oa = ( [ $enum, "ENUM" ] ); - add_cond($kif, $key, \@oa, \%ov_enum_conds); - $ov_enums .= $oa[0][0]." \\\n"; - $n_e_def && ($ov_enum_defs .= "\n"); - } elsif ($type =~ /^(int|bool|group|string|path|list)$/) { - getl(); - } else { - pegout("unknown Type ".$type." for key ".$key." in section [".$sect."]"); - } - } else { - pegout("expecting Type for key ".$key." in section [".$sect."]"); - } - my ($odflt, $dflt, $cdflt, $ddflt); - my $quot = ($type =~ /^(int|bool|enum|group)$/); - if (/^Default: (\*?)(.+)$/) { - my $defd = $1; - ($odflt, $dflt) = ($2, $2); - $quot && ($dflt = "\"".$dflt."\""); - $defd && ($ov_defaults .= "#define def_".$key." ".$dflt."\n"); - getl(); - } else { - pegout("expecting Default for key ".$key." in section [".$sect."]"); - } - if (/^CDefault: (.+)$/) { - if ($1 eq "-") { - $ddflt = - $cdflt = ""; - } else { - $ddflt = - $cdflt = $1; - $cdflt =~ s/"/\\"/g; - $cdflt = " \\\n\"# Default is ".$cdflt."\\n\""; - } - getl(); - } else { - $ddflt = $odflt; - if ($quot) { - $cdflt = " \\\n\"# Default is ".$odflt."\\n\""; - } else { - $cdflt = " \\\n\"# Default is \\\"\" ".$dflt." \"\\\"\\n\""; - } - } - if (/^DDefault: -$/) { - $ddflt = ""; - getl(); - } - my $pproc; - if (/^PostProc: (.+)$/) { - $pproc = $1; - getl(); - } else { - $pproc = ""; - } - my $nusers = 0; - my ($vname, $kid, $xkid, $ctype, $cpptype, $cget, $cppget); - while (/^User: (.+)$/) { - my $user = $1; - if ($user eq "dummy") { - $vname = "dummy"; - $kid = "C_INTERNAL | C_TYPE_STR"; - $xkid = ""; - } elsif ($user =~ s/^(core|greeter|greeter-c|dep|config)(\((.+)\))?(:font)?$/$1/) { - my ($hvn, $isfn) = (defined($3) ? $3 : mkvname($key), $4); - ($kid, $xkid, $ctype, $cpptype, $cget, $cppget) = @{$th{$type}}; - $kid = sprintf "%#x | %s", $kid_seq, $kid; - if ($user eq "dep") { - $vname = $hvn; - $xkid .= " | C_INTERNAL"; - } elsif ($user eq "config") { - $vname = $hvn; - $xkid .= " | C_INTERNAL | C_CONFIG"; - } else { - $vname = ""; - if ($user eq "core") { - if ($sect =~ /^-/) { - my @oa = ( - [ "{ ".$kid.", boffset(".$hvn.") },", "LOC" ], - [ $ctype.$hvn.";", "LDEF" ] - ); - add_cond($kif, $hvn, \@oa, \%ov_loc_conds); - $ov_locs .= " \\\n".$oa[0][0]; - $ov_loc_defs{$ctype} .= " \\\n\t".$oa[1][0]; - } else { - my @oa = ( - [ "{ ".$kid.", (char **) &".$hvn." },", "GLOB" ], - [ $ctype.$hvn.";", "GDEF" ], - [ "extern ".$ctype.$hvn.";", "GDECL" ] - ); - add_cond($kif, $hvn, \@oa, \%ov_glob_conds); - $ov_globs .= " \\\n".$oa[0][0]; - $ov_glob_defs{$ctype} .= " \\\n".$oa[1][0]; - $ov_glob_decls .= " \\\n".$oa[2][0]; - } - } else { # greeter(-c)? - my ($typ, $gtr, $isc); - if ($isfn) { - $typ = "TQFont\t"; - $gtr = "Str2Font( GetCfgQStr( ".$kid." ) )"; - $isc = 0; - } elsif ($user eq "greeter" && $cppget) { - $typ = $cpptype; - $gtr = $cppget."( ".$kid." )"; - $isc = 0; - } else { - $typ = $ctype; - $gtr = $cget."( ".$kid.(($type eq "list") ? ", 0" : "")." )"; - $isc = 1; - } - my @oa = ( - [ "_".$hvn." = ".$gtr.";", "GRINIT" ], - [ $typ."_".$hvn.";", "GRDEF" ], - [ "extern ".$typ."_".$hvn.";", "GRDECL" ] - ); - add_cond($kif, $hvn, \@oa, \%ov_greet_conds); - $ov_greet_init .= " \\\n ".$oa[0][0]; - $ov_greet_defs{$typ} .= " \\\n".$oa[1][0]; - $ov_greet_decls[$isc] .= " \\\n".$oa[2][0]; - } - } - } else { - pegout("unrecognized User '".$user."' for key ".$key." in section [".$sect."]"); - } - $nusers++; - getl(); - } - $nusers || pegout("expecting User for key ".$key." in section [".$sect."]"); - my $ninsts = 0; - while (/^Instance: ?(.*)$/) { - my $inst = $1; - if ($inst ne "-") { - my $on = 1 - ($inst =~ s/^#//); - my $sec; - if ($sect =~ /^-/) { - ($inst =~ s/^([^\/]+)\///) || pegout("instance for key ".$key." in section [".$sect."] does not specify display"); - $sec = "X-".$1.$sect; - } else { - $sec = $sect; - } - if ($type eq "bool" && $inst eq "!") { - $inst = ($dflt eq "\"true\"") ? "\"false\"" : "\"true\""; - } elsif (!$inst) { - $inst = $dflt; - } else { - $quot && ($inst = "\"".$inst."\""); - } - defined($ex_sects{$sec}) || - pegout("instantiating key ".$key." in section [".$sect."] in undeclared section"); - my @oa = ( [ "{ \"".$key."\",\t".$inst.", ".$on." },", "INST" ] ); - add_cond($key_if, $key, \@oa, \%ex_conds); - $ex_config[$ex_sects{$sec}][2] .= $oa[0][0]." \\\n"; - $ex_config[$ex_sects{$sec}][3] = $sect_if; - } - $ninsts++; - getl(); - } - $ninsts || - print STDERR "Warning: key ".$key." in section [".$sect."] not instanciated\n"; - my ($update, $prio) = ("0", ""); - if (/^Update: ([^\/]+)(\/(\d+))?$/) { - ($update, $prio) = ($1, $3); - getl(); - } - if ($prio) { - ($max_prio < $prio) && ($max_prio = $prio); - } else { - $prio = 0; - } - my $mcnt = 0; - while (/^Merge: (.+)$/) { - my $merge = $1; - if ($merge =~ /^xdm(:([^\(]+))?(\((.+)\))?$/) { - my ($what, $proc) = ($2, $4); - my @oa = ( - [ "{ \"".($what ? $what : lcfirst($key))."\", ". - "\"".(($sect =~ /^-/) ? "X-%s" : "").$sect."\", ". - ($what ? "\"".$key."\"" : "0").", ". - ($proc ? $proc : "0")." },", "XM" ] - ); - add_cond($kif, $key, \@oa, \%ov_xm_conds); - $ov_xm[$sect =~ /^-/] .= $oa[0][0]." \\\n"; - } elsif ($merge =~ /^tdm:([^\(]+)(\((.+)\))?$/) { - my ($where, $func) = ($1, $3); - my $sec = ""; - ($where =~ s/^([^\/]+)\///) && ($sec = $1); - my @oa = ( - [ "{ \"".($where ? $where : $key)."\", ". - ($sec ? "\"".$sect."\"" : "0").", ". - ($where ? "\"".$key."\"" : "0").", ". - ($func ? $func : "0")." },", "KM".($mcnt++) ] - ); - add_cond($kif, $key, \@oa, \%ov_km_conds); - $ov_km{$sec ? $sec : $sect} .= $oa[0][0]." \\\n"; - } else { - pegout("bogus Merge '".$merge."' for key ".$key." in section [".$sect."]"); - } - getl(); - } - # todo: handle $func here, too - my @oa = ( [ "{ \"".$key."\", 0, 0, 0 },", "KM" ] ); - add_cond($kif, $key, \@oa, \%ov_km_conds); - $ov_km{$sect} .= $oa[0][0]." \\\n"; - my $comm = ""; - if (/^Comment:(( [-&])?)$/) { - if ($1 eq " &") { - $comm = "&"; - getl(); - } elsif ($1 ne " -") { - while (getl(), /^ (.*)$/) { - $comm .= $1."\n"; - } - $comm || - print STDERR "Warning: key ".$key." in section [".$sect."] has empty Comment\n"; - } else { - getl(); - } - } else { - print STDERR "Warning: key ".$key." in section [".$sect."] has no Comment\n"; - } - if (/^Description:(( [-!])?)$/) { - if ($1 ne " -") { - $doc_ref .= - "\n". - "\n". - "\n"; - ($1 eq " !") && - ($e_desc = ""); - my $desc = ""; - while (getl(), /^ (_|(.*))$/) { - $desc .= $2."\n"; - } - $desc || - print STDERR "Warning: key ".$key." in section [".$sect."] has empty Description\n"; - ($comm eq "&") && - ($comm = $desc); - $desc = "\n".$desc."\n"; - if ($e_desc) { - $e_desc = "\n".$e_desc."\n"; - ($desc =~ s/%ENUM%/$e_desc/) || - ($desc .= $e_desc); - } - $doc_ref .= $desc; - if ($ddflt) { - if ($ddflt eq '""') { - $doc_ref .= "Empty by default.\n"; - } else { - $ddflt =~ s/\"//g; - $ddflt =~ s,TDMCONF ,\${kde_confdir}/tdm,; - $ddflt =~ s,TDMDATA ,\${kde_datadir}/tdm,; - $ddflt =~ s,XBINDIR ,\${x_bindir},; - $doc_ref .= "The default is ".$ddflt.".\n"; - } - } - $doc_ref .= "\n\n\n"; - } else { - getl(); - } - } else { - print STDERR "Warning: key ".$key." in section [".$sect."] has no Description\n"; - } - pegout("unidentified section body '".$_."' in section [".$sect."]") if ($_); - if ($vname) { - ($vname ne "dummy") && - ($arr_ov_vars{$vname} = $kif); - $vname = "&V".$vname; - } elsif ($pproc) { - $vname = "(void *)".$pproc; - } elsif ($type eq "enum") { - $vname = "e".$key; - } else { - $vname = "0"; - } - $comm = dedb($comm); - $comm =~ s/"/\\"/g; - $comm =~ s/([^\n]*)\n/ \\\n\"# $1\\n\"/g; - @oa = ( - [ "{ \"".$key."\", ".$kid.$xkid.", ".$vname.", ".$dflt." },", "RENT" ], - [ "{ \"".$key."\", ".$prio.", ".$update.",".$comm.$e_comm.$cdflt." },", "GENT" ], - ); - add_cond($key_if, $key, \@oa, \%ov_ent_conds); - $ov_rd_ents .= $oa[0][0]." \\\n"; - $ov_gen_ents .= $oa[1][0]." \\\n"; - $kid_seq++; - } elsif (/^Section: (.+)$/) { - emit_section() if ($sect); - $sect = $1; - defined($sect_names{$sect}) && pegout("redefinition of section [".$sect."]"); - $sect_names{$sect} = ""; - %key_names = (); - getl(); - if (/^If: (.+)$/) { - $sect_if = $1; - getl(); - } else { - $sect_if = ""; - } - my ($sref, $stit, $sna); - if ($sect =~ /^-(.*)$/) { - $sref = lc($1); - $stit = "X-*-".$1; - $sna = "section class"; - } else { - $sref = lc($sect); - $stit = $sect; - $sna = "section"; - } - $doc_ref .= - "\n\n". - "The [".$stit."] ".$sna." of &tdmrc;\n\n"; - if (/^Description:(( -)?)$/) { - if ($1 ne " -") { - my $desc = 0; - $doc_ref .= "\n"; - while (getl(), /^ (_|(.*))$/) { - $doc_ref .= $2."\n"; - $desc = 1; - } - $doc_ref .= "\n"; - $desc || - print STDERR "Warning: section [".$sect."] has empty Description\n"; - } else { - getl(); - } - } else { - print STDERR "Warning: section [".$sect."] has no Description\n"; - } - $doc_ref .= "\n\n\n"; - pegout("unidentified section body '".$_."' in section [".$sect."]") if ($_); - } else { - pegout("invalid section leadin: '".$_."'"); - } - } -} -emit_section(); -close INFILE; - -my $srcf = relpath($ARGV[0], $ARGV[1]); -my $exen = relpath($0, $ARGV[1]); - -open (OUTFILE, ">".$ARGV[1]) || pegout("$0: cannot create output file ".$ARGV[1]); - -if (!$do_doc) { - -print OUTFILE - "/* generated from $srcf by $exen - DO NOT EDIT! */\n\n". - "#ifndef CONFIG_DEFS\n". - "#define CONFIG_DEFS\n\n". - $raw_out."\n\n". - $ov_enum_defs."\n". - $ov_defaults."\n\n"; - -my $ov_vars = ""; -my %ov_var_conds = (); -for my $v (keys %arr_ov_vars) { - my @oa = ( ["V".$v.",", "VAR"] ); - add_cond($arr_ov_vars{$v}, $v, \@oa, \%ov_var_conds); - $ov_vars .= " ".$oa[0][0]." \\\n"; -} -print OUTFILE - emit_conds(\%ov_var_conds). - "#define CONF_READ_VARS \\\n \\\n". - "static Value \\\n". - $ov_vars. - " Vdummy;\n\n\n"; - -print OUTFILE - emit_conds(\%ov_ent_conds). - emit_conds(\%ov_sec_conds). - "#define CONF_SECTS \\\n \\\n". - "static Sect \\\n". - $ov_sect_defs. - " *allSects[]\t= { \\\n". - $ov_sect_refs. - " };\n\n\n"; - -print OUTFILE - emit_conds(\%ov_enum_conds). - "#define CONF_READ_ENTRIES \\\n \\\n". - $ov_enums. - $ov_rd_sects." \\\n". - "CONF_SECTS\n\n\n"; - -print OUTFILE - "#define CONF_MAX_PRIO ".$max_prio."\n\n". - "#define CONF_GEN_ENTRIES \\\n". - $ov_gen_sects." \\\n". - "CONF_SECTS\n\n\n"; - -print OUTFILE - emit_conds(\%ov_glob_conds). - "#define CONF_CORE_GLOBALS \\\n". - $ov_globs."\n\n\n". - "#define CONF_CORE_GLOBAL_DECLS \\\n". - $ov_glob_decls."\n\n\n". - "#define CONF_CORE_GLOBAL_DEFS \\\n". - emit_defs(\%ov_glob_defs)."\n\n\n"; - -print OUTFILE - emit_conds(\%ov_loc_conds). - "#define CONF_CORE_LOCALS \\\n". - $ov_locs."\n\n\n". - "#define CONF_CORE_LOCAL_DEFS \\\n". - emit_defs(\%ov_loc_defs)."\n\n\n\n"; - -print OUTFILE - emit_conds(\%ov_greet_conds). - "#define CONF_GREET_INIT \\\n". - $ov_greet_init."\n\n\n". - "#define CONF_GREET_C_DECLS \\\n". - $ov_greet_decls[1]."\n\n\n". - "#define CONF_GREET_CPP_DECLS \\\n". - $ov_greet_decls[0]."\n\n\n". - "#define CONF_GREET_DEFS \\\n". - emit_defs(\%ov_greet_defs)."\n\n\n"; - -my ($ov1, $ov2) = ("", ""); -my %ex_sec_conds = (); -for my $i (@ex_config) { - my $vn; - if ($i->[0] =~ /^X-(.+)-(.+)$/) { - if ($1 eq "*") { - $vn = "dEntsAny".$2; - } elsif ($1 eq ":*") { - $vn = "dEntsLocal".$2; - } else { - my ($t1, $t2) = ($1, $2); - $t1 =~ s/[-:]/_/g; - $vn = "dEnts".$t1.$t2; - } - } else { - $vn = "dEnts".$i->[0]; - } - my @oa = ( - [ "static DEnt ".$vn."[] = { \\\n".$i->[2]."};", "DSEC" ], - [ "{ \"".$i->[0]."\",\t".$vn.",\tas(".$vn."),".$i->[1]." },", "DSECS" ] - ); - add_cond($i->[3], $vn, \@oa, \%ex_sec_conds); - $ov1 .= $oa[0][0]." \\\n \\\n"; - $ov2 .= $oa[1][0]." \\\n"; -} -print OUTFILE - emit_conds(\%ex_conds). - emit_conds(\%ex_sec_conds). - "#define CONF_GEN_EXAMPLE \\\n \\\n". - $ov1. - "static DSect dAllSects[] = { \\\n". - $ov2. - "};\n\n\n"; - -print OUTFILE - emit_conds(\%ov_xm_conds). - "#define CONF_GEN_XMERGE \\\n \\\n". - "XResEnt globents[] = { \\\n". - $ov_xm[0]. - "}, dpyents[] = { \\\n". - $ov_xm[1]. - "};\n\n\n"; - -my $ov_km_sects = ""; -my $ov_km_sect_refs = ""; -for my $s (keys %ov_km) { - my $ts = $s; - $ts =~ s/-/_/; - $ov_km_sects .= - "KUpdEnt upd".$ts."[] = { \\\n". - $ov_km{$s}. - "}; \\\n \\\n"; - $ov_km_sect_refs .= "{ \"".$s."\", upd".$ts.", as(upd".$ts.") }, \\\n"; -} -print OUTFILE - emit_conds(\%ov_km_conds). - "#define CONF_GEN_KMERGE \\\n \\\n". - $ov_km_sects. - "KUpdSec kupsects[] = { \\\n". - $ov_km_sect_refs. - "};\n"; -print OUTFILE - "\n#endif /* CONFIG_DEFS */\n"; - -} else { - -$doc =~ s/%REF%/$doc_ref/; -print OUTFILE - "\n\n". - $doc; - -} - -close OUTFILE; diff --git a/kdm/kfrontend/CMakeLists.txt b/kdm/kfrontend/CMakeLists.txt deleted file mode 100644 index 4a069a3ae..000000000 --- a/kdm/kfrontend/CMakeLists.txt +++ /dev/null @@ -1,101 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -add_subdirectory( themer ) -add_subdirectory( themes ) -add_subdirectory( pics ) -add_subdirectory( sessions ) - -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/tdm/backend - ${CMAKE_SOURCE_DIR}/tdmlib - ${CMAKE_SOURCE_DIR}/kcontrol/background - ${TDE_INCLUDE_DIR} - ${TQT_INCLUDE_DIRS} -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - - -##### other data ################################ - -if( NOT DEFINED GENTDMCONF_FLAGS ) - set( GENTDMCONF_FLAGS "--no-old" ) -endif( ) - -install( CODE "execute_process( COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gentdmconf --in \$ENV{DESTDIR}${CONFIG_INSTALL_DIR}/tdm --no-in-notice --face-src ${CMAKE_CURRENT_SOURCE_DIR}/pics ${GENTDMCONF_FLAGS} )" ) - - -##### config.ci (generated) ##################### - -add_custom_command( OUTPUT config.ci - COMMAND perl -w ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def config.ci - DEPENDS ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def ) - - -##### tdm_config (executable) ################### - -set_property( SOURCE tdm_config.c APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/config.ci ) - -tde_add_executable( tdm_config - SOURCES tdm_config.c - LINK - DESTINATION ${BIN_INSTALL_DIR} -) - - -##### tdm_greet (executable) #################### -if( WITH_XRANDR ) - set( TDMGREET_OPTIONAL_LINK "krandr-shared" ) -endif ( ) - -tde_add_executable( tdm_greet AUTOMOC - SOURCES - tdm_greet.c tdmconfig.cpp tdmclock.cpp kconsole.cpp - kfdialog.cpp kgdialog.cpp kchooser.cpp kgverify.cpp - tdmshutdown.cpp tdmadmindialog.cpp kgreeter.cpp - kgapp.cpp sakdlg.cc - LINK tdmthemer-static tdeui-shared Xtst ${TDMGREET_OPTIONAL_LINK} - DESTINATION ${BIN_INSTALL_DIR} -) - - -##### krootimage (executable) ################### - -tde_add_executable( krootimage AUTOMOC - SOURCES krootimage.cpp - LINK bgnd-static kio-shared - DESTINATION ${BIN_INSTALL_DIR} -) - - -##### gentdmconf (executable) ################### - -set_property( SOURCE gentdmconf.c APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/config.ci ) - -tde_add_executable( gentdmconf AUTOMOC - SOURCES gentdmconf.c - LINK X11 - DESTINATION ${BIN_INSTALL_DIR} -) - - -##### tdmctl (executable) ####################### - -tde_add_executable( tdmctl - SOURCES tdmctl.c - LINK - DESTINATION ${BIN_INSTALL_DIR} -) diff --git a/kdm/kfrontend/Makefile.am b/kdm/kfrontend/Makefile.am deleted file mode 100644 index 7c58dc67f..000000000 --- a/kdm/kfrontend/Makefile.am +++ /dev/null @@ -1,67 +0,0 @@ -# use 'make GENTDMCONF_FLAGS=... install' to override -GENTDMCONF_FLAGS = --no-old - -SUBDIRS = themer themes pics sessions - -AM_CPPFLAGS = -I$(srcdir)/../backend -I.. -I$(top_srcdir)/kcontrol/background \ - -I$(top_srcdir)/tdmlib $(all_includes) - -bin_PROGRAMS = tdm_config tdm_greet krootimage gentdmconf tdmctl - -tdm_config_SOURCES = tdm_config.c -tdm_config_LDADD = $(LIBRESOLV) $(LIBSOCKET) $(LIBPOSIX4) - -tdm_greet_SOURCES = \ - tdm_greet.c \ - tdmconfig.cpp \ - tdmclock.cpp \ - kconsole.cpp \ - kfdialog.cpp \ - kgdialog.cpp \ - kchooser.cpp \ - kgverify.cpp \ - tdmshutdown.cpp \ - tdmadmindialog.cpp \ - kgreeter.cpp \ - kgapp.cpp -tdm_greet_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -lktexteditor -tdm_greet_LDADD = themer/libtdmthemer.a $(LIB_TDEUI) $(XTESTLIB) $(LIBPOSIX4) - -krootimage_SOURCES = krootimage.cpp -krootimage_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -lktexteditor -krootimage_LDADD = $(top_builddir)/kcontrol/background/libbgnd.la $(LIB_KIO) - -METASOURCES = AUTO - -gentdmconf_SOURCES = gentdmconf.c -gentdmconf_LDFLAGS = $(X_LDFLAGS) $(X_RPATH) -gentdmconf_LDADD = $(LIB_X11) - -tdmctl_SOURCES = tdmctl.c -tdmctl_LDADD = $(LIBSOCKET) - -install-data-local: gentdmconf - ./gentdmconf --in $(DESTDIR)$(kde_confdir)/tdm --no-in-notice --face-src $(srcdir)/pics $(GENTDMCONF_FLAGS) - -messages: - $(XGETTEXT) `find . -name "*.cpp"` -o $(podir)/tdmgreet.pot - -noinst_HEADERS = \ - tdm_greet.h \ - tdmconfig.h \ - tdmclock.h \ - kconsole.h \ - kfdialog.h \ - kgdialog.h \ - kchooser.h \ - kgverify.h \ - tdmshutdown.h \ - kgreeter.h \ - kgapp.h \ - \ - krootimage.h - -tdm_greet_COMPILE_FIRST = ../config.ci -tdm_config_COMPILE_FIRST = ../config.ci -gentdmconf_COMPILE_FIRST = ../config.ci - diff --git a/kdm/kfrontend/genkdmconf.c b/kdm/kfrontend/genkdmconf.c deleted file mode 100644 index f55ffbbbc..000000000 --- a/kdm/kfrontend/genkdmconf.c +++ /dev/null @@ -1,2849 +0,0 @@ -/* - -Create a suitable configuration for tdm taking old xdm/tdm -installations into account - -Copyright (C) 2001-2005 Oswald Buddenhagen - - -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 -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef BSD -# include -#endif - -#include "config.ci" - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) -# define ATTR_UNUSED __attribute__((unused)) -#else -# define ATTR_UNUSED -#endif - -#if defined(__sun) && !defined(__sun__) -# define __sun__ -#endif - -#define as(ar) ((int)(sizeof(ar)/sizeof(ar[0]))) - -#define __stringify(x) #x -#define stringify(x) __stringify(x) - -#define RCVERSTR stringify(RCVERMAJOR) "." stringify(RCVERMINOR) - -static int old_scripts, no_old_scripts, old_confs, no_old, - no_backup, no_in_notice, use_destdir, mixed_scripts; -static const char *newdir = TDMCONF, *facesrc = TDMDATA "/pics/users", - *oldxdm, *oldkde; - -static int oldver; - - -typedef struct StrList { - struct StrList *next; - const char *str; -} StrList; - - -static void * -mmalloc( size_t sz ) -{ - void *ptr; - - if (!(ptr = malloc( sz ))) { - fprintf( stderr, "Out of memory\n" ); - exit( 1 ); - } - return ptr; -} - -static void * -mcalloc( size_t sz ) -{ - void *ptr; - - if (!(ptr = calloc( 1, sz ))) { - fprintf( stderr, "Out of memory\n" ); - exit( 1 ); - } - return ptr; -} - -static void * -mrealloc( void *optr, size_t sz ) -{ - void *ptr; - - if (!(ptr = realloc( optr, sz ))) { - fprintf( stderr, "Out of memory\n" ); - exit( 1 ); - } - return ptr; -} - -static char * -mstrdup( const char *optr ) -{ - char *ptr; - - if (!optr) - return 0; - if (!(ptr = strdup( optr ))) { - fprintf( stderr, "Out of memory\n" ); - exit( 1 ); - } - return ptr; -} - - -#define NO_LOGGER -#define STATIC static -#include - -typedef struct { - char *buf; - int clen, blen, tlen; -} OCABuf; - -static void -OutCh_OCA( void *bp, char c ) -{ - OCABuf *ocabp = (OCABuf *)bp; - - ocabp->tlen++; - if (ocabp->clen >= ocabp->blen) { - ocabp->blen = ocabp->blen * 3 / 2 + 100; - ocabp->buf = mrealloc( ocabp->buf, ocabp->blen ); - } - ocabp->buf[ocabp->clen++] = c; -} - -static int -VASPrintf( char **strp, const char *fmt, va_list args ) -{ - OCABuf ocab = { 0, 0, 0, -1 }; - - DoPr( OutCh_OCA, &ocab, fmt, args ); - OutCh_OCA( &ocab, 0 ); - *strp = realloc( ocab.buf, ocab.clen ); - if (!*strp) - *strp = ocab.buf; - return ocab.tlen; -} - -static int -ASPrintf( char **strp, const char *fmt, ... ) -{ - va_list args; - int len; - - va_start( args, fmt ); - len = VASPrintf( strp, fmt, args ); - va_end( args ); - return len; -} - -static void -StrCat( char **strp, const char *fmt, ... ) -{ - char *str, *tstr; - va_list args; - int el; - - va_start( args, fmt ); - el = VASPrintf( &str, fmt, args ); - va_end( args ); - if (*strp) { - int ol = strlen( *strp ); - tstr = mmalloc( el + ol + 1 ); - memcpy( tstr, *strp, ol ); - memcpy( tstr + ol, str, el + 1 ); - free( *strp ); - free( str ); - *strp = tstr; - } else - *strp = str; -} - - -#define WANT_CLOSE 1 - -typedef struct File { - char *buf, *eof, *cur; -#if defined(HAVE_MMAP) && defined(WANT_CLOSE) - int ismapped; -#endif -} File; - -static int -readFile( File *file, const char *fn ) -{ - off_t flen; - int fd; - - if ((fd = open( fn, O_RDONLY )) < 0) - return 0; - - flen = lseek( fd, 0, SEEK_END ); -#ifdef HAVE_MMAP -# ifdef WANT_CLOSE - file->ismapped = 0; -# endif - file->buf = mmap( 0, flen + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0 ); -# ifdef WANT_CLOSE - if (file->buf) - file->ismapped = 1; - else -# else - if (!file->buf) -# endif -#endif - { - file->buf = mmalloc( flen + 1 ); - lseek( fd, 0, SEEK_SET ); - if (read( fd, file->buf, flen ) != flen) { - free( file->buf ); - close( fd ); - fprintf( stderr, "Cannot read file\n" ); - return 0; /* maybe better abort? */ - } - } - file->eof = file->buf + flen; - close( fd ); - return 1; -} - -#ifdef WANT_CLOSE -static void -freeBuf( File *file ) -{ -# ifdef HAVE_MMAP - if (file->ismapped) - munmap( file->buf, file->eof - file->buf ); - else -# endif - free( file->buf ); -} -#endif - -static int -isTrue( const char *val ) -{ - return !strcmp( val, "true" ) || - !strcmp( val, "yes" ) || - !strcmp( val, "on" ) || - atoi( val ); -} - -static int -mkdirp( const char *name, int mode, const char *what, int existok ) -{ - char *mfname = mstrdup( name ); - int i; - struct stat st; - - for (i = 1; mfname[i]; i++) - if (mfname[i] == '/') { - mfname[i] = 0; - if (stat( mfname, &st )) { - if (mkdir( mfname, 0755 )) { - fprintf( stderr, "Cannot create parent %s of %s directory %s: %s\n", - mfname, what, name, strerror( errno ) ); - free( mfname ); - return 0; - } - chmod( mfname, 0755 ); - } - mfname[i] = '/'; - } - free( mfname ); - if (stat( name, &st )) { - if (mkdir( name, mode )) { - fprintf( stderr, "Cannot create %s directory %s: %s\n", - what, name, strerror( errno ) ); - return 0; - } - chmod( name, mode ); - return 1; - } - return existok; -} - - -static void -displace( const char *fn ) -{ - if (!no_backup) { - char bn[PATH_MAX + 4]; - sprintf( bn, "%s.bak", fn ); /* won't overflow if only existing paths are passed */ - rename( fn, bn ); - } else - unlink( fn ); -} - - -static char * -locate( const char *exe ) -{ - int len; - char *path, *name, *thenam, nambuf[PATH_MAX+1]; - char *pathe; - - if (!(path = getenv( "PATH" ))) - return 0; - len = strlen( exe ); - name = nambuf + PATH_MAX - len; - memcpy( name, exe, len + 1 ); - *--name = '/'; - do { - if (!(pathe = strchr( path, ':' ))) - pathe = path + strlen( path ); - len = pathe - path; - if (len && !(len == 1 && *path == '.')) { - thenam = name - len; - if (thenam >= nambuf) { - memcpy( thenam, path, len ); - if (!access( thenam, X_OK )) - return mstrdup( thenam ); - } - } - path = pathe; - } while (*path++ != '\0'); - return 0; -} - - -/* - * target data to be written to tdmrc - */ - -typedef struct Entry { - struct Entry *next; - struct Ent *spec; - const char *value; - int active:1; - int written:1; -} Entry; - -typedef struct Section { - struct Section *next; - struct Sect *spec; - const char *name; - const char *comment; - Entry *ents; -} Section; - -static Section *config; /* the tdmrc data to be written */ - -/* - * Specification of the (currently possible) tdmrc entries - */ - -typedef struct Ent { - const char *key; - int prio; - void (*func)( Entry *ce, Section *cs ); - const char *comment; -} Ent; - -typedef struct Sect { - const char *name; - Ent *ents; - int nents; -} Sect; - -static Sect *findSect( const char *name ); -static Ent *findEnt( Sect *sect, const char *key ); - -/* - * Functions to manipulate the current tdmrc data - */ - -static const char * -getfqval( const char *sect, const char *key, const char *defval ) -{ - Section *cs; - Entry *ce; - - for (cs = config; cs; cs = cs->next) - if (!strcmp( cs->name, sect )) { - for (ce = cs->ents; ce; ce = ce->next) - if (!strcmp( ce->spec->key, key )) { - if (ce->active && ce->written) - return ce->value; - break; - } - break; - } - return defval; -} - -static void -putfqval( const char *sect, const char *key, const char *value ) -{ - Section *cs, **csp; - Entry *ce, **cep; - - if (!value) - return; - - for (csp = &config; (cs = *csp); csp = &(cs->next)) - if (!strcmp( sect, cs->name )) - goto havesec; - cs = mcalloc( sizeof(*cs) ); - ASPrintf( (char **)&cs->name, "%s", sect ); - cs->spec = findSect( sect ); - *csp = cs; - havesec: - - for (cep = &(cs->ents); (ce = *cep); cep = &(ce->next)) - if (!strcmp( key, ce->spec->key )) - goto haveent; - ce = mcalloc( sizeof(*ce) ); - ce->spec = findEnt( cs->spec, key ); - *cep = ce; - haveent: - ASPrintf( (char **)&ce->value, "%s", value ); - ce->written = ce->active = 1; -} - -static const char *csect; - -#define setsect(se) csect = se - -static void -putval( const char *key, const char *value ) -{ - putfqval( csect, key, value ); -} - - -static void -wrconf( FILE *f ) -{ - Section *cs; - Entry *ce; - StrList *sl = 0, *sp; - const char *cmt; - - putfqval( "General", "ConfigVersion", RCVERSTR ); - for (cs = config; cs; cs = cs->next) { - fprintf( f, "%s[%s]\n", - cs->comment ? cs->comment : "\n", cs->name ); - for (ce = cs->ents; ce; ce = ce->next) { - if (ce->spec->comment) { - cmt = ce->spec->comment; - for (sp = sl; sp; sp = sp->next) - if (sp->str == cmt) { - cmt = "# See above\n"; - goto havit; - } - if (!(sp = malloc( sizeof(*sp) ))) - fprintf( stderr, "Warning: Out of memory\n" ); - else { - sp->str = cmt; - sp->next = sl; sl = sp; - } - } else - cmt = ""; - havit: - fprintf( f, "%s%s%s=%s\n", - cmt, ce->active ? "" : "#", ce->spec->key, ce->value ); - } - } -} - - -/* - * defaults - */ -#ifdef XDMCP -static const char def_xaccess[] = -"# Xaccess - Access control file for XDMCP connections\n" -"#\n" -"# To control Direct and Broadcast access:\n" -"#\n" -"# pattern\n" -"#\n" -"# To control Indirect queries:\n" -"#\n" -"# pattern list of hostnames and/or macros ...\n" -"#\n" -"# To use the chooser:\n" -"#\n" -"# pattern CHOOSER BROADCAST\n" -"#\n" -"# or\n" -"#\n" -"# pattern CHOOSER list of hostnames and/or macros ...\n" -"#\n" -"# To define macros:\n" -"#\n" -"# %name list of hosts ...\n" -"#\n" -"# The first form tells xdm which displays to respond to itself.\n" -"# The second form tells xdm to forward indirect queries from hosts matching\n" -"# the specified pattern to the indicated list of hosts.\n" -"# The third form tells xdm to handle indirect queries using the chooser;\n" -"# the chooser is directed to send its own queries out via the broadcast\n" -"# address and display the results on the terminal.\n" -"# The fourth form is similar to the third, except instead of using the\n" -"# broadcast address, it sends DirectQuerys to each of the hosts in the list\n" -"#\n" -"# In all cases, xdm uses the first entry which matches the terminal;\n" -"# for IndirectQuery messages only entries with right hand sides can\n" -"# match, for Direct and Broadcast Query messages, only entries without\n" -"# right hand sides can match.\n" -"#\n" -"\n" -"#* #any host can get a login window\n" -"\n" -"#\n" -"# To hardwire a specific terminal to a specific host, you can\n" -"# leave the terminal sending indirect queries to this host, and\n" -"# use an entry of the form:\n" -"#\n" -"\n" -"#terminal-a host-a\n" -"\n" -"\n" -"#\n" -"# The nicest way to run the chooser is to just ask it to broadcast\n" -"# requests to the network - that way new hosts show up automatically.\n" -"# Sometimes, however, the chooser can't figure out how to broadcast,\n" -"# so this may not work in all environments.\n" -"#\n" -"\n" -"#* CHOOSER BROADCAST #any indirect host can get a chooser\n" -"\n" -"#\n" -"# If you'd prefer to configure the set of hosts each terminal sees,\n" -"# then just uncomment these lines (and comment the CHOOSER line above)\n" -"# and edit the %hostlist line as appropriate\n" -"#\n" -"\n" -"#%hostlist host-a host-b\n" -"\n" -"#* CHOOSER %hostlist #\n"; -#endif - -#ifdef XDMCP -static const char def_willing[] = -"#! /bin/sh\n" -"# The output of this script is displayed in the chooser window\n" -"# (instead of \"Willing to manage\").\n" -"\n" -"load=`uptime|sed -e 's/^.*load[^0-9]*//'`\n" -"nrusers=`who|cut -c 1-8|sort -u|wc -l|sed 's/^[ \t]*//'`\n" -"s=\"\"; [ \"$nrusers\" != 1 ] && s=s\n" -"\n" -"echo \"${nrusers} user${s}, load: ${load}\"\n"; -#endif - -static const char def_setup[] = -"#! /bin/sh\n" -"# Xsetup - run as root before the login dialog appears\n" -"\n" -"#xconsole -geometry 480x130-0-0 -notify -verbose -fn fixed -exitOnFail -file /dev/xconsole &\n"; - -static const char def_startup[] = -"#! /bin/sh\n" -"# Xstartup - run as root before session starts\n" -"\n" -"\n" -"\n" -"if [ -e /etc/nologin ]; then\n" -" # always display the nologin message, if possible\n" -" if [ -s /etc/nologin ] && which xmessage > /dev/null 2>&1; then\n" -" xmessage -file /etc/nologin -geometry 640x480\n" -" fi\n" -" if [ \"$(id -u)\" != \"0\" ] && \\\n" -" ! grep -qs '^ignore-nologin' /etc/trinity/tdm/tdm.options; then\n" -" exit 1\n" -" fi\n" -"fi\n" -"\n" -"if grep -qs '^use-sessreg' /etc/trinity/tdm/tdm.options && \\\n" -" which sessreg > /dev/null 2>&1; then\n" -" exec sessreg -a -l \"$DISPLAY\" -u /var/run/utmp \\\n" -" -h \"`echo $DISPLAY | cut -d: -f1`\" \"$USER\"\n" -" # NOTREACHED\n" -"fi\n"; - -static const char def_reset[] = -"#! /bin/sh\n" -"# Xreset - run as root after session exits\n" -"\n" -"# Reassign ownership of the console to root, this should disallow\n" -"# assignment of console output to any random users's xterm. See Xstartup.\n" -"#\n" -"#chown root /dev/console\n" -"#chmod 622 /dev/console\n" -"\n" -#ifdef _AIX -"#devname=`echo $DISPLAY | cut -c1-8`\n" -"#exec sessreg -d -l xdm/$devname -h \"`echo $DISPLAY | cut -d: -f1`\"" -#else -"if grep -qs '^use-sessreg' /etc/trinity/tdm/tdm.options && \\\n" -" which sessreg > /dev/null 2>&1; then\n" -" exec sessreg -d -l \"$DISPLAY\" -u /var/run/utmp \\\n" -" -h \"`echo $DISPLAY | cut -d: -f1`\" \"$USER\"\n" -" # NOTREACHED\n" -"fi\n"; -#endif /* _AIX */ - -static const char def_session1[] = -"#! /bin/sh\n" -"# Xsession - run as user\n" -"\n" -"session=$1\n" -"\n" -"# Note that the respective logout scripts are not sourced.\n" -"case $SHELL in\n" -" */bash)\n" -" [ -z \"$BASH\" ] && exec $SHELL $0 \"$@\"\n" -" set +o posix\n" -" [ -f /etc/profile ] && . /etc/profile\n" -" if [ -f $HOME/.bash_profile ]; then\n" -" . $HOME/.bash_profile\n" -" elif [ -f $HOME/.bash_login ]; then\n" -" . $HOME/.bash_login\n" -" elif [ -f $HOME/.profile ]; then\n" -" . $HOME/.profile\n" -" fi\n" -" ;;\n" -" */zsh)\n" -" [ -z \"$ZSH_NAME\" ] && exec $SHELL $0 \"$@\"\n" -" emulate -R zsh\n" -" [ -d /etc/zsh ] && zdir=/etc/zsh || zdir=/etc\n" -" zhome=${ZDOTDIR:-$HOME}\n" -" # zshenv is always sourced automatically.\n" -" [ -f $zdir/zprofile ] && . $zdir/zprofile\n" -" [ -f $zhome/.zprofile ] && . $zhome/.zprofile\n" -" [ -f $zdir/zlogin ] && . $zdir/zlogin\n" -" [ -f $zhome/.zlogin ] && . $zhome/.zlogin\n" -" setopt shwordsplit noextendedglob\n" -" ;;\n" -" */csh|*/tcsh)\n" -" # [t]cshrc is always sourced automatically.\n" -" # Note that sourcing csh.login after .cshrc is non-standard.\n" -" xsess_tmp="; -static const char def_session2[] = -"\n" -" $SHELL -c \"if (-f /etc/csh.login) source /etc/csh.login; if (-f ~/.login) source ~/.login; /bin/sh -c export -p >! $xsess_tmp\"\n" -" . $xsess_tmp\n" -" rm -f $xsess_tmp\n" -" ;;\n" -" *) # Plain sh, ksh, and anything we don't know.\n" -" [ -f /etc/profile ] && . /etc/profile\n" -" [ -f $HOME/.profile ] && . $HOME/.profile\n" -" ;;\n" -"esac\n" -"# invoke global X session script\n" -". /etc/X11/Xsession\n"; - -static const char def_background[] = -"[Desktop0]\n" -"BackgroundMode=Flat\n" -"BlendBalance=100\n" -"BlendMode=NoBlending\n" -"ChangeInterval=60\n" -"Color1=0,0,200\n" -"Color2=192,192,192\n" -"CurrentWallpaper=0\n" -"LastChange=0\n" -"MinOptimizationDepth=1\n" -"MultiWallpaperMode=NoMulti\n" -"Pattern=fish\n" -"Program=\n" -"ReverseBlending=false\n" -"UseSHM=false\n" -"Wallpaper=isadora.png\n" -"WallpaperList=\n" -"WallpaperMode=Scaled\n"; - -static char * -prepName( const char *fn ) -{ - const char *tname; - char *nname; - - tname = strrchr( fn, '/' ); - ASPrintf( &nname, "%s/%s", newdir, tname ? tname + 1 : fn ); - displace( nname ); - return nname; -} - -static FILE * -Create( const char *fn, int mode ) -{ - char *nname; - FILE *f; - - nname = prepName( fn ); - if (!(f = fopen( nname, "w" ))) { - fprintf( stderr, "Cannot create %s\n", nname ); - exit( 1 ); - } - chmod( nname, mode ); - free( nname ); - return f; -} - -static void -WriteOut( const char *fn, int mode, time_t stamp, const char *buf, size_t len ) -{ - char *nname; - int fd; - struct utimbuf utim; - - nname = prepName( fn ); - if ((fd = creat( nname, mode )) < 0) { - fprintf( stderr, "Cannot create %s\n", nname ); - exit( 1 ); - } - write( fd, buf, len ); - close( fd ); - if (stamp) { - utim.actime = utim.modtime = stamp; - utime( nname, &utim ); - } - free( nname ); -} - - -/* returns static array! */ -static const char * -resect( const char *sec, const char *name ) -{ - static char sname[64]; - char *p; - - if ((p = strrchr( sec, '-' ))) { - sprintf( sname, "%.*s-%s", p - sec, sec, name ); - return sname; - } else - return name; -} - -static int -inNewDir( const char *name ) -{ - return !memcmp( name, TDMCONF "/", sizeof(TDMCONF) ); -} - -static int -inList( StrList *sp, const char *s ) -{ - for (; sp; sp = sp->next) - if (!strcmp( sp->str, s )) - return 1; - return 0; -} - -static void -addStr( StrList **sp, const char *s ) -{ - for (; *sp; sp = &(*sp)->next) - if (!strcmp( (*sp)->str, s )) - return; - *sp = mcalloc( sizeof(**sp) ); - ASPrintf( (char **)&(*sp)->str, "%s", s ); -} - -StrList *aflist, *uflist, *eflist, *cflist, *lflist; - -/* file is part of new config */ -static void -addedFile( const char *fn ) -{ - addStr( &aflist, fn ); -} - -/* file from old config was parsed */ -static void -usedFile( const char *fn ) -{ - addStr( &uflist, fn ); -} - -/* file from old config was copied with slight modifications */ -static void -editedFile( const char *fn ) -{ - addStr( &eflist, fn ); -} - -/* file from old config was copied verbatim */ -static void -copiedFile( const char *fn ) -{ - addStr( &cflist, fn ); -} - -/* file from old config is still being used */ -static void -linkedFile( const char *fn ) -{ - addStr( &lflist, fn ); -} - -/* - * XXX this stuff is highly borked. it does not handle collisions at all. - */ -static int -copyfile( Entry *ce, const char *tname, int mode, int (*proc)( File * ) ) -{ - const char *tptr; - char *nname; - File file; - int rt; - - if (!*ce->value) - return 1; - - tptr = strrchr( tname, '/' ); - ASPrintf( &nname, TDMCONF "/%s", tptr ? tptr + 1 : tname ); - if (inList( cflist, ce->value ) || - inList( eflist, ce->value ) || - inList( lflist, ce->value )) - { - rt = 1; - goto doret; - } - if (!readFile( &file, ce->value )) { - fprintf( stderr, "Warning: cannot copy file %s\n", ce->value ); - rt = 0; - } else { - if (!proc || !proc( &file )) { - if (!use_destdir && !strcmp( ce->value, nname )) - linkedFile( nname ); - else { - struct stat st; - stat( ce->value, &st ); - WriteOut( nname, mode, st.st_mtime, file.buf, file.eof - file.buf ); - copiedFile( ce->value ); - } - } else { - WriteOut( nname, mode, 0, file.buf, file.eof - file.buf ); - editedFile( ce->value ); - } - if (strcmp( ce->value, nname ) && inNewDir( ce->value ) && !use_destdir) - displace( ce->value ); - addedFile( nname ); - rt = 1; - } - doret: - ce->value = nname; - return rt; -} - -static void -dlinkfile( const char *name ) -{ - File file; - - if (!readFile( &file, name )) { - fprintf( stderr, "Warning: cannot read file %s\n", name ); - return; - } - if (inNewDir( name ) && use_destdir) { - struct stat st; - stat( name, &st ); - WriteOut( name, st.st_mode, st.st_mtime, file.buf, file.eof - file.buf ); - copiedFile( name ); - } else - linkedFile( name ); - addedFile( name ); -} - -static void -linkfile( Entry *ce ) -{ - if (ce->written && *ce->value) - dlinkfile( ce->value ); -} - -static void -writefile( const char *tname, int mode, const char *cont ) -{ - WriteOut( tname, mode, 0, cont, strlen( cont ) ); - addedFile( tname ); -} - - -char *background; - -static void -handBgCfg( Entry *ce, Section *cs ATTR_UNUSED ) -{ - if (!ce->active) /* can be only the X-*-Greeter one */ - writefile( def_BackgroundCfg, 0644, - background ? background : def_background ); -#if 0 /* risk of kcontrol clobbering the original file */ - else if (old_confs) - linkfile( ce ); -#endif - else { - if (!copyfile( ce, ce->value, 0644, 0 )) { - if (!strcmp( cs->name, "X-*-Greeter" )) - writefile( def_BackgroundCfg, 0644, def_background ); - ce->active = 0; - } - } -} - - -#ifdef HAVE_VTS -static char * -mem_mem( char *mem, int lmem, const char *smem, int lsmem ) -{ - for (; lmem >= lsmem; mem++, lmem--) - if (!memcmp( mem, smem, lsmem )) - return mem + lsmem; - return 0; -} - -static int maxTTY, TTYmask; - -static void -getInitTab( void ) -{ - File it; - char *p, *eol, *ep; - int tty; - - if (maxTTY) - return; - if (!maxTTY) { - maxTTY = 6; - TTYmask = 0x3f; - } -} -#endif - - -/* TODO: handle solaris' local_uid specs */ - -static char * -ReadWord( File *file, int EOFatEOL ) -{ - char *wordp, *wordBuffer; - int quoted; - char c; - - rest: - wordp = wordBuffer = file->cur; - mloop: - quoted = 0; - qloop: - if (file->cur == file->eof) { - doeow: - if (wordp == wordBuffer) - return 0; - retw: - *wordp = '\0'; - return wordBuffer; - } - c = *file->cur++; - switch (c) { - case '#': - if (quoted) - break; - do { - if (file->cur == file->eof) - goto doeow; - c = *file->cur++; - } while (c != '\n'); - case '\0': - case '\n': - if (EOFatEOL && !quoted) { - file->cur--; - goto doeow; - } - if (wordp != wordBuffer) { - file->cur--; - goto retw; - } - goto rest; - case ' ': - case '\t': - if (wordp != wordBuffer) - goto retw; - goto rest; - case '\\': - if (!quoted) { - quoted = 1; - goto qloop; - } - break; - } - *wordp++ = c; - goto mloop; -} - -/* backslashes are double-escaped - for KConfig and for parseArgs */ -static const char * -joinArgs( StrList *argv ) -{ - StrList *av; - const char *s, *rs; - char *str; - int slen; - - if (!argv) - return ""; - for (slen = 0, av = argv; slen++, av; av = av->next) { - int nq = 0; - for (s = av->str; *s; s++, slen++) - if (isspace( *s ) || *s == '\'') - nq = 2; - else if (*s == '"') - slen += 2; - else if (*s == '\\') - slen += 3; - slen += nq; - } - rs = str = mmalloc( slen ); - for (av = argv; av; av = av->next) { - int nq = 0; - for (s = av->str; *s; s++) - if (isspace( *s ) || *s == '\'') - nq = 2; - if (av != argv) - *str++ = ' '; - if (nq) - *str++ = '"'; - for (s = av->str; *s; s++) { - if (*s == '\\') - *str++ = '\\'; - if (*s == '"' || *s == '\\') { - *str++ = '\\'; - *str++ = '\\'; - } - *str++ = *s; - } - if (nq) - *str++ = '"'; - } - *str = 0; - return rs; -} - -# define dLocation 1 -# define dLocal 0 -# define dForeign 1 - -static struct displayMatch { - const char *name; - int len, type; -} displayTypes[] = { - { "local", 5, dLocal }, - { "foreign", 7, dForeign }, -}; - -static int -parseDisplayType( const char *string, const char **atPos ) -{ - struct displayMatch *d; - - *atPos = 0; - for (d = displayTypes; d < displayTypes + as(displayTypes); d++) { - if (!memcmp( d->name, string, d->len ) && - (!string[d->len] || string[d->len] == '@')) - { - if (string[d->len] == '@' && string[d->len + 1]) - *atPos = string + d->len + 1; - return d->type; - } - } - return -1; -} - -typedef struct serverEntry { - struct serverEntry *next; - const char *name, *class2, *console, *argvs, *arglvs; - StrList *argv, *arglv; - int type, reserve, vt; -} ServerEntry; - -static void -absorb_xservers( const char *sect ATTR_UNUSED, char **value ) -{ - ServerEntry *se, *se1, *serverList, **serverPtr; - const char *word, *word2; - char *sdpys, *rdpys; - StrList **argp, **arglp, *ap, *ap2; - File file; - int nldpys = 0, nrdpys = 0, dpymask = 0; - int cpcmd, cpcmdl; -#ifdef HAVE_VTS - int dn, cpvt, mtty; -#endif - - if (**value == '/') { - if (!readFile( &file, *value )) - return; - usedFile( *value ); - } else { - file.buf = *value; - file.eof = *value + strlen( *value ); - } - file.cur = file.buf; - - serverPtr = &serverList; -#ifdef HAVE_VTS - bustd: -#endif - while ((word = ReadWord( &file, 0 ))) { - se = mcalloc( sizeof(*se) ); - se->name = word; - if (!(word = ReadWord( &file, 1 ))) - continue; - se->type = parseDisplayType( word, &se->console ); - if (se->type < 0) { - se->class2 = word; - if (!(word = ReadWord( &file, 1 ))) - continue; - se->type = parseDisplayType( word, &se->console ); - if (se->type < 0) { - while (ReadWord( &file, 1 )); - continue; - } - } - word = ReadWord( &file, 1 ); - if (word && !strcmp( word, "reserve" )) { - se->reserve = 1; - word = ReadWord( &file, 1 ); - } - if (((se->type & dLocation) == dLocal) != (word != 0)) - continue; - argp = &se->argv; - arglp = &se->arglv; - while (word) { -#ifdef HAVE_VTS - if (word[0] == 'v' && word[1] == 't') - se->vt = atoi( word + 2 ); - else if (!strcmp( word, "-crt" )) { /* SCO style */ - if (!(word = ReadWord( &file, 1 )) || - memcmp( word, "/dev/tty", 8 )) - goto bustd; - se->vt = atoi( word + 8 ); - } else -#endif - if (strcmp( word, se->name )) { - ap = mmalloc( sizeof(*ap) ); - ap->str = word; - if (!strcmp( word, "-nolisten" )) { - if (!(word2 = ReadWord( &file, 1 ))) - break; - ap2 = mmalloc( sizeof(*ap2) ); - ap2->str = word2; - ap->next = ap2; - if (!strcmp( word2, "unix" )) { - *argp = ap; - argp = &ap2->next; - } else { - *arglp = ap; - arglp = &ap2->next; - } - } else { - *argp = ap; - argp = &ap->next; - } - } - word = ReadWord( &file, 1 ); - } - *argp = *arglp = 0; - if ((se->type & dLocation) == dLocal) { - nldpys++; - dpymask |= 1 << atoi( se->name + 1 ); - if (se->reserve) - nrdpys++; - } - *serverPtr = se; - serverPtr = &se->next; - } - *serverPtr = 0; - -#ifdef HAVE_VTS - /* don't copy only if all local displays are ordered and have a vt */ - cpvt = 0; - getInitTab(); - for (se = serverList, mtty = maxTTY; se; se = se->next) - if ((se->type & dLocation) == dLocal) { - mtty++; - if (se->vt != mtty) { - cpvt = 1; - break; - } - } -#endif - - for (se = serverList; se; se = se->next) { - se->argvs = joinArgs( se->argv ); - se->arglvs = joinArgs( se->arglv ); - } - - se1 = 0, cpcmd = cpcmdl = 0; - for (se = serverList; se; se = se->next) - if ((se->type & dLocation) == dLocal) { - if (!se1) - se1 = se; - else { - if (strcmp( se1->argvs, se->argvs )) - cpcmd = 1; - if (strcmp( se1->arglvs, se->arglvs )) - cpcmdl = 1; - } - } - if (se1) { - putfqval( "X-:*-Core", "ServerCmd", se1->argvs ); - putfqval( "X-:*-Core", "ServerArgsLocal", se1->arglvs ); - for (se = serverList; se; se = se->next) - if ((se->type & dLocation) == dLocal) { - char sec[32]; - sprintf( sec, "X-%s-Core", se->name ); - if (cpcmd) - putfqval( sec, "ServerCmd", se->argvs ); - if (cpcmdl) - putfqval( sec, "ServerArgsLocal", se->arglvs ); -#ifdef HAVE_VTS - if (cpvt && se->vt) { - char vt[8]; - sprintf( vt, "%d", se->vt ); - putfqval( sec, "ServerVT", vt ); - } -#else - if (se->console) - putfqval( sec, "ServerTTY", se->console ); -#endif - } - } - - sdpys = rdpys = 0; - for (se = serverList; se; se = se->next) - StrCat( se->reserve ? &rdpys : &sdpys, - se->class2 ? ",%s_%s" : ",%s", se->name, se->class2 ); - -#ifdef HAVE_VTS - /* add reserve dpys */ - if (nldpys < 4 && nldpys && !nrdpys) - for (; nldpys < 4; nldpys++) { - for (dn = 0; dpymask & (1 << dn); dn++); - dpymask |= (1 << dn); - StrCat( &rdpys, ",:%d", dn ); - } -#endif - - putfqval( "General", "StaticServers", sdpys ? sdpys + 1 : "" ); - putfqval( "General", "ReserveServers", rdpys ? rdpys + 1 : "" ); - - if (**value == '/' && inNewDir( *value ) && !use_destdir) - displace( *value ); -} - -#ifdef HAVE_VTS -static void -upd_servervts( Entry *ce, Section *cs ATTR_UNUSED ) -{ - if (!ce->active) { /* there is only the Global one */ -#ifdef __linux__ /* XXX actually, sysvinit */ - getInitTab(); - ASPrintf( (char **)&ce->value, "-%d", maxTTY + 1 ); - ce->active = ce->written = 1; -#endif - } -} - -static void -upd_consolettys( Entry *ce, Section *cs ATTR_UNUSED ) -{ - if (!ce->active) { /* there is only the Global one */ -#ifdef __linux__ /* XXX actually, sysvinit */ - char *buf; - int i; - - getInitTab(); - for (i = 0, buf = 0; i < 16; i++) - if (TTYmask & (1 << i)) - StrCat( &buf, ",tty%d", i + 1 ); - if (buf) { - ce->value = buf + 1; - ce->active = ce->written = 1; - } -#endif - } -} -#endif - -#ifdef XDMCP -static void -cp_keyfile( Entry *ce, Section *cs ATTR_UNUSED ) -{ - if (!ce->active) /* there is only the Global one */ - return; - if (old_confs) - linkfile( ce ); - else - if (!copyfile( ce, "tdmkeys", 0600, 0 )) - ce->active = 0; -} - -static void -mk_xaccess( Entry *ce, Section *cs ATTR_UNUSED ) -{ - if (!ce->active) /* there is only the Global one */ - writefile( def_Xaccess, 0644, def_xaccess ); - else if (old_confs) - linkfile( ce ); - else - copyfile( ce, "Xaccess", 0644, 0 ); /* don't handle error, it will disable Xdmcp automatically */ -} - -static void -mk_willing( Entry *ce, Section *cs ATTR_UNUSED ) -{ - char *fname; - - if (!ce->active) /* there is only the Global one */ - goto dflt; - else { - if (!(fname = strchr( ce->value, '/' ))) - return; /* obviously in-line (or empty) */ - if (old_scripts || inNewDir( fname )) - dlinkfile( fname ); - else { - dflt: - ce->value = TDMCONF "/Xwilling"; - ce->active = ce->written = 1; - writefile( ce->value, 0755, def_willing ); - } - } -} -#endif - -/* -static int -edit_resources( File *file ) -{ - // XXX remove any login*, chooser*, ... resources - return 0; -} -*/ - -static void -cp_resources( Entry *ce, Section *cs ATTR_UNUSED ) -{ - if (!ce->active) /* the X-*-Greeter one */ - return; - if (old_confs) - linkfile( ce ); - else - if (!copyfile( ce, ce->value, 0644, 0/*edit_resources*/ )) - ce->active = 0; -} - -static int -delstr( File *fil, const char *pat ) -{ - char *p, *pp, *bpp; - const char *pap, *paap; - - *fil->eof = 0; - for (p = fil->buf; *p; p++) { - for (pp = p, pap = pat; ; ) { - if (!*pap) { - *p = '\n'; - memcpy( p + 1, pp, fil->eof - pp + 1 ); - fil->eof -= pp - p - 1; - return 1; - } else if (!memcmp( pap, "*/", 2 )) { - paap = pap += 2; - while (!isspace( *pap )) - pap++; - if (*pp != '/') - break; - for (;;) - for (bpp = ++pp; *pp != '/'; pp++) - if (!*pp || isspace( *pp )) - goto wbrk; - wbrk: - if ((pp - bpp != pap - paap) || memcmp( bpp, paap, pap - paap )) - break; - } else if (*pap == '\t') { - pap++; - while (*pp == ' ' || *pp == '\t') - pp++; - } else if (*pap == '[') { - pap++; - for (;;) { - if (!*pap) { - fprintf( stderr, "Internal error: unterminated char set\n" ); - exit( 1 ); - } - if (*pap == *pp) { - while (*++pap != ']') - if (!*pap) { - fprintf( stderr, "Internal error: unterminated char set\n" ); - exit( 1 ); - } - pap++; - pp++; - break; - } - if (*++pap == ']') - goto no; - } - } else { - if (*pap == '\n') - while (*pp == ' ' || *pp == '\t') - pp++; - if (*pap != *pp) - break; - pap++; - pp++; - } - } - no: ; - } - return 0; -} - -/* XXX - the UseBackground voodoo will horribly fail, if multiple sections link - to the same Xsetup file -*/ - -static int mod_usebg; - -static int -edit_setup( File *file ) -{ - int chg = - delstr( file, "\n" - "(\n" - " PIDFILE=/var/run/tdmdesktop-$DISPLAY.pid\n" - " */tdmdesktop\t&\n" - " echo $! >$PIDFILE\n" - " wait $!\n" - " rm $PIDFILE\n" - ")\t&\n" ) | - delstr( file, "\n" - "*/tdmdesktop\t&\n" ) | - delstr( file, "\n" - "tdmdesktop\t&\n" ) | - delstr( file, "\n" - "tdmdesktop\n" ); - putval( "UseBackground", chg ? "true" : "false" ); - return chg; -} - -static void -mk_setup( Entry *ce, Section *cs ) -{ - setsect( resect( cs->name, "Greeter" ) ); - if (old_scripts || mixed_scripts) { - if (mod_usebg && *ce->value) - putval( "UseBackground", "false" ); - linkfile( ce ); - } else { - if (ce->active && inNewDir( ce->value )) { - if (mod_usebg) - copyfile( ce, ce->value, 0755, edit_setup ); - else - linkfile( ce ); - } else { - ce->value = TDMCONF "/Xsetup"; - ce->active = ce->written = 1; - writefile( ce->value, 0755, def_setup ); - } - } -} - -static int -edit_startup( File *file ) -{ - int chg1 = 0, chg2 = 0; - - if (mod_usebg && - (delstr( file, "\n" - "PIDFILE=/var/run/tdmdesktop-$DISPLAY.pid\n" - "if [[] -f $PIDFILE ] ; then\n" - " kill `cat $PIDFILE`\n" - "fi\n" ) || - delstr( file, "\n" - "PIDFILE=/var/run/tdmdesktop-$DISPLAY.pid\n" - "test -f $PIDFILE && kill `cat $PIDFILE`\n" ))) - chg1 = 1; - if (oldver < 0x0203) { - chg2 = -#ifdef _AIX - delstr( file, "\n" -"# We create a pseudodevice for finger. (host:0 becomes [kx]dm/host_0)\n" ); -"# Without it, finger errors out with \"Can't stat /dev/host:0\".\n" -"#\n" -"if [[] -f /usr/lib/X11/xdm/sessreg ]; then\n" -" devname=`echo $DISPLAY | /usr/bin/sed -e 's/[[]:\\.]/_/g' | /usr/bin/cut -c1-8`\n" -" hostname=`echo $DISPLAY | /usr/bin/cut -d':' -f1`\n" -"\n" -" if [[] -z \"$devname\" ]; then\n" -" devname=\"unknown\"\n" -" fi\n" -" if [[] ! -d /dev/[kx]dm ]; then\n" -" /usr/bin/mkdir /dev/[kx]dm\n" -" /usr/bin/chmod 755 /dev/[kx]dm\n" -" fi\n" -" /usr/bin/touch /dev/[kx]dm/$devname\n" -" /usr/bin/chmod 644 /dev/[kx]dm/$devname\n" -"\n" -" if [[] -z \"$hostname\" ]; then\n" -" exec /usr/lib/X11/xdm/sessreg -a -l [kx]dm/$devname $USER\n" -" else\n" -" exec /usr/lib/X11/xdm/sessreg -a -l [kx]dm/$devname -h $hostname $USER\n" -" fi\n" -"fi\n") | -#else -# ifdef BSD - delstr( file, "\n" -"exec sessreg -a -l $DISPLAY -x */Xservers -u " _PATH_UTMP " $USER\n" ) | -# endif -#endif /* _AIX */ - delstr( file, "\n" -"exec sessreg -a -l $DISPLAY" -#ifdef BSD -" -x */Xservers" -#endif -" $USER\n" ) | - delstr( file, "\n" -"exec sessreg -a -l $DISPLAY -u /var/run/utmp -x */Xservers $USER\n" ); - putval( "UseSessReg", chg2 ? "true" : "false"); - } - return chg1 | chg2; -} - -static void -mk_startup( Entry *ce, Section *cs ) -{ - setsect( cs->name ); - if (old_scripts || mixed_scripts) - linkfile( ce ); - else { - if (ce->active && inNewDir( ce->value )) { - if (mod_usebg || oldver < 0x0203) - copyfile( ce, ce->value, 0755, edit_startup ); - else - linkfile( ce ); - } else { - ce->value = TDMCONF "/Xstartup"; - ce->active = ce->written = 1; - writefile( ce->value, 0755, def_startup ); - } - } -} - -static int -edit_reset( File *file ) -{ - return -#ifdef _AIX - delstr( file, "\n" -"if [[] -f /usr/lib/X11/xdm/sessreg ]; then\n" -" devname=`echo $DISPLAY | /usr/bin/sed -e 's/[[]:\\.]/_/g' | /usr/bin/cut -c1-8`\n" -" exec /usr/lib/X11/xdm/sessreg -d -l [kx]dm/$devname $USER\n" -"fi\n" ) | -#else -# ifdef BSD - delstr( file, "\n" -"exec sessreg -d -l $DISPLAY -x */Xservers -u " _PATH_UTMP " $USER\n" ) | -# endif -#endif /* _AIX */ - delstr( file, "\n" -"exec sessreg -d -l $DISPLAY" -# ifdef BSD -" -x */Xservers" -# endif -" $USER\n" ) | - delstr( file, "\n" -"exec sessreg -d -l $DISPLAY -u /var/run/utmp -x */Xservers $USER\n" ); -} - -static void -mk_reset( Entry *ce, Section *cs ATTR_UNUSED ) -{ - if (old_scripts || mixed_scripts) - linkfile( ce ); - else { - if (ce->active && inNewDir( ce->value )) { - if (oldver < 0x0203) - copyfile( ce, ce->value, 0755, edit_reset ); - else - linkfile( ce ); - } else { - ce->value = TDMCONF "/Xreset"; - ce->active = ce->written = 1; - writefile( ce->value, 0755, def_reset ); - } - } -} - -static void -mk_session( Entry *ce, Section *cs ATTR_UNUSED ) -{ - char *def_session; - const char *tmpf; - - if ((old_scripts || (ce->active && inNewDir( ce->value ))) && - oldver >= 0x202) - linkfile( ce ); - else { - tmpf = locate( "mktemp" ) ? - "`mktemp /tmp/xsess-env-XXXXXX`" : - locate( "tempfile" ) ? - "`tempfile`" : - "$HOME/.xsession-env-$DISPLAY"; - ASPrintf( &def_session, "%s%s%s", def_session1, tmpf, def_session2 ); - ce->value = TDMCONF "/Xsession"; - ce->active = ce->written = 1; - writefile( ce->value, 0755, def_session ); - } -} - -static void -upd_language( Entry *ce, Section *cs ATTR_UNUSED ) -{ - if (!strcmp( ce->value, "C" )) - ce->value = (char *)"en_US"; -} - -static void -upd_guistyle( Entry *ce, Section *cs ATTR_UNUSED ) -{ - if (!strcmp( ce->value, "Motif+" )) - ce->value = (char *)"MotifPlus"; - else if (!strcmp( ce->value, "KDE" )) - ce->value = (char *)"Default"; -} - -static void -upd_showusers( Entry *ce, Section *cs ) -{ - if (!strcmp( ce->value, "All" )) - ce->value = (char *)"NotHidden"; - else if (!strcmp( ce->value, "None" )) { - if (ce->active) - putfqval( cs->name, "UserList", "false" ); - ce->value = (char *)"Selected"; - ce->active = 0; - ce->written = 1; - } -} - -static const char *defminuid, *defmaxuid; - -static void -upd_minshowuid( Entry *ce, Section *cs ATTR_UNUSED ) -{ - if (!ce->active) { - ce->value = defminuid; - ce->active = ce->written = 1; - } -} - -static void -upd_maxshowuid( Entry *ce, Section *cs ATTR_UNUSED ) -{ - if (!ce->active) { - ce->value = defmaxuid; - ce->active = ce->written = 1; - } -} - -static void -upd_hiddenusers( Entry *ce, Section *cs ATTR_UNUSED ) -{ - char *nv; - const char *msu, *pt, *et; - struct passwd *pw; - unsigned minuid, maxuid; - char nbuf[128]; - - if (!ce->active) - return; - - msu = getfqval( cs->name, "MinShowUID", "0" ); - sscanf( msu, "%u", &minuid ); - msu = getfqval( cs->name, "MaxShowUID", "65535" ); - sscanf( msu, "%u", &maxuid ); - - nv = 0; - pt = ce->value; - for (;;) { - et = strpbrk( pt, ";," ); - if (et) { - memcpy( nbuf, pt, et - pt ); - nbuf[et - pt] = 0; - } else - strcpy( nbuf, pt ); - if ((pw = getpwnam( nbuf ))) { - if (!pw->pw_uid || - (pw->pw_uid >= minuid && pw->pw_uid <= maxuid)) - { - if (nv) - StrCat( &nv, ",%s", nbuf ); - else - nv = mstrdup( nbuf ); - } - } - if (!et) - break; - pt = et + 1; - } - ce->value = nv ? nv : ""; -} - -static void -upd_forgingseed( Entry *ce, Section *cs ATTR_UNUSED ) -{ - if (!ce->active) { - ASPrintf( (char **)&ce->value, "%d", time( 0 ) ); - ce->active = ce->written = 1; - } -} - -static void -upd_fifodir( Entry *ce, Section *cs ATTR_UNUSED ) -{ - const char *dir; - struct stat st; - - if (use_destdir) - return; - dir = ce->active ? ce->value : def_FifoDir; - stat( dir, &st ); - chmod( dir, st.st_mode | 0755 ); -} - -static void -upd_datadir( Entry *ce, Section *cs ATTR_UNUSED ) -{ - char *oldsts, *newsts; - const char *dir; - - if (use_destdir) - return; - dir = ce->active ? ce->value : def_DataDir; - if (mkdirp( dir, 0755, "data", 0 ) && oldkde) { - ASPrintf( &oldsts, "%s/tdm/tdmsts", oldkde ); - ASPrintf( &newsts, "%s/tdmsts", dir ); - rename( oldsts, newsts ); - } -} - -static void -CopyFile( const char *from, const char *to ) -{ - File file; - int fd; - - if (readFile( &file, from )) { - if ((fd = creat( to, 0644 )) >= 0) { - write( fd, file.buf, file.eof - file.buf ); - close( fd ); - } - freeBuf( &file ); - } -} - -static void -upd_facedir( Entry *ce, Section *cs ATTR_UNUSED ) -{ - char *oldpic, *newpic, *defpic, *rootpic; - const char *dir; - struct passwd *pw; - - if (use_destdir) - return; - dir = ce->active ? ce->value : def_FaceDir; - if (mkdirp( dir, 0755, "user face", 0 )) { - ASPrintf( &defpic, "%s/.default.face.icon", dir ); - ASPrintf( &rootpic, "%s/root.face.icon", dir ); - if (oldkde) { - setpwent(); - while ((pw = getpwent())) - if (strcmp( pw->pw_name, "root" )) { - ASPrintf( &oldpic, "%s/../apps/tdm/pics/users/%s.png", - oldkde, pw->pw_name ); - ASPrintf( &newpic, "%s/%s.face.icon", dir, pw->pw_name ); - rename( oldpic, newpic ); - free( newpic ); - free( oldpic ); - } - endpwent(); - ASPrintf( &oldpic, "%s/../apps/tdm/pics/users/default.png", oldkde ); - if (!rename( oldpic, defpic )) - defpic = 0; - ASPrintf( &oldpic, "%s/../apps/tdm/pics/users/root.png", oldkde ); - if (!rename( oldpic, rootpic )) - rootpic = 0; - } - if (defpic) { - ASPrintf( &oldpic, "%s/default1.png", facesrc ); - CopyFile( oldpic, defpic ); - } - if (rootpic) { - ASPrintf( &oldpic, "%s/root1.png", facesrc ); - CopyFile( oldpic, rootpic ); - } - } -} - -CONF_GEN_ENTRIES - -static Sect * -findSect( const char *name ) -{ - const char *p; - int i; - - p = strrchr( name, '-' ); - if (!p) - p = name; - for (i = 0; i < as(allSects); i++) - if (!strcmp( allSects[i]->name, p )) - return allSects[i]; - fprintf( stderr, "Internal error: unknown section %s\n", name ); - exit( 1 ); -} - -static Ent * -findEnt( Sect *sect, const char *key ) -{ - int i; - - for (i = 0; i < sect->nents; i++) - if (!strcmp( sect->ents[i].key, key )) - return sect->ents + i; - fprintf( stderr, "Internal error: unknown key %s in section %s\n", - key, sect->name ); - exit( 1 ); -} - - -/* - * defaults - */ - -typedef struct DEnt { - const char *key; - const char *value; - int active; -} DEnt; - -typedef struct DSect { - const char *name; - DEnt *ents; - int nents; - const char *comment; -} DSect; - -CONF_GEN_EXAMPLE - -static void -mkdefconf( void ) -{ - Section *cs, **csp; - Entry *ce, **cep; - int sc, ec; - - for (csp = &config, sc = 0; sc < as(dAllSects); csp = &(cs->next), sc++) { - cs = mcalloc( sizeof(*cs) ); - *csp = cs; - cs->spec = findSect( dAllSects[sc].name ); - cs->name = dAllSects[sc].name; - cs->comment = dAllSects[sc].comment; - for (cep = &(cs->ents), ec = 0; ec < dAllSects[sc].nents; - cep = &(ce->next), ec++) - { - ce = mcalloc( sizeof(*ce) ); - *cep = ce; - ce->spec = findEnt( cs->spec, dAllSects[sc].ents[ec].key ); - ce->value = dAllSects[sc].ents[ec].value; - ce->active = dAllSects[sc].ents[ec].active; - } - } -} - - -/* - * read rc file structure - */ - -typedef struct REntry { - struct REntry *next; - const char *key; - char *value; -} REntry; - -typedef struct RSection { - struct RSection *next; - const char *name; - REntry *ents; -} RSection; - -static RSection * -ReadConf( const char *fname ) -{ - char *nstr; - char *s, *e, *st, *en, *ek, *sl; - RSection *rootsec = 0, *cursec; - REntry *curent; - int nlen; - int line, sectmoan; - File file; - - if (!readFile( &file, fname )) - return 0; - usedFile( fname ); - - for (s = file.buf, line = 0, cursec = 0, sectmoan = 1; s < file.eof; s++) { - line++; - - while ((s < file.eof) && isspace( *s ) && (*s != '\n')) - s++; - - if ((s < file.eof) && ((*s == '\n') || (*s == '#'))) { - sktoeol: - while ((s < file.eof) && (*s != '\n')) - s++; - continue; - } - sl = s; - - if (*s == '[') { - while ((s < file.eof) && (*s != '\n')) - s++; - e = s - 1; - while ((e > sl) && isspace( *e )) - e--; - if (*e != ']') { - fprintf( stderr, "Invalid section header at %s:%d\n", - fname, line ); - continue; - } - sectmoan = 0; - nstr = sl + 1; - nlen = e - nstr; - for (cursec = rootsec; cursec; cursec = cursec->next) - if (!memcmp( nstr, cursec->name, nlen ) && - !cursec->name[nlen]) - { -#if 0 /* not our business ... */ - fprintf( stderr, "Warning: Multiple occurrences of section " - "[%.*s] in %s. Consider merging them.\n", - nlen, nstr, fname ); -#endif - goto secfnd; - } - cursec = mmalloc( sizeof(*cursec) ); - ASPrintf( (char **)&cursec->name, "%.*s", nlen, nstr ); - cursec->ents = 0; - cursec->next = rootsec; - rootsec = cursec; - secfnd: - continue; - } - - if (!cursec) { - if (sectmoan) { - sectmoan = 0; - fprintf( stderr, "Entry outside any section at %s:%d", - fname, line ); - } - goto sktoeol; - } - - for (; (s < file.eof) && (*s != '\n'); s++) - if (*s == '=') - goto haveeq; - fprintf( stderr, "Invalid entry (missing '=') at %s:%d\n", fname, line ); - continue; - - haveeq: - for (ek = s - 1;; ek--) { - if (ek < sl) { - fprintf( stderr, "Invalid entry (empty key) at %s:%d\n", - fname, line ); - goto sktoeol; - } - if (!isspace( *ek )) - break; - } - - s++; - while ((s < file.eof) && isspace( *s ) && (*s != '\n')) - s++; - st = s; - while ((s < file.eof) && (*s != '\n')) - s++; - for (en = s - 1; en >= st && isspace( *en ); en--); - - nstr = sl; - nlen = ek - sl + 1; - for (curent = cursec->ents; curent; curent = curent->next) - if (!memcmp( nstr, curent->key, nlen ) && - !curent->key[nlen]) { - fprintf( stderr, "Multiple occurrences of key '%s' in section " - "[%s] of %s.\n", curent->key, cursec->name, fname ); - goto keyfnd; - } - curent = mmalloc( sizeof(*curent) ); - ASPrintf( (char **)&curent->key, "%.*s", nlen, nstr ); - ASPrintf( (char **)&curent->value, "%.*s", en - st + 1, st ); - curent->next = cursec->ents; - cursec->ents = curent; - keyfnd: - continue; - } - return rootsec; -} - - -static int -mergeKdmRcOld( const char *path ) -{ - char *p; - struct stat st; - - ASPrintf( &p, "%s/tdmrc", path ); - if (stat( p, &st )) { - free( p ); - return 0; - } - printf( "Information: ignoring old tdmrc %s from kde < 2.2\n", p ); - free( p ); - return 1; -} - -typedef struct { - const char *sect, *key, *def; - int (*cond)( void ); -} FDefs; - -static void -applydefs( FDefs *chgdef, int ndefs, const char *path ) -{ - char *p; - int i; - - for (i = 0; i < ndefs; i++) - if (!getfqval( chgdef[i].sect, chgdef[i].key, 0 ) && - (!chgdef[i].cond || chgdef[i].cond())) - { - ASPrintf( &p, chgdef[i].def, path ); - putfqval( chgdef[i].sect, chgdef[i].key, p ); - free( p ); - } -} - -#ifdef XDMCP -static FDefs tdmdefs_all[] = { -{ "Xdmcp", "Xaccess", "%s/tdm/Xaccess", 0 }, -{ "Xdmcp", "Willing", "", 0 }, -}; -#endif - -static FDefs tdmdefs_eq_22[] = { -{ "General", "PidFile", "/var/run/xdm.pid", 0 }, -{ "X-*-Core", "Setup", "%s/tdm/Xsetup", 0 }, -{ "X-*-Core", "Startup", "%s/tdm/Xstartup", 0 }, -{ "X-*-Core", "Reset", "%s/tdm/Xreset", 0 }, -{ "X-*-Core", "Session", "%s/tdm/Xsession", 0 }, -}; - -#ifdef XDMCP -static int -if_xdmcp (void) -{ - return isTrue( getfqval( "Xdmcp", "Enable", "true" ) ); -} - -static FDefs tdmdefs_le_30[] = { -{ "Xdmcp", "KeyFile", "%s/tdm/tdmkeys", if_xdmcp }, -}; -#endif - -/* HACK: misused by is22conf() below */ -static FDefs tdmdefs_ge_30[] = { -{ "X-*-Core", "Setup", "", 0 }, -{ "X-*-Core", "Startup", "", 0 }, -{ "X-*-Core", "Reset", "", 0 }, -{ "X-*-Core", "Session", XBINDIR "/xterm -ls -T", 0 }, -}; - -static int -if_usebg (void) -{ - return isTrue( getfqval( "X-*-Greeter", "UseBackground", "true" ) ); -} - -static FDefs tdmdefs_ge_31[] = { -{ "X-*-Greeter","BackgroundCfg","%s/tdm/backgroundrc", if_usebg }, -}; - -static int -is22conf( const char *path ) -{ - char *p; - const char *val; - int i, sl; - - sl = ASPrintf( &p, "%s/tdm/", path ); - /* safe bet, i guess ... */ - for (i = 0; i < 4; i++) { - val = getfqval( "X-*-Core", tdmdefs_ge_30[i].key, 0 ); - if (val && !memcmp( val, p, sl )) { - free( p ); - return 0; - } - } - free( p ); - return 1; -} - -typedef struct KUpdEnt { - const char *okey, *nsec, *nkey; - void (*func)( const char *sect, char **value ); -} KUpdEnt; - -typedef struct KUpdSec { - const char *osec; - KUpdEnt *ents; - int nents; -} KUpdSec; - -#ifdef XDMCP -static void -P_EnableChooser( const char *sect ATTR_UNUSED, char **value ) -{ - *value = (char *)(isTrue( *value ) ? "DefaultLocal" : "LocalOnly"); -} -#endif - -static void -P_UseLilo( const char *sect ATTR_UNUSED, char **value ) -{ - *value = (char *)(isTrue( *value ) ? "Lilo" : "None"); -} - -CONF_GEN_KMERGE - -static int -mergeKdmRcNewer( const char *path ) -{ - char *p; - const char *cp, *sec, *key; - RSection *rootsect, *cs; - REntry *ce; - int i, j; - static char sname[64]; - - ASPrintf( &p, "%s/tdm/tdmrc", path ); - if (!(rootsect = ReadConf( p ))) { - free( p ); - return 0; - } - printf( "Information: reading current tdmrc %s (from kde >= 2.2.x)\n", p ); - free( p ); - - for (cs = rootsect; cs; cs = cs->next) { - if (!strcmp( cs->name, "Desktop0" )) { - background = mstrdup( "[Desktop0]\n" ); - for (ce = cs->ents; ce; ce = ce->next) - StrCat( &background, "%s=%s\n", ce->key, ce->value ); - } else { - cp = strrchr( cs->name, '-' ); - if (!cp) - cp = cs->name; - else if (cs->name[0] != 'X' || cs->name[1] != '-') - goto dropsec; - for (i = 0; i < as(kupsects); i++) - if (!strcmp( cp, kupsects[i].osec )) { - for (ce = cs->ents; ce; ce = ce->next) { - for (j = 0; j < kupsects[i].nents; j++) - if (!strcmp( ce->key, kupsects[i].ents[j].okey )) { - if (kupsects[i].ents[j].nsec == (char *)-1) { - kupsects[i].ents[j].func( 0, &ce->value ); - goto gotkey; - } - if (!kupsects[i].ents[j].nsec) - sec = cs->name; - else { - sec = sname; - sprintf( sname, "%.*s-%s", cp - cs->name, cs->name, - kupsects[i].ents[j].nsec ); - } - if (!kupsects[i].ents[j].nkey) - key = ce->key; - else - key = kupsects[i].ents[j].nkey; - if (kupsects[i].ents[j].func) - kupsects[i].ents[j].func( sec, &ce->value ); - putfqval( sec, key, ce->value ); - goto gotkey; - } - printf( "Information: dropping key %s from section [%s]\n", - ce->key, cs->name ); - gotkey: ; - } - goto gotsec; - } - dropsec: - printf( "Information: dropping section [%s]\n", cs->name ); - gotsec: ; - } - } - -#ifdef XDMCP - applydefs( tdmdefs_all, as(tdmdefs_all), path ); -#endif - if (!*(cp = getfqval( "General", "ConfigVersion", "" ))) { /* < 3.1 */ - mod_usebg = 1; - if (is22conf( path )) { - /* work around 2.2.x defaults borkedness */ - applydefs( tdmdefs_eq_22, as(tdmdefs_eq_22), path ); - printf( "Information: current tdmrc is from kde 2.2\n" ); - } else { - applydefs( tdmdefs_ge_30, as(tdmdefs_ge_30), path ); - printf( "Information: current tdmrc is from kde 3.0\n" ); - } -#ifdef XDMCP - /* work around minor <= 3.0.x defaults borkedness */ - applydefs( tdmdefs_le_30, as(tdmdefs_le_30), path ); -#endif - } else { - int ma, mi; - sscanf( cp, "%d.%d", &ma, &mi ); - oldver = (ma << 8) | mi; - printf( "Information: current tdmrc is from kde >= 3.1 (config version %d.%d)\n", ma, mi ); - applydefs( tdmdefs_ge_30, as(tdmdefs_ge_30), path ); - applydefs( tdmdefs_ge_31, as(tdmdefs_ge_31), path ); - } - - return 1; -} - - -typedef struct XResEnt { - const char *xname; - const char *ksec, *kname; - void (*func)( const char *sect, char **value ); -} XResEnt; - -static void -handleXdmVal( const char *dpy, const char *key, char *value, - const XResEnt *ents, int nents ) -{ - const char *kname; - int i; - char knameb[80], sname[80]; - - for (i = 0; i < nents; i++) - if (!strcmp( key, ents[i].xname ) || - (key[0] == toupper( ents[i].xname[0] ) && - !strcmp( key + 1, ents[i].xname + 1 ))) - { - if (ents[i].ksec == (char *)-1) { - ents[i].func (0, &value); - break; - } - sprintf( sname, ents[i].ksec, dpy ); - if (ents[i].kname) - kname = ents[i].kname; - else { - kname = knameb; - sprintf( knameb, "%c%s", - toupper( ents[i].xname[0] ), ents[i].xname + 1 ); - } - if (ents[i].func) - ents[i].func( sname, &value ); - putfqval( sname, kname, value ); - break; - } -} - -static void -P_List( const char *sect ATTR_UNUSED, char **value ) -{ - int is, d, s; - char *st; - - for (st = *value, is = d = s = 0; st[s]; s++) - if (st[s] == ' ' || st[s] == '\t') { - if (!is) - st[d++] = ','; - is = 1; - } else { - st[d++] = st[s]; - is = 0; - } - st[d] = 0; -} - -static void -P_authDir( const char *sect ATTR_UNUSED, char **value ) -{ - int l; - - l = strlen( *value ); - if (l < 4) { - *value = 0; - return; - } - if ((*value)[l-1] == '/') - (*value)[--l] = 0; - if (!strncmp( *value, "/tmp/", 5 ) || - !strncmp( *value, "/var/tmp/", 9 )) - { - printf( "Warning: Resetting inappropriate value %s for AuthDir to default\n", - *value ); - *value = 0; - return; - } - if ((l >= 4 && !strcmp( *value + l - 4, "/tmp" )) || - (l >= 6 && !strcmp( *value + l - 6, "/xauth" )) || - (l >= 8 && !strcmp( *value + l - 8, "/authdir" )) || - (l >= 10 && !strcmp( *value + l - 10, "/authfiles" ))) - return; - ASPrintf( value, "%s/authdir", *value ); -} - -static void -P_openDelay( const char *sect, char **value ) -{ - putfqval( sect, "ServerTimeout", *value ); -} - -static void -P_noPassUsers( const char *sect, char **value ATTR_UNUSED ) -{ - putfqval( sect, "NoPassEnable", "true" ); -} - -static void -P_autoUser( const char *sect, char **value ATTR_UNUSED ) -{ - putfqval( sect, "AutoLoginEnable", "true" ); -} - -#ifdef XDMCP -static void -P_requestPort( const char *sect, char **value ) -{ - if (!strcmp( *value, "0" )) { - *value = 0; - putfqval( sect, "Enable", "false" ); - } else - putfqval( sect, "Enable", "true" ); -} -#endif - -static int tdmrcmode = 0644; - -static void -P_autoPass( const char *sect ATTR_UNUSED, char **value ATTR_UNUSED ) -{ - tdmrcmode = 0600; -} - -CONF_GEN_XMERGE - -static XrmQuark XrmQString, empty = NULLQUARK; - -static Bool -DumpEntry( XrmDatabase *db ATTR_UNUSED, - XrmBindingList bindings, - XrmQuarkList quarks, - XrmRepresentation *type, - XrmValuePtr value, - XPointer data ATTR_UNUSED ) -{ - const char *dpy, *key; - int el, hasu; - char dpybuf[80]; - - if (*type != XrmQString) - return False; - if (*bindings == XrmBindLoosely || - strcmp( XrmQuarkToString (*quarks), "DisplayManager" )) - return False; - bindings++, quarks++; - if (!*quarks) - return False; - if (*bindings != XrmBindLoosely && !quarks[1]) { /* DM.foo */ - key = XrmQuarkToString (*quarks); - handleXdmVal( 0, key, value->addr, globents, as(globents) ); - return False; - } else if (*bindings == XrmBindLoosely && !quarks[1]) { /* DM*bar */ - dpy = "*"; - key = XrmQuarkToString (*quarks); - } else if (*bindings != XrmBindLoosely && quarks[1] && - *bindings != XrmBindLoosely && !quarks[2]) - { /* DM.foo.bar */ - dpy = dpybuf + 4; - strcpy( dpybuf + 4, XrmQuarkToString (*quarks) ); - for (hasu = 0, el = 4; dpybuf[el]; el++) - if (dpybuf[el] == '_') - hasu = 1; - if (!hasu/* && isupper (dpy[0])*/) { - dpy = dpybuf; - memcpy( dpybuf, "*:*_", 4 ); - } else { - for (; --el >= 0; ) - if (dpybuf[el] == '_') { - dpybuf[el] = ':'; - for (; --el >= 4; ) - if (dpybuf[el] == '_') - dpybuf[el] = '.'; - break; - } - } - key = XrmQuarkToString (quarks[1]); - } else - return False; - handleXdmVal( dpy, key, value->addr, dpyents, as(dpyents) ); - return False; -} - -static FDefs xdmdefs[] = { -#ifdef XDMCP -{ "Xdmcp", "Xaccess", "%s/Xaccess", 0 }, -{ "Xdmcp", "Willing", "", 0 }, -#endif -{ "X-*-Core", "Setup", "", 0 }, -{ "X-*-Core", "Startup", "", 0 }, -{ "X-*-Core", "Reset", "", 0 }, -{ "X-*-Core", "Session", "", 0 }, -}; - -static int -mergeXdmCfg( const char *path ) -{ - char *p; - XrmDatabase db; - - ASPrintf( &p, "%s/xdm-config", path ); - if ((db = XrmGetFileDatabase( p ))) { - printf( "Information: reading current xdm config file %s\n", p ); - usedFile( p ); - free( p ); - XrmEnumerateDatabase( db, &empty, &empty, XrmEnumAllLevels, - DumpEntry, (XPointer)0 ); - applydefs( xdmdefs, as(xdmdefs), path ); - mod_usebg = 1; - return 1; - } - free( p ); - return 0; -} - -static void -fwrapprintf( FILE *f, const char *msg, ... ) -{ - char *txt, *ftxt, *line; - va_list ap; - int col, lword, fspace; - - va_start( ap, msg ); - VASPrintf( &txt, msg, ap ); - va_end( ap ); - ftxt = 0; - for (line = txt, col = 0, lword = fspace = -1; line[col]; ) { - if (line[col] == '\n') { - StrCat( &ftxt, "%.*s", ++col, line ); - line += col; - col = 0; - lword = fspace = -1; - continue; - } else if (line[col] == ' ') { - if (lword >= 0) { - fspace = col; - lword = -1; - } - } else { - if (lword < 0) - lword = col; - if (col >= 78 && fspace >= 0) { - StrCat( &ftxt, "%.*s\n", fspace, line ); - line += lword; - col -= lword; - lword = 0; - fspace = -1; - } - } - col++; - } - free( txt ); - fputs( ftxt, f ); - free( ftxt ); -} - - -static const char *oldkdes[] = { - KDE_CONFDIR, - "/opt/trinity/share/config", - "/usr/local/trinity/share/config", - - "/opt/kde/share/config", - "/usr/local/kde/share/config", - "/usr/local/share/config", - "/usr/share/config", - - "/opt/kde2/share/config", - "/usr/local/kde2/share/config", -}; - -static const char *oldxdms[] = { - "/etc/X11/xdm", - XLIBDIR "/xdm", -}; - -int main( int argc, char **argv ) -{ - const char **where; - char *newtdmrc; - FILE *f; - StrList *fp; - Section *cs; - Entry *ce, **cep; - int i, ap, newer, locals, foreigns; - int no_old_xdm = 0, no_old_kde = 0; - struct stat st; - char *nname; - - for (ap = 1; ap < argc; ap++) { - if (!strcmp( argv[ap], "--help" )) { - printf( -"gentdmconf - generate configuration files for tdm\n" -"\n" -"If an older xdm/tdm configuration is found, its config files are \"absorbed\";\n" -"if it lives in the new target directory, its scripts are reused (and possibly\n" -"modified) as well, otherwise the scripts are ignored and default scripts are\n" -"installed.\n" -"\n" -"options:\n" -" --in /path/to/new/tdm-config-dir\n" -" In which directory to put the new configuration. You can use this\n" -" to support a $(DESTDIR), but not to change the final location of\n" -" the installation - the paths inside the files are not affected.\n" -" Default is " TDMCONF ".\n" -" --old-xdm /path/to/old/xdm-dir\n" -" Where to look for the config files of an xdm/older tdm.\n" -" Default is to scan /etc/X11/tdm, $XLIBDIR/tdm, /etc/X11/xdm,\n" -" $XLIBDIR/xdm; there in turn look for tdm-config and xdm-config.\n" -" Note that you possibly need to use --no-old-kde to make this take effect.\n" -" --old-kde /path/to/old/kde-config-dir\n" -" Where to look for the tdmrc of an older tdm.\n" -" Default is to scan " KDE_CONFDIR " and\n" -" {/usr,/usr/local,{/opt,/usr/local}/{trinity,kde,kde2,kde1}}/share/config.\n" -" --no-old\n" -" Don't look at older xdm/tdm configurations, just create default config.\n" -" --no-old-xdm\n" -" Don't look at older xdm configurations.\n" -" --no-old-kde\n" -" Don't look at older tdm configurations.\n" -" --old-scripts\n" -" Directly use all scripts from the older xdm/tdm configuration.\n" -" --no-old-scripts\n" -" Don't use scripts from the older xdm/tdm configuration even if it lives\n" -" in the new target directory.\n" -" --old-confs\n" -" Directly use all ancillary config files from the older xdm/tdm\n" -" configuration. This is usually a bad idea.\n" -" --no-backup\n" -" Overwrite/delete old config files instead of backing them up.\n" -" --no-in-notice\n" -" Don't put the notice about --in being used into the generated README.\n" -); - exit( 0 ); - } - if (!strcmp( argv[ap], "--no-old" )) { - no_old = 1; - continue; - } - if (!strcmp( argv[ap], "--old-scripts" )) { - old_scripts = 1; - continue; - } - if (!strcmp( argv[ap], "--no-old-scripts" )) { - no_old_scripts = 1; - continue; - } - if (!strcmp( argv[ap], "--old-confs" )) { - old_confs = 1; - continue; - } - if (!strcmp( argv[ap], "--no-old-xdm" )) { - no_old_xdm = 1; - continue; - } - if (!strcmp( argv[ap], "--no-old-kde" )) { - no_old_kde = 1; - continue; - } - if (!strcmp( argv[ap], "--no-backup" )) { - no_backup = 1; - continue; - } - if (!strcmp( argv[ap], "--no-in-notice" )) { - no_in_notice = 1; - continue; - } - where = 0; - if (!strcmp( argv[ap], "--in" )) - where = &newdir; - else if (!strcmp( argv[ap], "--old-xdm" )) - where = &oldxdm; - else if (!strcmp( argv[ap], "--old-kde" )) - where = &oldkde; - else if (!strcmp( argv[ap], "--face-src" )) - where = &facesrc; - else { - fprintf( stderr, "Unknown command line option '%s', try --help\n", argv[ap] ); - exit( 1 ); - } - if (ap + 1 == argc || argv[ap + 1][0] == '-') { - fprintf( stderr, "Missing argument to option '%s', try --help\n", argv[ap] ); - exit( 1 ); - } - *where = argv[++ap]; - } - if (memcmp( newdir, TDMCONF, sizeof(TDMCONF) )) - use_destdir = 1; - - if (!mkdirp( newdir, 0755, "target", 1 )) - exit( 1 ); - - mkdefconf(); - newer = 0; - if (no_old) { - DIR *dir; - if ((dir = opendir( newdir ))) { - struct dirent *ent; - char bn[PATH_MAX]; - while ((ent = readdir( dir ))) { - int l; - if (!strcmp( ent->d_name, "." ) || !strcmp( ent->d_name, ".." )) - continue; - l = sprintf( bn, "%s/%s", newdir, ent->d_name ); /* cannot overflow (kernel would not allow the creation of a longer path) */ - if (!stat( bn, &st ) && !S_ISREG( st.st_mode )) - continue; - if (no_backup || !memcmp( bn + l - 4, ".bak", 5 )) - unlink( bn ); - else - displace( bn ); - } - closedir( dir ); - } - } else { - if (oldkde) { - if (!(newer = mergeKdmRcNewer( oldkde )) && !mergeKdmRcOld( oldkde )) - fprintf( stderr, - "Cannot read old tdmrc at specified location\n" ); - } else if (!no_old_kde) { - for (i = 0; i < as(oldkdes); i++) { - if ((newer = mergeKdmRcNewer( oldkdes[i] )) || - mergeKdmRcOld( oldkdes[i] )) { - oldkde = oldkdes[i]; - break; - } - } - } - if (!newer && !no_old_xdm) { - XrmInitialize(); - XrmQString = XrmPermStringToQuark( "String" ); - if (oldxdm) { - if (!mergeXdmCfg( oldxdm )) - fprintf( stderr, - "Cannot read old tdm-config/xdm-config at specified location\n" ); - } else - for (i = 0; i < as(oldxdms); i++) - if (mergeXdmCfg( oldxdms[i] )) { - oldxdm = oldxdms[i]; - break; - } - } else - oldxdm = 0; - } - if (no_old_scripts) - goto no_old_s; - if (!old_scripts) { - locals = foreigns = 0; - for (cs = config; cs; cs = cs->next) - if (!strcmp( cs->spec->name, "-Core" )) { - for (ce = cs->ents; ce; ce = ce->next) - if (ce->active && - (!strcmp( ce->spec->key, "Setup" ) || - !strcmp( ce->spec->key, "Startup" ) || - !strcmp( ce->spec->key, "Reset" ))) - { - if (inNewDir( ce->value )) - locals = 1; - else - foreigns = 1; - } - } - if (foreigns) { - if (locals) { - fprintf( stderr, - "Warning: both local and foreign scripts referenced. " - "Won't touch any.\n" ); - mixed_scripts = 1; - } else { - no_old_s: - for (cs = config; cs; cs = cs->next) { - if (!strcmp( cs->spec->name, "Xdmcp" )) { - for (ce = cs->ents; ce; ce = ce->next) - if (!strcmp( ce->spec->key, "Willing" )) - ce->active = ce->written = 0; - } else if (!strcmp( cs->spec->name, "-Core" )) { - for (cep = &cs->ents; (ce = *cep); ) { - if (ce->active && - (!strcmp( ce->spec->key, "Setup" ) || - !strcmp( ce->spec->key, "Startup" ) || - !strcmp( ce->spec->key, "Reset" ) || - !strcmp( ce->spec->key, "Session" ))) - { - if (!memcmp( cs->name, "X-*-", 4 )) - ce->active = ce->written = 0; - else { - *cep = ce->next; - free( ce ); - continue; - } - } - cep = &ce->next; - } - } - } - } - } - } -#ifdef __linux__ - if (!stat( "/etc/debian_version", &st )) { /* debian */ - defminuid = "1000"; - defmaxuid = "29999"; - } else if (!stat( "/usr/portage", &st )) { /* gentoo */ - defminuid = "1000"; - defmaxuid = "65000"; - } else if (!stat( "/etc/mandrake-release", &st )) { /* mandrake - check before redhat! */ - defminuid = "500"; - defmaxuid = "65000"; - } else if (!stat( "/etc/redhat-release", &st )) { /* redhat */ - defminuid = "100"; - defmaxuid = "65000"; - } else /* if (!stat( "/etc/SuSE-release", &st )) */ { /* suse */ - defminuid = "500"; - defmaxuid = "65000"; - } -#else - defminuid = "1000"; - defmaxuid = "65000"; -#endif - for (i = 0; i < CONF_MAX_PRIO; i++) - for (cs = config; cs; cs = cs->next) - for (ce = cs->ents; ce; ce = ce->next) - if (ce->spec->func && i == ce->spec->prio) - ce->spec->func( ce, cs ); - ASPrintf( &newtdmrc, "%s/tdmrc", newdir ); - f = Create( newtdmrc, tdmrcmode ); - wrconf( f ); - fclose( f ); - - ASPrintf( &nname, "%s/README", newdir ); - f = Create( nname, 0644 ); - fprintf( f, -"This automatically generated configuration consists of the following files:\n" ); - fprintf( f, "- " TDMCONF "/tdmrc\n" ); - for (fp = aflist; fp; fp = fp->next) - fprintf( f, "- %s\n", fp->str ); - if (use_destdir && !no_in_notice) - fwrapprintf( f, -"All files destined for " TDMCONF " were actually saved in %s; " -"this config won't be workable until moved in place.\n", newdir ); - if (uflist || eflist || cflist || lflist) { - fprintf( f, -"\n" -"This config was derived from existing files. As the used algorithms are\n" -"pretty dumb, it may be broken.\n" ); - if (uflist) { - fprintf( f, -"Information from these files was extracted:\n" ); - for (fp = uflist; fp; fp = fp->next) - fprintf( f, "- %s\n", fp->str ); - } - if (lflist) { - fprintf( f, -"These files were directly incorporated:\n" ); - for (fp = lflist; fp; fp = fp->next) - fprintf( f, "- %s\n", fp->str ); - } - if (cflist) { - fprintf( f, -"These files were copied verbatim:\n" ); - for (fp = cflist; fp; fp = fp->next) - fprintf( f, "- %s\n", fp->str ); - } - if (eflist) { - fprintf( f, -"These files were copied with modifications:\n" ); - for (fp = eflist; fp; fp = fp->next) - fprintf( f, "- %s\n", fp->str ); - } - if (!no_backup && !use_destdir) - fprintf( f, -"Old files that would have been overwritten were renamed to .bak.\n" ); - } - fprintf( f, -"\nTry 'gentdmconf --help' if you want to generate another configuration.\n" -"\nYou may delete this README.\n" ); - fclose( f ); - - return 0; -} diff --git a/kdm/kfrontend/kchooser.cpp b/kdm/kfrontend/kchooser.cpp deleted file mode 100644 index 00b08cd35..000000000 --- a/kdm/kfrontend/kchooser.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - -chooser widget for TDM - -Copyright (C) 2002-2003 Oswald Buddenhagen -based on the chooser (C) 1999 by Harald Hoyer - -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 - -#ifdef XDMCP - -#include "kchooser.h" -#include "kconsole.h" -#include "tdmconfig.h" -#include "tdm_greet.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include // for free() - -class ChooserListViewItem : public TQListViewItem { - public: - ChooserListViewItem( TQListView* parent, int _id, const TQString& nam, const TQString& sts ) - : TQListViewItem( parent, nam, sts ) { id = _id; }; - - int id; -}; - - -ChooserDlg::ChooserDlg() - : inherited() -{ - completeMenu( LOGIN_REMOTE_ONLY, ex_greet, i18n("&Local Login"), ALT+Key_L ); - - TQBoxLayout *vbox = new TQVBoxLayout( this, 10, 10 ); - - TQLabel *title = new TQLabel( i18n("XDMCP Host Menu"), this ); - title->setAlignment( AlignCenter ); - vbox->addWidget( title ); - - host_view = new TQListView( this, "hosts" ); - host_view->addColumn( i18n("Hostname") ); - host_view->setColumnWidth( 0, fontMetrics().width( "login.crap.net" ) ); - host_view->addColumn( i18n("Status") ); - host_view->setMinimumWidth( fontMetrics().width( "login.crap.com Display not authorized to connect this server" ) ); - host_view->setResizeMode( TQListView::LastColumn ); - host_view->setAllColumnsShowFocus( true ); - vbox->addWidget( host_view ); - - iline = new TQLineEdit( this ); - iline->setEnabled( TRUE ); - TQLabel *itxt = new TQLabel( iline, i18n("Hos&t:"), this ); - TQPushButton *addButton = new TQPushButton( i18n("A&dd"), this ); - connect( addButton, TQT_SIGNAL(clicked()), TQT_SLOT(addHostname()) ); - TQBoxLayout *hibox = new TQHBoxLayout( vbox, 10 ); - hibox->addWidget( itxt ); - hibox->addWidget( iline ); - hibox->addWidget( addButton ); - - // Buttons - TQPushButton *acceptButton = new TQPushButton( i18n("&Accept"), this ); - acceptButton->setDefault( true ); - TQPushButton *pingButton = new TQPushButton( i18n("&Refresh"), this ); - - TQBoxLayout *hbox = new TQHBoxLayout( vbox, 20 ); - hbox->addWidget( acceptButton ); - hbox->addWidget( pingButton ); - hbox->addStretch( 1 ); - - if (optMenu) { - TQPushButton *menuButton = new TQPushButton( i18n("&Menu"), this ); - menuButton->setPopup( optMenu ); - hbox->addWidget( menuButton ); - hbox->addStretch( 1 ); - } - -// TQPushButton *helpButton = new TQPushButton( i18n("&Help"), this ); -// hbox->addWidget( helpButton ); - -#ifdef WITH_TDM_XCONSOLE - if (consoleView) - vbox->addWidget( consoleView ); -#endif - - sn = new TQSocketNotifier( rfd, TQSocketNotifier::Read, TQT_TQOBJECT(this) ); - connect( sn, TQT_SIGNAL(activated( int )), TQT_SLOT(slotReadPipe()) ); - - connect( pingButton, TQT_SIGNAL(clicked()), TQT_SLOT(pingHosts()) ); - connect( acceptButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); -// connect( helpButton, TQT_SIGNAL(clicked()), TQT_SLOT(slotHelp()) ); - connect( host_view, TQT_SIGNAL(doubleClicked(TQListViewItem *)), TQT_SLOT(accept()) ); - - adjustGeometry(); -} - -/* -void ChooserDlg::slotHelp() -{ - KMessageBox::information(0, - i18n("Choose a host, you want to work on,\n" - "in the list or add one.\n\n" - "After this box, you must press cancel\n" - "in the Host Menu to enter a host. :(")); - iline->setFocus(); -} -*/ - -void ChooserDlg::addHostname() -{ - if (!iline->text().isEmpty()) { - GSendInt( G_Ch_RegisterHost ); - GSendStr( iline->text().latin1() ); - iline->clear(); - } -} - -void ChooserDlg::pingHosts() -{ - GSendInt( G_Ch_Refresh ); -} - -void ChooserDlg::accept() -{ - if (focusWidget() == iline) { - if (!iline->text().isEmpty()) { - GSendInt( G_Ch_DirectChoice ); - GSendStr( iline->text().latin1() ); - iline->clear(); - } - return; - } else /*if (focusWidget() == host_view)*/ { - TQListViewItem *item = host_view->currentItem(); - if (item) { - GSendInt( G_Ready ); - GSendInt( ((ChooserListViewItem *)item)->id ); - ::exit( EX_NORMAL ); - } - } -} - -void ChooserDlg::reject() -{ -} - -TQString ChooserDlg::recvStr() -{ - char *arr = GRecvStr(); - if (arr) { - TQString str = TQString::fromLatin1( arr ); - free( arr ); - return str; - } else - return i18n(""); -} - -TQListViewItem *ChooserDlg::findItem( int id ) -{ - TQListViewItem *itm; - for (TQListViewItemIterator it( host_view ); (itm = it.current()); ++it) - if (((ChooserListViewItem *)itm)->id == id) - return itm; - return 0; -} - -void ChooserDlg::slotReadPipe() -{ - int id; - TQString nam, sts; - - int cmd = GRecvInt(); - switch (cmd) { - case G_Ch_AddHost: - case G_Ch_ChangeHost: - id = GRecvInt(); - nam = recvStr(); - sts = recvStr(); - GRecvInt(); /* swallow willing for now */ - if (cmd == G_Ch_AddHost) - host_view->insertItem( - new ChooserListViewItem( host_view, id, nam, sts ) ); - else { - TQListViewItem *itm = findItem( id ); - itm->setText( 0, nam ); - itm->setText( 1, sts ); - } - break; - case G_Ch_RemoveHost: - delete findItem( GRecvInt() ); - break; - case G_Ch_BadHost: - KFMsgBox::box( this, TQMessageBox::Warning, i18n("Unknown host %1").arg( recvStr() ) ); - break; - case G_Ch_Exit: - done( ex_exit ); - break; - default: /* XXX huuh ...? */ - break; - } -} - -#include "kchooser.moc" - -#endif diff --git a/kdm/kfrontend/kchooser.h b/kdm/kfrontend/kchooser.h deleted file mode 100644 index fcf14b1e1..000000000 --- a/kdm/kfrontend/kchooser.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - -chooser widget for TDM - -Copyright (C) 2002-2003 Oswald Buddenhagen -based on the chooser (C) 1999 by Harald Hoyer - -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. - -*/ - -#ifndef KCHOOSER_H -#define KCHOOSER_H - -#include "kgdialog.h" - -class TQSocketNotifier; -class TQPopupMenu; -class TQLineEdit; -class TQListView; -class TQListViewItem; - -class ChooserDlg : public KGDialog { - Q_OBJECT - typedef KGDialog inherited; - - public: - ChooserDlg(); - - public slots: - void slotReadPipe(); - void addHostname(); -// void slotHelp(); - void pingHosts(); - void accept(); - void reject(); - - private: - TQString recvStr(); - TQListViewItem *findItem( int id ); - - TQListView *host_view; - TQLineEdit *iline; - TQSocketNotifier *sn; -}; - -#endif /* KCHOOSER_H */ diff --git a/kdm/kfrontend/kconsole.cpp b/kdm/kfrontend/kconsole.cpp deleted file mode 100644 index 834507bdb..000000000 --- a/kdm/kfrontend/kconsole.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* - -xconsole widget for TDM - -Copyright (C) 2002-2003 Oswald Buddenhagen - - -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 - -#ifdef WITH_TDM_XCONSOLE - -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_TERMIOS_H -/* for HP-UX (some versions) the extern C is needed, and for other - platforms it doesn't hurt */ -extern "C" { -#include -} -#endif -#if !defined(__osf__) -#ifdef HAVE_TERMIO_H -/* needed at least on AIX */ -#include -#endif -#endif - -#if defined (_HPUX_SOURCE) -#define _TERMIOS_INCLUDED -#include -#endif - - -#include "kconsole.h" -#include "tdmconfig.h" -#include "tdm_greet.h" - -#include -#include - -#include - -KConsole::KConsole( TQWidget *_parent ) - : inherited( _parent ) - , pty( 0 ) - , notifier( 0 ) - , fd( -1 ) -{ - setReadOnly( true ); - setWordWrap( NoWrap ); - setTextFormat( PlainText ); - - if (!OpenConsole()) - append( i18n("Cannot open console") ); -} - -KConsole::~KConsole() -{ - CloseConsole(); -} - -int -KConsole::OpenConsole() -{ -#ifdef TIOCCONS - static const char on = 1; -#endif - - if (*_logSource) { - if ((fd = open( _logSource, O_RDONLY | O_NONBLOCK )) >= 0) - goto gotcon; - LogError( "Cannot open log source %s, " - "falling back to /dev/console.\n", _logSource ); - } - - pty = new KPty; - if (!pty->open()) { - delete pty; - pty = 0; - return 0; - } - -#ifdef TIOCCONS - if (ioctl( pty->slaveFd(), TIOCCONS, &on ) < 0) { - perror( "ioctl TIOCCONS" ); - delete pty; - pty = 0; - return 0; - } -#else - int consfd; - if ((consfd = open( "/dev/console", O_RDONLY )) < 0) { - perror( "opening /dev/console" ); - delete pty; - pty = 0; - return 0; - } - if (ioctl( consfd, SRIOCSREDIR, slave_fd ) < 0) { - perror( "ioctl SRIOCSREDIR" ); - ::close( consfd ); - delete pty; - pty = 0; - return 0; - } - ::close( consfd ); -#endif - fd = pty->masterFd(); - - gotcon: - notifier = new TQSocketNotifier( fd, TQSocketNotifier::Read, this ); - connect( notifier, TQT_SIGNAL(activated( int )), TQT_SLOT(slotData()) ); - return 1; -} - -void -KConsole::CloseConsole() -{ - delete notifier; - notifier = 0; - if (pty) { - delete pty; - pty = 0; - } else - ::close( fd ); - fd = -1; -} - -void -KConsole::slotData() -{ - int n; - char buffer[1024]; - - if ((n = read( fd, buffer, sizeof(buffer) )) <= 0) { - CloseConsole(); - if (!n) - if (!OpenConsole()) - append( i18n("\n*** Cannot open console log source ***") ); - } else { - bool as = !verticalScrollBar()->isVisible() || - (verticalScrollBar()->value() == - verticalScrollBar()->maxValue()); - TQString str( TQString::fromLocal8Bit( buffer, n ).remove( '\r' ) ); - int pos, opos; - for (opos = 0; (pos = str.find( '\n', opos )) >= 0; opos = pos + 1) { - if (paragraphs() == 100) - removeParagraph( 0 ); - if (!leftover.isEmpty()) { - append( leftover + str.mid( opos, pos - opos ) ); - leftover = TQString::null; - } else - append( str.mid( opos, pos - opos ) ); - } - leftover += str.mid( opos ); - if (as) - scrollToBottom(); - } -} - -#include "kconsole.moc" - -#endif diff --git a/kdm/kfrontend/kconsole.h b/kdm/kfrontend/kconsole.h deleted file mode 100644 index 2b3e2aac3..000000000 --- a/kdm/kfrontend/kconsole.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - -xconsole widget for TDM - -Copyright (C) 2002-2003 Oswald Buddenhagen - - -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. - -*/ - -#ifndef KCONSOLE_H -#define KCONSOLE_H - -#include - -class TQSocketNotifier; -class KPty; - -class KConsole : public TQTextEdit { - Q_OBJECT - typedef TQTextEdit inherited; - - public: - KConsole( TQWidget *_parent = 0 ); - ~KConsole(); - - private slots: - void slotData(); - - private: - int OpenConsole(); - void CloseConsole(); - - KPty *pty; - TQSocketNotifier *notifier; - TQString leftover; - int fd; -}; - -#endif // KCONSOLE_H diff --git a/kdm/kfrontend/kdm_config.c b/kdm/kfrontend/kdm_config.c deleted file mode 100644 index 48f316320..000000000 --- a/kdm/kfrontend/kdm_config.c +++ /dev/null @@ -1,1477 +0,0 @@ -/* - -Read options from tdmrc - -Copyright (C) 2001-2005 Oswald Buddenhagen - - -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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _POSIX_PRIORITY_SCHEDULING -# include -#endif - -#include -#ifdef FamilyInternet6 -# define IPv6 -#endif - -#include -#include - -/* - * Section/Entry definition structs - */ - -typedef struct Ent { - const char *name; - int id; - void *ptr; - const char *def; -} Ent; - -typedef struct Sect { - const char *name; - Ent *ents; - int numents; -} Sect; - -/* - * Parsed ini file structs - */ - -typedef struct Entry { - struct Entry *next; - const char *val; - Ent *ent; - int vallen; - int line; -} Entry; - -typedef struct Section { - struct Section *next; - Entry *entries; - Sect *sect; - const char *name, *dname, *dhost, *dnum, *dclass; - int nlen, dlen, dhostl, dnuml, dclassl; -} Section; - - -/* - * Split up display-name/-class for fast comparison - */ -typedef struct DSpec { - const char *dhost, *dnum, *dclass; - int dhostl, dnuml, dclassl; -} DSpec; - - -/* - * Config value storage structures - */ - -typedef struct Value { - const char *ptr; - int len; -} Value; - -typedef struct Val { - Value val; - int id; -} Val; - -typedef struct ValArr { - Val *ents; - int nents, esiz, nchars, nptrs; -} ValArr; - - -static void *Malloc( size_t size ); -static void *Realloc( void *ptr, size_t size ); - -#define PRINT_QUOTES -#define LOG_NAME "tdm_config" -#define LOG_DEBUG_MASK DEBUG_CONFIG -#define LOG_PANIC_EXIT 1 -#define STATIC static -#include - - -static void * -Malloc( size_t size ) -{ - void *ret; - - if (!(ret = malloc( size ))) - LogOutOfMem(); - return ret; -} - -static void * -Realloc( void *ptr, size_t size ) -{ - void *ret; - - if (!(ret = realloc( ptr, size )) && size) - LogOutOfMem(); - return ret; -} - - -static void -MkDSpec( DSpec *spec, const char *dname, const char *dclass ) -{ - spec->dhost = dname; - for (spec->dhostl = 0; dname[spec->dhostl] != ':'; spec->dhostl++); - spec->dnum = dname + spec->dhostl + 1; - spec->dnuml = strlen( spec->dnum ); - spec->dclass = dclass; - spec->dclassl = strlen( dclass ); -} - - -static int rfd, wfd; - -static int -Reader( void *buf, int count ) -{ - int ret, rlen; - - for (rlen = 0; rlen < count; ) { - dord: - ret = read( rfd, (void *)((char *)buf + rlen), count - rlen ); - if (ret < 0) { - if (errno == EINTR) - goto dord; - if (errno == EAGAIN) - break; - return -1; - } - if (!ret) - break; - rlen += ret; - } - return rlen; -} - -static void -GRead( void *buf, int count ) -{ - if (Reader( buf, count ) != count) - LogPanic( "Can't read from core\n" ); -} - -static void -GWrite( const void *buf, int count ) -{ - if (write( wfd, buf, count ) != count) - LogPanic( "Can't write to core\n" ); -#ifdef _POSIX_PRIORITY_SCHEDULING - if ((debugLevel & DEBUG_HLPCON)) - sched_yield(); -#endif -} - -static void -GSendInt( int val ) -{ - GWrite( &val, sizeof(val) ); -} - -static void -GSendStr( const char *buf ) -{ - if (buf) { - int len = strlen( buf ) + 1; - GWrite( &len, sizeof(len) ); - GWrite( buf, len ); - } else - GWrite( &buf, sizeof(int)); -} - -static void -GSendNStr( const char *buf, int len ) -{ - int tlen = len + 1; - GWrite( &tlen, sizeof(tlen) ); - GWrite( buf, len ); - GWrite( "", 1 ); -} - -#ifdef XDMCP -static void -GSendArr( int len, const char *data ) -{ - GWrite( &len, sizeof(len) ); - GWrite( data, len ); -} -#endif - -static int -GRecvCmd( int *val ) -{ - if (Reader( val, sizeof(*val) ) != sizeof(*val)) - return 0; - return 1; -} - -static int -GRecvInt() -{ - int val; - - GRead( &val, sizeof(val) ); - return val; -} - -static char * -GRecvStr() -{ - int len; - char *buf; - - len = GRecvInt(); - if (!len) - return 0; - if (!(buf = malloc( len ))) - LogPanic( "No memory for read buffer" ); - GRead( buf, len ); - return buf; -} - - -/* #define WANT_CLOSE 1 */ - -typedef struct File { - char *buf, *eof, *cur; -#if defined(HAVE_MMAP) && defined(WANT_CLOSE) - int ismapped; -#endif -} File; - -static int -readFile( File *file, const char *fn, const char *what ) -{ - int fd; - off_t flen; - - if ((fd = open( fn, O_RDONLY )) < 0) { - LogInfo( "Cannot open %s file %s\n", what, fn ); - return 0; - } - - flen = lseek( fd, 0, SEEK_END ); -#ifdef HAVE_MMAP -# ifdef WANT_CLOSE - file->ismapped = 0; -# endif - file->buf = mmap( 0, flen + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0 ); -# ifdef WANT_CLOSE - if (file->buf) - file->ismapped = 1; - else -# else - if (!file->buf) -# endif -#endif - { - if (!(file->buf = Malloc( flen + 1 ))) { - close( fd ); - return 0; - } - lseek( fd, 0, SEEK_SET ); - if (read( fd, file->buf, flen ) != flen) { - free( file->buf ); - LogError( "Cannot read %s file %s\n", what, fn ); - close( fd ); - return 0; - } - } - file->eof = (file->cur = file->buf) + flen; - close( fd ); - return 1; -} - -#ifdef WANT_CLOSE -static void -freeBuf( File *file ) -{ -# ifdef HAVE_MMAP - if (file->ismapped) - munmap( file->buf, file->eof - file->buf + 1 ); - else -# endif - free( file->buf ); -} -#endif - -CONF_READ_VARS - -#define C_MTYPE_MASK 0x30000000 -# define C_PATH 0x10000000 /* C_TYPE_STR is a path spec */ -# define C_BOOL 0x10000000 /* C_TYPE_INT is a boolean */ -# define C_ENUM 0x20000000 /* C_TYPE_INT is an enum (option) */ -# define C_GRP 0x30000000 /* C_TYPE_INT is a group spec */ -#define C_INTERNAL 0x40000000 /* don't expose to core */ -#define C_CONFIG 0x80000000 /* process only for finding deps */ - -#ifdef XDMCP -static int -PrequestPort( Value *retval ) -{ - if (!VxdmcpEnable.ptr) { - retval->ptr = (char *)0; - return 1; - } - return 0; -} -#endif - -static Value - emptyStr = { "", 1 }, - nullValue = { 0, 0 }, - emptyArgv = { (char *)&nullValue, 0 }; - -static int -PnoPassUsers( Value *retval ) -{ - if (!VnoPassEnable.ptr) { - *retval = emptyArgv; - return 1; - } - return 0; -} - -static int -PautoLoginX( Value *retval ) -{ - if (!VautoLoginEnable.ptr) { - *retval = emptyStr; - return 1; - } - return 0; -} - -CONF_READ_ENTRIES - -static const char *tdmrc = TDMCONF "/tdmrc"; -static const char *tdmrc_dist = TDMCONF "/tdmdistrc"; - -static Section *rootsec; - -static void -ReadConf() -{ - const char *nstr, *dstr, *cstr, *dhost, *dnum, *dclass; - char *s, *e, *st, *en, *ek, *sl, *pt; - Section *cursec; - Entry *curent; - Ent *ce; - int nlen, dlen, clen, dhostl, dnuml, dclassl; - int i, line, sectmoan, restl; - File file; - static int confread; - - if (confread) - return; - confread = 1; - - Debug( "reading config %s ...\n", tdmrc_dist ); - if (!readFile( &file, tdmrc_dist, "master configuration" )) { - Debug( "reading config %s ...\n", tdmrc ); - if (!readFile( &file, tdmrc, "master configuration" )) - return; - } - else { - tdmrc = tdmrc_dist; - } - - for (s = file.buf, line = 0, cursec = 0, sectmoan = 1; s < file.eof; s++) { - line++; - - while ((s < file.eof) && isspace( *s ) && (*s != '\n')) - s++; - - if ((s < file.eof) && ((*s == '\n') || (*s == '#'))) { - sktoeol: - while ((s < file.eof) && (*s != '\n')) - s++; - continue; - } - sl = s; - - if (*s == '[') { - sectmoan = 0; - while ((s < file.eof) && (*s != '\n')) - s++; - e = s - 1; - while ((e > sl) && isspace( *e )) - e--; - if (*e != ']') { - cursec = 0; - LogError( "Invalid section header at %s:%d\n", tdmrc, line ); - continue; - } - nstr = sl + 1; - nlen = e - nstr; - for (cursec = rootsec; cursec; cursec = cursec->next) - if (nlen == cursec->nlen && - !memcmp( nstr, cursec->name, nlen )) - { - LogInfo( "Multiple occurrences of section [%.*s] in %s. " - "Consider merging them.\n", nlen, nstr, tdmrc ); - goto secfnd; - } - if (nstr[0] == 'X' && nstr[1] == '-') { - cstr = nstr + nlen; - clen = 0; - while (++clen, *--cstr != '-'); - if (cstr == nstr + 1) - goto illsec; - dstr = nstr + 2; - dlen = nlen - clen - 2; - dhost = dstr; - dhostl = 0; - for (restl = dlen; restl; restl--) { - if (dhost[dhostl] == ':') { - dnum = dhost + dhostl + 1; - dnuml = 0; - for (restl--; restl; restl--) { - if (dnum[dnuml] == '_') { - dclass = dnum + dnuml + 1; - dclassl = restl; - goto gotall; - } - dnuml++; - } - goto gotnum; - } - dhostl++; - } - dnum = "*"; - dnuml = 1; - gotnum: - dclass = "*"; - dclassl = 1; - gotall: ; - } else { - if (nstr[0] == '-') - goto illsec; - dstr = 0; - dlen = 0; - dhost = 0; - dhostl = 0; - dnum = 0; - dnuml = 0; - dclass = 0; - dclassl = 0; - cstr = nstr; - clen = nlen; - } - for (i = 0; i < as(allSects); i++) - if ((int)strlen( allSects[i]->name ) == clen && - !memcmp( allSects[i]->name, cstr, clen )) - goto newsec; - illsec: - cursec = 0; - LogError( "Unrecognized section name [%.*s] at %s:%d\n", - nlen, nstr, tdmrc, line ); - continue; - newsec: - if (!(cursec = Malloc( sizeof(*cursec) ))) - return; - cursec->name = nstr; - cursec->nlen = nlen; - cursec->dname = dstr; - cursec->dlen = dlen; - cursec->dhost = dhost; - cursec->dhostl = dhostl; - cursec->dnum = dnum; - cursec->dnuml = dnuml; - cursec->dclass = dclass; - cursec->dclassl = dclassl; - cursec->sect = allSects[i]; - cursec->entries = 0; - cursec->next = rootsec; - rootsec = cursec; - /*Debug( "now in section [%.*s], dpy '%.*s', core '%.*s'\n", - nlen, nstr, dlen, dstr, clen, cstr );*/ - secfnd: - continue; - } - - if (!cursec) { - if (sectmoan) { - sectmoan = 0; - LogError( "Entry outside any section at %s:%d", tdmrc, line ); - } - goto sktoeol; - } - - for (; (s < file.eof) && (*s != '\n'); s++) - if (*s == '=') - goto haveeq; - LogError( "Invalid entry (missing '=') at %s:%d\n", tdmrc, line ); - continue; - - haveeq: - for (ek = s - 1; ; ek--) { - if (ek < sl) { - LogError( "Invalid entry (empty key) at %s:%d\n", tdmrc, line ); - goto sktoeol; - } - if (!isspace( *ek )) - break; - } - - s++; - while ((s < file.eof) && isspace( *s ) && (*s != '\n')) - s++; - for (pt = st = en = s; s < file.eof && *s != '\n'; s++) { - if (*s == '\\') { - s++; - if (s >= file.eof || *s == '\n') { - LogError( "Trailing backslash at %s:%d\n", tdmrc, line ); - break; - } - switch (*s) { - case 's': *pt++ = ' '; break; - case 't': *pt++ = '\t'; break; - case 'n': *pt++ = '\n'; break; - case 'r': *pt++ = '\r'; break; - case '\\': *pt++ = '\\'; break; - default: *pt++ = '\\'; *pt++ = *s; break; - } - en = pt; - } else { - *pt++ = *s; - if (*s != ' ' && *s != '\t') - en = pt; - } - } - - nstr = sl; - nlen = ek - sl + 1; - /*Debug( "read entry '%.*s'='%.*s'\n", nlen, nstr, en - st, st );*/ - for (i = 0; i < cursec->sect->numents; i++) { - ce = cursec->sect->ents + i; - if ((int)strlen( ce->name ) == nlen && - !memcmp( ce->name, nstr, nlen )) - goto keyok; - } - LogError( "Unrecognized key '%.*s' in section [%.*s] at %s:%d\n", - nlen, nstr, cursec->nlen, cursec->name, tdmrc, line ); - continue; - keyok: - for (curent = cursec->entries; curent; curent = curent->next) - if (ce == curent->ent) { - LogError( "Multiple occurrences of key '%s' in section [%.*s]" - " of %s\n", - ce->name, cursec->nlen, cursec->name, tdmrc ); - goto keyfnd; - } - if (!(curent = Malloc( sizeof(*curent) ))) - return; - curent->ent = ce; - curent->line = line; - curent->val = st; - curent->vallen = en - st; - curent->next = cursec->entries; - cursec->entries = curent; - keyfnd: - continue; - } -} - -static Entry * -FindGEnt( int id ) -{ - Section *cursec; - Entry *curent; - - for (cursec = rootsec; cursec; cursec = cursec->next) - if (!cursec->dname) - for (curent = cursec->entries; curent; curent = curent->next) - if (curent->ent->id == id) { - Debug( "line %d: %s = %'.*s\n", - curent->line, curent->ent->name, - curent->vallen, curent->val ); - return curent; - } - return 0; -} - -/* Display name match scoring: - * - class (any/exact) -> 0/1 - * - number (any/exact) -> 0/2 - * - host (any/nonempty/trail/exact) -> 0/4/8/12 - */ -static Entry * -FindDEnt( int id, DSpec *dspec ) -{ - Section *cursec, *bestsec; - Entry *curent, *bestent; - int score, bestscore; - - bestscore = -1, bestent = 0; - for (cursec = rootsec; cursec; cursec = cursec->next) - if (cursec->dname) { - score = 0; - if (cursec->dclassl != 1 || cursec->dclass[0] != '*') { - if (cursec->dclassl == dspec->dclassl && - !memcmp( cursec->dclass, dspec->dclass, dspec->dclassl )) - score = 1; - else - continue; - } - if (cursec->dnuml != 1 || cursec->dnum[0] != '*') { - if (cursec->dnuml == dspec->dnuml && - !memcmp( cursec->dnum, dspec->dnum, dspec->dnuml )) - score += 2; - else - continue; - } - if (cursec->dhostl != 1 || cursec->dhost[0] != '*') { - if (cursec->dhostl == 1 && cursec->dhost[0] == '+') { - if (dspec->dhostl) - score += 4; - else - continue; - } else if (cursec->dhost[0] == '.') { - if (cursec->dhostl < dspec->dhostl && - !memcmp( cursec->dhost, - dspec->dhost + dspec->dhostl - cursec->dhostl, - cursec->dhostl )) - score += 8; - else - continue; - } else { - if (cursec->dhostl == dspec->dhostl && - !memcmp( cursec->dhost, dspec->dhost, dspec->dhostl )) - score += 12; - else - continue; - } - } - if (score > bestscore) { - for (curent = cursec->entries; curent; curent = curent->next) - if (curent->ent->id == id) { - bestent = curent; - bestsec = cursec; - bestscore = score; - break; - } - } - } - if (bestent) - Debug( "line %d: %.*s:%.*s_%.*s/%s = %'.*s\n", bestent->line, - bestsec->dhostl, bestsec->dhost, - bestsec->dnuml, bestsec->dnum, - bestsec->dclassl, bestsec->dclass, - bestent->ent->name, bestent->vallen, bestent->val ); - return bestent; -} - -static const char * -CvtValue( Ent *et, Value *retval, int vallen, const char *val, char **eopts ) -{ - Value *ents; - int i, b, e, tlen, nents, esiz; - char buf[80]; - - switch (et->id & C_TYPE_MASK) { - case C_TYPE_INT: - for (i = 0; i < vallen && i < (int)sizeof(buf) - 1; i++) - buf[i] = tolower( val[i] ); - buf[i] = 0; - if ((et->id & C_MTYPE_MASK) == C_BOOL) { - if (!strcmp( buf, "true" ) || - !strcmp( buf, "on" ) || - !strcmp( buf, "yes" ) || - !strcmp( buf, "1" )) - retval->ptr = (char *)1; - else if (!strcmp( buf, "false" ) || - !strcmp( buf, "off" ) || - !strcmp( buf, "no" ) || - !strcmp( buf, "0" )) - retval->ptr = (char *)0; - else - return "boolean"; - return 0; - } else if ((et->id & C_MTYPE_MASK) == C_ENUM) { - for (i = 0; eopts[i]; i++) - if (!memcmp( eopts[i], val, vallen ) && !eopts[i][vallen]) { - retval->ptr = (char *)i; - return 0; - } - return "option"; - } else if ((et->id & C_MTYPE_MASK) == C_GRP) { - struct group *ge; - if ((ge = getgrnam( buf ))) { - retval->ptr = (char *)ge->gr_gid; - return 0; - } - } - retval->ptr = 0; - if (sscanf( buf, "%li", &retval->ptr ) != 1) - return "integer"; - return 0; - case C_TYPE_STR: - retval->ptr = val; - retval->len = vallen + 1; - if ((et->id & C_MTYPE_MASK) == C_PATH) - if (vallen && val[vallen-1] == '/') - retval->len--; - return 0; - case C_TYPE_ARGV: - if (!(ents = Malloc( sizeof(Value) * (esiz = 10) ))) - return 0; - for (nents = 0, tlen = 0, i = 0; ; i++) { - for (; i < vallen && isspace( val[i] ); i++); - for (b = i; i < vallen && val[i] != ','; i++); - if (b == i) - break; - for (e = i; e > b && isspace( val[e - 1] ); e--); - if (esiz < nents + 2) { - Value *entsn = Realloc( ents, - sizeof(Value) * (esiz = esiz * 2 + 1) ); - if (!nents) - break; - ents = entsn; - } - ents[nents].ptr = val + b; - ents[nents].len = e - b; - nents++; - tlen += e - b + 1; - } - ents[nents].ptr = 0; - retval->ptr = (char *)ents; - retval->len = tlen; - return 0; - default: - LogError( "Internal error: unknown value type in id %#x\n", et->id ); - return 0; - } -} - -static void -GetValue( Ent *et, DSpec *dspec, Value *retval, char **eopts ) -{ - Entry *ent; - const char *errs; - -/* Debug( "Getting value %#x\n", et->id );*/ - if (dspec) - ent = FindDEnt( et->id, dspec ); - else - ent = FindGEnt( et->id ); - if (ent) { - if (!(errs = CvtValue( et, retval, ent->vallen, ent->val, eopts ))) - return; - LogError( "Invalid %s value '%.*s' at %s:%d\n", - errs, ent->vallen, ent->val, tdmrc, ent->line ); - } - Debug( "default: %s = %'s\n", et->name, et->def ); - if ((errs = CvtValue( et, retval, strlen( et->def ), et->def, eopts ))) - LogError( "Internal error: invalid default %s value '%s' for key %s\n", - errs, et->def, et->name ); -} - -static int -AddValue( ValArr *va, int id, Value *val ) -{ - int nu; - -/* Debug( "Addig value %#x\n", id );*/ - if (va->nents == va->esiz) { - va->ents = Realloc( va->ents, sizeof(Val) * (va->esiz += 50) ); - if (!va->ents) - return 0; - } - va->ents[va->nents].id = id; - va->ents[va->nents].val = *val; - va->nents++; - switch (id & C_TYPE_MASK) { - case C_TYPE_INT: - break; - case C_TYPE_STR: - va->nchars += val->len; - break; - case C_TYPE_ARGV: - va->nchars += val->len; - for (nu = 0; ((Value *)val->ptr)[nu++].ptr; ); - va->nptrs += nu; - break; - } - return 1; -} - -static void -CopyValues( ValArr *va, Sect *sec, DSpec *dspec, int isconfig ) -{ - Value val; - int i; - - Debug( "getting values for section class [%s]\n", sec->name ); - for (i = 0; i < sec->numents; i++) { -/*Debug ("value %#x\n", sec->ents[i].id);*/ - if ((sec->ents[i].id & (int)C_CONFIG) != isconfig) - ; - else if (sec->ents[i].id & C_INTERNAL) { - GetValue( sec->ents + i, dspec, ((Value *)sec->ents[i].ptr), 0 ); - } else { - if (((sec->ents[i].id & C_MTYPE_MASK) == C_ENUM) || - !sec->ents[i].ptr || - !((int (*)( Value * ))sec->ents[i].ptr)(&val)) { - GetValue( sec->ents + i, dspec, &val, - (char **)sec->ents[i].ptr ); - } - if (!AddValue( va, sec->ents[i].id, &val )) - break; - } - } - return; -} - -static void -SendValues( ValArr *va ) -{ - Value *cst; - int i, nu; - - GSendInt( va->nents ); - GSendInt( va->nptrs ); - GSendInt( 0/*va->nints*/ ); - GSendInt( va->nchars ); - for (i = 0; i < va->nents; i++) { - GSendInt( va->ents[i].id & ~C_PRIVATE ); - switch (va->ents[i].id & C_TYPE_MASK) { - case C_TYPE_INT: - GSendInt( (int)va->ents[i].val.ptr ); - break; - case C_TYPE_STR: - GSendNStr( va->ents[i].val.ptr, va->ents[i].val.len - 1 ); - break; - case C_TYPE_ARGV: - cst = (Value *)va->ents[i].val.ptr; - for (nu = 0; cst[nu].ptr; nu++); - GSendInt( nu ); - for (; cst->ptr; cst++) - GSendNStr( cst->ptr, cst->len ); - break; - } - } -} - - -#ifdef XDMCP -static char * -ReadWord( File *file, int *len, int EOFatEOL ) -{ - char *wordp, *wordBuffer; - int quoted; - char c; - - rest: - wordp = wordBuffer = file->cur; - mloop: - quoted = 0; - qloop: - if (file->cur == file->eof) { - doeow: - if (wordp == wordBuffer) - return 0; - retw: - *wordp = '\0'; - *len = wordp - wordBuffer; - return wordBuffer; - } - c = *file->cur++; - switch (c) { - case '#': - if (quoted) - break; - do { - if (file->cur == file->eof) - goto doeow; - c = *file->cur++; - } while (c != '\n'); - case '\0': - case '\n': - if (EOFatEOL && !quoted) { - file->cur--; - goto doeow; - } - if (wordp != wordBuffer) { - file->cur--; - goto retw; - } - goto rest; - case ' ': - case '\t': - if (wordp != wordBuffer) - goto retw; - goto rest; - case '\\': - if (!quoted) { - quoted = 1; - goto qloop; - } - break; - } - *wordp++ = c; - goto mloop; -} - -#define ALIAS_CHARACTER '%' -#define EQUAL_CHARACTER '=' -#define NEGATE_CHARACTER '!' -#define CHOOSER_STRING "CHOOSER" -#define BROADCAST_STRING "BROADCAST" -#define NOBROADCAST_STRING "NOBROADCAST" -#define LISTEN_STRING "LISTEN" -#define WILDCARD_STRING "*" - -typedef struct hostEntry { - struct hostEntry *next; - int type; - union _hostOrAlias { - char *aliasPattern; - char *hostPattern; - struct _display { - int connectionType; - int hostAddrLen; - char *hostAddress; - } displayAddress; - } entry; -} HostEntry; - -typedef struct listenEntry { - struct listenEntry *next; - int iface; - int mcasts; - int nmcasts; -} ListenEntry; - -typedef struct aliasEntry { - struct aliasEntry *next; - char *name; - HostEntry **pHosts; - int hosts; - int nhosts; - int hasBad; -} AliasEntry; - -typedef struct aclEntry { - struct aclEntry *next; - HostEntry **pEntries; - int entries; - int nentries; - HostEntry **pHosts; - int hosts; - int nhosts; - int flags; -} AclEntry; - - -static int -HasGlobCharacters( char *s ) -{ - for (;;) - switch (*s++) { - case '?': - case '*': - return 1; - case '\0': - return 0; - } -} - -#define PARSE_ALL 0 -#define PARSE_NO_BCAST 1 -#define PARSE_NO_PAT 2 -#define PARSE_NO_ALIAS 4 - -static int -ParseHost( int *nHosts, HostEntry ***hostPtr, int *nChars, - char *hostOrAlias, int len, int parse ) -{ -#if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai; -#else - struct hostent *hostent; -#endif - void *addr; - int addr_type, addr_len; - - if (!(**hostPtr = (HostEntry *)Malloc( sizeof(HostEntry)))) - return 0; - if (!(parse & PARSE_NO_BCAST) && !strcmp( hostOrAlias, BROADCAST_STRING )) - { - (**hostPtr)->type = HOST_BROADCAST; - } - else if (!(parse & PARSE_NO_ALIAS) && *hostOrAlias == ALIAS_CHARACTER) - { - (**hostPtr)->type = HOST_ALIAS; - (**hostPtr)->entry.aliasPattern = hostOrAlias + 1; - *nChars += len; - } - else if (!(parse & PARSE_NO_PAT) && HasGlobCharacters( hostOrAlias )) - { - (**hostPtr)->type = HOST_PATTERN; - (**hostPtr)->entry.hostPattern = hostOrAlias; - *nChars += len + 1; - } - else - { - (**hostPtr)->type = HOST_ADDRESS; -#if defined(IPv6) && defined(AF_INET6) - if (getaddrinfo( hostOrAlias, NULL, NULL, &ai )) -#else - if (!(hostent = gethostbyname( hostOrAlias ))) -#endif - { - LogWarn( "XDMCP ACL: unresolved host %'s\n", hostOrAlias ); - free( (char *)(**hostPtr) ); - return 0; - } -#if defined(IPv6) && defined(AF_INET6) - addr_type = ai->ai_addr->sa_family; - if (ai->ai_family == AF_INET) { - addr = &((struct sockaddr_in *)ai->ai_addr)->sin_addr; - addr_len = sizeof(struct in_addr); - } else /*if (ai->ai_addr->sa_family == AF_INET6)*/ { - addr = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr; - addr_len = sizeof(struct in6_addr); - } -#else - addr_type = hostent->h_addrtype; - addr = hostent->h_addr; - addr_len = hostent->h_length; -#endif - if (!((**hostPtr)->entry.displayAddress.hostAddress = - Malloc( addr_len ))) - { -#if defined(IPv6) && defined(AF_INET6) - freeaddrinfo( ai ); -#endif - free( (char *)(**hostPtr) ); - return 0; - } - memcpy( (**hostPtr)->entry.displayAddress.hostAddress, addr, addr_len ); - *nChars += addr_len; - (**hostPtr)->entry.displayAddress.hostAddrLen = addr_len; - (**hostPtr)->entry.displayAddress.connectionType = addr_type; -#if defined(IPv6) && defined(AF_INET6) - freeaddrinfo( ai ); -#endif - } - *hostPtr = &(**hostPtr)->next; - (*nHosts)++; - return 1; -} - -/* Returns non-0 if string is matched by pattern. Does case folding. */ -static int -patternMatch( const char *string, const char *pattern ) -{ - int p, s; - - if (!string) - string = ""; - - for (;;) { - s = *string++; - switch (p = *pattern++) { - case '*': - if (!*pattern) - return 1; - for (string--; *string; string++) - if (patternMatch( string, pattern )) - return 1; - return 0; - case '?': - if (s == '\0') - return 0; - break; - case '\0': - return s == '\0'; - case '\\': - p = *pattern++; - /* fall through */ - default: - if (tolower( p ) != tolower( s )) - return 0; - } - } -} - -#define MAX_DEPTH 32 - -#define CHECK_NOT 1 -#define CHECK_NO_PAT 2 - -static int -checkHostlist( HostEntry **hosts, int nh, AliasEntry *aliases, int na, - int depth, int flags ) -{ - HostEntry *h; - AliasEntry *a; - int hn, an, am; - - for (h = *hosts, hn = 0; hn < nh; hn++, h = h->next) - if (h->type == HOST_ALIAS) { - if (depth == MAX_DEPTH) { - LogError( "XDMCP ACL: alias recursion involving %%%s\n", - h->entry.aliasPattern ); - return 1; - } - for (a = aliases, an = 0, am = 0; an < na; an++, a = a->next) - if (patternMatch( a->name, h->entry.aliasPattern )) { - am = 1; - if ((flags & CHECK_NOT) && a->hasBad) { - LogError( "XDMCP ACL: alias %%%s with unresolved hosts " - "in denying rule\n", a->name ); - return 1; - } - if (checkHostlist( a->pHosts, a->nhosts, aliases, na, - depth + 1, flags )) - return 1; - } - if (!am) { - if (flags & CHECK_NOT) { - LogError( "XDMCP ACL: unresolved alias pattern %%%s " - "in denying rule\n", h->entry.aliasPattern ); - return 1; - } else - LogWarn( "XDMCP ACL: unresolved alias pattern %%%s\n", - h->entry.aliasPattern ); - } - } else if (h->type == HOST_PATTERN && (flags & CHECK_NO_PAT)) - LogWarn( "XDMCP ACL: wildcarded pattern %'s in host-only context\n", - h->entry.hostPattern ); - return 0; -} - -static void -ReadAccessFile( const char *fname ) -{ - HostEntry *hostList, **hostPtr = &hostList; - AliasEntry *aliasList, **aliasPtr = &aliasList; - AclEntry *acList, **acPtr = &acList, *acl; - ListenEntry *listenList, **listenPtr = &listenList; - char *displayOrAlias, *hostOrAlias; - File file; - int nHosts, nAliases, nAcls, nListens, nChars, error, bad; - int i, len; - - nHosts = nAliases = nAcls = nListens = nChars = error = 0; - if (!readFile( &file, fname, "XDMCP access control" )) - goto sendacl; - while ((displayOrAlias = ReadWord( &file, &len, FALSE ))) { - if (*displayOrAlias == ALIAS_CHARACTER) - { - if (!(*aliasPtr = (AliasEntry *)Malloc( sizeof(AliasEntry)))) { - error = 1; - break; - } - (*aliasPtr)->name = displayOrAlias + 1; - nChars += len; - (*aliasPtr)->hosts = nHosts; - (*aliasPtr)->pHosts = hostPtr; - (*aliasPtr)->nhosts = 0; - (*aliasPtr)->hasBad = 0; - while ((hostOrAlias = ReadWord( &file, &len, TRUE ))) { - if (ParseHost( &nHosts, &hostPtr, &nChars, hostOrAlias, len, - PARSE_NO_BCAST )) - (*aliasPtr)->nhosts++; - else - (*aliasPtr)->hasBad = 1; - } - aliasPtr = &(*aliasPtr)->next; - nAliases++; - } - else if (!strcmp( displayOrAlias, LISTEN_STRING )) - { - if (!(*listenPtr = (ListenEntry *)Malloc( sizeof(ListenEntry)))) { - error = 1; - break; - } - (*listenPtr)->iface = nHosts; - if (!(hostOrAlias = ReadWord( &file, &len, TRUE )) || - !strcmp( hostOrAlias, WILDCARD_STRING ) || - !ParseHost( &nHosts, &hostPtr, &nChars, hostOrAlias, len, - PARSE_NO_BCAST|PARSE_NO_PAT|PARSE_NO_ALIAS )) - { - (*listenPtr)->iface = -1; - } - (*listenPtr)->mcasts = nHosts; - (*listenPtr)->nmcasts = 0; - while ((hostOrAlias = ReadWord( &file, &len, TRUE ))) { - if (ParseHost( &nHosts, &hostPtr, &nChars, hostOrAlias, len, - PARSE_NO_BCAST|PARSE_NO_PAT|PARSE_NO_ALIAS )) - (*listenPtr)->nmcasts++; - } - listenPtr = &(*listenPtr)->next; - nListens++; - } - else - { - if (!(*acPtr = (AclEntry *)Malloc( sizeof(AclEntry)))) { - error = 1; - break; - } - (*acPtr)->flags = 0; - if (*displayOrAlias == NEGATE_CHARACTER) { - (*acPtr)->flags |= a_notAllowed; - displayOrAlias++; - } else if (*displayOrAlias == EQUAL_CHARACTER) - displayOrAlias++; - (*acPtr)->entries = nHosts; - (*acPtr)->pEntries = hostPtr; - (*acPtr)->nentries = 1; - if (!ParseHost( &nHosts, &hostPtr, &nChars, displayOrAlias, len, - PARSE_NO_BCAST )) - { - bad = 1; - if ((*acPtr)->flags & a_notAllowed) { - LogError( "XDMCP ACL: unresolved host in denying rule\n" ); - error = 1; - } - } else - bad = 0; - (*acPtr)->hosts = nHosts; - (*acPtr)->pHosts = hostPtr; - (*acPtr)->nhosts = 0; - while ((hostOrAlias = ReadWord( &file, &len, TRUE ))) { - if (!strcmp( hostOrAlias, CHOOSER_STRING )) - (*acPtr)->flags |= a_useChooser; - else if (!strcmp( hostOrAlias, NOBROADCAST_STRING )) - (*acPtr)->flags |= a_notBroadcast; - else { - if (ParseHost( &nHosts, &hostPtr, &nChars, - hostOrAlias, len, PARSE_NO_PAT )) - (*acPtr)->nhosts++; - } - } - if (!bad) { - acPtr = &(*acPtr)->next; - nAcls++; - } - } - } - - if (!nListens) { - if (!(*listenPtr = (ListenEntry *)Malloc( sizeof(ListenEntry)))) - error = 1; - else { - (*listenPtr)->iface = -1; - (*listenPtr)->mcasts = nHosts; - (*listenPtr)->nmcasts = 0; -#if defined(IPv6) && defined(AF_INET6) && defined(XDM_DEFAULT_MCAST_ADDR6) - if (ParseHost( &nHosts, &hostPtr, &nChars, - XDM_DEFAULT_MCAST_ADDR6, - sizeof(XDM_DEFAULT_MCAST_ADDR6)-1, - PARSE_ALL )) - (*listenPtr)->nmcasts++; -#endif - nListens++; - } - } - - for (acl = acList, i = 0; i < nAcls; i++, acl = acl->next) - if (checkHostlist( acl->pEntries, acl->nentries, aliasList, nAliases, - 0, (acl->flags & a_notAllowed) ? CHECK_NOT : 0 ) || - checkHostlist( acl->pHosts, acl->nhosts, aliasList, nAliases, - 0, CHECK_NO_PAT )) - error = 1; - - if (error) { - nHosts = nAliases = nAcls = nListens = nChars = 0; - sendacl: - LogError( "No XDMCP requests will be granted\n" ); - } - GSendInt( nHosts ); - GSendInt( nListens ); - GSendInt( nAliases ); - GSendInt( nAcls ); - GSendInt( nChars ); - for (i = 0; i < nHosts; i++, hostList = hostList->next) { - GSendInt( hostList->type ); - switch (hostList->type) { - case HOST_ALIAS: - GSendStr( hostList->entry.aliasPattern ); - break; - case HOST_PATTERN: - GSendStr( hostList->entry.hostPattern ); - break; - case HOST_ADDRESS: - GSendArr( hostList->entry.displayAddress.hostAddrLen, - hostList->entry.displayAddress.hostAddress ); - GSendInt( hostList->entry.displayAddress.connectionType ); - break; - } - } - for (i = 0; i < nListens; i++, listenList = listenList->next) { - GSendInt( listenList->iface ); - GSendInt( listenList->mcasts ); - GSendInt( listenList->nmcasts ); - } - for (i = 0; i < nAliases; i++, aliasList = aliasList->next) { - GSendStr( aliasList->name ); - GSendInt( aliasList->hosts ); - GSendInt( aliasList->nhosts ); - } - for (i = 0; i < nAcls; i++, acList = acList->next) { - GSendInt( acList->entries ); - GSendInt( acList->nentries ); - GSendInt( acList->hosts ); - GSendInt( acList->nhosts ); - GSendInt( acList->flags ); - } -} -#endif - - -int main( int argc ATTR_UNUSED, char **argv ) -{ - DSpec dspec; - ValArr va; - char *ci, *disp, *dcls, *cfgfile; - int what; - - if (!(ci = getenv( "CONINFO" ))) { - fprintf( stderr, "This program is part of tdm and should not be run manually.\n" ); - return 1; - } - if (sscanf( ci, "%d %d", &rfd, &wfd ) != 2) - return 1; - - InitLog(); - - if ((debugLevel = GRecvInt()) & DEBUG_WCONFIG) - sleep( 100 ); - -/* Debug ("parsing command line\n");*/ - if (**++argv) - tdmrc_dist = tdmrc = *argv; -/* - while (*++argv) { - } -*/ - - for (;;) { -/* Debug ("Awaiting command ...\n");*/ - if (!GRecvCmd( &what )) - break; - switch (what) { - case GC_Files: -/* Debug ("GC_Files\n");*/ - ReadConf(); - CopyValues( 0, &secGeneral, 0, C_CONFIG ); -#ifdef XDMCP - CopyValues( 0, &secXdmcp, 0, C_CONFIG ); - GSendInt( 2 ); -#else - GSendInt( 1 ); -#endif - GSendStr( tdmrc ); - GSendInt( -1 ); -#ifdef XDMCP - GSendNStr( VXaccess.ptr, VXaccess.len - 1 ); - GSendInt( 0 ); -#endif - for (; (what = GRecvInt()) != -1; ) - switch (what) { - case GC_gGlobal: - case GC_gDisplay: - GSendInt( 0 ); - break; -#ifdef XDMCP - case GC_gXaccess: - GSendInt( 1 ); - break; -#endif - default: - GSendInt( -1 ); - break; - } - break; - case GC_GetConf: -/* Debug( "GC_GetConf\n" );*/ - memset( &va, 0, sizeof(va) ); - what = GRecvInt(); - cfgfile = GRecvStr(); - switch (what) { - case GC_gGlobal: -/* Debug( "GC_gGlobal\n" );*/ - Debug( "getting global config\n" ); - ReadConf(); - CopyValues( &va, &secGeneral, 0, 0 ); -#ifdef XDMCP - CopyValues( &va, &secXdmcp, 0, 0 ); -#endif - CopyValues( &va, &secShutdown, 0, 0 ); - SendValues( &va ); - break; - case GC_gDisplay: -/* Debug( "GC_gDisplay\n" );*/ - disp = GRecvStr(); -/* Debug( " Display %s\n", disp );*/ - dcls = GRecvStr(); -/* Debug( " Class %s\n", dcls );*/ - Debug( "getting config for display %s, class %s\n", disp, dcls ); - MkDSpec( &dspec, disp, dcls ? dcls : "" ); - ReadConf(); - CopyValues( &va, &sec_Core, &dspec, 0 ); - CopyValues( &va, &sec_Greeter, &dspec, 0 ); - free( disp ); - if (dcls) - free( dcls ); - SendValues( &va ); - break; -#ifdef XDMCP - case GC_gXaccess: - ReadAccessFile( cfgfile ); - break; -#endif - default: - Debug( "Unsupported config category %#x\n", what ); - } - free( cfgfile ); - break; - default: - Debug( "Unknown config command %#x\n", what ); - } - } - -/* Debug( "Config reader exiting ..." );*/ - return EX_NORMAL; -} diff --git a/kdm/kfrontend/kdm_greet.c b/kdm/kfrontend/kdm_greet.c deleted file mode 100644 index f74c2410d..000000000 --- a/kdm/kfrontend/kdm_greet.c +++ /dev/null @@ -1,787 +0,0 @@ -/* - -KDE Greeter module for xdm - -Copyright (C) 2001-2003 Oswald Buddenhagen - -This file contains code from the old xdm core, -Copyright 1988, 1998 Keith Packard, MIT X Consortium/The Open Group - -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 - -#include "tdm_greet.h" -#include "tdmconfig.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _POSIX_PRIORITY_SCHEDULING -# include -#endif - -# include -#if defined(HAVE_XTEST) || defined(HAVE_XKB) -# include -#endif - -#ifdef HAVE_XTEST -# include -#endif - -#ifdef HAVE_XKB -# include -#endif - -extern void LogOutOfMem( void ); - -static void * -Realloc( void *ptr, size_t size ) -{ - void *ret; - - if (!(ret = realloc( ptr, size )) && size) - LogOutOfMem(); - return ret; -} - -#define PRINT_QUOTES -#define PRINT_ARRAYS -#define LOG_NAME "tdm_greet" -#define LOG_DEBUG_MASK DEBUG_GREET -#define LOG_PANIC_EXIT 1 -#define STATIC -#include - -static void -GDebug( const char *fmt, ... ) -{ - va_list args; - - if (debugLevel & DEBUG_HLPCON) { - va_start( args, fmt ); - Logger( DM_DEBUG, fmt, args ); - va_end( args ); - } -} - - -char *dname; - -int rfd; -static int wfd, mrfd, mwfd, srfd, swfd; -static const char *who; - -void -GSet( int master ) -{ - if (master) - rfd = mrfd, wfd = mwfd, who = "core (master)"; - else - rfd = srfd, wfd = swfd, who = "core"; - -} - -static int -Reader( void *buf, int count ) -{ - int ret, rlen; - - for (rlen = 0; rlen < count; ) { - dord: - ret = read( rfd, (void *)((char *)buf + rlen), count - rlen ); - if (ret < 0) { - if (errno == EINTR) - goto dord; - if (errno == EAGAIN) - break; - return -1; - } - if (!ret) - break; - rlen += ret; - } - return rlen; -} - -static void -GRead( void *buf, int count ) -{ - if (Reader( buf, count ) != count) - LogPanic( "Can't read from %s\n", who ); -} - -static void -GWrite( const void *buf, int count ) -{ - if (write( wfd, buf, count ) != count) - LogPanic( "Can't write to %s\n", who ); -#ifdef _POSIX_PRIORITY_SCHEDULING - if ((debugLevel & DEBUG_HLPCON)) - sched_yield(); -#endif -} - -void -GSendInt( int val ) -{ - GDebug( "Sending int %d (%#x) to %s\n", val, val, who ); - GWrite( &val, sizeof(val) ); -} - -void -GSendStr( const char *buf ) -{ - int len = buf ? strlen( buf ) + 1 : 0; - GDebug( "Sending string %'s to %s\n", buf, who ); - GWrite( &len, sizeof(len) ); - GWrite( buf, len ); -} - -/* -static void -GSendNStr( const char *buf, int len ) -{ - int tlen = len + 1; - GDebug( "Sending string %'.*s to %s\n", len, buf, who ); - GWrite( &tlen, sizeof(tlen) ); - GWrite( buf, len ); - GWrite( "", 1 ); -} -*/ - -void -GSendArr( int len, const char *buf ) -{ - GDebug( "Sending array %02[:*hhx to %s\n", len, buf, who ); - GWrite( &len, sizeof(len) ); - GWrite( buf, len ); -} - -int -GRecvInt() -{ - int val; - - GDebug( "Receiving int from %s ...\n", who ); - GRead( &val, sizeof(val) ); - GDebug( " -> %d (%#x)\n", val, val ); - return val; -} - -static char * -iGRecvArr( int *rlen ) -{ - int len; - char *buf; - - GRead( &len, sizeof(len) ); - *rlen = len; - GDebug( " -> %d bytes\n", len ); - if (!len) - return (char *)0; - if (!(buf = malloc( len ))) - LogPanic( "No memory for read buffer\n" ); - GRead( buf, len ); - return buf; -} - -char * -GRecvStr() -{ - int len; - char *buf; - - GDebug( "Receiving string from %s ...\n", who ); - buf = iGRecvArr( &len ); - GDebug( " -> %'.*s\n", len, buf ); - return buf; -} - -char ** -GRecvStrArr( int *rnum ) -{ - int num; - char **argv, **cargv; - - GDebug( "Receiving string array from %s ...\n", who ); - GRead( &num, sizeof(num) ); - GDebug( " -> %d strings\n", num ); - if (rnum) - *rnum = num; - if (!num) - return (char **)0; - if (!(argv = malloc( num * sizeof(char *)))) - LogPanic( "No memory for read buffer\n" ); - for (cargv = argv; --num >= 0; cargv++) - *cargv = GRecvStr(); - return argv; -} - -char * -GRecvArr( int *num ) -{ - char *arr; - - GDebug( "Receiving array from %s ...\n", who ); - GRead( num, sizeof(*num) ); - GDebug( " -> %d bytes\n", *num ); - if (!*num) - return (char *)0; - if (!(arr = malloc( *num ))) - LogPanic( "No memory for read buffer\n" ); - GRead( arr, *num ); - GDebug( " -> %02[*hhx\n", *num, arr ); - return arr; -} - -static void -ReqCfg( int id ) -{ - GSendInt( G_GetCfg ); - GSendInt( id ); - switch (GRecvInt()) { - case GE_NoEnt: - LogPanic( "Config value %#x not available\n", id ); - case GE_BadType: - LogPanic( "Core does not know type of config value %#x\n", id ); - } -} - -int -GetCfgInt( int id ) -{ - ReqCfg( id ); - return GRecvInt(); -} - -char * -GetCfgStr( int id ) -{ - ReqCfg( id ); - return GRecvStr(); -} - -char ** -GetCfgStrArr( int id, int *len ) -{ - ReqCfg( id ); - return GRecvStrArr( len ); -} - -static void -disposeSession( dpySpec *sess ) -{ - free( sess->display ); - free( sess->from ); - if (sess->user) - free( sess->user ); - if (sess->session) - free( sess->session ); -} - -dpySpec * -fetchSessions( int flags ) -{ - dpySpec *sess, *sessions = 0, tsess; - - GSet( 1 ); - GSendInt( G_List ); - GSendInt( flags ); - next: - while ((tsess.display = GRecvStr())) { - tsess.from = GRecvStr(); -#ifdef HAVE_VTS - tsess.vt = GRecvInt(); -#endif - tsess.user = GRecvStr(); - tsess.session = GRecvStr(); - tsess.flags = GRecvInt(); - if ((tsess.flags & isTTY) && *tsess.from) - for (sess = sessions; sess; sess = sess->next) - if (sess->user && !strcmp( sess->user, tsess.user ) && - !strcmp( sess->from, tsess.from )) - { - sess->count++; - disposeSession( &tsess ); - goto next; - } - if (!(sess = malloc( sizeof(*sess) ))) - LogPanic( "Out of memory\n" ); - tsess.count = 1; - tsess.next = sessions; - *sess = tsess; - sessions = sess; - } - GSet( 0 ); - return sessions; -} - -void -disposeSessions( dpySpec *sess ) -{ - while (sess) { - dpySpec *nsess = sess->next; - disposeSession( sess ); - free( sess ); - sess = nsess; - } -} - -void -freeStrArr( char **arr ) -{ - char **tarr; - - if (arr) { - for (tarr = arr; *tarr; tarr++) - free( *tarr ); - free( arr ); - } -} - - -static int -ignoreErrors( Display *dpy ATTR_UNUSED, XErrorEvent *event ATTR_UNUSED ) -{ - Debug( "ignoring X error\n" ); - return 0; -} - -/* - * this is mostly bogus -- but quite useful. I wish the protocol - * had some way of enumerating and identifying clients, that way - * this code wouldn't have to be this kludgy. - */ - -static void -killWindows( Display *dpy, Window window ) -{ - Window root, parent, *children; - unsigned child, nchildren = 0; - - while (XQueryTree( dpy, window, &root, &parent, &children, &nchildren ) - && nchildren > 0) - { - for (child = 0; child < nchildren; child++) { - Debug( "XKillClient 0x%lx\n", (unsigned long)children[child] ); - XKillClient( dpy, children[child] ); - } - XFree( (char *)children ); - } -} - -static jmp_buf resetJmp; - -static void -abortReset( int n ATTR_UNUSED ) -{ - longjmp (resetJmp, 1); -} - -/* - * this display connection better not have any windows... - */ - -static void -pseudoReset( Display *dpy ) -{ - int screen; - - if (setjmp( resetJmp )) { - LogError( "pseudoReset timeout\n" ); - } else { - (void)signal( SIGALRM, abortReset ); - (void)alarm( 30 ); - XSetErrorHandler( ignoreErrors ); - for (screen = 0; screen < ScreenCount( dpy ); screen++) { - Debug( "pseudoReset screen %d\n", screen ); - killWindows( dpy, RootWindow( dpy, screen ) ); - } - Debug( "before XSync\n" ); - XSync( dpy, False ); - (void)alarm( 0 ); - } - signal( SIGALRM, SIG_DFL ); - XSetErrorHandler( (XErrorHandler)0 ); - Debug( "pseudoReset done\n" ); -} - - -static jmp_buf syncJump; - -static void -syncTimeout( int n ATTR_UNUSED ) -{ - longjmp( syncJump, 1 ); -} - -void -SecureDisplay( Display *dpy ) -{ - Debug( "SecureDisplay %s\n", dname ); - (void)signal( SIGALRM, syncTimeout ); - if (setjmp( syncJump )) { - LogError( "Display %s could not be secured\n", dname ); - exit( EX_RESERVER_DPY ); - } - (void)alarm( (unsigned)_grabTimeout ); - Debug( "Before XGrabServer %s\n", dname ); - XGrabServer( dpy ); - Debug( "XGrabServer succeeded %s\n", dname ); - if (XGrabKeyboard( dpy, DefaultRootWindow( dpy ), True, GrabModeAsync, - GrabModeAsync, CurrentTime ) != GrabSuccess) - { - (void)alarm( 0 ); - (void)signal( SIGALRM, SIG_DFL ); - LogError( "Keyboard on display %s could not be secured\n", dname ); - sleep( 10 ); - exit( EX_RESERVER_DPY ); - } - (void)alarm( 0 ); - (void)signal( SIGALRM, SIG_DFL ); - pseudoReset( dpy ); - if (!_grabServer) - { - XUngrabServer( dpy ); - XSync( dpy, 0 ); - } - Debug( "done secure %s\n", dname ); -#ifdef HAVE_XKBSETPERCLIENTCONTROLS - /* - * Activate the correct mapping for modifiers in XKB extension as - * grabbed keyboard has its own mapping by default - */ - { - int opcode, evbase, errbase, majret, minret; - unsigned int value = XkbPCF_GrabsUseXKBStateMask; - if (XkbQueryExtension( dpy, &opcode, &evbase, - &errbase, &majret, &minret )) - XkbSetPerClientControls( dpy, value, &value ); - } -#endif -} - -void -UnsecureDisplay( Display *dpy ) -{ - Debug( "Unsecure display %s\n", dname ); - if (_grabServer) { - XUngrabServer( dpy ); - XSync( dpy, 0 ); - } -} - -static jmp_buf pingTime; - -static int -PingLostIOErr( Display *dpy ATTR_UNUSED ) -{ - longjmp( pingTime, 1 ); -} - -static void -PingLostSig( int n ATTR_UNUSED ) -{ - longjmp( pingTime, 1 ); -} - -int -PingServer( Display *dpy ) -{ - int (*oldError)( Display * ); - void (*oldSig)( int ); - int oldAlarm; - - oldError = XSetIOErrorHandler( PingLostIOErr ); - oldAlarm = alarm( 0 ); - oldSig = signal( SIGALRM, PingLostSig ); - (void)alarm( _pingTimeout * 60 ); - if (!setjmp( pingTime )) { - Debug( "Ping server\n" ); - XSync( dpy, 0 ); - } else { - Debug( "Server dead\n" ); - (void)alarm( 0 ); - (void)signal( SIGALRM, SIG_DFL ); - XSetIOErrorHandler( oldError ); - return 0; - } - (void)alarm( 0 ); - (void)signal( SIGALRM, oldSig ); - (void)alarm( oldAlarm ); - Debug( "Server alive\n" ); - XSetIOErrorHandler( oldError ); - return 1; -} - -/* - * Modifier changing code based on tdebase/kxkb/kcmmisc.cpp - * - * XTest part: Copyright (C) 2000-2001 Lubos Lunak - * XKB part: Copyright (C) 2001-2002 Oswald Buddenhagen - * - */ - -#ifdef HAVE_XKB -static int -xkb_init( Display *dpy ) -{ - int xkb_opcode, xkb_event, xkb_error; - int xkb_lmaj = XkbMajorVersion; - int xkb_lmin = XkbMinorVersion; - return XkbLibraryVersion( &xkb_lmaj, &xkb_lmin ) && - XkbQueryExtension( dpy, &xkb_opcode, &xkb_event, - &xkb_error, &xkb_lmaj, &xkb_lmin ); -} - -static unsigned int -xkb_modifier_mask_work( XkbDescPtr xkb, const char *name ) -{ - int i; - - if (!xkb->names) - return 0; - for (i = 0; i < XkbNumVirtualMods; i++) { - char *modStr = XGetAtomName( xkb->dpy, xkb->names->vmods[i] ); - if (modStr != NULL && strcmp( name, modStr ) == 0) { - unsigned int mask; - XkbVirtualModsToReal( xkb, 1 << i, &mask ); - return mask; - } - } - return 0; -} - -static unsigned int -xkb_modifier_mask( Display *dpy, const char *name ) -{ - XkbDescPtr xkb; - - if ((xkb = XkbGetKeyboard( dpy, XkbAllComponentsMask, XkbUseCoreKbd ))) { - unsigned int mask = xkb_modifier_mask_work( xkb, name ); - XkbFreeKeyboard( xkb, 0, True ); - return mask; - } - return 0; -} - -static int -xkb_get_modifier_state( Display *dpy, const char *name ) -{ - unsigned int mask; - XkbStateRec state; - - if (!(mask = xkb_modifier_mask( dpy, name ))) - return 0; - XkbGetState( dpy, XkbUseCoreKbd, &state ); - return (mask & state.locked_mods) != 0; -} - -static int -xkb_set_modifier( Display *dpy, const char *name, int sts ) -{ - unsigned int mask; - - if (!(mask = xkb_modifier_mask( dpy, name ))) - return 0; - XkbLockModifiers( dpy, XkbUseCoreKbd, mask, sts ? mask : 0 ); - return 1; -} -#endif /* HAVE_XKB */ - -#ifdef HAVE_XTEST -static int -xtest_get_modifier_state( Display *dpy, int key ) -{ - XModifierKeymap *map; - KeyCode modifier_keycode; - unsigned int i, mask; - Window dummy1, dummy2; - int dummy3, dummy4, dummy5, dummy6; - - if ((modifier_keycode = XKeysymToKeycode( dpy, key )) == NoSymbol) - return 0; - map = XGetModifierMapping( dpy ); - for (i = 0; i < 8; ++i) - if (map->modifiermap[map->max_keypermod * i] == modifier_keycode) { - XFreeModifiermap( map ); - XQueryPointer( dpy, DefaultRootWindow( dpy ), - &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, - &mask ); - return (mask & (1 << i)) != 0; - } - XFreeModifiermap( map ); - return 0; -} - -static void -xtest_fake_keypress( Display *dpy, int key ) -{ - XTestFakeKeyEvent( dpy, XKeysymToKeycode( dpy, key ), True, CurrentTime ); - XTestFakeKeyEvent( dpy, XKeysymToKeycode( dpy, key ), False, CurrentTime ); -} -#endif /* HAVE_XTEST */ - -#ifdef HAVE_XKB -static int havexkb; -#endif -static int nummodified, oldnumstate, newnumstate; -static Display *dpy; - -void -setup_modifiers( Display *mdpy, int numlock ) -{ - if (numlock == 2) - return; - newnumstate = numlock; - nummodified = 1; - dpy = mdpy; -#ifdef HAVE_XKB - if (xkb_init( mdpy )) { - havexkb = 1; - oldnumstate = xkb_get_modifier_state( mdpy, "NumLock" ); - xkb_set_modifier( mdpy, "NumLock", numlock ); - return; - } -#endif -#ifdef HAVE_XTEST - oldnumstate = xtest_get_modifier_state( mdpy, XK_Num_Lock ); - if (oldnumstate != numlock) - xtest_fake_keypress( mdpy, XK_Num_Lock ); -#endif -} - -void -restore_modifiers( void ) -{ -#ifdef HAVE_XTEST - int numstat; -#endif - - if (!nummodified) - return; -#ifdef HAVE_XKB - if (havexkb) { - if (xkb_get_modifier_state( dpy, "NumLock" ) == newnumstate) - xkb_set_modifier( dpy, "NumLock", oldnumstate ); - return; - } -#endif -#ifdef HAVE_XTEST - numstat = xtest_get_modifier_state( dpy, XK_Num_Lock ); - if (numstat == newnumstate && newnumstate != oldnumstate) - xtest_fake_keypress( dpy, XK_Num_Lock ); -#endif -} - -void -setCursor( Display *mdpy, int window, int shape ) -{ - Cursor xcursor; - - if ((xcursor = XCreateFontCursor( mdpy, shape ))) { - XDefineCursor( mdpy, window, xcursor ); - XFreeCursor( mdpy, xcursor ); - XFlush( mdpy ); - } -} - -static void -sigterm( int n ATTR_UNUSED ) -{ - exit( EX_NORMAL ); -} - -static char *savhome; - -static void -cleanup( void ) -{ - char buf[128]; - - if (strcmp( savhome, getenv( "HOME" ) ) || memcmp( savhome, "/tmp/", 5 )) - LogError( "Internal error: memory corruption detected\n" ); /* no panic: recursion */ - else { - sprintf( buf, "rm -rf %s", savhome ); - system( buf ); - } -} - -extern void kg_main( const char *argv0 ); - -int -main( int argc ATTR_UNUSED, char **argv ) -{ - char *ci; - int i; - char qtrc[40]; - - if (!(ci = getenv( "CONINFO" ))) { - fprintf( stderr, "This program is part of tdm and should not be run manually.\n" ); - return 1; - } - if (sscanf( ci, "%d %d %d %d", &srfd, &swfd, &mrfd, &mwfd ) != 4) - return 1; - fcntl( srfd, F_SETFD, FD_CLOEXEC ); - fcntl( swfd, F_SETFD, FD_CLOEXEC ); - fcntl( mrfd, F_SETFD, FD_CLOEXEC ); - fcntl( mwfd, F_SETFD, FD_CLOEXEC ); - GSet( 0 ); - - InitLog(); - - if ((debugLevel = GRecvInt()) & DEBUG_WGREET) - sleep( 100 ); - - signal( SIGTERM, sigterm ); - - dname = getenv( "DISPLAY" ); - - init_config(); - - /* for TQSettings */ - srand( time( 0 ) ); - for (i = 0; i < 10000; i++) { - sprintf( qtrc, "/tmp/%010d", rand() ); - if (!mkdir( qtrc, 0700 )) - goto okay; - } - LogPanic( "Cannot create $HOME\n" ); - okay: - if (setenv( "HOME", qtrc, 1 )) - LogPanic( "Cannot set $HOME\n" ); - if (!(savhome = strdup( qtrc ))) - LogPanic( "Cannot save $HOME\n" ); - atexit( cleanup ); - - setenv( "LC_ALL", _language, 1 ); - - kg_main( argv[0] ); - - return EX_NORMAL; -} diff --git a/kdm/kfrontend/kdm_greet.h b/kdm/kfrontend/kdm_greet.h deleted file mode 100644 index 9f7e3bd6a..000000000 --- a/kdm/kfrontend/kdm_greet.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - -KDE Greeter module for xdm - -Copyright (C) 2001-2003 Oswald Buddenhagen - -This file contains code from the old xdm core, -Copyright 1988, 1998 Keith Packard, MIT X Consortium/The Open Group - -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. - -*/ - -#ifndef _TDM_GREET_H_ -#define _TDM_GREET_H_ - -#include /* for the ATTR_ defines */ -#include /* for the HAVE_VTS define */ - -#ifdef __cplusplus -extern "C" { -#endif - -void GSet( int master ); -void GSendInt( int val ); -void GSendStr( const char *buf ); -/*void GSendNStr( const char *buf, int len );*/ -void GSendArr( int len, const char *buf ); -int GRecvInt( void ); -char *GRecvStr( void ); -char **GRecvStrArr( int *len ); -char *GRecvArr( int *len ); - -int GetCfgInt( int id ); -char *GetCfgStr( int id ); -char **GetCfgStrArr( int id, int *len ); - -typedef struct dpySpec { - struct dpySpec *next; - char *display, *from, *user, *session; -#ifdef HAVE_VTS - int vt; -#endif - int flags; - int count; -} dpySpec; - -dpySpec *fetchSessions( int flags ); -void disposeSessions( dpySpec *sess ); - -void freeStrArr( char **arr ); - -void Debug( const char *fmt, ... ); -void LogInfo( const char *fmt, ... ); -void LogWarn( const char *fmt, ... ); -void LogError( const char *fmt, ... ); -void LogPanic( const char *fmt, ... ) ATTR_NORETURN; - -struct _XDisplay; - -void SecureDisplay( struct _XDisplay *dpy ); -void UnsecureDisplay( struct _XDisplay *dpy ); -int PingServer( struct _XDisplay *dpy ); - -void setup_modifiers( struct _XDisplay *mdpy, int numlock ); -void restore_modifiers( void ); - -void setCursor( struct _XDisplay *mdpy, int window, int shape ); - - -extern int rfd; /* for select() loops */ - -extern char *dname; /* d->name */ - -#ifdef __cplusplus -} -#endif - -#endif /* _TDM_GREET_H_ */ diff --git a/kdm/kfrontend/kdmadmindialog.cpp b/kdm/kfrontend/kdmadmindialog.cpp deleted file mode 100644 index 6486eb3dc..000000000 --- a/kdm/kfrontend/kdmadmindialog.cpp +++ /dev/null @@ -1,176 +0,0 @@ - /* - - Admin dialog - - Copyright (C) 1997, 1998, 2000 Steffen Hansen - Copyright (C) 2000-2003 Oswald Buddenhagen - - - 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - */ - -#include "tdmadmindialog.h" -#include "tdmconfig.h" -#include "kgdialog.h" -#include "tdm_greet.h" -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -int TDMAdmin::curPlugin = -1; -PluginList TDMAdmin::pluginList; - -TDMAdmin::TDMAdmin( const TQString &user, TQWidget *_parent ) - : inherited( _parent ) - , verify( 0 ), curUser(user) -{ - TQSizePolicy fp( TQSizePolicy::Fixed, TQSizePolicy::Fixed ); - - TQVBoxLayout *box = new TQVBoxLayout( this, 10 ); - - TQHBoxLayout *hlay = new TQHBoxLayout( box ); - - GSendInt( G_ReadDmrc ); - GSendStr( "root" ); - GRecvInt(); // ignore status code ... - - if (curPlugin < 0) { - curPlugin = 0; - pluginList = KGVerify::init( "classic" ); - } - verify = new KGStdVerify( this, this, - this, "root", - pluginList, KGreeterPlugin::Authenticate, - KGreeterPlugin::Shutdown ); - verify->selectPlugin( curPlugin ); - box->addLayout( verify->getLayout() ); - TQAccel *accel = new TQAccel( this ); - accel->insertItem( ALT+Key_A, 0 ); - connect( accel, TQT_SIGNAL(activated(int)), TQT_SLOT(slotActivatePlugMenu()) ); - - box->addWidget( new KSeparator( KSeparator::HLine, this ) ); - - okButton = new KPushButton( KStdGuiItem::ok(), this ); - okButton->setSizePolicy( fp ); - okButton->setDefault( true ); - cancelButton = new KPushButton( KStdGuiItem::cancel(), this ); - cancelButton->setSizePolicy( fp ); - - hlay = new TQHBoxLayout( box ); - hlay->addStretch( 1 ); - hlay->addWidget( okButton ); - hlay->addStretch( 1 ); - hlay->addWidget( cancelButton ); - hlay->addStretch( 1 ); - - connect( okButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); - connect( cancelButton, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) ); - - slotWhenChanged(); -} - -TDMAdmin::~TDMAdmin() -{ - hide(); - delete verify; -} - -void -TDMAdmin::slotActivatePlugMenu() -{ - TQPopupMenu *cmnu = verify->getPlugMenu(); - TQSize sh( cmnu->sizeHint() / 2 ); - cmnu->exec( geometry().center() - TQPoint( sh.width(), sh.height() ) ); -} - -void -TDMAdmin::accept() -{ - verify->accept(); -} - -void -TDMAdmin::slotWhenChanged() -{ - verify->abort(); - verify->setEnabled( 1 ); - verify->start(); -} - -void -TDMAdmin::bye_bye() -{ - GSendInt( G_GetDmrc ); - GSendStr( "Session" ); - char *sess = GRecvStr(); - if (sess && strcmp(sess, "admin")) { - GSendInt( G_PutDmrc ); - GSendStr( "OrigSession"); - GSendStr( sess); - free(sess); - } - - GSendInt( G_PutDmrc ); - GSendStr( "Session" ); - GSendStr( "admin" ); - inherited::accept(); -} - -void -TDMAdmin::verifyPluginChanged( int id ) -{ - curPlugin = id; - adjustSize(); -} - -void -TDMAdmin::verifyOk() -{ - bye_bye(); -} - -void -TDMAdmin::verifyFailed() -{ - okButton->setEnabled( false ); - cancelButton->setEnabled( false ); -} - -void -TDMAdmin::verifyRetry() -{ - okButton->setEnabled( true ); - cancelButton->setEnabled( true ); -} - -void -TDMAdmin::verifySetUser( const TQString & ) -{ -} - - -#include "tdmadmindialog.moc" diff --git a/kdm/kfrontend/kdmadmindialog.h b/kdm/kfrontend/kdmadmindialog.h deleted file mode 100644 index e5a68fbb9..000000000 --- a/kdm/kfrontend/kdmadmindialog.h +++ /dev/null @@ -1,70 +0,0 @@ - /* - - Shutdown dialog - - Copyright (C) 1997, 1998 Steffen Hansen - Copyright (C) 2000-2003 Oswald Buddenhagen - - - 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - */ - - -#ifndef TDMADMIN_H -#define TDMADMIN_H - -#include "kgverify.h" - -#include - -class LiloInfo; -class TQLabel; -class KPushButton; -class TQButtonGroup; -class TQComboBox; - -class TDMAdmin : public FDialog, public KGVerifyHandler { - Q_OBJECT - typedef FDialog inherited; - -public: - TDMAdmin( const TQString &user, TQWidget *_parent = 0 ); - ~TDMAdmin(); - -public slots: - void accept(); - void slotWhenChanged(); - void slotActivatePlugMenu(); - -private: - void bye_bye(); - - KPushButton *okButton, *cancelButton; - KGStdVerify *verify; - TQString curUser; - - static int curPlugin; - static PluginList pluginList; - -public: // from KGVerifyHandler - virtual void verifyPluginChanged( int id ); - virtual void verifyOk(); - virtual void verifyFailed(); - virtual void verifyRetry(); - virtual void verifySetUser( const TQString &user ); -}; - -#endif diff --git a/kdm/kfrontend/kdmclock.cpp b/kdm/kfrontend/kdmclock.cpp deleted file mode 100644 index 2b2a99cea..000000000 --- a/kdm/kfrontend/kdmclock.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - -clock module for tdm - -Copyright (C) 2000 Espen Sand, espen@kde.org - Based on work by NN(yet to be determined) -flicker free code by Remi Guyomarch - -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 "tdmclock.h" - -//#include -//#include - -#include -#include -#include -#include - -KdmClock::KdmClock( TQWidget *parent, const char *name ) - : inherited( parent, name ) -{ - // start timer - TQTimer *timer = new TQTimer( this ); - connect( timer, TQT_SIGNAL(timeout()), TQT_SLOT(timeout()) ); - timer->start( 1000 ); - - // reading rc file - //KConfig *config = kapp->config(); - - //config->setGroup( "Option" ); - mDate = false;//config->readNumEntry( "date", FALSE ); - mSecond = true;//config->readNumEntry( "second", TRUE ); - mDigital = false;//config->readNumEntry( "digital", FALSE ); - mBorder = false;//config->readNumEntry( "border", FALSE ); - - //config->setGroup( "Font" ); - mFont.setFamily( TQString::fromLatin1("Utopia")/*config->readEntry( "Family", "Utopia")*/ ); - mFont.setPointSize( 51/*config->readNumEntry( "Point Size", 51)*/ ); - mFont.setWeight( 75/*config->readNumEntry( "Weight", 75)*/ ); - mFont.setItalic( TRUE/*config->readNumEntry( "Italic",TRUE )*/ ); - mFont.setBold( TRUE/*config->readNumEntry( "Bold",TRUE )*/ ); - - setFixedSize( 100, 100 ); - - if (mBorder) { - setLineWidth( 1 ); - setFrameStyle( Box|Plain ); - //setFrameStyle( WinPanel|Sunken ); - } - -/* - if (!mDigital) { - if (height() < width()) - resize( height(), height() ); - else - resize( width() ,width() ); - } -*/ - - //setBackgroundOrigin( WindowOrigin ); - mBackgroundBrush = backgroundBrush(); - setBackgroundMode( NoBackground ); - repaint(); -} - - -void KdmClock::showEvent( TQShowEvent * ) -{ - repaint(); -} - - -void KdmClock::timeout() -{ - repaint(); -} - -void KdmClock::paintEvent( TQPaintEvent * ) -{ - if (!isVisible()) - return; - - TQPainter p( this ); - drawFrame( &p ); - - TQPixmap pm( contentsRect().size() ); - TQPainter paint; - paint.begin( &pm ); - paint.fillRect( contentsRect(), mBackgroundBrush ); - - // get current time - TQTime time = TQTime::currentTime(); - -/* - if (mDigital) { - TQString buf; - if (mSecond) - buf.sprintf( "%02d:%02d:%02d", time.hour(), time.minute(), - time.second() ); - else - buf.sprintf( "%02d:%02d", time.hour(), time.minute() ); - mFont.setPointSize( QMIN( (int)(width()/buf.length()*1.5),height() ) ); - paint.setFont( mFont ); - paint.setPen( backgroundColor() ); - paint.drawText( contentsRect(),AlignHCenter|AlignVCenter, buf,-1,0,0 ); - } else { -*/ - TQPointArray pts; - TQPoint cp = contentsRect().center() - TQPoint( 2,2 ); - int d = QMIN( contentsRect().width()-15,contentsRect().height()-15 ); - paint.setPen( foregroundColor() ); - paint.setBrush( foregroundColor() ); - - TQWMatrix matrix; - matrix.translate( cp.x(), cp.y() ); - matrix.scale( d/1000.0F, d/1000.0F ); - - // Hour - float h_angle = 30*(time.hour()%12-3) + time.minute()/2; - matrix.rotate( h_angle ); - paint.setWorldMatrix( matrix ); - pts.setPoints( 4, -20,0, 0,-20, 300,0, 0,20 ); - paint.drawPolygon( pts ); - matrix.rotate( -h_angle ); - - // Minute - float m_angle = (time.minute()-15)*6; - matrix.rotate( m_angle ); - paint.setWorldMatrix( matrix ); - pts.setPoints( 4, -10,0, 0,-10, 400,0, 0,10 ); - paint.drawPolygon( pts ); - matrix.rotate( -m_angle ); - - // Second - float s_angle = (time.second()-15)*6; - matrix.rotate( s_angle ); - paint.setWorldMatrix( matrix ); - pts.setPoints( 4,0,0,0,0,400,0,0,0 ); - if (mSecond) - paint.drawPolygon( pts ); - matrix.rotate( -s_angle ); - - // quadrante - for (int i=0 ; i < 60 ; i++) { - paint.setWorldMatrix( matrix ); - if ((i % 5) == 0) - paint.drawLine( 450,0, 500,0 ); // draw hour lines - else - paint.drawPoint( 480,0 ); // draw second lines - matrix.rotate( 6 ); - } - -// } // if (mDigital) - paint.end(); - - // flicker free code by Remi Guyomarch - bitBlt( this, contentsRect().topLeft(), &pm ); -} - -#include "tdmclock.moc" diff --git a/kdm/kfrontend/kdmclock.h b/kdm/kfrontend/kdmclock.h deleted file mode 100644 index 89a48eb8e..000000000 --- a/kdm/kfrontend/kdmclock.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - -clock module for tdm - -Copyright (C) 2000 Espen Sand, espen@kde.org - Based on work by NN (yet to be determined) - -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. - -*/ - -#ifndef _TDM_CLOCK_H_ -#define _TDM_CLOCK_H_ - -#include - -class KdmClock : public TQFrame { - Q_OBJECT - typedef TQFrame inherited; - - public: - KdmClock( TQWidget *parent=0, const char *name=0 ); - - protected: - virtual void showEvent( TQShowEvent * ); - virtual void paintEvent( TQPaintEvent * ); - - private slots: - void timeout(); - - private: - TQBrush mBackgroundBrush; - TQFont mFont; - bool mSecond; - bool mDigital; - bool mDate; - bool mBorder; -}; - -#endif diff --git a/kdm/kfrontend/kdmconfig.cpp b/kdm/kfrontend/kdmconfig.cpp deleted file mode 100644 index 5b57a6375..000000000 --- a/kdm/kfrontend/kdmconfig.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - -Config for tdm - -Copyright (C) 1997, 1998 Steffen Hansen -Copyright (C) 2000-2003 Oswald Buddenhagen - - -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 "tdmconfig.h" -#include "tdm_greet.h" - -#include -#include - -#include -#include -#include -#include - -struct timeval st = {0, 0}; - -CONF_GREET_DEFS - -TQString _stsFile; -bool _isLocal; -bool _authorized; - -static TQString -GetCfgQStr( int id ) -{ - char *tmp = GetCfgStr( id ); - TQString qs = TQString::fromUtf8( tmp ); - free( tmp ); - return qs; -} - -static TQStringList -GetCfgQStrList( int id ) -{ - int i, len; - char **tmp = GetCfgStrArr( id, &len ); - TQStringList qsl; - for (i = 0; i < len - 1; i++) { - qsl.append( TQString::fromUtf8( tmp[i] ) ); - free( tmp[i] ); - } - free( tmp ); - return qsl; -} - -// Based on kconfigbase.cpp -static TQFont -Str2Font( const TQString &aValue ) -{ - uint nFontBits; - TQFont aRetFont; - TQString chStr; - - TQStringList sl = TQStringList::split( TQString::fromLatin1(","), aValue ); - - if (sl.count() == 1) { - /* X11 font spec */ - aRetFont = TQFont( aValue ); - aRetFont.setRawMode( true ); - } else if (sl.count() == 10) { - /* qt3 font spec */ - aRetFont.fromString( aValue ); - } else if (sl.count() == 6) { - /* backward compatible kde2 font spec */ - aRetFont = TQFont( sl[0], sl[1].toInt(), sl[4].toUInt() ); - - aRetFont.setStyleHint( (TQFont::StyleHint)sl[2].toUInt() ); - - nFontBits = sl[5].toUInt(); - aRetFont.setItalic( (nFontBits & 0x01) != 0 ); - aRetFont.setUnderline( (nFontBits & 0x02) != 0 ); - aRetFont.setStrikeOut( (nFontBits & 0x04) != 0 ); - aRetFont.setFixedPitch( (nFontBits & 0x08) != 0 ); - aRetFont.setRawMode( (nFontBits & 0x20) != 0 ); - } - aRetFont.setStyleStrategy( (TQFont::StyleStrategy) - (TQFont::PreferMatch | - (_antiAliasing ? TQFont::PreferAntialias : TQFont::NoAntialias)) ); - - return aRetFont; -} - -extern "C" -void init_config( void ) -{ - CONF_GREET_INIT - - _isLocal = GetCfgInt( C_isLocal ); - _hasConsole = _hasConsole && _isLocal && GetCfgInt( C_hasConsole ); - _authorized = GetCfgInt( C_isAuthorized ); - - _stsFile = _dataDir + "/tdmsts"; - - // Greet String - char hostname[256], *ptr; - hostname[0] = '\0'; - if (!gethostname( hostname, sizeof(hostname) )) - hostname[sizeof(hostname)-1] = '\0'; - struct utsname tuname; - uname( &tuname ); - TQString gst = _greetString; - _greetString = TQString::null; - int i, j, l = gst.length(); - for (i = 0; i < l; i++) { - if (gst[i] == '%') { - switch (gst[++i].cell()) { - case '%': _greetString += gst[i]; continue; - case 'd': ptr = dname; break; - case 'h': ptr = hostname; break; - case 'n': ptr = tuname.nodename; - for (j = 0; ptr[j]; j++) - if (ptr[j] == '.') { - ptr[j] = 0; - break; - } - break; - case 's': ptr = tuname.sysname; break; - case 'r': ptr = tuname.release; break; - case 'm': ptr = tuname.machine; break; - default: _greetString += i18n("[fix tdmrc!]"); continue; - } - _greetString += TQString::fromLocal8Bit( ptr ); - } else - _greetString += gst[i]; - } -} - - -/* out-of-place utility function */ -void -decodeSess( dpySpec *sess, TQString &user, TQString &loc ) -{ - if (sess->flags & isTTY) { - user = - i18n( "%1: TTY login", "%1: %n TTY logins", sess->count ) - .arg( sess->user ); - loc = -#ifdef HAVE_VTS - sess->vt ? - TQString("vt%1").arg( sess->vt ) : -#endif - TQString::fromLatin1( *sess->from ? sess->from : sess->display ); - } else { - user = - !sess->user ? - i18n("Unused") : - *sess->user ? - i18n("user: session type", "%1: %2") - .arg( sess->user ).arg( sess->session ) : - i18n("... host", "X login on %1").arg( sess->session ); - loc = -#ifdef HAVE_VTS - sess->vt ? - TQString("%1, vt%2").arg( sess->display ).arg( sess->vt ) : -#endif - TQString::fromLatin1( sess->display ); - } -} diff --git a/kdm/kfrontend/kdmconfig.h b/kdm/kfrontend/kdmconfig.h deleted file mode 100644 index 275cafa1b..000000000 --- a/kdm/kfrontend/kdmconfig.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - -Configuration for tdm - -Copyright (C) 1997, 1998, 2000 Steffen Hansen -Copyright (C) 2000-2003 Oswald Buddenhagen - - -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. - -*/ - - -#ifndef TDMCONFIG_H -#define TDMCONFIG_H - -#include - -#include "config.ci" - -#ifdef __cplusplus - -#include -#include -#include -#include - -extern TQString _stsFile; -extern bool _isLocal; -extern bool _authorized; - -CONF_GREET_CPP_DECLS - -// this file happens to be included everywhere, so just put it here -struct dpySpec; -void decodeSess( dpySpec *sess, TQString &user, TQString &loc ); - -extern struct timeval st; - -inline TQString timestamp() { - struct timeval nst; - gettimeofday(&nst, 0); - if (!st.tv_sec) - gettimeofday(&st, 0); - - TQString ret; - ret.sprintf("[%07ld]", (nst.tv_sec - st.tv_sec) * 1000 + (nst.tv_usec - st.tv_usec) / 1000); - return ret; -} - -extern "C" -#endif -void init_config( void ); - -CONF_GREET_C_DECLS - -#endif /* TDMCONFIG_H */ diff --git a/kdm/kfrontend/kdmctl.c b/kdm/kfrontend/kdmctl.c deleted file mode 100644 index d6abe959a..000000000 --- a/kdm/kfrontend/kdmctl.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - -TDM remote control application - -Copyright (C) 2004 Oswald Buddenhagen - -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 - -#include -#include -#include -#include -#include -#include -#include - -static int -openctl( int fd, int err, const char *ctl, const char *dpy ) -{ - struct sockaddr_un sa; - - sa.sun_family = AF_UNIX; - if (dpy) - snprintf( sa.sun_path, sizeof(sa.sun_path), - "%s/dmctl-%s/socket", ctl, dpy ); - else - snprintf( sa.sun_path, sizeof(sa.sun_path), - "%s/dmctl/socket", ctl ); - if (!connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) - return 1; - if (err) - fprintf( stderr, "Cannot connect socket '%s'.\n", sa.sun_path ); - return 0; -} - -static const char * -readcfg( const char *cfg ) -{ - FILE *fp; - const char *ctl; - char *ptr, *ptr2; - char buf[1024]; - - if (!(fp = fopen( cfg, "r" ))) { - fprintf( stderr, - "Cannot open tdm config file '%s'.\n", - cfg ); - return 0; - } - ctl = "/var/run/xdmctl"; - while (fgets( buf, sizeof(buf), fp )) - if (!strncmp( buf, "FifoDir", 7 )) { - ptr = buf + 7; - while (*ptr && isspace( *ptr )) - ptr++; - if (*ptr++ != '=') - continue; - while (*ptr && isspace( *ptr )) - ptr++; - for (ptr2 = buf + strlen( buf ); - ptr2 > ptr && isspace( *(ptr2 - 1) ); - ptr2--); - *ptr2 = 0; - ctl = strdup( ptr ); - break; - } - fclose( fp ); - return ctl; -} - -static int -exe( int fd, const char *in, int len ) -{ - char buf[4096]; - - if (write( fd, in, len ) != len) { - fprintf( stderr, "Cannot send command\n" ); - return 1; - } - do { - if ((len = read(fd, buf, sizeof(buf))) <= 0) { - fprintf(stderr, "Cannot receive reply\n"); - return 1; - } - fwrite(buf, 1, len, stdout); - } while (buf[len - 1] != '\n'); - return 0; -} - -static int -run( int fd, char **argv ) -{ - unsigned len, l; - char buf[1024]; - - if (!*argv) - return exe( fd, "caps\n", 5 ); - if (!strcmp( *argv, "-" )) { - for (;;) { - if (isatty( 0 )) { - fputs( "> ", stdout ); - fflush( stdout ); - } - if (!fgets( buf, sizeof(buf), stdin )) - return 0; - if (exe( fd, buf, strlen( buf ) )) - return 1; - } - } else { - len = strlen( *argv ); - if (len >= sizeof(buf)) - goto bad; - memcpy( buf, *argv, len ); - while (*++argv) { - l = strlen( *argv ); - if (len + l + 1 >= sizeof(buf)) - goto bad; - buf[len++] = '\t'; - memcpy( buf + len, *argv, l ); - len += l; - } - buf[len++] = '\n'; - return exe( fd, buf, len ); - bad: - fprintf( stderr, "Command too long\n" ); - return 1; - } -} - -int -main( int argc, char **argv ) -{ - char *dpy = getenv( "DISPLAY" ); - const char *ctl = getenv( "DM_CONTROL" ); - const char *cfg = KDE_CONFDIR "/tdm/tdmrc"; - char *ptr; - int fd; - - (void)argc; - while (*++argv) { - ptr = *argv; - if (*ptr != '-' || !*(ptr + 1)) - break; - ptr++; - if (*ptr == '-') - ptr++; - if (!strcmp( ptr, "h" ) || !strcmp( ptr, "help" )) { - puts( -"Usage: tdmctl [options] [command [command arguments]]\n" -"\n" -"Options are:\n" -" -h -help This help message.\n" -" -g -global Use global control socket even if $DISPLAY is set\n" -" -d -display Override $DISPLAY\n" -" -s -sockets Override $DM_CONTROL\n" -" -c -config Use alternative tdm config file\n" -"\n" -"The directory in which the sockets are located is determined this way:\n" -"- the -s option is examined\n" -"- the $DM_CONTROL variable is examined\n" -"- the tdm config file is searched for the FifoDir key\n" -"- /var/run/xdmctl and /var/run are tried\n" -"\n" -"If $DISPLAY is set (or -d was specified) and -g was not specified, the\n" -"display-specific control socket will be used, otherwise the global one.\n" -"\n" -"Tokens in the command and the reply are tab-separated.\n" -"Command arguments can be specified as separate command line parameters,\n" -"in which case they are simply concatenated with tabs in between.\n" -"\n" -"If the command is '-', tdmctl reads commands from stdin.\n" -"The default command is 'caps'.\n" - ); - return 0; - } else if (!strcmp( ptr, "g" ) || !strcmp( ptr, "global" )) - dpy = 0; - else if (!strcmp( ptr, "d" ) || !strcmp( ptr, "display" )) { - if (!argv[1]) - goto needarg; - dpy = *++argv; - } else if (!strcmp( ptr, "s" ) || !strcmp( ptr, "sockets" )) { - if (!argv[1]) - goto needarg; - ctl = *++argv; - } else if (!strcmp( ptr, "c" ) || !strcmp( ptr, "config" )) { - if (!argv[1]) { - needarg: - fprintf( stderr, "Option '%s' needs argument.\n", - ptr ); - return 1; - } - cfg = *++argv; - } else { - fprintf( stderr, "Unknown option '%s'.\n", ptr ); - return 1; - } - } - if ((!ctl || !*ctl) && *cfg) - ctl = readcfg( cfg ); - if ((fd = socket( PF_UNIX, SOCK_STREAM, 0 )) < 0) { - fprintf( stderr, "Cannot create UNIX socket\n" ); - return 1; - } - if (dpy && (ptr = strchr( dpy, ':' )) && (ptr = strchr( ptr, '.' ))) - *ptr = 0; - if (ctl && *ctl) { - if (!openctl( fd, 1, ctl, dpy )) - return 1; - } else { - if (!openctl( fd, 0, "/var/run/xdmctl", dpy ) && - !openctl( fd, 0, "/var/run", dpy )) - { - fprintf( stderr, "No command socket found.\n" ); - return 1; - } - } - return run( fd, argv ); -} diff --git a/kdm/kfrontend/kdmshutdown.cpp b/kdm/kfrontend/kdmshutdown.cpp deleted file mode 100644 index e546f62b6..000000000 --- a/kdm/kfrontend/kdmshutdown.cpp +++ /dev/null @@ -1,925 +0,0 @@ -/* - -Shutdown dialog - -Copyright (C) 1997, 1998, 2000 Steffen Hansen -Copyright (C) 2000-2003,2005 Oswald Buddenhagen - - -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 "tdmshutdown.h" -#include "tdm_greet.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define KDmh KDialog::marginHint() -#define KDsh KDialog::spacingHint() - -#include - -extern bool has_twin; - -int TDMShutdownBase::curPlugin = -1; -PluginList TDMShutdownBase::pluginList; - -TDMShutdownBase::TDMShutdownBase( int _uid, TQWidget *_parent ) - : inherited( _parent ) - , box( new TQVBoxLayout( this, KDmh, KDsh ) ) -#ifdef HAVE_VTS - , willShut( true ) -#endif - , mayNuke( false ) - , doesNuke( false ) - , mayOk( true ) - , maySched( false ) - , rootlab( 0 ) - , verify( 0 ) - , needRoot( -1 ) - , uid( _uid ) -{ -} - -TDMShutdownBase::~TDMShutdownBase() -{ - hide(); - delete verify; -} - -void -TDMShutdownBase::complete( TQWidget *prevWidget ) -{ - TQSizePolicy fp( TQSizePolicy::Fixed, TQSizePolicy::Fixed ); - - if (uid && - ((willShut && _allowShutdown == SHUT_ROOT) || - (mayNuke && _allowNuke == SHUT_ROOT))) - { - rootlab = new TQLabel( i18n("Root authorization required."), this ); - box->addWidget( rootlab ); - if (curPlugin < 0) { - curPlugin = 0; - pluginList = KGVerify::init( _pluginsShutdown ); - } - verify = new KGStdVerify( this, this, - prevWidget, "root", - pluginList, KGreeterPlugin::Authenticate, - KGreeterPlugin::Shutdown ); - verify->selectPlugin( curPlugin ); - box->addLayout( verify->getLayout() ); - TQAccel *accel = new TQAccel( this ); - accel->insertItem( ALT+Key_A, 0 ); - connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotActivatePlugMenu()) ); - } - - box->addWidget( new KSeparator( KSeparator::HLine, this ) ); - - TQBoxLayout *hlay = new TQHBoxLayout( box, KDsh ); - hlay->addStretch( 1 ); - if (mayOk) { - okButton = new KPushButton( KStdGuiItem::ok(), this ); - okButton->setSizePolicy( fp ); - okButton->setDefault( true ); - hlay->addWidget( okButton ); - hlay->addStretch( 1 ); - connect( okButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); - } - if (maySched) { - KPushButton *schedButton = - new KPushButton( KGuiItem( i18n("&Schedule...") ), this ); - schedButton->setSizePolicy( fp ); - hlay->addWidget( schedButton ); - hlay->addStretch( 1 ); - connect( schedButton, TQT_SIGNAL(clicked()), TQT_SLOT(slotSched()) ); - } - cancelButton = new KPushButton( KStdGuiItem::cancel(), this ); - cancelButton->setSizePolicy( fp ); - if (!mayOk) - cancelButton->setDefault( true ); - hlay->addWidget( cancelButton ); - hlay->addStretch( 1 ); - connect( cancelButton, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) ); - - updateNeedRoot(); -} - -void -TDMShutdownBase::slotActivatePlugMenu() -{ - if (needRoot) { - TQPopupMenu *cmnu = verify->getPlugMenu(); - if (!cmnu) - return; - TQSize sh( cmnu->sizeHint() / 2 ); - cmnu->exec( geometry().center() - TQPoint( sh.width(), sh.height() ) ); - } -} - -void -TDMShutdownBase::accept() -{ - if (needRoot == 1) - verify->accept(); - else - accepted(); -} - -void -TDMShutdownBase::slotSched() -{ - done( Schedule ); -} - -void -TDMShutdownBase::updateNeedRoot() -{ - int nNeedRoot = uid && - (((willShut && _allowShutdown == SHUT_ROOT) || - (_allowNuke == SHUT_ROOT && doesNuke))); - if (verify && nNeedRoot != needRoot) { - if (needRoot == 1) - verify->abort(); - needRoot = nNeedRoot; - rootlab->setEnabled( needRoot ); - verify->setEnabled( needRoot ); - if (needRoot) - verify->start(); - } -} - -void -TDMShutdownBase::accepted() -{ - inherited::done( needRoot ? (int)Authed : (int)Accepted ); -} - -void -TDMShutdownBase::verifyPluginChanged( int id ) -{ - curPlugin = id; - adjustSize(); -} - -void -TDMShutdownBase::verifyOk() -{ - accepted(); -} - -void -TDMShutdownBase::verifyFailed() -{ - okButton->setEnabled( false ); - cancelButton->setEnabled( false ); -} - -void -TDMShutdownBase::verifyRetry() -{ - okButton->setEnabled( true ); - cancelButton->setEnabled( true ); -} - -void -TDMShutdownBase::verifySetUser( const TQString & ) -{ -} - - -static void -doShutdown( int type, const char *os ) -{ - GSet( 1 ); - GSendInt( G_Shutdown ); - GSendInt( type ); - GSendInt( 0 ); - GSendInt( 0 ); - GSendInt( SHUT_FORCE ); - GSendInt( 0 ); /* irrelevant, will timeout immediately anyway */ - GSendStr( os ); - GSet( 0 ); -} - - - -TDMShutdown::TDMShutdown( int _uid, TQWidget *_parent ) - : inherited( _uid, _parent ) -{ - setCaption(i18n("Shutdown TDE")); - - TQSizePolicy fp( TQSizePolicy::Fixed, TQSizePolicy::Fixed ); - - TQHBoxLayout *hlay = new TQHBoxLayout( box, KDsh ); - - howGroup = new TQVButtonGroup( i18n("Shutdown Type"), this ); - hlay->addWidget( howGroup, 0, AlignTop ); - - TQRadioButton *rb; - rb = new TDMRadioButton( i18n("&Turn off computer"), howGroup ); - rb->setChecked( true ); - rb->setFocus(); - - restart_rb = new TDMRadioButton( i18n("&Restart computer"), howGroup ); - - connect( rb, TQT_SIGNAL(doubleClicked()), TQT_SLOT(accept()) ); - connect( restart_rb, TQT_SIGNAL(doubleClicked()), TQT_SLOT(accept()) ); - - GSet( 1 ); - GSendInt( G_ListBootOpts ); - if (GRecvInt() == BO_OK) { /* XXX show dialog on failure */ - char **tlist = GRecvStrArr( 0 ); - int defaultTarget = GRecvInt(); - oldTarget = GRecvInt(); - TQWidget *hlp = new TQWidget( howGroup ); - targets = new TQComboBox( hlp ); - for (int i = 0; tlist[i]; i++) - targets->insertItem( TQString(TQString::fromLocal8Bit( tlist[i] )) ); - freeStrArr( tlist ); - targets->setCurrentItem( oldTarget == -1 ? defaultTarget : oldTarget ); - TQHBoxLayout *hb = new TQHBoxLayout( hlp, 0, KDsh ); - int spc = kapp->style().pixelMetric( TQStyle::PM_ExclusiveIndicatorWidth ) - + howGroup->insideSpacing(); - hb->addSpacing( spc ); - hb->addWidget( targets ); - connect( targets, TQT_SIGNAL(activated( int )), TQT_SLOT(slotTargetChanged()) ); - } - GSet( 0 ); - - howGroup->setSizePolicy( fp ); - - schedGroup = new TQGroupBox( i18n("Scheduling"), this ); - hlay->addWidget( schedGroup, 0, AlignTop ); - - le_start = new TQLineEdit( schedGroup ); - TQLabel *lab1 = new TQLabel( le_start, i18n("&Start:"), schedGroup ); - - le_timeout = new TQLineEdit( schedGroup ); - TQLabel *lab2 = new TQLabel( le_timeout, i18n("T&imeout:"), schedGroup ); - - cb_force = new TQCheckBox( i18n("&Force after timeout"), schedGroup ); - if (_allowNuke != SHUT_NONE) { - connect( cb_force, TQT_SIGNAL(clicked()), TQT_SLOT(slotWhenChanged()) ); - mayNuke = true; - } else - cb_force->setEnabled( false ); - - TQGridLayout *grid = new TQGridLayout( schedGroup, 0, 0, KDmh, KDsh ); - grid->addRowSpacing( 0, schedGroup->fontMetrics().height() - 5 ); - grid->addWidget( lab1, 1, 0, Qt::AlignRight ); - grid->addWidget( le_start, 1, 1 ); - grid->addWidget( lab2, 2, 0, Qt::AlignRight ); - grid->addWidget( le_timeout, 2, 1 ); - grid->addMultiCellWidget( cb_force, 3,3, 0,1 ); - - schedGroup->setSizePolicy( fp ); - - le_start->setText( "0" ); - if (_defSdMode == SHUT_SCHEDULE) - le_timeout->setText( "-1" ); - else { - le_timeout->setText( "0" ); - if (_defSdMode == SHUT_FORCENOW && cb_force->isEnabled()) - cb_force->setChecked( true ); - } - - complete( schedGroup ); -} - -static int -get_date( const char *str ) -{ - KProcIO prc; - prc << "/bin/date" << "+%s" << "-d" << str; - prc.start( KProcess::Block, false ); - TQString dstr; - if (prc.readln( dstr, false, 0 ) < 0) - return -1; - return dstr.toInt(); -} - -void -TDMShutdown::accept() -{ - if (le_start->text() == "0" || le_start->text() == "now") - sch_st = time( 0 ); - else if (le_start->text()[0] == '+') - sch_st = time( 0 ) + le_start->text().toInt(); - else if ((sch_st = get_date( le_start->text().latin1() )) < 0) { - MsgBox( errorbox, i18n("Entered start date is invalid.") ); - le_start->setFocus(); - return; - } - if (le_timeout->text() == "-1" || le_timeout->text().startsWith( "inf" )) - sch_to = TO_INF; - else if (le_timeout->text()[0] == '+') - sch_to = sch_st + le_timeout->text().toInt(); - else if ((sch_to = get_date( le_timeout->text().latin1() )) < 0) { - MsgBox( errorbox, i18n("Entered timeout date is invalid.") ); - le_timeout->setFocus(); - return; - } - - inherited::accept(); -} - -void -TDMShutdown::slotTargetChanged() -{ - restart_rb->setChecked( true ); -} - -void -TDMShutdown::slotWhenChanged() -{ - doesNuke = cb_force->isChecked(); - updateNeedRoot(); -} - -void -TDMShutdown::accepted() -{ - GSet( 1 ); - GSendInt( G_Shutdown ); - GSendInt( restart_rb->isChecked() ? SHUT_REBOOT : SHUT_HALT ); - GSendInt( sch_st ); - GSendInt( sch_to ); - GSendInt( cb_force->isChecked() ? SHUT_FORCE : SHUT_CANCEL ); - GSendInt( _allowShutdown == SHUT_ROOT ? 0 : -2 ); - GSendStr( (restart_rb->isChecked() && - targets && targets->currentItem() != oldTarget) ? - targets->currentText().local8Bit().data() : 0 ); - GSet( 0 ); - inherited::accepted(); -} - -void -TDMShutdown::scheduleShutdown( TQWidget *_parent ) -{ - GSet( 1 ); - GSendInt( G_QueryShutdown ); - int how = GRecvInt(); - int start = GRecvInt(); - int timeout = GRecvInt(); - int force = GRecvInt(); - int uid = GRecvInt(); - char *os = GRecvStr(); - GSet( 0 ); - if (how) { - int ret = - TDMCancelShutdown( how, start, timeout, force, uid, os, - _parent ).exec(); - if (!ret) - return; - doShutdown( 0, 0 ); - uid = ret == Authed ? 0 : -1; - } else - uid = -1; - if (os) - free( os ); - TDMShutdown( uid, _parent ).exec(); -} - - -TDMRadioButton::TDMRadioButton( const TQString &label, TQWidget *parent ) - : inherited( label, parent ) -{ -} - -void -TDMRadioButton::mouseDoubleClickEvent( TQMouseEvent * ) -{ - emit doubleClicked(); -} - - -TDMDelayedPushButton::TDMDelayedPushButton( const KGuiItem &item, - TQWidget *parent, - const char *name ) - : inherited( item, parent, name ) - , pop( 0 ) -{ - connect( this, TQT_SIGNAL(pressed()), TQT_SLOT(slotPressed()) ); - connect( this, TQT_SIGNAL(released()), TQT_SLOT(slotReleased()) ); - connect( &popt, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeout()) ); -} - -void TDMDelayedPushButton::setPopup( TQPopupMenu *p ) -{ - pop = p; - setIsMenuButton( p != 0 ); -} - -void TDMDelayedPushButton::slotPressed() -{ - if (pop) - popt.start( TQApplication::startDragTime() ); -} - -void TDMDelayedPushButton::slotReleased() -{ - popt.stop(); -} - -void TDMDelayedPushButton::slotTimeout() -{ - popt.stop(); - pop->popup( mapToGlobal( rect().bottomLeft() ) ); - setDown( false ); -} - -TDMSlimShutdown::TDMSlimShutdown( TQWidget *_parent ) - : inherited( _parent ) - , targetList( 0 ) -{ - setCaption(i18n("Shutdown TDE")); - - bool doUbuntuLogout = KConfigGroup(KGlobal::config(), "Shutdown").readBoolEntry("doUbuntuLogout", false); - - TQFrame* lfrm = new TQFrame( this ); - TQHBoxLayout* hbuttonbox; - - if(doUbuntuLogout) - { - TQVBoxLayout* vbox = new TQVBoxLayout( this ); - if (has_twin) - lfrm->setFrameStyle( TQFrame::NoFrame ); - else - lfrm->setFrameStyle( TQFrame::StyledPanel | TQFrame::Raised ); - lfrm->setLineWidth( style().pixelMetric( TQStyle::PM_DefaultFrameWidth, lfrm ) ); - // we need to set the minimum size for the logout box, since it - // gets too small if there all options are not available - lfrm->setMinimumSize(300,120); - vbox->addWidget( lfrm ); - vbox = new TQVBoxLayout( lfrm, 2 * KDialog::marginHint(), - 2 * KDialog::spacingHint() ); - - // first line of buttons - hbuttonbox = new TQHBoxLayout( vbox, 8 * KDialog::spacingHint() ); - hbuttonbox->setAlignment( Qt::AlignHCenter ); - - // Reboot - FlatButton* btnReboot = new FlatButton( lfrm ); - btnReboot->setTextLabel( i18n("&Restart"), false ); - btnReboot->setPixmap( DesktopIcon( "reload") ); - int i = btnReboot->textLabel().find( TQRegExp("\\&"), 0 ); // i == 1 - btnReboot->setAccel( "ALT+" + btnReboot->textLabel().lower()[i+1] ) ; - hbuttonbox->addWidget ( btnReboot); - connect(btnReboot, TQT_SIGNAL(clicked()), TQT_SLOT(slotReboot())); - - // Copied completely from the standard restart/shutdown dialog - GSet( 1 ); - GSendInt( G_ListBootOpts ); - if (GRecvInt() == BO_OK) { - targetList = GRecvStrArr( 0 ); - /*int def =*/ GRecvInt(); - int cur = GRecvInt(); - TQPopupMenu *targets = new TQPopupMenu( this ); - btnReboot->setPopupDelay(300); // visually add dropdown - for (int i = 0; targetList[i]; i++) { - TQString t( TQString::fromLocal8Bit( targetList[i] ) ); - targets->insertItem( i == cur ? - i18n("current option in boot loader", - "%1 (current)").arg( t ) : - t, i ); - } - btnReboot->setPopup( targets ); - connect( targets, TQT_SIGNAL(activated(int)), TQT_SLOT(slotReboot(int)) ); - } - GSet( 0 ); - // Copied completely from the standard restart/shutdown dialog - - // Shutdown - FlatButton* btnHalt = new FlatButton( lfrm ); - btnHalt->setTextLabel( i18n("&Turn Off"), false ); - btnHalt->setPixmap( DesktopIcon( "exit") ); - i = btnHalt->textLabel().find( TQRegExp("\\&"), 0 ); // i == 1 - btnHalt->setAccel( "ALT+" + btnHalt->textLabel().lower()[i+1] ) ; - hbuttonbox->addWidget ( btnHalt ); - connect(btnHalt, TQT_SIGNAL(clicked()), TQT_SLOT(slotHalt())); - - // cancel buttonbox - TQHBoxLayout* hbuttonbox2 = new TQHBoxLayout( vbox, 8 * KDialog::spacingHint() ); - hbuttonbox2->setAlignment( Qt::AlignRight ); - - // Back to tdm - KSMPushButton* btnBack = new KSMPushButton( KStdGuiItem::cancel(), lfrm ); - hbuttonbox2->addWidget( btnBack ); - connect(btnBack, TQT_SIGNAL(clicked()), TQT_SLOT(reject())); - } - else - { - TQHBoxLayout *hbox = new TQHBoxLayout( this, KDmh, KDsh ); - if (has_twin) - lfrm->setFrameStyle( TQFrame::NoFrame ); - else - lfrm->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); - hbox->addWidget( lfrm, AlignCenter ); - // we need to set the minimum size for the logout box, since it - // gets too small if there all options are not available - TQLabel *icon = new TQLabel( lfrm ); - icon->setPixmap( TQPixmap( locate( "data", "tdm/pics/shutdown.jpg" ) ) ); - TQVBoxLayout *iconlay = new TQVBoxLayout( lfrm ); - iconlay->addWidget( icon ); - - TQVBoxLayout *buttonlay = new TQVBoxLayout( hbox, KDsh ); - - buttonlay->addStretch( 1 ); - - KPushButton *btnHalt = new - KPushButton( KGuiItem( i18n("&Turn Off Computer"), "exit" ), this ); - buttonlay->addWidget( btnHalt ); - connect( btnHalt, TQT_SIGNAL(clicked()), TQT_SLOT(slotHalt()) ); - - buttonlay->addSpacing( KDialog::spacingHint() ); - - TDMDelayedPushButton *btnReboot = new - TDMDelayedPushButton( KGuiItem( i18n("&Restart Computer"), "reload" ), this ); - buttonlay->addWidget( btnReboot ); - connect( btnReboot, TQT_SIGNAL(clicked()), TQT_SLOT(slotReboot()) ); - - GSet( 1 ); - GSendInt( G_ListBootOpts ); - if (GRecvInt() == BO_OK) { - targetList = GRecvStrArr( 0 ); - /*int def =*/ GRecvInt(); - int cur = GRecvInt(); - TQPopupMenu *targets = new TQPopupMenu( this ); - for (int i = 0; targetList[i]; i++) { - TQString t( TQString::fromLocal8Bit( targetList[i] ) ); - targets->insertItem( i == cur ? - i18n("current option in boot loader", - "%1 (current)").arg( t ) : - t, i ); - } - btnReboot->setPopup( targets ); - connect( targets, TQT_SIGNAL(activated(int)), TQT_SLOT(slotReboot(int)) ); - } - GSet( 0 ); - - buttonlay->addStretch( 1 ); - - if (_scheduledSd != SHUT_NEVER) { - KPushButton *btnSched = new - KPushButton( KGuiItem( i18n("&Schedule...") ), this ); - buttonlay->addWidget( btnSched ); - connect( btnSched, TQT_SIGNAL(clicked()), TQT_SLOT(slotSched()) ); - - buttonlay->addStretch( 1 ); - } - - buttonlay->addWidget( new KSeparator( this ) ); - - buttonlay->addSpacing( 0 ); - - KPushButton *btnBack = new KPushButton( KStdGuiItem::cancel(), this ); - buttonlay->addWidget( btnBack ); - connect( btnBack, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) ); - - buttonlay->addSpacing( KDialog::spacingHint() ); - } - -} - -TDMSlimShutdown::~TDMSlimShutdown() -{ - freeStrArr( targetList ); -} - -void -TDMSlimShutdown::slotSched() -{ - reject(); - TDMShutdown::scheduleShutdown(); -} - -void -TDMSlimShutdown::slotHalt() -{ - if (checkShutdown( SHUT_HALT, 0 )) - doShutdown( SHUT_HALT, 0 ); -} - -void -TDMSlimShutdown::slotReboot() -{ - if (checkShutdown( SHUT_REBOOT, 0 )) - doShutdown( SHUT_REBOOT, 0 ); -} - -void -TDMSlimShutdown::slotReboot( int opt ) -{ - if (checkShutdown( SHUT_REBOOT, targetList[opt] )) - doShutdown( SHUT_REBOOT, targetList[opt] ); -} - -bool -TDMSlimShutdown::checkShutdown( int type, const char *os ) -{ - reject(); - dpySpec *sess = fetchSessions( lstRemote | lstTTY ); - if (!sess && _allowShutdown != SHUT_ROOT) - return true; - int ret = TDMConfShutdown( -1, sess, type, os ).exec(); - disposeSessions( sess ); - if (ret == Schedule) { - TDMShutdown::scheduleShutdown(); - return false; - } - return ret; -} - -void -TDMSlimShutdown::externShutdown( int type, const char *os, int uid ) -{ - dpySpec *sess = fetchSessions( lstRemote | lstTTY ); - int ret = TDMConfShutdown( uid, sess, type, os ).exec(); - disposeSessions( sess ); - if (ret == Schedule) - TDMShutdown( uid ).exec(); - else if (ret) - doShutdown( type, os ); -} - - -KSMPushButton::KSMPushButton( const KGuiItem &item, - TQWidget *parent, - const char *name) - : KPushButton( item, parent, name), - m_pressed(false) -{ - setDefault( false ); - setAutoDefault ( false ); -} - -void KSMPushButton::keyPressEvent( TQKeyEvent* e ) -{ - switch ( e->key() ) - { - case Key_Enter: - case Key_Return: - case Key_Space: - m_pressed = TRUE; - setDown(true); - emit pressed(); - break; - case Key_Escape: - e->ignore(); - break; - default: - e->ignore(); - } - - TQPushButton::keyPressEvent(e); -} - - -void KSMPushButton::keyReleaseEvent( TQKeyEvent* e ) -{ - switch ( e->key() ) - { - case Key_Space: - case Key_Enter: - case Key_Return: - if ( m_pressed ) - { - setDown(false); - m_pressed = FALSE; - emit released(); - emit clicked(); - } - break; - case Key_Escape: - e->ignore(); - break; - default: - e->ignore(); - - } -} - -FlatButton::FlatButton( TQWidget *parent, const char *name ) - : TQToolButton( parent, name/*, TQt::WNoAutoErase*/ ), - m_pressed(false) -{ - init(); -} - - -FlatButton::~FlatButton() {} - -void FlatButton::init() -{ - setUsesTextLabel(true); - setUsesBigPixmap(true); - setAutoRaise(true); - setTextPosition( TQToolButton::Under ); - setFocusPolicy(TQ_StrongFocus); - } - - -void FlatButton::keyPressEvent( TQKeyEvent* e ) -{ - switch ( e->key() ) - { - case Key_Enter: - case Key_Return: - case Key_Space: - m_pressed = TRUE; - setDown(true); - emit pressed(); - break; - case Key_Escape: - e->ignore(); - break; - default: - e->ignore(); - } - - TQToolButton::keyPressEvent(e); -} - -void FlatButton::keyReleaseEvent( TQKeyEvent* e ) -{ - switch ( e->key() ) - { - case Key_Space: - case Key_Enter: - case Key_Return: - if ( m_pressed ) - { - setDown(false); - m_pressed = FALSE; - emit released(); - emit clicked(); - } - break; - case Key_Escape: - e->ignore(); - break; - default: - e->ignore(); - } - -} - - - -TDMConfShutdown::TDMConfShutdown( int _uid, dpySpec *sess, int type, const char *os, - TQWidget *_parent ) - : inherited( _uid, _parent ) -{ -#ifdef HAVE_VTS - if (type == SHUT_CONSOLE) - willShut = false; -#endif - box->addWidget( new TQLabel( TQString( "
" - "%1%2" - "

" ) - .arg( (type == SHUT_HALT) ? - i18n("Turn Off Computer") : -#ifdef HAVE_VTS - (type == SHUT_CONSOLE) ? - i18n("Switch to Console") : -#endif - i18n("Restart Computer") ) - .arg( os ? - i18n("
(Next boot: %1)") - .arg( TQString::fromLocal8Bit( os ) ) : - TQString() ), - this ) ); - - if (sess) { - if (willShut && _scheduledSd != SHUT_NEVER) - maySched = true; - mayNuke = doesNuke = true; - if (_allowNuke == SHUT_NONE) - mayOk = false; - TQLabel *lab = new TQLabel( mayOk ? - i18n("Abort active sessions:") : - i18n("No permission to abort active sessions:"), - this ); - box->addWidget( lab ); - TQListView *lv = new TQListView( this ); - lv->setSelectionMode( TQListView::NoSelection ); - lv->setAllColumnsShowFocus( true ); - lv->header()->setResizeEnabled( false ); - lv->addColumn( i18n("Session") ); - lv->addColumn( i18n("Location") ); - TQListViewItem *itm; - int ns = 0; - TQString user, loc; - do { - decodeSess( sess, user, loc ); - itm = new TQListViewItem( lv, user, loc ); - sess = sess->next, ns++; - } while (sess); - int fw = lv->frameWidth() * 2; - lv->setFixedHeight( fw + lv->header()->height() + - itm->height() * (ns < 3 ? 3 : ns > 10 ? 10 : ns) ); - box->addWidget( lv ); - complete( lv ); - } else - complete( 0 ); -} - - -TDMCancelShutdown::TDMCancelShutdown( int how, int start, int timeout, - int force, int uid, const char *os, - TQWidget *_parent ) - : inherited( -1, _parent ) -{ - if (force == SHUT_FORCE) { - if (_allowNuke == SHUT_NONE) - mayOk = false; - else if (_allowNuke == SHUT_ROOT) - mayNuke = doesNuke = true; - } - TQLabel *lab = new TQLabel( mayOk ? - i18n("Abort pending shutdown:") : - i18n("No permission to abort pending shutdown:"), - this ); - box->addWidget( lab ); - TQDateTime qdt; - TQString strt, end; - if (start < time( 0 )) - strt = i18n("now"); - else { - qdt.setTime_t( start ); - strt = qdt.toString( Qt::LocalDate ); - } - if (timeout == TO_INF) - end = i18n("infinite"); - else { - qdt.setTime_t( timeout ); - end = qdt.toString( Qt::LocalDate ); - } - TQString trg = - i18n("Owner: %1" - "\nType: %2%5" - "\nStart: %3" - "\nTimeout: %4") - .arg( uid == -2 ? - i18n("console user") : - uid == -1 ? - i18n("control socket") : - KUser( uid ).loginName() ) - .arg( how == SHUT_HALT ? - i18n("turn off computer") : - i18n("restart computer") ) - .arg( strt ).arg( end ) - .arg( os ? - i18n("\nNext boot: %1").arg( TQString::fromLocal8Bit( os ) ) : - TQString() ); - if (timeout != TO_INF) - trg += i18n("\nAfter timeout: %1") - .arg( force == SHUT_FORCE ? - i18n("abort all sessions") : - force == SHUT_FORCEMY ? - i18n("abort own sessions") : - i18n("cancel shutdown") ); - lab = new TQLabel( trg, this ); - box->addWidget( lab ); - complete( 0 ); -} - -#include "tdmshutdown.moc" diff --git a/kdm/kfrontend/kdmshutdown.h b/kdm/kfrontend/kdmshutdown.h deleted file mode 100644 index 6a2ee3a70..000000000 --- a/kdm/kfrontend/kdmshutdown.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - -Shutdown dialog - -Copyright (C) 1997, 1998 Steffen Hansen -Copyright (C) 2000-2003,2005 Oswald Buddenhagen - - -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. - -*/ - - -#ifndef TDMSHUTDOWN_H -#define TDMSHUTDOWN_H - -#include "tdmconfig.h" // for HAVE_VTS -#include "kgverify.h" - -#include - -#include -#include -#include - -class TQLabel; -class KPushButton; -class TQButtonGroup; -class TQGroupBox; -class TQComboBox; -class TQCheckBox; -class TQLineEdit; - -enum { Authed = TQDialog::Accepted + 1, Schedule }; - -class TDMShutdownBase : public FDialog, public KGVerifyHandler { - Q_OBJECT - typedef FDialog inherited; - - public: - TDMShutdownBase( int _uid, TQWidget *_parent ); - virtual ~TDMShutdownBase(); - - protected slots: - virtual void accept(); - - protected: - virtual void accepted(); - - protected: - void updateNeedRoot(); - void complete( TQWidget *prevWidget ); - - TQVBoxLayout *box; -#ifdef HAVE_VTS - bool willShut; -#else - static const bool willShut = true; -#endif - bool mayNuke, doesNuke, mayOk, maySched; - - private slots: - void slotSched(); - void slotActivatePlugMenu(); - - private: - KPushButton *okButton, *cancelButton; - TQLabel *rootlab; - KGStdVerify *verify; - int needRoot, uid; - - static int curPlugin; - static PluginList pluginList; - - public: // from KGVerifyHandler - virtual void verifyPluginChanged( int id ); - virtual void verifyOk(); - virtual void verifyFailed(); - virtual void verifyRetry(); - virtual void verifySetUser( const TQString &user ); -}; - - -class TDMShutdown : public TDMShutdownBase { - Q_OBJECT - typedef TDMShutdownBase inherited; - - public: - TDMShutdown( int _uid, TQWidget *_parent = 0 ); - static void scheduleShutdown( TQWidget *_parent = 0 ); - - protected slots: - virtual void accept(); - - protected: - virtual void accepted(); - - private slots: - void slotTargetChanged(); - void slotWhenChanged(); - - private: - TQButtonGroup *howGroup; - TQGroupBox *schedGroup; - TQRadioButton *restart_rb; - TQLineEdit *le_start, *le_timeout; - TQCheckBox *cb_force; - TQComboBox *targets; - int oldTarget; - int sch_st, sch_to; - -}; - -class TDMRadioButton : public TQRadioButton { - Q_OBJECT - typedef TQRadioButton inherited; - - public: - TDMRadioButton( const TQString &label, TQWidget *parent ); - - private: - virtual void mouseDoubleClickEvent( TQMouseEvent * ); - - signals: - void doubleClicked(); - -}; - -class TDMDelayedPushButton : public KPushButton { - Q_OBJECT - typedef KPushButton inherited; - - public: - TDMDelayedPushButton( const KGuiItem &item, TQWidget *parent, const char *name = 0 ); - void setPopup( TQPopupMenu *pop ); - - private slots: - void slotTimeout(); - void slotPressed(); - void slotReleased(); - - private: - TQPopupMenu *pop; - TQTimer popt; -}; - -class TDMSlimShutdown : public FDialog { - Q_OBJECT - typedef FDialog inherited; - - public: - TDMSlimShutdown( TQWidget *_parent = 0 ); - ~TDMSlimShutdown(); - static void externShutdown( int type, const char *os, int uid ); - - private slots: - void slotHalt(); - void slotReboot(); - void slotReboot( int ); - void slotSched(); - - private: - bool checkShutdown( int type, const char *os ); - char **targetList; - -}; - -class TDMConfShutdown : public TDMShutdownBase { - Q_OBJECT - typedef TDMShutdownBase inherited; - - public: - TDMConfShutdown( int _uid, struct dpySpec *sess, int type, const char *os, - TQWidget *_parent = 0 ); -}; - -class TDMCancelShutdown : public TDMShutdownBase { - Q_OBJECT - typedef TDMShutdownBase inherited; - - public: - TDMCancelShutdown( int how, int start, int timeout, int force, int uid, - const char *os, TQWidget *_parent ); -}; - -class KSMPushButton : public KPushButton -{ - Q_OBJECT - -public: - - KSMPushButton( const KGuiItem &item, TQWidget *parent, const char *name = 0 ); - -protected: - virtual void keyPressEvent(TQKeyEvent*e); - virtual void keyReleaseEvent(TQKeyEvent*e); - -private: - - bool m_pressed; - -}; - -class FlatButton : public TQToolButton -{ - Q_OBJECT - - public: - - FlatButton( TQWidget *parent = 0, const char *name = 0 ); - ~FlatButton(); - - protected: - virtual void keyPressEvent(TQKeyEvent*e); - virtual void keyReleaseEvent(TQKeyEvent*e); - - private slots: - - private: - void init(); - - bool m_pressed; - TQString m_text; - TQPixmap m_pixmap; - -}; - -#endif /* TDMSHUTDOWN_H */ diff --git a/kdm/kfrontend/kfdialog.cpp b/kdm/kfrontend/kfdialog.cpp deleted file mode 100644 index 98b5773c2..000000000 --- a/kdm/kfrontend/kfdialog.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - -Dialog class that handles input focus in absence of a wm - -Copyright (C) 1997, 1998 Steffen Hansen -Copyright (C) 2000-2003 Oswald Buddenhagen - - -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 "kfdialog.h" -#include "tdmconfig.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -extern bool has_twin; -extern bool is_themed; - -FDialog::FDialog( TQWidget *parent, bool framed ) - : inherited( parent, 0, true, (framed&&has_twin)?0:WX11BypassWM ), winFrame(NULL), m_wmTitle(has_twin) -{ - if (framed) { - // Signal that we do not want any window controls to be shown at all - Atom kde_wm_system_modal_notification; - kde_wm_system_modal_notification = XInternAtom(qt_xdisplay(), "_KDE_WM_MODAL_SYS_NOTIFICATION", False); - XChangeProperty(qt_xdisplay(), winId(), kde_wm_system_modal_notification, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L); - } - - if (framed) { - winFrame = new TQFrame( this, 0, TQt::WNoAutoErase ); - if (m_wmTitle) - winFrame->setFrameStyle( TQFrame::NoFrame ); - else - winFrame->setFrameStyle( TQFrame::WinPanel | TQFrame::Raised ); - winFrame->setLineWidth( 2 ); - } else - winFrame = 0; - - setCaption(TDM_LOGIN_SCREEN_BASE_TITLE); - - if (framed) { - if (m_wmTitle) setFixedSize(sizeHint()); - } -} - -void -FDialog::resizeEvent( TQResizeEvent *e ) -{ - inherited::resizeEvent( e ); - if (winFrame) { - winFrame->resize( size() ); - winFrame->erase(); - if (m_wmTitle) setFixedSize(sizeHint()); - } -} - -void -FDialog::adjustGeometry() -{ - TQDesktopWidget *dsk = tqApp->desktop(); - - if (_greeterScreen < 0) - _greeterScreen = _greeterScreen == -2 ? - dsk->screenNumber( TQPoint( dsk->width() - 1, 0 ) ) : - dsk->screenNumber( TQPoint( 0, 0 ) ); - - TQRect scr = dsk->screenGeometry( _greeterScreen ); - if (!winFrame) - setFixedSize( scr.size() ); - else { - setMaximumSize( scr.size() * .9 ); - adjustSize(); - } - - if (parentWidget()) - return; - - TQRect grt( rect() ); - if (winFrame) { - unsigned x = 50, y = 50; - sscanf( _greeterPos, "%u,%u", &x, &y ); - grt.moveCenter( TQPoint( scr.x() + scr.width() * x / 100, - scr.y() + scr.height() * y / 100 ) ); - int di; - if ((di = scr.right() - grt.right()) < 0) - grt.moveBy( di, 0 ); - if ((di = scr.left() - grt.left()) > 0) - grt.moveBy( di, 0 ); - if ((di = scr.bottom() - grt.bottom()) < 0) - grt.moveBy( 0, di ); - if ((di = scr.top() - grt.top()) > 0) - grt.moveBy( 0, di ); - setGeometry( grt ); - } - - if (dsk->screenNumber( TQCursor::pos() ) != _greeterScreen) - TQCursor::setPos( grt.center() ); -} - -struct WinList { - struct WinList *next; - TQWidget *win; -}; - -int -FDialog::exec() -{ - static WinList *wins; - WinList *win; - - win = new WinList; - win->win = this; - win->next = wins; - wins = win; - show(); - setActiveWindow(); - inherited::exec(); - hide(); - wins = win->next; - delete win; - if (wins) - wins->win->setActiveWindow(); - return result(); -} - -void -FDialog::box( TQWidget *parent, TQMessageBox::Icon type, const TQString &text ) -{ - KFMsgBox dlg( parent, type, text.stripWhiteSpace() ); - dlg.exec(); -} - -KFMsgBox::KFMsgBox( TQWidget *parent, TQMessageBox::Icon type, const TQString &text ) - : inherited( parent, !is_themed ) -{ - if (type == TQMessageBox::NoIcon) setCaption(TDM_LOGIN_SCREEN_BASE_TITLE); - if (type == TQMessageBox::Question) setCaption(TDM_LOGIN_SCREEN_BASE_TITLE + " - " + i18n("Question")); - if (type == TQMessageBox::Information) setCaption(TDM_LOGIN_SCREEN_BASE_TITLE + " - " + i18n("Information")); - if (type == TQMessageBox::Warning) setCaption(TDM_LOGIN_SCREEN_BASE_TITLE + " - " + i18n("Warning")); - if (type == TQMessageBox::Critical) setCaption(TDM_LOGIN_SCREEN_BASE_TITLE + " - " + i18n("Error")); - - TQLabel *label1 = new TQLabel( this ); - label1->setPixmap( TQMessageBox::standardIcon( type ) ); - TQLabel *label2 = new TQLabel( text, this ); - TQRect d = KGlobalSettings::desktopGeometry(this); - if ( label2->fontMetrics().size( 0, text).width() > d.width() * 3 / 5) - label2->setAlignment(TQt::WordBreak | TQt::AlignAuto ); - KPushButton *button = new KPushButton( KStdGuiItem::ok(), this ); - button->setDefault( true ); - button->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) ); - connect( button, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); - - TQGridLayout *grid = new TQGridLayout( this, 2, 2, 10 ); - grid->addWidget( label1, 0, 0, Qt::AlignCenter ); - grid->addWidget( label2, 0, 1, Qt::AlignCenter ); - grid->addMultiCellWidget( button, 1,1, 0,1, Qt::AlignCenter ); -} diff --git a/kdm/kfrontend/kfdialog.h b/kdm/kfrontend/kfdialog.h deleted file mode 100644 index 851d9a2db..000000000 --- a/kdm/kfrontend/kfdialog.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - -Dialog class that handles input focus in absence of a wm - -Copyright (C) 1997, 1998 Steffen Hansen -Copyright (C) 2000-2003 Oswald Buddenhagen - - -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. - -*/ - -#define TDM_LOGIN_SCREEN_BASE_TITLE i18n("Login to TDE") - -#ifndef FDIALOG_H -#define FDIALOG_H - -#include -#include - -class TQFrame; - -class FDialog : public TQDialog { - typedef TQDialog inherited; - - public: - FDialog( TQWidget *parent = 0, bool framed = true ); - virtual int exec(); - - static void box( TQWidget *parent, TQMessageBox::Icon type, - const TQString &text ); -#define errorbox TQMessageBox::Critical -#define sorrybox TQMessageBox::Warning -#define infobox TQMessageBox::Information - void MsgBox( TQMessageBox::Icon typ, const TQString &msg ) { box( this, typ, msg ); } - - protected: - virtual void resizeEvent( TQResizeEvent *e ); - void adjustGeometry(); - - private: - TQFrame *winFrame; - bool m_wmTitle; -}; - -class KFMsgBox : public FDialog { - typedef FDialog inherited; - - public: - KFMsgBox( TQWidget *parent, TQMessageBox::Icon type, const TQString &text ); -}; - -#endif /* FDIALOG_H */ diff --git a/kdm/kfrontend/kgapp.cpp b/kdm/kfrontend/kgapp.cpp deleted file mode 100644 index 5ad52dda6..000000000 --- a/kdm/kfrontend/kgapp.cpp +++ /dev/null @@ -1,469 +0,0 @@ -/* - -Greeter module for xdm - -Copyright (C) 1997, 1998 Steffen Hansen -Copyright (C) 2000-2003 Oswald Buddenhagen - - -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 - -#include "tdm_greet.h" -#include "tdmshutdown.h" -#include "tdmconfig.h" -#include "kgapp.h" -#include "kgreeter.h" -#ifdef XDMCP -# include "kchooser.h" -#endif -#include "sakdlg.h" - -#include -#include -#include -#include -#include -#include -#include -#ifdef WITH_XRANDR -#include -#endif - -#include -#include -#include -#include - -#include // free(), exit() -#include // alarm() - -#include -#include -#include -#include - -#ifdef HAVE_XCOMPOSITE -#include -#include -#endif - -#include - -bool argb_visual_available = false; -bool has_twin = false; -bool is_themed = false; -bool trinity_desktop_lock_use_sak = TRUE; - -static int -ignoreXError( Display *dpy ATTR_UNUSED, XErrorEvent *event ATTR_UNUSED ) -{ - return 0; -} - -extern "C" { - -static void -sigAlarm( int ) -{ - exit( EX_RESERVER_DPY ); -} - -} - -GreeterApp::GreeterApp() -{ - pingInterval = _isLocal ? 0 : _pingInterval; - if (pingInterval) { - struct sigaction sa; - sigemptyset( &sa.sa_mask ); - sa.sa_flags = 0; - sa.sa_handler = sigAlarm; - sigaction( SIGALRM, &sa, 0 ); - alarm( pingInterval * 70 ); // sic! give the "proper" pinger enough time - startTimer( pingInterval * 60000 ); - } -} - -GreeterApp::GreeterApp(Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap) : KApplication(dpy, visual, colormap) -{ - pingInterval = _isLocal ? 0 : _pingInterval; - if (pingInterval) { - struct sigaction sa; - sigemptyset( &sa.sa_mask ); - sa.sa_flags = 0; - sa.sa_handler = sigAlarm; - sigaction( SIGALRM, &sa, 0 ); - alarm( pingInterval * 70 ); // sic! give the "proper" pinger enough time - startTimer( pingInterval * 60000 ); - } -} - -void -GreeterApp::timerEvent( TQTimerEvent * ) -{ - alarm( 0 ); - if (!PingServer( qt_xdisplay() )) - ::exit( EX_RESERVER_DPY ); - alarm( pingInterval * 70 ); // sic! give the "proper" pinger enough time -} - -bool -GreeterApp::x11EventFilter( XEvent * ev ) -{ - KeySym sym; - - switch (ev->type) { - case FocusIn: - case FocusOut: - // Hack to tell dialogs to take focus when the keyboard is grabbed - ev->xfocus.mode = NotifyNormal; - break; - case KeyPress: - sym = XLookupKeysym( &ev->xkey, 0 ); - if (sym != XK_Return && !IsModifierKey( sym )) - emit activity(); - break; - case ButtonPress: - emit activity(); - /* fall through */ - case ButtonRelease: - // Hack to let the RMB work as LMB - if (ev->xbutton.button == 3) - ev->xbutton.button = 1; - /* fall through */ - case MotionNotify: - if (ev->xbutton.state & Button3Mask) - ev->xbutton.state = (ev->xbutton.state & ~Button3Mask) | Button1Mask; - break; - } - return false; -} - -extern bool kde_have_kipc; - -extern "C" { - -static int -xIOErr( Display * ) -{ - exit( EX_RESERVER_DPY ); -} - -//KSimpleConfig *iccconfig; - -void -checkSAK(GreeterApp* app) -{ - app->restoreOverrideCursor(); - SAKDlg sak(0); - sak.exec(); - app->setOverrideCursor( Qt::WaitCursor ); -} - -void -kg_main( const char *argv0 ) -{ - static char *argv[] = { (char *)"tdmgreet", 0 }; - KCmdLineArgs::init( 1, argv, *argv, 0, 0, 0, true ); - - kdDebug() << timestamp() << "start" << endl; - kde_have_kipc = false; - KApplication::disableAutoDcopRegistration(); - KCrash::setSafer( true ); - - KProcess *tsak = 0; - KProcess *proc = 0; - KProcess *comp = 0; - KProcess *twin = 0; - - trinity_desktop_lock_use_sak = _useSAK; - if (trinity_desktop_lock_use_sak) { - tsak = new KProcess; - *tsak << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + "tsak"; - tsak->start(KProcess::Block); - } - if (tsak) { - tsak->closeStdin(); - tsak->detach(); - delete tsak; - } - -#ifdef HAVE_XCOMPOSITE - // Begin ARGB initialization - XSetErrorHandler( ignoreXError ); - argb_visual_available = false; - char *display = 0; - - Display *dpyi = XOpenDisplay( display ); - if ( !dpyi ) { - kdError() << "cannot connect to X server " << display << endl; - exit( 1 ); - } - - int screen = DefaultScreen( dpyi ); - Colormap colormap = 0; - Visual *visual = 0; - int event_base, error_base; - - if ( XRenderQueryExtension( dpyi, &event_base, &error_base ) ) { - int nvi; - XVisualInfo templ; - templ.screen = screen; - templ.depth = 32; - templ.c_class = TrueColor; - XVisualInfo *xvi = XGetVisualInfo( dpyi, VisualScreenMask | VisualDepthMask - | VisualClassMask, &templ, &nvi ); - - for ( int i = 0; i < nvi; i++ ) { - XRenderPictFormat *format = XRenderFindVisualFormat( dpyi, xvi[i].visual ); - if ( format->type == PictTypeDirect && format->direct.alphaMask ) { - visual = xvi[i].visual; - colormap = XCreateColormap( dpyi, RootWindow( dpyi, screen ), visual, AllocNone ); - kdDebug() << "found visual with alpha support" << endl; - argb_visual_available = true; - break; - } - } - } - XSetErrorHandler( (XErrorHandler)0 ); - - GreeterApp *app; - if ( (argb_visual_available == true) && (!_compositor.isEmpty()) ) { - app = new GreeterApp(dpyi, Qt::HANDLE( visual ), Qt::HANDLE( colormap )); - } - else { - app = new GreeterApp(); - } - // End ARGB initialization -#else - GreeterApp *app = new GreeterApp(); -#endif - - XSetIOErrorHandler( xIOErr ); - TQString login_user; - - Display *dpy = qt_xdisplay(); - - if (!_GUIStyle.isEmpty()) - app->setStyle( _GUIStyle ); - - // Load up systemwide display settings -#ifdef WITH_XRANDR - KRandrSimpleAPI *randrsimple = new KRandrSimpleAPI(); - TQPoint primaryScreenPosition = randrsimple->applySystemwideDisplayConfiguration("", KDE_CONFDIR); - delete randrsimple; -#endif - - // Load up the systemwide ICC profile - TQString iccConfigFile = TQString(KDE_CONFDIR); - iccConfigFile += "/kicc/kiccconfigrc"; - KSimpleConfig iccconfig(iccConfigFile, true); - if (iccconfig.readBoolEntry("EnableICC", false) == true) { - TQString iccCommand = TQString("/usr/bin/xcalib "); - iccCommand += iccconfig.readEntry("ICCFile"); - iccCommand += TQString(" &"); - system(iccCommand.ascii()); - } - - _colorScheme = locate( "data", "kdisplay/color-schemes/" + _colorScheme + ".kcsrc" ); - if (!_colorScheme.isEmpty()) { - KSimpleConfig config( _colorScheme, true ); - config.setGroup( "Color Scheme" ); - app->setPalette( app->createApplicationPalette( &config, 7 ) ); - } - - app->setFont( _normalFont ); - - setup_modifiers( dpy, _numLockStatus ); - SecureDisplay( dpy ); - if (!_grabServer) { - if (_useBackground) { - proc = new KProcess; - *proc << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + "krootimage"; - *proc << _backgroundCfg; - proc->start(); - } - GSendInt( G_SetupDpy ); - GRecvInt(); - } - - if (!_compositor.isEmpty()) { - comp = new KProcess; - *comp << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + _compositor.ascii(); - comp->start(KProcess::NotifyOnExit, KProcess::Stdin); - } - - if (!_windowManager.isEmpty()) { - twin = new KProcess; - *twin << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + _windowManager.ascii(); - twin->start(); - has_twin = true; - } - - GSendInt( G_Ready ); - - kdDebug() << timestamp() << " main1" << endl; - setCursor( dpy, app->desktop()->winId(), XC_left_ptr ); - - for (;;) { - int rslt, cmd = GRecvInt(); - - if (cmd == G_ConfShutdown) { - int how = GRecvInt(), uid = GRecvInt(); - char *os = GRecvStr(); - TDMSlimShutdown::externShutdown( how, os, uid ); - if (os) - free( os ); - GSendInt( G_Ready ); - _autoLoginDelay = 0; - continue; - } - - if (cmd == G_ErrorGreet) { - if (KGVerify::handleFailVerify( TQT_TQWIDGET(tqApp->desktop()->screen( _greeterScreen )) )) - break; - _autoLoginDelay = 0; - cmd = G_Greet; - } - - KProcess *proc2 = 0; - app->setOverrideCursor( Qt::WaitCursor ); - FDialog *dialog = NULL; -#ifdef XDMCP - if (cmd == G_Choose) { - dialog = new ChooserDlg; - GSendInt( G_Ready ); /* tell chooser to go into async mode */ - GRecvInt(); /* ack */ - } else -#endif - { - if ((cmd != G_GreetTimed && !_autoLoginAgain) || - _autoLoginUser.isEmpty()) - _autoLoginDelay = 0; - if (_useTheme && !_theme.isEmpty()) { - // Qt4 has a nasty habit of generating BadWindow errors in normal operation, so we simply ignore them - // This also prevents the user from being dropped to a console login if Xorg glitches or is buggy - XSetErrorHandler( ignoreXError ); - KThemedGreeter *tgrt; - bool has_twin_bkp = has_twin; - is_themed = true; - has_twin = false; // [FIXME] The themed greeter is built on the assumption that there is no window manager available (i.e. it keeps stealing focus) and needs to be repaired. - dialog = tgrt = new KThemedGreeter; - kdDebug() << timestamp() << " themed" << endl; - if (!tgrt->isOK()) { - is_themed = false; - has_twin = has_twin_bkp; - delete tgrt; - checkSAK(app); - dialog = new KStdGreeter; -#ifdef WITH_XRANDR - dialog->move(dialog->x() + primaryScreenPosition.x(), dialog->y() + primaryScreenPosition.y()); -#endif - } - else { -#ifdef WITH_XRANDR - dialog->move(primaryScreenPosition.x(), primaryScreenPosition.y()); -#endif - } - XSetErrorHandler( (XErrorHandler)0 ); - } else { - checkSAK(app); - dialog = new KStdGreeter; -#ifdef WITH_XRANDR - dialog->move(dialog->x() + primaryScreenPosition.x(), dialog->y() + primaryScreenPosition.y()); -#endif - } - TQPoint oldCursorPos = TQCursor::pos(); -#ifdef WITH_XRANDR - TQCursor::setPos(oldCursorPos.x() + primaryScreenPosition.x(), oldCursorPos.y() + primaryScreenPosition.y()); -#endif - if (*_preloader) { - proc2 = new KProcess; - *proc2 << _preloader; - proc2->start(); - } - } - app->restoreOverrideCursor(); - Debug( "entering event loop\n" ); - // Qt4 has a nasty habit of generating BadWindow errors in normal operation, so we simply ignore them - // This also prevents the user from being dropped to a console login if Xorg glitches or is buggy - XSetErrorHandler( ignoreXError ); - rslt = dialog->exec(); - XSetErrorHandler( (XErrorHandler)0 ); - Debug( "left event loop\n" ); - - login_user = static_cast(dialog)->curUser; - - if (rslt != ex_greet) { - delete dialog; - } - delete proc2; -#ifdef XDMCP - switch (rslt) { - case ex_greet: - GSendInt( G_DGreet ); - continue; - case ex_choose: - GSendInt( G_DChoose ); - continue; - default: - break; - } -#endif - break; - } - - KGVerify::done(); - - if (comp) { - if (_compositor == "kompmgr") { - // Change process UID - // Get user UID - passwd* userinfo = getpwnam(login_user.ascii()); - if (userinfo) { - TQString newuid = TQString("%1").arg(userinfo->pw_uid); - // kompmgr allows us to change its uid in this manner: - // 1.) Send SIGUSER1 - // 2.) Send the new UID to it on the command line - comp->kill(SIGUSR1); - comp->writeStdin(newuid.ascii(), newuid.length()); - usleep(50000); // Give the above function some time to execute. Note that on REALLY slow systems this could fail, leaving kompmgr running as root. TODO: Look into ways to make this more robust. - } - } - comp->closeStdin(); - comp->detach(); - delete comp; - } - if (twin) { - twin->closeStdin(); - twin->detach(); - delete twin; - } - delete proc; - UnsecureDisplay( dpy ); - restore_modifiers(); - - XSetInputFocus( qt_xdisplay(), PointerRoot, PointerRoot, CurrentTime ); - - delete app; -} - -} // extern "C" - -#include "kgapp.moc" diff --git a/kdm/kfrontend/kgapp.h b/kdm/kfrontend/kgapp.h deleted file mode 100644 index 2c4374f47..000000000 --- a/kdm/kfrontend/kgapp.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - -Greeter module for xdm - -Copyright (C) 1997, 1998 Steffen Hansen -Copyright (C) 2000-2003 Oswald Buddenhagen - - -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. - -*/ - - -#ifndef KGAPP_H -#define KGAPP_H - -#include - -class GreeterApp : public KApplication { - Q_OBJECT - typedef KApplication inherited; - - public: - GreeterApp(); - GreeterApp(Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap); - virtual bool x11EventFilter( XEvent * ); - - protected: - virtual void timerEvent( TQTimerEvent * ); - - signals: - void activity(); - - private: - int pingInterval; -}; - -#endif /* KGAPP_H */ diff --git a/kdm/kfrontend/kgdialog.cpp b/kdm/kfrontend/kgdialog.cpp deleted file mode 100644 index 667eca8e1..000000000 --- a/kdm/kfrontend/kgdialog.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* - -Base class for various tdm greeter dialogs - -Copyright (C) 1997, 1998 Steffen Hansen -Copyright (C) 2000-2004 Oswald Buddenhagen - - -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 "kgdialog.h" -#include "kgverify.h" -#include "kconsole.h" -#include "tdmshutdown.h" -#include "tdm_greet.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include - -KGDialog::KGDialog( bool themed ) : inherited( 0, !themed ) -{ -#ifdef WITH_TDM_XCONSOLE - consoleView = _showLog ? new KConsole( this ) : 0; -#endif - - optMenu = 0; - verify = 0; -} - -void -#ifdef XDMCP -KGDialog::completeMenu( int _switchIf, int _switchCode, const TQString &_switchMsg, int _switchAccel ) -#else -KGDialog::completeMenu() -#endif -{ -#ifdef HAVE_VTS - if (_isLocal) { - dpyMenu = new TQPopupMenu( this ); - int id = inserten( i18n("Sw&itch User"), ALT+Key_I, dpyMenu ); - connect( dpyMenu, TQT_SIGNAL(activated( int )), - TQT_SLOT(slotDisplaySelected( int )) ); - connect( dpyMenu, TQT_SIGNAL(aboutToShow()), - TQT_SLOT(slotPopulateDisplays()) ); - TQAccel *accel = new TQAccel( this ); - accel->insertItem( ALT+CTRL+Key_Insert, id ); - connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotActivateMenu( int )) ); - } -#endif - - if (_allowClose) - inserten( _isLocal ? i18n("R&estart X Server") : i18n("Clos&e Connection"), - ALT+Key_E, TQT_SLOT(slotExit()) ); - -#ifdef XDMCP - if (_isLocal && _loginMode != _switchIf) { - switchCode = _switchCode; - inserten( _switchMsg, _switchAccel, TQT_SLOT(slotSwitch()) ); - } -#endif - - if (_hasConsole) - inserten( i18n("Co&nsole Login"), ALT+Key_N, TQT_SLOT(slotConsole()) ); - - if (_allowShutdown != SHUT_NONE) { - ensureMenu(); - optMenu->insertItem(SmallIconSet( "exit" ), i18n("&Shutdown..."), this, TQT_SLOT(slotShutdown(int)), ALT+Key_S ); - TQAccel *accel = new TQAccel( this ); - accel->insertItem( ALT+CTRL+Key_Delete ); - connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotShutdown( int )) ); - accel = new TQAccel( this ); - accel->insertItem( SHIFT+ALT+CTRL+Key_PageUp, SHUT_REBOOT ); - connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotShutdown( int )) ); - accel = new TQAccel( this ); - accel->insertItem( SHIFT+ALT+CTRL+Key_PageDown, SHUT_HALT ); - connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotShutdown( int )) ); - } -} - -void -KGDialog::ensureMenu() -{ - if (!optMenu) { - optMenu = new TQPopupMenu( this ); - optMenu->setCheckable( false ); - needSep = false; - } else if (needSep) { - optMenu->insertSeparator(); - needSep = false; - } -} - -void -KGDialog::inserten( const TQString& txt, int accel, const char *member ) -{ - ensureMenu(); - optMenu->insertItem( txt, this, member, accel ); -} - -int -KGDialog::inserten( const TQString& txt, int accel, TQPopupMenu *cmnu ) -{ - ensureMenu(); - int id = optMenu->insertItem( txt, cmnu ); - optMenu->setAccel( accel, id ); - optMenu->connectItem( id, this, TQT_SLOT(slotActivateMenu( int )) ); - optMenu->setItemParameter( id, id ); - return id; -} - -void -KGDialog::slotActivateMenu( int id ) -{ - TQPopupMenu *cmnu = optMenu->findItem( id )->popup(); - TQSize sh( cmnu->sizeHint() / 2 ); - cmnu->exec( geometry().center() - TQPoint( sh.width(), sh.height() ) ); -} - -void -KGDialog::slotExit() -{ - if (verify) - verify->abort(); - ::exit( EX_RESERVER_DPY ); -} - -void -KGDialog::slotSwitch() -{ -#ifdef XDMCP - // workaround for Qt bug - TQTimer::singleShot( 0, this, TQT_SLOT(slotReallySwitch()) ); -#endif -} - -void -KGDialog::slotReallySwitch() -{ -#ifdef XDMCP - done( switchCode ); -#endif -} - -void -KGDialog::slotConsole() -{ -#ifdef HAVE_VTS - dpySpec *sess = fetchSessions( 0 ); - if (sess) { - if (verify) - verify->suspend(); - int ret = TDMConfShutdown( -1, sess, SHUT_CONSOLE, 0 ).exec(); - if (verify) - verify->resume(); - disposeSessions( sess ); - if (!ret) - return; - } -#else - if (verify) - verify->abort(); -#endif - GSet( 1 ); - GSendInt( G_Console ); - GSet( 0 ); -} - -void -KGDialog::slotShutdown( int id ) -{ - if (verify) - verify->suspend(); - if (id < 0) { - if (_scheduledSd == SHUT_ALWAYS) - TDMShutdown::scheduleShutdown( this ); - else - TDMSlimShutdown( this ).exec(); - } else - TDMSlimShutdown::externShutdown( id, 0, -1 ); - if (verify) - verify->resume(); -} - -void -KGDialog::slotDisplaySelected( int vt ) -{ -#ifdef HAVE_VTS - GSet( 1 ); - GSendInt( G_Activate ); - GSendInt( vt ); - GSet( 0 ); -#else - (void)vt; -#endif -} - -void -KGDialog::slotPopulateDisplays() -{ -#ifdef HAVE_VTS - dpyMenu->clear(); - dpySpec *sessions = fetchSessions( lstPassive | lstTTY ); - TQString user, loc; - for (dpySpec *sess = sessions; sess; sess = sess->next) { - decodeSess( sess, user, loc ); - int id = dpyMenu->insertItem( - i18n("session (location)", "%1 (%2)").arg( user ).arg( loc ), - sess->vt ? sess->vt : -1 ); - if (!sess->vt) - dpyMenu->setItemEnabled( id, false ); - if (sess->flags & isSelf) - dpyMenu->setItemChecked( id, true ); - } - disposeSessions( sessions ); -#endif -} - -#include "kgdialog.moc" diff --git a/kdm/kfrontend/kgdialog.h b/kdm/kfrontend/kgdialog.h deleted file mode 100644 index a902b6ff0..000000000 --- a/kdm/kfrontend/kgdialog.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - -Base class for various tdm greeter dialogs - -Copyright (C) 1997, 1998 Steffen Hansen -Copyright (C) 2000-2004 Oswald Buddenhagen - - -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. - -*/ - - -#ifndef KGDIALOG_H -#define KGDIALOG_H - -#include // for WITH_TDM_XCONSOLE - -#include "tdmconfig.h" -#include "kfdialog.h" - -class TQPopupMenu; -class TQGridLayout; -class KConsole; -class KGVerify; - -#define ex_exit 1 -#define ex_greet 2 -#define ex_choose 3 - -class KGDialog : public FDialog { - Q_OBJECT - typedef FDialog inherited; - - public: - KGDialog( bool themed = false ); - - public slots: - void slotActivateMenu( int id ); - void slotExit(); - void slotSwitch(); - void slotReallySwitch(); - void slotConsole(); - void slotShutdown( int id ); - - protected: -#ifdef XDMCP - void completeMenu( int _switchIf, int _switchCode, const TQString &_switchMsg, int _switchAccel ); -#else - void completeMenu(); -#endif - void inserten( const TQString& txt, int accel, const char *member ); - int inserten( const TQString& txt, int accel, TQPopupMenu *cmnu ); - - bool needSep; - TQPopupMenu *optMenu; - KGVerify *verify; -#ifdef WITH_TDM_XCONSOLE - KConsole *consoleView; -#endif - - private slots: - void slotDisplaySelected( int vt ); - void slotPopulateDisplays(); - - private: - void ensureMenu(); - -#ifdef HAVE_VTS - TQPopupMenu *dpyMenu; -#endif - int switchCode; -}; - -#endif /* KGDIALOG_H */ diff --git a/kdm/kfrontend/kgreeter.cpp b/kdm/kfrontend/kgreeter.cpp deleted file mode 100644 index ee1bf3e72..000000000 --- a/kdm/kfrontend/kgreeter.cpp +++ /dev/null @@ -1,1280 +0,0 @@ -/* - -Greeter widget for tdm - -Copyright (C) 1997, 1998, 2000 Steffen Hansen -Copyright (C) 2000-2004 Oswald Buddenhagen - - -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 "kgreeter.h" -#include "kconsole.h" -#include "tdmconfig.h" -#include "tdmclock.h" -#include "tdm_greet.h" -#include "tdmadmindialog.h" -#include "themer/tdmthemer.h" -#include "themer/tdmitem.h" -#include "themer/tdmlabel.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#undef Unsorted // x headers suck - make tqdir.h work with --enable-final -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define FIFO_DIR "/tmp/ksocket-global/tdm" -#define FIFO_FILE "/tmp/ksocket-global/tdm/tdmctl-%1" -#define FIFO_SAK_FILE "/tmp/ksocket-global/tdm/tdmctl-sak-%1" - -class UserListView : public KListView { - public: - UserListView( bool _them, TQWidget *parent = 0, const char *name = 0 ) - : KListView( parent, name ) - , themed(_them), cachedSizeHint( -1, 0 ) - { - setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Ignored ); - header()->hide(); - addColumn( TQString::null ); - setColumnAlignment( 0, AlignVCenter ); - setResizeMode( TQListView::LastColumn ); - // FIXME: This must be configurable, so disable - // painting of list background for now. -// if (themed) { -// setBackgroundMode( Qt::NoBackground ); -// viewport()->setBackgroundMode( Qt::NoBackground ); -// setFrameStyle( TQFrame::NoFrame ); -// } - } - - bool themed; - mutable TQSize cachedSizeHint; - - int sumHeight() const - { - int sum = 0; - for (TQListViewItem *itm = firstChild(); itm; itm = itm->nextSibling()) { - sum += itm->height(); - } - return sum; - } -public: - virtual TQSize sizeHint() const - { - if (themed) - return KListView::sizeHint(); - - if (!cachedSizeHint.isValid()) { - constPolish(); - uint maxw = 0; - for (TQListViewItem *itm = firstChild(); itm; itm = itm->nextSibling()) { - uint thisw = itm->width( fontMetrics(), this, 0 ); - if (thisw > maxw) - maxw = thisw; - } - cachedSizeHint.setWidth( - style().pixelMetric( TQStyle::PM_ScrollBarExtent ) + - frameWidth() * 2 + maxw ); - } - return cachedSizeHint; - } - virtual void paintEmptyArea ( TQPainter * p, const TQRect & rect ) - { - if (!themed) - return KListView::paintEmptyArea(p, rect ); - - // FIXME: This must be configurable, so disable - // painting of list background for now. - return KListView::paintEmptyArea(p, rect ); - - const TQPixmap *pm = TQT_TQPIXMAP_CONST(paletteBackgroundPixmap()); - if (!pm || pm->isNull()) - return; - - kdDebug() << "paintEmpty " << rect << endl; - TQRect devRect = p->xForm( rect ); - kdDebug() << "paintEmpty2 " << devRect << endl; - p->drawPixmap(0, 0, *pm, devRect.left(), devRect.top() ); - } - - TQPixmap background; -}; - -int KGreeter::curPlugin = -1; -PluginList KGreeter::pluginList; - -KGreeter::KGreeter( bool framed ) - : inherited( framed ) - , dName( dname ) - , userView( 0 ) - , userList( 0 ) - , nNormals( 0 ) - , nSpecials( 0 ) - , curPrev( -1 ) - , curSel( -1 ) - , prevValid( true ) - , needLoad( false ) - , themed( framed ) - , mPipe_fd( -1 ) - , closingDown( false ) -{ - stsFile = new KSimpleConfig( _stsFile ); - stsFile->setGroup( "PrevUser" ); - - if (_userList) { - readFacesList(); - userView = new UserListView( framed, this ); - connect( userView, TQT_SIGNAL(clicked( TQListViewItem * )), - TQT_SLOT(slotUserClicked( TQListViewItem * )) ); - connect( userView, TQT_SIGNAL(doubleClicked( TQListViewItem * )), - TQT_SLOT(accept()) ); - } - if (_userCompletion) - userList = new TQStringList; - - sessMenu = new TQPopupMenu( this ); - connect( sessMenu, TQT_SIGNAL(activated( int )), - TQT_SLOT(slotSessionSelected( int )) ); - insertSessions(); - - if (curPlugin < 0) { - curPlugin = 0; - pluginList = KGVerify::init( _pluginsLogin ); - } - - TQTimer::singleShot( 0, this, TQT_SLOT(handleInputPipe()) ); -} - -KGreeter::~KGreeter() -{ - if (mPipe_fd != -1) { - closingDown = true; - ::close(mPipe_fd); - ::unlink(mPipeFilename.ascii()); - } - hide(); - delete userList; - delete verify; - delete stsFile; -} - -void KGreeter::done(int r) { - closingDown = true; - inherited::done(r); -} - -void KGreeter::handleInputPipe(void) { - if (closingDown) { - ::unlink(mPipeFilename.ascii()); - return; - } - - if (isShown() == false) { - TQTimer::singleShot( 100, this, TQT_SLOT(handleInputPipe()) ); - return; - } - - char readbuf[2048]; - int displayNumber; - TQString currentDisplay; - currentDisplay = TQString(getenv("DISPLAY")); - currentDisplay = currentDisplay.replace(":", ""); - displayNumber = currentDisplay.toInt(); - mPipeFilename = TQString(FIFO_FILE).arg(displayNumber); - ::unlink((TQString(FIFO_SAK_FILE).arg(displayNumber)).ascii()); - - /* Create the FIFOs if they do not exist */ - umask(0); - struct stat buffer; - int status; - status = stat(FIFO_DIR, &buffer); - if (status == 0) { - int file_mode = ((buffer.st_mode & S_IRWXU) >> 6) * 100; - file_mode = file_mode + ((buffer.st_mode & S_IRWXG) >> 3) * 10; - file_mode = file_mode + ((buffer.st_mode & S_IRWXO) >> 0) * 1; - if ((file_mode != 600) || (buffer.st_uid != 0) || (buffer.st_gid != 0)) { - ::unlink(mPipeFilename.ascii()); - printf("[WARNING] Possible security breach! Please check permissions on " FIFO_DIR " (must be 600 and owned by root/root, got %d %d/%d). Not listening for login credentials on remote control socket.\n", file_mode, buffer.st_uid, buffer.st_gid); fflush(stdout); - return; - } - } - mkdir(FIFO_DIR,0600); - mknod(mPipeFilename.ascii(), S_IFIFO|0600, 0); - chmod(mPipeFilename.ascii(), 0600); - - mPipe_fd = ::open(mPipeFilename.ascii(), O_RDONLY | O_NONBLOCK); - int numread; - TQString inputcommand = ""; - while ((!inputcommand.contains('\n')) && (!closingDown)) { - numread = ::read(mPipe_fd, readbuf, 2048); - readbuf[numread] = 0; - readbuf[2047] = 0; - inputcommand += readbuf; - if (!tqApp->hasPendingEvents()) { - usleep(500); - } - tqApp->processEvents(); - } - if (closingDown) { - ::unlink(mPipeFilename.ascii()); - return; - } - inputcommand = inputcommand.replace('\n', ""); - TQStringList commandList = TQStringList::split('\t', inputcommand, false); - if ((*(commandList.at(0))) == "LOGIN") { - if (verify) { - verify->setUser( (*(commandList.at(1))) ); - verify->setPassword( (*(commandList.at(2))) ); - accept(); - } - } - if (!closingDown) { - TQTimer::singleShot( 0, this, TQT_SLOT(handleInputPipe()) ); - ::close(mPipe_fd); - ::unlink(mPipeFilename.ascii()); - } - else { - ::unlink(mPipeFilename.ascii()); - } -} - -void KGreeter::readFacesList() -{ - FILE *f = fopen( TQFile::encodeName( _faceDir + "/.randomlist" ), "rt" ); - if ( !f ) - return; - TQTextIStream is( f ); - while ( !is.eof() ) - { - TQString line = is.readLine().simplifyWhiteSpace(); - if ( line.isEmpty() ) - continue; - TQString icon; - int index = line.find( ' ' ); - if ( index > 0 ) { - icon = line.left( index ); - line = line.mid( index ); - } else { - icon = line; - line = TQString::null; - } - randomFaces.push_back( icon ); - TQStringList list = TQStringList::split( ' ', line ); - for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) - randomFacesMap[*it] = icon; - } -} - -class UserListViewItem : public KListViewItem { - public: - UserListViewItem( UserListView *parent, const TQString &text, - const TQPixmap &pixmap, const TQString &username ) - : KListViewItem( parent ) - , login( username ) - { - setPixmap( 0, pixmap ); - setMultiLinesEnabled( true ); - setText( 0, text ); - parent->cachedSizeHint.setWidth( -1 ); - } - - virtual void paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment) - { - if (((UserListView*)listView())->themed) - TQListViewItem::paintCell(p, cg, column, width, alignment); - else - KListViewItem::paintCell(p, cg, column, width, alignment); - } - - TQString login; -}; - -#define FILE_LIMIT_ICON 20 -#define FILE_LIMIT_IMAGE 200 - -void -KGreeter::insertUser( const TQImage &default_pix, - const TQString &username, struct passwd *ps ) -{ - if (setegid( ps->pw_gid )) - return; - if (seteuid( ps->pw_uid )) { - setegid(0); - return; - } - - if (userList) - userList->append( username ); - if (!userView) - return; - - int dp = 0, nd = 0; - if (_faceSource == FACE_USER_ONLY || - _faceSource == FACE_PREFER_USER) - dp = 1; - if (_faceSource != FACE_USER_ONLY && - _faceSource != FACE_ADMIN_ONLY) - nd = 1; - TQImage p; - do { - dp ^= 1; - TQCString fn = !dp ? - TQCString( ps->pw_dir ) + '/' : - TQCString(TQFile::encodeName( _faceDir + '/' + username )); - fn += ".face.icon"; - int fd, ico; - if ((fd = open( fn.data(), O_RDONLY | O_NONBLOCK )) < 0) { - fn.truncate( fn.length() - 5 ); - if ((fd = open( fn.data(), O_RDONLY | O_NONBLOCK )) < 0) - continue; - ico = 0; - } else - ico = 1; - TQFile f; - f.open( IO_ReadOnly, fd ); - int fs = f.size(); - if (fs > (ico ? FILE_LIMIT_ICON : FILE_LIMIT_IMAGE) * 1000) { - LogWarn( "%s exceeds file size limit (%dkB)\n", - fn.data(), ico ? FILE_LIMIT_ICON : FILE_LIMIT_IMAGE ); - continue; - } - TQByteArray fc( fs ); - int rfs = f.readBlock( fc.data(), fs ); - ::close( fd ); - fc.resize( rfs > 0 ? rfs : 0 ); - TQBuffer buf( fc ); - buf.open( IO_ReadOnly ); - TQImageIO ir; - ir.setIODevice( TQT_TQIODEVICE(&buf) ); - if (!ir.read()) { - LogInfo( "%s is no valid image\n", fn.data() ); - continue; - } - p = ir.image(); - TQSize ns( 48, 48 ); - if (p.size() != ns) - p = p.convertDepth( 32 ).smoothScale( ns, TQ_ScaleMin ); - break; - } while (--nd >= 0); - - if ( p.isNull() && randomFaces.count() ) { - TQString randomFace = randomFacesMap[username]; - if ( randomFace.isNull() ) { - TQStringList::size_type index = 0; - for ( size_t i = 0; i < username.length(); ++i ) - index += ( 0x7f - username.at( i ).latin1() ) % 37; - randomFace = randomFaces[ index % randomFaces.count() ]; - } - p.load( _faceDir + "/../pics/users/" + randomFace + ".png" ); - } - - if ( p.isNull() ) - p = default_pix; - - TQString realname = KStringHandler::from8Bit( ps->pw_gecos ); - realname.truncate( realname.find( ',' ) ); - if (realname.isEmpty() || realname == username) - new UserListViewItem( userView, username, TQPixmap( p ), username ); - else { - realname.append( "\n" ).append( username ); - new UserListViewItem( userView, realname, TQPixmap( p ), username ); - } - - seteuid( 0 ); - setegid( 0 ); -} - -class KCStringList : public TQValueList { - public: - bool contains( const char *str ) const - { - for (ConstIterator it = begin(); it != end(); ++it) - if (*it == str) - return true; - return false; - } -}; - -class UserList { - public: - UserList( char **in ); - bool hasUser( const char *str ) const { return users.contains( str ); } - bool hasGroup( gid_t gid ) const - { return groups.find( gid ) != groups.end(); } - bool hasGroups() const { return !groups.isEmpty(); } - KCStringList users; - - private: - TQValueList groups; -}; - -UserList::UserList( char **in ) -{ - struct group *grp; - - for (; *in; in++) - if (**in == '@') { - if ((grp = getgrnam( *in + 1 ))) { - for (; *grp->gr_mem; grp->gr_mem++) - users.append( *grp->gr_mem ); - groups.append( grp->gr_gid ); - } - } else - users.append( *in ); -} - -void -KGreeter::insertUsers(int limit_users) -{ - struct passwd *ps; - - if (!(ps = getpwnam( "nobody" ))) - return; - - TQImage default_pix; - if (userView) { - if (!default_pix.load( _faceDir + "/.default.face.icon" )) - if (!default_pix.load( _faceDir + "/.default.face" )) - LogError( "Can't open default user face\n" ); - TQSize ns( 48, 48 ); - if (default_pix.size() != ns) - default_pix = - default_pix.convertDepth( 32 ).smoothScale( ns, TQ_ScaleMin ); - } - if (_showUsers == SHOW_ALL) { - UserList noUsers( _noUsers ); - TQDict dupes( 1000 ); // Potential crash risk with buffer overrun? - TQStringList toinsert; - int count = 0; - for (setpwent(); (ps = getpwent()) != 0;) { - if (*ps->pw_dir && *ps->pw_shell && - ((ps->pw_uid >= (unsigned)_lowUserId) || - ((!ps->pw_uid) && _showRoot)) && - (ps->pw_uid <= (unsigned)_highUserId) && - (!noUsers.hasUser( ps->pw_name )) && - (!noUsers.hasGroup( ps->pw_gid ))) - { - TQString username( TQFile::decodeName( ps->pw_name ) ); - if (!dupes.find( username )) { - dupes.insert( username, (int *)-1 ); - toinsert.append( username ); - - if ( limit_users >= 0 && ++count > limit_users ) - break; - } - } - } - // FIXME: OpenSUSE added this code - // For some reason it does not allow LDAP users to be listed (!), - // therefore it was deactivated. It should be repaired and reactivated. -// if ( limit_users >= 0 && ++count > limit_users ) { -// utmpname( _PATH_WTMP ); -// setutxent(); -// toinsert = TQStringList(); -// dupes.clear(); -// -// for ( count = 0; count < limit_users; ) { -// struct utmpx * ent = getutxent(); -// if ( !ent ) -// break; -// struct passwd *ps = getpwnam( ent->ut_user ); -// if (ps && *ps->pw_dir && *ps->pw_shell && -// (ps->pw_uid >= (unsigned)_lowUserId || -// !ps->pw_uid && _showRoot) && -// ps->pw_uid <= (unsigned)_highUserId && -// !noUsers.hasUser( ps->pw_name ) && -// !noUsers.hasGroup( ps->pw_gid )) -// { -// TQString username( TQFile::decodeName( ent->ut_user ) ); -// if (!dupes.find( username )) { -// dupes.insert( username, (int *)-1 ); -// toinsert.append( username ); -// count++; -// } -// } -// -// -// } -// endutxent(); -// } - - for ( TQStringList::ConstIterator it = toinsert.begin(); - it != toinsert.end(); ++it ) - { - // pretty stupid to do another lookup round, but the number is limited - // and caching struct passwd is pretty ugly - struct passwd *ps = getpwnam( TQFile::encodeName( *it ) ); - if ( ps ) - insertUser( default_pix, *it, ps ); - } - } else { - UserList users( _users ); - if (users.hasGroups()) { - TQDict dupes( 1000 ); - for (setpwent(); (ps = getpwent()) != 0;) { - if (*ps->pw_dir && *ps->pw_shell && - (ps->pw_uid >= (unsigned)_lowUserId || - ((!ps->pw_uid) && _showRoot)) && - ps->pw_uid <= (unsigned)_highUserId && - (users.hasUser( ps->pw_name ) || - users.hasGroup( ps->pw_gid ))) - { - TQString username( TQFile::decodeName( ps->pw_name ) ); - if (!dupes.find( username )) { - dupes.insert( username, (int *)-1 ); - insertUser( default_pix, username, ps ); - } - } - } - } else { - KCStringList::ConstIterator it = users.users.begin(); - for (; it != users.users.end(); ++it) - if ((ps = getpwnam( (*it).data() )) && - (ps->pw_uid || _showRoot)) - insertUser( default_pix, TQFile::decodeName( *it ), ps ); - } - } - endpwent(); - if (_sortUsers) { - if (userView) - userView->sort(); - if (userList) - userList->sort(); - } -} - -void -KGreeter::putSession( const TQString &type, const TQString &name, bool hid, const char *exe ) -{ - int prio = exe ? (!strcmp( exe, "default" ) ? 0 : - !strcmp( exe, "failsafe" ) ? 3 : 2) : 2; - for (uint i = 0; i < sessionTypes.size(); i++) - if (sessionTypes[i].type == type) { - sessionTypes[i].prio = prio; - return; - } - sessionTypes.append( SessType( name, type, hid, prio ) ); -} - -void -KGreeter::insertSessions() -{ - for (char **dit = _sessionsDirs; *dit; ++dit) { - TQStringList ents = TQDir( *dit ).entryList(); - for (TQStringList::ConstIterator it = ents.begin(); it != ents.end(); ++it) - if ((*it).endsWith( ".desktop" ) && !(*it).endsWith("admin.desktop")) { - KSimpleConfig dsk( TQString( *dit ).append( '/' ).append( *it ) ); - dsk.setGroup( "Desktop Entry" ); - putSession( (*it).left( (*it).length() - 8 ), - dsk.readEntry( "Name" ), - (dsk.readBoolEntry( "Hidden", false ) || - (dsk.hasKey( "TryExec" ) && - KStandardDirs::findExe( dsk.readEntry( "TryExec" ) ).isEmpty())), - dsk.readEntry( "Exec" ).latin1() ); - } - } - putSession( "default", i18n("Default"), false, "default" ); - putSession( "failsafe", i18n("Failsafe"), false, "failsafe" ); - qBubbleSort( sessionTypes ); - for (uint i = 0; i < sessionTypes.size() && !sessionTypes[i].hid; i++) { - sessMenu->insertItem( sessionTypes[i].name, i ); - switch (sessionTypes[i].prio) { - case 0: case 1: nSpecials++; break; - case 2: nNormals++; break; - } - } -} - -void -KGreeter::slotUserEntered() -{ - if (userView) { - TQListViewItem *item; - for (item = userView->firstChild(); item; item = item->nextSibling()) - if (((UserListViewItem *)item)->login == curUser) { - userView->setSelected( item, true ); - userView->ensureItemVisible( item ); - goto oke; - } - userView->clearSelection(); - } - oke: - if (isVisible()) - slotLoadPrevWM(); - else - TQTimer::singleShot( 0, this, TQT_SLOT(slotLoadPrevWM()) ); -} - -void -KGreeter::slotUserClicked( TQListViewItem *item ) -{ - if (item) { - curUser = ((UserListViewItem *)item)->login; - verify->setUser( curUser ); - slotLoadPrevWM(); - } -} - -void -KGreeter::slotSessionSelected( int id ) -{ - if (id != curSel) { - sessMenu->setItemChecked( curSel, false ); - sessMenu->setItemChecked( id, true ); - curSel = id; - verify->gplugActivity(); - } -} - -void -KGreeter::reject() -{ - verify->reject(); -} - -void -KGreeter::accept() -{ - if (userView && userView->hasFocus()) - slotUserClicked( userView->currentItem() ); - else - verify->accept(); -} - -void // private -KGreeter::setPrevWM( int wm ) -{ - if (curPrev != wm) { - if (curPrev != -1) - sessMenu->changeItem( curPrev, sessionTypes[curPrev].name ); - if (wm != -1) - sessMenu->changeItem( wm, sessionTypes[wm].name + i18n(" (previous)") ); - curPrev = wm; - } -} - -void -KGreeter::slotLoadPrevWM() -{ - int len, i, b; - unsigned long crc, by; - TQCString name; - char *sess; - - if (verify->coreLock) { - needLoad = true; - return; - } - needLoad = false; - - prevValid = true; - name = curUser.local8Bit(); - GSendInt( G_ReadDmrc ); - GSendStr( name.data() ); - GRecvInt(); // ignore status code ... - if ((len = name.length())) { - GSendInt( G_GetDmrc ); - GSendStr( "Session" ); - sess = GRecvStr(); - if (!sess) { /* no such user */ - if (!userView && !userList) { // don't fake if user list shown - prevValid = false; - /* simple crc32 */ - for (crc = _forgingSeed, i = 0; i < len; i++) { - by = (crc & 255) ^ name[i]; - for (b = 0; b < 8; b++) - by = (by >> 1) ^ (-(by & 1) & 0xedb88320); - crc = (crc >> 8) ^ by; - } - /* forge a session with this hash - default & custom more probable */ - /* XXX - this should do a statistical analysis of the real users */ -#if 1 - setPrevWM( crc % (nSpecials * 2 + nNormals) % (nSpecials + nNormals) ); -#else - i = crc % (nSpecials * 2 + nNormals); - if (i < nNormals) - setPrevWM( i + nSpecials ); - else - setPrevWM( (i - nNormals) / 2 ); -#endif - return; - } - } else { - if (!strcmp(sess, "admin")) { - // need to get the original - GSendInt( G_GetDmrc); - GSendStr( "OrigSession"); - sess = GRecvStr(); - if (!sess) { - free(sess); - sess = strdup("default"); - } - } - - for (uint i = 0; i < sessionTypes.count() && !sessionTypes[i].hid; i++) - if (sessionTypes[i].type == sess) { - free( sess ); - setPrevWM( i ); - return; - } - if (curSel == -1) - MsgBox( sorrybox, i18n("Your saved session type '%1' is not valid any more.\n" - "Please select a new one, otherwise 'default' will be used.").arg( sess ) ); - free( sess ); - prevValid = false; - } - } - setPrevWM( -1 ); -} - -void // protected -KGreeter::pluginSetup() -{ - int field = 0; - TQString ent, pn( verify->pluginName() ), dn( dName + '_' + pn ); - - if (_preselUser != PRESEL_PREV) - stsFile->deleteEntry( verify->entitiesLocal() ? dName : dn, false ); - if (_preselUser != PRESEL_NONE && verify->entityPresettable()) { - if (verify->entitiesLocal()) - ent = _preselUser == PRESEL_PREV ? - stsFile->readEntry( dName ) : _defaultUser; - else - ent = _preselUser == PRESEL_PREV ? - stsFile->readEntry( dn ) : - verify->getConf( 0, (pn + ".DefaultEntity").latin1(), TQVariant() ).toString(); - field = verify->entitiesFielded() ? - verify->getConf( 0, (pn + ".FocusField").latin1(), TQVariant( 0 ) ).toInt() : - _focusPasswd; - } - verify->presetEntity( ent, field ); - if (userList) - verify->loadUsers( *userList ); -} - -void -KGreeter::verifyPluginChanged( int id ) -{ - curPlugin = id; - pluginSetup(); -} - -void -KGreeter::verifyClear() -{ - curUser = TQString::null; - slotUserEntered(); - slotSessionSelected( -1 ); -} - -void -KGreeter::verifyOk() -{ - if (_preselUser == PRESEL_PREV && verify->entityPresettable()) - stsFile->writeEntry( verify->entitiesLocal() ? - dName : - dName + '_' + verify->pluginName(), - verify->getEntity() ); - if (curSel != -1) { - GSendInt( G_PutDmrc ); - GSendStr( "Session" ); - GSendStr( sessionTypes[curSel].type.utf8() ); - } else if (!prevValid) { - GSendInt( G_PutDmrc ); - GSendStr( "Session" ); - GSendStr( "default" ); - } - GSendInt( G_Ready ); - closingDown = true; - done( ex_exit ); -} - -void -KGreeter::verifyFailed() -{ - if (needLoad) - slotLoadPrevWM(); -} - -void -KGreeter::verifySetUser( const TQString &user ) -{ - curUser = user; - slotUserEntered(); -} - -KStdGreeter::KStdGreeter() - : KGreeter() - , clock( 0 ) - , pixLabel( 0 ) -{ - TQBoxLayout *main_box; -#ifdef WITH_TDM_XCONSOLE - if (consoleView) { - TQBoxLayout *ex_box = new TQVBoxLayout( this, 10, 10 ); - main_box = new TQHBoxLayout( ex_box, 10 ); - ex_box->addWidget( consoleView ); - } else -#endif - main_box = new TQHBoxLayout( this, 10, 10 ); - - if (userView) - main_box->addWidget( userView ); - - TQBoxLayout *inner_box = new TQVBoxLayout( main_box, 10 ); - - if (!_authorized && _authComplain) { - TQLabel *complainLabel = new TQLabel( - i18n("Warning: this is an unsecured session"), this ); - TQToolTip::add( complainLabel, - i18n("This display requires no X authorization.\n" - "This means that anybody can connect to it,\n" - "open windows on it or intercept your input.") ); - complainLabel->setAlignment( AlignCenter ); - complainLabel->setFont( _failFont ); - complainLabel->setPaletteForegroundColor( Qt::red ); - inner_box->addWidget( complainLabel ); - } - if (!_greetString.isEmpty()) { - TQLabel *welcomeLabel = new TQLabel( _greetString, this ); - welcomeLabel->setAlignment( AlignCenter ); - welcomeLabel->setFont( _greetFont ); - inner_box->addWidget( welcomeLabel ); - } - - switch (_logoArea) { - case LOGO_CLOCK: - clock = new KdmClock( this, "clock" ); - break; - case LOGO_LOGO: - { - TQMovie movie( _logo ); - kapp->eventLoop()->processEvents( TQEventLoop::ExcludeUserInput | TQEventLoop::ExcludeSocketNotifiers, 100 ); - TQPixmap pixmap; - if (!movie.framePixmap().isNull() || pixmap.load( _logo )) { - pixLabel = new TQLabel( this ); - if (!movie.framePixmap().isNull()) { - pixLabel->setMovie( movie ); - if (!movie.framePixmap().hasAlpha()) - pixLabel->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); - } else { - pixLabel->setPixmap( pixmap ); - if (!pixmap.hasAlpha()) - pixLabel->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); - } - pixLabel->setIndent( 0 ); - } - } - break; - } - - if (userView) { - if (clock) - inner_box->addWidget( clock, 0, AlignCenter ); - else if (pixLabel) - inner_box->addWidget( pixLabel, 0, AlignCenter ); - } else { - if (clock) - main_box->addWidget( clock, 0, AlignCenter ); - else if (pixLabel) - main_box->addWidget( pixLabel, 0, AlignCenter ); - } - - goButton = new TQPushButton( i18n("L&ogin"), this ); - goButton->setDefault( true ); - connect( goButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); - menuButton = new TQPushButton( i18n("&Menu"), this ); - //helpButton - - TQWidget *prec; - if (userView) - prec = userView; -#ifdef WITH_TDM_XCONSOLE - else if (consoleView) - prec = consoleView; -#endif - else - prec = menuButton; - KGStdVerify *sverify = - new KGStdVerify( this, this, prec, TQString::null, - pluginList, KGreeterPlugin::Authenticate, - KGreeterPlugin::Login ); - inner_box->addLayout( sverify->getLayout() ); - TQPopupMenu *plugMenu = sverify->getPlugMenu(); - sverify->selectPlugin( curPlugin ); - verify = sverify; - - inner_box->addWidget( new KSeparator( KSeparator::HLine, this ) ); - - TQBoxLayout *hbox2 = new TQHBoxLayout( inner_box, 10 ); - hbox2->addWidget( goButton ); - hbox2->addStretch( 1 ); - hbox2->addWidget( menuButton ); - hbox2->addStretch( 1 ); - - if (sessMenu->count() > 1) { - inserten( i18n("Session &Type"), 0, sessMenu ); - needSep = true; - } - - if (plugMenu) { - inserten( i18n("&Authentication Method"), 0, plugMenu ); - needSep = true; - } - -#ifdef XDMCP - completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), 0 ); -#else - completeMenu(); -#endif - - if (userView || userList) - insertUsers(); - - if (optMenu) - menuButton->setPopup( optMenu ); - else - menuButton->hide(); - - pluginSetup(); - - verify->start(); -} - -void -KStdGreeter::pluginSetup() -{ - inherited::pluginSetup(); - if (userView) { - if (verify->entitiesLocal() && verify->entityPresettable()) - userView->show(); - else - userView->hide(); - } - adjustGeometry(); - update(); -} - -void -KStdGreeter::verifyFailed() -{ - goButton->setEnabled( false ); - menuButton->setEnabled( false ); - if (userView) - userView->setEnabled( false ); - inherited::verifyFailed(); -} - -void -KStdGreeter::verifyRetry() -{ - goButton->setEnabled( true ); - menuButton->setEnabled( true ); - if (userView) - userView->setEnabled( true ); -} - - -KThemedGreeter::KThemedGreeter() - : KGreeter( true ) - , themer( 0 ) -// , clock( 0 ) -{ - // We do all painting ourselves - setBackgroundMode( NoBackground ); - // Allow tracking the mouse position - setMouseTracking( true ); - - adjustGeometry(); - - themer = new KdmThemer( _theme, "console", this ); - if (!themer->isOK()) { - delete themer; - themer = 0; - return; - } - - connect( themer, TQT_SIGNAL(activated( const TQString & )), - TQT_SLOT(slotThemeActivated( const TQString & )) ); - - console_rect = themer->findNode( "xconsole" ); // tdm ext - userlist_rect = themer->findNode( "userlist" ); - caps_warning = themer->findNode( "caps-lock-warning" ); - xauth_warning = themer->findNode( "xauth-warning" ); // tdm ext - pam_error = themer->findNode( "pam-error" ); - timed_label = themer->findNode( "timed-label" ); - if (pam_error && pam_error->isA( "KdmLabel" )) - static_cast(pam_error)->setText( i18n("Login Failed.") ); - - KdmItem *itm; - if ((itm = themer->findNode( "pam-message" ))) // done via msgboxes - itm->hide( true ); - if ((itm = themer->findNode( "language_button" ))) // not implemented yet - itm->hide( true ); - -#ifdef WITH_TDM_XCONSOLE - if (console_rect) { - if (consoleView) - console_rect->setWidget( consoleView ); - else - console_rect->hide( true ); - } -#endif - - if (xauth_warning && (_authorized || !_authComplain)) - xauth_warning->hide( true ); - - if (userView || userList) - insertUsers( 7 ); // TODO: find out how many are a good value - -// if (!_greetString.isEmpty()) { -// } -// clock = new KdmClock( this, "clock" ); - - TQWidget *prec; - if (userView) - prec = userView; -#ifdef WITH_TDM_XCONSOLE - else if (consoleView) - prec = consoleView; -#endif - else - prec = 0; - KGThemedVerify *tverify = - new KGThemedVerify( this, themer, this, prec, TQString::null, - pluginList, KGreeterPlugin::Authenticate, - KGreeterPlugin::Login ); - TQPopupMenu *plugMenu = tverify->getPlugMenu(); - tverify->selectPlugin( curPlugin ); - verify = tverify; - - session_button = 0; - if ((itm = themer->findNode( "session_button" ))) { - if (sessMenu->count() <= 1) - itm->hide( true ); - else - session_button = itm; - } else { - if (sessMenu->count() > 1) { - inserten( i18n("Session &Type"), ALT+Key_T, sessMenu ); - needSep = true; - } - } - - admin_button = themer->findNode( "admin_button"); - if ( admin_button ) { - if ( !_useAdminSession ) - admin_button->hide( true ); - } - - if (plugMenu) { - inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu ); - needSep = true; - } - -#ifdef XDMCP - completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), ALT+Key_R ); -#else - completeMenu(); -#endif - - system_button = themer->findNode( "system_button" ); - TQAccel *accel = new TQAccel( this ); - accel->insertItem( ALT+Key_M, 0 ); - connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotActionMenu()) ); - - pluginSetup(); - - verify->start(); -} - -bool -KThemedGreeter::event( TQEvent *e ) -{ - if (themer) - themer->widgetEvent( e ); - return inherited::event( e ); -} - -void -KThemedGreeter::pluginSetup() -{ - inherited::pluginSetup(); - - if (userView && verify->entitiesLocal() && verify->entityPresettable() && userlist_rect) { -// userView->setMaximumHeight( userView->sumHeight() ); - userlist_rect->setWidget( userView ); - } else { - if (userView) - userView->hide(); - if (userlist_rect) - userlist_rect->hide( true ); - } - - update(); -} - -void -KThemedGreeter::verifyFailed() -{ -// goButton->setEnabled( false ); - inherited::verifyFailed(); - if (userView) - userView->setEnabled(false); -} - -void -KThemedGreeter::verifyRetry() -{ -// goButton->setEnabled( true ); - if (userView) - userView->setEnabled(true); - -} - -TQString KThemedGreeter::timedUser = TQString::null; -int KThemedGreeter::timedDelay = -1; - -void -KThemedGreeter::updateStatus( bool fail, bool caps, int timedleft ) -{ - if (pam_error) { - if (fail) - pam_error->show( true ); - else - pam_error->hide( true ); - } - if (caps_warning) { - if (caps) - caps_warning->show( true ); - else - caps_warning->hide( true ); - } - if (timed_label) { - if (timedleft) { - if (timedleft != timedDelay) { - timedDelay = timedleft; - timedUser = curUser; - timed_label->show( true ); - timed_label->update(); - } - } else { - timedDelay = -1; - timed_label->hide( true ); - } - } -} - -void -KThemedGreeter::slotThemeActivated( const TQString &id ) -{ - if (id == "login_button") - accept(); - else if (id == "session_button") - slotSessMenu(); - else if (id == "system_button") - slotActionMenu(); - else if (id == "admin_button") - slotAskAdminPassword(); -} - -void -KThemedGreeter::slotSessMenu() -{ - sessMenu->popup( mapToGlobal( session_button->rect().center() ) ); -} - -void -KThemedGreeter::slotActionMenu() -{ - if (system_button) - optMenu->popup( mapToGlobal( system_button->rect().center() ) ); - else - optMenu->popup( mapToGlobal( rect().center() ) ); -} - -void -KThemedGreeter::keyPressEvent( TQKeyEvent *e ) -{ - inherited::keyPressEvent( e ); - if (!(e->state() & KeyButtonMask) && - (e->key() == Key_Return || e->key() == Key_Enter)) - accept(); -} - -void -KThemedGreeter::slotAskAdminPassword() -{ - TDMAdmin k(curUser, this); - if (k.exec()) { - GSendInt(G_Ready); - hide(); - closingDown = true; - done(ex_exit); - } -} - -#include "kgreeter.moc" diff --git a/kdm/kfrontend/kgreeter.h b/kdm/kfrontend/kgreeter.h deleted file mode 100644 index 0de48a21d..000000000 --- a/kdm/kfrontend/kgreeter.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - -Greeter widget for tdm - -Copyright (C) 1997, 1998 Steffen Hansen -Copyright (C) 2000-2004 Oswald Buddenhagen - - -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. - -*/ - - -#ifndef KGREETER_H -#define KGREETER_H - -#include "kgverify.h" -#include "kgdialog.h" - -class KdmClock; -class UserListView; -class KdmThemer; -class KdmItem; - -class KListView; -class KSimpleConfig; - -class TQLabel; -class TQPushButton; -class TQPopupMenu; -class TQListViewItem; - -struct SessType { - TQString name, type; - bool hid; - int prio; - - SessType() {} - SessType( const TQString &n, const TQString &t, bool h, int p ) : - name( n ), type( t ), hid( h ), prio( p ) {} - bool operator<( const SessType &st ) { - return hid != st.hid ? hid < st.hid : - prio != st.prio ? prio < st.prio : - name < st.name; - } -}; - -class KGreeter : public KGDialog, public KGVerifyHandler { - Q_OBJECT - typedef KGDialog inherited; - - public: - KGreeter( bool themed = false ); - ~KGreeter(); - - public slots: - void accept(); - void reject(); - void done(int r); - void slotUserClicked( TQListViewItem * ); - void slotSessionSelected( int ); - void slotUserEntered(); - void handleInputPipe(); - - public: - TQString curUser, dName; - - protected: - void readFacesList(); - void installUserList(); - void insertUser( const TQImage &, const TQString &, struct passwd * ); - void insertUsers( int limit = -1); - void putSession( const TQString &, const TQString &, bool, const char * ); - void insertSessions(); - virtual void pluginSetup(); - void setPrevWM( int ); - - KSimpleConfig *stsFile; - UserListView *userView; - TQStringList *userList; - TQPopupMenu *sessMenu; - TQValueVector sessionTypes; - TQStringList randomFaces; - TQMap randomFacesMap; - int nNormals, nSpecials; - int curPrev, curSel; - bool prevValid; - bool needLoad; - bool themed; - - static int curPlugin; - static PluginList pluginList; - - private slots: - void slotLoadPrevWM(); - - private: - int mPipe_fd; - TQString mPipeFilename; - - protected: - bool closingDown; - - public: // from KGVerifyHandler - virtual void verifyPluginChanged( int id ); - virtual void verifyClear(); - virtual void verifyOk(); - virtual void verifyFailed(); -// virtual void verifyRetry(); - virtual void verifySetUser( const TQString &user ); -}; - -class KStdGreeter : public KGreeter { - Q_OBJECT - typedef KGreeter inherited; - - public: - KStdGreeter(); - - protected: - virtual void pluginSetup(); - - private: - KdmClock *clock; - TQLabel *pixLabel; - TQPushButton *goButton; - TQPushButton *menuButton; - - public: // from KGVerifyHandler - virtual void verifyFailed(); - virtual void verifyRetry(); -}; - -class KThemedGreeter : public KGreeter { - Q_OBJECT - typedef KGreeter inherited; - - public: - KThemedGreeter(); - bool isOK() { return themer != 0; } - static TQString timedUser; - static int timedDelay; - - public slots: - void slotThemeActivated( const TQString &id ); - void slotSessMenu(); - void slotActionMenu(); - void slotAskAdminPassword(); - - protected: - virtual void updateStatus( bool fail, bool caps, int timedleft ); - virtual void pluginSetup(); - virtual void keyPressEvent( TQKeyEvent * ); - virtual bool event( TQEvent *e ); - - private: -// KdmClock *clock; - KdmThemer *themer; - KdmItem *caps_warning, *xauth_warning, *pam_error, *timed_label, - *console_rect, *userlist_rect, - *session_button, *system_button, *admin_button; - - public: // from KGVerifyHandler - virtual void verifyFailed(); - virtual void verifyRetry(); -}; - -#endif /* KGREETER_H */ diff --git a/kdm/kfrontend/kgverify.cpp b/kdm/kfrontend/kgverify.cpp deleted file mode 100644 index ec0bfae6c..000000000 --- a/kdm/kfrontend/kgverify.cpp +++ /dev/null @@ -1,1218 +0,0 @@ -/* - -Shell for tdm conversation plugins - -Copyright (C) 1997, 1998, 2000 Steffen Hansen -Copyright (C) 2000-2004 Oswald Buddenhagen - - -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 - -#include "kgverify.h" -#include "tdmconfig.h" -#include "tdm_greet.h" - -#include "themer/tdmthemer.h" -#include "themer/tdmitem.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include // for updateLockStatus() -#include // ... and make eventFilter() work again - -#define FULL_GREET_TO 40 // normal inactivity timeout -#define TIMED_GREET_TO 20 // inactivity timeout when persisting timed login -#define MIN_TIMED_TO 5 // minimal timed login delay -#define DEAD_TIMED_TO 2 // dead time after re-activating timed login -#define SECONDS 1000 // reduce to 100 to speed up testing - -void KGVerifyHandler::verifyClear() -{ -} - -void KGVerifyHandler::updateStatus( bool, bool, int ) -{ -} - -KGVerify::KGVerify( KGVerifyHandler *_handler, KdmThemer *_themer, - TQWidget *_parent, TQWidget *_predecessor, - const TQString &_fixedUser, - const PluginList &_pluginList, - KGreeterPlugin::Function _func, - KGreeterPlugin::Context _ctx ) - : inherited() - , coreLock( 0 ) - , fixedEntity( _fixedUser ) - , pluginList( _pluginList ) - , handler( _handler ) - , themer( _themer ) - , parent( _parent ) - , predecessor( _predecessor ) - , plugMenu( 0 ) - , curPlugin( -1 ) - , timedLeft( 0 ) - , func( _func ) - , ctx( _ctx ) - , enabled( true ) - , running( false ) - , suspended( false ) - , failed( false ) - , isClear( true ) -{ - connect( &timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeout()) ); - connect( kapp, TQT_SIGNAL(activity()), TQT_SLOT(slotActivity()) ); - - _parent->installEventFilter( this ); -} - -KGVerify::~KGVerify() -{ - Debug( "delete %s\n", pName.data() ); - delete greet; -} - -TQPopupMenu * -KGVerify::getPlugMenu() -{ - // assert( !cont ); - if (!plugMenu) { - uint np = pluginList.count(); - if (np > 1) { - plugMenu = new TQPopupMenu( parent ); - connect( plugMenu, TQT_SIGNAL(activated( int )), - TQT_SLOT(slotPluginSelected( int )) ); - for (uint i = 0; i < np; i++) - plugMenu->insertItem( i18n(greetPlugins[pluginList[i]].info->name), pluginList[i] ); - } - } - return plugMenu; -} - -bool // public -KGVerify::entitiesLocal() const -{ - return greetPlugins[pluginList[curPlugin]].info->flags & kgreeterplugin_info::Local; -} - -bool // public -KGVerify::entitiesFielded() const -{ - return greetPlugins[pluginList[curPlugin]].info->flags & kgreeterplugin_info::Fielded; -} - -bool // public -KGVerify::entityPresettable() const -{ - return greetPlugins[pluginList[curPlugin]].info->flags & kgreeterplugin_info::Presettable; -} - -bool // public -KGVerify::isClassic() const -{ - return !strcmp( greetPlugins[pluginList[curPlugin]].info->method, "classic" ); -} - -TQString // public -KGVerify::pluginName() const -{ - TQString name( greetPlugins[pluginList[curPlugin]].library->fileName() ); - uint st = name.findRev( '/' ) + 1; - uint en = name.find( '.', st ); - if (en - st > 7 && TQConstString( name.unicode() + st, 7 ).string() == "kgreet_") - st += 7; - return name.mid( st, en - st ); -} - -static void -showWidgets( TQLayoutItem *li ) -{ - TQWidget *w; - TQLayout *l; - - if ((w = li->widget())) - w->show(); - else if ((l = li->layout())) { - TQLayoutIterator it = l->iterator(); - for (TQLayoutItem *itm = it.current(); itm; itm = ++it) - showWidgets( itm ); - } -} - -void // public -KGVerify::selectPlugin( int id ) -{ - if (pluginList.isEmpty()) { - MsgBox( errorbox, i18n("No greeter widget plugin loaded. Check the configuration.") ); - ::exit( EX_UNMANAGE_DPY ); - } - curPlugin = id; - if (plugMenu) - plugMenu->setItemChecked( id, true ); - pName = ("greet_" + pluginName()).latin1(); - Debug( "new %s\n", pName.data() ); - greet = greetPlugins[pluginList[id]].info->create( this, themer, parent, predecessor, fixedEntity, func, ctx ); - timeable = _autoLoginDelay && entityPresettable() && isClassic(); -} - -void // public -KGVerify::loadUsers( const TQStringList &users ) -{ - Debug( "%s->loadUsers(...)\n", pName.data() ); - greet->loadUsers( users ); -} - -void // public -KGVerify::presetEntity( const TQString &entity, int field ) -{ - presEnt = entity; - presFld = field; -} - -bool // private -KGVerify::applyPreset() -{ - if (!presEnt.isEmpty()) { - Debug( "%s->presetEntity(%\"s, %d)\n", pName.data(), - presEnt.latin1(), presFld ); - greet->presetEntity( presEnt, presFld ); - if (entitiesLocal()) { - curUser = presEnt; - handler->verifySetUser( presEnt ); - } - return true; - } - return false; -} - -bool // private -KGVerify::scheduleAutoLogin( bool initial ) -{ - if (timeable) { - Debug( "%s->presetEntity(%\"s, -1)\n", pName.data(), - _autoLoginUser.latin1(), -1 ); - greet->presetEntity( _autoLoginUser, -1 ); - curUser = _autoLoginUser; - handler->verifySetUser( _autoLoginUser ); - timer.start( 1000 ); - if (initial) { - timedLeft = _autoLoginDelay; - deadTicks = 0; - } else { - timedLeft = QMAX( _autoLoginDelay - TIMED_GREET_TO, MIN_TIMED_TO ); - deadTicks = DEAD_TIMED_TO; - } - updateStatus(); - running = false; - isClear = true; - return true; - } - return false; -} - -void // private -KGVerify::performAutoLogin() -{ -// timer.stop(); - GSendInt( G_AutoLogin ); - handleVerify(); -} - -TQString // public -KGVerify::getEntity() const -{ - Debug( "%s->getEntity()\n", pName.data() ); - TQString ent = greet->getEntity(); - Debug( " entity: %s\n", ent.latin1() ); - return ent; -} - -void -KGVerify::setUser( const TQString &user ) -{ - // assert( fixedEntity.isEmpty() ); - curUser = user; - Debug( "%s->setUser(%\"s)\n", pName.data(), user.latin1() ); - greet->setUser( user ); - gplugActivity(); -} - -void -KGVerify::setPassword( const TQString &pass ) -{ - greet->setPassword( pass ); - gplugActivity(); -} - -void -KGVerify::start() -{ - authTok = (func == KGreeterPlugin::ChAuthTok); - cont = false; - if (func == KGreeterPlugin::Authenticate && ctx == KGreeterPlugin::Login) { - if (scheduleAutoLogin( true )) { - if (!_autoLoginAgain) - _autoLoginDelay = 0, timeable = false; - return; - } else - applyPreset(); - } - running = true; - Debug( "%s->start()\n", pName.data() ); - greet->start(); - if (!(func == KGreeterPlugin::Authenticate || - ctx == KGreeterPlugin::ChangeTok || - ctx == KGreeterPlugin::ExChangeTok)) - { - cont = true; - handleVerify(); - } -} - -void -KGVerify::abort() -{ - Debug( "%s->abort()\n", pName.data() ); - greet->abort(); - running = false; -} - -void -KGVerify::suspend() -{ - // assert( !cont ); - if (running) { - Debug( "%s->abort()\n", pName.data() ); - greet->abort(); - } - suspended = true; - updateStatus(); - timer.suspend(); -} - -void -KGVerify::resume() -{ - timer.resume(); - suspended = false; - updateLockStatus(); - if (running) { - Debug( "%s->start()\n", pName.data() ); - greet->start(); - } else if (delayed) { - delayed = false; - running = true; - Debug( "%s->start()\n", pName.data() ); - greet->start(); - } -} - -void // not a slot - called manually by greeter -KGVerify::accept() -{ - Debug( "%s->next()\n", pName.data() ); - greet->next(); -} - -void // private -KGVerify::doReject( bool initial ) -{ - // assert( !cont ); - if (running) { - Debug( "%s->abort()\n", pName.data() ); - greet->abort(); - } - handler->verifyClear(); - Debug( "%s->clear()\n", pName.data() ); - greet->clear(); - curUser = TQString::null; - if (!scheduleAutoLogin( initial )) { - isClear = !(isClear && applyPreset()); - if (running) { - Debug( "%s->start()\n", pName.data() ); - greet->start(); - } - if (!failed) - timer.stop(); - } -} - -void // not a slot - called manually by greeter -KGVerify::reject() -{ - doReject( true ); -} - -void -KGVerify::setEnabled( bool on ) -{ - Debug( "%s->setEnabled(%s)\n", pName.data(), on ? "true" : "false" ); - greet->setEnabled( on ); - enabled = on; - updateStatus(); -} - -void // private -KGVerify::slotTimeout() -{ - if (failed) { - failed = false; - updateStatus(); - Debug( "%s->revive()\n", pName.data() ); - greet->revive(); - handler->verifyRetry(); - if (suspended) - delayed = true; - else { - running = true; - Debug( "%s->start()\n", pName.data() ); - greet->start(); - slotActivity(); - gplugActivity(); - if (cont) - handleVerify(); - } - } else if (timedLeft) { - deadTicks--; - if (!--timedLeft) - performAutoLogin(); - else - timer.start( 1000 ); - updateStatus(); - } else { - // assert( ctx == Login ); - isClear = true; - doReject( false ); - } -} - -void -KGVerify::slotActivity() -{ - if (timedLeft) { - Debug( "%s->revive()\n", pName.data() ); - greet->revive(); - Debug( "%s->start()\n", pName.data() ); - greet->start(); - running = true; - timedLeft = 0; - updateStatus(); - timer.start( TIMED_GREET_TO * SECONDS ); - } else if (timeable) - timer.start( TIMED_GREET_TO * SECONDS ); -} - - -void // private static -KGVerify::VMsgBox( TQWidget *parent, const TQString &user, - TQMessageBox::Icon type, const TQString &mesg ) -{ - FDialog::box( parent, type, user.isEmpty() ? - mesg : i18n("Authenticating %1...\n\n").arg( user ) + mesg ); -} - -static const char *msgs[]= { - I18N_NOOP( "You are required to change your password immediately (password aged)." ), - I18N_NOOP( "You are required to change your password immediately (root enforced)." ), - I18N_NOOP( "You are not allowed to login at the moment." ), - I18N_NOOP( "Home folder not available." ), - I18N_NOOP( "Logins are not allowed at the moment.\nTry again later." ), - I18N_NOOP( "Your login shell is not listed in /etc/shells." ), - I18N_NOOP( "Root logins are not allowed." ), - I18N_NOOP( "Your account has expired; please contact your system administrator." ) -}; - -void // private static -KGVerify::VErrBox( TQWidget *parent, const TQString &user, const char *msg ) -{ - TQMessageBox::Icon icon; - TQString mesg; - - if (!msg) { - mesg = i18n("A critical error occurred.\n" - "Please look at TDM's logfile(s) for more information\n" - "or contact your system administrator."); - icon = errorbox; - } else { - mesg = TQString::fromLocal8Bit( msg ); - TQString mesg1 = mesg + '.'; - for (uint i = 0; i < as(msgs); i++) - if (mesg1 == msgs[i]) { - mesg = i18n(msgs[i]); - break; - } - icon = sorrybox; - } - VMsgBox( parent, user, icon, mesg ); -} - -void // private static -KGVerify::VInfoBox( TQWidget *parent, const TQString &user, const char *msg ) -{ - TQString mesg = TQString::fromLocal8Bit( msg ); - TQRegExp rx( "^Warning: your account will expire in (\\d+) day" ); - if (rx.search( mesg ) >= 0) { - int expire = rx.cap( 1 ).toInt(); - mesg = expire ? - i18n("Your account expires tomorrow.", - "Your account expires in %n days.", expire) : - i18n("Your account expires today."); - } else { - rx.setPattern( "^Warning: your password will expire in (\\d+) day" ); - if (rx.search( mesg ) >= 0) { - int expire = rx.cap( 1 ).toInt(); - mesg = expire ? - i18n("Your password expires tomorrow.", - "Your password expires in %n days.", expire) : - i18n("Your password expires today."); - } - } - VMsgBox( parent, user, infobox, mesg ); -} - -bool // public static -KGVerify::handleFailVerify( TQWidget *parent ) -{ - Debug( "handleFailVerify ...\n" ); - char *msg = GRecvStr(); - TQString user = TQString::fromLocal8Bit( msg ); - free( msg ); - - for (;;) { - int ret = GRecvInt(); - - // non-terminal status - switch (ret) { - /* case V_PUT_USER: cannot happen - we are in "classic" mode */ - /* case V_PRE_OK: cannot happen - not in ChTok dialog */ - /* case V_CHTOK: cannot happen - called by non-interactive verify */ - case V_CHTOK_AUTH: - Debug( " V_CHTOK_AUTH\n" ); - { - TQStringList pgs( _pluginsLogin ); - pgs += _pluginsShutdown; - TQStringList::ConstIterator it; - for (it = pgs.begin(); it != pgs.end(); ++it) - if (*it == "classic" || *it == "modern") { - pgs = *it; - goto gotit; - } else if (*it == "generic") { - pgs = "modern"; - goto gotit; - } - pgs = "classic"; - gotit: - KGChTok chtok( parent, user, init( pgs ), 0, - KGreeterPlugin::AuthChAuthTok, - KGreeterPlugin::Login ); - return chtok.exec(); - } - case V_MSG_ERR: - Debug( " V_MSG_ERR\n" ); - msg = GRecvStr(); - Debug( " message %\"s\n", msg ); - VErrBox( parent, user, msg ); - if (msg) - free( msg ); - continue; - case V_MSG_INFO: - Debug( " V_MSG_INFO\n" ); - msg = GRecvStr(); - Debug( " message %\"s\n", msg ); - VInfoBox( parent, user, msg ); - free( msg ); - continue; - } - - // terminal status - switch (ret) { - case V_OK: - Debug( " V_OK\n" ); - return true; - case V_AUTH: - Debug( " V_AUTH\n" ); - VMsgBox( parent, user, sorrybox, i18n("Authentication failed") ); - return false; - case V_FAIL: - Debug( " V_FAIL\n" ); - return false; - default: - LogPanic( "Unknown V_xxx code %d from core\n", ret ); - } - } -} - -void // private -KGVerify::handleVerify() -{ - TQString user; - - Debug( "handleVerify ...\n" ); - for (;;) { - char *msg; - int ret, echo, ndelay; - KGreeterPlugin::Function nfunc; - - ret = GRecvInt(); - - // requests - coreLock = 1; - switch (ret) { - case V_GET_TEXT: - Debug( " V_GET_TEXT\n" ); - msg = GRecvStr(); - Debug( " prompt %\"s\n", msg ); - echo = GRecvInt(); - Debug( " echo = %d\n", echo ); - ndelay = GRecvInt(); - Debug( " ndelay = %d\n%s->textPrompt(...)\n", ndelay, pName.data() ); - greet->textPrompt( msg, echo, ndelay ); - if (msg) - free( msg ); - return; - case V_GET_BINARY: - Debug( " V_GET_BINARY\n" ); - msg = GRecvArr( &ret ); - Debug( " %d bytes prompt\n", ret ); - ndelay = GRecvInt(); - Debug( " ndelay = %d\n%s->binaryPrompt(...)\n", ndelay, pName.data() ); - greet->binaryPrompt( msg, ndelay ); - if (msg) - free( msg ); - return; - } - - // non-terminal status - coreLock = 2; - switch (ret) { - case V_PUT_USER: - Debug( " V_PUT_USER\n" ); - msg = GRecvStr(); - curUser = user = TQString::fromLocal8Bit( msg ); - // greet needs this to be able to return something useful from - // getEntity(). but the backend is still unable to tell a domain ... - Debug( " %s->setUser(%\"s)\n", pName.data(), user.latin1() ); - greet->setUser( curUser ); - handler->verifySetUser( curUser ); - if (msg) - free( msg ); - continue; - case V_PRE_OK: // this is only for func == AuthChAuthTok - Debug( " V_PRE_OK\n" ); - // With the "classic" method, the wrong user simply cannot be - // authenticated, even with the generic plugin. Other methods - // could do so, but this applies only to ctx == ChangeTok, which - // is not implemented yet. - authTok = true; - cont = true; - Debug( "%s->succeeded()\n", pName.data() ); - greet->succeeded(); - continue; - case V_CHTOK_AUTH: - Debug( " V_CHTOK_AUTH\n" ); - nfunc = KGreeterPlugin::AuthChAuthTok; - user = curUser; - goto dchtok; - case V_CHTOK: - Debug( " V_CHTOK\n" ); - nfunc = KGreeterPlugin::ChAuthTok; - user = TQString::null; - dchtok: - { - timer.stop(); - Debug( "%s->succeeded()\n", pName.data() ); - greet->succeeded(); - KGChTok chtok( parent, user, pluginList, curPlugin, nfunc, KGreeterPlugin::Login ); - if (!chtok.exec()) - goto retry; - handler->verifyOk(); - return; - } - case V_MSG_ERR: - Debug( " V_MSG_ERR\n" ); - msg = GRecvStr(); - Debug( " %s->textMessage(%\"s, true)\n", pName.data(), msg ); - if (!greet->textMessage( msg, true )) { - Debug( " message passed\n" ); - VErrBox( parent, user, msg ); - } else - Debug( " message swallowed\n" ); - if (msg) - free( msg ); - continue; - case V_MSG_INFO: - Debug( " V_MSG_INFO\n" ); - msg = GRecvStr(); - Debug( " %s->textMessage(%\"s, false)\n", pName.data(), msg ); - if (!greet->textMessage( msg, false )) { - Debug( " message passed\n" ); - VInfoBox( parent, user, msg ); - } else - Debug( " message swallowed\n" ); - free( msg ); - continue; - } - - // terminal status - coreLock = 0; - running = false; - timer.stop(); - - if (ret == V_OK) { - Debug( " V_OK\n" ); - if (!fixedEntity.isEmpty()) { - Debug( " %s->getEntity()\n", pName.data() ); - TQString ent = greet->getEntity(); - Debug( " entity %\"s\n", ent.latin1() ); - if (ent != fixedEntity) { - Debug( "%s->failed()\n", pName.data() ); - greet->failed(); - MsgBox( sorrybox, - i18n("Authenticated user (%1) does not match requested user (%2).\n") - .arg( ent ).arg( fixedEntity ) ); - goto retry; - } - } - Debug( "%s->succeeded()\n", pName.data() ); - greet->succeeded(); - handler->verifyOk(); - return; - } - - Debug( "%s->failed()\n", pName.data() ); - greet->failed(); - - if (ret == V_AUTH) { - Debug( " V_AUTH\n" ); - failed = true; - updateStatus(); - handler->verifyFailed(); - timer.start( 1500 + kapp->random()/(RAND_MAX/1000) ); - return; - } - if (ret != V_FAIL) - LogPanic( "Unknown V_xxx code %d from core\n", ret ); - Debug( " V_FAIL\n" ); - retry: - Debug( "%s->revive()\n", pName.data() ); - greet->revive(); - running = true; - Debug( "%s->start()\n", pName.data() ); - greet->start(); - if (!cont) - return; - user = TQString::null; - } -} - -void -KGVerify::gplugReturnText( const char *text, int tag ) -{ - Debug( "%s: gplugReturnText(%\"s, %d)\n", pName.data(), - tag & V_IS_SECRET ? "" : text, tag ); - GSendStr( text ); - if (text) { - GSendInt( tag ); - handleVerify(); - } else - coreLock = 0; -} - -void -KGVerify::gplugReturnBinary( const char *data ) -{ - if (data) { - unsigned const char *up = (unsigned const char *)data; - int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24); - Debug( "%s: gplugReturnBinary(%d bytes)\n", pName.data(), len ); - GSendArr( len, data ); - handleVerify(); - } else { - Debug( "%s: gplugReturnBinary(NULL)\n", pName.data() ); - GSendArr( 0, 0 ); - coreLock = 0; - } -} - -void -KGVerify::gplugSetUser( const TQString &user ) -{ - Debug( "%s: gplugSetUser(%\"s)\n", pName.data(), user.latin1() ); - curUser = user; - handler->verifySetUser( user ); -} - -void -KGVerify::gplugStart() -{ - // XXX handle func != Authenticate - Debug( "%s: gplugStart()\n", pName.data() ); - GSendInt( ctx == KGreeterPlugin::Shutdown ? G_VerifyRootOK : G_Verify ); - GSendStr( greetPlugins[pluginList[curPlugin]].info->method ); - handleVerify(); -} - -void -KGVerify::gplugActivity() -{ - Debug( "%s: gplugActivity()\n", pName.data() ); - if (func == KGreeterPlugin::Authenticate && - ctx == KGreeterPlugin::Login) - { - isClear = false; - if (!timeable) - timer.start( FULL_GREET_TO * SECONDS ); - } -} - -void -KGVerify::gplugMsgBox( TQMessageBox::Icon type, const TQString &text ) -{ - Debug( "%s: gplugMsgBox(%d, %\"s)\n", pName.data(), type, text.latin1() ); - MsgBox( type, text ); -} - -bool -KGVerify::eventFilter( TQObject *o, TQEvent *e ) -{ - switch (e->type()) { - case TQEvent::KeyPress: - if (timedLeft) { - TQKeyEvent *ke = (TQKeyEvent *)e; - if (ke->key() == Key_Return || ke->key() == Key_Enter) { - if (deadTicks <= 0) { - timedLeft = 0; - performAutoLogin(); - } - return true; - } - } - /* fall through */ - case TQEvent::KeyRelease: - updateLockStatus(); - /* fall through */ - default: - break; - } - return inherited::eventFilter( o, e ); -} - -void -KGVerify::updateLockStatus() -{ - unsigned int lmask; - Window dummy1, dummy2; - int dummy3, dummy4, dummy5, dummy6; - XQueryPointer( qt_xdisplay(), DefaultRootWindow( qt_xdisplay() ), - &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, - &lmask ); - capsLocked = lmask & LockMask; - updateStatus(); -} - -void -KGVerify::MsgBox( TQMessageBox::Icon typ, const TQString &msg ) -{ - timer.suspend(); - FDialog::box( parent, typ, msg ); - timer.resume(); -} - - -TQVariant // public static -KGVerify::getConf( void *, const char *key, const TQVariant &dflt ) -{ - if (!qstrcmp( key, "EchoMode" )) - return TQVariant( _echoMode ); - else { - TQString fkey = TQString::fromLatin1( key ) + '='; - for (TQStringList::ConstIterator it = _pluginOptions.begin(); - it != _pluginOptions.end(); ++it) - if ((*it).startsWith( fkey )) - return (*it).mid( fkey.length() ); - return dflt; - } -} - -TQValueVector KGVerify::greetPlugins; - -PluginList -KGVerify::init( const TQStringList &plugins ) -{ - PluginList pluginList; - - for (TQStringList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it) { - GreeterPluginHandle plugin; - TQString path = KLibLoader::self()->findLibrary( - ((*it)[0] == '/' ? *it : "kgreet_" + *it ).latin1() ); - if (path.isEmpty()) { - LogError( "GreeterPlugin %s does not exist\n", (*it).latin1() ); - continue; - } - uint i, np = greetPlugins.count(); - for (i = 0; i < np; i++) - if (greetPlugins[i].library->fileName() == path) - goto next; - if (!(plugin.library = KLibLoader::self()->library( path.latin1() ))) { - LogError( "Cannot load GreeterPlugin %s (%s)\n", (*it).latin1(), path.latin1() ); - continue; - } - if (!plugin.library->hasSymbol( "kgreeterplugin_info" )) { - LogError( "GreeterPlugin %s (%s) is no valid greet widget plugin\n", - (*it).latin1(), path.latin1() ); - plugin.library->unload(); - continue; - } - plugin.info = (kgreeterplugin_info*)plugin.library->symbol( "kgreeterplugin_info" ); - if (!plugin.info->init( TQString::null, getConf, 0 )) { - LogError( "GreeterPlugin %s (%s) refuses to serve\n", - (*it).latin1(), path.latin1() ); - plugin.library->unload(); - continue; - } - Debug( "GreeterPlugin %s (%s) loaded\n", (*it).latin1(), plugin.info->name ); - greetPlugins.append( plugin ); - next: - pluginList.append( i ); - } - return pluginList; -} - -void -KGVerify::done() -{ - for (uint i = 0; i < greetPlugins.count(); i++) { - if (greetPlugins[i].info->done) - greetPlugins[i].info->done(); - greetPlugins[i].library->unload(); - } -} - - -KGStdVerify::KGStdVerify( KGVerifyHandler *_handler, TQWidget *_parent, - TQWidget *_predecessor, const TQString &_fixedUser, - const PluginList &_pluginList, - KGreeterPlugin::Function _func, - KGreeterPlugin::Context _ctx ) - : inherited( _handler, 0, _parent, _predecessor, _fixedUser, - _pluginList, _func, _ctx ) - , failedLabelState( 0 ) -{ - grid = new TQGridLayout; - grid->setAlignment( AlignCenter ); - - failedLabel = new TQLabel( parent ); - failedLabel->setFont( _failFont ); - grid->addWidget( failedLabel, 1, 0, Qt::AlignCenter ); - - updateLockStatus(); -} - -KGStdVerify::~KGStdVerify() -{ - grid->removeItem( greet->getLayoutItem() ); -} - -void // public -KGStdVerify::selectPlugin( int id ) -{ - inherited::selectPlugin( id ); - grid->addItem( greet->getLayoutItem(), 0, 0 ); - showWidgets( greet->getLayoutItem() ); -} - -void // private slot -KGStdVerify::slotPluginSelected( int id ) -{ - if (failed) - return; - if (id != curPlugin) { - plugMenu->setItemChecked( curPlugin, false ); - parent->setUpdatesEnabled( false ); - grid->removeItem( greet->getLayoutItem() ); - Debug( "delete %s\n", pName.data() ); - delete greet; - selectPlugin( id ); - handler->verifyPluginChanged( id ); - if (running) - start(); - parent->setUpdatesEnabled( true ); - } -} - -void -KGStdVerify::updateStatus() -{ - int nfls; - - if (!enabled) - nfls = 1; - else if (failed) - nfls = 2; - else if (timedLeft) - nfls = -timedLeft; - else if (!suspended && capsLocked) - nfls = 3; - else - nfls = 1; - - if (failedLabelState != nfls) { - failedLabelState = nfls; - if (nfls < 0) { - failedLabel->setPaletteForegroundColor( Qt::black ); - failedLabel->setText( i18n( "Automatic login in 1 second...", - "Automatic login in %n seconds...", - timedLeft ) ); - } else { - switch (nfls) { - default: - failedLabel->clear(); - break; - case 3: - failedLabel->setPaletteForegroundColor( Qt::red ); - failedLabel->setText( i18n("Warning: Caps Lock on") ); - break; - case 2: - failedLabel->setPaletteForegroundColor( Qt::black ); - failedLabel->setText( authTok ? - i18n("Change failed") : - fixedEntity.isEmpty() ? - i18n("Login failed") : - i18n("Authentication failed") ); - break; - } - } - } -} - -KGThemedVerify::KGThemedVerify( KGVerifyHandler *_handler, - KdmThemer *_themer, - TQWidget *_parent, TQWidget *_predecessor, - const TQString &_fixedUser, - const PluginList &_pluginList, - KGreeterPlugin::Function _func, - KGreeterPlugin::Context _ctx ) - : inherited( _handler, _themer, _parent, _predecessor, _fixedUser, - _pluginList, _func, _ctx ) -{ - updateLockStatus(); -} - -KGThemedVerify::~KGThemedVerify() -{ -} - -void // public -KGThemedVerify::selectPlugin( int id ) -{ - inherited::selectPlugin( id ); - TQLayoutItem *l; - KdmItem *n; - if (themer && (l = greet->getLayoutItem())) { - if (!(n = themer->findNode( "talker" ))) - MsgBox( errorbox, - i18n("Theme not usable with authentication method '%1'.") - .arg( i18n(greetPlugins[pluginList[id]].info->name) ) ); - else { - n->setLayoutItem( l ); - showWidgets( l ); - } - } - if (themer) - themer->updateGeometry( true ); -} - -void // private slot -KGThemedVerify::slotPluginSelected( int id ) -{ - if (failed) - return; - if (id != curPlugin) { - plugMenu->setItemChecked( curPlugin, false ); - Debug( "delete %s\n", pName.data() ); - delete greet; - selectPlugin( id ); - handler->verifyPluginChanged( id ); - if (running) - start(); - } -} - -void -KGThemedVerify::updateStatus() -{ - handler->updateStatus( enabled && failed, - enabled && !suspended && capsLocked, - timedLeft ); -} - - -KGChTok::KGChTok( TQWidget *_parent, const TQString &user, - const PluginList &pluginList, int curPlugin, - KGreeterPlugin::Function func, - KGreeterPlugin::Context ctx ) - : inherited( _parent ) - , verify( 0 ) -{ - TQSizePolicy fp( TQSizePolicy::Fixed, TQSizePolicy::Fixed ); - okButton = new KPushButton( KStdGuiItem::ok(), this ); - okButton->setSizePolicy( fp ); - okButton->setDefault( true ); - cancelButton = new KPushButton( KStdGuiItem::cancel(), this ); - cancelButton->setSizePolicy( fp ); - - verify = new KGStdVerify( this, this, cancelButton, user, pluginList, func, ctx ); - verify->selectPlugin( curPlugin ); - - TQVBoxLayout *box = new TQVBoxLayout( this, 10 ); - - box->addWidget( new TQLabel( i18n("Changing authentication token"), this ), 0, AlignHCenter ); - - box->addLayout( verify->getLayout() ); - - box->addWidget( new KSeparator( KSeparator::HLine, this ) ); - - TQHBoxLayout *hlay = new TQHBoxLayout( box ); - hlay->addStretch( 1 ); - hlay->addWidget( okButton ); - hlay->addStretch( 1 ); - hlay->addWidget( cancelButton ); - hlay->addStretch( 1 ); - - connect( okButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); - connect( cancelButton, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) ); - - TQTimer::singleShot( 0, verify, TQT_SLOT(start()) ); -} - -KGChTok::~KGChTok() -{ - hide(); - delete verify; -} - -void -KGChTok::accept() -{ - verify->accept(); -} - -void -KGChTok::verifyPluginChanged( int ) -{ - // cannot happen -} - -void -KGChTok::verifyOk() -{ - inherited::accept(); -} - -void -KGChTok::verifyFailed() -{ - okButton->setEnabled( false ); - cancelButton->setEnabled( false ); -} - -void -KGChTok::verifyRetry() -{ - okButton->setEnabled( true ); - cancelButton->setEnabled( true ); -} - -void -KGChTok::verifySetUser( const TQString & ) -{ - // cannot happen -} - - -////// helper class, nuke when qtimer supports suspend()/resume() - -QXTimer::QXTimer() - : inherited( 0 ) - , left( -1 ) -{ - connect( &timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeout()) ); -} - -void -QXTimer::start( int msec ) -{ - left = msec; - timer.start( left, true ); - gettimeofday( &stv, 0 ); -} - -void -QXTimer::stop() -{ - timer.stop(); - left = -1; -} - -void -QXTimer::suspend() -{ - if (timer.isActive()) { - timer.stop(); - struct timeval tv; - gettimeofday( &tv, 0 ); - left -= (tv.tv_sec - stv.tv_sec) * 1000 + (tv.tv_usec - stv.tv_usec) / 1000; - if (left < 0) - left = 0; - } -} - -void -QXTimer::resume() -{ - if (left >= 0 && !timer.isActive()) { - timer.start( left, true ); - gettimeofday( &stv, 0 ); - } -} - -void -QXTimer::slotTimeout() -{ - left = 0; - emit timeout(); -} - - -#include "kgverify.moc" diff --git a/kdm/kfrontend/kgverify.h b/kdm/kfrontend/kgverify.h deleted file mode 100644 index 44fab973a..000000000 --- a/kdm/kfrontend/kgverify.h +++ /dev/null @@ -1,249 +0,0 @@ -/* - -Shell for tdm conversation plugins - -Copyright (C) 1997, 1998 Steffen Hansen -Copyright (C) 2000-2004 Oswald Buddenhagen - - -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. - -*/ - - -#ifndef KGVERIFY_H -#define KGVERIFY_H - -#include "kgreeterplugin.h" -#include "kfdialog.h" - -#include -#include -#include - -#include -#include - -// helper class, nuke when qt supports suspend()/resume() -class QXTimer : public TQObject { - Q_OBJECT - typedef TQObject inherited; - - public: - QXTimer(); - void start( int msec ); - void stop(); - void suspend(); - void resume(); - - signals: - void timeout(); - - private slots: - void slotTimeout(); - - private: - TQTimer timer; - struct timeval stv; - long left; -}; - -class KGVerifyHandler { - public: - virtual void verifyPluginChanged( int id ) = 0; - virtual void verifyClear(); - virtual void verifyOk() = 0; - virtual void verifyFailed() = 0; - virtual void verifyRetry() = 0; - virtual void verifySetUser( const TQString &user ) = 0; - virtual void updateStatus( bool fail, bool caps, int left ); // for themed only -}; - -class TQWidget; -class TQLabel; -class TQPopupMenu; -class TQTimer; -class KPushButton; -class KLibrary; - -struct GreeterPluginHandle { - KLibrary *library; - kgreeterplugin_info *info; -}; - -typedef TQValueVector PluginList; - -class KGVerify : public TQObject, public KGreeterPluginHandler { - Q_OBJECT - typedef TQObject inherited; - - public: - KGVerify( KGVerifyHandler *handler, KdmThemer *themer, - TQWidget *parent, TQWidget *predecessor, - const TQString &fixedEntity, const PluginList &pluginList, - KGreeterPlugin::Function func, KGreeterPlugin::Context ctx ); - virtual ~KGVerify(); - TQPopupMenu *getPlugMenu(); - void loadUsers( const TQStringList &users ); - void presetEntity( const TQString &entity, int field ); - TQString getEntity() const; - void setUser( const TQString &user ); - void setPassword( const TQString &pass ); - /* virtual */ void selectPlugin( int id ); - bool entitiesLocal() const; - bool entitiesFielded() const; - bool entityPresettable() const; - bool isClassic() const; - TQString pluginName() const; - void setEnabled( bool on ); - void abort(); - void suspend(); - void resume(); - void accept(); - void reject(); - - int coreLock; - - static bool handleFailVerify( TQWidget *parent ); - static PluginList init( const TQStringList &plugins ); - static void done(); - - public slots: - void start(); - - protected: - bool eventFilter( TQObject *, TQEvent * ); - void MsgBox( TQMessageBox::Icon typ, const TQString &msg ); - void setTimer(); - void updateLockStatus(); - virtual void updateStatus() = 0; - void handleVerify(); - - QXTimer timer; - TQString fixedEntity, presEnt, curUser; - PluginList pluginList; - KGVerifyHandler *handler; - KdmThemer *themer; - TQWidget *parent, *predecessor; - KGreeterPlugin *greet; - TQPopupMenu *plugMenu; - int curPlugin, presFld, timedLeft, deadTicks; - TQCString pName; - KGreeterPlugin::Function func; - KGreeterPlugin::Context ctx; - bool capsLocked; - bool enabled, running, suspended, failed, delayed, cont; - bool authTok, isClear, timeable; - - static void VMsgBox( TQWidget *parent, const TQString &user, TQMessageBox::Icon type, const TQString &mesg ); - static void VErrBox( TQWidget *parent, const TQString &user, const char *msg ); - static void VInfoBox( TQWidget *parent, const TQString &user, const char *msg ); - - static TQValueVector greetPlugins; - - private: - bool applyPreset(); - void performAutoLogin(); - bool scheduleAutoLogin( bool initial ); - void doReject( bool initial ); - - private slots: - //virtual void slotPluginSelected( int id ) = 0; - void slotTimeout(); - void slotActivity(); - - public: // from KGreetPluginHandler - virtual void gplugReturnText( const char *text, int tag ); - virtual void gplugReturnBinary( const char *data ); - virtual void gplugSetUser( const TQString &user ); - virtual void gplugStart(); - virtual void gplugActivity(); - virtual void gplugMsgBox( TQMessageBox::Icon type, const TQString &text ); - - static TQVariant getConf( void *ctx, const char *key, const TQVariant &dflt ); -}; - -class KGStdVerify : public KGVerify { - Q_OBJECT - typedef KGVerify inherited; - - public: - KGStdVerify( KGVerifyHandler *handler, TQWidget *parent, - TQWidget *predecessor, const TQString &fixedEntity, - const PluginList &pluginList, - KGreeterPlugin::Function func, KGreeterPlugin::Context ctx ); - virtual ~KGStdVerify(); - TQLayout *getLayout() const { return TQT_TQLAYOUT(grid); } - void selectPlugin( int id ); - - protected: - void updateStatus(); - - private: - TQGridLayout *grid; - TQLabel *failedLabel; - int failedLabelState; - - private slots: - void slotPluginSelected( int id ); -}; - -class KGThemedVerify : public KGVerify { - Q_OBJECT - typedef KGVerify inherited; - - public: - KGThemedVerify( KGVerifyHandler *handler, KdmThemer *themer, - TQWidget *parent, TQWidget *predecessor, - const TQString &fixedEntity, - const PluginList &pluginList, - KGreeterPlugin::Function func, - KGreeterPlugin::Context ctx ); - virtual ~KGThemedVerify(); - void selectPlugin( int id ); - - protected: - void updateStatus(); - - private slots: - void slotPluginSelected( int id ); -}; - -class KGChTok : public FDialog, public KGVerifyHandler { - Q_OBJECT - typedef FDialog inherited; - - public: - KGChTok( TQWidget *parent, const TQString &user, - const PluginList &pluginList, int curPlugin, - KGreeterPlugin::Function func, KGreeterPlugin::Context ctx ); - ~KGChTok(); - - public slots: - void accept(); - - private: - KPushButton *okButton, *cancelButton; - KGStdVerify *verify; - - public: // from KGVerifyHandler - virtual void verifyPluginChanged( int id ); - virtual void verifyOk(); - virtual void verifyFailed(); - virtual void verifyRetry(); - virtual void verifySetUser( const TQString &user ); -}; - -#endif /* KGVERIFY_H */ diff --git a/kdm/kfrontend/krootimage.cpp b/kdm/kfrontend/krootimage.cpp deleted file mode 100644 index b51367485..000000000 --- a/kdm/kfrontend/krootimage.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - -Copyright (C) 1999 Matthias Hoelzer-Kluepfel -Copyright (C) 2002,2004 Oswald Buddenhagen - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public -License version 2 as published by the Free Software Foundation. - -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; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. - -*/ - -#include - -#include -#include -#include - -#include - -#include "krootimage.h" - -#include -#include - -#include - -static const char description[] = - I18N_NOOP( "Fancy desktop background for tdm" ); - -static const char version[] = "v2.0"; - -static KCmdLineOptions options[] = { - { "+config", I18N_NOOP( "Name of the configuration file" ), 0 }, - KCmdLineLastOption -}; - -static Atom prop_root; -static bool properties_inited = false; - -MyApplication::MyApplication( const char *conf ) - : KApplication(), - renderer( 0, new KSimpleConfig( TQFile::decodeName( conf ) ) ) -{ - connect( &timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeout()) ); - connect( &renderer, TQT_SIGNAL(imageDone( int )), this, TQT_SLOT(renderDone()) ); - renderer.enableTiling( true ); // optimize - renderer.changeWallpaper(); // cannot do it when we're killed, so do it now - timer.start( 60000 ); - renderer.start(); - - if( !properties_inited ) { - prop_root = XInternAtom(qt_xdisplay(), "_XROOTPMAP_ID", False); - properties_inited = true; - } -} - - -void -MyApplication::renderDone() -{ - // Get the newly drawn pixmap... - TQPixmap pm = renderer.pixmap(); - - // ...set it to the desktop widget... - TQT_TQWIDGET(desktop())->setBackgroundPixmap( pm ); - TQT_TQWIDGET(desktop())->repaint( true ); - - // ...and export it via Esetroot-style so that composition managers can use it! - Pixmap bgPm = pm.handle(); // fetch the actual X handle to it - XChangeProperty(qt_xdisplay(), qt_xrootwin(), prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &bgPm, 1); - - renderer.saveCacheFile(); - renderer.cleanup(); - for (unsigned i=0; ibackgroundMode() == KBackgroundSettings::Program || - (r->multiWallpaperMode() != KBackgroundSettings::NoMulti && - r->multiWallpaperMode() != KBackgroundSettings::NoMultiRandom)) { - return; - } - } - -} - -void -MyApplication::slotTimeout() -{ - bool change = false; - - if (renderer.needProgramUpdate()) { - renderer.programUpdate(); - change = true; - } - - if (renderer.needWallpaperChange()) { - renderer.changeWallpaper(); - change = true; - } - - if (change) - renderer.start(); -} - -int -main( int argc, char *argv[] ) -{ - KApplication::disableAutoDcopRegistration(); - - KLocale::setMainCatalogue( "kdesktop" ); - KCmdLineArgs::init( argc, argv, "krootimage", I18N_NOOP( "KRootImage" ), description, version ); - KCmdLineArgs::addCmdLineOptions( options ); - - KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - if (!args->count()) - args->usage(); - MyApplication app( args->arg( 0 ) ); - args->clear(); - - app.exec(); - - app.flushX(); - - // Keep color resources after termination - XSetCloseDownMode( qt_xdisplay(), RetainTemporary ); - - return 0; -} - -#include "krootimage.moc" diff --git a/kdm/kfrontend/krootimage.h b/kdm/kfrontend/krootimage.h deleted file mode 100644 index e46190116..000000000 --- a/kdm/kfrontend/krootimage.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - -Copyright (C) 1999 Matthias Hoelzer-Kluepfel -Copyright (C) 2002,2004 Oswald Buddenhagen - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public -License version 2 as published by the Free Software Foundation. - -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; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. - -*/ - -#ifndef __TDMDESKTOP_H__ -#define __TDMDESKTOP_H__ - - -#include -#include - -#include - - -class MyApplication : public KApplication -{ - Q_OBJECT - - public: - MyApplication( const char * ); - - private slots: - void renderDone(); - void slotTimeout(); - - private: - KVirtualBGRenderer renderer; - TQTimer timer; -}; - -#endif diff --git a/kdm/kfrontend/pics/CMakeLists.txt b/kdm/kfrontend/pics/CMakeLists.txt deleted file mode 100644 index e1b61b4f8..000000000 --- a/kdm/kfrontend/pics/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -install( FILES - kdelogo.png kdelogo-crystal.png shutdown.jpg - DESTINATION ${DATA_INSTALL_DIR}/tdm/pics ) - -install( FILES - default1.png default2.png default3.png root1.png - DESTINATION ${DATA_INSTALL_DIR}/tdm/pics/users ) diff --git a/kdm/kfrontend/pics/Makefile.am b/kdm/kfrontend/pics/Makefile.am deleted file mode 100644 index 9ba04536e..000000000 --- a/kdm/kfrontend/pics/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ - -picsdir = $(kde_datadir)/tdm/pics -pics_DATA = kdelogo.png kdelogo-crystal.png shutdown.jpg - -usersdir = $(picsdir)/users -users_DATA = default1.png default2.png default3.png root1.png - - -EXTRA_DIST = $(pics_DATA) $(users_DATA) diff --git a/kdm/kfrontend/pics/default1.png b/kdm/kfrontend/pics/default1.png deleted file mode 100644 index ef3aef3f9..000000000 Binary files a/kdm/kfrontend/pics/default1.png and /dev/null differ diff --git a/kdm/kfrontend/pics/default2.png b/kdm/kfrontend/pics/default2.png deleted file mode 100644 index 194acfe2c..000000000 Binary files a/kdm/kfrontend/pics/default2.png and /dev/null differ diff --git a/kdm/kfrontend/pics/default3.png b/kdm/kfrontend/pics/default3.png deleted file mode 100644 index a8663b15e..000000000 Binary files a/kdm/kfrontend/pics/default3.png and /dev/null differ diff --git a/kdm/kfrontend/pics/kdelogo-crystal.png b/kdm/kfrontend/pics/kdelogo-crystal.png deleted file mode 100644 index 592a7e321..000000000 Binary files a/kdm/kfrontend/pics/kdelogo-crystal.png and /dev/null differ diff --git a/kdm/kfrontend/pics/kdelogo.png b/kdm/kfrontend/pics/kdelogo.png deleted file mode 100644 index c89a7f660..000000000 Binary files a/kdm/kfrontend/pics/kdelogo.png and /dev/null differ diff --git a/kdm/kfrontend/pics/root1.png b/kdm/kfrontend/pics/root1.png deleted file mode 100644 index fced75c11..000000000 Binary files a/kdm/kfrontend/pics/root1.png and /dev/null differ diff --git a/kdm/kfrontend/pics/shutdown.jpg b/kdm/kfrontend/pics/shutdown.jpg deleted file mode 100644 index f1353c54b..000000000 Binary files a/kdm/kfrontend/pics/shutdown.jpg and /dev/null differ diff --git a/kdm/kfrontend/sakdlg.cc b/kdm/kfrontend/sakdlg.cc deleted file mode 100644 index 396fa1627..000000000 --- a/kdm/kfrontend/sakdlg.cc +++ /dev/null @@ -1,247 +0,0 @@ -//=========================================================================== -// -// This file is part of the KDE project -// -// Copyright (c) 2010-2011 Timothy Pearson - -#include - -#include "sakdlg.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kfdialog.h" - -#ifndef AF_LOCAL -# define AF_LOCAL AF_UNIX -#endif - -#define FIFO_DIR "/tmp/ksocket-global/tdm" -#define FIFO_FILE "/tmp/ksocket-global/tdm/tdmctl-%1" -#define FIFO_SAK_FILE "/tmp/ksocket-global/tdm/tdmctl-sak-%1" - -bool trinity_desktop_lock_use_system_modal_dialogs = TRUE; -extern bool trinity_desktop_lock_use_sak; - -//=========================================================================== -// -// Simple dialog for displaying an unlock status or recurring error message -// -SAKDlg::SAKDlg(TQWidget *parent) - : TQDialog(parent, "information dialog", true, (trinity_desktop_lock_use_system_modal_dialogs?((WFlags)WStyle_StaysOnTop):((WFlags)WX11BypassWM))), - mUnlockingFailed(false), mPipe_fd(-1), closingDown(false) -{ - if (trinity_desktop_lock_use_system_modal_dialogs) { - // Signal that we do not want any window controls to be shown at all - Atom kde_wm_system_modal_notification; - kde_wm_system_modal_notification = XInternAtom(qt_xdisplay(), "_KDE_WM_MODAL_SYS_NOTIFICATION", False); - XChangeProperty(qt_xdisplay(), winId(), kde_wm_system_modal_notification, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L); - } - setCaption(TDM_LOGIN_SCREEN_BASE_TITLE); - - frame = new TQFrame( this ); - if (trinity_desktop_lock_use_system_modal_dialogs) - frame->setFrameStyle( TQFrame::NoFrame ); - else - frame->setFrameStyle( TQFrame::Panel | TQFrame::Raised ); - frame->setLineWidth( 2 ); - - KSMModalDialogHeader* theader = new KSMModalDialogHeader( frame ); - - KUser user; - - mStatusLabel = new TQLabel( " ", frame ); - mStatusLabel->setAlignment( TQLabel::AlignVCenter ); - - TQVBoxLayout *unlockDialogLayout = new TQVBoxLayout( this ); - unlockDialogLayout->addWidget( frame ); - - TQHBoxLayout *layStatus = new TQHBoxLayout( 0, 0, KDialog::spacingHint()); - layStatus->addWidget( mStatusLabel ); - - frameLayout = new TQGridLayout( frame, 1, 1, KDialog::marginHint(), KDialog::spacingHint() ); - frameLayout->addMultiCellWidget( theader, 0, 0, 0, 1, AlignTop | AlignLeft ); - frameLayout->addMultiCellLayout( layStatus, 1, 1, 0, 1, AlignLeft | AlignVCenter); - - mStatusLabel->setText("" + i18n("Press Ctrl+Alt+Del to begin.") + "

" + i18n("This process helps keep your password secure.") + "
" + i18n("It prevents unauthorized users from emulating the login screen.")); - - installEventFilter(this); - - mSAKProcess = new KProcess; - *mSAKProcess << "tdmtsak" << "dm"; - connect(mSAKProcess, TQT_SIGNAL(processExited(KProcess*)), this, TQT_SLOT(slotSAKProcessExited())); - mSAKProcess->start(); - - TQTimer::singleShot( 0, this, TQT_SLOT(handleInputPipe()) ); -} - -void SAKDlg::slotSAKProcessExited() -{ - int retcode = mSAKProcess->exitStatus(); - if (retcode != 0) trinity_desktop_lock_use_sak = false; - closingDown = true; - hide(); -} - -void SAKDlg::handleInputPipe(void) { - if (closingDown) { - ::unlink(mPipeFilename.ascii()); - return; - } - - if (isShown() == false) { - TQTimer::singleShot( 100, this, TQT_SLOT(handleInputPipe()) ); - return; - } - - char readbuf[2048]; - int displayNumber; - TQString currentDisplay; - currentDisplay = TQString(getenv("DISPLAY")); - currentDisplay = currentDisplay.replace(":", ""); - displayNumber = currentDisplay.toInt(); - mPipeFilename = TQString(FIFO_SAK_FILE).arg(displayNumber); - ::unlink((TQString(FIFO_FILE).arg(displayNumber)).ascii()); - - /* Create the FIFOs if they do not exist */ - umask(0); - struct stat buffer; - int status; - status = stat(FIFO_DIR, &buffer); - if (status == 0) { - int file_mode = ((buffer.st_mode & S_IRWXU) >> 6) * 100; - file_mode = file_mode + ((buffer.st_mode & S_IRWXG) >> 3) * 10; - file_mode = file_mode + ((buffer.st_mode & S_IRWXO) >> 0) * 1; - if ((file_mode != 600) || (buffer.st_uid != 0) || (buffer.st_gid != 0)) { - ::unlink(mPipeFilename.ascii()); - printf("[WARNING] Possible security breach! Please check permissions on " FIFO_DIR " (must be 600 and owned by root/root, got %d %d/%d). Not listening for login credentials on remote control socket.\n", file_mode, buffer.st_uid, buffer.st_gid); fflush(stdout); - return; - } - } - mkdir(FIFO_DIR,0600); - mknod(mPipeFilename.ascii(), S_IFIFO|0600, 0); - chmod(mPipeFilename.ascii(), 0600); - - mPipe_fd = ::open(mPipeFilename.ascii(), O_RDONLY | O_NONBLOCK); - int numread; - TQString inputcommand = ""; - while ((!inputcommand.contains('\n')) && (!closingDown)) { - numread = ::read(mPipe_fd, readbuf, 2048); - readbuf[numread] = 0; - readbuf[2047] = 0; - inputcommand += readbuf; - tqApp->processEvents(); - } - if (closingDown) { - ::unlink(mPipeFilename.ascii()); - return; - } - inputcommand = inputcommand.replace('\n', ""); - TQStringList commandList = TQStringList::split('\t', inputcommand, false); - if ((*(commandList.at(0))) == "CLOSE") { - mSAKProcess->kill(); - } - if (!closingDown) { - TQTimer::singleShot( 0, this, TQT_SLOT(handleInputPipe()) ); - ::close(mPipe_fd); - ::unlink(mPipeFilename.ascii()); - } - else { - ::unlink(mPipeFilename.ascii()); - } -} - -SAKDlg::~SAKDlg() -{ - if ((mSAKProcess) && (mSAKProcess->isRunning())) { - mSAKProcess->kill(SIGTERM); - delete mSAKProcess; - } - if (mPipe_fd != -1) { - closingDown = true; - ::close(mPipe_fd); - ::unlink(mPipeFilename.ascii()); - } - hide(); -} - -void SAKDlg::closeDialogForced() -{ - TQDialog::reject(); -} - -void SAKDlg::reject() -{ - -} - -void SAKDlg::updateLabel(TQString &txt) -{ - mStatusLabel->setPaletteForegroundColor(Qt::black); - mStatusLabel->setText("" + txt + ""); -} - -void SAKDlg::show() -{ - TQDialog::show(); - TQApplication::flushX(); -} - -#include "sakdlg.moc" diff --git a/kdm/kfrontend/sakdlg.h b/kdm/kfrontend/sakdlg.h deleted file mode 100644 index a930707b1..000000000 --- a/kdm/kfrontend/sakdlg.h +++ /dev/null @@ -1,64 +0,0 @@ -//=========================================================================== -// -// This file is part of the KDE project -// -// Copyright (c) 2010 Timothy Pearson -// - -#ifndef __SAKDLG_H__ -#define __SAKDLG_H__ - -#include -#include - -#include - -class TQFrame; -class TQGridLayout; -class TQLabel; -class KPushButton; -class TQListView; - -//=========================================================================== -// -// Simple dialog for displaying an info message. -// It does not handle password validation. -// -class SAKDlg : public TQDialog -{ - Q_OBJECT - -public: - SAKDlg(TQWidget *parent); - ~SAKDlg(); - virtual void show(); - - void updateLabel( TQString &txt ); - void closeDialogForced(); - -private slots: - void slotSAKProcessExited(); - void handleInputPipe(); - -protected slots: - virtual void reject(); - -private: - TQFrame *frame; - TQGridLayout *frameLayout; - TQLabel *mStatusLabel; - int mCapsLocked; - bool mUnlockingFailed; - TQStringList layoutsList; - TQStringList::iterator currLayout; - int sPid, sFd; - KProcess* mSAKProcess; - int mPipe_fd; - TQString mPipeFilename; - -protected: - bool closingDown; -}; - -#endif - diff --git a/kdm/kfrontend/sessions/9wm.desktop b/kdm/kfrontend/sessions/9wm.desktop deleted file mode 100644 index d17276782..000000000 --- a/kdm/kfrontend/sessions/9wm.desktop +++ /dev/null @@ -1,76 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=9wm -TryExec=9wm -Name=9WM -Name[cy]= 9WM -Name[eo]=9FA -Name[hi]=9डबल्यू-एम -Name[ta]=9 WM -Name[te]=9 డబ్ల్యు ఎం -Name[th]=ตัวจัดการหน้าต่าง gWM -Comment=An emulation of the Plan 9 window manager 8-1/2 -Comment[af]='n Nabootsing van die 'Plan 9' venster bestuurder -Comment[be]=Эмуляцыя кіраўніка вокнаў 8-1/2 для Plan 9 -Comment[bn]=প্ল্যান ৯ উইণ্ডো ম্যানেজার ৮-১/২ -এর এমুলেশন -Comment[bs]=Simulacija Plan 9 window managera 8-1/2 -Comment[ca]=Una emulació del gestor de finestres Plan 9 -Comment[cs]=Emulace Plane 9 správce oken 8-1/2 -Comment[csb]=Emùlacëjô menedżera òknów Plan 9 - 8-1/2 -Comment[cy]=Efelychiad o 8-1/2, y trefnydd ffenestri Plan 9 -Comment[da]=En emulering af Plan 9 vindueshåndteringen 8-1/2 -Comment[de]=Emulation des Plan 9-Fenstermanagers 8-1/2 -Comment[el]=Μια προσομοίωση του Plan 9 διαχειριστή παραθύρων 8-1/2 -Comment[eo]=KDE-fenestroadministrilo de plano 9 -Comment[es]=Una emulación del gestor de ventanas Plan 9 8-1/2 -Comment[et]=Plan 9 aknahalduri 8-1/2 emuleerimine -Comment[eu]=Plan 9 8-1/2 leiho kudeatzailearen emulazioa -Comment[fa]=تقلیدی از نقشۀ مدیر پنجره ۹. ۸-۱/ ۲ -Comment[fi]=Emulaatio Plan9-ikkunaohjelmasta 8-1/2 -Comment[fr]=Une émulation du gestionnaire de fenêtres Plan 9 8-1/2 -Comment[fy]=In emulator foar de Plan9 finstersbehearder 8-1/2 -Comment[gl]=Unha emulación do xestor de fiestras de Plan9 -Comment[he]=מדמה של מנהל חלונות Plan 9 8-1/2 -Comment[hi]=प्लान 9 विंडो प्रबंधक 8-1/2 का एक एमुलेशन -Comment[hr]=Emulacija Plan 9 upravitelja prozora 8-1/2 -Comment[hu]=A Plan 9 operációs rendszer 8-1/2 nevű ablakkezelőjének emulálása -Comment[is]=Eftirlíking af Plan 9 gluggastjóranum 8-1/2 -Comment[it]=Un emulatore del window manager 8-1/2 Plan 9 -Comment[ja]=Plan9 ウィンドウマネージャのエミュレーション 8-1/2 -Comment[ka]=Plan 9 ფანჯრის მმართველის ემულატორი -Comment[kk]=Plan 9 терезе менеджерінің эмуляторы -Comment[km]=ការ​ត្រាប់​តាម​កម្មវិធី​គ្រប់គ្រង​បង្អួច Plan 9 8-1/2 -Comment[ko]=Plan 9 창 관리자 8-1/2 에뮬레이션 -Comment[lt]=Plan 9 langų tvarkyklės emuliatorius 8-1/2 -Comment[lv]=Plan 9 logu menedžera emulators 8-1/2 -Comment[mk]=Емулација на менаџерот на прозорци Plan 9 8-1/2 -Comment[ms]=Pelagakan Plan 9 pengurus tetingkap 8-1/2 -Comment[mt]=Emulazzjoni tal-window manager "Plan 9" 8½ -Comment[nb]=En emulering av vindusbehandleren 8 ½ fra Plan 9 -Comment[nds]=Emuleert den Plan-9-Finsterpleger 8-1/2 -Comment[ne]=योजना 9 सञ्झ्याल प्रबन्धक 8-1/2 को इमुलेसन -Comment[nl]=Een emulator voor de Plan9 windowmanager 8-1/2 -Comment[nn]=Emulering av vindaugssjefen 8 ½ frå Plan 9 -Comment[pa]=ਪਲੇਨ 9 ਝਰੋਖਾ ਮੈਨੇਜਰ 8-1/2 ਦਾ ਸਮਰੂਪ -Comment[pl]=Emulacja menedżera okien Plan 9 - 8-1/2 -Comment[pt]=Uma emulação do gestor de janelas do Plan 9 8-1/2 -Comment[pt_BR]=Uma emulação do gerenciador de janelas do Plan 9 -Comment[ro]=Un emulator al managerului de ferestre 8-1/2 din Plan 9 -Comment[ru]=Эмуляция оконного менеджера Plan 9 -Comment[rw]=Ikurura rya mugenga dirishya 8-1/2 Plan 9 -Comment[se]=Lásegieđahalli mii áddestaddá Plan 9 lásegieđahalli 8-1/2. -Comment[sk]=Emulácia správcu okien 8-1/2 systému Plan 9 -Comment[sl]=Emulacija okenskega upravitelja Plan 9 8-1/2 -Comment[sr]=Емулација Plan 9 менаџера прозора 8-1/2 -Comment[sr@Latn]=Emulacija Plan 9 menadžera prozora 8-1/2 -Comment[sv]=Emulering av Plan-9-fönsterhanteraren 8-1/2 -Comment[ta]= திட்டம் 9 சாளர மேலாளர் 8-1/2 இன் முன்மாதிரி -Comment[tg]=Эмулятори нақшаи 9-и мудири тирезаи 8-1/2 -Comment[th]=การจำลองตัวจัดการหน้าต่าง Plan 9 8-1/2 -Comment[tr]=Plan 9 pencere yöneticisi 8-1/2 için bir emülasyon -Comment[tt]=Plan 9 atlı täräzä idäräçenä axşap eşläw -Comment[uk]=Емуляція менеджера вікон Plan 9 "8-1/2" -Comment[vi]=Một bộ mô phỏng bộ quản lý cửa sổ Plan 9 8-1/2 -Comment[wa]=Ene emulåcion do manaedjeu di purneas di Plan 9 -Comment[zh_CN]=Plan 9 窗口管理器 8-1/2 的模拟 -Comment[zh_TW]=模仿 Plan 9 的視窗管理程式 8-1/2 diff --git a/kdm/kfrontend/sessions/CMakeLists.txt b/kdm/kfrontend/sessions/CMakeLists.txt deleted file mode 100644 index 780963bd4..000000000 --- a/kdm/kfrontend/sessions/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -configure_file( tde.desktop.cmake tde.desktop @ONLY ) - -install( FILES - admin.desktop ${CMAKE_CURRENT_BINARY_DIR}/tde.desktop - gnome.desktop 9wm.desktop aewm++.desktop aewm.desktop - afterstep.desktop amaterus.desktop amiwm.desktop - asclassic.desktop blackbox.desktop cde.desktop - ctwm.desktop cwwm.desktop enlightenment.desktop - evilwm.desktop fluxbox.desktop flwm.desktop fvwm.desktop - fvwm95.desktop golem.desktop icewm.desktop ion.desktop - larswm.desktop lwm.desktop matchbox.desktop metacity.desktop - mwm.desktop olvwm.desktop olwm.desktop openbox.desktop - oroborus.desktop phluid.desktop pwm.desktop qvwm.desktop - ratpoison.desktop sapphire.desktop sawfish.desktop - twm.desktop ude.desktop vtwm.desktop w9wm.desktop - waimea.desktop wm2.desktop wmaker.desktop xfce.desktop - xfce4.desktop - DESTINATION ${DATA_INSTALL_DIR}/tdm/sessions ) diff --git a/kdm/kfrontend/sessions/Makefile.am b/kdm/kfrontend/sessions/Makefile.am deleted file mode 100644 index a29872441..000000000 --- a/kdm/kfrontend/sessions/Makefile.am +++ /dev/null @@ -1,49 +0,0 @@ -sessionsdir = $(kde_datadir)/tdm/sessions -sessions_DATA = \ - admin.desktop tde.desktop gnome.desktop \ - 9wm.desktop \ - aewm++.desktop \ - aewm.desktop \ - afterstep.desktop \ - amaterus.desktop \ - amiwm.desktop \ - asclassic.desktop \ - blackbox.desktop \ - cde.desktop \ - ctwm.desktop \ - cwwm.desktop \ - enlightenment.desktop \ - evilwm.desktop \ - fluxbox.desktop \ - flwm.desktop \ - fvwm.desktop \ - fvwm95.desktop \ - golem.desktop \ - icewm.desktop \ - ion.desktop \ - larswm.desktop \ - lwm.desktop \ - matchbox.desktop \ - metacity.desktop \ - mwm.desktop \ - olvwm.desktop \ - olwm.desktop \ - openbox.desktop \ - oroborus.desktop \ - phluid.desktop \ - pwm.desktop \ - qvwm.desktop \ - ratpoison.desktop \ - sapphire.desktop \ - sawfish.desktop \ - twm.desktop \ - ude.desktop \ - vtwm.desktop \ - w9wm.desktop \ - waimea.desktop \ - wm2.desktop \ - wmaker.desktop \ - xfce.desktop \ - xfce4.desktop - -EXTRA_DIST = $(sessions_DATA) diff --git a/kdm/kfrontend/sessions/admin.desktop b/kdm/kfrontend/sessions/admin.desktop deleted file mode 100644 index 73e6ae3bf..000000000 --- a/kdm/kfrontend/sessions/admin.desktop +++ /dev/null @@ -1,7 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Type=XSession -Exec=YaSTadminSession -TryExec=YaSTadminSession -Name=admin -Comment=Yast Admin Session diff --git a/kdm/kfrontend/sessions/aewm++.desktop b/kdm/kfrontend/sessions/aewm++.desktop deleted file mode 100644 index 3eb4ee8e8..000000000 --- a/kdm/kfrontend/sessions/aewm++.desktop +++ /dev/null @@ -1,74 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=aewm++_xsession -TryExec=aewm++_xsession -Name=AEWM++ -Name[eo]=MFA++ -Name[hi]=एईडबल्यूएम++ -Name[te]=ఎ ఈ డబ్ల్యు ఎం ++ -Comment=A minimal window manager based on AEWM, enhanced by virtual desktops and partial GNOME support -Comment[af]='n Minimale venster bestuurder wat op AEWM gebaseer is. Dit is verbeter met virtuale werkskerms en gedeeltelike GNOME ondersteuning -Comment[ar]=مدير نوافذ مصغّر مبني على AEWM، محسّن بأسطح مكتب وهمية ودعم جينوم جزئي -Comment[be]=Мінімалістычны кіраўнік вокнаў, заснаваны на AEWM, з віртуальнымі працоўнымі сталамі і частковай падтрымкай GNOME -Comment[bn]=AEWM ভিত্তিক একটি পরিমিত উইণ্ডো ম্যানেজার, ভার্চুয়াল ডেস্কটপ এবং আংশিক গনোম সমর্থন দ্বারা বর্ধিত -Comment[bs]=Minimalni window manager baziran na AEWM, proširen virtuelnim desktopima i djelomičnom GNOME podrškom -Comment[ca]=Un gestor de finestres minimalista basat en AEWM, orientat a escriptoris virtuals i funcionament parcial per a GNOME -Comment[cs]=Minimalizovaný správce oken založený na AEWM rozšířený o virtuální plochy a částečnou podporu GNOME -Comment[csb]=Prosti menedżer òknów na spòdlém AEWM, zbògacony o wirtualné pùltë ë dzélowé wspiarce dlô GNOME -Comment[cy]= Trefnydd ffenestri lleiafol wed'i seilio ar AEWM, wedi'i wella gan penbyrddau rhith a cynhaliaeth Gnome rhannol. -Comment[da]=En minimal vindueshåndtering baseret på AEWM, udvidet med virtuelle desktoppe og delvis GNOME-støtte -Comment[de]=Minimalistischer Fenstermanager. Beruht auf AEWM, verbessert durch virtuelle Arbeitsflächen und teilweise GNOME-Unterstützung -Comment[el]=Ένας μικρός διαχειριστής παραθύρων βασισμένος στον AEWM, εμπλουτισμένος με εικονικές επιφάνειες εργασίας και μερική υποστήριξη GNOME -Comment[eo]=Minimuma fenestroadministrilo el MFA, plibonigita per virtualaj labortabloj kaj parta helpo por Gnomikuo -Comment[es]=Un gestor de ventanas minimalista basado en AEWM, mejorado con soporte para escritorios virtailes y, parcialmente, GNOME -Comment[et]=Vähenõudlik aknahaldur, mille aluseks on AEWM ja mida on täiendatud virtuaalsete töölaudade ning osalise GNOME toetusega -Comment[eu]=AEWMn oinarritutako leiho kudeatzaile minimoa, mahaigain birtualen euskarriaz eta, zati batez, GNOMEz hobetua -Comment[fa]= مدیر پنجرۀ کمینه بر اساس AEWM، گسترش‌یافته توسط رومیزیهای مجازی و پشتیبانی جزئی GNOME -Comment[fi]=Minimaalinen AEWM:ään pohjautuva ikkunaohjelma, jota on parannettuna virtuaalityöpöydillä ja osittaisella GNOME-tuella -Comment[fr]=Un gestionnaire de fenêtres minimal fondé sur AEWM avec, en plus, la gestion des bureaux virtuels ainsi qu'un support partiel de GNOME -Comment[fy]=In minimalistyske finstersmanager basearre op AEWM, útbreide mei firtuele buroblêden en gedieltelike GNOME-stipe -Comment[gl]=Un xestor de fiestras mínimo baseado en AEWM, mellorado cos escritórios virtuais e con soporte parcial para GNOME -Comment[he]=מנהל חלונות מינימלי המבוסס על AEWM, המשופר על ידי שולחנות עבודה וירטואליים ותמיכה חלקית ב GNOME -Comment[hi]= एईडबल्यूएम आधारित अल्प विंडो प्रबंधक, आभासी डेस्कटॉप तथा आंशिक ग्नोम समर्थन से बेहतर बनाया गया -Comment[hr]=Minimalistički upravitelj prozora zasnovan na AEWM, unaprijeđen virtualnim radnim površinama i djelomičnom podrškom za GNOME -Comment[hu]=Egy nagyon egyszerű ablakkezelő az AEWM alapján, virtuális munkaasztalokkal és részleges GNOME-támogatással kiegészítve -Comment[is]=Einfaldur gluggastjóri byggður á AEWM en með stuðningi fyrir sýndarskjáborð og takmörkuðum GNOME stuðningi -Comment[it]= Un window manager minimale basato su AEWM, migliorato con desktop virtuali e supporto parziale per GNOME -Comment[ja]=仮想デスクトップと部分的な GNOME サポートを強化した AEWM ベースの小さなウィンドウマネージャ -Comment[ka]=მინიმალური ფანჯრის მენეჯერი AEWM -ის ბაზაზე, имеющий частичную поддержку GNOME. -Comment[kk]=Виртуалды үстелдері және шамалы GNOME қолдауы бар AEWM-негіздеген шағын терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​តូច ដែល​ផ្អែក​លើ AEWM ដែល​ធ្វើ​ឲ្យ​ប្រសើរ​ដោយ​ផ្ទៃតុ​និមិត្ត និង​ការ​គាំទ្រ GNOME -Comment[ko]=부분적 그놈 지원과 가상 데스크톱 지원을 사용하는 AEWM 기반 창 관리자 -Comment[lt]=Minimalistinė langų tvarkyklė paremta AEWM, išplėsta virtualių darbastalių ir daliniu GNOME palaikymu -Comment[lv]=Minimālistisks logu menedžeris bāzēts uz AEWM, papildināts ar virtuālajām darbvirsmām un daļēju GNOME atbalstu -Comment[mk]=Минимален менаџер на прозорци базиран на AEWM, подобрен со виртуелни површини и парцијална GNOME поддршка -Comment[ms]=Pengurus tetingkap minima berdasarkan AEWM, dipertingkatkan dengan desktop visual dan sokongan GNOME separa -Comment[mt]=Window manager żgħir ibbażat fuq AEWM, filmkien ma' desktops virtwali u sapport parzjali għal GNOME. -Comment[nb]=En minimal vindusbehandler basert på AEWM, forbedret med virtuelle skrivebord og delvis støtte for GNOME -Comment[nds]=En minimaal Finsterpleger, opbuut op AEWM, verwiedert üm virtuelle Schriefdischen un deelwies Ünnerstütten för GNOME -Comment[ne]=अवास्तविक डेस्कटप र आंशिक GNOME समर्थनद्वारा बृद्धि गरिएको AEWM मा आधारित न्यूनतम सञ्झ्याल प्रबन्धक -Comment[nl]=Een minimalistische windowmanager gebaseerd op AEWM, uitgebreid met virtuele bureaubladen en gedeeltelijke GNOME-ondersteuning -Comment[nn]=Ein minimal vindaugssjef basert på AEWM, forbetra med virtuelle skrivebord og delvis støtte for GNOME -Comment[pa]= AEWM ਤੇ ਅਧਾਰਿਤ ਛੋਟਾ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਫਰਜ਼ੀ ਵੇਹੜਿਆਂ ਨਾਲ ਲੈੱਸ ਤੇ ਥੋੜਾ GNOME ਸਹਾਇਕ -Comment[pl]=Prosty menedżer okien na bazie AEWM, wzbogacony o wirtualne pulpity i częściowe wsparcie dla GNOME -Comment[pt]=Um gestor de janelas simples baseado no AEWM, melhorado com os ecrãs virtuais e com um suporte parcial do GNOME -Comment[pt_BR]=Um gerenciador de janelas pequeno, baseado no AEWM, melhorado pelas áreas de trabalho virtuais e com suporte parcial ao GNOME -Comment[ro]=Un manager de ferestre minimal bazat pe AEWM, îmbunătățit cu ecrane virtuale și suport parțial pentru GNOME -Comment[ru]=Минимальный оконный менеджер на основе AEWM, имеющий частичную поддержку GNOME. -Comment[rw]=Mugenga dirishya nto ishingiye kuri AEWM, rivuguruwe n'ibiro bitagaragara n'iyifashisha GNOME rituzuye -Comment[se]=Geahpes lásegieđahalli vuođđoduvvon AEWM:as, mas leat virtuella čállinbeavddit ja doarju GNOME muhton muddui. -Comment[sk]=Minimálny správca okien založený na AEWM, rozšírrený o virtuálne plochy a čiastočnú podporu GNOME -Comment[sl]=Skromen okenski upavitelj na osnovi AEWM, izboljšan z navideznimi namizji in delno podporo GNOME -Comment[sr]=Минимални менаџер прозора заснован на AEWM-у, побољшан виртуелним радним површинама и делимичном подршком за Гном -Comment[sr@Latn]=Minimalni menadžer prozora zasnovan na AEWM-u, poboljšan virtuelnim radnim površinama i delimičnom podrškom za Gnom -Comment[sv]=Minimal fönsterhanterare baserad på AEWM, utökad med virtuella skrivbord och delvis stöd för Gnome -Comment[ta]=AEWM அடிப்படையிலான சிறிய சாளர மேலாண்மை, மெய்நிகர் மேல்மேசை மற்றும் பகுதி GNOME ஆதரவால் மேப்படுத்தப்பட்டுள்ளது -Comment[tg]=Мудири равзанаҳои хурд дар асоси AEWM дорои нопурраи интерфейси GNOME -Comment[th]=ตัวจัดการหน้าต่างขนาดเล็ก โดยใช้พื้นฐานของ AEWM แล้วเพิ่มความสามารถด้วย พื้นที่ทำงานเสมือน และสนับสนุน GNOME บางส่วน -Comment[tr]=AEWM tabanlı bir pencere yöneticisi -Comment[tt]=AEWM asılında yasalğan, xıyalí öställär belän beraz GNOME totqan ciñel täräzä-idäräçe -Comment[uk]=Мінімальний менеджер вікон, заснований на AEWM, покращений підтримкою віртуальних стільниць та частковою підтримкою GNOME -Comment[vi]=Bộ quản lý cửa sổ tối thiểu dựa trên AEWM, cải tiến với màn hình nền ảo và được hỗ trợ một phần bởi GNOME -Comment[wa]=On manaedjeu di purneas minimå båzé so AEWM, avou sopoirt po les forveyous scribannes eyet ene miete di sopoirt po Gnome -Comment[zh_CN]=基于 AEWM 的小型窗口管理器,增强了虚拟桌面和部分 GNOME 支持 -Comment[zh_TW]=基於 AEWM 的小型視窗管理程式,增強了虛擬桌面及部分的 GNOME 支援 diff --git a/kdm/kfrontend/sessions/aewm.desktop b/kdm/kfrontend/sessions/aewm.desktop deleted file mode 100644 index 362fd921f..000000000 --- a/kdm/kfrontend/sessions/aewm.desktop +++ /dev/null @@ -1,76 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=aewm -TryExec=aewm -Name=AEWM -Name[eo]=MFA -Name[hi]=एईडबल्यूएम -Name[te]=ఎ ఈ డబ్ల్యు ఎం -Comment=A minimalist window manager -Comment[af]='n Minimale venster bestuurder -Comment[ar]=مسيير نوافذ ذو الميزات الأقل -Comment[be]=Мінімалістычны кіраўнік вокнаў -Comment[bn]=একটি পরিমিত উইণ্ডো ম্যানেজার -Comment[bs]=Minimalistički window manager -Comment[ca]=Un gestor de finestres minimalista -Comment[cs]=Minimalistický správce oken -Comment[csb]=Prosti menedżer òknów -Comment[cy]=Trefnydd ffenestri lleiafol -Comment[da]=En minimalistisk vindueshåndtering -Comment[de]=Minimalistischer Fenstermanager -Comment[el]=Ένας μινιμαλιστικός διαχειριστής παραθύρων -Comment[eo]=Minimumema fenestroadministrilo -Comment[es]=Un gestor de ventanas minimalista -Comment[et]=Vähenõudlik aknahaldur -Comment[eu]=Leiho kudeatzaile minimalista -Comment[fa]=یک مدیر پنجرۀ کمینه -Comment[fi]=Minimalistinen ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres minimaliste -Comment[fy]=In minimalistyske finstersmanager -Comment[gl]=Un xestor de fiestras minimalista -Comment[he]=מנהל חלונות מינימליסטי -Comment[hi]=एक अल्पतम विंडो प्रबंधक -Comment[hr]=Minimalistički upravitelj prozora -Comment[hu]=Egy nagyon egyszerű ablakkezelő -Comment[is]=Einfaldur gluggastjóri -Comment[it]=Un window manager minimalista -Comment[ja]=小さなウィンドウマネージャ -Comment[ka]=მინიმალისტური ფანჯრების მნეჯერი -Comment[kk]=Шағын терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​លក្ខណៈ​ពិសេស​តិច -Comment[ko]=최소 지향 창 관리자 -Comment[lt]=Minimalistinė langų tvarkyklė -Comment[lv]=Minimālistisks logu menedžeris -Comment[mk]=Минималистички менаџер на прозорци -Comment[mn]=Хамгийн жижиг цонхны удирдагч -Comment[mt]=Window manager żgħir -Comment[nb]=En minimalistisk vindusbehandler -Comment[nds]=En minimalistisch Finsterpleger -Comment[ne]=एक मिनिमलिस्ट सञ्झ्याल प्रबन्धक -Comment[nl]=Een minimalistische windowmanager -Comment[nn]=Ein minimalistisk vindaugssjef -Comment[pa]=ਇੱਕ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Prosty menedżer okien -Comment[pt]=Um gestor de janelas minimalista -Comment[pt_BR]=Um gerenciador de janelas minimalista -Comment[ro]=Un manager de ferestre minimal -Comment[ru]=Минимальный оконный менеджер -Comment[rw]=Mugenga dirishya igira-bito -Comment[se]=Minimalisttalaš lásegieđahalli -Comment[sk]=Minimálny správca okien -Comment[sl]=Minimalističen okenski upravitelj -Comment[sr]=Минималистички менаџер прозора -Comment[sr@Latn]=Minimalistički menadžer prozora -Comment[sv]=Minimalistisk fönsterhanterare -Comment[ta]=ஒரு சிறிதுப்படுத்தப்பட்ட சாளர மேலாளர் -Comment[tg]=Мудири тирезаи minimalist -Comment[th]=ระบบจัดการหน้าต่างขนาดเล็ก -Comment[tr]=Küçük bir pencere yöneticisi -Comment[tt]=Bik ciñel täräzä-idäräçe -Comment[uk]=Аскетичний менеджер вікон -Comment[uz]=Juda oddiy oyna boshqaruvchi -Comment[uz@cyrillic]=Жуда оддий ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ đơn giản -Comment[wa]=On manaedjeu di purneas minimå -Comment[zh_CN]=最小的窗口管理器 -Comment[zh_TW]=一個最小型的視窗管理程式 diff --git a/kdm/kfrontend/sessions/afterstep.desktop b/kdm/kfrontend/sessions/afterstep.desktop deleted file mode 100644 index c3f8d7329..000000000 --- a/kdm/kfrontend/sessions/afterstep.desktop +++ /dev/null @@ -1,83 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=afterstep -TryExec=afterstep -Name=AfterStep -Name[bn]=আফটার-স্টেপ -Name[eo]=Postpaŝo -Name[hi]=आफ्टर-स्टेप -Name[ne]=चरण पछाडि -Name[pa]=ਪਗਬਾਅਦ -Name[rw]=NyumaIntambwe -Name[sv]=Afterstep -Name[ta]=ஆஃப்டர்ஸ்டெப் -Name[te]=ఆఫ్టర్ స్టెప్ -Comment=A window manager with the NeXTStep look and feel, based on FVWM -Comment[af]='n Venster bestuurder wat NeXTStep naboots, gebaseer of FVWM -Comment[ar]=مدير نوافذ ذو مظهر شبيه بـNeXTStep، مبني على FVWM -Comment[be]=Кіраўнік вокнаў з вонкавым выглядам NeXTStep, заснаваны на FVWM -Comment[bn]=FVWM-এর ওপর ভিত্তি করে তৈরি একটি উইণ্ডো ম্যানেজার, যা দেখতে শুনতে অনেকটানেক্সট-স্টেপ (NeXTStep)-এর মত -Comment[bs]=Window manager sa NeXTStep izgledom i osjećajem, baziran na FVWM -Comment[ca]=Un gestor de finestres amb l'aspecte i comportament de NeXTStep, basat en FVWM -Comment[cs]=Správce oken podobný NeXTStepu založený na FVWM -Comment[csb]=Menedżer òknów jidący w szlach NeXTStep, ùsôdzony na spòdlém FVWM -Comment[cy]= Trefnydd ffenestri efo golwg a theimlad CamNesaf (NeXTStep), wedi'i seilio ar FVWM -Comment[da]=En vindueshåndtering med NeXTStep udseende, baseret på FVWM -Comment[de]=Fenstermanager mit der Optik von NeXTStep, basiert auf FVWM -Comment[el]=Ένας διαχειριστής παραθύρων με την όψη και αίσθηση του NeXTStep, βασισμένος στον FVWM -Comment[eo]=Fenestroadministrilo, kiu aperas kiel Venontpaŝo, farita de FVWM -Comment[es]=Un gestor de ventanas con el aspecto de NeXTStep, basado en FVWM -Comment[et]=Aknahaldur NeXTStep välimuse ja vaimuga, aluseks FVWM -Comment[eu]=FVWMn oinarritutako, eta NeXTStep-en itxura eta portaera duen leiho kudeatzailea -Comment[fa]=یک مدیر پنجره توسط ظاهر و احساس NeXTStep، براساس FVWM -Comment[fi]=NeXTStep-tyylinen ja -tuntuinen FVWM:ään pohjautuva ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres similaire à NeXTStep et fondé sur FVWM -Comment[fy]=In finstersmanager mei it úterlik en gedrach fan NeXTStep; basearre op FVWM -Comment[gl]=Un xestor de fiestras de aspeito NeXTStep, baseado en FVWM -Comment[he]=מנהל חלונות עם מראה ומרגש כמו של NeXTStep המבוסס על, FVWM -Comment[hi]=एफ़वीडबल्यूएम आधारित नेक्स्टस्टेप की तरह दिखने और महसूस होने वाला विंडो प्रबंधक -Comment[hr]=Upravitelj prozora s NeXTStep izgledom i načinom rada, zasnovan na FVWM-u -Comment[hu]=Egy FVWM-alapú ablakkezelő, megjelenése a NeXTStepére hasonlít -Comment[is]=Gluggastjóri sem líkist þeim sem er í NeXTStep, byggður á FVWM -Comment[it]=Un window manager con lo stile NeXTStep, basato su FVWM -Comment[ja]=NeXTStep のルック&フィールをもった FVWM ベースのウィンドウマネージャ -Comment[ka]=ფანჯრის მენეჯერი FVWM -ის ბაზაზე, რომელიც NeXTStep-ს ჰგავს -Comment[kk]=FVWM-негіздеген, көрінісі NeXTStep-те сияқты, терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​មាន​រូបរាង និង​មុខងារ NeXTStep ដែល​ផ្អែក​លើ FVWM -Comment[ko]=FVWM 기반 NeXTStep 모양 창 관리자 -Comment[lt]=Langų tvarkyklė su NeXTStep išvaizda ir jausena, paremta FVWM -Comment[lv]=Logu menedžeris ar NeXTStep izskatu un izturēšanos, bāzēts uz FVWM -Comment[mk]=Менаџер на прозорци со изгледот и чувството на NeXTStep, базиран на FVWM -Comment[mn]=NeXTStep look болон feel, based бүхий FVWM-д суурилсан цонх удирдагч -Comment[ms]=Pengurus tetingkap dengan rupa dan rasa NeXTStep berdasarkan FVWM -Comment[mt]=Window manager ibbażat fuq FVWM, jixbaħ lil NeXTStep -Comment[nb]=En vindusbehandler som ligner på NeXTStep, basert på FVWM -Comment[nds]=En Finsterpleger mit dat Utsehn vun NeXTStep, opbuut op FVWM -Comment[ne]=FVWMA आधारित एउटा सञ्झ्याल प्रबन्धक NeXTStep मा हेर्छ र थाहा पाउँछ -Comment[nl]=Een windowmanager met het uiterlijk en gedrag van NeXTStep; gebaseerd op FVWM -Comment[nn]=Ein vindaugssjef som liknar på NeXTStep, basert på FVWM -Comment[pa]=NeXTStep ਦੀ ਦਿੱਖ ਤੇ ਦਰਿਸ਼ ਵਾਲਾ FVWM ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien naśladujący NeXTStep, stworzony na podstawie FVWM -Comment[pt]=Um gestor de janelas com a aparência e comportamento do NeXTStep. Baseado no FVWM. -Comment[pt_BR]=Um gerenciador de janelas com a aparência do NeXTSep, baseado no FVWM -Comment[ro]=Un manager de ferestre cu aspect NeXTStep, bazat pe FVWM -Comment[ru]=Оконный менеджер на основе FVWM, повторяющий внешний вид NeXTStep -Comment[rw]=Mugenga dirishya ifite imboneko n'ukumva NtambweIkurikira, ishingiye kuri FVWM -Comment[se]=Lásegieđahalli mii sulastahttá NeXTStep, vuođđoduvvon FVWM:as -Comment[sk]=Správca okien podobný NeXTStep založený na FVWM -Comment[sl]=Okenski upravitelj z občutkom in izgledom NeXTStep-a, na osnovi FVWM -Comment[sr]=Менаџер прозора са NeXTStep-овим изгледом и осећајем, заснован на FVWM-у -Comment[sr@Latn]=Menadžer prozora sa NeXTStep-ovim izgledom i osećajem, zasnovan na FVWM-u -Comment[sv]=Fönsterhanterare med Nextstep-utseende och -känsla, baserad på FVWM -Comment[ta]=FVWM அடிப்படையிலான NeXTStep உடனான சாளர மேலாளர். -Comment[tg]=Мудири равзанаҳо дар асоси FVWM дорои намуди NeXTStep -Comment[th]=ระบบจัดการหน้าต่างที่มีรูปแบบและสัมผัสของระบบปฏิบัติการ NeXTStep โดยใช้พื้นฐานของ FVWM -Comment[tr]=NeXTStep görünümlü bir pencere yöneticisi -Comment[tt]=FVWM asılında qorılğan, NeXTStep küreneşe belän täräzä-idäräçe -Comment[uk]=Менеджер вікон з виглядом та поведінкою NeXTStep, заснований на FVWM -Comment[uz]=FVWM asosida yaratilgan NeXTStep'ga oʻxshash oyna boshqaruvchi -Comment[uz@cyrillic]=FVWM асосида яратилган NeXTStep'га ўхшаш ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ với giao diện NeXTStep, dựa trên FVWM -Comment[wa]=On manaedjeu di purneas avou l' rivnance di NeXTStep, båzé so FVWM -Comment[zh_CN]=一个带有 NeXTStep 观感的窗口管理器,基于 FVWM -Comment[zh_TW]=一個基於 FVWM 並擁有 NeXTStep 外觀及感覺的視窗管理程式 diff --git a/kdm/kfrontend/sessions/amaterus.desktop b/kdm/kfrontend/sessions/amaterus.desktop deleted file mode 100644 index 3c52ee180..000000000 --- a/kdm/kfrontend/sessions/amaterus.desktop +++ /dev/null @@ -1,75 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=amaterus -TryExec=amaterus -Name=AMATERUS -Name[hi]=एमेच्योर्स -Name[te]=అమాటెరస్ -Comment=A GTK+ based window manager with a window grouping feature -Comment[af]='n GTK+ gebaseerde venster bestuurder met 'n venster groepering funksie -Comment[ar]=مدير نوافذ مبني على GTK+ له ميزة تجميع النوافذ -Comment[be]=Кіраўнік вокнаў, заснаваны на GTK+, са здольнасцю групавання вокнаў -Comment[bn]=GTK+ ভিত্তিল উইণ্ডো ম্যানেজার, যাতে উইণ্ডো গ্রুপিং করা যায় -Comment[bs]=Window manager baziran na GTK+ sa mogućnošću grupisanja prozora -Comment[ca]=Un gestor de finestres de GTK+ amb una característica per a l'agrupament de finestres -Comment[cs]=Správce oken založený na GTK+ s funkcí seskupování okne -Comment[csb]=Menedżer òknów brëkùjący GTK+, z optacëją grëpòwaniô òknów -Comment[cy]=Trefnydd ffenestri wedi'i seilio ar GTK+, efo nodwedd casglu ffenestri -Comment[da]=En GTK+ baseret vindueshåndtering med en vinduesgrupperingsegenskab -Comment[de]=Auf GTK+ basierender Fenstermanager mit Gruppierungsfunktion für die Fenster -Comment[el]=Ένας διαχειριστής παραθύρων βασισμένος στο GTK+ με ένα χαρακτηριστικό ομαδοποίησης παραθύρων -Comment[eo]=Fenestroadministrilo kun ebleco kunigi fenestrojn, kiu uzas GTK+ -Comment[es]=Un gestor de ventanas basado en GTK+ con la posibilidad de agrupar ventanas -Comment[et]=GTK+-le tuginev aknahaldur akende grupeerimise võimalusega -Comment[eu]=GTK+-n oinarritutako leiho kudeatzailea, leihoak taldeka biltzeko gaitasuna duena -Comment[fa]=یک GTK+ بر مبنای مدیر پنجره توسط ویژگی گروهی کردن پنجره‌ها -Comment[fi]=GTK+-pohjainen ikkunaohjelma ikkunoiden ryhmittely -ominaisuudella -Comment[fr]=Un gestionnaire de fenêtres écrit en GTK+, avec une fonctionnalité de groupement des fenêtres -Comment[fy]=In op GTK+ basearre finstersmanager mei finsterkeppelfûnksje -Comment[gl]=Un xestor de fiestras baseado en GTK+ con agrupamento de fiestras -Comment[he]=מנהל חלונות מבוסס GTK+ עם אפשרות לקבץ חלונות -Comment[hi]=जीटीके+ आधारित विंडो प्रबंधक, विंडो समूह विशेषता सहित -Comment[hr]=Upravitelj prozora zasnovan na GTK+ s mogućnošću grupiranja prozora -Comment[hu]=Egy GTK+-alapú ablakkezelő ablakcsoportosítási lehetőséggel -Comment[is]=Gluggastjóri sem hópar saman glugga og er byggður á GTK+ -Comment[it]=Un window manager basato su GTK+ con la possibilità di raggruppare le finestre -Comment[ja]=ウィンドウのグループ化が可能な GTK+ ベースのウィンドウマネージャ -Comment[ka]=ფანჯრის მენეჯერი GTK+ ს ბაზაზე ფანჯრების დაჯგუფების ფუნქციით -Comment[kk]=GTK+ негіздеген, терезелерді топтастыру қасиеті бар, терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ផ្អែក​លើ GTK+ ដែល​មាន​លក្ខណៈ​ពិសេស​ដាក់​បង្អួច​ជា​ក្រុម -Comment[ko]=창 그룹 기능을 사용하는 GTK+ 기반 창 관리자 -Comment[lt]=GTK+ paremta langų tvarkyklė su langų grupavimo galimybe -Comment[lv]=GTK+ bāzēts logu menedžeris ar logu grupēšanas iespēju -Comment[mk]=GTK+ базиран менаџер на прозорци со можност за групирање на прозорци -Comment[mn]=A GTK+ суурилсан цонх бүлэглэгчтэй цонх удирдагч -Comment[mt]=Window manager ibbażat fuq GTK+ b'faċilitajiet ta' gruppi ta' windows -Comment[nb]=En vindusbehandler basert på GTK+ med vindusgruppering -Comment[nds]=En Finsterpleger opbuut op GTK+, kann Finstern in Koppeln tosamenfaten -Comment[ne]=सञ्झ्याल समूह विशेषतासँग GTK+ मा आधारित सञ्झ्याल प्रबन्धक -Comment[nl]=Een op GTK+ gebaseerde windowmanager met venstergroeperingfunctionaliteit -Comment[nn]=Ein GTK+-basert vindaugssjef med vindaugsgruppering -Comment[pa]=ਇੱਕ GTK+ ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਜੋ ਕਿ ਝਰੋਖਿਆਂ ਨੂੰ ਇੱਕ ਥਾਂ ਸੰਭਾਲਣ ਦੀ ਸਹੂਲਤ ਨਾਲ ਲੈੱਸ ਹੈ। -Comment[pl]=Menedżer okien korzystający z GTK+, z opcją grupowania okien -Comment[pt]=Um gestor de janelas baseado em GTK+ com uma funcionalidade de agrupamento de janelas -Comment[pt_BR]=Um gerenciador de janelas baseado em GTK+, com o recurso de agrupamento de janelas -Comment[ro]=Un manager de ferestre bazat pe GTK+ și cu posibilitatea de grupare a ferestrelor -Comment[ru]=Оконный менеджер на основе GTK+ c функцией группировки окон -Comment[rw]=GTK + bishingiye mugenga dirishya ifite idirishya rihuza ibiranga -Comment[se]=GTK+-vuođđoduvvon lásegieđahalli mii sáhttá sierra lásiid bidjat seamma joavkui -Comment[sk]=Správca okien založený na GTK+ s funkciou zoskupovania okien -Comment[sl]=Okenski upravitelj na osnovi GTK+ z možnostjo združevanja oken -Comment[sr]=Менаџер прозора заснован на GTK+-у са особином груписања прозора -Comment[sr@Latn]=Menadžer prozora zasnovan na GTK+-u sa osobinom grupisanja prozora -Comment[sv]=GTK+-baserad fönsterhanterare med en funktion för fönstergruppering -Comment[ta]=சாளர குழுப்பிரித்தல் தன்மையுடனான சாளர மேலாளர் அடிப்படையிலான GTK+. -Comment[tg]=Мудири равзанаҳо дар асоси GTK+ дорои фаъолияти гурӯҳ кардан равзанаҳо -Comment[th]=ตัวจัดการหน้าต่างที่ใช้พื้นฐานจาก GTK+ พร้อมด้วยความสามารถในการจัดกลุ่มหน้าต่าง -Comment[tr]=GTK+ tabanlı bir pencere yöneticisi -Comment[tt]=GTK+ asılında qorılğan, täräzälärne törkemli ala torğan täräzä-idäräçe -Comment[uk]=Менеджер вікон заснований на GTK+ з підтримкою групування вікон -Comment[uz]=A GTK+ asosida yaratilgan, oynalarni guruhlash imkoniyatiga ega oyna boshqaruvchi -Comment[uz@cyrillic]=A GTK+ асосида яратилган, ойналарни гуруҳлаш имкониятига эга ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ với khả năng tạo nhóm cửa sổ dựa trên GTK+ -Comment[wa]=On manaedjeu di purneas båzé so GTK+, avou ene fonccionålité di rgroupaedje des purneas -Comment[zh_CN]=一个基于 GTK+ 的窗口管理器,带有窗口成组特性 -Comment[zh_TW]=一個基於 GTK+ 的視窗管理程式並擁有視窗群組功能 diff --git a/kdm/kfrontend/sessions/amiwm.desktop b/kdm/kfrontend/sessions/amiwm.desktop deleted file mode 100644 index ced73c346..000000000 --- a/kdm/kfrontend/sessions/amiwm.desktop +++ /dev/null @@ -1,78 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=amiwm -TryExec=amiwm -Name=AmiWM -Name[eo]=AmiFA -Name[hi]=एमी-डबल्यूएम -Name[sv]=Ami WM -Name[te]=ఎమి డబ్ల్యు ఎం -Comment=The Amiga look-alike window manager -Comment[af]='n Amiga gebaseerde venster bestuurder -Comment[ar]=مدبِر نوافذ مشابه لِــ Amiga -Comment[be]=Кіраўнік вокнаў, падобны на Amiga -Comment[bn]=অ্যামিগার মত দেখতে উইণ্ডো ম্যানেজার -Comment[bs]=Window manager nalik na Amigu -Comment[ca]=Un gestor de finestres que dona l'aspecte d'un Amiga -Comment[cs]=Správce oken podobný Amize -Comment[csb]=Menedżer òknów szlachùjący za Amiga -Comment[cy]=Trefnydd ffenestri sy'n edrych yn debyg i'r Amiga -Comment[da]=Amiga-lignende vindueshåndtering -Comment[de]=Fenstermanager im Stil des Amiga -Comment[el]=Ο διαχειριστής παραθύρων με όψη αλά Amiga -Comment[eo]=Fenestroadministrilo kiel tiu de Amiga -Comment[es]=Un gestor de ventanas con el aspecto de Amiga -Comment[et]=Amiga välimusega aknahaldur -Comment[eu]=Amigaren itxura duen leiho kudeatzailea -Comment[fa]=Amiga شبیه مدیر پنجره -Comment[fi]=Amigan tyylinen ikkunaohjelma -Comment[fr]=Le gestionnaire de fenêtres ressemblant à Amiga -Comment[fy]=In Amiga-likens finstersmanager -Comment[gl]=Un xestor de fiestras coma o de Amiga -Comment[he]=מנהל החלונות הדומה ל־Amiga -Comment[hi]=अमीगा की तरह दिखने वाला विंडो प्रबंधक -Comment[hr]=Upravitelj prozora koji podsjeća na Amigu -Comment[hu]=Egy Amiga-szerű ablakkezelő -Comment[is]=Gluggastjóri sem líkist Amiga tölvunum -Comment[it]=Un window manager in stile Amiga -Comment[ja]=Amiga に似たウィンドウマネージャ -Comment[ka]=ფანჯრის მენეჯერი Amiga-ს სტილში -Comment[kk]=Amiga секілді терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រប់​បង្អួច​ស្រដៀង Amiga -Comment[ko]=Amiga를 닮은 창 관리자 -Comment[lt]=Langų tvarkyklė, panaši į Amiga -Comment[lv]=Amiga izskata logu menedžeris -Comment[mk]=Менаџер на прозорци со изглед на Amiga -Comment[mn]=Amiga look-alike Цонхны удирдагч -Comment[ms]=Pengurus tetingkap serupa Amiga -Comment[mt]=Window manager jixbaħ lill-Amiga -Comment[nb]=Vindusbehandler som ligner på Amiga -Comment[nds]=De Finsterpleger mit dat Utsehn vun den Amiga -Comment[ne]=अमिगा सञ्झ्याल प्रबन्धक जस्तो छ -Comment[nl]=Een Amiga-achtige windowmanager -Comment[nn]=Vindaugssjef som liknar på Amiga -Comment[pa]=ਅਮੀਗਾ ਵਰਗਾ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien naśladujący Amigę -Comment[pt]=O gestor de janelas com o visual do Amiga -Comment[pt_BR]=Um gerenciador de janelas com a aparência do Amiga -Comment[ro]=Manager de ferestre cu aspect Amiga -Comment[ru]=Оконный менеджер в стиле Amiga -Comment[rw]=Amiga ijya gusa na mugenga dirishya -Comment[se]=Amiga-lágan lásegieđahalli -Comment[sk]=Správca okien podobný systému Amiga -Comment[sl]=Okenski upravitelj, podoben Amiginemu -Comment[sr]=Менаџер прозора који подсећа на Амигу -Comment[sr@Latn]=Menadžer prozora koji podseća na Amigu -Comment[sv]=Fönsterhanteraren som ser ut som Amiga -Comment[ta]=சாளர மேலாளரை ஒத்த அமிகா -Comment[tg]=Монанди мудири тирезаи Amiga look -Comment[th]=ระบบจัดการหน้าต่างที่ดูเหมือน Amiga -Comment[tr]=Amiga görünümlü bir pencere yöneticisi -Comment[tt]=Amiga küreneşendä täräzä idäräçe -Comment[uk]=Менеджер вікон на штиб Amiga -Comment[uz]=Amiga'ga oʻxshash oyna boshqaruvchi -Comment[uz@cyrillic]=Amiga'га ўхшаш ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ nhìn giống Amiga -Comment[wa]=On manaedjeu di purneas rishonnant l' ci di l' Amiga -Comment[zh_CN]=Amiga 外观的窗口管理器 -Comment[zh_TW]=一個看起來像 Amiga 視窗管理程式 diff --git a/kdm/kfrontend/sessions/asclassic.desktop b/kdm/kfrontend/sessions/asclassic.desktop deleted file mode 100644 index e84a0977e..000000000 --- a/kdm/kfrontend/sessions/asclassic.desktop +++ /dev/null @@ -1,81 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=asclassic -TryExec=asclassic -Name=ASClassic -Name[af]= ASClassic -Name[cy]=ASClasurol -Name[eo]=KlasikaPP -Name[hi]=एएस-क्लॉसिक -Name[ne]=AS शास्त्रीय -Name[sv]=AS klassisk -Name[ta]=ASதரமான -Name[te]=ఏఎస్ క్లాసిక్ -Comment=AfterStep Classic, a window manager based on AfterStep v1.1 -Comment[af]=AfterStep Classic, 'n venster bestuurder wat op AfterStep v1.1 gebaseer is. -Comment[ar]=AfterStep كلاسيك، وهو مدير نوافذ مبني على AfterStep الإصدارة 1.1 -Comment[be]=Класічны AfterStep, кіраўнік вокнаў, заснаваны на AfterStep 1.1 -Comment[bn]=আফটার-স্টেপ ক্লাসিক: আফটার-স্টেপ ১.১ ভিত্তিক একটি উইণ্ডো ম্যানেজার -Comment[bs]=AfterStep Classic, window manager baziran na AfterStep v1.1 -Comment[ca]=El clàssic AfterStep, un gestor de finestres basat en AfterStep v1.1 -Comment[cs]=AfterStep Classic, správce oken založený na AfterStepu v1.1 -Comment[csb]=AfterStep Classic, menedżer òknów ùsôdzony na spòdlém AfterStep v1.1 -Comment[cy]=ÔlGam Clasurol, trefnydd ffenestri wedi'i seilio ar AfterStep v1.1 -Comment[da]=AfterStep Classic, en vindueshåndtering baseret på AfterStep v1.1 -Comment[de]=AfterStep Classic, ein Fenstermanager, der auf AfterStep v1.1 basiert -Comment[el]=AfterStep κλασικός, ένας διαχειριστής παραθύρων βασισμένος στον AfterStep v1.1 -Comment[eo]=Klasika Postpaŝo, fenestroadministrilo kiel Postpaŝo v1.1 -Comment[es]=AfterStep Classic, un gestor de ventanas basado en AfterStep v1.1 -Comment[et]=AfterStep Classic - aknahaldur, mille aluseks on AfterStep v1.1 -Comment[eu]=AfterStep Classic, AfterStep v1.1-en oinarrituta dagoen leiho kudeatzailea -Comment[fa]=AfterStep کلاسیک، مدیر پنجره بر اساس AfterStep نسخه ۱.۱ -Comment[fi]=AfterStep Classic, After Step v1.1:een pohjautuva ikkunaohjelma -Comment[fr]=AfterStep Classic, un gestionnaire de fenêtres fondé sur AfterStep v1.1 -Comment[fy]=AfterStep Classic, In finstersmanager basearre op AfterStep 1.1 -Comment[gl]=AfterStep Clásico, un xestor de fiestras baseado en AfterSetp v1.1 -Comment[he]=AfterStep Classic, מנהל חלונות המבוסס על AfterStep v1.1 -Comment[hi]=आफ्टरस्टेप क्लासिक, एक विंडो प्रबंधक जो आफ्टरस्टेप व.1 पर आधारित है -Comment[hr]=Klasični AfterStep, upravitelj prozora zasnovan na AfterStepu verzija 1.1 -Comment[hu]=AfterStep Classic ablakkezelő, az AfterStep v1.1 alapján -Comment[is]=Klassískur AfterStep gluggastjóri byggður á AfterStep v1.1 -Comment[it]=AfterStep Classico, un window manager basato su AfterStep v1.1 -Comment[ja]=AfterStep クラシック, AfterStep v1.1 ベースのウィンドウマネージャ -Comment[ka]=AfterStep Classic, ფანჯრის მენეჯერი AfterStep v1.1 -ის ბაზაზე -Comment[kk]=AfterStep v1.1 негіздеген AfterStep Classic терезе менеджері -Comment[km]=AfterStep បុរាណ,កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​ផ្អែក​លើ AfterStep v1.1 -Comment[ko]=AfterStrp 1.1 기반 창 관리자 -Comment[lt]=AfterStep Classic, langų tvarkyklė, paremta AfterStep v1.1 -Comment[lv]=Klasiskais Afterstep, logu menedžeris bāzēts uz AfterStem v1.1 -Comment[mk]=AfterStep Classic, менаџер на прозорци базиран на AfterStep v1.1 -Comment[mn]=AfterStep Classic, AfterStep v1.1 дээр суурилсан цонх удирдагч -Comment[mt]=AfterStep klassiku, window manager ibbażat fuq AfterStep v1.1 -Comment[nb]=AfterStep Classic, en vindusbehandler basert på AfterStep v1.1 -Comment[nds]=De AfterStepClassic-Finsterpleger is opbuut op AfterStep v1.1 -Comment[ne]=AfterStep शास्त्रीय, AfterStep v१.१ मा आधारित सञ्झ्याल प्रबन्धक -Comment[nl]=AfterStep Classic, een windowmanager gebaseerd op AfterStep 1.1 -Comment[nn]=AfterStep Classic, ein vindaugssjef som byggjer på AfterStep 1.1 -Comment[pa]=AfterStep ਟਕਸਾਲੀ, AfterStep v1.1 ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=AfterStep Classic, menedżer okien stworzony na podstawie AfterStep v1.1 -Comment[pt]=AfterStep Classic, um gestor de janelas baseado no AfterStep v1.1 -Comment[pt_BR]=AfterSep clássico, um gerenciador de janelas baseado no AfterStep v1.1 -Comment[ro]=AfterStep Classic, un manager de ferestre bazat pe AfterStep v1.1 -Comment[ru]=AfterStep Classic, оконный менеджер на основе AfterStep v1.1 -Comment[rw]=AfterStep Classic, mugenga dirishya ishingiye kuri AfterStep v1.1 -Comment[se]=AfterStep Classic, lásegieđahalli ráhkaduvvon AfterStep 1.1 vuođul -Comment[sk]=AfterStep Classic, správca okien založený na AfterStep v1.1 -Comment[sl]=AfterStep Classic, okenski upravitelj na osnovi AfterStep različice 1.1 -Comment[sr]=Класични AfterStep, менаџер прозора заснован на AfterStep-у верзије 1.1 -Comment[sr@Latn]=Klasični AfterStep, menadžer prozora zasnovan na AfterStep-u verzije 1.1 -Comment[sv]=Afterstep klassisk, en fönsterhanterare baserad på Afterstep version 1.1 -Comment[ta]=ஆஃப்டர்ஸ்டெப் க்ளாசிக், ஆஃப்டர்ஸ்டெப் க்ளாசிக் v1.1 அடிப்படையிலான சாளர மேலாளர் -Comment[tg]=Мудири равзанаҳои AfterStep Classic дар асоси AfterStep v1.1 -Comment[th]=AfterStep Classic คือระบบจัดการหน้าต่างที่ใช้ฐานของอาฟเตอร์สเตปเวอร์ชั่น 1.1 -Comment[tr]=AfterStep Classic pencere yöneticisi -Comment[tt]=AfterStep Classic, AfterStep v1.1 asılında täräzä-idäräçe -Comment[uk]=AfterStep Classic, менеджер вікон, заснований на AfterStep v1.1 -Comment[uz]=AfterStep Classic - AfterStep v1.1 asosida yaratilgan oyna boshqaruvchi -Comment[uz@cyrillic]=AfterStep Classic - AfterStep v1.1 асосида яратилган ойна бошқарувчи -Comment[vi]=AfterStep Classic, một trình quản lý cửa sổ dựa trên AfterStep v1.1 -Comment[wa]=AfterStep Classic, on manaedjeu di purneas båzé so AfterStep v1.1 -Comment[zh_CN]=AfterStep 经典,一个基于 AfterStep v1.1 的窗口管理器 -Comment[zh_TW]=AfterStep 經典, 一個基於 AfterStep v1.1 的視窗管理程式 diff --git a/kdm/kfrontend/sessions/blackbox.desktop b/kdm/kfrontend/sessions/blackbox.desktop deleted file mode 100644 index 457ec7614..000000000 --- a/kdm/kfrontend/sessions/blackbox.desktop +++ /dev/null @@ -1,88 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=blackbox -TryExec=blackbox -Name=Blackbox -Name[bn]=ব্ল্যাকবক্স -Name[cy]= Du-flwch (Blackbox) -Name[eo]=Negrujo -Name[hi]=ब्लेकबॉक्स -Name[ja]=BlackBox -Name[mn]=Хар хайрцаг -Name[ne]=कालो बाकस -Name[pa]=ਕਾਲਾਬਕਸਾ -Name[rw]=AgasandukuUmukara -Name[ta]=கறுப்புப் பெட்டி -Name[te]=నల్లడబ్బా -Name[tg]=Қуттии сиёҳ -Comment=A fast & light window manager -Comment[af]='n Vinnige, lig gewig venster bestuurder -Comment[ar]=مدير نوافذ خفيف وسريع -Comment[be]=Хуткі і лёгкі кіраўнік вокнаў -Comment[bg]=Бърз и лек мениджър на прозорци -Comment[bn]=একটি হালকা এবং দ্রুত উইণ্ডো ম্যানেজার -Comment[bs]=Brz i lagan window manager -Comment[ca]=Un gestor de finestres ràpid i clar -Comment[cs]=Rychlý a malý správce oken -Comment[csb]=Chùtczi menedżer òknów o môłëch żądaniach -Comment[cy]=Trefnydd ffenestri cyflym ac ysgafn -Comment[da]=En hurtig & let vindueshåndtering -Comment[de]=Kleiner, schneller Fenstermanager -Comment[el]=Ένας γρήγορος και ελαφρύς διαχειριστής παραθύρων -Comment[eo]=Rapida kaj malpeza fenestroadministrilo -Comment[es]=Un gestor de ventanas rápido y ligero -Comment[et]=Kiire ja vähenõudlik aknahaldur -Comment[eu]=Leiho kudeatzaile bizkor eta arina -Comment[fa]=یک مدیر پنجرۀ سبک و سریع -Comment[fi]=Kevyt ja nopea ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres rapide et léger -Comment[fy]=In flugge lichtgewicht finstersmanager -Comment[ga]=Bainisteoir fuinneoga gasta éadrom -Comment[gl]=Un xestor de fiestras lixeiro e rápido -Comment[he]=מנהל חלונות מהיר וקל -Comment[hi]=तेज और सरल विंडो प्रबंधक -Comment[hr]=Brzi i lagani upravitelj prozora -Comment[hu]=Egy gyors, egyszerű ablakkezelő -Comment[is]=Léttur og hraðvirkur gluggastjóri -Comment[it]=Un window manager veloce e leggero -Comment[ja]=軽快なウィンドウマネージャ -Comment[ka]=სწრაფი და მსუბუქი ფანჯრის მენეჯერი -Comment[kk]=Жедел және жеңіл терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​លឿន ហើយ​ភ្លឺ -Comment[ko]=빠르고 가벼운 창 관리자 -Comment[lt]=Greita ir nedaug resursų naudojanti langų tvarkyklė -Comment[lv]=Ātrs un viegls logu menedžeris -Comment[mk]=Брз и лесен менаџер на прозорци -Comment[mn]=Хурдан & хөнгөн цонхны удирдагч -Comment[ms]=Pengurus tetingkap yang pantas & ringan -Comment[mt]=Window manager ħafif u żgħir -Comment[nb]=En rask og lett vindusbehandler -Comment[nds]=En gaue un lütte Finsterpleger -Comment[ne]=छिटो र हल्का सञ्झ्याल प्रबन्धक -Comment[nl]=Een snelle lichtgewicht windowmanager -Comment[nn]=Ein rask og lett vindaugssjef -Comment[pa]=ਇੱਕ ਤੇਜ਼ ਅਤੇ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Szybki menedżer okien o małych wymaganiach -Comment[pt]=Um gestor de janelas rápido e leve -Comment[pt_BR]=Um gerenciador de janelas rápido e leve -Comment[ro]=Un manager de ferestre mic și rapid -Comment[ru]=Быстрый и лёгкий оконный менеджер -Comment[rw]=Mugenga dirishya yihuta & yoroshye -Comment[se]=Jođánis ja geahpes lásegieđahalli -Comment[sk]=Rýchly a nenáročný správca okien -Comment[sl]=Hiter in lahek okenski uporavljalnik -Comment[sr]=Брзи и лагани менаџер прозора -Comment[sr@Latn]=Brzi i lagani menadžer prozora -Comment[sv]=Snabb och lättviktig fönsterhanterare -Comment[ta]=விரைவான மற்றும் இலகுவான KDE சாளர மேலாளர் -Comment[tg]=Суст ва мудири тирезаи равшан -Comment[th]=ระบบจัดการหน้าต่างที่เร็วและเบา -Comment[tr]=Hızlı ve hafif bir pencere yöneticisi -Comment[tt]=Citez ciñel täräzä-idäräçe -Comment[uk]=Легкий та швидкий менеджер вікон -Comment[uz]=Tez va oddiy oyna boshqaruvchi -Comment[uz@cyrillic]=Тез ва оддий ойна бошқарувчи -Comment[vi]=Một trình quản lý cửa sổ nhẹ và nhanh -Comment[wa]=On ledjir et roed manaedjeu di purneas -Comment[zh_CN]=又快又轻巧的窗口管理器 -Comment[zh_TW]=一個快速及輕量化的視窗管理程式 diff --git a/kdm/kfrontend/sessions/cde.desktop b/kdm/kfrontend/sessions/cde.desktop deleted file mode 100644 index 1f2dee088..000000000 --- a/kdm/kfrontend/sessions/cde.desktop +++ /dev/null @@ -1,74 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=/usr/dt/bin/Xsession -TryExec=/usr/dt/bin/Xsession -Name=CDE -Name[hi]=सीडीई -Name[mn]=КДE -Name[te]=సిడిఈ -Name[tg]=Муҳити графикии муштарак (CDE) -Name[th]=แบบ CDE -Comment=The Common Desktop Environment, a proprietary industry standard desktop environment -Comment[af]=Die 'Common Desktop Environment', 'n beskermde, industrie standaard werkskerm omgewing -Comment[ar]=محيط سطح المكتب الشائع، محيط سطح المكتب الصناعي المعايير -Comment[be]=Common Desktop Environment, прапрыетарнае стандартнае працоўнае асяроддзе -Comment[bn]=কমন ডেস্কটপ এনভায়রনমেন্ট (Common Desktop Environment), একটি মালিকানাধীন ইনডাস্ট্রি স্ট্যান্ডার্ড -Comment[bs]=Common Desktop Environment, vlasnička desktop okolina, industrijski standard -Comment[ca]=The Common Desktop Environment, l'entorn d'escriptori estàndard de la indústria propietària -Comment[csb]=Common Desktop Environment, sztandardowé industrëjné òkrãże pùltu -Comment[cy]=Yr Amgylchedd Penbwrdd Cyffredin (Common Desktop Environment), amgylchedd penbwrdd perchnogol sy'n safonol yn y diwydiant -Comment[da]=Common Desktop Environment, et privatejet industristandard desktopmiljø -Comment[de]=Das Common Desktop Environment, eine proprietäre Arbeitsumgebung und ein Industriestandard -Comment[el]=To Κοινό Περιβάλλον Επιφάνειας εργασίας, ένα βιομηχανικό πρότυπο επιφάνειας εργασίας -Comment[eo]=La Komuna Labortablo Ĉirkaŭaĵo -Comment[es]=El Common Desktop Environment, un estándar en los entornos de escritorio propietarios -Comment[et]=Üldine töölaua keskond (Common Desktop Environment) on kaubanduslik standardne töölaua keskkond -Comment[eu]=Common Desktopo Environment, mahaigain jabedun inguruneetako estandarra -Comment[fa]=محیط رومیزی مشترک، محیط رومیزی استاندارد صنعت اختصاصی -Comment[fi]=Common Desktop Environment, patentoitu työpöytäympäristöjen teollisuusstandardi -Comment[fr]=Le Common Desktop Environment, un environnement de bureau propriétaire standard dans l'industrie -Comment[fy]=The Common Desktop Environment, In kommersjele yndustrieel standerdisearre buroblêd omwrâld -Comment[gl]=O Common Desktop Environment, un entorno de escritório proprietario estándar para industria -Comment[he]=The Common Desktop Environment, סביבת עבודה מסחרית וקניינית סטנדרטית -Comment[hi]=सामूहिक डेस्कटॉप माहौल, एक स्वामित्व युक्त औद्योगिक मानक डेस्कटॉप माहौल -Comment[hr]=Opće okruženje radne površine, standardizirano industrijskim vlasništvima -Comment[hu]=The Common Desktop Environment, egy kereskedelmi, kváziszabványnak számító grafikus környezet -Comment[is]=Common Desktop Environment er lokað skjáborðsumhverfi sem var staðlað umhverfi til skamms tíma -Comment[it]=Il Common Desktop Environment, un desktop environment proprietario standard. -Comment[ja]=Common Desktop Environment,プロプライエタリな業界標準のデスクトップ環境 -Comment[ka]=Common Desktop Environment, UNIX -ის სამუშაო სფეროს სამრეწვლო სტანდარტი -Comment[kk]=Common Desktop Environment - UNIX жұмыс ортаның өнеркәсіп стандарты -Comment[km]=The Common Desktop Environment, បរិស្ថាន​ផ្ទៃតុ​ខ្នាត​គំរូ​ដែល​មាន​កម្មសិទ្ធិ -Comment[lt]=Common Desktop Environment, nuosavybinių sistemų standartinė darbastalio tvarkyklė -Comment[mk]=Common Desktop Environment, сопственичка индустриски стандардна работна околина -Comment[mn]=Нийтлэг дэлгэцийн системийн орчин, үйлдвэрийн стандарт дэлгэцийн системийн орчин -Comment[ms]=Persekitaran Desktop Biasa, persekitaran desktop standard industri proprietari -Comment[mt]=Common Desktop Environment, ambjent grafiku propjetarju u standard tal-industrija -Comment[nb]=Common desktop Environment, et godseid skrivebordsmiljø som er standard i programvareindustrien -Comment[nds]=De Common Desktop Environment, de Schriefdisch-Ümgeven vun en proprieteren Industrie-Standard -Comment[ne]=साझा डेस्कटप वातावरण, श: शुल्क उद्योग मानक डेस्कटप वातावरण -Comment[nl]=The Common Desktop Environment, een commerciële industrieel gestandariseerde desktop environment -Comment[nn]=Common Desktop Environment, eit godseigd skrivebordsmiljø som er standard i programvareindustrien -Comment[pa]=ਇੱਕ ਆਮ ਵੇਹੜਾ ਵਾਤਾਵਰਣ, ਇੱਕ ਵਪਾਰਿਕ ਮਿਆਰ ਦਾ ਵੇਹੜਾ ਵਾਤਾਵਰਣ -Comment[pl]=Common Desktop Environment, standardowe przemysłowe środowisko pulpitu -Comment[pt]=O Common Desktop Environment, um ambiente de trabalho gráfico padrão e proprietário -Comment[pt_BR]=O Ambiente de Trabalho Comum (CDE), um ambiente de trabalho proprietário padrão da indústria -Comment[ro]=Common Desktop Environment, un mediu grafic proprietar și devenit standard industrial -Comment[ru]=Common Desktop Environment, промышленный стандарт рабочей среды UNIX -Comment[rw]=Ibikikije Ibiro Rusange, ibikikije ibiro bisanzwe bwite by'isosiyete -Comment[se]=Common Desktop Environment, čállinbeavdebiras mii lea standárda prográmmagálvoindustriijas -Comment[sk]=The Common Desktop Environment, proprietárne štandardné pracovné prostredie -Comment[sl]=Common Desktop Environment, lastniško standardno industrijsko namizno okolje -Comment[sr]=„Common Desktop Environment“, власничко индустријски стандардно радно окружење -Comment[sr@Latn]=„Common Desktop Environment“, vlasničko industrijski standardno radno okruženje -Comment[sv]=Common Desktop Environment, en privatägd industristandard skrivbordsmiljö -Comment[ta]=பொதுவான மேல்மேசை, தன்உரிமை உடைய நிறுவனத்தின் நிலையான மேல்மேசை சூழல் -Comment[tg]=Common Desktop Environment дар асоси UNIX -Comment[th]=Common Desktop Environment คือ สภาพแวดล้อมของพื้นที่ทำงานที่ได้มาตรฐานอุตสาหกรรม ที่ไม่ใช่ซอฟต์แวร์เสรี -Comment[tr]=Common Desktop Environment (CDE) -Comment[tt]=Common Desktop Environment, UNIX öçen citeşterü standardı -Comment[uk]=The Common Desktop Environment, закритий промисловий стандарт графічного середовища -Comment[vi]=Môi trường Màn hình nền Chung, một môi trường màn hình nền giữ bản quyền, tuân thủ chuẩn công nghiệp -Comment[wa]=Li Comon Evironmint d' Sicribanne (Common Desktop Environment), on evironmint d' sicribanne nén libe po l' industreye -Comment[zh_CN]=通用窗口环境(CDE),私有工业标准的桌面环境 -Comment[zh_TW]=The Common Desktop Environment, 一個有專利的工業標準 diff --git a/kdm/kfrontend/sessions/ctwm.desktop b/kdm/kfrontend/sessions/ctwm.desktop deleted file mode 100644 index e7ee84471..000000000 --- a/kdm/kfrontend/sessions/ctwm.desktop +++ /dev/null @@ -1,72 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=ctwm -TryExec=ctwm -Name=CTWM -Name[eo]=TFAC -Name[hi]=सीटीडबल्यूएम -Name[te]=సి టి డబ్ల్యు ఎం -Comment=Claude's Tab Window Manager, TWM enhanced by virtual screens, etc. -Comment[af]=Claude se Tab venster bestuurder. Dis TWM wat met virtuele skerms verbeter is -Comment[ar]=مدير نوافذ Claude's Tab، وهي TWM محسّن بشاشات وهمية، إلخ. -Comment[be]=Кіраўнік вокнаў з укладкамі ад Claude, TWM з падтрымкай віртуальных экранаў і інш. -Comment[bg]=Claude"s Tab Window Manager, TWM enhanced by virtual screens, etc. -Comment[bn]=ক্লড-এর ট্যাব উইণ্ডো ম্যানেজার -Comment[bs]=Claude's Tab Window Manager, TWM proširen virtuelnim ekranima itd. -Comment[ca]=Gestor de finestres amb pestanyes d'en Claude, millores TWM per a pantalles virtuals, etc. -Comment[csb]=Menedżer òknów Claude, TWM zbògacony ò wirtualné pùltë, ëtp. -Comment[cy]=Trefnydd Ffenestri Tab Claude, TWM wedi ei wella gan sgriniau rhith, ayyb. -Comment[da]=Claude's Tab vindueshåndtering, TWM udvidet med virtuelle skærme osv. -Comment[de]=Claudes Fenstermanager mit Karteikartenfenstern, eine verbesserte Fassung von TWM mit virtuellen Ansichten usw. -Comment[el]=Ο διαχειριστής παραθύρων Tab του Claude, ο TWM εμπλουτισμένος με εικονικές οθόνες, κτλ. -Comment[eo]=Taba Fenestroadministrilo de Claude, TWM, bonigita per virtualaj ekranoj ktp -Comment[es]=Claude's Tab Window Manager, TWM mejorado con pantallas virtuales, etc. -Comment[et]=Claude kaartidega aknahaldur, aluseks TWM, mida on täiendatud virtuaaltöölaudadega jne. -Comment[eu]=Claude's Tab leiho kudeatzailea, pantaila birtual eta abarrez hobetutako TWMa -Comment[fa]=مدیر پنجرۀ تب Claude، TWM، گسترش‌یافته توسط پرده‌های مجازی و غیره. -Comment[fi]=Clauden välilehtiikkunaohjelma. TWM, johon lisätty muun muassa virtuaalityöpöydät. -Comment[fr]=Claude's Tab Window Manager, TWM avec en plus les bureaux virtuels, etc. -Comment[fy]=Claude's Tab _indow Manager, TWM útbreide mei firtuele skermen etc. -Comment[gl]=Xestor de Fiestras de Claude, TWM mellorado con pantallas virtuais, etc. -Comment[he]=Claude's Tab Window Manager, TWM המשופרת על ידי מסכים וירטואליים וכו' -Comment[hi]=क्लाउडे का टैब युक्त विंडो प्रबंधक, टीडबल्यूएम को आभासी स्क्रीन इत्यादि से बेहतर बनाया गया. -Comment[hr]=Claudov Tab upravitelj prozora, TWM poboljšan virtualnim zaslonima, itd. -Comment[hu]=Claude lapozós ablakkezelője, lényegében a TWM, kiegészítve virtuális képernyőkkel, egyebekkel -Comment[is]=Tab gluggastjórinn eftir Claude sem hefur verið endurbættur með sýndarskjáum og fl. -Comment[it]=Window manager con linguette di Claude, TWM migliorato con schermi virtuali, ecc. -Comment[ja]=TWM に仮想デスクトップなどを強化した Claude のウィンドウマネージャ -Comment[ka]=Claude's Tab Window Manager - TWM-ის გაუმჯობესებული ვერსია -Comment[kk]=Claude's Tab Window Manager, TWM-ның жетілдірген нұсқасы. -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ជា​ផ្ទាំង​របស់ Claude, TWM ដែល​ធ្វើ​ឲ្យ​ប្រសើរ​ដោយ​អេក្រង់​និមិត្ត​ជាដើម -Comment[lt]=Claude kortelių langų tvarkyklė, TWM praplėsta virtualių ekranų palaikymu ir t.t. -Comment[mk]=Claude's Tab Window Manager, TWM подобрен менаџер со виртуелни екрани итн. -Comment[mn]=Клаудиагийн  ТАВ цонхны удирдагч, TWM виртуал дэлгэцээр өргөтгөгдсөн, гэх мэт. -Comment[mt]=Claude's Tab Window Manager, TWM flimkien ma' virtual screens, eċċ. -Comment[nb]=Claude's Tab Window Manager, TWM forbedret med virtuelle skrivebord,osv. -Comment[nds]=Claude's Tab Finsterpleger, TWM verbetert üm virtuelle Schriefdischen usw. -Comment[ne]=क्लाउडको ट्याब सञ्झ्याल प्रबन्धक, अवास्तविक पर्दाद्वारा बृद्धि गरिएको TWM, आदि -Comment[nl]=Claude's Tab Window Manager, TWM uitgebreid met virtuele schermen etc. -Comment[nn]=Claude's Tab Window Manager, TWM med virtuelle skrivebord og andre forbetringar -Comment[pa]=ਕਲਾਉਡੀ ਦਾ ਟੈਬ ਝਰੋਖਾ ਮੈਨੈਜਰ, TWM ਫਰਜ਼ੀ ਪਰਦਿਆਂ ਆਦਿ ਨਾਲ ਲੈੱਸ ਹੈ। -Comment[pl]=Menedżer okien Claude, TWM wzbogacony o wirtualne pulpity, itp. -Comment[pt]=O Tab Window Manager do Claude, um TWM melhorado com ecrãs virtuais, etc. -Comment[pt_BR]=O gerenciador de janelas em abas do Claude, o TWM melhorado pelas telas virtuais, etc. -Comment[ro]=Managerul de ferestre al lui Claude, o versiune îmbunătățită de TWM cu ecrane virtuale etc. -Comment[ru]=Claude's Tab Window Manager - улучшенная версия TWM -Comment[rw]=Mugenga Dirishya y'Agafishi ya Claude, TWM ivuguruwe na mugaragaza zitagaragara, n'ibindi -Comment[se]=Claudea Tab Window Manager, TWM mas lea virtuella čállinbeavddit ja eará buorideamit. -Comment[sk]=Claude's Tab Window Manager, TWM rozšírený o virtuálne plochy, atď. -Comment[sl]=Claude's Tab Window Manager, TWM izboljšan z navideznimi zasloni ipd. -Comment[sr]=„Claude's Tab Window Manager“, TWM побољшан виртуелним екранима и сл. -Comment[sr@Latn]=„Claude's Tab Window Manager“, TWM poboljšan virtuelnim ekranima i sl. -Comment[sv]=Claudes fönsterhanterare med flikar, TWM förbättrad med virtuella skärmar, etc. -Comment[ta]= க்ளூடின் தத்தல் சாளர மேளாளர், TWM ஆல் மேம்படுத்தப்பட்ட மெய்நிகர் திரைகள்.. -Comment[tg]=Claude's Tab Window Manager - Версияи навтарини TWM -Comment[th]=ตัวจัดการแท็บหน้าต่างของ Claude คือ TWM ที่เพิ่มความสามารถด้วยหน้าจอเสมือน และอื่นๆ -Comment[tr]=Claude's Sekme Pencere Yöneticisi, sanal ekranlar ile TWM genişletilmiş, vb. -Comment[tt]=Claude's Tab Window Manager, TWM'nıñ qulaylanğan töre -Comment[uk]=Claude's Tab Window Manager, TWM з підтримкою віртуальних екранів, тощо. -Comment[vi]=Trình quản lý cửa sổ kiểu Thẻ của Claude, TWM cải tiến với màn hình ảo v.v. -Comment[wa]=Li Manaedjeu di Purneas a Linwetes di Claude (Claude's Tab Window Manager). TWM permete des forveyowès waitroûles, evnd. -Comment[zh_CN]=Claude 的标签式窗口管理器,加强了虚拟屏幕等功能的 TWM。 -Comment[zh_TW]=Claude's Tab 視窗管理程式, 基於 TWM 並加強虛擬螢幕等功能 diff --git a/kdm/kfrontend/sessions/cwwm.desktop b/kdm/kfrontend/sessions/cwwm.desktop deleted file mode 100644 index 51b60abd3..000000000 --- a/kdm/kfrontend/sessions/cwwm.desktop +++ /dev/null @@ -1,74 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=cwwm -TryExec=cwwm -Name=CWWM -Name[eo]=CWFA -Name[hi]=सीडबल्यूडबल्यूएम -Name[te]=సి డబ్ల్యు డబ్ల్యు ఎం -Comment=The ChezWam Window Manager, a minimalist window manager based on EvilWM -Comment[af]=Die ChezWam venster bestuurder. Dis 'n minimalistiese venster bestuurder wat op EvilWM gebaseer is. -Comment[ar]=مدير نوافذ ChezWam، وهو مدير نوافذ مصغّر مبني على EvilWM -Comment[be]=Кіраўнік вокнаў ChezWam, мінімалістычны, заснаваны на EvilWM -Comment[bn]=ChezWam উইণ্ডো ম্যানেজার, EvilWM ভিত্তিক একটি উইণ্ডো ম্যানেজার -Comment[bs]=ChezWam Window Manager, minimalistički window manager baziran na EvilWM -Comment[ca]=El gestor de finestres ChezWam, un gestor de finestres minimalista basat en EvilWM -Comment[cs]=ChezWam, minimalistický správce oken založený na EvilWM -Comment[csb]=Menedżer òknów ChezWam, prosti menedżer òknów ùsôdzony na spòdlém EvilWM -Comment[cy]=Y Trefnydd Ffenestri ChezWam, trefnydd ffenestri lleiafol wedi'i seilio ar EvilWM -Comment[da]=ChezWam vindueshåndteringen, en minimalistisk vindueshåndtering baseret på EvilWM -Comment[de]=Deer ChezWam-Fenstermanager, eine minimalistische Lösung, die auf EvilWM basiert -Comment[el]=Ο ChezWam διαχειριστής παραθύρων, ένας μινιμαλιστικός διαχειριστής παραθύρων βασισμένος στον EvilWM -Comment[eo]=La ChezWam Fenestroadministrilo, devenigita de MalbonaFA -Comment[es]=El gestor de ventanas ChezWam, un gestor minimalista basado en EvilWM -Comment[et]=ChezWami aknahaldur on vähenõudlik aknahaldur, mille aluseks on EvilWM -Comment[eu]=ChezWarn leiho kudeatzailea, EvilWM-en oinarritutako leiho kudeatzaile minimalista -Comment[fa]=مدیر پنجره ChezWam، مدیر پنجرۀ کمینه بر اساس EvilWM -Comment[fi]=ChezWam, minimalistinen EvilWM:ään pohjautuva ikkunaohjelma. -Comment[fr]=Le ChezWam Window Manager, un gestionnaire de fenêtres minimaliste fondé sur EvilWM -Comment[fy]=The ChezWam Window Manager, in minimalistyske finstersmanager baseare op EvilWM -Comment[gl]=O Xestor de Fiestras ChezWarm, un xestor minimalista baseado en EvilWM -Comment[he]=The ChezWam Window Manager, מנהל חלונות מינימליסטי המבוסס על EvilWM -Comment[hi]=चेकवाम विंडो प्रबंधक, एक अल्पतम विंडो प्रबंधक EvilWM पर आधारित -Comment[hr]=ChezWam, minimalistički upravitelj prozora zasnovan na EvilWM -Comment[hu]=ChezWam ablakkezelő, egy nagyon egyszerű ablakkezelő az EvilWM alapján -Comment[is]=ChezWam gluggastjórinn er lágmarks gluggastjóri sem er byggður á EvilWM -Comment[it]=Il ChezWam Window Manager, un window manager minimalista basato su EvilWM -Comment[ja]=ChezWam ウィンドウマネージャ, EvilWM ベースの小さなウィンドウマネージャ -Comment[ka]=ChezWam Window Manager - მინიმალისტური ფანჯრის მენეჯერი EvilWM -ის ბაზაზე -Comment[kk]=ChezWam Window Manager, EvilWM-негіздеген шағын терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច ChezWam ដែល​ជា​កម្មវិធី​គ្រប់គ្រង​បង្អួច​មិន​សូវ​សម្បូរ​បែប​ហើយ​ផ្អែក​លើ EvilWM -Comment[lt]=ChezWam langų tvarkyklė, minimalistinė langų tvarkyklė, paremta EvilWM -Comment[mk]=ChezWam Window Manager, минималистички менаџер на прозорци базиран на EvilWM -Comment[mn]=ChezWam Цонхны удирдагч, EvilWM дээр суурилсан хамгийн жижиг цонхны удирдагч -Comment[mt]=ChezWam Window Manager - window manager minimu ibbażat fuq EvilWM -Comment[nb]=The ChezWam Window Manager, en minimalistisk vindusbehandler basert på EvilWM -Comment[nds]=De ChezWam Finsterpleger is minimalistisch un buut op EvilWM op -Comment[ne]=चेजवाम सञ्झ्याल प्रबन्धक, EvilWM आधारित मिनिमलिस्ट सञ्झ्याल प्रबन्धक -Comment[nl]=The ChezWam Window Manager, een minimalistische windowmanager gebaseerd op EvilWM -Comment[nn]=ChezWam Window Manager, ein minimalistisk vindaugssjef som byggjer på EvilWM -Comment[pa]=ChezWam ਝਰੋਖਾ ਮੈਨੇਜਰ, ਇੱਕ EvilWM ਤੇ ਆਧਾਰਿਤ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ ਹੈ -Comment[pl]=Menedżer okien ChezWam, prosty menedżer okien stworzony na podstawie EvilWM -Comment[pt]=O ChezWam Window Manager, um gestor de janelas minimalista baseado no EvilWM -Comment[pt_BR]=O gerenciador de janelas de ChezWam, um gerenciador de janelas minimalista baseado no EvilWM -Comment[ro]=Managerul de ferestre ChezWam, o versiune minimalistică bazată pe EvilWM -Comment[ru]=ChezWam Window Manager - минимальный оконный менеджер на основе EvilWM -Comment[rw]=Mugenga Dirishya ChezWam, mugenga dirishya igira-nto ishingiye kuri EvilWM -Comment[se]=ChezWam Window Manager, ein minimalisttalaš lásegieđahalli, ráhkaduvvon EvilWM vuođul -Comment[sk]=The ChezWam Window Manager, minimálny správca okien založený na EvilWM -Comment[sl]=ChezWam Window Manager, skromen okenski upravitelj na osnovi EvilWM -Comment[sr]=„ChezWam Window Manager“, минималистички менаџер прозора заснован на EvilWM-у -Comment[sr@Latn]=„ChezWam Window Manager“, minimalistički menadžer prozora zasnovan na EvilWM-u -Comment[sv]=Fönsterhanteraren Chezwam, en minimalistisk fönsterhanterare baserad på Ond WM -Comment[ta]=செஸ்வாம் சாளர மேளாளர்,EvilWM ஐ அடிப்படையிலான குறைந்தபட்ச சாளர மேளாளர் -Comment[tg]=ChezWam Window Manager - Мудири равзанаҳои хурд дар асоси EvilWM -Comment[th]=ตัวจัดการหน้าต่าง ChezWarm คือ ระบบจัดการ หน้าต่างขนาดเล็ก สร้างจากพื้นฐานของ EvilWM -Comment[tr]=ChezWam Pencere Yöneticisi -Comment[tt]=ChezWam Window Manager, EvilWM asılında ciñel täräzä-idäräçe -Comment[uk]=Мінімалістичний менеджер вікон ChezWam, заснований на EvilWM -Comment[uz]=EvilWM asosida yaratilgan juda oddiy oyna boshqaruvchi -Comment[uz@cyrillic]=EvilWM асосида яратилган жуда оддий ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ ChezWam, một trình quản lý cửa sổ đơn giản dựa trên EvilWM -Comment[wa]=Li Manaedjeu di Purneas di ChezWam (ChezWam Window Manager). On manaedjeu di purneas tot simpe, båzé so EvilWM -Comment[zh_CN]=ChezWam 窗口管理器,基于 EvilWM 的最小化窗口管理器 -Comment[zh_TW]=The ChezWam 視窗管理程式,基於 EvilWM 的小型化視窗管理程式 diff --git a/kdm/kfrontend/sessions/enlightenment.desktop b/kdm/kfrontend/sessions/enlightenment.desktop deleted file mode 100644 index 66dcdd574..000000000 --- a/kdm/kfrontend/sessions/enlightenment.desktop +++ /dev/null @@ -1,86 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=enlightenment_start -TryExec=enlightenment -Name=Enlightenment -Name[bn]=এনলাইটেনমেন্ট -Name[cy]=Goleuni (Enlightenment) -Name[eo]=Lumaĵo -Name[fa]=روشن‌فکری -Name[hi]=एनलाइटनमेंट -Name[km]=ភ្លឺ -Name[mn]=Гэгээрэл -Name[ne]=बुद्धत्व -Name[pa]=ਗਿਆਨ -Name[rw]=Imurika -Name[ta]=விளக்கிக்கூறுதல் -Name[te]=జ్ఞానొదయం -Comment=An extremely themable very feature-rich window manager -Comment[af]='n Uitbreibare, tema geaktiveerde venster bestuurder -Comment[ar]=مدير نوافذ غني بالمزايا وقابل لاستخدام السّمات بشكل كبير. -Comment[be]=Абсалютна змяняльны, багаты на здольнасці кіраўнік вокнаў -Comment[bn]=প্রচুর বৈশিষ্ট্য সম্বলিত একটি উইণ্ডো ম্যানেজার, যা বহুভাবে নিজের পছন্দমত বদলে নেওয়া যায় -Comment[bs]=Izuzetno prilagodljiv window manager bogat opcijama -Comment[ca]=Un gestor de finestres extremadament temible molt ric en característiques -Comment[cs]=Na funkce bohatý správce oken s širokou škálou témat -Comment[csb]=Bògati w fùnkcëje menedżer òknów ò wiôldżich mòżnotach zjinaczi wëzdrzatkù -Comment[cy]=Trefnydd ffenestri sy'n llawn o nodweddion, efo llawer o themau. -Comment[da]=En ekstremt tema-fleksibel egenskabsrig vindueshåndtering -Comment[de]=Sehr design- und funktionsreicher Fenstermanager -Comment[el]=Ένας εξαιρετικά παραμετροποιήσιμος και πλούσιος σε χαρακτηριστικά διαχειριστής παραθύρων -Comment[eo]=Fenestroadministrilo kun tre multaj eblecoj -Comment[es]=Un gestor de ventanas lleno de características y extremadamente personalizable -Comment[et]=Äärmiselt paljude teemade ja väga laialdaste võimalustega aknahaldur -Comment[eu]=Gaitasun ugari dituen, eta zeharo pertsonalizagarria den leiho kudeatzailea -Comment[fa]=مدیر پنجره با ویژگی زیاد و شدیداً موضوعی -Comment[fi]=Erittäin muokattavissa oleva ominaisuusrikas ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres avec beaucoup de thèmes et de fonctionnalités -Comment[fy]=In tige rike en ynstelbere finstersmanager -Comment[gl]=Un xestor de fiestras moi configurábel en apariencia e rico en características -Comment[he]=מנהל חלונות פונקציונלי המכיל אפשרויות רבות להגדרת ערכות נושא -Comment[hi]=एक विंडो प्रबंधक जो अत्यंत प्रसंग युक्त तथा विशेषता से भरपूर है -Comment[hr]=Izuzetno prilagodljiv upravitelj prozora, bogat mogućnostima -Comment[hu]=Egy nagyon sokoldalúan témázható, sok lehetőséget biztosító ablakkezelő -Comment[is]=Afskaplega öflugur gluggastjóri með góðum þemastuðningi -Comment[it]=Un window manager estremamente temabile con molte funzionalità -Comment[ja]=詳細な部分までもテーマ化が可能な非常に多機能のウィンドウマネージャ -Comment[ka]=მრავალფუნქციური ფანჯრის მენეჯერი თემების მხარდაჭერით -Comment[kk]=Қасиеттер жағынан бай, көп тақырыпты терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​មាន​លក្ខណៈ​ពិសេស​សម្បូរ​បែប ដែល​អាច​ប្ដូរ​រូបរាង​បាន​តាម​ចិត្ត -Comment[ko]=다양한 곳을 꾸밀 수 있는 기능이 풍부한 창 관리자 -Comment[lt]=Daug temų ir savybių turinti langų tvarkyklė -Comment[lv]=Tēmām un iespējām bagāts logu menedžeris -Comment[mk]=Менаџер на прозорци богат со можности и екстремно подложен на стилизирање со теми -Comment[mn]=Маш ирээдүйтэй цонхны удирдагч -Comment[ms]=Pengurus tetingkap kaya ciri yang amat boleh tema -Comment[mt]=Window manager rikk u b'ħafna effetti viżwali. -Comment[nb]=En svært omfattende vindusbehandler som kan tilpasses med temaer -Comment[nds]=En Finsterpleger mit bannig vele Funkschonen un Mustern -Comment[ne]=अत्याधिक विषयवस्तु योग्य धेरै आकृति सञ्झ्याल प्रबन्धक -Comment[nl]=Een zeer rijke en configureerbare windowmanager -Comment[nn]=Ein svært omfattande vindaugssjef som kan tilpassast med tema -Comment[pa]=ਇੱਕ ਸਰੂਪ ਦੇ ਪੂਰੇ ਫੀਚਰਾਂ ਨਾਲ ਭਰਪੂਰ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Bogaty w funkcje menedżer okien o dużych możliwościach zmiany wyglądu -Comment[pt]=Um gestor de janelas muito rico em funcionalidades e extremamente personalizado na sua aparência -Comment[pt_BR]=Um gerenciador de janelas rico em recursos e extremamente configurável através de temas -Comment[ro]=Un manager de ferestre extrem de versatil și cu multe facilități -Comment[ru]=Многофункциональный, поддерживающий темы оконный менеджер -Comment[rw]=Mugenga Dirishya biranga-bikize cyane ngirwa-nsanganyamatsiko mu buryo burenze -Comment[se]=Lášegieđahalli mas leat erenoamáš ollu doaimmat ja maid sáhttá heivehit fáttáin -Comment[sk]=Správca okien s veľkým množstvom funkcií a extrémnou podporou tém -Comment[sl]=Okenski upravitelj, zelo prilagodljiv in poln možnosti -Comment[sr]=Изузетно прилагодљив менаџер прозора са пуно могућности -Comment[sr@Latn]=Izuzetno prilagodljiv menadžer prozora sa puno mogućnosti -Comment[sv]=En ytterst anpassningsbar mycket funktionsrik fönsterhanterare -Comment[ta]=நிறைய தன்மைகள் அடங்கிய சாளர மேளாளர் -Comment[tg]=Мудири равзанаҳо дорои мавзӯъҳои гуногун ва дигар бисёр функсияҳо -Comment[th]=ระบบจัดการหน้าต่างที่เต็มไปด้วยความสามารถ และใช้ชุดตกแต่งมากมาย -Comment[tr]=İleri derecede temalanabilir, özellik zengini bir masaüstü yöneticisi -Comment[tt]=Küpçaralı tışlanulı täräzä-idäräçe -Comment[uk]=Менеджер вікон з потужною підтримкою тем та різноманітних функцій -Comment[uz]=Mavzu va imkoniyatlarga juda boy oyna boshqaruvchi -Comment[uz@cyrillic]=Мавзу ва имкониятларга жуда бой ойна бошқарувчи -Comment[vi]=Một trình quản lý cửa sổ cực kỳ dễ thay đổi sắc thái với nhiều tích năng -Comment[wa]=On manaedjeu di purneas foirt bén po-z eployî des tinmes et foirt ritche en usteyes -Comment[zh_CN]=强主题化的多功能窗口管理器 -Comment[zh_TW]=一個功能相當豐富的視窗管理程式 diff --git a/kdm/kfrontend/sessions/evilwm.desktop b/kdm/kfrontend/sessions/evilwm.desktop deleted file mode 100644 index 3c8c4f657..000000000 --- a/kdm/kfrontend/sessions/evilwm.desktop +++ /dev/null @@ -1,77 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=evilwm -TryExec=evilwm -Name=EvilWM -Name[eo]=MalbonaFA -Name[hi]=एविलडबल्यूएम -Name[sv]=Ond WM -Name[te]=ఈవిల్ డబ్ల్యు ఎం -Comment=A minimalist window manager based on AEWM -Comment[af]='n Minimalistiese venster bestuurder wat op AEWM gebaseer is -Comment[ar]=مدير نوافذ مصغّر مبني على AEWM -Comment[be]=Кіраўнік вокнаў для мінімаліста, заснаваны на AEWM -Comment[bn]=AEWM ভিত্তিক একটি পরিমিত উইণ্ডো ম্যানেজার -Comment[bs]=Minimalistički window manager baziran na AEWM -Comment[ca]=Un gestor de finestres minimalista basat en AEWM -Comment[cs]=Minimalistický správce oken založený na AEWM -Comment[csb]=Prosti menedżer òknów ùsôdzony na spòdlém AEWM -Comment[cy]=Trefnydd ffenestri lleiafol wedi'i seilio ar AEM -Comment[da]=En minimalistisk vindueshåndtering baseret på AEWM -Comment[de]=Minimalistischer Fenstermanager, der auf AEWM basiert -Comment[el]=Ένας μινιμαλιστικός διαχειριστής παραθύρων βασισμένος στον AEWM -Comment[eo]=Minimumema fenestroadministrilo -Comment[es]=Un administrado de ventanas minimalista basado en AEWM -Comment[et]=Vähenõudlik aknahaldur, mille aluseks on AEWM -Comment[eu]=AEWMn oinarritutako leiho kudeatzaile minimalista -Comment[fa]=یک مدیر پنجرۀ کمینه براساس AEWM -Comment[fi]=Minimalistinen, AEWM:ään pohjautuva ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres fondé sur AEWM -Comment[fy]=In minimalistyske finstersmanager basearre op AEWM -Comment[gl]=Un xestor de fiestras minimalista baseado en AEWM -Comment[he]=מנהל חלונות מינימליסטי המבוסס על AEWM -Comment[hi]= एक अल्पतम विंडो प्रबंधक एईडबल्यूएम पर आधारित -Comment[hr]=Minimalistički upravitelj prozora zasnovan na AEWM-u -Comment[hu]=Egy nagyon egyszerű ablakkezelő az AEWM alapján -Comment[is]=Lágmarks gluggastjóri sem er byggður á AEWM -Comment[it]=Un window manager minimalista basato su AEWM -Comment[ja]=AEWM ベースの小さなウィンドウマネージャ -Comment[ka]=მინიმალისტური ფანჯრის მენეჯერი AEWM-ის ბაზაზე -Comment[kk]=AEWM-негіздеген шағын терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​លក្ខណៈ​ពិសេស​តិច ដែល​ផ្អែក​លើ AEWM -Comment[ko]=AEWM 기반 창 관리자 -Comment[lt]=Minimalistinė langų tvarkyklė, paremta AEWM -Comment[lv]=Minimālistisks logu menedžeris bāzēts uz AEWM -Comment[mk]=Минималистички менаџер на прозорци базиран на AEWM -Comment[mn]=AEWM дээр суурилсан цонхны удирдагч -Comment[mt]=Window manager minimu ibbażat fuq AEWM -Comment[nb]=En minimalistisk vindusbehandler basert på AEWM -Comment[nds]=En minimalistischen Finsterpleger, de op AEWM opbuut -Comment[ne]=AEWM आधारित मिनिमलिस्ट सञ्झ्याल प्रबन्धक -Comment[nl]=Een minimalistische windowmanager gebaseerd op AEWM -Comment[nn]=Ein minimalistisk vindaugssjef som byggjer på AEWM -Comment[pa]=AEWM ਤੇ ਆਧਾਰਿਤ ਨਿਊਨਤਮ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Prosty menedżer okien stworzony na podstawie AEWM -Comment[pt]=Um gestor de janelas minimalista baseado no AEWM -Comment[pt_BR]=Um gerenciador de janelas minimalista baseado no AEWM -Comment[ro]=Un manager de ferestre minimalistic bazat pe AEWM -Comment[ru]=Минимальный оконный менеджер, основанный на AEWM -Comment[rw]=Mugenga dirishya igira-nto ishingiye kuri AEWM -Comment[se]=Minimalisttalaš lásegieđahalli, ráhkaduvvon AEWM vuođul -Comment[sk]=Minimálny správca okien založený na AEWM -Comment[sl]=Minimalističen okenski upravitelj na osnovi AEWM -Comment[sr]=Минималистички менаџер прозора заснован на AEWM-у -Comment[sr@Latn]=Minimalistički menadžer prozora zasnovan na AEWM-u -Comment[sv]=Minimalistisk fönsterhanterare baserad på AEWM -Comment[ta]=AEWM அடிப்படையிலான குறைதபட்ச சாளர மேளாளர் -Comment[tg]=Мудири равзанаҳои хурд дар асоси AEWM -Comment[th]=ระบบจัดการหน้าต่างขนาดเล็ก สร้างจากพื้นฐานของ AEWM -Comment[tr]=AEWM tabanlı küçük bir pencere yöneticisi -Comment[tt]=AEWM asılında ciñel täräcä-idäräçe -Comment[uk]=Мінімалістичний менеджер вікон, заснований на AEWM -Comment[uz]=AEWM asosida yaratilgan juda oddiy oyna boshqaruvchi -Comment[uz@cyrillic]=AEWM асосида яратилган жуда оддий ойна бошқарувчи -Comment[vi]=Một trình quản lý cửa sổ đơn giản dựa trên AEWM -Comment[wa]=On manaedjeu di purneas minimå båzé so AEWM -Comment[zh_CN]=基于 AEWM 的最小化窗口管理器 -Comment[zh_TW]=一個基於 AEWM 的小型化視窗管理程式 diff --git a/kdm/kfrontend/sessions/fluxbox.desktop b/kdm/kfrontend/sessions/fluxbox.desktop deleted file mode 100644 index df6a0813c..000000000 --- a/kdm/kfrontend/sessions/fluxbox.desktop +++ /dev/null @@ -1,81 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=startfluxbox -TryExec=startfluxbox -Name=Fluxbox -Name[bn]=ফ্লাক্সবক্স -Name[cy]=Llif-flwch (Fluxbox) -Name[eo]=Fluujo -Name[hi]=फ्ल्क्स-बाक्स -Name[ne]=फ्लक्सबक्स -Name[pa]=ਫਕਸਬਕਸ -Name[rw]=AgasandukuUmujyoumwe -Name[ta]=ப்ளக்ஸ் பெட்டி -Name[te]=ఫ్లక్స్ బాక్స్ -Name[tg]=Қуттии Flux -Comment=A highly configurable and low resource window manager based on Blackbox -Comment[af]='n Baie konfigureerbare en lae hulpbron intensiewe venster bestuurder, wat op Blackbox gebaseer is. -Comment[ar]=مدير نوافذ قابل للإعداد بشكل كبير ويستخدم القليل من موارد الجهاز وهو مبني Blackbox -Comment[be]=Кіраўнік вокнаў, заснаваны на Blackbox, з вялікімі здольнасцямі змяняцца і з нізкай патрабавальнасцю да рэсурсаў -Comment[bn]=ব্ল্যাকবক্স ভিত্তিক একটি উইণ্ডো ম্যানেজার, যা নানাভাবে কনফিগার করা যায়, কিন্তু খুবই কম রিসোর্স ব্যবহার করে -Comment[bs]=Visoko prilagodljiv window manager sa malim zauzećem resursa baziran na Blackbox-u -Comment[ca]=Un gestor de finestres altament configurable i que necessita pocs recursos basat en Blackbox -Comment[cs]=Vysoce přizpůsobitelný a nízkoúrovňový správce oken založený na Blackboxu -Comment[csb]=Menedżer òknów òpiarti na Blackbox ò wiôldżich mòżnotach kònfigùracëji ë nisczich żądaniach -Comment[cy]=Trefnydd ffenestri hawdd ei ffurfweddu ac ysgafn ei ddefnydd adnoddau, wedi'i seilio ar Ddu-flwch (Blackbox) -Comment[da]=En meget indstillelig vindueshåndtering med lavt ressourceforbrug baseret på Blackbox -Comment[de]=Sehr flexibler, aber ressourcenschonender Fenstermanager, der auf Blackbox basiert -Comment[el]=Ένας ιδιαίτερα παραμετροποιήσιμος και με μικρή κατανάλωση πόρων διαχειριστής παραθύρων βασισμένος στον Blackbox -Comment[eo]=Fenestroadministrilo devenigita de Negrujo -Comment[es]=Un gestor de ventanas basado en Blackbox muy configurable y con poco consumo de recursos -Comment[et]=Väga hästi kohandatav ja vähenõudlik aknahaldur, mille aluseks on Blackbox -Comment[eu]=Blackbox-en oinarritutako leiho kudeatzaile zeharo konfiguragarria, eta errekurtso gutxi kontsumitzen dituena -Comment[fa]=یک مدیر پنجره با قابلیت پیکربندی بالا و منبع پایین براساس Blackbox -Comment[fi]=Blackboxiin pohjautuva erittäin muokattava ja vähäisen resurssitarpeen omaava ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres très configurable et utilisant peu de ressources, fondé sur Blackbox -Comment[fy]=In tige ynstelbere lichtgewicht finstersmanager basearre op Blackbox -Comment[gl]=Un xestor de fiestras moi configurábel e lixeiro baseado en Blackbox -Comment[he]=מנהל חלונות בעל הגדרות רבות הצורך משאבים מעטים ומבוסס עלBlackbox -Comment[hi]=ब्लेक-बाक्स आधारित, अत्यंत कॉन्फ़िगरेबल तथा कम साधन चाहने वाला विंडो प्रबंधक -Comment[hr]=Visoko konfigurabilan upravitelj prozora, male potrošnje resursa, zasnovan na Blackbox-u -Comment[hu]=Egy Blackbox-alapú ablakkezelő, alacsony erőforrásigénnyel, sokféle beállítási lehetőséggel -Comment[is]=Öflugur gluggastjóri sem notar lítið af auðlindum vélarinnar sem er byggður á Blackbox -Comment[it]= Un window manager molto configurabile e che utilizza poche risorse basato su Blackbox -Comment[ja]=Blackbox ベースの高度な設定が可能でリソースにやさしいウィンドウマネージャ -Comment[ka]=კონფიგურირებადი ფანჯრის მენეჯერი Blackbox -ის ბაზაზე -Comment[kk]=Blackbox-негіздеген, баптаулары көп, үнемді терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​អាច​កំណត់​រចនាសម្ព័ន្ធ​បាន​ខ្ពស់ និង​ប្រើ​ធនធាន​តិច ដែល​ផ្អែក​លើ Blackbox -Comment[ko]=Blackbox 기반의 다양하게 설정 가능하고 자원을 적게 사용하는 창 관리자 -Comment[lt]=Daug konfigūravimo parinkčių turinti ir mažai resursų naudojanti langų tvarkyklė, paremta Blackbox -Comment[lv]=Plaši konfigurējams un resursus taupošs logu menedžeris bāzēts uz Blackbox -Comment[mk]=Високо конфигурабилен менаџер на прозорци со мали побарувања на ресурси базиран на Blackbox -Comment[mn]=Хар хайрцаг дээр суурилсан маш бага нөөц хэрэглэдэг тохируулах чадвар өндөр цонхны удирдагч -Comment[mt]=Window manager ħafif u konfigurabbli ibbażat fuq BlackBox -Comment[nb]=En lite ressurskrevende og svært fleksibel vindusbehandler basert på Blackbox -Comment[nds]=En Finsterpleger, de wenig Ressourcen bruukt, man bannig vele Instellen hett. Opbuut op Blackbox -Comment[ne]=कालो बाकसमा आधारित उच्च कन्फिगरयोग्य र न्यून संसाधन सञ्झ्याल प्रबन्धक -Comment[nl]=Een zeer configureerbare lichtgewicht windowmanager gebaseerd op Blackbox. -Comment[nn]=Ein lite ressurskrevjande og svært fleksibel vindaugssjef basert på Blackbox -Comment[pa]=ਇੱਕ ਬਿਲਕੁੱਲ ਹਲਕਾ ਤੇ ਜਿਆਦਾ ਸੋਧਯੋਗ ਫਾਇਲ਼ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien oparty na Blackbox o dużych możliwościach konfiguracji i niskich wymaganiach -Comment[pt]=Um gestor de janelas bastante configurável e que usa poucos recursos, baseado no Blackbox -Comment[pt_BR]=Um gerenciador de janelas altamente configurável e com baixo uso de recursos, baseado no Blackbox -Comment[ro]=Un manager de ferestre foarte configurabil și mic, bazat pe Blackbox -Comment[ru]=Настраиваемый оконный менеджер, основанный на Blackbox -Comment[rw]=Mugenga dirishya mbonezwa mu buryo buhanitse kandi bikorana bike ishingiye ku Gasandukumukara -Comment[se]=Lásegieđahalli vuođđoduvvon Blackbox:as, hui heivehahtti ja geavaha unnán resurssaid -Comment[sk]=Veľmi konfigurovateľný a nenáročný správca okien založený na Blackbox -Comment[sl]=Visoko nastavljiv in učinkovit okenski upravitelj na osnovi Blackboxa -Comment[sr]=Врло подесив и незахтеван менаџер прозора заснован на Blackbox-у -Comment[sr@Latn]=Vrlo podesiv i nezahtevan menadžer prozora zasnovan na Blackbox-u -Comment[sv]=Mycket anpassningsbar fönsterhanterare med litet resursbehov baserad på Blackbox -Comment[ta]=கறுப்புபெட்டி சார்ந்த அமைக்கக்கூடிய குறைந்த வள சாளர மேளாளர் -Comment[tg]=Мудири равзанаҳои танзимшаванда дар асоси Blackbox -Comment[th]=ระบบจัดการหน้าต่างที่สามารถปรับแต่งได้อย่างละ เอียด และใช้ทรัพยากรน้อย สร้างบนพื้นฐานของ Blackbox -Comment[tr]=Blackbox temelli, kolayca özelleştirilebilir düşük kaynaklı bir pencere yöneticisi -Comment[tt]=Blackbox asılında qorılğan, yaqşı caylana torğan täräcä-idäräçe -Comment[uk]=Дуже гнучкий та невибагливий для ресурсів менеджер вікон, заснований на Blackbox -Comment[vi]=Một trình quản lý cửa sổ rất dễ cấu hình và đòi hỏi ít tài nguyên dựa trên Blackbox -Comment[wa]=On ledjir et foirt apontiåve manaedjeu di purneas båzé so Blackbox -Comment[zh_CN]=基于 BlackBox 可深入配置且占用资源较少的窗口管理器 -Comment[zh_TW]=一個基於 Blackbox 且高可組態及低資源的視窗管理程式 diff --git a/kdm/kfrontend/sessions/flwm.desktop b/kdm/kfrontend/sessions/flwm.desktop deleted file mode 100644 index d6dc24010..000000000 --- a/kdm/kfrontend/sessions/flwm.desktop +++ /dev/null @@ -1,77 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=flwm -TryExec=flwm -Name=FLWM -Name[eo]=RMFA -Name[hi]=एफएलडबल्यूएम -Name[te]=ఎఫ్ ఎల్ డబ్ల్యు ఎం -Name[th]=ตัวจัดการหน้าต่าง FLWM -Comment=The Fast Light Window Manager, based primarily on WM2 -Comment[af]=Die Vinnige, ligte venster bestuurder, wat op WM2 gebaseer is -Comment[ar]=مدير النوافذ السريع الخفيف، مبني بشكل أساسي على WM2 -Comment[be]=The Fast Light Window Manager, заснаваны на WM2 -Comment[bn]=ফাস্ট লাইট উইণ্ডো ম্যানেজার, WM2 ভিত্তি করে তৈরি -Comment[bs]=Fast Light Window Manager, baziran uglavnom na WM2 -Comment[ca]=El gestor de finestres Fast Light, primerament basat en WM2 -Comment[cs]=Fast Light Window Manager založený původně na WM2 -Comment[csb]=Fast Light Window Manager, menedżer òknów ùsôdzony przédno na WM2 -Comment[cy]=Y Trefnydd Ffenestri Chwim ac Ysgafn, wedi'i seilio ar WM2 am y rhan fwyaf -Comment[da]=Fast Light vindueshåndtering, baseret først og fremmest på WM2 -Comment[de]=Der Fast Light Window Manager, der vor allem auf WM2 basiert -Comment[el]=Ο Fast Light διαχειριστής παραθύρων, βασισμένος κυρίως στον WM2 -Comment[eo]=Rapida malpeza fenestroadministrilo -Comment[es]=El Fast Light Window Manager, basado principalmente en WM2 -Comment[et]=Kiire ja vähenõudlik aknahaldur, aluseks peamiselt WM2 -Comment[eu]=Batez ere WM2-en oinarritutako leiho kudeatzaile arin eta bizkorra -Comment[fa]=مدیر پنجرۀ سریع و سبک، در اصل بر اساس WM2 -Comment[fi]=Fast Light Window Manager. Pohjautuu suurimmaksi osin WM2:een -Comment[fr]=The Fast Light Window Manager, fondé au départ sur WM2 -Comment[fy]=De Fast Light Window Manager, primêr basearre op WM2 -Comment[gl]=O Fast Light Window Manager, un xestor de fiestras lixeiro baseado en WM2 -Comment[he]=The Fast Light Window Manager, מבוסס בעיקר על WM2 -Comment[hi]=मुख्यतः डबल्यूएम2 पर आधारित तेज और हल्का विंडो प्रबंधक -Comment[hr]=Brzi i lagani upravitelj prozora (FLWM), zasnovan na WM2 -Comment[hu]=Fast Light Window Manager ablakkezelő, elsősorban a WM2 alapján -Comment[is]=Léttur og hraðvirkur gluggastjóri sem er aðallega byggður á WM2 -Comment[it]=Il Fast Light Window Manager, basato principalmente su WM2 -Comment[ja]="高速で軽い"WM2 ベースのウィンドウマネージャ -Comment[ka]=სწრაფი და მსუბუქი ფანჯრების მენეჯერი WM2 -ის ბაზაზე -Comment[kk]=WM2-негіздеген жеңіл және жедел терезе менеджері -Comment[km]=Fast Light Window Manager ផ្អែក​ចម្បង​លើ WM2 -Comment[ko]=WM2에 기반을 둔 빠르고 가벼운 창 관리자 -Comment[lt]=Greita ir lengva langų tvarkyklė, paremta daugiausiai WM2 -Comment[lv]=Fast Light logu menedžeris, bāzēts galvenokārt uz WM2 -Comment[mk]=Fast Light Window Manager, менаџер примарно базиран на WM2 -Comment[mn]=Ерөнхийдөө WM2 дээр суурилсан хурдан хөнгөн цонхны удирдагч -Comment[mt]=Fast Light Window Manager, ibbażat fuq WM2 -Comment[nb]=En rask, lett vindusbehandler (Fast Light Window Manager), mest basert på WM2 -Comment[nds]=De "Fast Light"-Finsterpleger, to'n gröttsten Deel opbuut op WM2 -Comment[ne]=साधारणतया WM2 मा आधारित छिटो हल्का सञ्झ्याल प्रबन्धक -Comment[nl]=De Fast Light Window Manager, primair gebaseerd op WM2. -Comment[nn]=Ein rask, lett vindaugssjef (Fast Light Window Manager), mest basert på WM2 -Comment[pa]=ਇੱਕ ਹਲਕਾ ਤੇਜ਼ ਫਾਇਲ਼ ਮੈਨੇਜਰ, ਜੋ ਕਿ WM2 ਤੇ ਆਧਾਰਿਤ ਹੈ -Comment[pl]=Fast Light Window Manager, menedżer okien stworzony głownie na podstawie WM2 -Comment[pt]=O Fast Light Window Manager, baseado em primeiro lugar no WM2 -Comment[pt_BR]=Acrônimo para Fast Light Window Manager (gerenciador rápido e leve), baseado primeiramente no WM2 -Comment[ro]=Fast Light Window Manager, bazat în principal pe WM2 -Comment[ru]=Быстрый и лёгкий оконный менеджер, основанный на WM2 -Comment[rw]=Mugenga Dirishya Yihuta Yoroshye, ishingiye mbere na mbere kuri WM2 -Comment[se]=Jođánis, geahpes lásegieđahalli, ráhkaduvvon WM2 vuođul -Comment[sk]=The Fast Light Window Manager založený na WM2 -Comment[sl]=Fast Light Window Manager, v glavnem na osnovi WM2 -Comment[sr]=Брзи лаки менаџер прозора (FLWM), заснован на WM2 -Comment[sr@Latn]=Brzi laki menadžer prozora (FLWM), zasnovan na WM2 -Comment[sv]=Fönsterhanteraren Fast Light Window Manager, i huvudsak baserad på WM2 -Comment[ta]=WM2 அடிப்படையிலான வேக ஒளி வேக சாளர மேளாளர் -Comment[tg]=мудири равзанаҳои тез ва осон дар асоси WM2 -Comment[th]=ระบบจัดการหน้าต่างที่เร็วและเบา สร้างบนพื้นฐานของ WM2 -Comment[tr]=Fast Light Pencere Yöneticisi -Comment[tt]=WM2 asılında qorılğan, citez ciñel täräcä-idäräçe -Comment[uk]=Швидкий легкий менеджер вікон, заснований здебільшого на WM2 -Comment[uz]=Asosan WM2 asosida yaratilgan tez va oddiy oyna boshqaruvchi -Comment[uz@cyrillic]=Асосан WM2 асосида яратилган тез ва оддий ойна бошқарувчи -Comment[vi]=Trình Quản lý Cửa sổ Nhanh và Nhẹ, dựa chủ yếu vào WM2 -Comment[wa]=Li Roed et Ledjir Manaedjeu di Purneas (ast Light Window Manager) båzé so WM2 -Comment[zh_CN]=又快又轻巧的窗口管理器,主要基于 WM2 -Comment[zh_TW]=一個主要基於 WM2 且快速及輕量化的視窗管理程式 diff --git a/kdm/kfrontend/sessions/fvwm.desktop b/kdm/kfrontend/sessions/fvwm.desktop deleted file mode 100644 index 20ae57d4c..000000000 --- a/kdm/kfrontend/sessions/fvwm.desktop +++ /dev/null @@ -1,71 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=fvwm -TryExec=fvwm -Name=FVWM -Name[hi]=एफ़वीडबल्यूएम -Name[te]=ఎఫ్ వి డబ్ల్యు ఎం -Comment=A powerful ICCCM-compliant multiple virtual desktop window manager -Comment[af]='n Kragtige, ICCCM-aanpasbare veelvuldige virtuele werkskermvenster bestuurder. -Comment[ar]=مدير نوافذ قوي ومتوافق مع ICCCM ذي أسطح مكتب وهمية متعددة -Comment[be]=Магутны ICCCM-сумяшчальны кіраўнік вокнаў з падтрымкай віртуальных працоўных сталоў -Comment[bn]= একটি শক্তিশালী ICCCM-compliant উইণ্ডো ম্যানেজার, যাতে একাধিক ভার্চুয়াল ডেস্কটপ সম্ভব -Comment[bs]=Moćan ICCCM-sukladan window manager sa podrškom za više virtuelnih desktopa -Comment[ca]=Un poderós gestor de finestres per a múltiples escriptoris virtuals que compleix amb ICCCM -Comment[csb]=Stolemny menedżer òknów zgòdny z ICCCM òbsłëgòwujący wirtualné pùltë -Comment[cy]=Trefnydd ffenestri pwerus efo penbyrddau rhith lluosol, sy'n cydymffurfio â ICCCM -Comment[da]=En kraftig ICCCM-kompliant vindueshåndtering med flere virtuelle desktoppe -Comment[de]=Ein leistungsfähiger ICCCM-kompatibler Fenstermanager mit virtuellen Arbeitsflächen -Comment[el]=Ένας πολύ δυνατός, συμβατός με το ICCCM, διαχειριστής παραθύρων με πολλαπλές εικονικές επιφάνειες εργασίας -Comment[eo]=Fenestroadministrilo -Comment[es]=Un potente gestor de ventanas, compatible con ICCCM y que soporta varios escritorios virtuales -Comment[et]=Võimas ICCCM nõuetele vastav mitme virtuaalse töölauaga aknahaldur -Comment[eu]=ICCCM konpatiblea den, eta mahaigain birtual ugari dituen leiho kudeatzaile bortitza -Comment[fa]=یک مدیر پنجرۀ رومیزی مجازی چندگانه ICCCM-compliant نیرومند -Comment[fi]=Tehokas ICCCM-mukautuva virtuaalityöpöytiä tukeva ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres puissant compatible ICCCM avec gestion de bureaux virtuels multiples -Comment[fy]=In krêftige ICCCM-compliant finstersmanager mei meardere buroblêden -Comment[gl]=Un xestor de fiestras potente acorde coa ICCCM con múltiplos escritórios virtuais -Comment[he]=מנהל חלונות עצמתי עם תאימות ל־ICCCM בעל שולחנות עבודה וירטואליים רבים -Comment[hi]=शक्तिशाली आईसीसीसीएम-कम्पलाएंट अनेक आभासी डेस्कटॉप विंडो प्रबंधक -Comment[hr]=Comment=Moćni, ICCCM kompatibilan, upravitelj prozora s više virtualnih radnih površina -Comment[hu]=Egy sokoldalú, ICCCM-kompatibilis ablakkezelő, virtuális munkaasztal-kezeléssel -Comment[is]=Öflugur ICCCM samhæfður gluggastjóri með sýndarskjáborðum -Comment[it]=Un window manager molto potente e ICCCM-compatibile che supporta i desktop virtuali -Comment[ja]=複数の仮想デスクトップをサポートした ICCCM 準拠のパワフルなウィンドウマネージャ -Comment[ka]=ძლიერი ICCCM-თავსებადი ვირტულური სამუშაო დაფების მხარდამჭერი ფანჯრის მენეჯერი -Comment[kk]=Қуатты ICCCM-үйлесімді, көп виртуалды үстел қолдайтын терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ផ្ទៃតុ​និមិត្ត​ច្រើន​ដ៏​មាន​អានុភាព ដែល​អនុវត្ត​តាម ICCCM -Comment[ko]=다중 가상 데스크톱을 사용하는 ICCCM 호환 창 관리자 -Comment[lt]=galinga, su ICCCM suderinama daugelio virtualių darbastalių langų tvarkyklė -Comment[lv]=Spēcīgs ICCCM-savietojams logu menedžeris ar vairāku darbvirsmu atbalstu -Comment[mk]=Моќен менаџер на прозорци со повеќе виртуелни површини во согласност со ICCCM -Comment[mt]=Window manager b'saħħtu, konformi ma' ICCCM, b'desktops virtwali. -Comment[nb]=En slagkraftig vindusbehandler med flere virtuelle skrivebord, som støtter ICCCM -Comment[nds]=En kraftvulle, ICCCM-kompatible Finsterpleger mit vele virtuelle Schriefdischen -Comment[ne]=शक्तिशाली ICCCM-मान्ने बहुविध अवास्तविक डेस्कटप सञ्झ्याल प्रबन्धक -Comment[nl]=Een krachtige ICCCM-compliant windowmanager met meerdere bureaubladen -Comment[nn]=Ein slagkraftig vindaugssjef med fleire virtuelle skrivebord, som støttar ICCCM -Comment[pa]=ਇੱਕ ਸ਼ਕਤੀਸ਼ਾਲੀ ICCCM-ਅਨੁਕੂਲ ਬਹੁ-ਫਰਜ਼ੀ ਵੇਹੜਿਆਂ ਵਾਲਾ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Potężny menedżer okien zgodny z ICCCM obsługujący wirtualne pulpity -Comment[pt]=Um gestor de janelas poderoso em conformidade com o ICCCM e que suporta vários ecrãs virtuais -Comment[pt_BR]=Um poderoso gerenciador de janelas compatível com o ICCM, com suporte a múltiplas áreas de trabalho virtuais -Comment[ro]=Un manager de ferestre puternic compliant ICCCM ce suportă ecrane virtuale -Comment[ru]=Мощный ICCCM-совместимый оконный менеджер, поддерживающий виртуальные рабочие столы -Comment[rw]=igikoranisha-ICCCM nyembaraga mugenga dirishya y'ibiro bitandukanye bitagaragara -Comment[se]=Fápmolaš ICCCM-heivvolaš lásegieđahalli mas lea virtuealla čállinbeavddit -Comment[sk]=Výkonný správca okien kompatibilný s ICCCM s podporou virtuálnych plôch -Comment[sl]=Močan okenski upravitelj z večimi navideznimi namizji in popolnoma v skladu z ICCCM -Comment[sr]=Моћни, ICCCM-сагласни, менаџер прозора са више виртуелних радних површина -Comment[sr@Latn]=Moćni, ICCCM-saglasni, menadžer prozora sa više virtuelnih radnih površina -Comment[sv]=Kraftfull fönsterhanterare med flera virtuella skrivbord som följer ICCCM -Comment[ta]=ICCCM-தரத்தில் பலதரப்பட்ட மெய்நிகர் மேல் மேசை சாளர மேளாளர் -Comment[tg]=Мудири равзанаҳои бузург дар асоси ICCCM дорои мудири равзанаҳо бо мизикориҳои виртуалӣ -Comment[th]=ระบบจัดการหน้าต่างที่มีหลายพื้นที่ทำงานเสมือน สอดรับกับ ICCCM ประสิทธิภาพสูง -Comment[tr]=Güçlü ICCCM-uyumlu çoklu sanal masaüstü yöneticisi -Comment[tt]=ICCCM-ütkän, küp öställär totqan köçle täräzä-idäräçe -Comment[uk]=Потужний, сумісний з ICCCM менеджер вікон, з підтримкою віртуальних стільниць -Comment[vi]=Trình quản lý cửa sổ tương thích với ICCCM nhiều chức năng, quản lý nhiều màn hình nền ảo -Comment[wa]=On manaedjeu di purneas avou multi-forveyowès sicribannes ki rote avou ICCM -Comment[zh_CN]=强大的多虚拟桌面窗口管理器,与 ICCCM 兼容 -Comment[zh_TW]=一個強大的 ICCCM 相容的多重虛擬桌面視窗管理程式 diff --git a/kdm/kfrontend/sessions/fvwm2.desktop b/kdm/kfrontend/sessions/fvwm2.desktop deleted file mode 100644 index 1a25a91e4..000000000 --- a/kdm/kfrontend/sessions/fvwm2.desktop +++ /dev/null @@ -1,70 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=fvwm2 -TryExec=fvwm2 -Name=FVWM2 -Name[te]=ఎఫ్ వి డబ్ల్యు ఎం 2 -Comment=A powerful ICCCM-compliant multiple virtual desktop window manager -Comment[af]='n Kragtige, ICCCM-aanpasbare veelvuldige virtuele werkskermvenster bestuurder. -Comment[ar]=مدير نوافذ قوي ومتوافق مع ICCCM ذي أسطح مكتب وهمية متعددة -Comment[be]=Магутны ICCCM-сумяшчальны кіраўнік вокнаў з падтрымкай віртуальных працоўных сталоў -Comment[bn]= একটি শক্তিশালী ICCCM-compliant উইণ্ডো ম্যানেজার, যাতে একাধিক ভার্চুয়াল ডেস্কটপ সম্ভব -Comment[bs]=Moćan ICCCM-sukladan window manager sa podrškom za više virtuelnih desktopa -Comment[ca]=Un poderós gestor de finestres per a múltiples escriptoris virtuals que compleix amb ICCCM -Comment[csb]=Stolemny menedżer òknów zgòdny z ICCCM òbsłëgòwujący wirtualné pùltë -Comment[cy]=Trefnydd ffenestri pwerus efo penbyrddau rhith lluosol, sy'n cydymffurfio â ICCCM -Comment[da]=En kraftig ICCCM-kompliant vindueshåndtering med flere virtuelle desktoppe -Comment[de]=Ein leistungsfähiger ICCCM-kompatibler Fenstermanager mit virtuellen Arbeitsflächen -Comment[el]=Ένας πολύ δυνατός, συμβατός με το ICCCM, διαχειριστής παραθύρων με πολλαπλές εικονικές επιφάνειες εργασίας -Comment[eo]=Fenestroadministrilo -Comment[es]=Un potente gestor de ventanas, compatible con ICCCM y que soporta varios escritorios virtuales -Comment[et]=Võimas ICCCM nõuetele vastav mitme virtuaalse töölauaga aknahaldur -Comment[eu]=ICCCM konpatiblea den, eta mahaigain birtual ugari dituen leiho kudeatzaile bortitza -Comment[fa]=یک مدیر پنجرۀ رومیزی مجازی چندگانه ICCCM-compliant نیرومند -Comment[fi]=Tehokas ICCCM-mukautuva virtuaalityöpöytiä tukeva ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres puissant compatible ICCCM avec gestion de bureaux virtuels multiples -Comment[fy]=In krêftige ICCCM-compliant finstersmanager mei meardere buroblêden -Comment[gl]=Un xestor de fiestras potente acorde coa ICCCM con múltiplos escritórios virtuais -Comment[he]=מנהל חלונות עצמתי עם תאימות ל־ICCCM בעל שולחנות עבודה וירטואליים רבים -Comment[hi]=शक्तिशाली आईसीसीसीएम-कम्पलाएंट अनेक आभासी डेस्कटॉप विंडो प्रबंधक -Comment[hr]=Comment=Moćni, ICCCM kompatibilan, upravitelj prozora s više virtualnih radnih površina -Comment[hu]=Egy sokoldalú, ICCCM-kompatibilis ablakkezelő, virtuális munkaasztal-kezeléssel -Comment[is]=Öflugur ICCCM samhæfður gluggastjóri með sýndarskjáborðum -Comment[it]=Un window manager molto potente e ICCCM-compatibile che supporta i desktop virtuali -Comment[ja]=複数の仮想デスクトップをサポートした ICCCM 準拠のパワフルなウィンドウマネージャ -Comment[ka]=ძლიერი ICCCM-თავსებადი ვირტულური სამუშაო დაფების მხარდამჭერი ფანჯრის მენეჯერი -Comment[kk]=Қуатты ICCCM-үйлесімді, көп виртуалды үстел қолдайтын терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ផ្ទៃតុ​និមិត្ត​ច្រើន​ដ៏​មាន​អានុភាព ដែល​អនុវត្ត​តាម ICCCM -Comment[ko]=다중 가상 데스크톱을 사용하는 ICCCM 호환 창 관리자 -Comment[lt]=galinga, su ICCCM suderinama daugelio virtualių darbastalių langų tvarkyklė -Comment[lv]=Spēcīgs ICCCM-savietojams logu menedžeris ar vairāku darbvirsmu atbalstu -Comment[mk]=Моќен менаџер на прозорци со повеќе виртуелни површини во согласност со ICCCM -Comment[mt]=Window manager b'saħħtu, konformi ma' ICCCM, b'desktops virtwali. -Comment[nb]=En slagkraftig vindusbehandler med flere virtuelle skrivebord, som støtter ICCCM -Comment[nds]=En kraftvulle, ICCCM-kompatible Finsterpleger mit vele virtuelle Schriefdischen -Comment[ne]=शक्तिशाली ICCCM-मान्ने बहुविध अवास्तविक डेस्कटप सञ्झ्याल प्रबन्धक -Comment[nl]=Een krachtige ICCCM-compliant windowmanager met meerdere bureaubladen -Comment[nn]=Ein slagkraftig vindaugssjef med fleire virtuelle skrivebord, som støttar ICCCM -Comment[pa]=ਇੱਕ ਸ਼ਕਤੀਸ਼ਾਲੀ ICCCM-ਅਨੁਕੂਲ ਬਹੁ-ਫਰਜ਼ੀ ਵੇਹੜਿਆਂ ਵਾਲਾ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Potężny menedżer okien zgodny z ICCCM obsługujący wirtualne pulpity -Comment[pt]=Um gestor de janelas poderoso em conformidade com o ICCCM e que suporta vários ecrãs virtuais -Comment[pt_BR]=Um poderoso gerenciador de janelas compatível com o ICCM, com suporte a múltiplas áreas de trabalho virtuais -Comment[ro]=Un manager de ferestre puternic compliant ICCCM ce suportă ecrane virtuale -Comment[ru]=Мощный ICCCM-совместимый оконный менеджер, поддерживающий виртуальные рабочие столы -Comment[rw]=igikoranisha-ICCCM nyembaraga mugenga dirishya y'ibiro bitandukanye bitagaragara -Comment[se]=Fápmolaš ICCCM-heivvolaš lásegieđahalli mas lea virtuealla čállinbeavddit -Comment[sk]=Výkonný správca okien kompatibilný s ICCCM s podporou virtuálnych plôch -Comment[sl]=Močan okenski upravitelj z večimi navideznimi namizji in popolnoma v skladu z ICCCM -Comment[sr]=Моћни, ICCCM-сагласни, менаџер прозора са више виртуелних радних површина -Comment[sr@Latn]=Moćni, ICCCM-saglasni, menadžer prozora sa više virtuelnih radnih površina -Comment[sv]=Kraftfull fönsterhanterare med flera virtuella skrivbord som följer ICCCM -Comment[ta]=ICCCM-தரத்தில் பலதரப்பட்ட மெய்நிகர் மேல் மேசை சாளர மேளாளர் -Comment[tg]=Мудири равзанаҳои бузург дар асоси ICCCM дорои мудири равзанаҳо бо мизикориҳои виртуалӣ -Comment[th]=ระบบจัดการหน้าต่างที่มีหลายพื้นที่ทำงานเสมือน สอดรับกับ ICCCM ประสิทธิภาพสูง -Comment[tr]=Güçlü ICCCM-uyumlu çoklu sanal masaüstü yöneticisi -Comment[tt]=ICCCM-ütkän, küp öställär totqan köçle täräzä-idäräçe -Comment[uk]=Потужний, сумісний з ICCCM менеджер вікон, з підтримкою віртуальних стільниць -Comment[vi]=Trình quản lý cửa sổ tương thích với ICCCM nhiều chức năng, quản lý nhiều màn hình nền ảo -Comment[wa]=On manaedjeu di purneas avou multi-forveyowès sicribannes ki rote avou ICCM -Comment[zh_CN]=强大的多虚拟桌面窗口管理器,与 ICCCM 兼容 -Comment[zh_TW]=一個強大的 ICCCM 相容的多重虛擬桌面視窗管理程式 diff --git a/kdm/kfrontend/sessions/fvwm95.desktop b/kdm/kfrontend/sessions/fvwm95.desktop deleted file mode 100644 index 2bbd1c403..000000000 --- a/kdm/kfrontend/sessions/fvwm95.desktop +++ /dev/null @@ -1,76 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=fvwm95 -TryExec=fvwm95 -Name=FVWM95 -Name[hi]=एफ़वीडबल्यूएम95 -Name[te]=ఎఫ్ వి డబ్ల్యు ఎం 95 -Comment=A Windows 95 look-alike derivative of FVWM -Comment[af]='n FVWM venster bestuurder wat soos Windows 95 lyk -Comment[ar]=شبيه بـWin95 ومشتق من FVWM -Comment[be]=Вытворная ад FVWM, падобная на Windows 95 -Comment[bn]=FVWM-ভিত্তিক Windows 95-এর মত দেখতে একটি উইণ্ডো ম্যানেজার -Comment[bs]=Derivacija FVWM nalik na Windows 95 -Comment[ca]=Un semblant a Win95 derivat de FVWM -Comment[cs]=Správce oken se vzhledem Windows 95 odvozený od FVWM -Comment[csb]=Pòchòdzący z FVWM menedżer òknów ò wëzdrzatkù szlachùjącym za Windows 95 -Comment[cy]=Deilliant o FVWM sy'n edrych yn debyg i Windows95 -Comment[da]=En Windows 95-lignende vindueshåndtering afledt af FVWM -Comment[de]=Ein Abkömmling von FVWM im Stil von Windows 95 -Comment[el]=Ένας παρόμοιος με τα Windows 95 διαχειριστής παραθύρων προερχόμενος από τον FVWM -Comment[eo]=Fenestroadministrilo kiel tiu de Vindozo 95 -Comment[es]=Un derivado de FVWM de aspecto similar a Win95 -Comment[et]=FVWM derivaat, mis näeb välja nagu Windows 95 -Comment[eu]=Windows 95en itxura duen FVWMren ondorengo bat -Comment[fa]=ویندوز ۹۵ شبیه مشتق FVWM -Comment[fi]=Windows 95:lta näyttävä FVWM-johdannainen -Comment[fr]=Un gestionnaire de fenêtres ressemblant à Windows 95 dérivant de FVWM -Comment[fy]=In op Windows 95 lykjende fariant fan FVWM -Comment[gl]=Un xestor de fiestras coma o de Windows 95 derivado de FVWM -Comment[he]=נגזרת של FVWM הנראה כמו חלונות 95 -Comment[hi]=विंडोज़ 95 जैसा दिखने वाला एफ़वीडबल्यूएम का प्रतिरूप -Comment[hr]=Derivat FVWM-a nalik na Windows 95 -Comment[hu]=Win95-szerű FVWM-változat -Comment[is]=Útgáfa af FVWM sem líkist Windows 95 -Comment[it]=Una variante di FVWM che assomiglia a Windows 95 -Comment[ja]=Windows95 に似た外見の FVWM 派生ウィンドウマネージャ -Comment[ka]=FVWM კლონი Windows 95-ის სტილში -Comment[kk]=Windows 95 секілді FVWM-негіздеген терезе менеджері -Comment[km]=ស្រដៀង Windows 95 ដែល​ក្លាយ​មក​ពី FVWM -Comment[ko]=FVWM의 윈도 95를 닮은 변종 -Comment[lt]=Windows 95 išvaizdą primenanti FVWM atmaina -Comment[lv]=Windows 95 līdzīgs FVWM atvasinājums -Comment[mk]=Деривација на FVWM менаџерот со изглед на Windows 95 -Comment[mn]=FVWM -ээс уламжилсан Виндовс 95 шиг харагдалттай -Comment[ms]=Terbitan FVWM yang menyerupai Windows 95 -Comment[mt]=Derivattiv ta' FVWM jixbaħ lil Windows 95 -Comment[nb]=En variant av FVWM som ser ut som Windows 95 -Comment[nds]=Süht ut as A Windows 95 un is vun FVWM afleddt -Comment[ne]=विण्डोज ९५ FVWM को डेरिभेटिभ जस्तो छ -Comment[nl]=Een op Windows 95 lijkende variant van FVWM -Comment[nn]=Ein variant av FVWM som ser ut som Windows 95 -Comment[pa]=ਵਿੰਡੋ 95 ਵਰਗਾ FVWM ਦਾ ਇੱਕ ਰੂਪ -Comment[pl]=Wywodzący się z FVWM menedżer okien o wyglądzie podobnym do Windows 95 -Comment[pt]=Uma derivação do FVWM parecida com o Windows 95 -Comment[pt_BR]=Um derivado do FVWM com a aparência do Windows 95 -Comment[ro]=O versiune de FVWM cu aspect de Windows 95 -Comment[ru]=Клон FVWM в стиле Windows 95 -Comment[rw]=Windows 95 isa nk'ikomoka kuri FVWM -Comment[se]=FVWM-vuođđoduvvon lásegieđahalli mii lea Windows 95-lágan -Comment[sk]=Správca okien podobný Windows 95 založený na FVWM -Comment[sl]=Izpeljanka FVWM v izgledu Windows 95 -Comment[sr]=Дериват FVWM-а налик на Windows 95 -Comment[sr@Latn]=Derivat FVWM-a nalik na Windows 95 -Comment[sv]=Fönsterhanterare som liknar Windows 95 med ursprung i FVWM -Comment[ta]=FVWM லிருந்து தோன்றிய விண்டோஸ் 95 ஐப் போன்ற -Comment[tg]=Windows 95 look-монанди маҳсулии FVWM -Comment[th]=FVWM ที่ถูกทำให้ดูเหมือนวินโดวส์ 95 -Comment[tr]=Windows 95'e benzeyen bir pencere yönetimi -Comment[tt]=Windows 95 küreneşendä FVWM qabatlama -Comment[uk]=Похідний від FVWM з виглядом Windows 95 -Comment[uz]=Win95'ga oʻxshagan FVWM'ning turi -Comment[uz@cyrillic]=Win95'га ўхшаган FVWM'нинг тури -Comment[vi]=Trình quản lý cửa sổ giống Windows 95, hậu duệ của FVWM -Comment[wa]=On manaedjeu di purneas rishonnant a Windows 95 et k' est båzé so FVWM -Comment[zh_CN]=一个与 Windows 95 外观类似的 FVWM 变种 -Comment[zh_TW]=一個由 FVWM 演化出來且外觀像 Win95 的視窗管理程式 diff --git a/kdm/kfrontend/sessions/gnome.desktop b/kdm/kfrontend/sessions/gnome.desktop deleted file mode 100644 index ed89391ec..000000000 --- a/kdm/kfrontend/sessions/gnome.desktop +++ /dev/null @@ -1,81 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=gnome-session -TryExec=gnome-session -Name=GNOME -Name[bn]=গনোম -Name[eo]=Gnomikuo -Name[hi]=ग्नोम -Name[ko]=세임 그놈 -Name[mn]=ГНОМЕ -Name[ne]=जिनोम -Name[sv]=Gnome -Name[ta]=க்னோம் -Name[te]=గ్నొమ్ -Comment=The GNU Network Object Model Environment. A complete, free and easy-to-use desktop environment -Comment[af]=Die GNU 'Network Object Model Environment'. 'n Volledige, gratis en maklik om te gebruik werkskerm omgewing. -Comment[ar]=بيئة نموذج الكائن الشبكي من GNU، بيئة سطح مكتبي حرّة وسهلة الاستخدام -Comment[be]=The GNU Network Object Model Environment. Поўнае, свабоднае і простае ў выкарыстанні працоўнае асяроддзе -Comment[bn]=দি গনিউ নেটওয়ার্ক অবজেক্টমডেল এনভায়রনমেন্ট। একটি পূর্ণ, মুক্ত এবং সহজেই ব্যবহারযোগ্য ডেস্কটপ এনভায়রনমেন্ট -Comment[bs]=GNU Network Object Model Environment. Kompletna, slobodna i jednostavna za upotrebu desktop okolina -Comment[ca]=El GNU Network Object Model Environment. Un complet, lliure i fàcil d'usar entorn d'escriptori -Comment[cs]=GNOME, GNU Network Object Model Environment. Kompletní, svobodné a uživatelsky přívětivé garfické prostředí. -Comment[csb]=GNU Network Object Model Environment (GNOME). Fùlwôrtné, wòlné ë prosté w brëkòwaniô òkrãżé pùltu -Comment[cy]=Yr Amgylchedd Model Gwrthrych Rhwydwaith GNU (GNU Network Object Model Environment). Amgylchedd penbwrdd cyflawn, rhydd, a hawdd ei ddefnyddio. -Comment[da]=GNU Network Object Model Environment. Et fuldstænding, frit og nemt at bruge desktopmiljø -Comment[de]=Das GNU Network Object Model Environment. Eine vollständige, freie und leicht bedienbare Arbeitsumgebung -Comment[el]=Το GNU Network Object Model Environment. Ένα πλήρης, ελεύθερο και εύκολο στη χρήση περιβάλλον επιφάνειας εργασίας -Comment[eo]=Plena labortabla ĉirkaŭaĵo -Comment[es]=El GNU Network Object Model Environment, un entorno de escritorio completo, libre y fácil de usar -Comment[et]=GNU Network Object Model Environment on täielik, vaba ja väga hõlpsasti kasutatav töölaua keskkond -Comment[eu]=GNU Network Object Model Environment. mahaigain-ingurune oso, libre eta erabilterraza -Comment[fa]=محیط مدل شئ شبکه گنو. محیط رومیزی کامل، آزاد و آسان برای استفاده. -Comment[fi]=GNU Network Object Model Environment. Valmis, vapaa ja helppokäyttöinen työpöytäympäristö -Comment[fr]=The GNU Network Object Model Environment. Un environnement de bureau complet, gratuit et facile à utiliser -Comment[fy]=De GNU Network Object Model Environment, In komplete, frije en ienfâldige te brûken buroblêd omwrâld -Comment[gl]=O GNU Network Object Model Environment. Un entorno de escritório completo, libre e de uso doado -Comment[he]=The GNU Network Object Model Environment. סביבת עבודה מלאה, חופשית וקלה לשימוש -Comment[hi]=जीएनयू नेटवर्क ऑब्जेक्ट मॉडल एनवायरनमेंट. एक संपूर्ण, उपयोग में आसान डेस्कटॉप वातावरण -Comment[hr]=GNOME - GNU Network Object Model Environment - Cjelokupno, besplatno i jednostavno okruženje radne površine -Comment[hu]=GNU Network Object Model Environment (GNOME), egy teljes, ingyenes, könnyen kezelhető grafikus környezet -Comment[is]=GNU Network Object Model Environment er fullkomið og fjrálst skjáborðsumhverfi sem er auðvelt að nota -Comment[it]=Il GNU Network Object Model Environment. Un ambiente desktop completo, libero e facile da usare -Comment[ja]=GNU オブジェクトモデル環境, 完全にフリーで使いやすいデスクトップ環境 -Comment[ka]=GNU Network Object Model Environment - სრული, თავისუფალი და ადვილად გამოყენებადი სამუშაო გარემო -Comment[kk]=GNU Network Object Model Environment. Толық, еркін таратылатын, ыңғайлы графикалық орта -Comment[km]=GNU Network Object Model Environment ។ បរិស្ថាន​ផ្ទៃតុ​ពេញលេញ, ឥត​គិត​ថ្លៃ និង​ងាយស្រួល​ប្រើ -Comment[ko]=GNU Network Object Model Environment(그놈). 완전한 자유 소프트웨어 데스크톱 환경입니다. -Comment[lt]=GNU tinklo objektų modeliavimo aplinka. Savarankiška, laisva ir lengvai naudojama darbastalio aplinka -Comment[lv]=GNU Network Object Model Environment. Pilnvērtīga bezmaksas viegli lietojama darba vide. -Comment[mk]=GNU Network Object Model Environment. Работна околина која е комплетна, слободна и едноставна за користење -Comment[mn]=GNU Network Object Model Environment. Бүрэн, үнэгүй хэрэглэхэд хялбар дэлгэцийн системийн орчин -Comment[mt]=GNU Network Object Model Environment. Ambjent grafiku komplet, ħieles u faċli tużah. -Comment[nb]=GNU Network Object Model Environment. Et skrivebordsmiljø som er komplett, fritt og lett å bruke. -Comment[nds]=De "GNU Network Object Model Environment". En komplette Schriefdisch-Ümgeven, ümsunst un eenfach to bruken -Comment[ne]=GNU सञ्जाल बस्तु नमूना वातावरण । पूर्ण, स्वतन्त्र र प्रयोग गर्न सजिलो डेस्कटप वातावरण -Comment[nl]=De GNU Network Object Model Environment, een complete, vrije en eenvoudig te gebruiken desktop environment. -Comment[nn]=GNU Network Object Model Environment. Eit skrivebordsmiljø som er komplett, fritt og lett å bruka. -Comment[pa]=GNU Network Object Model Environment, ਇੱਕ ਸੰਪੂਰਨ, ਮੁਫਤ ਅਤ ਵਰਤਣ ਵਿੱਚ ਅਤਿ ਆਸਾਨ ਵੇਹੜਾ ਵਾਤਾਵਰਣ -Comment[pl]=GNU Network Object Model Environment (GNOME). Pełne, wolne i łatwe w użyciu środowisko pulpitu -Comment[pt]=O GNU Network Object Model Environment. Um ambiente de trabalho completo, livre e fácil de usar -Comment[pt_BR]=Acrônimo para GNU Network Object Model Environment ou Ambiente de Modelo de Objetos de Rede GNU; um ambiente de trabalho completo, livre e fácil de usar -Comment[ro]=GNU Network Object Model Environment. Un mediu grafic complet, gratuit și ușor de utilizat -Comment[ru]=GNU Network Object Model Environment - полная, свободная и лёгкая в использовании графическая среда -Comment[rw]=Ibikikije Moderi Igikoresho Urusobemiyoboro GNU. Ibikikije by'ibiro byuzuye, by'ubuntu kandi byoroshye-gukoresha. -Comment[se]=GNU Netword Object Model Environment: Čállinbeavdebiras mii lea aibbas fridja ja álki geavahit. -Comment[sk]=The GNU Network Object Model Environment. Úplné, voľne šíriteľné a ľahko použiteľné pracovné prostredie -Comment[sl]=GNU Network Object Model Environment. Popolno, prosto in preposto namizno okolje -Comment[sr]=„GNU Network Object Model Environment“(Gnome, Гном). Потпуно, бесплатно и лако за коришћење радно окружење -Comment[sr@Latn]=„GNU Network Object Model Environment“(Gnome, Gnom). Potpuno, besplatno i lako za korišćenje radno okruženje -Comment[sv]=GNU Network Object Model Environment. En fullständig, fri och lättanvänd skrivbordsmiljö -Comment[ta]=GNU மாதிரி வலை பொருள் சூழல்.முழுமையான , இலவச சுலபமாக பயன்படுத்தக்கூடிய மேல்மேசை சூழல் -Comment[th]=GNU Network Object Model Environment สภาพแวดล้อมสำหรับเดสก์ทอปที่ครบถ้วน, ฟรี และใช้งานง่าย -Comment[tr]=GNU Network Object Model Environment (GNOME) -Comment[tt]=The GNU Network Object Model Environment. Qullanu öçen ciñel, buşlay, tulıçaralı östäl möxite -Comment[uk]=The GNU Network Object Model Environment. Повнофункціональне, вільне та зручне графічне середовище -Comment[uz]=GNOME (GNU Network Object Model Environment) - mukammal, erkin va foydalanish uchun juda qulay ish stoli muhiti -Comment[uz@cyrillic]=GNOME (GNU Network Object Model Environment) - мукаммал, эркин ва фойдаланиш учун жуда қулай иш столи муҳити -Comment[vi]=Môi trường Mạng Mô hình Đối tượng của GNU. Một môi trường màn hình nền đầy đủ, tự do và dễ sử dụng -Comment[wa]=L' evironmint di modele di cayets d' rantoele GNU (GNU Network Object Model Environment). On complet evironmint d' sicribanne, libe et åjhey a -z eployî. -Comment[zh_CN]=GNU 网络对象模型环境。完整、自由、易用的桌面环境 -Comment[zh_TW]=GNU 網路物件模型環境。一個完整,免費且容易使用的桌面環境 diff --git a/kdm/kfrontend/sessions/golem.desktop b/kdm/kfrontend/sessions/golem.desktop deleted file mode 100644 index 3ba7f2b41..000000000 --- a/kdm/kfrontend/sessions/golem.desktop +++ /dev/null @@ -1,81 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=golem -TryExec=golem -Name=Golem -Name[bn]=গোলেম -Name[eo]=Golemo -Name[hi]=गोलेम -Name[ne]=गोलेम -Name[pa]=ਗੋਲੀਮ -Name[te]=గొలెం -Comment=A lightweight window manager -Comment[af]='n Lig gewig venster bestuurder -Comment[ar]=مدير نوافر خفيف العبء -Comment[be]=Лёгкі кіраўнік вокнаў -Comment[bn]=একটি হাল্কা উইণ্ডো ম্যানেজার -Comment[bs]=Lagani window manager -Comment[ca]=Un lleuger gestor de finestres KDE -Comment[cs]=Malý správce oken -Comment[csb]=Menedżer òknół ò môłëch żądaniach -Comment[cy]=Trefnydd ffenestri ysgafn -Comment[da]=En letvægtsvindueshåndtering -Comment[de]=Eine schlanker Fenstermanager -Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων -Comment[eo]=Malpeza fenestroadministrilo -Comment[es]=Un gestor de ventanas ligero -Comment[et]=Imeväike aknahaldur -Comment[eu]=Leiho kudeatzaile arina -Comment[fa]=یک مدیر پنجرۀ سبک -Comment[fi]=Kevyt ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres très léger -Comment[fy]=In lichtgewicht finstersmanager -Comment[gl]=Un xestor de fiestras lixeiro -Comment[he]=מנהל החלונות קל משקל -Comment[hi]=एक हल्का विंडो प्रबंधक -Comment[hr]=Lagani upravitelj prozora -Comment[hu]=Egy nagyon egyszerű ablakkezelő -Comment[is]=Léttur gluggastjóri -Comment[it]=Un window manager leggero -Comment[ja]=軽量なウィンドウマネージャ -Comment[ka]=მსუბუქი ფანჯრი მენეჯერი -Comment[kk]=Жеңіл терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​សមត្ថភាព​ខ្សោយ -Comment[ko]=가벼운 창 관리자 -Comment[lt]=Nedaug resursų eikvojanti langų tvarkyklė -Comment[lv]=Viegls logu menedžeris -Comment[mk]=Лесен менаџер на прозорци -Comment[mn]=Хөнгөн цонхны удирдагч -Comment[ms]=Pengurus tetingkap ringan -Comment[mt]=Window manager ħafif -Comment[nb]=En lettvekts vindusbehandler -Comment[nds]=En ranke Finsterpleger -Comment[ne]=हल्का वजन सञ्झ्याल प्रबन्धक -Comment[nl]=Een lichtgewicht windowmanager -Comment[nn]=Ein lett vindaugssjef -Comment[pa]=ਇੱਕ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien o małych wymaganiach -Comment[pt]=Um gestor de janelas leve -Comment[pt_BR]=Um gerenciador de janelas leve -Comment[ro]=Un manager de ferestre foarte mic -Comment[ru]=Лёгкий оконный менеджер -Comment[rw]=Mugenga dirishya yoroshye -Comment[se]=Geahpes lásegieđahalli -Comment[sk]=Nenáročný správca okien -Comment[sl]=Lahek okenski upravitelj -Comment[sr]=Лагани менаџер прозора -Comment[sr@Latn]=Lagani menadžer prozora -Comment[sv]=Lättviktig fönsterhanterare -Comment[ta]=குறைவான எடை உடைய சாளர மேலாளர் -Comment[te]=తెలికైన విండొ అభికర్త -Comment[tg]=Мудири тирезаи сабук -Comment[th]=ระบบจัดการหน้าต่างขนาดเบา -Comment[tr]=Hızlı çalışan bir pencere yöneticisi -Comment[tt]=Ciñel täräzä-idäräçe -Comment[uk]=Швидкий менеджер вікон -Comment[uz]=Oddiy oyna boshqaruvchi -Comment[uz@cyrillic]=Оддий ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ nhẹ ký -Comment[wa]=On ledjir manaedjeu di purneas -Comment[zh_CN]=轻量级窗口管理器 -Comment[zh_TW]=一個輕量化的視窗管理程式 diff --git a/kdm/kfrontend/sessions/icewm.desktop b/kdm/kfrontend/sessions/icewm.desktop deleted file mode 100644 index 8b70361fa..000000000 --- a/kdm/kfrontend/sessions/icewm.desktop +++ /dev/null @@ -1,81 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=icewm-session -TryExec=icewm-session -Name=IceWM -Name[eo]=GlaciFA -Name[hi]=आइस-डबल्यूएम -Name[lo]=ຕົວຈັດການຫນ້າຕ່າງ IceWM -Name[sv]=Ice WM -Name[te]=ఐస్ డబ్ల్యు ఎం -Name[th]=ตัวจัดการหน้าต่าง IceWM -Comment=A Windows 95-OS/2-Motif-like window manager -Comment[af]='n Windows 95-OS/2-Motif tipe venster bestuurder -Comment[ar]=مدير نوافذ مشابه لـ Win95-OS/2-Motif -Comment[be]=Кіраўнік вокнаў, падобны на Windows 95-OS/2-Motif -Comment[bn]=Windows 95-OS/2-Motif-এর অনুরূপ একটি উইণ্ডো ম্যানেজার -Comment[bs]=Window manager nalik na Windows 95-OS/2-Motif -Comment[ca]=Un gestor de finestres com els de Windows 95-OS/2-Motif -Comment[cs]=Správce oken podobný Windows 95-OS/2-Motif -Comment[csb]=Menedżer òknół szlachùjący za Windows 95-OS/2-Motif -Comment[cy]=Trefnydd ffenestri sy'n debyg i Windows95-OS/2-Motif -Comment[da]=En Windows 95-OS/2-Motif-lignende vindueshåndtering -Comment[de]=Fenstermanager im Stil von Windows 95, OS/2 und Motif -Comment[el]=Ένας διαχειριστής παραθύρων παρόμοιος με τα Windows 95-OS/2-Motif -Comment[eo]=Fenestroadministrilo kiel Vindozo 95, OS/2 kaj Motifo -Comment[es]=Un gestor de ventanas similar a Win95-OS/2-Motif -Comment[et]=Aknahaldur, mis näeb välja nagu Windows 95-OS/2-Motif -Comment[eu]=Windows 95 OS/2 Motif-en itxura duen leiho kudeatzailea -Comment[fa]=یک مدیر پنجره شبیه Windows 95-OS/2-Motif -Comment[fi]=Windows 95:n ja OS/2-Motifin tyylinen ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres ressemblant à Windows 95-OS/2-Motif -Comment[fy]=In Win95-OS/2-Motif-likens finstersmanager -Comment[gl]=Un xestor de fiestras coma o de Windows 95-OS/2-Motif -Comment[he]=מנהל חלונות מבוסס Motif הדומה במראהו לחלונות 95/OS-2 -Comment[hi]=विंडोज़ 95-ओएस/2-मोटिफ जैसा विंडो प्रबंधक -Comment[hr]=Upravitelj prozora nalik na Windows 95/OS/2/Motif -Comment[hu]=Win95-OS/2-Motif-szerű ablakkezelő -Comment[is]=Gluggastjóri sem líkist 95-OS/2-Motif -Comment[it]=Un window manager in stile Windows 95-OS/2-Motif -Comment[ja]=Windows95, OS/2, Motif に似たウィンドウマネージャ -Comment[ka]=ფანჯრების მენეჯერი Windows95-OS/2-Motif სტილში -Comment[kk]=Windows 95-OS/2-Motif-секілді терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​ដូច Windows 95-OS/2-Motif -Comment[ko]=윈도 95, OS/2, Motif를 닮은 창 관리자 -Comment[lt]=A Windows 95-OS/2-Motif-primenanti langų tvarkyklė -Comment[lv]=Windows 95 - OS/2 - Motif līdzīgs logu menedžeris -Comment[mk]=Менаџер на прозорци со изглед на Windows 95, OS/2 и Motif -Comment[mn]=Виндовс 95-OS/2-Motif-шиг цонхны удирдагч -Comment[ms]=Pengurus tetingkap seperti Motif Windows 95-OS/2 -Comment[mt]=Window manager jixbaħ lill-Windows 95-OS/2-Motif -Comment[nb]=En vindusbehandler som likner Windows 95-OS/2-Motif -Comment[nds]=Finsterpleger, de utsüht as Windows 95-OS/2-Motif -Comment[ne]=विण्डोज ९५-OS/2-मोटिफ जस्तो सञ्झ्याल प्रबन्धक -Comment[nl]=Een Win95-OS/2-Motif-achtige windowmanager -Comment[nn]=Ein vindaugssjef som liknar Windows 95-OS/2-Motif -Comment[pa]=ਇੱਕ ਵਿੰਡੋ 95-OS/2-Motif-ਵਰਗਾ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien podobny do Windows 95-OS/2-Motif -Comment[pt]=Um gestor de janelas parecido com o Windows 95, o OS/2 e o Motif -Comment[pt_BR]=Um gerenciador de janelas parecido com Windows 95-OS/2-Motif -Comment[ro]=Un manager de ferestre cu aspect de Windows 95, OS/2 sau Motif -Comment[ru]=Оконный менеджер в стиле Windows95-OS/2-Motif -Comment[rw]=Windows 95-OS/2-umutako-nka mugenga dirishya -Comment[se]=Windows 95-OS/2-Motif-lágan lásegieđahalli -Comment[sk]=Správca okien podobný Windows 95-OS/2-Motif -Comment[sl]=Okenski upravitelj, podoben Windows 95, OS/2 in Motifu -Comment[sr]=Менаџер прозора налик на Windows 95/OS/2/Motif -Comment[sr@Latn]=Menadžer prozora nalik na Windows 95/OS/2/Motif -Comment[sv]=Fönsterhanterare som liknar Windows 95-OS/2-Motif -Comment[ta]=சாளரங்கள் 95-OS/2-மாடிஃப்-லைக் சாளர மேலாளர் -Comment[te]=విండొస్ 95-ఒఎస్/2 -మొటిఫ్ లాంటి విండొ అభికర్త -Comment[tg]=Windows 95-OS/2-Motif-монанди мудири тиреза -Comment[th]=ระบบจัดการหน้าต่างของที่ดูคล้าย วินโดวส์ 95-โอเอสทู-โมทิฟ -Comment[tr]=Windows 95-OS/2-Motif benzeri bir pencere yöneticisi -Comment[tt]=Windows 95-OS/2-Motif küreneşendä täräzä-idäräçe -Comment[uk]=Менеджер вікон на кшталт Windows 95-OS/2-Motif -Comment[uz]=Win95-OS/2-Motif'ga oʻxshash oyna boshqaruvchi -Comment[uz@cyrillic]=Win95-OS/2-Motif'га ўхшаш ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ với mô típ kiểu Windows 95 -Comment[wa]=On manaedjeu di purneas rishonnant Windows95-OS/2-Motif -Comment[zh_CN]=类似 Windows-OS/2-Motif 的窗口管理器 -Comment[zh_TW]=一個像 Win95-OS/2-Motif 的視窗管理程式 diff --git a/kdm/kfrontend/sessions/ion.desktop b/kdm/kfrontend/sessions/ion.desktop deleted file mode 100644 index c4ae9ca04..000000000 --- a/kdm/kfrontend/sessions/ion.desktop +++ /dev/null @@ -1,77 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=ion -TryExec=ion -Name=Ion -Name[bn]=আয়ন (Ion) -Name[eo]=Iono -Name[hi]=आयन -Name[ja]=ION -Name[ko]=카메룬 -Name[pa]=ਲੋਨ -Name[te]=ఐయాన్ -Name[th]=ไอออน -Comment=A keyboard-friendly window manager with tiled windows, based on PWM -Comment[af]='n Sleutelbord vriendelike venster bestuurder, met geteëlde vensters. Dis op PWM gebaseer. -Comment[ar]=مدير نوافذ سهل استخدام لوحة المفاتيح ذي نوافذ معنونة، مبني على PWM -Comment[be]=Кіраўнік вокнаў для працы з клавіятурай, заснаваны на PWM -Comment[bn]=PWM ভিত্তিক উইণ্ডো ম্যানেজার, যা কীবোর্ড দিয়ে নিয়ন্ত্রণ করা সহজ -Comment[bs]=Window manager za tastaturu sa popločanim prozorima, baziran na PWM -Comment[ca]=Un gestor de finestres amigable amb el teclat i amb finestres alicatades, basat en PWM -Comment[csb]=Menedżer òknów z dobrą òbsłëgą klawiaturë ë kachelkòwaniém òknów, ùsôdzony na spòdlém PWM -Comment[cy]=Trefnydd ffenestri sy'n hawdd ei ddefnyddio o'r alweddell, efo ffenestri wedi'u teilio, wedi'i seilio ar PVM -Comment[da]=En tastaturvenlig vindueshåndtering med fliselagte vinduer, baseret på PWM -Comment[de]=Tastaturfreundlicher Fenstermanager mit gekachelten Fenstern, basiert auf PWM -Comment[el]=Ένας φιλικός με το πληκτρολόγιο διαχειριστής παραθύρων με υποστήριξη παραθύρων σε παράθεση, βασισμένος στον PWM -Comment[eo]=Fenestroadministrilo por la uzo klaviara -Comment[es]=Un gestor de ventanas utilizable desde el teclado con mosaico de ventanas, basado en PWM -Comment[et]=Klaviatuurisõprade aknahaldur paanitud akendega, aluseks PWM -Comment[eu]=PWMn oinarritutako leiho-mosaikoa duen leiho kudeatzailea, teklatutik erabil daitekeena -Comment[fa]=یک مدیر پنجرۀ صفحه کلید پسند با پنجره‌های کاشی‌شده، براساس PWM -Comment[fi]=Näppäimistöystävällinen ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres utilisable au clavier avec des fenêtres en mosaïque, fondé sur PWM -Comment[fy]=In toetseboerdfreonlike finstersmanager mei tegele finsters. basearre op PWM -Comment[gl]=Un xestor de fiestras de manexo co teclado e fiestras en mosaico baseado en PWM -Comment[he]=מנהל חלונות ידידותי למקלדת עם חלונות פרושים המבוסס על PWM -Comment[hi]=पीडबल्यूएम आधारित चटाई विंडो युक्त विंडो प्रबंधक जो कुंजीपट फ्रेडली है -Comment[hr]=Comment=Upravitelj prozora s popločenim prozorima, namijenjen tipkovnici i zasnovan na PWM-u -Comment[hu]=Egy billentyűzetről könnyen kezelhető ablakkezelő, mozaikszerű ablakelrendezéssel, a PWM alapján -Comment[is]=Gluggastjóri sem er gott að vinna í með lyklaborðinu einu, byggður á PWM -Comment[it]=Un window manager "amico della tastiera" con finestre affiancate, basato su PWM -Comment[ja]=PWM ベースのキーボード操作に適したタイル表示式のウィンドウマネージャ -Comment[ka]=კლავიატურით მართვადი ფანჯრების მენეჯერი, PWM-ის ბაზაზე -Comment[kk]=PWM-негіздеген, пернетақтадан басқарылатын, терезелері кезектескен, терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​ងាយ​ប្រើ​ជាមួយ​ក្ដារចុច ហើយ​អាច​រៀប​បង្អួច​ជា​ក្បឿង និង​ផ្អែក​លើ PWM -Comment[lt]=Patogi dirbti su klaviatūra langų tvarkyklė su išklotais langais, paremta PWM -Comment[lv]=Tastatūrai draudzīgs logu menedžeris ar tiled logiem, bāzēts uz PWM -Comment[mk]=Менаџер на прозорци со поплочени прозорци базиран на PWM погоден за работа со тастатура -Comment[mn]=PWM дээр суурилсан гараар ажиллахад тохиромжтой цонх удирдагч -Comment[ms]=Pengurus tetingkap mesra papan kekunci dengan tetingkap berjubin, berdasarkan PWM -Comment[mt]=Window manager ibbażat fuq PWM, b'sapport għal tastieri u windows imqassma fuiq madum -Comment[nb]=En tastaturvennlig vindusbehandler med flislagte vinduer, basert på PWM -Comment[nds]=En tastatuurfründliche Finsterpleger mit kachelte Finstern, opbuut op PWM -Comment[ne]=शीर्षक सञ्झ्यालसँग सोझो सञ्झ्याल प्रबन्धक कुञ्जीपाटी -Comment[nl]=Een toetsenbordvriendelijke windowmanager met getegelde vensters. Gebaseerd op PWM -Comment[nn]=Ein tastaturvennleg vindaugssjef med flislagde vindauge, basert på PWM -Comment[pa]=ਇੱਕ ਕੀ-ਬੋਰਡ ਸਹਾਇਕ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਜੋ ਕਿ PWM ਤੇ ਆਧਾਰਿਤ ਹੈ -Comment[pl]=Menedżer okien z dobrą obsługą klawiatury i kafelkowaniem okiem, stworzony na podstawie PWM -Comment[pt]=Um gestor de janelas amigável para o teclado, com janelas lado-a-lado, baseado no PWM -Comment[pt_BR]=Um gerenciador de janelas amigável com o teclado, com janelas ladrilhadas, baseado no PWM -Comment[ro]=Un manager de ferestre ușor de utilizat din tastatură, cu ferestre ce pot fi așezate în mozaic, bazat pe PWM -Comment[ru]=Управляемый с клавиатуры оконный менежер, основанный на PWM -Comment[rw]=mugenga dirishya ya mwandikisho-yoroshyeikoresha ifite amadirishya agerekeranye, ishingiye kuri PWM -Comment[se]=Boallobeavdeustitlaš lašegieđahalli, mas leat bálddalas láset, ráhkaduvvon PWM vuođul -Comment[sk]=Správca okien s podporou kláves, usporiadania okien do dlaždíc, založený na PWM -Comment[sl]=Tipkovnici prijazen okenski upravitelj z razdeljenimi okni, na osnovi PWM -Comment[sr]=Пријатељски према тастатури менаџер прозора са наслаганим прозорима, заснован на PWM-у -Comment[sr@Latn]=Prijateljski prema tastaturi menadžer prozora sa naslaganim prozorima, zasnovan na PWM-u -Comment[sv]=Tangentbordsvänlig fönsterhanterare med fönster sida vid sida, baserad på PWM -Comment[ta]=PWM அடிப்படையிலான விசைப்பலகையால் கையாளமுடிந்த சாளர மேளாளர் -Comment[th]=ระบบจัดการหน้าต่างที่เป็นมิตรกับการใช้แป้นพิมพ์ พร้อมกับหน้าต่างที่ถูกปูเรียง สร้างจาก PWM -Comment[tr]=PWM tabanlı, klavye dostu uzatılmış pencereleriyle bir pencere yönetici -Comment[tt]=Täräzä bülü belän töylek-söygän täräzä-idäräçe, PWM asılında -Comment[uk]=Менеджер вікон налаштований для легкого використання з клавіатурою, засновано на PWM -Comment[vi]=Trình quản lý cửa sổ thiết kết thân thiện với việc dùng bàn phím, có các cửa sổ xếp ngói, dựa trên PWM -Comment[wa]=On manaedjeu di purneas k' inme li taprece avou des purneas å pus grand, båzé so PWM -Comment[zh_CN]=一个基于 PWM 的窗口管理器,适合键盘操作,可平铺窗口 -Comment[zh_TW]=一個基於 PWM 且方便鍵盤使用和支援棋盤化視窗的視窗管理程式 diff --git a/kdm/kfrontend/sessions/larswm.desktop b/kdm/kfrontend/sessions/larswm.desktop deleted file mode 100644 index 072b382c5..000000000 --- a/kdm/kfrontend/sessions/larswm.desktop +++ /dev/null @@ -1,72 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=larswm -TryExec=larswm -Name=LarsWM -Name[eo]=Lazero -Name[hi]=लार्स-डबल्यूएम -Name[ko]=라이코스 -Name[sv]=Lars WM -Name[te]=లార్స్ డబ్ల్యు ఎం -Comment=The Lars Window Manager, based on 9WM, supports tiled windows -Comment[af]=Die Lars venster bestuurder, wat op 9WM gebaseer is. Dit ondersteun geteëlde vensters. -Comment[ar]=مدير نوافذ لارس، مبني على 9WM، يدعم النوافذ المعنونة -Comment[be]=Кіраўнік вокнаў Lars Window Manager, заснаваны на 9WM -Comment[bn]=লার্স উইণ্ডো ম্যানেজার, 9WM-এর ওপর ভিত্তি করে তৈরি -Comment[bs]=Lars Window Manager, baziran 9WM, podržava popločane prozore -Comment[ca]=El gestor de finestres Lars, basat en 9WM, permet finestres alicatades -Comment[csb]=Menedżer òknów Larsa, ùsôdzony na spòdlém 9WM, wspiérô kachelkòwanié òknów -Comment[cy]=Y Trefnydd Ffenestri Lars, wedi'i seilio ar 9WM, sy'n cynnal ffenestri wedi'u teilio -Comment[da]=Lars vindueshåndteringen, baseret på 9WM, understøtter fliselagte vinduer -Comment[de]=Lars-Fenstermanager, basiert auf 9WM und unterstützt gekachelte Fenstern -Comment[el]=Ο διαχειριστής παραθύρων Lars, βασισμένος στον 9WM, υποστηρίζει παράθυρα σε παράθεση -Comment[eo]=La Laza Fenestroadministrilo, devenigita de 9FA -Comment[es]=El Lars Window Manager, basado en 9WM, soporta mosaico de ventanas -Comment[et]=Larsi aknahaldur, mille aluseks on 9WM, toetab paanitud aknaid -Comment[eu]=Lars leiho kudeatzailea, 9WM-n oinarritua, leiho-mosaikorako euskarria duena -Comment[fa]=مدیر پنجرۀ Lars، بر اساس 9WM، پنجره‌های کاشی‌شده را پشتیبانی می‌کند. -Comment[fi]=Lars-ikkunaohjelma. Pohjautuu 9WM:ään ja tukee järjestettyjä ikkunoita -Comment[fr]=The Lars Window Manager, fondé sur 9WM, avec une gestion des fenêtres en mosaïque -Comment[fy]=De Lars Window Manager, basearre op 9WM. Biedt stipe foar tegele finsters -Comment[gl]=O Xestor de Fiestras Lars, baseado en 9WM, atura fiestras en mosaico -Comment[he]=The Lars Window Manager, מבוסס על 9WM, תומך בחלונות פרושים -Comment[hi]=9डबल्यूएम आधारित लार्स विंडो प्रबंधक, चटाई विडो समर्थित करता है -Comment[hr]=Lars upravitelj prozora, zasnovan na 9WMu, podržava popločene prozore -Comment[hu]=Lars ablakkezelője, a 9WM alapján, mozaikszerű ablakelrendezési lehetőséggel -Comment[is]=Lars gluggastjórinn, byggður á 9WM og styður flísaða glugga -Comment[it]=Il Window Manager di Lars, basato su 9WM, supporta le finestre affiancate -Comment[ja]=Lars ウィンドウマネージャ, 9WMベース, タイル表示をサポートするウィンドウマネージャ -Comment[kk]=9WM-негіздеген терезе менеджері -Comment[km]=Lars Window Manager ផ្អែក​លើ 9WM គាំទ្រ​បង្អួច​ជា​ក្បឿង -Comment[lt]=Lars langų tvarkyklė, paremta 9WM, turi galimybę iškloti langus -Comment[mk]=Lars Window Manager, менаџер базиран на 9WM, поддржува поплочени прозорци -Comment[mn]=The Lars Window Manager, 9WM дээр суурилсан, олон цонхтой -Comment[ms]=Pengurus Tetingkap Lars, berdasarkan 9WM, menyokong tetingkap berjubin -Comment[mt]=Lars Window Manager - ibbażat fuq 9WM u jiflaħ windows imqassma f'madum -Comment[nb]=Lars vindusbehandler, basert på 9WM, støtter flislagte vinduer -Comment[nds]=De Lars-Finsterpleger, opbuut op 9WM, ünnerstütt kachelte Finstern -Comment[ne]=9WM मा आधारित लार्स सञ्झ्याल प्रबन्धक, टायल गरिएका सञ्झ्यालहरू समर्थन गर्छ -Comment[nl]=De Lars Window Manager, gebaseerd op 9WM. Biedt ondersteuning voor getegelde vensters -Comment[nn]=Vindaugssjefen Lars, basert på 9WM, støttar flislagde vindauge -Comment[pa]=ਲਾਰਸ ਫਾਇਲ਼ ਮੈਨੇਜਰ 9WM ਤੇ ਆਧਾਰਿਤ, ਝਰੋਖਿਆਂ ਦੇ ਸਮੇਟਣ ਲਈ ਸਹਾਈ -Comment[pl]=Menedżer okien Larsa, stworzony na podstawie 9WM, obsługuje kafelkowanie okien -Comment[pt]=O Lars Window Manager, baseado no 9WM, e que suporta janelas lado-a-lado -Comment[pt_BR]=O gerenciador de janelas Lars, baseado no 9WM, com suporte a janelas ladrilhadas -Comment[ro]=Managerul de ferestre al lui Lars, bazat pe 9WM. Suportă ferestre aranjate în mozaic -Comment[ru]=Оконный менеджер на основе 9wm -Comment[rw]=Mugenga Dirishya Lars, ishingiye kuri 9WM, yemera amadirishya agerekeranye -Comment[se]=Lásegieđahalli Lars, ráhkaduvvon 9WM vuođul, doarju bálddalas lásiid. -Comment[sk]=The Lars Window Manager založený na 9WM s podporou okien usporiadaných do dlaždíc -Comment[sl]=Larsov okenski upravitelj, na osnovi 9WM, podpira porazdeljena okna -Comment[sr]=„Lars Window Manager“, заснован на 9WM-у, подржава наслагане прозоре -Comment[sr@Latn]=„Lars Window Manager“, zasnovan na 9WM-u, podržava naslagane prozore -Comment[sv]=Lars fönsterhanterare, baserad på 9WM, med stöd för fönster sida vid sida -Comment[ta]=9WM அடிபடையிலான லார்ஸ் சாளர மேலாளர் சீரமைக்கப்பட்ட சாளரங்களை ஆதரிக்கிறது -Comment[th]=ระบบจัดการหน้าต่าง Lars สร้างจาก 9WM สนับสนุนการปูเรียงหน้าต่าง -Comment[tr]=Lars Pencere Yöneticisi -Comment[tt]=Lars Window Manager, 9WM asılında, bülengän täräzä tota -Comment[uk]=The Lars Window Manager, засновано на 9WM, підтримує розташування вікон плиткою -Comment[vi]= Trình Quản lý Cửa sổ Lars, dựa vào 9WM, hỗ trợ cửa sổ xếp ngói -Comment[wa]=Li manaedjeu d' purnea d' Lasrs (Lars Window Manager), båzé so 9WM, sopoite les purneas å pus grand -Comment[zh_CN]=Lars 窗口管理器,基于 9WM,支持平铺窗口 -Comment[zh_TW]=The Lars 視窗管理程式,基於 9WM,支援棋盤化視窗 diff --git a/kdm/kfrontend/sessions/lwm.desktop b/kdm/kfrontend/sessions/lwm.desktop deleted file mode 100644 index 2f3e0ff00..000000000 --- a/kdm/kfrontend/sessions/lwm.desktop +++ /dev/null @@ -1,76 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=lwm -TryExec=lwm -Name=LWM -Name[eo]=MFA -Name[hi]=एलडबल्यूएम -Name[te]=ఎల్ డబ్ల్యు ఎం -Name[th]=ตัวจัดการหน้าต่าง LWM -Comment=The Lightweight Window Manager. A non-configurable, bare window manager -Comment[af]=Die lig gewig venster bestuurder. -Comment[ar]=مدير النوافذ خفيف العبء، مدير نوافذ مجرّد غير قابل للإعداد -Comment[be]=The Lightweight Window Manager. Пусты кіраўнік вокнаў без падтрымкі настаўленняў -Comment[bn]=দি লাইটওয়েট উইণ্ডো ম্যানেজার -Comment[bs]=Lightweight Window Manager. Ne-podesivi, potpuno osnovni window manager -Comment[ca]=El gestor de finestres Lightweight. Un gestor de finestres no configurable i pelat -Comment[cs]=The Lightweight Window Manager. Prostý a nekonfigurovatelný správce oken -Comment[csb]=Lightweight Window Manager (Letczi menedżer òknół). Bro prosti menedżer òknów bez mòżnoté kònfigùracëji -Comment[cy]=Y Trefnydd Ffenestri Ysgafn. Trefnydd ffenestri noeth, na ellir ffurfweddu -Comment[da]=Lightweight Window Manager, en ikke-indstillelig, minimal vindueshåndtering -Comment[de]=Lightweight Window Manager -- reiner Fenstermanager ohne Einstellmöglichkeiten -Comment[el]=Ο ελαφρύς διαχειριστής παραθύρων. Ένας μη παραμετροποιήσιμος, πολύ απλός διαχειριστής παραθύρων -Comment[eo]=Malpeza Fenestroadministrilo -Comment[es]=El Lightweight Window Manager, un sencillísimo y no configurable gestor de ventanas -Comment[et]=Imeväike aknahaldur on seadistamatu, sõna otseses mõttes ainult akende haldur -Comment[eu]=Libhtweight leiho kudeatzailea. Konfiguraziorik onartzen ez duen leiho-kudeatzaile zeharo sinplea -Comment[fa]=مدیر پنجرۀ سبک، مدیر پنجرۀ غیرقابل پیکربندی و ساده -Comment[fi]=Kevyt ikkunaohjelma. Paljas, ei muokattavissa oleva ikkunaohjelma -Comment[fr]=The Lightweight Window Manager. Un gestionnaire de fenêtres non configurable et nu -Comment[fy]=De Lightweight Window Manager, in net-ynstelbere, keale finstersmanager -Comment[gl]=O Xestor de Fiestras Lixeiro. -Comment[he]=The Lightweight Window Manager. מנהל חלונות מצומצם בלי אפשרויות להגדרה. -Comment[hi]=हल्का विंडो प्रबंधक. खाली विंडो प्रबंधक जो कॉन्फ़िगर नहीं हो सकता -Comment[hr]=LWM - Lightweight Window Manager (Lagani upravitelj prozora) - Temeljni upravitelj prozora bez mogućnosti konfiguriranja -Comment[hu]=Lightweight Window Manager, egy könnyen konfigurálható, alapszintű ablakkezelő -Comment[is]=Hinn létti gluggastjóri. Ekki stillanlegur og hrár -Comment[it]=Il Window Manager Leggero. Un window manager essenziale e non configurabile -Comment[ja]=設定項目のない、単純なウィンドウマネージャ -Comment[ka]=მსუბუქი არაკონფიგურირებადი ფანჯრების მენეჯერი -Comment[kk]=Lightweight Window Manager. Баптауы жоқ, жай терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​សមត្ថភាព​ខ្សោយ ។ កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​គ្មាន​អ្វី​បិទបាំង ហើយ​មិន​អាច​កំណត់​រចនាសម្ព័ន្ធ​បាន -Comment[lt]=„Lengva“ langų tvarkyklė. Nekonfigūruojama, „plika“ langų tvarkyklė -Comment[lv]=Vieglais logu menedžeris. Nekonfigurējams, vienkāršs logu menedžeris -Comment[mk]=Lightweight Window Manager. Неконфигурабилен, скоро празен менаџер на прозорци -Comment[mn]=The Lightweight Window Manager. Тохируулгах боломжгүй,цонхны удирдлага -Comment[ms]=Pengurus tetingkap Ringan. Tidak boleh konfigur, pengurus tetingkap terdedah -Comment[mt]=Lightweight Window Manager. Window Manager sempliċi u mhux konfigurabbli -Comment[nb]=Lettvekts vindusbehandler- Lightweight Window Manager. En enkel vindusbehandler uten innstillinger. -Comment[nds]=De "Lightweight"-Finsterpleger. En reen Finsterpleger ahn Instellen -Comment[ne]=हल्का वजन सञ्झ्याल प्रबन्धक । कन्फिगर गर्न नसकिने, बेयर सञ्झ्याल प्रबन्धक -Comment[nl]=De Lightweight Window Manager, een niet-instelbare, kale windowmanager -Comment[nn]=Lightweight Window Manager. Ein enkel vindaugssjef utan innstillingar. -Comment[pa]=ਇੱਕ ਹਲਕਾ, ਨਾ-ਸੰਰਚਿਤਯੋਗ ਪੱਟੀ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Lightweight Window Manager (Lekki menedżer okien). Surowy menedżer okien bez możliwości konfiguracji -Comment[pt]=O Lightweight Window Manager. Um gestor de janelas não-configurável e básico -Comment[pt_BR]=Um gerenciador de janelas leve, sendo básico e não muito configurável -Comment[ro]=Lightweight Window Manager. Un manager de ferestre neconfigurabil și minimal -Comment[ru]=Облегчённый, не настраиваемый простой оконный менеджер -Comment[rw]=Mugenga Dirishya Yoroshye. Mugenga dirishya idafite ikintu, itabonezwa. -Comment[se]=Lightweight Window Manager. Oktageardánis lásegieđahalli mii ii lea heivehahtti. -Comment[sk]=The Lightweight Window Manager. Nenastaviteľný, jednoduchý správca okien -Comment[sl]=Lahek okenski upravitelj. Ni nastavljiv, osnovni okenski upravitelj -Comment[sr]=„Lightweight Window Manager“. Неподесив, голи менаџер прозора -Comment[sr@Latn]=„Lightweight Window Manager“. Nepodesiv, goli menadžer prozora -Comment[sv]=Den lättviktiga fönsterhanteraren. En enkel fönsterhanterare utan anpassningsmöjligheter -Comment[ta]=குறைந்த எடையுள்ள சாளர மேலாளர். வடிவமைக்க முடியாத -Comment[th]=Lightweight Window Manager ระบบจัดการหน้าต่างเปล่าๆ ที่ไม่สามารถปรับแต่งได้เลย -Comment[tr]=Lightweight Pencere Yöneticisi. Yapılandırılamayan, kaba pencere yönetici -Comment[tt]=Lightweight Window Manager. Caylanmí torğan, ciñel täräzä-idäräçe -Comment[uk]=Невеличкий менеджер вікон без можливості налаштування -Comment[vi]=Trình Quản lý Cửa sổ Nhẹ ký. Rất khó cấu hình -Comment[wa]=Li Ledjir Manaedjeu di Purneas (Lightweight Window Manager). On manaedjeu di purneas tot simpe, nén apontiåve -Comment[zh_CN]=轻量级窗口管理器。不可配置的裸窗口管理器 -Comment[zh_TW]=一個輕量化的視窗管理程式。不可組態、只有基礎視窗管理的視窗管理程式 -# this can't be used as a session in itself -Hidden=true diff --git a/kdm/kfrontend/sessions/matchbox.desktop b/kdm/kfrontend/sessions/matchbox.desktop deleted file mode 100644 index 3bec343b0..000000000 --- a/kdm/kfrontend/sessions/matchbox.desktop +++ /dev/null @@ -1,82 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=matchbox-window-manager -TryExec=matchbox-window-manager -Name=Matchbox -Name[bn]=ম্যাচবক্স -Name[eo]=Alumetujo -Name[hi]=मैचबॉक्स -Name[ne]=मिल्ने बाकस -Name[pa]=ਮੈਚ-ਬਾਕਸ -Name[rw]=Agasandukugahura -Name[ta]=பொருத்தப்பெட்டி -Name[te]=అగ్గి పెట్టె -Name[tg]=Қуттии гӯгирд -Name[wa]=Boesse di brocales (Matchbox) -Comment=A window manager for handheld devices -Comment[af]='n Venster bestuurder vir draagbare toestelle -Comment[ar]=مدير نوافذ للأجهزة اليدوية -Comment[be]=Кіраўнік вокнаў для кішанёвых кампутараў -Comment[bn]=হ্যাণ্ডহেল্ড যন্ত্রাদির উপযোগী একটি উইণ্ডো ম্যানেজার -Comment[bs]=Window manager za ručne uređaje -Comment[ca]=Un gestor de finestres per a dispositius de ma -Comment[cs]=Správce oken pro PDA -Comment[csb]=Menedżer òknów dlô palmtopów -Comment[cy]=Trefnydd ffenestri ar gyfer llawiaduron -Comment[da]=En vindueshåndtering for håndholdte enheder -Comment[de]=Fenstermanager für portable Geräte -Comment[el]=Ένας διακομιστής παραθύρων για συσκευές παλάμης -Comment[eo]=Fenestroadministrilo por manaj aparatoj -Comment[es]=Un gestor de ventanas para dispositivos de mano -Comment[et]=Aknahaldur pihuarvutitele -Comment[eu]=Eskuan erabiltzeko gailuentzako leiho kudeatzailea -Comment[fa]=یک مدیر پنجره برای دستگاههای دستی -Comment[fi]=ikkunaohjelma PDA-laitteisiin -Comment[fr]=Un gestionnaire de fenêtres pour les périphériques contrôlés à la main -Comment[fy]=In finstersmanager foar hânkompjûters -Comment[gl]=Un xestor de fiestras para dispositivos manuais -Comment[he]=מנהל חלונות למכשירים נישאים -Comment[hi]=हाथ में रखने वाले औज़ारों के लिए विंडो प्रबंधक -Comment[hr]=Upravitelj prozora za ručna računala -Comment[hu]=Ez az ablakkezelő elsősorban kéziszámítógépekhez ajánlott -Comment[is]=Gluggastjóri fyrir lófatölvur -Comment[it]=Un window manager per palmari -Comment[ja]=ハンドヘルドデバイス向けのウィンドウマネージャ -Comment[ka]=ფანჯრების მენეჯერი მობილური მოწყობილობებისთვის -Comment[kk]=Қол құрылғыларға арналған терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច សម្រាប់​ឧបករណ៍​យួរដៃ -Comment[ko]=핸드헬드 장치를 위한 창 관리자 -Comment[lt]=Langų tvarkyklė įvairiems įrenginiams -Comment[lv]=Logu menedžeris priekš portatīvajām iekārtām -Comment[mk]=Менаџер на прозорци за преносни уреди -Comment[mn]=Гар төхөөрөмжид зориулсан цонхны удирдлага -Comment[ms]=Pengurus tetingkap untuk peranti telapak -Comment[mt]=Window manager għal apparat "handheld" -Comment[nb]=En vindusbehandler for håndholdte enheter -Comment[nds]=Finsterpleger för Handreekner -Comment[ne]=ह्यान्डहेल्ड यन्त्रहरूका लागि सञ्झ्याल प्रबन्धक -Comment[nl]=Een windowmanager voor handcomputers -Comment[nn]=Ein vindaugssjef for handhaldne einingar -Comment[pa]=ਹੱਥਲੇ ਜੰਤਰਾਂ ਲਈ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien dla palmtopów -Comment[pt]=Um gestor de janelas para dispositivos móveis -Comment[pt_BR]=Um gerenciador de janelas para dispositivos handheld -Comment[ro]=Un manager de ferestre pentru PDA-uri -Comment[ru]=Оконный менеджер для мобильных устройств -Comment[rw]=Mugenga dirishya y'amapareye atwarwa-ntoki -Comment[se]=Lásegieđahalli giehtaovttadagaid várás -Comment[sk]=Správca okien pre prenosné zariadenia -Comment[sl]=Okenski upravitelj za dlančne naprave -Comment[sr]=Менаџер прозора за мале преносне уређаје -Comment[sr@Latn]=Menadžer prozora za male prenosne uređaje -Comment[sv]=Fönsterhanterare för handburna enheter -Comment[ta]=கையில் உள்ள சாதனங்களுக்கான சாளர மேலாளர் -Comment[tg]=Як мудири тиреза барои дастгоҳҳои дастӣ -Comment[th]=ระบบจัดการหน้าต่างของอุปกรณ์มือถือ -Comment[tr]=El bilgisayarları için bir pencere yöneticisi -Comment[tt]=Qul cıhazı öçen täräzä-idäräçe -Comment[uk]=Менеджер вікон для портативних пристроїв -Comment[vi]=Trình quản lý cửa sổ dành cho thiết bị cầm tay -Comment[wa]=On manaedjeu di purneas po les éndjins ebarkés -Comment[zh_CN]=手持设备的窗口管理器 -Comment[zh_TW]=一個掌上型設備所使用的視窗管理程式 diff --git a/kdm/kfrontend/sessions/metacity.desktop b/kdm/kfrontend/sessions/metacity.desktop deleted file mode 100644 index d2a5a5537..000000000 --- a/kdm/kfrontend/sessions/metacity.desktop +++ /dev/null @@ -1,83 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=metacity -TryExec=metacity -Name=Metacity -Name[bn]=মেটাসিটি -Name[eo]=Metaurbo -Name[hi]=मेटासिटी -Name[mn]=Метасити -Name[ne]=मेटासिटी -Name[rw]=Metacity(Mugenga-dirishya) -Name[ta]=மெடாசிட்டி -Name[te]=మెటాసిటి -Comment=A lightweight GTK2 based window manager -Comment[af]=Die lig gewig GTK2 gebaseerde venster bestuurder -Comment[ar]=مدير نوافذ خفيف العبء مبني على GTK2 -Comment[be]=Лёгкі кіраўнік вокнаў, заснаваны на GTK2 -Comment[bn]=একটি হাল্কা GTK2 ভিত্তিক উইণ্ডো ম্যানেজার -Comment[bs]=Lagani window manager baziran na GTK2 -Comment[ca]=Un gestor de finestres lleuger basat en GTK2 -Comment[cs]=Malý správce oken založený na GTK2 -Comment[csb]=Menedżer òknół ò môłëch żądniach, òpiarti na GTK2 -Comment[cy]=Trefnydd ffenestri ysgafn, wedi'i seilio ar GTK2 -Comment[da]=En letvægts GTK2 baseret vindueshåndtering -Comment[de]=Schlanker Fenstermanager, der auf GTK2 basiert -Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων βασισμένος στο GTK2 -Comment[eo]=Malpeza fenestroadministrilo -Comment[es]=Un gestor de ventanas ligero basado en GTK2 -Comment[et]=Imeväike aknahaldur, mille aluseks on GTK2 -Comment[eu]=GTK2n oinarritutako leiho kudeatzaile arin bat -Comment[fa]=GTK2 سبک بر اساس مدیر پنجره -Comment[fi]=Kevyt, GTK2-pohjainen ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres fondé sur GTK2 et léger -Comment[fy]=In lichtgewicht op GTK2 basearre finstersmanager -Comment[gl]=Un xestor de fiestras lixeiro baseado en GTK2 -Comment[he]=מנהל חלונות קל מבוסס GTK2 -Comment[hi]=जीटीके2 आधारित हल्का विंडो प्रबंधक -Comment[hr]=Lagani upravitelj prozora zasnovan na GTK2 -Comment[hu]=Egy egyszerű, GTK2-alapú ablakkezelő -Comment[is]=Léttur gluggastjóri byggður á GTK2 -Comment[it]=Un window manager leggero basato su GTK2 -Comment[ja]=GTK2 ベースの軽量なウィンドウマネージャ -Comment[ka]=GTK2-ს ბაზაზე მსუბუქი ფანჯრის მენეჯერი -Comment[kk]=GTK2-негіздеген, жеңіл терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​សមត្ថភាព​ខ្សោយ ដែល​ផ្អែក​លើ GTK2 -Comment[ko]=가벼운 GTK2 기반 창 관리자 -Comment[lt]=Nedaug resursų reikalaujanti langų tvarkyklė, paremta GTK2 -Comment[lv]=Viegls GTK 2 bāzēts logu menedžeris -Comment[mk]=Лесен менаџер на прозорци базиран на GTK2 -Comment[mn]=Хөнгөн GTK2 суурьт цонхны удирдагч -Comment[ms]=Pengurus tetingkap berasaskan GTK2 ringan -Comment[mt]=Window manager ħafif ibbażat fuq GTK2 -Comment[nb]=En lettvekts vindusbehandler basert på GTK2 -Comment[nds]=En ranke Finsterpleger, opbuut op GTK2 -Comment[ne]=सञ्झ्याल प्रबन्धकमा आधारित हल्का वजन GTK2 -Comment[nl]=Een lichtgewicht op GTK2 gebaseerde windowmanager -Comment[nn]=En lett vindaugssjef basert på GTK2 -Comment[pa]=ਇੱਕ ਹਲਕਾ GTK2 ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien o małych wymaganiach, oparty na GTK2 -Comment[pt]=Um gestor de janelas leve, baseado em GTK2 -Comment[pt_BR]=Um gerenciador de Janelas leve baseado em GTK2 -Comment[ro]=Un manager de ferestre mic bazat pe GTK2 -Comment[ru]=Лёгкий оконный менеджер на основе GTK2 -Comment[rw]=Mugenga dirishya ishingiye kuri GTK2 yoroshye -Comment[se]=Geahpes GTK2-vuođđoduvvon lásegieđahalli -Comment[sk]=Nenáročný správca okien založený na GTK2 -Comment[sl]=Lahek okenski upravitelj na osnovi GTK2 -Comment[sr]=Лагани менаџер прозора заснован на GTK2 -Comment[sr@Latn]=Lagani menadžer prozora zasnovan na GTK2 -Comment[sv]=Lättviktig GTK2-baserad fönsterhanterare -Comment[ta]=சாளர மேலாளர் அடிப்படையிலான ஒரு குறைந்த எடை GTK2 -Comment[te]=తెలికైన జిటికె2 ఆధారిత విండొ అభికర్త -Comment[tg]=Сабуки GTK2 ба асоси мудири тиреза -Comment[th]=ระบบจัดการหน้าต่างขนาดเบาที่ใช้ GTK2 -Comment[tr]=Gtk2 tabanlı hafif bir pencere yöneticisi -Comment[tt]=GTK2 asılında ciñel täräzä-idäräçe -Comment[uk]=Простий менеджер вікон для GTK2 -Comment[uz]=GTK2 asosida yaratilgan oddiy oyna boshqaruvchi -Comment[uz@cyrillic]=GTK2 асосида яратилган оддий ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ nhỏ gọn dựa trên GTK2 -Comment[wa]=On ledjir manaedjeu di purneas båzé so GTK2 -Comment[zh_CN]=轻量级 GTK2 窗口管理器 -Comment[zh_TW]=一個基於 GTK2 的輕量化視窗管理程式 diff --git a/kdm/kfrontend/sessions/mwm.desktop b/kdm/kfrontend/sessions/mwm.desktop deleted file mode 100644 index b1d6e2acd..000000000 --- a/kdm/kfrontend/sessions/mwm.desktop +++ /dev/null @@ -1,78 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=mwm -TryExec=mwm -Name=MWM -Name[eo]=MFA -Name[hi]=एमडबल्यूएम -Name[te]=ఎం డబ్ల్యు ఎం -Name[th]=ตัวจัดการหน้าต่าง MWM -Comment=The Motif Window Manager -Comment[af]=Die Motif venster bestuurder -Comment[ar]=مسيير النوافذ Motif -Comment[be]=Кіраўнік вокнаў Motif -Comment[bn]=দি মোটিফ উইণ্ডো ম্যানেজার -Comment[bs]=Motif Window Manager -Comment[ca]=El gestor de finestres Motif -Comment[cs]=Motif Window Manager -Comment[csb]=Menedżer òknów Motif -Comment[cy]=Y Trefnydd Ffenestri Motif -Comment[da]=Motif vindueshåndtering -Comment[de]=Motif-Fenstermanager -Comment[el]=Ο διαχειριστής παραθύρων Motif -Comment[eo]=Motifa fenestroadministrilo -Comment[es]=El gestor de ventanas de Motif -Comment[et]=Motifi aknahaldur -Comment[eu]=Motif leiho kudeatzailea -Comment[fa]=مدیر پنجره موتیف -Comment[fi]=Motif-ikkunaohjelma -Comment[fr]=Le gestionnaire de fenêtres Motif -Comment[fy]=De Motif Window Manager -Comment[ga]=Bainisteoir fuinneoga Motif -Comment[gl]=O Xestor de Fiestras Motif -Comment[he]=מנהל החלונות Motif -Comment[hi]=मोटिफ विंडो प्रबंधक -Comment[hr]=Motif upravitelj prozora -Comment[hu]=Motif ablakkezelő -Comment[is]=Motif gluggastjórinn -Comment[it]=Il window manager di Motif -Comment[ja]=Motif 風のウィンドウマネージャ -Comment[ka]=ფანჯრის მენეჯერი Motif -Comment[kk]=Motif терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច Motif -Comment[ko]=Motif 창 관리자 -Comment[lt]=Motif langų tvarkyklė -Comment[lv]=Motif logu menedžeris -Comment[mk]=Менаџерот на прозорци Motif -Comment[mn]=Motif Цонхны удирдагч -Comment[ms]=Pengurus Tertingkap Motif -Comment[mt]=Window manager tal-Motif -Comment[nb]=Motif vindusbehandler -Comment[nds]=De Motif-Finsterpleger -Comment[ne]=मोटिफ सञ्झ्याल प्रबन्धक -Comment[nl]=De Motif Window Manager -Comment[nn]=Motif-vindaugssjefen -Comment[pa]=Motif ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien Motif -Comment[pt]=O gestor de janelas do Motif -Comment[pt_BR]=O gerenciador de janelas Motif -Comment[ro]=Managerul de ferestre Motif -Comment[ru]=Оконный менеджер Motif -Comment[rw]=Mugenga Dirishya Umutako -Comment[se]=Motif lásegieđahalli -Comment[sk]=Správca okien Motif -Comment[sl]=Okenski upravitelj Motif -Comment[sv]=Motifs fönsterhanterare -Comment[ta]=மோடிஃப் சாளர மேலாளர் -Comment[te]=మొటిఫ్ విండొ అభికర్త -Comment[tg]=Мавзӯъи мудири тиреза -Comment[th]=ระบบจัดการหน้าต่างของโมทิฟ -Comment[tr]=Motif Pencere Yöneticisi -Comment[tt]=Motif Täräzä İdäräçe -Comment[uk]=Менеджер вікон Motif -Comment[uz]=Motif oyna boshqaruvchi -Comment[uz@cyrillic]=Motif ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ Motif -Comment[wa]=Li manaedjeu di purneas di Motif -Comment[zh_CN]=Motif 窗口管理器 -Comment[zh_TW]=Motif 視窗管理程式 diff --git a/kdm/kfrontend/sessions/olvwm.desktop b/kdm/kfrontend/sessions/olvwm.desktop deleted file mode 100644 index 23dee1169..000000000 --- a/kdm/kfrontend/sessions/olvwm.desktop +++ /dev/null @@ -1,71 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=olvwm-x-window-manager -TryExec=olvwm-x-window-manager -Name=OLVWM -Name[br]=OVLWM -Name[eo]=OLVFA -Name[hi]=ओएलवीडबल्यूएम -Name[te]=ఒ ఎల్ వి డబ్యు ఎం -Comment=The OpenLook Virtual Window Manager. OLWM enhanced for handling of virtual desktops -Comment[af]=Die OpenLook virtuele venster bestuurder. OLWM wat uitgebrei is vir virtuele werkskerms -Comment[ar]=مدير النوافذ الوهمي OpenLook، محسّن للتعامل مع أسطح المكتب الوهمية -Comment[be]=The OpenLook Virtual Window Manager. OLWM дапрацаваны для падтрымкі віртуальных працоўных сталоў -Comment[bn]=দি ওপেনলুক ভার্চুয়াল উইণ্ডো ম্যানেজার। OLWM-এর বর্ধিত সংস্করণ যাতে ভার্চুয়াল ডেস্কটপ সমর্থিত -Comment[bs]=OpenLook Virtual Window Manager. OLWM proširen podrškom za virtualne desktope -Comment[ca]=El OpenLook Virtual Window Manager. OLWM millorat per a escriptoris virtuals de ma -Comment[csb]=OpenLook Virtual Window Manager. OLWM zbògacony ò wspiarce wirtualnëch pùltów -Comment[cy]=Y Trefnydd Ffenestri Rhith GolwgAgored (OpenLook). OLWM wedi'i wella i gynnal penbyrddau rhith -Comment[da]=OpenLook Virtual Window Manager. OLWM udvidet med håndtering af virtuelle desktoppe -Comment[de]=OpenLook virtueller Fenstermanager, OLWM mit verbesserter Verwaltung von virtuellen Arbeitsflächen -Comment[el]=Ο OpenLook εικονικός διαχειριστής παραθύρων. Ο OLWM εμπλουτισμένος με διαχείριση εικονικών επιφανειών εργασίας -Comment[eo]=Fenestroadministrilo por virtualaj labortabloj -Comment[es]=El OpenLook Virtual Window Manager, un versión mejorada de OLWM con soporte para escritorios virtuales -Comment[et]=OpenLook virtuaalne aknahaldur on OLWM, mida on täiendatud virtuaalsete töölaudade võimalusega -Comment[eu]=OpenLook leiho kudeatzaile birtuala. mahaigain birtualak kudeatzeko OLWM hobetua -Comment[fa]=مدیر پنجرۀ مجازی OpenLook. OLWM گسترش‌یافته برای گرداندن رومیزیهای مجازی -Comment[fi]=OpenLook virtuaalinen ikkunanhallinta. OLWM:n paranneltu versio,joka käsittelee virtuaalityöpöytiä paremmin -Comment[fr]=The OpenLook Virtual Window Manager. OLWM avec en plus la gestion des bureaux virtuels -Comment[fy]=De OpenLook Virtual Window Manager. OLWM útbreide mei firtuele buroblêden -Comment[gl]=O OpenLook Virtual Window Manager. OLWM mellorado para manexar escritórios virtuais -Comment[he]=The OpenLook Virtual Window Manager. OLWM משופר בשביל טיפול בשולחנות עבודה וירטואליים -Comment[hi]=ओपनलुक आभासी विंडो प्रबंधक. ओएलडबल्यूएम को आभासी डेस्कटॉप हैंडल करने के लिए बेहतर बनाया गया -Comment[hr]=OpenLook virtualni upravitelj prozora - OLWM unaprijeđen mogućnošću rukovanja s virtualnim radnim površinama -Comment[hu]=OpenLook Virtual Window Manager (OLWM), virtuális munkaasztalok kezelésére is képes -Comment[is]=OpenLook sýndargluggastjórinn. Endurbættur með OLWM til að styðja sýndarskjáborð -Comment[it]=L'OpenLook Virtual Window Manager. OLWM migliorato per gestire i desktop virtuali -Comment[ja]=OpenLook 仮想ウィンドウマネージャ, OLWM 強化仮想デスクトップ -Comment[ka]=გაუმჯობესებული ფანჯრის მენეჯერი OpenLook, რამდენიმე სამუშაო დაფის მხარდაჭერით -Comment[kk]=OpenLook Virtual Window Manager - виртуалды үстелдерді қолдайтын терезе менеджері -Comment[km]=OpenLook Virtual Window Manager ។ OLWM ដែល​បាន​ធ្វើ​ឲ្យ​ប្រសើរ សម្រាប់​ការ​ប្រើ​ផ្ទៃតុ​និមិត្ត ។ -Comment[lt]=OpenLook virtuali langų tvarkyklė. OLWM išplėsta su virtualių darbastalių palaikymu -Comment[mk]=OpenLook Virtual Window Manager. OLWM менаџерот со подобрено ракување на виртуелни површини -Comment[ms]=Pengurus Tetingkap Maya OpenLook. OLWM dipertingkat untuk mengendalikan desktop maya -Comment[mt]=OpenLook Virtual Window Manager - OLWM flimkien ma' desktops virtwali. -Comment[nb]=OpenLook Virtual Window Manager. OLWM utvidet med virtuelle skrivebord. -Comment[nds]=De "OpenLook Virtual Window Manager" is OLWM verwiedert üm virtuelle Schriefdischen -Comment[ne]=अवास्तविक डेस्कटपहरूको ह्यान्डलका लागि बृद्धि गरिएको OLWM खुला देखिने अवास्तविक सञ्झ्याल प्रबन्धक । -Comment[nl]=De OpenLook Virtual Window Manager. OLWM uitgebreid met virtuele bureaubladen -Comment[nn]=OpenLook Virtual Window Manager. OLWM utvida med virtuelle skrivebord. -Comment[pa]=OpenLook Virtual Window Manager. OLWM ਫਰਜ਼ੀ ਵੇਹੜਿਆਂ ਲਈ ਖਾਸ ਤੌਰ ਤੇ ਤਿਆਰ -Comment[pl]=OpenLook Virtual Window Manager. OLWM wzbogacony o obsługę wirtualnych pulpitów -Comment[pt]=O OpenLook Virtual Window Manager. Um OLWM melhorado para lidar com ecrãs virtuais -Comment[pt_BR]=Acrônimo para OpenLook Virtual Window Manager, o OLWM melhorado para a manipulação de áreas de trabalho virtuais -Comment[ro]=OpenLook Virtual Window Manager. Un OLWM îmbunătățit cu ecrane virtuale -Comment[ru]=Улучшенный оконный менеджер OpenLook, поддерживающий несколько рабочих столов -Comment[rw]=Mugenga Dirishya Itagaragara GufunguraKureba. OLWM ivuguruwe mu gufasha ibiro bitagaragara -Comment[se]=The OpenLook Virtual Window Manager. OLWM buoriduvvon nu ahte das leat virtuella čállinbeavddit -Comment[sk]=Virtuálny správca okien OpenLook. OLWM rozšírený o podporu virtuálnych plôch -Comment[sl]=Open Look Virtual Window Manager je izboljšan OLWM s podporo navideznim namizjem -Comment[sr]=„OpenLook Virtual Window Manager“. OLWM побољшан за управљање виртуелним радним површинама -Comment[sr@Latn]=„OpenLook Virtual Window Manager“. OLWM poboljšan za upravljanje virtuelnim radnim površinama -Comment[sv]=Open Look virtuell fönsterhanterare. OLWM utökad för att hantera virtuella skrivbord -Comment[ta]=ஓபன்லுக் மெய்நிகர் சாளர மேலாளர். மெய்நிகர் மேல்மேசைகளை கையாளுவதற்கு OLWM மேம்படுத்தப்பட்டது. -Comment[th]=ระบบจัดการหน้าต่างเสมือน OpenLook คือ OLWM ที่ถูกเพิ่มเติมความสามารถในการรับมือกับพื้นที่ทำงานเสมือน -Comment[tr]=OpenLook Sanal Pencere Yöneticisi. -Comment[tt]=OpenLook Virtual Window Manager. Xıyalí öställär öçen yaqşırtılğan OpenLook -Comment[uk]=OpenLook Virtual Window Manager. OLWM з підтримкою віртуальних стільниць -Comment[vi]=Trình Quản lý Cửa sổ Ảo "Cái nhìn Mở". Nó được cải tiến cho việc xử lý màn hình nền ảo -Comment[wa]=Li Manaedjeu di Forveyou Purnea OpenLook (OpenLook Virtual Window Manager). OLWM permete d' apougnî des forveyowès sicribannes -Comment[zh_CN]=OpenLook 虚拟窗口管理器。OLWM 特别增强了虚拟桌面的处理 -Comment[zh_TW]=Openlook 視窗管理程式。基於 OLWM 並強化管理虛擬桌面 diff --git a/kdm/kfrontend/sessions/olwm.desktop b/kdm/kfrontend/sessions/olwm.desktop deleted file mode 100644 index 32612eaa3..000000000 --- a/kdm/kfrontend/sessions/olwm.desktop +++ /dev/null @@ -1,76 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=olwm-x-window-manager -TryExec=olwm-x-window-manager -Name=OLWM -Name[eo]=OLFA -Name[hi]=ओएलडबल्यूएम -Name[te]=ఒ ఎల్ డబ్యు ఎం -Name[th]=ตัวจัดการหน้าต่าง OLWM -Comment=The traditional Open Look Window Manager -Comment[af]=Die tradisionele Open Look venster bestuurder -Comment[ar]=مسيير النوافذ Open Look التقليدي -Comment[be]=Традыцыйны кіраўнік вокнаў Open Look -Comment[bn]=দি ওপেনলুক উইণ্ডো ম্যানেজার -Comment[bs]=Tradicionalni Open Look Window Manager -Comment[ca]=El tradicional gestor de finestres Open Look -Comment[cs]=Tradiční Open Look Window Manager -Comment[csb]=Tradicëjny menedżer òknów Open Look -Comment[cy]=Y Trefnydd Ffenestri GolwgAgored (OpenLook) traddodiadol -Comment[da]=Den traditionelle Open Look vindueshåndtering -Comment[de]=Der traditionelle Open-Look-Fenstermanager -Comment[el]=Ο παραδοσιακός διαχειριστής παραθύρων Open Look -Comment[eo]=La klasika OL-fenestroadministrilo -Comment[es]=El tradicional Open Look Window Manager -Comment[et]=Tavapärane OpenLooki aknahaldur -Comment[eu]=Betiko Open Look leiho kudeatzailea -Comment[fa]=مدیر پنجره Open Look سنتی -Comment[fi]=Perinteinen Open Look -ikkunaohjelma -Comment[fr]=Le gestionnaire de fenêtres traditionnel Open Look -Comment[fy]=De tradisjoneel iepen like finstersManager -Comment[gl]=O tradicional Xestor de Fiestras de Open Look -Comment[he]=Open Look Window Manager המסורתי -Comment[hi]=परम्परागत ओपन लुक विंडो प्रबंधक -Comment[hr]=Tradicionalni 'Open Look' upravitelj prozora -Comment[hu]=A hagyományos Open Look ablakkezelő -Comment[is]=Hinn hefðbundni Open Look gluggastjóri -Comment[it]=L'Open Look Window Manager tradizionale -Comment[ja]=伝統的な OpenLook ウィンドウマネージャ -Comment[ka]=OpenLook სისტემის ტრადიციული ფანჯრის მენეჯერი -Comment[kk]=Дәстүрлі Open Look терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​រូបរាង​បើក​ចំហ​បុរាណ -Comment[lt]=Tradicinė Open Look langų tvarkyklė -Comment[lv]=Tradicionālais Open Look logu menedžeris -Comment[mk]=Традиционален Open Look Window Manager -Comment[mn]=Уламжилалт нээж харагч цонхны удирдагч -Comment[ms]=Pengurus Tetingkap OpenLook tradisional -Comment[mt]=Window manager tradizzjonali ta' OpenLook -Comment[nb]=Den tradisjonelle Open Look-vindusbehandleren -Comment[nds]=De traditschonelle OpenLook-Finsterpleger -Comment[ne]=खुला देखिने परम्परागत सञ्झ्याल प्रबन्धक -Comment[nl]=De traditionele Open Look Window Manager -Comment[nn]=Den tradisjonelle Open Look-vindaugssjefen -Comment[pa]=ਇੱਕ ਮੂਲ ਓਪਨ ਲੁੱਕ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Tradycyjny menedżer okien Open Look -Comment[pt]=O gestor de janelas Open Look tradicional -Comment[pt_BR]=O tradicional Open Look Window Manager -Comment[ro]=Managerul de ferestre tradițional Open Look Window Manager -Comment[ru]=Традиционный оконный менеджер системы OpenLook -Comment[rw]=Mugenga Dirishya Gufungura Kureba karande -Comment[se]=Árbevirolaš Open Look lásegieđahalli -Comment[sk]=Tradičný správca okien Open Look -Comment[sl]=Tradicionalni Open Look Window Manager -Comment[sr]=Традиционални „Open Look“ менаџер прозора -Comment[sr@Latn]=Tradicionalni „Open Look“ menadžer prozora -Comment[sv]=Den traditionella Open Look fönsterhanteraren -Comment[ta]=பழமையான சாளர மேலாளர் -Comment[te]=సాంప్రదాయ ఒపెన్ లుక్ విండొ అభికర్త -Comment[tg]=Расмшудаи Open Look-и мудири тиреза -Comment[th]=ระบบจัดการหน้าต่าง OpenLook แบบดั้งเดิม -Comment[tr]=OpenLook Pencere Yöneticisi -Comment[tt]=Open Look täräzä-idäräçeneñ töp söreme -Comment[uk]=Традиційний менеджер вікон Open Look -Comment[vi]=Trình Quản lý Cửa sổ "Cái nhìn Mở" truyền thống -Comment[wa]=Li mwaisse Manaedjeu di Purnea OpenLook (OpenLook Virtual Window Manager) -Comment[zh_CN]=传统的 OpenLook 窗口管理器 -Comment[zh_TW]=傳統的 Open Look 視窗管理程式 diff --git a/kdm/kfrontend/sessions/openbox.desktop b/kdm/kfrontend/sessions/openbox.desktop deleted file mode 100644 index d0f4a06d7..000000000 --- a/kdm/kfrontend/sessions/openbox.desktop +++ /dev/null @@ -1,84 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=openbox-session -TryExec=openbox -Name=Openbox -Name[bn]=ওপেনবক্স -Name[cy]=Blwchagored (Openbox) -Name[eo]=Malfermujo -Name[hi]=ओपनबाक्स -Name[ne]=खुला बाकस -Name[pa]=ਓਪਨ ਬਕਸਾ -Name[rw]=GufunguraAgasanduku -Name[ta]=திறப்பு பெட்டி -Name[te]=ఒపెన్ బాక్స్ -Name[tg]=Кушодани қуттӣ -Comment=A lightweight window manager based on Blackbox -Comment[af]='n Lig gewig venster bestuurder wat op Blackbox gebaseer is -Comment[ar]=مدير نوافذ خفيف العبء مبني على Blackbox -Comment[be]=Лёгкі кіраўнік вокнаў, заснаваны на Blackbox -Comment[bn]=ব্ল্যাকবক্স ভিত্তিক হাল্কা উইণ্ডো ম্যানেজার -Comment[bs]=Lagani window manager baziran na Blackbox-u -Comment[ca]=Un lleuger gestor de finestres basat en Blackbox -Comment[cs]=Malý správce oken založený na Blackboxu -Comment[csb]=Menedżer òknów o môłëch żądaniach, òpairti na Blackbox -Comment[cy]=Trefnydd ffenestri ysgafn, wedi'i seilio ar Ddu-flwch -Comment[da]=En letvægts vindueshåndtering baseret på Blackbox -Comment[de]=Schlanker Fenstermanager, der auf Blackbox beruht -Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων βασισμένος στον Blackbox -Comment[eo]=Fenestroadministrilo devenigita de Negrujo -Comment[es]=Un gestor de ventanas ligero basado en BlackBox -Comment[et]=Imeväike aknahaldur, mille aluseks on Blackbox -Comment[eu]=Blackboxen oinarritutako leiho kudeatzaile arina -Comment[fa]=یک مدیر پنجرۀ سبک بر اساس Blackbox -Comment[fi]=Kevyt, Blackboxiin pohjautuva ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres léger fondé sur Blackbox -Comment[fy]=In lichtgewicht finstersmanager, basearre op Blackbox -Comment[gl]=Un xestor de fiestras lixeiro baseado en Blackbox -Comment[he]=מנהל חלונות קל מבוסס על Blackbox -Comment[hi]=ब्लेकबाक्स आधारित हल्का विंडो प्रबंधक -Comment[hr]=Lagani upravitelj prozora zasnovan na Blackboxu -Comment[hu]=Egy nagyon egyszerű ablakkezelő a Blackbox alapján -Comment[is]=Léttur gluggastjóri byggður á Blackbox -Comment[it]=Un window manager leggero basato su BlackBox -Comment[ja]=Blackbox ベースの軽量なウィンドウマネージャ -Comment[ka]=Blackbox-ის ბაზაზე ფანჯრიოს მენეჯერი -Comment[kk]=Blackbox-негіздеген жеңіл терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​សមត្ថភាព​ខ្សោយ ដែល​ផ្អែក​លើ Blackbox -Comment[ko]=Blackbox 기반 가벼운 창 관리자 -Comment[lt]=Nedaug resursų reikalaujanti langų tvarkyklė, paremta Blackbox -Comment[lv]=Viegls logu menedžeris, bāzēts uz Blackbox -Comment[mk]=Лесен менаџер на прозорци базиран на Blackbox -Comment[ms]=Pengurus tetingkap ringan berdasarkan Kotak Hitam -Comment[mt]=Window manager ħafif ibbażat fuq BlackBox -Comment[nb]=En lettvekts vindusbehandler basert på Blackbox -Comment[nds]=En ranke Finsterpleger, opbuut op Blackbox -Comment[ne]=कालो बाकसमा आधारित हल्का वजन सञ्झ्याल प्रबन्धक -Comment[nl]=Een lichtgewicht windowmanager, gebaseerd op Blackbox -Comment[nn]=Ein lett vindaugssjef basert på Blackbox -Comment[pa]=ਬਲੈਕਬਕਸੇ ਤੇ ਆਧਾਰਿਤ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien o małych wymaganiach, oparty na Blackbox -Comment[pt]=Um gestor de janelas leve baseado no Blackbox -Comment[pt_BR]=Um gerenciador de janelas leve, baseado no Blackbox -Comment[ro]=Un manager de ferestre minimal bazat pe Blackbox -Comment[ru]=Лёгкий оконный менеджер, основанный на Blackbox -Comment[rw]=Mugenga dirishya yoroshye ishingiye ku Gasandukumukara -Comment[se]=Geahpes lásegieđahalli ráhkaduvvon Blackboxa vuođul -Comment[sk]=Nenáročný správca okien založený na Blackbox -Comment[sl]=Lahek okenski upravitelj na osnovi Blackboxa -Comment[sr]=Лагани менаџер прозора заснован на Blackbox-у -Comment[sr@Latn]=Lagani menadžer prozora zasnovan na Blackbox-u -Comment[sv]=Lättviktig fönsterhanterare baserad på Blackbox -Comment[ta]=கருப்புப் பெட்டியின் அடிப்படையிலான ஒரு குறைந்த எடை சாளர மேலாளர் -Comment[te]=బ్లాక్ బాక్స్ ఆధారిత తెలికైన విండొ అభికర్త -Comment[tg]=Мудири тирезаи сабук ба асоси қуттии сиёҳ -Comment[th]=ระบบจัดการหน้าต่างขนาดเบา สร้างมาจาก Blackbox -Comment[tr]=Blackbox temelli küçük bir pencere yöneticisi -Comment[tt]=Blackbox asılında ciñel täräzä-idäräçe -Comment[uk]=Легкий менеджер вікон, заснований на Blackbox -Comment[uz]=Blackbox asosida yaratilgan oddiy oyna boshqaruvchi -Comment[uz@cyrillic]=Blackbox асосида яратилган оддий ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ nhỏ gọn dựa trên Blackbox -Comment[wa]=On ledjir manaedjeu di purneas båzé so Blackbox -Comment[zh_CN]=基于 BlackBox 的轻量级窗口管理器 -Comment[zh_TW]=一個基於 Blackbox 且輕量化的視窗管理程式 diff --git a/kdm/kfrontend/sessions/oroborus.desktop b/kdm/kfrontend/sessions/oroborus.desktop deleted file mode 100644 index b7ea37c30..000000000 --- a/kdm/kfrontend/sessions/oroborus.desktop +++ /dev/null @@ -1,76 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=oroborus -TryExec=oroborus -Name=Oroborus -Name[eo]=Koloroj -Name[hi]=ऑरोबोरस -Name[pa]=ਓਰੂਬੋਰੁਸ -Name[te]=ఒరొబొరస్ -Comment=A lightweight themeable window manager -Comment[af]='n Lig gewig, tema venster bestuurder -Comment[ar]=مدير نوافذ خفيف العبء قابل لاستخدام السمات -Comment[be]=Лёгкі кіраўнік вокнаў з падтрымкай тэмаў -Comment[bn]=হাল্কা থীমযুক্ত উইণ্ডো ম্যানেজার -Comment[bs]=Lagani window manager sa podrškom za teme -Comment[ca]=Un gestor de finestres lleuger i configurable amb temes -Comment[cs]=Malý správce oken s tématy -Comment[csb]=Menedżer òknów ò môłëch żądanich, z mòżnotą zmianë wëzdrzatkù -Comment[cy]=Trefnydd ffenestri ysgafn sy'n defnyddio themau -Comment[da]=En letvægts vindueshåndtering med temaer -Comment[de]=Schlanker Fenstermanager mit Designs -Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων με υποστήριξη θεμάτων -Comment[eo]=Fenestroadministrilo -Comment[es]=Un gestor de ventanas ligero con temas -Comment[et]=Imeväike teemadega aknahaldur -Comment[eu]=Temak onartzen dituen leiho kudeatzaile arina -Comment[fa]=یک مدیر پنجرۀ قابل چهره‌بندی سبک -Comment[fi]=Kevyt teemoitettava ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres avec gestion des thèmes -Comment[fy]=In lichtgewicht finstersmanager mei temabehear -Comment[gl]=Un xestor de fiestras lixeiro e con capacidade para temas -Comment[he]=מנהל חלונות קל ובר התאמה אישית של ערכות נושא -Comment[hi]=हल्का, प्रसंगयोग्य विंडो प्रबंधक -Comment[hr]=Lagani upravitelj prozora s temama -Comment[hu]=Kis erőforrásigényű ablakkezelő, témázási lehetőséggel -Comment[is]=Léttur þemanlegur gluggastjóri -Comment[it]=Un window manager leggero che supporta i temi -Comment[ja]=テーマ化可能な軽量のウィンドウマネージャ -Comment[ka]=მსუბუქი ფანჯრის მენეჯერი თემების მხარდაჭერით -Comment[kk]=Жеңіл, нақыштары бар терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​អាច​ប្ដូរ​ស្បែក​បាន តែ​មាន​សមត្ថភាព​ខ្សោយ -Comment[ko]=가벼운 테마를 설정할 수 있는 창 관리자 -Comment[lt]=Nedaug resursų reikalaujanti temas palaikanti langų tvarkyklė -Comment[lv]=Viegls logu menedžeris ar tēmu atbalstu -Comment[mk]=Лесен менаџер на прозорци со теми -Comment[ms]=Pengurus tetingkap boleh tema ringan -Comment[mt]=Window manager ħafif u temabbli -Comment[nb]=En lettvekts vindusbehandler med temaer -Comment[nds]=En ranke Finsterpleger, kann Mustern bruken -Comment[ne]=विषयवस्तु योग्य हल्का वजन सञ्झ्याल प्रबन्धक -Comment[nl]=Een lichtgewicht windowmanager met themabeheer -Comment[nn]=Ein lett vindaugssjef med tema -Comment[pa]=ਇੱਕ ਸਰੂਪਾਂ ਨਾਲ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien o małych wymaganiach, z możliwością zmiany wyglądu -Comment[pt]=Um gestor de janelas leve e com suporte para temas -Comment[pt_BR]=Um gerenciador de Janelas leve com vários temas -Comment[ro]=Un manager de ferestre mic și configurabil cu diverse tematici -Comment[ru]=Лёгкий оконный менеджер, поддерживающий темы -Comment[rw]=Mugenga dirishya ngirwa-nsanganyamatsiko yoroshye -Comment[se]=Geahpes lásegieđahalli mas leat fáttát -Comment[sk]=Nenáročný správca okien s podporou tém -Comment[sl]=Lahek okenski upravitelj s temami -Comment[sr]=Лагани менаџер прозора са темама -Comment[sr@Latn]=Lagani menadžer prozora sa temama -Comment[sv]=Lättviktig fönsterhanterare med teman -Comment[ta]=குறைந்தஎடை தலைப்புடைய சாளர மேலாளர் -Comment[th]=ระบบจัดการหน้าต่างขนาดเบาที่ใช้ชุดตกแต่งได้ -Comment[tr]=Küçük, hafif, temalı bir pencere yöneticisi -Comment[tt]=Tışlana torğan ciñel täräzä-idäräçe -Comment[uk]=Легкий менеджер вікон з підтримкою тем -Comment[vi]=Trình quản lý cửa sổ thay đổi được sắc thái -Comment[wa]=On ledjir manaedjeu di purneas avou des tinmes -Comment[zh_CN]=轻量级窗口管理器,可定义主题 -Comment[zh_TW]=一個輕量化且有佈景功能的視窗管理程式 -# not usable as a session -Hidden=true diff --git a/kdm/kfrontend/sessions/phluid.desktop b/kdm/kfrontend/sessions/phluid.desktop deleted file mode 100644 index f1cca1d66..000000000 --- a/kdm/kfrontend/sessions/phluid.desktop +++ /dev/null @@ -1,80 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=phluid -TryExec=phluid -Name=Phluid -Name[eo]=Plena -Name[hi]=फ्लुइड -Name[pa]=ਫਲੁਇਡ -Name[te]=ఫ్లూయిడ్ -Comment=An Imlib2 based window manager -Comment[af]='n Imlib2 gebaseerde venster bestuurder -Comment[ar]=مدير نوافذ مبني على Imlib2 -Comment[be]=Кіраўнік вокнаў, заснаваны на Imlib2 -Comment[bn]=Imlib2 ভিত্তিক উইণ্ডো ম্যানেজার -Comment[bs]=Window manager baziran na Imlib2 -Comment[ca]=Un gestor de finestres basta en Imlib2 -Comment[cs]=Správce oken založený na Imlib2 -Comment[csb]=Menedżer òknów òpiarti na Imlib2 -Comment[cy]=Trefnydd ffenestri wedi'i seilio ar lmlib2 -Comment[da]=En Imlib2 baseret vindueshåndtering -Comment[de]=Imlib2-basierter Fenstermanager -Comment[el]=Ένας διαχειριστής παραθύρων βασισμένος στην imlib2 -Comment[eo]=Fenestroadministrilo -Comment[es]=Un gestor de ventanas basado en Imlib2 -Comment[et]=Aknahaldur, mille aluseks on Imlib2 -Comment[eu]=Imlib2-n oinarritutako leiho kudeatzailea -Comment[fa]=یک Imlib2 بر اساس مدیر پنجره -Comment[fi]=Imlib2-pohjainen ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres fondé sur Imlib2 -Comment[fy]=In op imlib2 basearre finstersmanager -Comment[ga]=Bainisteoir fuinneoga bunaithe ar Imlib2 -Comment[gl]=Un xestor de fiestras baseado en Imlib2 -Comment[he]=מנהל חלונות מבוסס Imlib2 -Comment[hi]=आईएमलिब2 आधारित विंडो प्रबंधक -Comment[hr]=Upravitelj prozora zasnovan na Imlib2 -Comment[hu]=Egy Imlib2-alapú ablakkezelő -Comment[is]=Gluggastjóri sem notar Imlib2 -Comment[it]=Un window manager basato su Imlib2 -Comment[ja]=Imlib2ベースのウィンドウマネージャ -Comment[ka]=ფანჯრის მენეჯერი imlib2 ის ბაზაზე -Comment[kk]=Imlib2-негіздеген терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ផ្អែក​លើ Imlib2 -Comment[ko]=Imlib2 기반 창 관리자 -Comment[lt]=Langų tvarkyklė, paremta Imlib2 -Comment[lv]=Imlib 2 bāzēts logu menedžeris -Comment[mk]=Менаџер на прозорци базиран на Imlib2 -Comment[mn]=Imlib2 дээр суурилсан цонхны удирдагч -Comment[ms]=Pengurus tetingkap berasaskan lmlib2 -Comment[mt]=Window manager ibbażat fuq Imlib2 -Comment[nb]=En vindusbehandler basert på Imlib2 -Comment[nds]=En Finsterpleger opbuut op Imlib2 -Comment[ne]=Imlib2 मा आधारित सञ्झ्याल प्रबन्धक -Comment[nl]=Een op imlib2 gebaseerde windowmanager -Comment[nn]=Ein vindaugssjef basert på Imlib2 -Comment[pa]=ਇੱਕ Imlib2 ਆਧਾਰਿਤ ਫਾਇਲ਼ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien oparty na Imlib2 -Comment[pt]=Um gestor de janelas baseado na Imlib2 -Comment[pt_BR]=Um gerenciador de janelas baseado na lmlib2 -Comment[ro]=Un manager de ferestre bazat pe Imlib2 -Comment[ru]=Оконный менеджер на основе imlib2 -Comment[rw]=Mugenga dirishya ishingiye kuri Imlib2 -Comment[se]=Imlib2-vuođđoduvvon lásegieđahalli -Comment[sk]=Správca okien založený na imlib2 -Comment[sl]=Okenski upravitelj na osnovi lmlib2 -Comment[sr]=Менаџер прозора заснован на Imlib2 -Comment[sr@Latn]=Menadžer prozora zasnovan na Imlib2 -Comment[sv]=Imlib2-baserad fönsterhanterare -Comment[ta]=சாளர மேலாளர் அடிப்படையிலான ஒரு Imlib2 -Comment[te]=ఐఎంలిబ్2 ఆధారిత విండొ అభికర్త -Comment[tg]=Imlib2 ба асосимудири тиреза -Comment[th]=ระบบจัดการหน้าต่างที่สร้างบน Imlib2 -Comment[tr]=Imlib2 tabanlı bir pencere yöneticisi -Comment[tt]=Imlib2 asılında täräzä-idäräçe -Comment[uk]=Менеджер вікон, заснований на Imlib2 -Comment[uz]=Imlib2 asosida yaratilgan oyna boshqaruvchi -Comment[uz@cyrillic]=Imlib2 асосида яратилган ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ dựa trên lmlib2 -Comment[wa]=On manaedjeu di purneas båzé so lmlib2 -Comment[zh_CN]=基于 Imlib2 的窗口管理器 -Comment[zh_TW]=一個基於 Imlib2 的視窗管理程式 diff --git a/kdm/kfrontend/sessions/pwm.desktop b/kdm/kfrontend/sessions/pwm.desktop deleted file mode 100644 index 5d967c0c0..000000000 --- a/kdm/kfrontend/sessions/pwm.desktop +++ /dev/null @@ -1,72 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=pwm1 -TryExec=pwm1 -Name=PWM -Name[eo]=UnuFA -Name[hi]=पीडबल्यूएम -Name[te]=పి డబ్ల్యు ఎం -Name[th]=ตัวจัดการหน้าต่าง PWM -Comment=A lightweight window manager able to attach multiple windows to one frame -Comment[af]='n Lig gewig venster bestuurder wat veelvuldige vensters aan een raam kan koppel -Comment[ar]=مدير نوافذ خفيف العبء قابل لربط عدة نوافذ إلى إطار واحد -Comment[be]=Лёгкі кіраўнік вокнаў, які можа далучаць некалькі вокнаў да аднаго фрэйма -Comment[bn]=একটি হাল্কা উইণ্ডো ম্যানেজার, যাতে একটি ফ্রেমে একাধিক উইণ্ডো সংযুক্ত করা সম্ভব -Comment[bs]=Lagani window manager koji može prikačiti više prozora na jedan okvir -Comment[ca]=Un lleuger gestor de finestres capaç d'aplegar múltiples finestres en un marc -Comment[csb]=Menedżer òknów ò môłëch żądaniach, rozmiejący doczepic wiele òknów do jedny ramë -Comment[cy]=Trefnydd ffenestri ysgafn sy'n gallu atodi mwy nag un ffenestr at un ffrâm -Comment[da]=En letvægts vindueshåndtering der kan knytte flere vinduer til én ramme -Comment[de]=Schlanker Fenstermanager, der mehrere Fenster an einen Rahmen andocken kann -Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων με δυνατότητα να προσαρτά πολλαπλά παράθυρα σε ένα πλαίσιο -Comment[eo]=Fenestroadministrilo, kiu faras unun fenestron el kelkaj -Comment[es]=Un gestor de ventanas ligero capaz de conectar varias ventanas a un mismo marco -Comment[et]=Imeväike aknahaldur, mis suudab mitu akent ühe raami külge haakida -Comment[eu]=Hainbat leiho marko bakarrean uztar ditzakeen leiho kudeatzaile arina -Comment[fa]=مدیر پنجرۀ سبک قادر به پیوست پنجره‌های چندگانه در یک قابک -Comment[fi]=Kevyt ikkunaohjelma, joka osaa liittää useita ikkunoita yhteen kehykseen -Comment[fr]=Un gestionnaire de fenêtres léger capable d'attacher plusieurs fenêtres à un même cadre -Comment[fy]=In lichtgewicht finstersmanager, hokker meardere finsters kin ferbine mei in kader -Comment[gl]=Un xestor de fiestras lixeiro capaz de adxuntar varias fiestras nun marco -Comment[he]=מנהל חלונות קל המסוגל לחבר חלונות רבים למסגרת אחת -Comment[hi]=एक हल्का विंडो प्रबंधक जिसके एक फ़रमा में अनेक विंडो जोड़े जा सकते हैं -Comment[hr]=Lagani upravitelj prozora koji jednom okviru može pridodati više prozora -Comment[hu]=Alacsony erőforrásigényű ablakkezelő, több ablakot képes egy kerethez rendelni -Comment[is]=Léttur gluggastjóri sem getur tengt marga glugga við einn ramma -Comment[it]=Un window manager leggero in grado di attaccare più finestre ad una cornice -Comment[ja]=複数のウィンドウ枠を設定可能な軽量なウィンドウマネージャ -Comment[ka]=მსუბუქი ფანჯრის მენეჯერი, რომელსაც შეუძლია ბევრი ფანჯრის ერთ ჩარჩოში ჩასმა -Comment[kk]=Жеңіл, бір коршауда бірнеше терезелерді біріктірелетін, терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​សមត្ថភាព​ខ្សោយ អាច​ភ្ជាប់​បង្អួច​ច្រើន​ទៅ​ស៊ុម​មួយ -Comment[lt]=Nedaug resursų reikalaujanti langų tvarkyklė, galinti prijungti daug langų prie vieno rėmo -Comment[lv]=Viegls logu menedžeris ar iespēju pievienot vairākus logus vienam kadram -Comment[mk]=Лесен менаџер на прозорци кој може да прикачи повеќе прозорци на една рамка -Comment[ms]=Pengurus tetingkap ringan yang boleh melekapkan berbilang tetingkap pada satu bingkai -Comment[mt]=Window manager ħafif li jista' jgħaqqad iżjed minn window waħda fl-istess gwarniċ -Comment[nb]=En lettvekts vindusbehandler som kan koble flere vinduer til én ramme -Comment[nds]=En ranke Finsterpleger, de mennige Finstern an een Rahmen andocken kann -Comment[ne]=एक हल्का वजन सञ्झ्याल प्रबन्धकले बहुभागिय सञ्झ्यालहरूलाई एक फ्रेममा सङ्लग्न गर्न सक्छ -Comment[nl]=Een lichtgewicht windowmanager, welke meerdere vensters kan verbinden met een frame -Comment[nn]=Ein lett vindaugssjef som kan kopla fleire vindauge til den same ramma -Comment[pa]=ਇੱਕ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਜੋ ਕਿ ਕਈ ਝਰੋਖਿਆਂ ਨੂੰ ਇੱਕ ਫਰੇਮ ਵਿੱਚ ਰੱਖ ਸਕਦਾ ਹੈ -Comment[pl]=Menedżer okien o małych wymaganiach, potrafiący doczepić wiele okien do jednego obramowania -Comment[pt]=Um gestor de janelas leve, com a possibilidade de anexar várias janelas a uma área -Comment[pt_BR]=Um gerenciador de janelas leve, capaz de anexar múltiplas janelas em um quadro -Comment[ro]=Un manager de ferestre minimal capabil să atașeze multe ferestre la un singur cadru -Comment[ru]=Лёгкий оконный менеджер, способный объединить несколько окон в одной рамке -Comment[rw]=Mugenga dirishya yoroshye ishobora gufatishya amadirishya menshi ku ikadiri imwe. -Comment[se]=Geahpes lásegieđahalli mii sáhttá ovttastahttit máŋga láse seamma rámmii. -Comment[sk]=Nenáročný správca okien schopný spojiť viac okien do jednoho rámca -Comment[sl]=Lahek okenski upravitelj, ki lahko pripne več oken na en okvir -Comment[sr]=Лагани менаџер прозора способан да прикачи више прозора за један оквир -Comment[sr@Latn]=Lagani menadžer prozora sposoban da prikači više prozora za jedan okvir -Comment[sv]=Lättviktig fönsterhanterare som kan ansluta flera fönster till en ram -Comment[ta]=குறைந்த கனமுள்ள பல சாளரங்களை இணைக்க முடிந்த ஒற்றை சாளர மேலாளர் -Comment[th]=ระบบจัดการหน้าต่างขนาดเบา มีความสามารถในการปะติดหลายๆหน้าต่างลงใน 1 กรอบ -Comment[tr]=Düşük ağırlıklı bir çok pencereyi bir çerçeveye toplayabilen bir pencere yöneticisi -Comment[tt]=Ber qısa eçendä berniçä täräzä totaştırala torğan täräzä-idäräçe -Comment[uk]=Простий менеджер вікон, що дозволяє долучати декілька вікон до однієї рамки -Comment[vi]=Trình quản lý cửa sổ nhỏ gọn, có thể gắn nhiều cửa sổ vào một khung -Comment[wa]=On ledjir manaedjeu di purneas ki pout ataetchî sacwants purneas so-z on cåde -Comment[zh_CN]=轻量级窗口管理器,可将多个窗口附加到一个框架中 -Comment[zh_TW]=一個輕量化且可以將多個視窗結合在一起的視窗管理程式 diff --git a/kdm/kfrontend/sessions/qvwm.desktop b/kdm/kfrontend/sessions/qvwm.desktop deleted file mode 100644 index 922e3e0bd..000000000 --- a/kdm/kfrontend/sessions/qvwm.desktop +++ /dev/null @@ -1,80 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=qvwm -TryExec=qvwm -Name=QVWM -Name[eo]=QVFA -Name[hi]=क्यूवीडबल्यूएम -Name[te]=క్యు వి డబ్ల్యు ఎం -Name[th]=ตัวจัดการหน้าต่าง QVWM -Comment=A Windows 95 like window manager -Comment[af]='n Venster bestuurder wat soos Windows 95 lyk -Comment[ar]=مدير نوافذ شبيه بويندوز 95 -Comment[be]=Кіраўнік вокнаў, падобны на Windows 95 -Comment[bn]=Windows 95-এর অনুরূপ একটি উইণ্ডো ম্যানেজার -Comment[bs]=Window manager nalik na Windows 95 -Comment[ca]=Un gestor de finestres com el Windows 95 -Comment[cs]=Správce oken se vzhledem Windows 95 -Comment[csb]=Menedżer òknów o wëzdrzatkù szlachùjącym za Windows 95 -Comment[cy]=Trefnydd Ffenestri sy'n debyg i Windows95 -Comment[da]=En Windows 95-lignende vindueshåndtering -Comment[de]=Fenstermanager im Stil von Windows 95 -Comment[el]=Ένας διαχειριστής παραθύρων παρόμοιος με τα Windows 95 -Comment[eo]=Fenestroadministrilo kiel Vindozo 95 -Comment[es]=Un gestor de ventanas similar a Windows 95 -Comment[et]=Aknahaldur, mis näeb välja nagu Windows 95 -Comment[eu]=Windows 95en itxura duen leiho kudeatzailea -Comment[fa]=یک مدیر پنجره شبیه ویندوز ۹۵ -Comment[fi]=Windows 95:n tyylinen ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres semblable à Windows 95 -Comment[fy]=In Win95-likens finstersmanager -Comment[ga]=Bainisteoir fuinneoga cosúil le Windows 95 -Comment[gl]=Un xestor de fiestras como o de Windows 95 -Comment[he]=מנהל חלונות הדומה לחלונות 95 -Comment[hi]=विंडोज़ 95 जैसा विंडो प्रबंधक -Comment[hr]=Upravitelj prozora nalik na Windows 95 -Comment[hu]=Egy Windows 95-szerű ablakkezelő -Comment[is]=Gluggastjóri sem líkist Windows 95 -Comment[it]=Un window manager in stile Windows 95 -Comment[ja]=Windows95 風のウィンドウマネージャ -Comment[ka]=ფანჯრის მენეჯერი Windows 95-ს სტილში -Comment[kk]=Windows 95 секілді терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ស្រដៀង Windows 95 -Comment[ko]=윈도 95를 닮은 창 관리자 -Comment[lt]=Langų tvarkyklė, primenanti Windows 95 -Comment[lv]=Windows 95 līdzīgs logu menedžeris -Comment[mk]=Менаџер на прозорци со изглед на Windows 95 -Comment[mn]=Виндовс 95 шиг цонхны удирдагч -Comment[ms]=Pengurus tetingkap seperti Windows 95 -Comment[mt]=Window manager jixbaħ lil Windows95 -Comment[nb]=En vindusbehandler som likner Windows 95 -Comment[nds]=En Finsterpleger liek to Windows 95 -Comment[ne]=विण्डोज ९५ जस्तो सञ्झ्याल प्रबन्धक -Comment[nl]=Een Win95-achtige windowmanager -Comment[nn]=Ein vindaugssjef som liknar Windows 95 -Comment[pa]=ਇੱਕ ਵਿੰਡੋ 95 ਵਰਗਾ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien o wyglądzie podobnym do Windows 95 -Comment[pt]=Um gestor de janelas com o visual do Windows 95 -Comment[pt_BR]=Um gerenciador de janelas parecido com o Windows 95 -Comment[ro]=Un manager de ferestre cu aspect de Windows 95 -Comment[ru]=Оконный менеджер в стиле Windows 95 -Comment[rw]=Windows 95 nka mugenga dirishya -Comment[se]=Windows95-lágan lásegieđahalli -Comment[sk]=Správca okien podobný Windows 95 -Comment[sl]=Okenski upravitelj, podoben Windows 95 -Comment[sr]=Менаџер прозора налик на Windows 95 -Comment[sr@Latn]=Menadžer prozora nalik na Windows 95 -Comment[sv]=Fönsterhanterare som liknar Windows 95 -Comment[ta]=சாளர மேலாளர் போன்ற விண்டோஸ் 95 -Comment[te]=విండొస్ 95 లాంటి విండొ అభికర్త -Comment[tg]=Windows 95 монанди мудири тиреза -Comment[th]=ระบบจัดการหน้าต่างที่ดูคล้ายวินโดวส์ 95 -Comment[tr]=Windows 95 benzeri bir pencere yöneticisi -Comment[tt]=Windows 95 kebek täräzä-idäräçe -Comment[uk]=Менеджер вікон на кшталт Windows95 -Comment[uz]=Win95'ga oʻxshagan oyna boshqaruvchi -Comment[uz@cyrillic]=Win95'га ўхшаган ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ giống Windows 95 -Comment[wa]=On manaedjeu di purneas rishonnant a Windows 95 -Comment[zh_CN]=类似 Windows 95 的窗口管理器 -Comment[zh_TW]=一個像 Win95 的視窗管理程式 diff --git a/kdm/kfrontend/sessions/ratpoison.desktop b/kdm/kfrontend/sessions/ratpoison.desktop deleted file mode 100644 index 1127db151..000000000 --- a/kdm/kfrontend/sessions/ratpoison.desktop +++ /dev/null @@ -1,82 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=ratpoison -TryExec=ratpoison -Name=Ratpoison -Name[bn]=র‌্যাট-পয়সন -Name[cy]=Gwenwynllygodmawr (Ratpoison) -Name[eo]=Raticido -Name[fa]=مرگ موش -Name[hi]=रैट-पॉइज़न -Name[ne]=र्याटपोइजन -Name[pa]=ਰਾਟਪੋਈਸਾਨ -Name[rw]=UburoziImbeba -Name[sv]=Råttgift -Name[ta]=ராட் பாய்சன் -Name[te]=ఎలుకలమందు -Name[vi]=Bả chuột -Name[wa]=Pwezon po les rats (Ratpoison) -Comment=A simple keyboard-only window manager modeled after Screen -Comment[af]='n Eenvoudige venster bestuurder wat net met die sleutel bord werk en op Screen gemoduleer is. -Comment[ar]=مدير نوافذ بسيط يستخدم لوحة المفاتيح فقط صنع مشابهاً لـScreen -Comment[be]=Просты кіраўнік вокнаў, працуе толькі з клавіятурай -Comment[bn]=একটি সরল কীবোর্ড-ভিত্তিক উইণ্ডো ম্যানেজার, Screen-এর আদর্শে তৈরি -Comment[bs]=Jednostavan windows manager samo za tastaturu, modeliran po uzoru na Screen -Comment[ca]=Un gestor de finestres simple de sols teclat modelat després de Screen -Comment[csb]=Prosti menedżer òknów òbsłùgiwôny blós z klawiaturë, szlachùje za programą screen -Comment[cy]=Trefnydd ffenestri syml sy'n defnyddio'r allweddell yn unig, wedi'i arddullio ar Sgrîn (Screen) -Comment[da]=En simpel kun-tastatur vindueshåndtering modeleret efter Screen -Comment[de]=Einfacher Fenstermanager, der nur über die Tastatur bedient wird und Screen nachgebildet ist -Comment[el]=Ένας απλός, μονό για πληκτρολόγιο, διαχειριστής παραθύρων σχεδιασμένος με βάση το Screen -Comment[en_GB]=A simple keyboard-only window manager modelled after Screen -Comment[eo]=Fenestroadministrilo por klaviaro -Comment[es]=Un gestor de ventanas sólo para teclado realizado a partir de Screen -Comment[et]=Lihtne ainult klaviatuuri abil kasutatav aknahaldur, mille eeskujuks on Screen -Comment[eu]=Screen-en oinarriturik egindako leiho kudeatzailea, teklatu hutsez erabiltzekoa -Comment[fa]=یک مدیر پنجره فقط صفحه کلید سادۀ مدل‌یافته پس از پرده -Comment[fi]=Yksinkertainen, vain näppäimistöltä käytettävä ikkunamanageri, screen-ohjelman tyyliin -Comment[fr]=Un gestionnaire de fenêtres simple uniquement dirigeable au clavier et fondé sur Screen -Comment[fy]=In ienfâldige finstersmanager dy allinnich mei it toetseboerd te betsjinnen is, ynspiraasje troch Screen -Comment[gl]=Un xestor de fiestras de manexo co teclado modelado despois de Screen -Comment[he]=מנהל חלונות פשוט למקלדת בלבד המעוצב בסגנון Screen -Comment[hi]=आफ्टर स्क्रीन आधारित साधारण विंडो प्रबंधक जो सिर्फ कुंजीपट के लिए है -Comment[hr]=Jednostavan, samo za tipkovnicu, upravitelj prozora napravljen prema Screenu -Comment[hu]=Egyszerű, csak billentyűzetről vezérelhető ablakkezelő (a Screen alapján) -Comment[is]=Einfaldur gluggastjóri sem notar eingöngu lyklaborðið hannaður eftir Screen forritinu -Comment[it]=Un window manager semplice solo-tastiera pensato come Screen -Comment[ja]=Screen をもとに作られた、キーボードインターフェースのみのウィンドウマネージャ -Comment[ka]=მარტივი კლაიატურით მართვადი ფანჯრის მმართველი -Comment[kk]=Screen үлгідегі, тек перенетақтадан басқарылатын, қарапайым терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​សាមញ្ញ​ប្រើ​តែ​ក្ដារចុច ដែល​យក​គំរូ​តាម​អេក្រង់ -Comment[lt]=Paprasta, tik klaviatūra valdoma langų tvarkyklė, panaši į Screen -Comment[lv]=Vienkāršs tikai tastatūras logu menedžeris, līdzīgs Screen -Comment[mk]=Едноставен менаџер на прозорци кој работи само со тастатура, моделиран според Screen -Comment[ms]=Pengurus tetingkap hanya papan kekunci ringkas dimodelkan seperti Skrin -Comment[mt]=Window manager għal tastieri biss immudellat fuq Screen -Comment[nb]=En enkel tastaturbasert vindusbehandler, etter forbilde av Screen -Comment[nds]=En eenfache Finsterpleger, de bloots mit de Tastatuur bruukt warrt. Screen weer dat Modell dorför -Comment[ne]=पर्दा पछाडि सञ्झ्याल प्रबन्धक मात्र नमूना बनाउने साधारण कुञ्जीपाटी -Comment[nl]=Een eenvoudige windowmanager die alleen met het toetsenbord te bedienen is, geïnspireerd door Screen -Comment[nn]=Ein enkel tastaturbasert vindaugssjef, med Screen som førebilete -Comment[pa]=ਪਰਦੇ ਮੈਡੀਊਲ ਬਾਅਦ ਸਿਰਫ ਕੀ-ਬੋਰਡ ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Prosty menedżer okien obsługiwany wyłącznie za pomocą klawiatury, stworzony na podobieństwo programu screen -Comment[pt]=Um gestor de janelas simples, só para o teclado e modelado sobre o Screen -Comment[pt_BR]=Um simples gerenciador de janelas baseado somente em teclado, modelado após a tela -Comment[ro]=Un manager de ferestre manipulat din tastatură, modelat după Screen -Comment[ru]=Простой клавиатурный оконный менеджер, моделирующий Screen -Comment[rw]=Mugenga dirishya ya mwandikisho-gusa yoroheje itunganyijwe nyuma ya Mugaragaza -Comment[se]=Oktageardánis, boallobeavdestivrejuvvon lásegieđahalli, mas lea Screen ovdagovvan -Comment[sk]=Jednoduchý správca okien ovládaný iba klávesami podľa programu Screen -Comment[sl]=Preprost okenski uporavljalnik na osnovi Screen, upravlja se samo s tipkovnico -Comment[sr]=Једноставан, само за тастатуру менаџер прозора, направљен према Screen-у -Comment[sr@Latn]=Jednostavan, samo za tastaturu menadžer prozora, napravljen prema Screen-u -Comment[sv]=Enkel fönsterhanterare bara för tangentbord modellerad efter Screen -Comment[ta]=சாளரமொன்றில் நிழல் ஏறுகிறது -Comment[th]=ตัวจัดการหน้าต่างแบบเรียบง่าย ใช้แป้นพิมพ์ควบคุมได้อย่างเดียว ถูกสร้างขึ้นมาตามหลัง Screen -Comment[tr]=Screen'den sonra modellenmiş salt klavye basit pencere yöneticisi -Comment[tt]=Töylekle genä ciñel täräzä-idäräçe -Comment[uk]=Простий менеджер вікон, розроблений на базі Screen, з підтримкою тільки клавіатури -Comment[vi]=Trình quản lý cửa sổ chỉ dùng bàn phím, dựa theo Screen -Comment[wa]=On simpe manaedjeu di purneas eployant fok li taprece, båzé so ls idêyes da «Screen» -Comment[zh_CN]=Screen 后又一只支持键盘的窗口管理器 -Comment[zh_TW]=一個簡易、只支援鍵盤的視窗管理程式 diff --git a/kdm/kfrontend/sessions/sapphire.desktop b/kdm/kfrontend/sessions/sapphire.desktop deleted file mode 100644 index 5cdd998d7..000000000 --- a/kdm/kfrontend/sessions/sapphire.desktop +++ /dev/null @@ -1,84 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=sapphire -TryExec=sapphire -Name=Sapphire -Name[bn]=স্যাফায়ার -Name[eo]=Safiro -Name[fa]=ياقوت كبود -Name[hi]=सेफायर -Name[ka]=საფირონი -Name[ne]=नीलमणि -Name[pa]=ਸਾਪਰਫੀਰੀ -Name[ru]=Сапфир -Name[ta]=சபையர் -Name[te]=ఇంద్రనీలం -Name[tg]=Ёқути кабуд -Comment=A minimal but configurable window manager -Comment[af]='n Minimalistiese venster bestuurder, wat nogsteeds opstel funksionaliteit bevat. -Comment[ar]=مدير نوافذ مصغّر ولكن قابل للإعداد -Comment[be]=Мінімалістычны кіраўнік вокнаў з магчымасцю настаўлення -Comment[bn]=পরিমিত কিন্তু থীমযুক্ত উইণ্ডো ম্যানেজার -Comment[bs]=Minimalan ali podesiv window manager -Comment[ca]=Un minimalista però configurable gestor de finestres -Comment[cs]=Minimalistický, ale přizpůsobitelný správce oken -Comment[csb]=Prosti menedżer òknów, równak z mòżnotą kònfigùracëji -Comment[cy]=Trefnydd ffenestri lleiafol a ffurfweddir -Comment[da]=En minimal men indstillelig vindueshåndtering -Comment[de]=Minimalistischer, aber anpassbarer Fenstermanager -Comment[el]=Ένας μικρός αλλά παραμετροποιήσιμος διαχειριστής παραθύρων -Comment[eo]=Fenestroadministrilo -Comment[es]=Un gestor de ventanas minimalista pero configurable -Comment[et]=Väga väike, kuid seadistatav aknahaldur -Comment[eu]=Leiho kudeatzaile minimal baina konfiguragarria -Comment[fa]=یک مدیر پنجرۀ کمینه، اما قابل پیکربندی -Comment[fi]=Minimaalinen, mutta muokattavissa oleva ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres minimaliste mais configurable -Comment[fy]=In minimale mar ynstelbere finstersmanager -Comment[gl]=Un xestor de fiestras mínimo pero configurábel -Comment[he]=מנהל חלונות מינימלי אך ניתן להגדרה -Comment[hi]=एक अल्पतम परंतु कॉन्फ़िगर योग्य विंडो प्रबंधक -Comment[hr]=Minimalan, ali podesiv upravitelj prozora -Comment[hu]=Egyszerű, de jól konfigurálható ablakkezelő -Comment[is]=Einfaldur en stillanlegur gluggastjóri -Comment[it]=Un window manager minimale ma configurabile -Comment[ja]=各種設定が可能な小さなウィンドウマネージャ -Comment[ka]=მინიმალური მაგრამ კონფიგურირებადი ფანჯრის მენეჯერი -Comment[kk]=Шағын, баптауы бар, терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​តូច តែ​អាច​កំណត់​រចនាសម្ព័ន្ធ​បាន -Comment[ko]=설정 가능한 최소한의 창 관리자 -Comment[lt]=Minimalistinė tačiau konfigūruojama langų tvarkyklė -Comment[lv]=Minimālistisks, bet konfigurējams logu menedžeris -Comment[mk]=Минимален но конфигурабилен менаџер на прозорци -Comment[mn]=Маш жижиг тохируулах боломжгүй цонх удирдагч -Comment[ms]=Pengurus tetingkap minimum tetapi boleh konfigur -Comment[mt]=Window manager minimu imma konfigurabbli -Comment[nb]=En minimal vindusbehandler, men med innstillinger -Comment[nds]=En minimaal, man instellbor Finsterpleger -Comment[ne]=सानो तर कन्फिगर गर्न सकिने सञ्झ्याल प्रबन्धक -Comment[nl]=Een minimale maar instelbare windowmanager -Comment[nn]=Ein minimal vindaugssjef, men med innstillingar -Comment[pa]=ਇੱਕ ਨਿਊਨਤਮ, ਪਰ ਸੋਧਯੋਗ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Prosty menedżer okien, ale z możliwością konfiguracji -Comment[pt]=Um gestor de janelas configurável mas mínimo -Comment[pt_BR]=Um gerenciador de janelas mínimo, mas configurável -Comment[ro]=Un manager de ferestre minimal, dar configurabil -Comment[ru]=Минимальный, но настраиваемый оконный менеджер -Comment[rw]=Ntoya ariko mugenga dirishya ibonezwa -Comment[se]=Unna, muhto heivehahtti lásegieđahalli -Comment[sk]=Minimálny, ale nastaviteľný správca okien -Comment[sl]=Skromen, a nastavljiv okenski upravitelj -Comment[sr]=Минимални, али подесиви менаџер прозора -Comment[sr@Latn]=Minimalni, ali podesivi menadžer prozora -Comment[sv]=Minimal men anpassningsbar fönsterhanterare -Comment[ta]=சாளர மேலாளரின் மேம்பட்ட திறன்களை வடிவமைக்கலாம் -Comment[th]=ระบบจัดการหน้าต่างขนาดเล็ก แต่สามารถปรับแต่งได้ -Comment[tr]=Küçük, ancak kolayca özelleştirilebilir bir pencere yöneticisi -Comment[tt]=Ciñel bulsa da, köylänä torğan täräzä-idäräçe -Comment[uk]=Мінімальний менеджер вікон з можливістю налаштування -Comment[uz]=Oddiy, ammo moslab boʻladigan oyna boshqaruvchi -Comment[uz@cyrillic]=Оддий, аммо мослаб бўладиган ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ tối thiểu, nhưng có thể cấu hình được -Comment[wa]=On ptit, nén apontiåve, manaedjeu di purnea -Comment[zh_CN]=很小却可配置的窗口管理器 -Comment[zh_TW]=一個小但可組態的視窗管理程式 diff --git a/kdm/kfrontend/sessions/sawfish.desktop b/kdm/kfrontend/sessions/sawfish.desktop deleted file mode 100644 index 668620fff..000000000 --- a/kdm/kfrontend/sessions/sawfish.desktop +++ /dev/null @@ -1,74 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=sawfish -TryExec=sawfish -Name=Sawfish -Name[bn]=স-ফিশ -Name[eo]=Segfiŝo -Name[fa]=اره‌ماهی -Name[hi]=सा-फिश -Name[ne]=सफीस -Name[pa]=ਸ਼ਾਅਫਿਸ਼ -Name[te]=సాఫిష్ -Comment=An extensible window manager scriptable with an Emacs Lisp-like language -Comment[af]='n Uitbreibare venster bestuurder met 'n ingeboude skrip taal wat soos Emacs List lyk. -Comment[ar]=مدير نوافذ قابل للتوسعة يمكن بشفيره بلغة إيماكس ليسب -Comment[be]=Кіраўнік вокнаў з магчымасцю пашырэння сцэнарамі на мове, падобнай на Emacs Lisp -Comment[bs]=Proširiv window manager sa podškom za skriptiranje u jeziku sličnom Emacs Lisp-u -Comment[ca]=Un extensible gestor de finestres mitjançant scripts amb una aparença com el Lisp de Emacs -Comment[cs]=Rožšiřitelný správce oken skriptovatelný jazykem podobným jazyku Emacs Lisp -Comment[csb]=Menedżer òknów, jaczi je mòżno rozbùdowac dzãka skriptom w jãzëkù szlachùjącym za Emacs Lisp -Comment[cy]=Trefnydd ffenestri estynadwy a all ei sgriptio efo iaith sy'n debyg i Emacs Lisp -Comment[da]=En udvidelig vindueshåndtering der kan scriptes med et Emacs Lisp-lignende sprog -Comment[de]=Erweiterbarer Fenstermanager, der über Skripts ähnlich Emacs-Lisp gesteuert werden kann -Comment[el]=Ένας επεκτάσιμος διαχειριστής παραθύρων παραμετροποιήσιμος με μια γλώσσα παρόμοια με την Emacs Lisp -Comment[eo]=Fenestroadministrilo, kiu uzas Lispon por esti programata -Comment[es]=Un gestor de ventanas extensible con guiones escritos en un lenguaje similar a Lisp de Emacs -Comment[et]=Laiendatav aknahaldur, mis kasutab Emacs Lispi keele moodi skripte -Comment[eu]=Emacs Lisp bezalako hizkuntza batez idatziriko scripten bidez heda daitekeen leiho kudeatzailea -Comment[fa]=مدیر پنجرۀ توسعه‌پذیر دست‌نوشته‌ای با یک زبان شبیه Emacs Lisp -Comment[fi]=Laajennettavissa oleva ikkunaohjelma, johon voi luoda komentosarjoja Emacs lispin tyylisellä kielellä -Comment[fr]=Un gestionnaire de fenêtres extensible, à l'aide scripts dans un langage semblable au Lisp d'Emacs -Comment[fy]=In útbreidbere finstersmanager, skriptber fia in Emacs Lisp-likene taal -Comment[gl]=Un xestor de fiestras extensíbel e configurábel con scripts en linguaxe Emacs Lisp -Comment[he]=מנהל חלונות מקיף הניתן לתכנות עם שפה דמוית Emacs Lisp -Comment[hi]=ई-मेक्स लिस्प जैसे भाषा में स्क्रिप्ट किया जा सकने लायक विंडो प्रबंधक जिसे विस्तार दिया जा सकता है -Comment[hr]=Proširivi upravitelj prozora pisan u skripti nalik na jezik Emacs Lisp -Comment[hu]=Egy könnyen tovább bővíthető ablakkezelő, egy Emacs Lisp-szerű nyelvvel szkriptelhető -Comment[is]=Viðbætanlegur gluggastjóri sem er skriftanlegur á Emacs Lisp líku máli -Comment[it]=Un window manager estensibile per cui è possibile fare script in un linguaggio simile all'Emacs lisp -Comment[ja]=Emacs Lisp 言語スクリプトで機能拡張可能なウィンドウマネージャ -Comment[ka]=Lisp სკრიპტებით გაფათოვებადი Emacs ის მაგვარი ფანჯრის მენეჯერი -Comment[kk]=Emacs Lisp-секілді тілдегі скриптті қолданып, кеңейтілетін терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​អាច​ពង្រីក​បាន ហើយ​អាច​សរសេរ​ស្គ្រីប​ជាមួយ​ភាសា​ដែល​ដូច Emacs Lisp -Comment[lt]=Langų tvarkyklė, kurią galima išplėsti Emacs Lisp primenančia programavimo kalba -Comment[lv]=Paplašināms logu menedžeris ar Emacs Lisp līdzīgas valodas atbalstu -Comment[mk]=Екстензивен менаџер на прозорци кој може да се скриптира со јазик како Emacs Lisp -Comment[ms]=Pengurus tetingkap boleh kembang dan boleh diskrip dengan bahasa seperti Emacs Lisp -Comment[mt]=Window manager li jista' jiġi estiż, b'lingwa tixbaħ lil Emacs Lisp -Comment[nb]=En utvidbar vindusbehandler som kan skriptes med et språk som likner Emacs Lisp. -Comment[nds]=En verwiederbor Finsterpleger, de över en Skriptspraak liek to Emacs-Lisp stüert warrn kann -Comment[ne]=इमाक्स लिस्प जस्तो भाषसँग स्क्रिप्ट गर्न सकिने एउटा विस्तारयोग्य सञ्झ्याल प्रबन्धक -Comment[nl]=Een uitbreidbare windowmanager, scriptbaar via een Emacs Lisp-achtige taal -Comment[nn]=Ein utvidbar vindaugssjef som kan skriptast med eit språk som liknar Emacs Lisp -Comment[pa]= Emacs Lisp-ਵਰਗੀ ਭਾਸ਼ਾ ਸਕ੍ਰਿਪਟਯੋਗ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien, który można rozszerzać za pomocą skrytów w języku podobnym do Emacs Lisp -Comment[pt]=Um gestor de janelas extensível e programável com uma linguagem semelhante ao Emacs Lisp -Comment[pt_BR]=um gerenciador de janelas extensível, baseado em scripts, com uma linguagem parecida com o Lisp do Emacs -Comment[ro]=Un manager de ferestre extensibil scriptabil cu un limbaj similar cu Emacs Lisp -Comment[ru]=Расширяемый скриптами Lisp наподобие Emacs оконный менеджер -Comment[rw]=Mugenga dirishya yagurwa yandikwaho hakoreshejwe Emacs Kudedemanga-nka ururimi -Comment[sk]=Rozšíriteľný správca okien, ktorého je možné ovládať programovacím jazykom podobným Emacs Lispu -Comment[sl]=Razširljiv okenski upravitelj, ki se lahko upravlja s skripti v jeziku podobnem Emacs Lisp -Comment[sr]=Проширив менаџер прозора који се може скриптовати помоћу језика налик на Emacs-ов Lisp -Comment[sr@Latn]=Proširiv menadžer prozora koji se može skriptovati pomoću jezika nalik na Emacs-ov Lisp -Comment[sv]=Utökningsbar fönsterhanterare som kan styras med ett Emacs Lisp-liknande skriptspråk -Comment[ta]=Emacs Lisp-like மொழியுடனான விரிவாக்ககூடிய சாளர மேலாளர் எழுத்தாக்கம் -Comment[th]=ระบบจัดการหน้าต่างที่สามารถเพิ่มขยายได้ และควบคุมด้วยการเขียนสคริปต์โดยใช้ภาษาแบบ Emacs Lisp -Comment[tr]=Eklenti destekli Emacs Lisp benzeri bir kodlama dili kullanan kodlanabilir bir pencere yöneticisi -Comment[tt]=Emacs Lisp-kebek tel belän kiñäylelgän täräzä-idäräçe -Comment[uk]=Менеджер вікон, що можна розширювати мовою скриптів на кшталт Emacs Lisp -Comment[vi]=Trình quản lý cửa sổ có thể viết kịch bản được với ngôn ngữ giống Emacs Lisp -Comment[wa]=On manaedjeu d' purnea k' on pout radjouter des rawetes, apontiåve e scripes dins on lingaedje do stîle Emacs Lisp -Comment[zh_CN]=可用类似 Emacs Lisp 的语法进行编程的窗口管理器 -Comment[zh_TW]=一個可用類似 Emacs Lisp 語言延伸的視窗管理程式 diff --git a/kdm/kfrontend/sessions/tde.desktop.cmake b/kdm/kfrontend/sessions/tde.desktop.cmake deleted file mode 100644 index c23a33205..000000000 --- a/kdm/kfrontend/sessions/tde.desktop.cmake +++ /dev/null @@ -1,45 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Type=XSession -Exec=@TDE_BIN_DIR@/starttde -TryExec=@TDE_BIN_DIR@/starttde -Name=TDE -Name[hi]=केडीई -Name[mn]=КДЭ -Name[ta]=Kஏற்றக் காவலன் -Name[xh]=iTDE -Name[xx]=xxTDExx -Comment=The Trinity Desktop Environment. A powerful Open Source graphical desktop environment -Comment[bs]=Trinity Desktop Environment. Moćan grafički desktop otvorenog izvornog koda -Comment[ca]=L'entorn d'escriptori K. Un poderós entorn d'escriptori gràfic de Codi Font Obert -Comment[cy]=Yr Amgylchedd Penbwrdd K. Amgylchedd penbwrdd graffegol pwerus, sy'n gôd-agored. -Comment[da]=K Skrivebordsmiljøet. Et kraftigt, åbent, grafisk skrivebordsmiljø -Comment[de]=Das Trinity Desktop Environment. Eine mächtige, graphische Arbeitsumgebung und Open Source / Freie Software -Comment[el]=Το Trinity Desktop Environment. Ένα πανίσχυρο ελεύθερης προέλευσης γραφικό περιβάλλον επιφάνειας εργασίας -Comment[es]=El Entorno de Escritorio Trinity, un potente entorno de escritorio gráfico realizado de código abierto -Comment[et]=K töölaua keskkond on võimas vaba tarkvara graafiline töölaua keskkond -Comment[fi]=TDE-työpöytäympäristö (Trinity Desktop Environment) on tehokas avoimen lähdekoodin graafinen työpöytäympäristö -Comment[fr]=The Trinity Desktop Environment. Un environnement de bureau graphique, puissant et Open Source -Comment[he]=The Trinity Desktop Environment. סביבת עבודה גרפית, בעלת-עוצמה בקוד פתוח -Comment[hi]=के डेस्कटॉप वातावरण. एक शक्तिशाली, ओपन सोर्स चित्रमय डेस्कटॉप वातावरण -Comment[hu]=A TDE grafikus munkakörnyezet, egy szabad forráskódú grafikus ablakkezelő környezet -Comment[it]=L'ambiente desktop TDE. Un potente ambiente desktop grafico Open Source -Comment[mn]=The Trinity Desktop Environment. Хүчирхэг нээлттэй эх код бүхий график дэлгэцийн орчин -Comment[nb]=Trinity Desktop Environment. Et kraftig grafisk skrivebordsmiljø med åpen kildekode. -Comment[nl]=De Trinity Desktop Environment, een krachtige open source grafische desktop environment -Comment[nn]=Trinity Desktop Environment. Eit kraftig grafisk skrivebordsmiljø med open kjeldekode. -Comment[pl]=Środowisko TDE. Potężne środowisko graficzne Wolnego Oprogramowania. -Comment[pt]=O Trinity Desktop Environment. Um ambiente gráfico open source poderoso -Comment[pt_BR]=Acrônimo para Trinity Desktop Environment (ou Ambiente de Trabalho Trinity). Um poderoso ambiente de trabalho gráfico de código aberto -Comment[ro]=Trinity Desktop Environment. Un mediu grafic cu surse deschise, foarte puternic -Comment[sk]=The Trinity Desktop Environment. Výkonné, voľne šíriteľné grafické pracovné prostredie -Comment[sl]=Namizno okolje K. Zmogljivo grafično namizno okolje odprte kode -Comment[sr]=Trinity Desktop Environment (TDE). Моћно графичко радно окружење отвореног кода -Comment[sv]=Trinity-skrivbordsmiljön. En kraftfull grafisk skrivbordsmiljö med öppen källkod -Comment[ta]=Trinityமேல்மேசை சூழல். சக்திவாய்ந்த திறந்த ஆணைமூல சித்திர வகை மேல்மேசை சூழல் -Comment[tr]=TDE Masaüstü Yöneticisi. Güçlü bir grafiksel masaüstü ortamı -Comment[uk]=The Trinity Desktop Environment. Потужне графічне середовище з відкритими текстами -Comment[uz]=TDE (Trinity Desktop Environment) - кучли Open Source график иш столи муҳити -Comment[vi]=môi trường desktop Trinity, môi trường desktop đồ hoạ mã nguồn mở rất mạnh -Comment[xx]=xxThe Trinity Desktop Environment. A powerful Open Source graphical desktop environmentxx -Comment[zh_CN]=三位一体 桌面环境。强大的开放源代码图形桌面环境 diff --git a/kdm/kfrontend/sessions/tde.desktop.in b/kdm/kfrontend/sessions/tde.desktop.in deleted file mode 100644 index b9472453f..000000000 --- a/kdm/kfrontend/sessions/tde.desktop.in +++ /dev/null @@ -1,45 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Type=XSession -Exec=@TDE_BINDIR@/starttde -TryExec=@TDE_BINDIR@/starttde -Name=Trinity -Name[hi]=केडीई -Name[mn]=КДЭ -Name[ta]=Kஏற்றக் காவலன் -Name[xh]=iTDE -Name[xx]=xxTDExx -Comment=The Trinity Desktop Environment. A powerful Open Source graphical desktop environment. -Comment[bs]=Trinity Desktop Environment. Moćan grafički desktop otvorenog izvornog koda -Comment[ca]=L'entorn d'escriptori Trinity. Un poderós entorn d'escriptori gràfic de Codi Font Obert -Comment[cy]=Yr Amgylchedd Penbwrdd Trinity. Amgylchedd penbwrdd graffegol pwerus, sy'n gôd-agored. -Comment[da]=K Skrivebordsmiljøet. Et kraftigt, åbent, grafisk skrivebordsmiljø -Comment[de]=Das Trinity Desktop Environment. Eine mächtige, graphische Arbeitsumgebung und Open Source / Freie Software -Comment[el]=Το Trinity Desktop Environment. Ένα πανίσχυρο ελεύθερης προέλευσης γραφικό περιβάλλον επιφάνειας εργασίας -Comment[es]=El Entorno de Escritorio Trinity, un potente entorno de escritorio gráfico realizado de código abierto -Comment[et]=K töölaua keskkond on võimas vaba tarkvara graafiline töölaua keskkond -Comment[fi]=TDE-työpöytäympäristö (Trinity Desktop Environment) on tehokas avoimen lähdekoodin graafinen työpöytäympäristö -Comment[fr]=The Trinity Desktop Environment. Un environnement de bureau graphique, puissant et Open Source -Comment[he]=The Trinity Desktop Environment. סביבת עבודה גרפית, בעלת-עוצמה בקוד פתוח -Comment[hi]=के डेस्कटॉप वातावरण. एक शक्तिशाली, ओपन सोर्स चित्रमय डेस्कटॉप वातावरण -Comment[hu]=A TDE grafikus munkakörnyezet, egy szabad forráskódú grafikus ablakkezelő környezet -Comment[it]=L'ambiente desktop TDE. Un potente ambiente desktop grafico Open Source -Comment[mn]=The Trinity Desktop Environment. Хүчирхэг нээлттэй эх код бүхий график дэлгэцийн орчин -Comment[nb]=Trinity Desktop Environment. Et kraftig grafisk skrivebordsmiljø med åpen kildekode. -Comment[nl]=De Trinity Desktop Environment, een krachtige open source grafische desktop environment -Comment[nn]=Trinity Desktop Environment. Eit kraftig grafisk skrivebordsmiljø med open kjeldekode. -Comment[pl]=Środowisko TDE. Potężne środowisko graficzne Wolnego Oprogramowania. -Comment[pt]=O Trinity Desktop Environment. Um ambiente gráfico open source poderoso -Comment[pt_BR]=Acrônimo para Trinity Desktop Environment (ou Ambiente de Trabalho Trinity). Um poderoso ambiente de trabalho gráfico de código aberto -Comment[ro]=Trinity Desktop Environment. Un mediu grafic cu surse deschise, foarte puternic -Comment[sk]=The Trinity Desktop Environment. Výkonné, voľne šíriteľné grafické pracovné prostredie -Comment[sl]=Namizno okolje K. Zmogljivo grafično namizno okolje odprte kode -Comment[sr]=Trinity Desktop Environment (TDE). Моћно графичко радно окружење отвореног кода -Comment[sv]=Trinity-skrivbordsmiljön. En kraftfull grafisk skrivbordsmiljö med öppen källkod -Comment[ta]= Trinityமேல்மேசை சூழல். சக்திவாய்ந்த திறந்த ஆணைமூல சித்திர வகை மேல்மேசை சூழல் -Comment[tr]=TDE Masaüstü Yöneticisi. Güçlü bir grafiksel masaüstü ortamı -Comment[uk]=The Trinity Desktop Environment. Потужне графічне середовище з відкритими текстами -Comment[uz]=TDE (Trinity Desktop Environment) - кучли Open Source график иш столи муҳити -Comment[vi]=môi trường desktop K, môi trường desktop đồ hoạ mã nguồn mở rất mạnh -Comment[xx]=xxThe Trinity Desktop Environment. A powerful Open Source graphical desktop environmentxx -Comment[zh_CN]=三位一体 桌面环境。强大的开放源代码图形桌面环境 diff --git a/kdm/kfrontend/sessions/twm.desktop b/kdm/kfrontend/sessions/twm.desktop deleted file mode 100644 index 894371ae9..000000000 --- a/kdm/kfrontend/sessions/twm.desktop +++ /dev/null @@ -1,71 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=twm -TryExec=twm -Name=TWM -Name[eo]=TFA -Name[hi]=टीडबल्यूएम -Name[te]=టి డబ్ల్యు ఎం -Comment=The Tab Window Manager -Comment[af]=Die Tab venster bestuurder -Comment[ar]=مدير النوافذ Tab -Comment[be]=Кіраўнік вокнаў з укладкамі Tab Window Manager -Comment[bn]=দি ট্যাব উইণ্ডো ম্যানেজার -Comment[bs]=Tab Window Manager -Comment[ca]=El gestor de finestres Tab -Comment[csb]=Tab Window Manager -Comment[cy]=Y Trefnydd Ffenestri Tab -Comment[da]=Tab-vindueshåndtering -Comment[de]=Der Tab-Fenstermanager -Comment[el]=Ο διαχειριστής παραθύρων Tab -Comment[eo]=Taba fenestroadministrilo -Comment[es]=El Tab Window Manager -Comment[et]=Kaartidega aknahaldur -Comment[eu]=Tab leiho kudeatzailea -Comment[fa]=مدیر پنجرۀ تب -Comment[fi]=Välilehtiä tukeva ikkunaohjelma -Comment[fy]=De Ljepper Finster Behearder -Comment[gl]=O Xestor de Fiestras Tab -Comment[hi]=टैब विंडो प्रबंधक -Comment[hr]=Tab upravitelj prozora -Comment[hu]=Tab Window Manager ablakkezelő -Comment[is]=Tab gluggastjórinn -Comment[it]=Il Tab Window Manager -Comment[ja]=Tab 化ウィンドウマネージャ -Comment[ka]=X11 სისტემის ტრადიციული ფანჯრის მენეჯერი -Comment[kk]=Tab терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ជា​ផ្ទាំង -Comment[ko]=탭 창 관리자 -Comment[lt]=Kortelių langų tvarkyklė -Comment[lv]=Tabu logu menedžeris -Comment[mk]=Tab Window Manager -Comment[mn]=Tab Цонхны удирдагч -Comment[ms]=Pengurus Tetingkap Tab -Comment[mt]=Tab Window Manager -Comment[nb]=Tab Vindusbehandler -Comment[nds]=De Tab-Finsterpleger -Comment[ne]=ट्याब सञ्झ्याल प्रबन्धक -Comment[nl]=De Tab Window Manager -Comment[nn]=Tab Window Manager -Comment[pa]=ਟੈਬ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Tab Window Manager -Comment[pt]=O Tab Window Manager -Comment[pt_BR]=O Gerenciador de Janelas de Abas -Comment[ro]=Tab Window Manager -Comment[ru]=Традиционный оконный менеджер системы X11 -Comment[rw]=Mugenga Dirishya Agafishi -Comment[se]=Tab-láse lásegieđahalli -Comment[sk]=Správca okien s kartami -Comment[sl]=Tab Window Manager, okenski upravitelj z zavihki -Comment[sv]=Flikfönsterhanteraren -Comment[ta]=டாப் சாளர மேலாளர் -Comment[te]=టాబ్ విండొ అభికర్త -Comment[tg]=Tab-и мудири тиреза -Comment[th]=Tab Window Manager -Comment[tr]=Tab Pencere Yöneticisi -Comment[tt]=X11 sistemendäge kebek tabaqlı täräzä-idäräçe -Comment[uk]=Tab Window Manager -Comment[vi]=Trình Quản lý Cửa sổ Thẻ -Comment[wa]=Li manaedjeu di purneas avou Linwetes (Tab Window Manager) -Comment[zh_CN]=标签式窗口管理器 -Comment[zh_TW]=Tab 視窗管理程式 diff --git a/kdm/kfrontend/sessions/ude.desktop b/kdm/kfrontend/sessions/ude.desktop deleted file mode 100644 index 108a493e4..000000000 --- a/kdm/kfrontend/sessions/ude.desktop +++ /dev/null @@ -1,75 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=uwm -TryExec=uwm -Name=UDE -Name[eo]=ULĈ -Name[hi]=यूडीई -Name[te]=యుడిఈ -Comment=The UNIX Desktop Environment -Comment[af]=Die 'Unix Desktop Environment' -Comment[ar]=بيئة سطح مكتب يونكس -Comment[be]=Працоўнае асяроддзе UNIX -Comment[bn]=দি ইউনিক্স ডেস্কটপ এনভায়রনমেন্ট -Comment[br]=An endro burev UNIX -Comment[bs]=UNIX Desktop Environment -Comment[ca]=L'entorn d'escriptori de Unix -Comment[csb]=Òkrãże pùltu Uniksa -Comment[cy]=Yr Amgylchedd Penbwrdd UNIX -Comment[da]=UNIX desktopmiljø -Comment[de]=Das UNIX Desktop Environment -Comment[el]=Το περιβάλλον επιφάνειας εργασίας του UNIX -Comment[eo]=La Uniksa Labortablo Ĉirkauaĵo -Comment[es]=El UNIX Desktop Environment -Comment[et]=UNIXi töölaua keskkond -Comment[eu]=UNIX mahaigain ingurunea -Comment[fa]=محیط رومیزی یونیکس -Comment[fi]=UNIX-työpöytäympäristö -Comment[fy]=De Unix Desktop Environment -Comment[ga]=Timpeallacht Deisce UNIX (UDE) -Comment[gl]=O Entorno de Escritório de UNIX -Comment[hi]=यूनिक्स डेस्कटॉप माहौल -Comment[hr]=UNIX radno okruženje -Comment[hu]=UNIX Desktop Environment ablakkezelő -Comment[is]=UNIX skjáborðsumhverfið -Comment[it]=Lo Unix Desktop Environment -Comment[ja]=UNIX デスクトップ環境 -Comment[ka]=UNIX-ის სამუშაო გარემო -Comment[kk]=UNIX Desktop Environment -Comment[km]=UNIX Desktop Environment -Comment[ko]=UNIX 데스크톱 환경 -Comment[lt]=UNIX darbastalio aplinka -Comment[lv]= UNIX Darba virsmas vide -Comment[mk]=UNIX Desktop Environment -Comment[mn]=ЮНИКС ажлын тавцангийн орчин -Comment[ms]=Persekitaran Desktop UNIX -Comment[mt]=UNIX Desktop Environment -Comment[nb]=UNIX Desktop Environment -Comment[nds]=De UNIX-Schriefdisch-Ümgeven -Comment[ne]=युनिक्स डेस्कटप वातावरण -Comment[nl]=De Unix Desktop Environment -Comment[nn]=UNIX Desktop Environment -Comment[pa]=UNIX Desktop Environment -Comment[pl]=Środowisko pulpitu Uniksa -Comment[pt]=O Unix Desktop Environment -Comment[pt_BR]=Ambiente de Trabalho do UNIX -Comment[ro]=Mediul grafic UNIX -Comment[ru]=UNIX Desktop Environment -Comment[rw]=Ibikikije Ibiro UNIX -Comment[se]=UNIX Desktop Environment -Comment[sl]=Namizno okolje UNIX -Comment[sr]=Unix радно окружење -Comment[sr@Latn]=Unix radno okruženje -Comment[sv]=Unix-skrivbordsmiljön -Comment[ta]=யுனிக்ஸ் மேல்மேசை சூழல் -Comment[te]=యూనిక్స్ రంగస్థల పర్యావరణం -Comment[tg]=Атрофи мизи кории UNIX -Comment[th]=สภาพแวดล้อมเดสก์ทอป UNIX -Comment[tr]=Unix Masaüstü Ortamı -Comment[tt]=UNIX Desktop Environment -Comment[uz]=Unix ish stoli muhiti (Unix Desktop Environment) -Comment[uz@cyrillic]=Unix иш столи муҳити (Unix Desktop Environment) -Comment[vi]=Môi trường Màn hình nền UNIX -Comment[wa]=L' evironmint di scribanne Unix UDE -Comment[zh_CN]=UNIX 桌面环境 -Comment[zh_TW]=Unix 桌面環境 diff --git a/kdm/kfrontend/sessions/vtwm.desktop b/kdm/kfrontend/sessions/vtwm.desktop deleted file mode 100644 index 50af40a63..000000000 --- a/kdm/kfrontend/sessions/vtwm.desktop +++ /dev/null @@ -1,72 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=vtwm -TryExec=vtwm -Name=VTWM -Name[eo]=VTFA -Name[hi]=वीटीडबल्यूएम -Name[te]= వి టి డబ్ల్యు ఎం -Comment=The Virtual Tab Window Manager. TWM enhanced by virtual screens, etc. -Comment[af]=Die virtuele tab venster bestuurder. TWM wat met virtuele skerms uitgebreik is. -Comment[ar]=مدير نوافذ Tab الوهمي، مدير نوافذ TWM محسّن بأسطح المكتب الوهمية، إلخ. -Comment[be]=Віртуальны кіраўнік вокнаў з укладкамі Virtual Tab Window Manager. TWM, з дадатковай падтрымкай віртуальных экранаў і інш. -Comment[bn]=ভার্চুয়াল ট্যাব উইণ্ডো ম্যানেজার, ভার্চুয়াল স্ক্রীণ ইত্যাদি দ্বারা বর্ধিত -Comment[bs]=Virtual Tab Window Manager. TWM proširen virtuelnim ekranima itd. -Comment[ca]=El Virtual Tab Window Manager. TWM millorat per a pantalles virtuals, etc. -Comment[cs]=The Virtual Tab Window Manager. TWM vylepšené o virtuální obrazovky aj. -Comment[csb]=Virtual Tab Window Manager. TWM zbògacony ò wirtualné pùltë ëtp. -Comment[cy]=Y Trefnydd Ffenestri Tab Rhith. TWM wedi'i wella gan sgriniau rhith, ayyb. -Comment[da]=Virtual Tab Window Manager. TWM udvidet med virtuelle skærme osv. -Comment[de]=Der Virtual-Tab-Fenstermanager, eine Erweiterung von TWM mit virtuellen Arbeitsflächen usw. -Comment[el]=Ο εικονικός Tab διαχειριστής παραθύρων. Ο TWM εμπλουτισμένος με εικονικές οθόνες, κτλ. -Comment[eo]=La Virtuala Taba Fenestroadministrilo, TFA plibonigita per virtualaj ekranoj -Comment[es]=El Virtual Tab Window Manager, TWM mejorado con pantallas virtuales, etc. -Comment[et]=Virtuaalsete kaartidega aknahaldur ehk TWM, mida on täiendatud virtuaalsete ekraanidega jne. -Comment[eu]=Virtual Tab leiho kudeatzailea. Pantaila birtual eta abarrez hobetutako TWM-a -Comment[fa]=یک مدیر پنجرۀ تب مجازی.TWM گسترش‌یافته توسط پرده‌های مجازی و غیره. -Comment[fi]=Välilehtiä ja virtuaalityöpöytiä tukeva ikkunaohjelma, pohjautuu TWM:ään -Comment[fr]=The Virtual Tab Window Manager. TWM avec en plus la gestion des bureaux multiples -Comment[fy]=De firtuele Ljepper Window Manager. TWM útbreid mei firtuele buroblêden, ensfh. -Comment[gl]=O Virtual Tab Window Manager. TWM mellorado con pantallas virtuais, etc. -Comment[he]=The Virtual Tab Window Manager. TWM המשופר בשולחנות עבודה וירטואליים וכו' -Comment[hi]=आभासी टैब विंडो प्रबंधक. TWM को आभासी स्क्रीन इत्यादि से बेहतर बनाया गया -Comment[hr]=Comment=Virtual Tab Window Manager. TWM poboljšan virtualnim zaslonima itd. -Comment[hu]=Virtual Tab Window Manager, egy TWM-változat, támogatja a virtuális képernyőkezelést -Comment[is]=Tab gluggastjórinn endurbættur með sýndarskjám og fleiru. -Comment[it]=Il Virtual Tab Window Manager. TWM migliorato con schermi virtuali ecc. -Comment[ja]=仮想スクリーンなどの機能を拡張した TWM ベースの仮想タブウィンドウマネージャ -Comment[ka]=ვირტუალური ეკრანებით აღჭურვილი TWM-ის ვარიანტი -Comment[kk]=Virtual Tab Window Manager. TWM-негіздеген, виртуалды экрандары және т.б.с.с бар терезе менеджері. -Comment[km]=Virtual Tab Window Manager ។ TWM ដែល​បាន​ធ្វើ​ឲ្យ​ប្រសើរ​ដោយ​អេក្រង់​និមិត្ត ជាដើម ។ -Comment[lt]=Virtualių kortelių darbastalio aplinka. TWM išplėsta virtualiais darbastaliais ir pan. -Comment[lv]=Virtuālo tabu logu menedžeris. TWM papildināts ar virtuālajiem ekrāniem utml. -Comment[mk]=Virtual Tab Window Manager. TWM подобрен со виртуелни површини итн. -Comment[ms]=Pengurus Tetingkap Tab Maya. TWM dipertingkat dengan skrin maya, dsb. -Comment[mt]=Virtual Tab Window Manager. TWM flimkien ma' desktops virtwali eċċ -Comment[nb]=Virtual Tab vindusbehandler. TWM utvidet med virtuelle skjermer, osv. -Comment[nds]=De "Virtual Tab Window Manager". Dat is TWM verwiedert üm virtuelle Schirmen etc. -Comment[ne]=अवास्तविक ट्याब सञ्झ्याल प्रबन्धक । अवास्तविक पर्दाद्वारा बृद्धि गरिएको TWM, आदि -Comment[nl]=De Virtual Tab Window Manager. TWM uitgebreid met virtuele bureaubladen, etc. -Comment[nn]=Virtual Tab Window Manager. TWM utvida med virtuelle skjermar og anna. -Comment[pa]=Virtual Tab Window Manager. TWM ਫਰਜ਼ੀ ਪਰਦਿਆਂ ਨਾਲ ਲੈੱਸ -Comment[pl]=Virtual Tab Window Manager. TWM wzbogacony o wirtualne pulpity itp. -Comment[pt]=O Virtual Tab Window Manager. Um TWM melhorado com ecrãs virtuais, etc. -Comment[pt_BR]=O gerenciador de janelas de abas virtuais. TWM melhorado pelas telas virtuais. -Comment[ro]=Virtual Tab Window Manager. TWM îmbunătățit cu ecrane virtuale etc. -Comment[ru]=Вариант TWM, имеющий виртуальные экраны и т.д. -Comment[rw]=Mugenga Dirishya y'Agafishi Itaboneka.TWM ivuguruwe na mugaragaza zitagaragara, n'ibindi. -Comment[se]=The Virtual Tab Window Manager. TWM buoriduvvon virtuella čállinbevddiin, jna. -Comment[sk]=The Virtual Tab Window Manager. TWM rozšírený o virtuálne obrazovky atď. -Comment[sl]=Virtual Tab Window Manager. TWM, izboljšan z navideznimi zasloni ipd. -Comment[sr]=„The Virtual Tab Window Manager“. TWM побољшан виртуелним екранима и сл. -Comment[sr@Latn]=„The Virtual Tab Window Manager“. TWM poboljšan virtuelnim ekranima i sl. -Comment[sv]=Virtuell flikfönsterhanterare. TWM utökad med virtuella skärmar, etc. -Comment[ta]=மெய்நிகர் தத்தல் சாளர மேலாளர். TWM மெய்நிகர் திரைகளால் மேம்படுத்தப்பட்டது. -Comment[th]=The Virtual Tab Window Manager คือ TWM ที่เพิ่มความสามารถโดยหน้าจอเสมือน และอื่นๆ -Comment[tr]=Virtual Tab Masaüstü Yöneticisi. -Comment[tt]=Virtual Tab Window Manager. Öställär östälengän TWM kebek. -Comment[uk]=Virtual Tab Window Manager. TWM з підтримкою віртуальних екранів. -Comment[vi]=Trình Quản lý Cửa sổ Thẻ Ảo. TWM cải tiến với màn hình ảo, ... -Comment[wa]=Li Forveyou Manaedjeu di Purneas avou Linwetes (Virtual Tab Window Manager). TWM a sacwants forveyowès waitroûles, evnd. -Comment[zh_CN]=虚拟标签式窗口管理器。用虚拟屏幕等功能增强的 TWM。 -Comment[zh_TW]=虛擬 Tab 視窗管理程式。基於 TWM 並加強虛擬螢幕等等。 diff --git a/kdm/kfrontend/sessions/w9wm.desktop b/kdm/kfrontend/sessions/w9wm.desktop deleted file mode 100644 index 92633bcf7..000000000 --- a/kdm/kfrontend/sessions/w9wm.desktop +++ /dev/null @@ -1,74 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=w9wm -TryExec=w9wm -Name=W9WM -Name[eo]=F9FA -Name[hi]=डबल्यू9डबल्यूएम -Name[ta]=IceWM -Name[te]=డబ్ల్యు 9 డబ్ల్యు ఎం -Name[th]=ตัวจัดการหน้าต่าง W9WM -Comment=A window manager based on 9WM, enhanced by virtual screens and keyboard bindings -Comment[af]='n Venster bestuurder wat op 9WM gebaseer is, uitgebrei met virtuele skerms en sleutelbord bindinge -Comment[ar]=مدير نوافذ مبني على 9WM، محسّن الشاشات الوهمية والمفاتيح المرتبطة -Comment[be]=Кіраўнік вокнаў, заснаваны на 9WM, з дадатковай падтрымкай віртуальных экранаў і клавішных скаротаў -Comment[bn]=9WM ভিত্তিক উইণ্ডো ম্যানেজার, ভার্চুয়াল স্ক্রীণ এবং কীবোর্ড বাইন্ডিং দ্বারা বর্ধিত -Comment[bs]=Window manager baziran na 9WM, proširen virtuelnim ekranima i prečicama tastature -Comment[ca]=Un gestor de finestres basat en 9WM, millorat per a pantalles virtuals i amb dreceres de teclat -Comment[cs]=Správce oken založený na 9WM rozšířený o virtuální plochy a klávesové zkratky -Comment[csb]=Menedżer òknów òpiarty na 9WM, zbògacony ò wirtualné ekranë ë kònfigùracëjã klawiszowëch skrodzënów -Comment[cy]=Trefnydd ffenestri wedi'i seilio ar 9WM, wedi'i wella gan sgriniau rhith a rhwymiadau bysyll. -Comment[da]=En vindueshåndtering baseret på 9WM, udvidet med virtuelle skærme og tastaturbindinger -Comment[de]=Fenstermanager auf der Basis von 9WM, erweitert durch virtuelle Arbeitsflächen und Tastaturzuordnungen -Comment[el]=Ένας διαχειριστής παραθύρων βασισμένος στον 9WM, εμπλουτισμένος με εικονικές οθόνες και συνδυασμούς πλήκτρων -Comment[eo]=Fenestroadministrilo devenigita de 9FA, plibonigita per virtualaj ekranoj kaj klaviara uzo -Comment[es]=Un gestor de ventanas basado en 9WM, mejorado con ventanas virtuales y accesos rápidos de teclado -Comment[et]=Aknahaldur, mille aluseks on 9WM ja mida on täiendatud virtuaalsete ekraanide ja kiirklahvide võimalusega -Comment[eu]=9WM-n oinarritutako leiho kudeatzailea, pantaila birtual eta laster-teklez hobetua -Comment[fa]=یک مدیر پنجره بر اساس 9WM، گسترش‌یافته توسط ‌پرده‌های مجازی و مقیدسازیهای صفحه کلید -Comment[fi]=9WM:ään pohjautuva ikkunaohjelma, jossa tuki virtuaalityöpöydille ja näppäimistöyhdistelmille -Comment[fr]=Un gestionnaire de fenêtres fondé sur 9WM, avec en plus la gestion des bureaux virtuels et des raccourcis clavier -Comment[fy]=In finstersmanager basearrre op 9WM. útbreid mei firtuele buroblêden en fluchtoetsen -Comment[gl]=Un xestor de fiestras baseado en 9WM, mellorado polas pantallas virtuais e atallos de teclado -Comment[he]=מנהל חלונות המבוסס על 9WM, המשופר בשולחנות עבודה וירטואליים ומיפוי מקשים -Comment[hi]= 9डबल्यूएम आधारित विंडो प्रबंधक, आभासी स्क्रीन तथा की-बोर्ड बाइंडिंग से बेहतर बनाया गया -Comment[hr]=Upravitelj prozora zasnovan na 9WM, unaprijeđen virtualnim zaslonima i prečacima tipkovnice -Comment[hu]=Egy 9WM-alapú ablakkezelő, virtuális képernyőkezeléssel, konfigurálható billentyűparancsokkal -Comment[is]=Gluggastjóri byggður á 9WM en endurbættur með sýndarskjám og lyklaborðsvörpunum -Comment[it]=Un window manager basato su 9WM, migliorato con schermi virtuali e scorciatoie per la tastiera. -Comment[ja]=仮想スクリーンとキーボードショートカット機能を強化した 9WM ベースのウィンドウマネージャ -Comment[ka]=ფანჯრის მენეჯერი 9wm-ს ბაზაზე, ვირტუალური ეკრანებით და კლავიატურის შესაბამისობებით -Comment[kk]=9WM-негіздеген, виртуалды экрандары, пернетақта тіркесімдері бар терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ផ្អែក​លើ 9WM ដែល​ត្រូវ​បាន​ធ្វើ​ឲ្យ​ប្រសើរ​ដោយ​អេក្រង់​និមិត្ត និង​ការ​ចង​គ្រាប់ចុច -Comment[ko]=부분적 그놈 지원과 가상 데스크톱 지원을 사용하는 AEWM 기반 창 관리자 -Comment[lt]=Langų tvarkyklė, paremta 9WM, išplėsta virtualių ekranų ir klaviatūros greitųjų klavišų palaikymu -Comment[lv]=Logu menedžeris bāzēts uz 9WM, papildināts ar virtuālajiem ekrāniem un tastatūras saīsnēm -Comment[mk]=Менаџер на прозорци базиран на 9WM, подобрен со виртуелни површини и поврзувања за тастатурата -Comment[ms]=Pengurus tetingkap berdasarkan 9WM, dipertingkat dengan skrin maya dan ikatan papan kekunci -Comment[mt]=Window manager ibbażat fuq 9WM, flimkien ma desktops virtwali u hotkeys -Comment[nb]=En vindusbehandler basert på 9WM, forbedret med virtuelle skjermer og hurtigtaster -Comment[nds]=En Finsterpleger opbuut op 9WM, verwiedert üm virtuelle Schirmen un Tastkombinatschonen -Comment[ne]=कुञ्जीपाटी बाइन्डिङ र अवास्तविक पर्दाहरूद्वारा बृद्धि गरिएको 9WM मा आधारित सञ्झ्याल प्रबन्धक -Comment[nl]=Een windowmanager gebaseerd op 9WM. Uitgebreid met virtuele bureaubladen en sneltoetsen -Comment[nn]=Ein vindaugssjef basert på 9WM, forbetra med virtuelle skjermar og snøggtastar -Comment[pa]=9WM ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਫਰਜ਼ੀ ਪਰਦਿਆਂ ਤੇ ਕੀ-ਬੋਰਡ ਬਾਈਡਿੰਗ ਨਾਲ ਲੈੱਸ -Comment[pl]=Menedżer okien oparty na 9WM, wzbogacony o wirtualne ekrany i konfigurowanie skrótów klawiszowych -Comment[pt]=Um gestor de janelas baseado no 9WM, melhorado com ecrãs virtuais e atalhos de teclado -Comment[pt_BR]=Um gerenciador de janelas baseado no 9Wm, melhorado pelas telas virtuais e atalhos de teclado -Comment[ro]=Un manager de ferestre bazat pe 9WM, îmbunătățir cu ecrane virtuale și acceleratori de tastatură -Comment[ru]=Оконный менеджер на основе 9wm, имеющий виртуальные экраны и привязку клавиш -Comment[rw]=Mugenga Dirishya ishingiye kuri 9WM, ivuguruwe hakoreshejwe mugaragaza itaboneka n'amahuza mwandikisho -Comment[sk]=Správca okien založený na 9WM, rozšírený o virtuálne obrazovkya klávesové skratky -Comment[sl]=Okenski upravitelj na osnovi 9WM, izboljšan z navideznimi zasloni in tipkovnimi vezmi -Comment[sr]=Менаџер прозора заснован на 9WM-у, побољшан виртуелним екранима и повезивањем тастатуре -Comment[sr@Latn]=Menadžer prozora zasnovan na 9WM-u, poboljšan virtuelnim ekranima i povezivanjem tastature -Comment[sv]=Fönsterhanterare baserad på 9WM, utökad med virtuella skärmar och tangentbindingar -Comment[ta]=9WM அடிப்படையிலான மெய்நிகர் திரை மற்றும் விசைப்பலகை சேர்ப்புகளால் மேம்படுத்தப்பட்ட சாளர மேலாளார், -Comment[th]=ระบบจัดการหน้าต่างที่สร้างมาจาก 9WM และเพิ่มความสามารถด้วยหน้าจอเสมือนและแป้นพิมพ์ลัด -Comment[tr]=9WM tabanlı, sanal ekranları ve klavye kısayolları ile geliştirilmiş bir masaüstü yöneticisi -Comment[tt]=Xıyalí öställär belän töylekne totqan täräzä-idäräçe. 9WM asılında -Comment[uk]=Менеджер вікон, заснований на 9WM, додано віртуальні екрани та прив'язки клавіш -Comment[vi]=Trình quản lý cửa sổ dựa vào 9WM, cải tiến với màn hình ảo, tổ hợp phím -Comment[wa]=On manaedjeu di purneas båzé so 9WM, avou sopoirt po les forveyous scribannes eyet les rascourtis di taprece. -Comment[zh_CN]=基于 9WM 的窗口管理器,用虚拟屏幕和键盘绑定等功能增强了 -Comment[zh_TW]=一個基於 9WM 並加強虛擬螢幕及鍵盤組合鍵功能 diff --git a/kdm/kfrontend/sessions/waimea.desktop b/kdm/kfrontend/sessions/waimea.desktop deleted file mode 100644 index 8981b5af6..000000000 --- a/kdm/kfrontend/sessions/waimea.desktop +++ /dev/null @@ -1,77 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=waimea -TryExec=waimea -Name=Waimea -Name[eo]=Vaimeo -Name[hi]=वाईमिया -Name[ne]=विमेआ -Name[pa]=ਵਾਈਮਿਆ -Name[te]=వైమెయా -Comment=A highly customizable window manager based on Blackbox -Comment[af]='n Hoë opstelbare venster bestuurder wat op Blackbox gebaseer is -Comment[ar]=مدير نوافذ قابل جداً للتخصيص مبني على Blackbox -Comment[be]=Кіраўнік вокнаў, заснаваны на Blackbox, з магчымасцю настаўлення -Comment[bn]=ব্ল্যাকবক্স ভিত্তিক উইণ্ডো ম্যানেজার -Comment[bs]=Visoko prilagodljiv window manager baziran na Blackbox -Comment[ca]=Un gestor de finestres altament configurable basat en Blackbox -Comment[cs]=Vysoce přizpůsobitelný správce oken založený na Blackboxu -Comment[csb]=Menedżer òknów òpiartëch na Blackbox z wiôldżima mòżnotama dopasowaniô -Comment[cy]=Trefnydd ffenestri sy'n hawdd ei ffurfweddu, wedi'i seilio ar Ddu-flwch -Comment[da]=En meget indstillelig vindueshåndtering baseret på Blackbox -Comment[de]=Vielfältig anpassbarer Fenstermanager, der auf Blackbox basiert -Comment[el]=Ένας ιδιαίτερα παραμετροποιήσιμος διαχειριστής παραθύρων βασισμένος στον Blackbox -Comment[en_GB]=A highly customisable window manager based on Blackbox -Comment[eo]=Tre agordebla fenestroadministrilo, devenigita de Negrujo -Comment[es]=Un gestor de ventanas muy personalizable basado en Blackbox -Comment[et]=Väga hästi kohandatav aknahaldur, aluseks Blackbox -Comment[eu]=Blackboxen oinarritutako leiho-kudeatzaile zeharo pertsonalizagarria -Comment[fa]=یک مدیر پنجره با قابلیت سفارشی‌سازی بالا بر اساس Blackbox -Comment[fi]=Blackboxiin perustuva paljon muokattavissa oleva ikkunaohjelma -Comment[fr]=Un gestionnaire de fenêtres très configurable fondé sur Blackbox -Comment[fy]=In tige ynstelbere finstersmanager, basearre op Blackbox -Comment[gl]=Un xestor de fiestras moi personalizábel baseado en Blackbox -Comment[he]=מנהל חלונות המאפשר התאמה אישית גבוהה והמבוסס על Blackbox -Comment[hi]=ब्लेक-बाक्स आधारित, अत्यंत कस्टमाइजेबल विंडो प्रबंधक -Comment[hr]=Vrlo prilagodljiv upravitelj prozora zasnovan na Blackboxu -Comment[hu]=Egy sokféle beállítási lehetőséggel rendelkező ablakkezelő a Blackbox alapján -Comment[is]=Afar stillanlegur gluggastjóri byggður á Blackbox -Comment[it]=Un window manager molto personalizzabile basato su BlackBox -Comment[ja]=Blackbox ベースの高度なカスタマイズが可能なウィンドウマネージャ -Comment[ka]=კონფიგურირებადი ფანჯრის მენეჯერი Blackbox-ს ბაზაზე -Comment[kk]=Blackbox-негіздеген, баптау жағынан бай, терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​អាច​ប្ដូរ​តាម​បំណង​កម្រិត​ខ្ពស់ ដោយ​ផ្អែក​លើ Blackbox -Comment[ko]=Blackbox 기반의 사용자 정의가 가능한 관리자 -Comment[lt]=Daug konfigūravimo parinkčių turinti langų tvarkyklė, paremta Blackbox -Comment[lv]=Plaši konfigurējams logu menedžeris bāzēts uz Blackbox -Comment[mk]=Менаџер на прозорци базиран на Blackbox со голем број опции -Comment[ms]=Pengurus tetingkap boleh suai berdasarkan Kotak Hitam -Comment[mt]=Window manager konfigurabbli ibbażat fuq BlackBox -Comment[nb]=En vindusbehandler med mange tilpasninger, basert på Blackbox -Comment[nds]=En Finsterpleger mit mennige Instellen, opbuut op Blackbox -Comment[ne]=कालो बाकसमा आधारित उच्च अनुकूल योग्य एक सञ्झ्याल प्रबन्धक -Comment[nl]=Een zeer instelbare windowmanager, gebaseerd op Blackbox -Comment[nn]=Ein vindaugssjef med mange tilpassingar, basert på Blackbox -Comment[pa]=ਬਲੈਕਬਕਸੇ 'ਤੇ ਆਧਾਰਿਤ ਅਤਿ ਸੋਧਯਯੋਗ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Menedżer okien oparty na Blackbox z dużymi możliwościami dostosowania -Comment[pt]=Um gestor de janelas altamente configurável, baseado no Blackbox -Comment[pt_BR]=Um gerenciador de janelas altamente personalizável, baseado no Blackbox -Comment[ro]=Un manager de ferestre foarte configurabil bazat pe Blackbox -Comment[ru]=Настраиваемый оконный менеджер, основанный на Blackbox -Comment[rw]=Mugenga dirishya ihabwa imiterere yifuzwa mu buryo hejuru ishingiye ku Gasandukumukara -Comment[sk]=Veľmi prispôsobiteľný správca okien založený na Blackbox -Comment[sl]=Visoko nastavljiv okenski upravitelj na osnovi Blackboxa -Comment[sr]=Врло прилагодљив менаџер прозора заснован на Blackbox-у -Comment[sr@Latn]=Vrlo prilagodljiv menadžer prozora zasnovan na Blackbox-u -Comment[sv]=Ytterst anpassningsbar fönsterhanterare baserad på Blackbox -Comment[ta]=தனதாக்க வல்ல கருப்புப்பெட்டி சார்ந்த சாளர மேலாளர் -Comment[th]=ระบบจัดการหน้าต่างที่ปรับแต่งได้อย่างละเอียด สร้างมาจาก Blackbox -Comment[tr]=Blackbox temelli, kolayca özelleştirilebilir bir pencere yöneticisi -Comment[tt]=Yaqşı köylänüçän täräzä-idäräçe. Blackbox asılında -Comment[uk]=Надгнучкий менеджер вікон, заснований на Blackbox -Comment[uz]=Blackbox asosida yaratilgan, moslab boʻladigan oyna boshqaruvchi -Comment[uz@cyrillic]=Blackbox асосида яратилган, мослаб бўладиган ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ rất dễ cá nhân hoá dựa trên Blackbox -Comment[wa]=On manaedjeu di purneas k' vos ploz pår mete da vosse båzé so Blackbox -Comment[zh_CN]=基于 BlackBox 可高度自定义的窗口管理器 -Comment[zh_TW]=一個基於 Blackbox 且高度可客製化的視窗管理程式 diff --git a/kdm/kfrontend/sessions/wm2.desktop b/kdm/kfrontend/sessions/wm2.desktop deleted file mode 100644 index 618c10bcc..000000000 --- a/kdm/kfrontend/sessions/wm2.desktop +++ /dev/null @@ -1,77 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=wm2 -TryExec=wm2 -Name=WM2 -Name[eo]=Fa2 -Name[hi]=डबल्यूएम2 -Name[te]=డబ్ల్యు ఎం 2 -Name[th]=ตัวจัดการหน้าต่าง WM2 -Comment=A small, non-configurable window manager -Comment[af]='n Klein, nie opstelbare venster bestuurder -Comment[ar]=مدير نوافذ صغير غير قابل للإعداد -Comment[be]=Маленькі кіраўнік вокнаў, без магчымасці настаўленняў -Comment[bn]=একটি ছোটো উইণ্ডো ম্যানেজার -Comment[bs]=Mali, ne-konfigurabilni window manager -Comment[ca]=Un petit i no configurable gestor de finestres -Comment[cs]=Malý nepřizpůsobitelný správce oken -Comment[csb]=Môłi menedżer òknów bez mòżnotë kònfigùracëji -Comment[cy]=Trefnydd ffenestri bach na ellir ffurfweddu -Comment[da]=En lille, ikke-indstillelig vindueshåndtering -Comment[de]=Kleiner, nicht einstellbarer Fenstermanager -Comment[el]=Ένας μικρός, μη παραμετροποιήσιμος διαχειριστής παραθύρων -Comment[eo]=Malgranda, ne agordebla fenestroadministrilo -Comment[es]=Un gestor de ventanas pequeño y no configurable -Comment[et]=Väike ja seadistamatu aknahaldur -Comment[eu]=Leiho-kudeatzaile txikia, konfiguratu ezin dena -Comment[fa]=یک مدیر پنجرۀ کوچک و غیرقابل پیکربندی -Comment[fi]=Pieni ikkunaohjelma, jossa ei ole asetuksia -Comment[fr]=Un gestionnaire de fenêtres petit et non configurable -Comment[fy]=In lytse, net-ynstelbere finstersmanager -Comment[gl]=Un xestor de fiestras pequeno non configurábel -Comment[he]=מנהל חלונות קטן ולא ניתן להגדרה -Comment[hi]=एक छोटा विंडो प्रबंधक जो कॉन्फ़िगर नहीं हो सकता -Comment[hr]=Malen, nepodesiv upravitelj prozora -Comment[hu]=Egy nagyon egyszerű ablakkezelő, beállítási lehetőségek nélkül -Comment[is]=Lítill, einfaldur gluggastjóri sem er ekki hægt að stilla -Comment[it]=Un window manager piccolo e non configurabile -Comment[ja]=小さくて設定項目のないウィンドウマネージャ -Comment[ka]=პატარა და არაკონფიგურირებადი ფანჯრის მენეჯერი -Comment[kk]=Шағын, баптауы жоқ, терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​តូច ហើយ​មិន​អាច​កំណត់​រចនាសម្ព័ន្ធ​បាន -Comment[ko]=설정할 수 없는 작은 창 관리자 -Comment[lt]=Maža, nekonfigūruojama langų tvarkyklė -Comment[lv]=Mazs, nekonfigurējams logu menedžeris -Comment[mk]=Мал и неконфигурабилен менаџер на прозорци -Comment[mn]=Жижиг тохируулах боломжгүй цонх удирдагч -Comment[ms]=Pengurus tetingkap yang kecil dan tidak boleh konfigur -Comment[mt]=Window manager żgħir u mhux konfigurabbli -Comment[nb]=En liten vindusbehandler uten tilpasninger -Comment[nds]=En lütte Finsterpleger ahn Instellen -Comment[ne]=सानो, कन्फिगर गर्न नसकिने सञ्झ्याल प्रबन्धक -Comment[nl]=Een kleine, niet-instelbare windowmanager -Comment[nn]=Ein liten vindaugssjef utan tilpassingar -Comment[pa]=ਇੱਕ ਹਲਕਾ ਨਾ-ਸੋਧਯੋਗ ਝਰੋਖਾ ਮੈਨੇਜਰ -Comment[pl]=Mały menedżer okien nie podlegający konfiguracji -Comment[pt]=Um gestor de janelas pequeno e não-configurável -Comment[pt_BR]=Um pequeno e não-configurável gerenciador de janelas -Comment[ro]=Un manager de ferestre mic, neconfigurabil -Comment[ru]=Маленький, не настраиваемый оконный менеджер -Comment[rw]=Mugenga Dirishya itabonezwa, ntoya -Comment[se]=Unna, ii heivehahtti lásegieđahalli -Comment[sk]=Malý, nenastaviteľný správca okien -Comment[sl]=Majhen, nenastavljiv okenski upravitelj -Comment[sr]=Мали, неподесиви менаџер прозора -Comment[sr@Latn]=Mali, nepodesivi menadžer prozora -Comment[sv]=Liten fönsterhanterare utan anpassningsmöjligheter -Comment[ta]=சிறிய, வடிவமைக்க முடியாத சாளர மேலாளர் -Comment[th]=ระบบจัดการหน้าที่ขนาดเล็ก ที่ไม่สามารถปรับแต่งอะไรได้ -Comment[tr]=Küçük ve yapılandırılamayan bir pencere yöneticisi -Comment[tt]=Caylanmí torğan keçkenä täräzä-idäräçe -Comment[uk]=Невеличкий менеджер вікон без можливості налаштування -Comment[uz]=Kichik, moslab boʻlmaydigan oyna boshqaruvchi -Comment[uz@cyrillic]=Кичик, мослаб бўлмайдиган ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ nhỏ, không cấu hình được -Comment[wa]=On ptit, nén apontiåve, manaedjeu di purneas -Comment[zh_CN]=小巧的不可配置的窗口管理器 -Comment[zh_TW]=一個小型且不可組態的視窗管理者 diff --git a/kdm/kfrontend/sessions/wmaker.desktop b/kdm/kfrontend/sessions/wmaker.desktop deleted file mode 100644 index fada3d3b5..000000000 --- a/kdm/kfrontend/sessions/wmaker.desktop +++ /dev/null @@ -1,82 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=wmaker -TryExec=wmaker -Name=WindowMaker -Name[bn]=উইণ্ডো-মেকার -Name[cy]=GwneuthuryddFfenestri (WindowMaker) -Name[eo]=Fenestroadministrilo -Name[hi]=विंडोमेकर -Name[ne]=सञ्झ्याल निर्माता -Name[pa]=ਝਰੋਖਾ-ਨਿਰਮਾਤਾ -Name[rw]=MukoraDirishya -Name[sv]=Windowmaker -Name[ta]=விண்டோஸ்மேக்கர் -Name[te]=విండొమెకర్ -Name[tg]=Созандаи тиреза -Comment=A simple window manager that resembles the NeXTStep look very closely -Comment[af]='n Eenvoudige venster bestuurder wat soos NeXTStep lyk -Comment[ar]=مدير نوافذ بسيط يمثّل مظهر NeXTStep بشكل قريب جداً -Comment[be]=Просты кіраўнік вокнаў, які вельмі дакладна паўтарае вонкавы выгляд NeXTStep -Comment[bn]=একটি উইণ্ডো ম্যানেজার যা ভীষণরকম NeXTStep-এর মত দেখতে -Comment[bs]=Jednostavan window manager koji vrlo dosljedno imitira NeXTStep izgled -Comment[ca]=Un gestor de finestres simple que s'assembla molt a l'aspecte de NeXTStep -Comment[cs]=Jendoduchý správce oken, který se velmi podobá NeXTStep -Comment[csb]=Prosti menedżer òknów szlachùjący za NeXTStep -Comment[cy]=Trefnydd ffenestri syml sy'n debyg iawn i'r golwg CamNesaf -Comment[da]=En simpel vindueshåndtering der ligner NeXTStep's udseende meget -Comment[de]=Einfacher Fenstermanager mit starker Ähnlichkeit zu NeXTStep -Comment[el]=Ένας απλός διαχειριστής παραθύρων που προσομοιώνει πολύ καλά το στυλ του NeXTStep -Comment[eo]=Simpla fenestroadministrilo -Comment[es]=Un gestor de ventanas sencillo cuyo aspecto se parece mucho al de NeXTStep -Comment[et]=Lihtne aknahaldur, mis meenutab väga tugevasti NeXTStepi -Comment[eu]=Leiho kudeatzaile sinplea, NeXTStep-en antz handia duena -Comment[fa]=یک مدیر پنجرۀ ساده که خیلی شبیه گام بعدی است -Comment[fi]=Yksinkertainen ikkunaohjelma, joka muistuttaa erittäin paljon NeXTStepiltä -Comment[fr]=Un gestionnaire de fenêtres simple qui ressemble assez précisement à NeXTStep -Comment[fy]=In ienfâldige finstersmanager dy it úterlik fan NeXTStep saer tichtby benaderd -Comment[gl]=Un xestor de fiestras sinxelo que se achega moito á apariencia de NeXTStep -Comment[he]=מנהל חלונות פשוט הדומה מאוד במראה שלו ל־NeXTStep -Comment[hi]=नेक्स्टस्टेप की तरह दिखने वाला सादा विंडो प्रबंधक -Comment[hr]=Jednostavan upravitelj prozora koji odražava vrlo blisko izgled NeXTStepa -Comment[hu]=Egy egyszerű ablakkezelő, megjelenése nagyon hasonlít a NeXTStephez -Comment[is]=Einfaldur gluggastjóri sem líkir vel eftir NeXTStep umhverfinu -Comment[it]=Un semplice window manager che assomiglia molto a NeXTStep. -Comment[ja]=NextStep にとてもよく似たシンプルなウィンドウマネージャ -Comment[ka]=NeXTStep -ის მაგვარი მარტივი ფანჯრის მენეჯერი -Comment[kk]=Қарапайым, NeXTStep-ке үқсас терезе менеджері -Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ធម្មតា​មួយ ដែល​ប្រហាក់ប្រហែល​នឹង​រូបរាង NeXTStep បំផុត -Comment[lt]=Paprasta langų tvarkyklė, išvaizda labai primenanti NeXTStep -Comment[lv]=Vienkāršs logu menedžeris, kas ir ļoti līdzīgs NeXTStep -Comment[mk]=Едноставен менаџер на прозорци кој е многу сличен на изгледот на NeXTStep -Comment[ms]=Pengurus tetingkap ringkas yang memasang NeXTStep dan menjadikannya tampak sangat hampir -Comment[mt]=Window manager li jixbaħ ħafna lil NextStep -Comment[nb]=En enkel vindusbehandler som ligner mye på NeXTStep -Comment[nds]=En eenfache Finsterpleger, de meist utsüht as NeXTStep -Comment[ne]=NeXTStep जस्तो देखिने साधारण सञ्झ्याल प्रबन्धक -Comment[nl]=Een eenvoudige windowmanager die het uiterlijk van NeXTStep zeer dicht benaderd -Comment[nn]=Ein enkel vindaugssjef som liknar mykje på NeXTStep -Comment[pa]=ਇੱਕ ਸਧਾਰਨ ਜੋ ਕਿ NeXTStep ਵਰਗਾ ਜਾਪਦਾ ਹੈ -Comment[pl]=Prosty menedżer okien przypominający bardzo wyglądem NeXTStep -Comment[pt]=Um gestor de janelas simples que faz lembrar bastante o visual do NeXTStep -Comment[pt_BR]=Um gerenciador de janelas simples, que lembra a aparência do NeXTStep -Comment[ro]=Un manager de ferestre simplu, care amintește foarte bine de aspectul NeXTStep -Comment[ru]=Простой оконный менеджер, воспроизводящий интерфейс NeXTStep -Comment[rw]=Mugenga Dirishya yoroheje ihuriza hamwe imboneko IntambweIkurikira byegeranye cyane -Comment[se]=Oktageardánis lásegieđahalli mii sulástahttá NeXTStep hui ollu -Comment[sk]=Jednoduchý správca okien, ktorý veľmi pripojíma NeXTStep -Comment[sl]=Preprost okenski upravitelj, ki zelo spominja na izgled NeXTStep -Comment[sr]=Једноставан менаџер прозора који одражава врло блиско изглед NeXTStep-а -Comment[sr@Latn]=Jednostavan menadžer prozora koji odražava vrlo blisko izgled NeXTStep-a -Comment[sv]=Enkel fönsterhanterare som mycket nära efterliknar Nextstep-utseendet -Comment[ta]=NeXTStep ஐ ஒத்த எளிய சாளர மேலாளார். -Comment[th]=ระบบจัดการหน้าต่างแบบเรียบง่าย ที่ดูคล้ายระบบ NeXTStep มากๆ -Comment[tr]=NeXTStep'e aşırı benzeyen basit bir masaüstü yöneticisi -Comment[tt]=NeXTStep küreneşendä ciñel täräzä-idäräçe -Comment[uk]=Простий менеджер вікон, що дуже нагадує NeXTStep -Comment[uz]=NeXTStep'ga juda oʻxshash oddiy oyna boshqaruvchi -Comment[uz@cyrillic]=NeXTStep'га жуда ўхшаш оддий ойна бошқарувчи -Comment[vi]=Trình quản lý cửa sổ giống với NeXTStep -Comment[wa]=On simpe manaedjeu di purneas avou l' foite rivnance di NeXTStep -Comment[zh_CN]=非常接近 NeXTStep 外观的简单窗口管理器 -Comment[zh_TW]=一個小型且與 NeXTStep 外觀很接近的視窗管理程式 diff --git a/kdm/kfrontend/sessions/xfce.desktop b/kdm/kfrontend/sessions/xfce.desktop deleted file mode 100644 index 6b199228b..000000000 --- a/kdm/kfrontend/sessions/xfce.desktop +++ /dev/null @@ -1,73 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=xfwm -TryExec=xfwm -Name=XFce -Name[eo]=Facoj -Name[hi]=एक्सएफसीई -Name[sv]=Xfce -Name[te]=ఎక్స్ ఎఫ్ సి ఈ -Comment=The Cholesterol Free Desktop Environment. A desktop environment reminiscent of CDE -Comment[af]=Die Cholesterol Gratis Werkskerm Omgewing. 'n Werkskerm omgewing wat op CDE gebaseer is -Comment[ar]=بيئة سطح المكتب الخالي من الكوليسترول، بيئة سطح مكتب مليئة بذكريات CDE -Comment[be]=XFCE - Cholesterol Free Desktop Environment. Працоўнае асяроддзе, падобнае на CDE -Comment[bn]=দি কলেস্টরল ফ্রী ডেস্কটপ এনভায়রনমেন্ট। CDE-র কথা মনে করিয়ে দেয় এমন একটি ডেস্কটপ এনভায়রনমেন্ট -Comment[bs]=Cholesterol Free Desktop Environment. Desktop okolina nalik na CDE -Comment[ca]=El Cholesterol Free Desktop Environment. Un entorn d'escriptori amb reminiscències de CDE -Comment[cs]=Svobodné grafické prostředí neobsahující cholesterol. Prostředí připomínající CDE -Comment[csb]=Òkrãże pùltu szlachùjące za CDE -Comment[cy]=Yr Amgylchedd Penbwrdd Di-Golesterol. Amgylchedd penbwrdd sy'n atgoffaol o CDE -Comment[da]=Det kolesterolfrie desktopmiljø. Et desktopmiljø der minder om CDE -Comment[de]=Cholesterol Free Desktop Environment. Graphische Arbeitsumgebung, die an CDE erinnert -Comment[el]=Το Cholesterol Free Desktop Environment. Ένα περιβάλλον επιφάνειας εργασίας βασισμένο στο CDE -Comment[eo]=La libera labortablo ĉirkaŭajo -Comment[es]=El Cholesterol Free Desktop Environment, un entorno de escritorio que recuerda a CDE -Comment[et]=Kolesteroolivaba töölaua keskkond, mis meenutab mitmeti CDE-d -Comment[eu]=Kolesterolik gabeko mahaigain ingurunea. CDE gogorarazten duen mahaigaina -Comment[fa]=محیط رومیزی آزاد Cholesterol. یادآور محیط رومیزی CDE -Comment[fi]=Cholesterol Free -työpöytäympäristö. CDE:tä muistuttavatyöpöytäympäristö. -Comment[fr]=The Cholesterol Free Desktop Environment. Un environnement de bureau rappelant CDE -Comment[fy]=The Cholesterol Free Desktop Environment. In buroblêd omwrâld die tinken dat oan CDE -Comment[gl]=O Cholesterol Free Desktop Environment. Un entorno de escritório reminiscente de CDE -Comment[he]=The Cholesterol Free Desktop Environment. סביבת עבודה המזכירה את CDE -Comment[hi]=कॉलेस्ट्रॉल रहित डेस्कटॉप माहौल. एक डेस्कटॉप माहौल जो सीडीई जैसा है -Comment[hr]=Cholesterol Free Desktop Environment - Okruženje radne površine koje podsjeća na CDE -Comment[hu]=Cholesterol Free Desktop Environment, egy a CDE-re emlékeztető ablakkezelő -Comment[is]=Kólesterol-lausa skjáborðsumhverfið. Skjáborð sem líkist CDE -Comment[it]=Il Cholesterol Free Desktop Environment. Un desktop environment che ricorda CDE -Comment[ja]=Cholesterol Free Desktop Environment, CDE を思わせる、むだのないデスクトップ環境 -Comment[ka]=CDE-ს მაგვარი სამუშაო დაფა ქოლესტერინის გარეშე -Comment[kk]=Cholesterol Free Desktop Environment. CDE-ге үқсас графикалық орта -Comment[km]=Cholesterol Free Desktop Environment ។ បរិស្ថាន​ផ្ទៃតុ​ដែល​សម្អាង​លើ CDE -Comment[lt]=Darbatalio aplinka „Be cholesterolio“. CDE primenanti darbastalio aplinka -Comment[lv]=Darbvirsmas vide bez holesterīna. Darba virsmas vide, kas atgādina CDE -Comment[mk]=Cholesterol Free Desktop Environment. Работна околина која потсетува на CDE -Comment[ms]=Persekitaran Desktop Bebas Kolesterol. Mengenang kembali persekitaran desktop CDE -Comment[mt]=Cholesterol Free Desktop Environment. Ambjent grafiku li jixbaħ lis-CDE -Comment[nb]=Det kolesterolfrie skrivebordsmiljø. Et skrivebordsmiljø som minner om CDE -Comment[nds]=De "Cholesterol Free Desktop Environment". En Schriefdisch-Ümgeven, de wat liek is to CDE -Comment[ne]=कोलेस्ट्रोल रहित डेस्कटप परिवेश । CDE को स्मरणशील डेस्कटप परिवेश -Comment[nl]=The Cholesterol Free Desktop Environment. Een desktop environment die herinnert aan CDE -Comment[nn]=Cholesterol Free Desktop Environment. Eit skrivebordsmiljø som minner om CDE -Comment[pa]=ਚੋਲੀਸਟੀਰੋਲ ਮੁਫਤ ਵਾਤਾਵਰਣ, ਇੱਕ CDE ਵਰਗਾ ਵਾਤਾਵਰਣ -Comment[pl]=Środowisko pulpitu przypominające CDE -Comment[pt]=O Cholesterol Free Desktop Environment. Um ambiente de trabalho com vestígios do CDE -Comment[pt_BR]=Acrônimo para Cholesterol Free Desktop Environment (ou ambiente livre de colesterol), um ambiente de trabalho remanescente do CDE -Comment[ro]=Cholesterol Free Desktop Environment. Un mediu grafic cu reminescente din CDE -Comment[ru]="Не содержащая холестерина" рабочая среда, напоминающая CDE -Comment[rw]=Ibikikije Ibiro Ubuntu Kolesiterole. Ibikikije ibiro nkumburwa bya CDE -Comment[se]=The Cholesterol Free Desktop Environment. Čállinbeavdebiras mii muittuha CDE -Comment[sk]=The Cholesterol Free Desktop Environment. Pracovné prostredie pripomínajúce CDE -Comment[sl]=Cholesterol Free Desktop Environment. Namizno okolje, podobno okolju CDE -Comment[sr]=„The Cholesterol Free Desktop Environment“. Радно окружење које подсећа на CDE -Comment[sr@Latn]=„The Cholesterol Free Desktop Environment“. Radno okruženje koje podseća na CDE -Comment[sv]=Den kolesterolfria skrivbordsmiljön. En skrivbordsmiljö som påminner om CDE -Comment[ta]=கொலஸ்ட்ரால் இல்லாத மேல்மேசை சூழல். CDE பொருள்பொதிந்த மேல்மேசை சூழல் -Comment[th]=สภาพแวดล้อมสำหรับเดสก์ทอปไร้คอเลสเตอรอล เป็นสภาพแวดล้อมสำหรับเดสก์ทอปที่เหลือมาจาก CDE -Comment[tr]=Cholesterol Masaüstü Ortamı -Comment[tt]=Holesterol Bulmağan Östäl Möxite. CDE küreneşendä -Comment[uk]=The Cholesterol Free Desktop Environment. Графічне середовище, що нагадує CDE -Comment[vi]=Môi trường Màn hình nền Không có Cholesterol. Một môi trường màn hình nền gợi nhớ lại CDE -Comment[wa]=Li Libe Evironmint di Scribanne Colesterole (Cholesterol Free Desktop Environment). On evironmint d' sicribanne ki nos vént d' CDE -Comment[zh_CN]=胆固醇自由桌面环境。CDE 桌面环境的追随者 -Comment[zh_TW]=Cholesterol 免費桌面環境。一個另人懷念的 CDE 桌面環境 diff --git a/kdm/kfrontend/sessions/xfce4.desktop b/kdm/kfrontend/sessions/xfce4.desktop deleted file mode 100644 index 11b4097a6..000000000 --- a/kdm/kfrontend/sessions/xfce4.desktop +++ /dev/null @@ -1,72 +0,0 @@ -[Desktop Entry] -Type=XSession -Exec=startxfce4 -TryExec=startxfce4 -Name=XFce 4 -Name[eo]=Facoj 4 -Name[hi]=एक्सएफसीई4 -Name[sv]=Xfce 4 -Name[te]=ఎక్స్ ఎఫ్ సి ఈ 4 -Comment=The Cholesterol Free Desktop Environment, version 4. A desktop environment reminiscent of CDE -Comment[af]=Die Cholesterol Gratis Werkskerm Omgewing, weergawe 4. 'n Werkskerm omgewing wat op CDE gebaseer is -Comment[be]=XFCE4 - Cholesterol Free Desktop Environment, version 4. Працоўнае асяроддзе, падобнае на CDE -Comment[bn]=দি কলেস্টরল ফ্রী ডেস্কটপ এনভায়রনমেন্ট, ৪র্থ সংস্করণ। CDE-র কথা মনে করিয়ে দেয় এমন একটি ডেস্কটপ এনভায়রনমেন্ট -Comment[bs]=Cholesterol Free Desktop Environment. Desktop okolina nalik na CDE -Comment[ca]=L'entorn d'escriptori sense colesterol, versió 4. Un entorn d'escriptori que recorda a CDE -Comment[cs]=Svobodné grafické prostředí neobsahující cholesterol verze 4. Prostředí připomínající CDE -Comment[csb]=Cholesterol Free Desktop Environment, wersëjô 4 - graficzné òkrãże szlachùjące za CDE -Comment[cy]=Yr Amgylchedd Penbwrdd Di-Golesterol, fersiwn 4. Amgylchedd penbwrdd sy'n atgoffaol o CDE -Comment[da]=Det kolesterolfrie desktopmiljø, version 4. Et desktopmiljø der minder om CDE -Comment[de]=Cholesterol Free Desktop Environment, Version 4. Benutzerumgebung in der Art von CDE -Comment[el]=Το Cholesterol Free Desktop Environment, έκδοση 4. Ένα περιβάλλον επιφάνειας εργασίας βασισμένο στο CDE -Comment[eo]=La libera labortablo ĉirkaŭajo 4 -Comment[es]=El Cholesterol Free Desktop Environment, versión 4. Un entorno de escritorio que recuerda a CDE -Comment[et]=Kolesteroolivaba töölaua keskkond (versioon 4), mis meenutab mitmeti CDE-d -Comment[eu]=Kolesterolik gabeko mahaigain ingurunea, 4 bertsioa. CDE gogorarazten duen mahaigaina -Comment[fa]=محیط رومیزی آزاد Cholesterol، نسخه ۴. یادآور محیط رومیزی CDE -Comment[fi]=Cholesterol Free -työpöytäympäristö. CDE:tä muistuttavatyöpöytäympäristö. -Comment[fr]=The Cholesterol Free Desktop Environment, version 4. Un environnement de bureau rappelant CDE -Comment[fy]=De Cholesterol Free Desktop Environment, ferzje 4. In buroblêd omwrâld die tinken dat oan CDE -Comment[gl]=O Cholesterol Free Desktop Environment, versión 4. Un entorno de escritório reminiscencia de CDE -Comment[he]=The Cholesterol Free Desktop Environment. גרסה 4, סביבת עבודה המזכירה את CDE -Comment[hi]=कोलेस्ट्रॉल मुक्त डेस्कटॉप वातावरण, संस्करण 4. सीडीई की याद दिलाता एक डेस्कटॉप वातावरण -Comment[hr]=Cholesterol Free Desktop Environment verzija 4 - Okruženje radne površine koje podsjeća na CDE -Comment[hu]=The Cholesterol Free Desktop Environment, 4-es verzió. Egy CDE-szerű ablakkezelő -Comment[is]=Kólesterol-lausa skjáborðsumhverfið, útgáfa 4. Skjáborð sem líkist CDE -Comment[it]=Il Cholesterol Free Desktop Environment, versione 4. Un desktop environment che ricorda CDE -Comment[ja]=Cholesterol Free Desktop Environment, version 4, CDE を思わせる、むだのないデスクトップ環境 -Comment[ka]=CDE-ს მაგვარი უქოლესტერინო სამუშაო დაფა xfce 4 -Comment[kk]=Cholesterol Free Desktop Environment, 4-нұсқа. CDE-ге ұқсас графикалық орта -Comment[km]=Cholesterol Free Desktop Environment កំណែ 4 ។ បរិស្ថាន​ផ្ទៃតុ​ដែល​សម្អាង​លើ CDE -Comment[lt]=Darbatalio aplinka „Be cholesterolio“ , 4 versija. CDE primenanti darbastalio aplinka -Comment[lv]=Darbvirsmas vide bez holesterīna, versija 4. Darbavirsmas vide, kas atgādina CDE -Comment[mk]=Cholesterol Free Desktop Environment, верзија 4. Работна околина која потсетува на CDE -Comment[ms]=Persekitaran Desktop Bebas Kolesterol, versi 4. Mengingatkan kembali persekitaran desktop CDE -Comment[mt]=Cholesterol Free Desktop Environment (v4). Ambjent grafiku li jixbaħ lis-CDE -Comment[nb]=Det kolesterolfrie skrivebordet, versjon 4. Et skrivebordsmiljø som minner om CDE -Comment[nds]=De "Cholesterol Free Desktop Environment", Verschoon 4. En Schriefdisch-Ümgeven, de wat liek is to CDE -Comment[ne]=कोलेस्ट्रोल रहित डेस्कटप परिवेश, संस्करण ४ । CDE को स्मरणशील डेस्कटप परिवेश -Comment[nl]=De Cholesterol Free Desktop Environment, versie 4. Een desktop environment die herinnert aan CDE -Comment[nn]=Cholesterol Free Desktop Environment. Eit skrivebordsmiljø som minner om CDE -Comment[pa]=ਚੋਲੀਸਟੀਰੋਲ ਮੁਫਤ ਵਾਤਾਵਰਣ, ਵਰਜਨ 4 ਇੱਕ CDE ਵਰਗਾ ਵਾਤਾਵਰਣ -Comment[pl]=Cholesterol Free Desktop Environment, wersja 4 - środowisko graficzne podobne do CDE. -Comment[pt]=O Cholesterol Free Desktop Environment, versão 4. Um ambiente de trabalho com vestígios do CDE -Comment[pt_BR]=Acrônimo para Cholesterol Free Desktop Environment (ou ambiente livre de colesterol), versão 4; um ambiente de trabalho remanescente do CDE -Comment[ro]=Cholesterol Free Desktop Environment, versiunea 4. Un mediu grafic cu reminescente din CDE -Comment[ru]="Не содержащая холестерина" рабочая среда xfce версии 4, напоминающая CDE -Comment[rw]=Ibikikije Ibiro Ubuntu Kolesiterole, verisiyo 4. Ibikikije ibiro nkumburwa bya CDE -Comment[se]=The Cholesterol Free Desktop Environment, version 4. Čállinbeavdebiras mii muittuha CDE -Comment[sk]=The Cholesterol Free Desktop Environment verzia 4. Pracovné prostredie pripomínajúce CDE -Comment[sl]=Cholesterol Free Desktop Environment, različica 4. Namizno okolje, podobno okolju CDE -Comment[sr]=„The Cholesterol Free Desktop Environment“ 4. издање. Радно окружење које подсећа на CDE -Comment[sr@Latn]=„The Cholesterol Free Desktop Environment“ 4. izdanje. Radno okruženje koje podseća na CDE -Comment[sv]=Den kolesterolfria skrivbordsmiljön, version 4. En skrivbordsmiljö som påminner om CDE -Comment[ta]=கொலஸ்ட்ரால் இல்லாத மேல்மேசை சூழல். பதிப்பு 4. CDE பொருள்பொதிந்த மேல்மேசை சூழல் -Comment[th]=สภาพแวดล้อมสำหรับเดสก์ทอปแบบไร้คอเลสเตอรอล เวอร์ชั่น 4 เป็นสภาพแวดล้อมสำหรับเดสก์ทอปที่เหลือมาจาก CDE -Comment[tr]=Cholesterol Ücretsiz Masaüstü Ortamı, sürüm 4. CDE'nin benzeri olan masaüstü ortamı -Comment[tt]=Holesterol Bulmağan Östäl Möxiteneñ 4. söreme. CDE küreneşendä -Comment[uk]=The Cholesterol Free Desktop Environment, версія 4. Графічне середовище, що нагадує CDE -Comment[vi]=Môi trường Màn hình nền Không có Cholesterol, phiên bản 4. Một môi trường màn hình nền gợi nhớ lại CDE -Comment[wa]=Li Libe Evironmint di Scribanne Colesterole (Cholesterol Free Desktop Environment), modêye 4. On evironmint d' sicribanne ki nos vént d' CDE -Comment[zh_CN]=胆固醇自由桌面环境,版本 4。CDE 桌面环境的追随者 -Comment[zh_TW]=Cholesterol 免費桌面環境,第 4 版。一個另人懷念的 CDE 桌面環境 diff --git a/kdm/kfrontend/themer/CMakeLists.txt b/kdm/kfrontend/themer/CMakeLists.txt deleted file mode 100644 index fc0b80fc3..000000000 --- a/kdm/kfrontend/themer/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/tdm/kfrontend - ${CMAKE_SOURCE_DIR}/tdmlib - ${TDE_INCLUDE_DIR} - ${TQT_INCLUDE_DIRS} -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - - -# FIXME this must be optimized -##### config.ci (generated) ##################### - -add_custom_command( OUTPUT config.ci - COMMAND perl -w ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def config.ci - DEPENDS ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def ) -set_property( SOURCE tdmthemer.cpp APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/config.ci ) - - -##### tdmthemer (static) ######################## - -tde_add_library( tdmthemer STATIC_PIC AUTOMOC - SOURCES - tdmthemer.cpp tdmitem.cpp tdmpixmap.cpp - tdmrect.cpp tdmlabel.cpp tdmlayout.cpp -) diff --git a/kdm/kfrontend/themer/Makefile.am b/kdm/kfrontend/themer/Makefile.am deleted file mode 100644 index f736795d6..000000000 --- a/kdm/kfrontend/themer/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -AM_CPPFLAGS = -I$(srcdir)/../../backend -I$(srcdir)/.. -I../.. \ - -I$(top_srcdir)/tdmlib \ - $(all_includes) - -noinst_LIBRARIES = libtdmthemer.a -libtdmthemer_a_SOURCES = \ - tdmthemer.cpp \ - tdmitem.cpp \ - tdmpixmap.cpp \ - tdmrect.cpp \ - tdmlabel.cpp \ - tdmlayout.cpp - -METASOURCES = AUTO - -libtdmthemer_a_COMPILE_FIRST = ../../config.ci diff --git a/kdm/kfrontend/themer/kdmitem.cpp b/kdm/kfrontend/themer/kdmitem.cpp deleted file mode 100644 index 8cf126b66..000000000 --- a/kdm/kfrontend/themer/kdmitem.cpp +++ /dev/null @@ -1,657 +0,0 @@ -/* - * Copyright (C) 2003 by Unai Garro - * Copyright (C) 2004 by Enrico Ros - * Copyright (C) 2004 by Stephan Kulow - * Copyright (C) 2004 by Oswald Buddenhagen - * - * 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. - */ - -/* - * Generic Kdm Item - */ - -// #define DRAW_OUTLINE 1 // for debugging only - -#include "tdmitem.h" -#include "tdmlayout.h" -#include "tdmconfig.h" - -#include -#include - -#include -#include -#include -#include -#include - -extern bool argb_visual_available; - -KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name ) - : TQObject( parent, name ) - , boxManager( 0 ) - , fixedManager( 0 ) - , image( 0 ) - , myWidget( 0 ) - , myLayoutItem( 0 ) - , buttonParent( 0 ) -{ - init(node, name); -} - - -KdmItem::KdmItem( TQWidget *parent, const TQDomNode &node, const char *name ) - : TQObject( parent, name ) - , boxManager( 0 ) - , fixedManager( 0 ) - , image( 0 ) - , myWidget( 0 ) - , myLayoutItem( 0 ) - , buttonParent( 0 ) -{ - init(node, name); -} - -void -KdmItem::init( const TQDomNode &node, const char * ) -{ - // Set default layout for every item - currentManager = MNone; - pos.x = pos.y = 0; - pos.width = pos.height = 1; - pos.xType = pos.yType = pos.wType = pos.hType = DTnone; - pos.anchor = "nw"; - m_backgroundModifier = 255; - - isShown = InitialHidden; - - // Set defaults for derived item's properties - properties.incrementalPaint = false; - state = Snormal; - - // The "toplevel" node (the screen) is really just like a fixed node - if (!parent() || !parent()->inherits( "KdmItem" )) { - setFixedLayout(); - return; - } - // Read the mandatory Pos tag. Other tags such as normal, prelighted, - // etc.. are read under specific implementations. - TQDomNodeList childList = node.childNodes(); - for (uint nod = 0; nod < childList.count(); nod++) { - TQDomNode child = childList.item( nod ); - TQDomElement el = child.toElement(); - TQString tagName = el.tagName(), attr; - - if (tagName == "pos") { - parseAttribute( el.attribute( "x", TQString::null ), pos.x, pos.xType ); - parseAttribute( el.attribute( "y", TQString::null ), pos.y, pos.yType ); - parseAttribute( el.attribute( "width", TQString::null ), pos.width, pos.wType ); - parseAttribute( el.attribute( "height", TQString::null ), pos.height, pos.hType ); - pos.anchor = el.attribute( "anchor", "nw" ); - } - - if (tagName == "bgmodifier") { - m_backgroundModifier = TQString(el.attribute( "value", "255" )).toInt(); - } - } - - TQDomNode tnode = node; - id = tnode.toElement().attribute( "id", TQString::number( (ulong)this, 16 ) ); - - // Tell 'parent' to add 'me' to its children - KdmItem *parentItem = static_cast( parent() ); - parentItem->addChildItem( this ); -} - -KdmItem::~KdmItem() -{ - delete boxManager; - delete fixedManager; - delete image; -} - -void -KdmItem::update() -{ -} - -void -KdmItem::needUpdate() -{ - emit needUpdate( area.x(), area.y(), area.width(), area.height() ); -} - -void -KdmItem::show( bool force ) -{ - if (isShown != InitialHidden && !force) - return; - - TQValueList::Iterator it; - for (it = m_children.begin(); it != m_children.end(); ++it) - (*it)->show(); - - isShown = Shown; - - if (myWidget) - myWidget->show(); - // XXX showing of layouts not implemented, prolly pointless anyway - - needUpdate(); -} - -void -KdmItem::hide( bool force ) -{ - if (isShown == ExplicitlyHidden) - return; - - if (isShown == InitialHidden && force) { - isShown = ExplicitlyHidden; - return; // no need for further action - } - - TQValueList::Iterator it; - for (it = m_children.begin(); it != m_children.end(); ++it) - (*it)->hide(); - - isShown = force ? ExplicitlyHidden : InitialHidden; - - if (myWidget) - myWidget->hide(); - // XXX hiding of layouts not implemented, prolly pointless anyway - - needUpdate(); -} - -void -KdmItem::inheritFromButton( KdmItem *button ) -{ - if (button) - buttonParent = button; - - TQValueList::Iterator it; - for (it = m_children.begin(); it != m_children.end(); ++it) - (*it)->inheritFromButton( button ); -} - -KdmItem * -KdmItem::findNode( const TQString &_id ) const -{ - if (id == _id) - return const_cast( this ); - - TQValueList::ConstIterator it; - for (it = m_children.begin(); it != m_children.end(); ++it) { - KdmItem *t = (*it)->findNode( _id ); - if (t) - return t; - } - - return 0; -} - -void -KdmItem::setWidget( TQWidget *widget ) -{ -// delete myWidget; -- themer->widget() owns the widgets - - myWidget = widget; - if (isHidden()) - myWidget->hide(); - else - myWidget->show(); - - // Remove borders so that it blends nicely with the theme background - TQFrame* frame = ::tqqt_cast( widget ); - if (frame) - frame->setFrameStyle( TQFrame::NoFrame ); - - setGeometry(area, true); - - connect( myWidget, TQT_SIGNAL(destroyed()), TQT_SLOT(widgetGone()) ); -} - -void -KdmItem::widgetGone() -{ - myWidget = 0; -} - -void -KdmItem::setLayoutItem( TQLayoutItem *item ) -{ - myLayoutItem = item; - // XXX hiding not supported - it think it's pointless here - if (myLayoutItem->widget()) - connect( myLayoutItem->widget(), TQT_SIGNAL(destroyed()), - TQT_SLOT(layoutItemGone()) ); - else if (myLayoutItem->layout()) - connect( myLayoutItem->layout(), TQT_SIGNAL(destroyed()), - TQT_SLOT(layoutItemGone()) ); -} - -void -KdmItem::layoutItemGone() -{ - myLayoutItem = 0; -} - -/* This is called as a result of KdmLayout::update, and directly on the root */ -void -KdmItem::setGeometry( const TQRect &newGeometry, bool force ) -{ - kdDebug() << " KdmItem::setGeometry " << id << newGeometry << endl; - // check if already 'in place' - if (!force && area == newGeometry) - return; - - area = newGeometry; - - if (myWidget) { - TQRect widGeo = newGeometry; - if ( widGeo.height() > myWidget->maximumHeight() ) { - widGeo.moveTop( widGeo.top() + ( widGeo.height() - myWidget->maximumHeight() ) / 2 ); - widGeo.setHeight( myWidget->maximumHeight() ); - } - myWidget->setGeometry( widGeo ); - } - if (myLayoutItem) - myLayoutItem->setGeometry( newGeometry ); - - // recurr to all boxed children - if (boxManager && !boxManager->isEmpty()) - boxManager->update( newGeometry, force ); - - // recurr to all fixed children - if (fixedManager && !fixedManager->isEmpty()) - fixedManager->update( newGeometry, force ); - - // TODO send *selective* repaint signal -} - -void -KdmItem::paint( TQPainter *p, const TQRect &rect ) -{ - if (isHidden()) - return; - - if (myWidget || (myLayoutItem && myLayoutItem->widget())) { - // KListView because it's missing a Q_OBJECT' - // FIXME: This is a nice idea in theory, but in practice it is - // very confusing for the user not to see the empty list box - // delineated from the rest of the greeter. - // Maybe set a darker version of the background instead of an exact copy? - if ( myWidget && myWidget->isA( "KListView" ) ) { - if ((_compositor.isEmpty()) || (!argb_visual_available)) { - // Software blend only (no compositing support) - TQPixmap copy( myWidget->size() ); - kdDebug() << myWidget->geometry() << " " << area << " " << myWidget->size() << endl; - bitBlt( ©, TQPoint( 0, 0), p->device(), myWidget->geometry(), TQt::CopyROP ); - // Lighten it slightly - TQImage lightVersion; - lightVersion = copy.convertToImage(); - - register uchar * r = lightVersion.bits(); - register uchar * g = lightVersion.bits() + 1; - register uchar * b = lightVersion.bits() + 2; - uchar * end = lightVersion.bits() + lightVersion.numBytes(); - - while ( r != end ) { - if ((*r) < (255-m_backgroundModifier)) - *r = (uchar) (*r) + m_backgroundModifier; - else - *r = 255; - if ((*g) < (255-m_backgroundModifier)) - *g = (uchar) (*g) + m_backgroundModifier; - else - *g = 255; - if ((*b) < (255-m_backgroundModifier)) - *b = (uchar) (*b) + m_backgroundModifier; - else - *b = 255; - r += 4; - g += 4; - b += 4; - } - - copy = lightVersion; - // Set it - myWidget->setPaletteBackgroundPixmap( copy ); - } - else { - // We have compositing support! - TQRgb blend_color = tqRgba(m_backgroundModifier, m_backgroundModifier, m_backgroundModifier, 0); // RGBA overlay - float alpha = tqAlpha(blend_color) / 255.; - int pixel = tqAlpha(blend_color) << 24 | - int(tqRed(blend_color) * alpha) << 16 | - int(tqGreen(blend_color) * alpha) << 8 | - int(tqBlue(blend_color) * alpha); - - TQImage img( myWidget->size(), 32 ); - img = img.convertDepth(32); - img.setAlphaBuffer(true); - register uchar * rd = img.bits(); - for( int y = 0; y < img.height(); ++y ) - { - for( short int x = 0; x < img.width(); ++x ) - { - *reinterpret_cast(rd) = blend_color; - rd += 4; - } - } - myWidget->setPaletteBackgroundPixmap( img ); - } - } - return; - } - - if (area.intersects( rect )) { - TQRect contentsRect = area.intersect( rect ); - contentsRect.moveBy( QMIN( 0, -area.x() ), QMIN( 0, -area.y() ) ); - drawContents( p, contentsRect ); - } - -#ifdef DRAW_OUTLINE - // Draw bounding rect for this item - p->setPen( Qt::white ); - p->drawRect( area ); -#endif - - if (myLayoutItem) - return; - - // Dispatch paint events to children - TQValueList::Iterator it; - for (it = m_children.begin(); it != m_children.end(); ++it) - (*it)->paint( p, rect ); - - -} - -KdmItem *KdmItem::currentActive = 0; - -void -KdmItem::mouseEvent( int x, int y, bool pressed, bool released ) -{ - if (isShown == ExplicitlyHidden) - return; - - if (buttonParent && buttonParent != this) { - buttonParent->mouseEvent( x, y, pressed, released ); - return; - } - - ItemState oldState = state; - if (area.contains( x, y )) { - if (released && oldState == Sactive) { - if (buttonParent) - emit activated( id ); - state = Sprelight; - currentActive = 0; - } else if (pressed || currentActive == this) { - state = Sactive; - currentActive = this; - } else if (!currentActive) - state = Sprelight; - else - state = Snormal; - } else { - if (released) - currentActive = 0; - if (currentActive == this) - state = Sprelight; - else - state = Snormal; - } - - if (!buttonParent) { - TQValueList::Iterator it; - for (it = m_children.begin(); it != m_children.end(); ++it) - (*it)->mouseEvent( x, y, pressed, released ); - } - - if (oldState != state) - statusChanged(); -} - -void -KdmItem::statusChanged() -{ - if (buttonParent == this) { - TQValueList::Iterator it; - for (it = m_children.begin(); it != m_children.end(); ++it) { - (*it)->state = state; - (*it)->statusChanged(); - } - } -} - -// BEGIN protected inheritable - -TQSize -KdmItem::sizeHint() -{ - if (myWidget) - return myWidget->size(); - if (myLayoutItem) - return myLayoutItem->sizeHint(); - int w = pos.wType == DTpixel ? kAbs( pos.width ) : -1, - h = pos.hType == DTpixel ? kAbs( pos.height ) : -1; - return TQSize( w, h ); -} - -TQRect -KdmItem::placementHint( const TQRect &parentRect ) -{ - TQSize hintedSize = sizeHint(); - TQSize boxHint; - - int x = parentRect.left(), - y = parentRect.top(), - w = parentRect.width(), - h = parentRect.height(); - - kdDebug() << timestamp() << " KdmItem::placementHint parentRect=" << parentRect << " hintedSize=" << hintedSize << endl; - - // check if width or height are set to "box" - if (pos.wType == DTbox || pos.hType == DTbox) { - if (myLayoutItem || myWidget) - boxHint = hintedSize; - else { - if (!boxManager) - return parentRect; - boxHint = boxManager->sizeHint(); - } - kdDebug() << timestamp() << " boxHint " << boxHint << endl; - } - - if (pos.xType == DTpixel) - x += pos.x; - else if (pos.xType == DTnpixel) - x = parentRect.right() - pos.x; - else if (pos.xType == DTpercent) - x += tqRound( parentRect.width() / 100.0 * pos.x ); - - if (pos.yType == DTpixel) - y += pos.y; - else if (pos.yType == DTnpixel) - y = parentRect.bottom() - pos.y; - else if (pos.yType == DTpercent) - y += tqRound( parentRect.height() / 100.0 * pos.y ); - - if (pos.wType == DTpixel) - w = pos.width; - else if (pos.wType == DTnpixel) - w -= pos.width; - else if (pos.wType == DTpercent) - w = tqRound( parentRect.width() / 100.0 * pos.width ); - else if (pos.wType == DTbox) - w = boxHint.width(); - else if (hintedSize.width() > 0) - w = hintedSize.width(); - else - w = 0; - - if (pos.hType == DTpixel) - h = pos.height; - else if (pos.hType == DTnpixel) - h -= pos.height; - else if (pos.hType == DTpercent) - h = tqRound( parentRect.height() / 100.0 * pos.height ); - else if (pos.hType == DTbox) - h = boxHint.height(); - else if (hintedSize.height() > 0) { - if (w && pos.wType != DTnone) - h = (hintedSize.height() * w) / hintedSize.width(); - else - h = hintedSize.height(); - } else - h = 0; - - // we choose to take the hinted size, but it's better to listen to the aspect ratio - if (pos.wType == DTnone && pos.hType != DTnone && h && w) { - w = tqRound(float(hintedSize.width() * h) / hintedSize.height()); - } - - // defaults to center - int dx = -w / 2, dy = -h / 2; - - // anchor the rect to an edge / corner - if (pos.anchor.length() > 0 && pos.anchor.length() < 3) { - if (pos.anchor.find( 'n' ) >= 0) - dy = 0; - if (pos.anchor.find( 's' ) >= 0) - dy = -h; - if (pos.anchor.find( 'w' ) >= 0) - dx = 0; - if (pos.anchor.find( 'e' ) >= 0) - dx = -w; - } - // KdmItem *p = static_cast( parent() ); - kdDebug() << timestamp() << " placementHint " << this << " x=" << x << " dx=" << dx << " w=" << w << " y=" << y << " dy=" << dy << " h=" << h << " " << parentRect << endl; - y += dy; - x += dx; - - // Note: no clipping to parent because this broke many themes! - return TQRect( x, y, w, h ); -} - -// END protected inheritable - - -void -KdmItem::addChildItem( KdmItem *item ) -{ - m_children.append( item ); - switch (currentManager) { - case MNone: // fallback to the 'fixed' case - setFixedLayout(); - case MFixed: - fixedManager->addItem( item ); - break; - case MBox: - boxManager->addItem( item ); - break; - } - - // signal bounce from child to parent - connect( item, TQT_SIGNAL(needUpdate( int, int, int, int )), TQT_SIGNAL(needUpdate( int, int, int, int )) ); - connect( item, TQT_SIGNAL(activated( const TQString & )), TQT_SIGNAL(activated( const TQString & )) ); -} - -void -KdmItem::parseAttribute( const TQString &s, int &val, enum DataType &dType ) -{ - if (s.isEmpty()) - return; - - int p; - if (s == "box") { // box value - dType = DTbox; - val = 0; - } else if ((p = s.find( '%' )) >= 0) { // percent value - dType = DTpercent; - TQString sCopy = s; - sCopy.remove( p, 1 ); - sCopy.replace( ',', '.' ); - val = (int)sCopy.toDouble(); - } else { // int value - dType = DTpixel; - TQString sCopy = s; - if (sCopy.at( 0 ) == '-') { - sCopy.remove( 0, 1 ); - dType = DTnpixel; - } - sCopy.replace( ',', '.' ); - val = (int)sCopy.toDouble(); - } -} - -void -KdmItem::parseFont( const TQString &s, TQFont &font ) -{ - int splitAt = s.findRev( ' ' ); - if (splitAt < 1) - return; - font.setFamily( s.left( splitAt ) ); - int fontSize = s.mid( splitAt + 1 ).toInt(); - if (fontSize > 1) - font.setPointSize( fontSize ); -} - -void -KdmItem::parseColor( const TQString &s, TQColor &color ) -{ - if (s.at( 0 ) != '#') - return; - bool ok; - TQString sCopy = s; - int hexColor = sCopy.remove( 0, 1 ).toInt( &ok, 16 ); - if (ok) - color.setRgb( hexColor ); -} - -void -KdmItem::setBoxLayout( const TQDomNode &node ) -{ - if (!boxManager) - boxManager = new KdmLayoutBox( node ); - currentManager = MBox; -} - -void -KdmItem::setFixedLayout( const TQDomNode &node ) -{ - if (!fixedManager) - fixedManager = new KdmLayoutFixed( node ); - currentManager = MFixed; -} - -TQWidget * -KdmItem::parentWidget() const -{ - if (myWidget) - return myWidget; - if (!this->parent()) - return 0; - - if (parent()->qt_cast(TQWIDGET_OBJECT_NAME_STRING)) - return (TQWidget*)parent(); - return ((KdmItem*)parent())->parentWidget(); -} - -#include "tdmitem.moc" diff --git a/kdm/kfrontend/themer/kdmitem.h b/kdm/kfrontend/themer/kdmitem.h deleted file mode 100644 index 27158a7fd..000000000 --- a/kdm/kfrontend/themer/kdmitem.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2003 by Unai Garro - * Copyright (C) 2004 by Enrico Ros - * Copyright (C) 2004 by Stephan Kulow - * Copyright (C) 2004 by Oswald Buddenhagen - * - * 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. - */ - -#ifndef TDMITEM_H -#define TDMITEM_H - -#include -#include -#include -#include - -class KdmItem; -class KdmLayoutBox; -class KdmLayoutFixed; - -class TQPainter; -class TQLayoutItem; - -/** class KdmItem - * @short Base class for every tdmthemes' element. - * - * This class provides methods for arranging it and its children to the - * screen (see note below), painting the whole area or a sub-region using - * an opened painter, handling mouse events or events in general dispatching - * them to children and sending some signals to the root (for example on - * mouse click). - * - * KdmItem sits in a hierarchical top to bottom tree with signals that - * traverse the tree back from leafs (or inner nodes) to the root. - * - * To implement a KdmItem only a few virtual protected methods must be - * reimplemented, other virtual functions are there for convenience only - - * the default implementation should satisfy your needs. - */ - -/** - * A note on layouting - how does it work? - * - setgeometry is called by parent (passing the new geometry) - * - item changes its geometry - * - if item embeds a widget, reposition it too - * - call children's box manager. box->update( my geom ) - * - sum up the whole space taken by children (via *hint calls) if - * needed for box width / height computation. note that the computed - * geometry should be equal or similar to parent's geometry. - * - pad the rectangle bounding box' contents - * - for every child - * - if vertical - * ( use a top-to-bottom insertion, spacing insertion lines by - * children's individual height ) - * - set up a zero height Parent (placed at the insertion line's - * position) and get Geom = child->placementHint( p ) - * - set up child's Size using Parent's width and Geom's height. - * - call to child->setGeometry( Parent.topLeft, Size ) - * - if horizontal - * - flows like the vertical one but uses a left-to-right insertion - * and insertion entry points are vertical lines - * - call to children's fix manager. fixed->update( my geom ) - * - for every child - * - S = get child's geometry hint (and we'll give item the whole - * space it needs, without constraints) - * - call to child->setGeometry( S ) - * - TODO: send a selective redraw signal also merging children's areas - */ - -class KdmItem : public TQObject { - Q_OBJECT - - friend class KdmThemer; - -public: - /** - * Item constructor and destructor - */ - KdmItem( KdmItem *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 ); - KdmItem( TQWidget *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 ); // for the root - - virtual ~KdmItem(); - - /** - * Fixup the geometry of an item and its children (even if fixed - * or boxed ones). Note that this will generate repaint signals - * when needed. The default implementation should fit all needs. - */ - virtual void setGeometry( const TQRect &newGeometry, bool force ); - - /** - * Paint the item and its children using the given painter. - * This is the compositing core function. It buffers paint operations - * to speed up rendering of dynamic objects. - */ - void paint( TQPainter *painter, const TQRect &boundaries ); - - /** - * Update representation of contents and repaint. - */ - virtual void update(); - - /** - * Handle mouse motion and dispatch events to children. This - * leads to items prelighting, activation() on click and more.. - */ - void mouseEvent( int x, int y, bool pressed = false, bool released = false ); - - /** - * Similar to sizeHint(..), this returns the area of the item - * given the @p parentGeometry. The default implementation - * takes into account geometric constraints and layoutings. - * @param parentGeometry the geometry of the caller item or a - * null rect if the geometry of the parent is not yet defined. - */ - virtual TQRect placementHint( const TQRect &parentGeometry ); - - /** - * Create the box layout manager; next children will be - * managed by the box layouter - */ - void setBoxLayout( const TQDomNode &node = TQDomNode() ); - - /** - * Create the fixed layout manager; next children will be - * in fixed position relative to this item - */ - void setFixedLayout( const TQDomNode &node = TQDomNode() ); - - TQString type() const { return itemType; } - void setType( const TQString &t ) { itemType = t; } - void setBaseDir( const TQString &bd ) { basedir = bd; } - - TQString baseDir() const - { - if (basedir.isEmpty() && parent()) - return static_cast( parent()->qt_cast( "KdmItem" ) )->baseDir(); - return basedir; - } - - KdmItem *findNode( const TQString &id ) const; - virtual void setWidget( TQWidget *widget ); - TQWidget *widget() const { return myWidget; } - virtual void setLayoutItem( TQLayoutItem *item ); - - virtual void hide( bool force = false ); - virtual void show( bool force = false ); - - bool isHidden() const { return isShown != Shown; } - bool isExplicitlyHidden() const { return isShown == ExplicitlyHidden; } - TQRect rect() const { return area; } - - TQWidget *parentWidget() const; - TQString getId() const { return id; } - -signals: - void needUpdate( int x, int y, int w, int h ); - void activated( const TQString &id ); - -protected slots: - void widgetGone(); - void layoutItemGone(); - -protected: - /** - * Returns the optimal/minimal size for this item. - * This should be reimplemented in items like label and pixmap. - * @return (-1,-1) if no size can be determined (so it should - * default to parent's size). - */ - virtual TQSize sizeHint(); - - /** - * Low level graphical function to paint the item. - * All items must reimplement this function to draw themeselves - * (or a part of) into the @p image keeping inside the @p rect . - * Try to do this as fast as possible. - * @param painter the painter to draw the item with - * @param region the part of the the image to render - */ - virtual void drawContents( TQPainter *painter, const TQRect ®ion ) = 0; - - /** - * Called when item changes its 'state' variable. This must - * handle item's repaint. - */ - virtual void statusChanged(); - - /** - * emits needUpdate( int, int, int, int ) with the full widget area. - */ - void needUpdate(); - - // This enum identifies in which state the item is - enum ItemState { Snormal, Sactive, Sprelight } state; - - static KdmItem *currentActive; - - // This struct can be filled in by derived items - struct { - bool incrementalPaint; - } properties; - - // This is the placement of the item - TQRect area; - - // This struct is filled in by KdmItem base class - enum DataType { DTnone, DTpixel, DTnpixel, DTpercent, DTbox }; - struct { - enum DataType xType, yType, wType, hType; - int x; - int y; - int width; - int height; - TQString anchor; - } pos; - - /* For internal use ONLY - * Add a child item. This function is called automatically - * when constructing an @p item with this as the parent. - */ - void addChildItem( KdmItem *item ); - - /* For internal use ONLY - * Parse type and value of an attribute (pos tag), a font or a - * color. - */ - void parseAttribute( const TQString &, int &, enum DataType & ); - void parseFont( const TQString &, TQFont & ); - void parseColor( const TQString &, TQColor & ); - - void inheritFromButton( KdmItem *button ); - void init( const TQDomNode &node = TQDomNode(), const char *name = 0 ); - - TQString itemType, id; - TQValueList m_children; - - int m_backgroundModifier; - - // Layouting related variables - enum { MNone = 0, MFixed = 1, MBox = 2 } currentManager; - KdmLayoutBox *boxManager; - KdmLayoutFixed *fixedManager; - - // Compositing related variables - TQImage *image; - - // defines the directory the theme is in (may be present in the parent) - TQString basedir; - - TQWidget *myWidget; - TQLayoutItem *myLayoutItem; - - enum { InitialHidden, ExplicitlyHidden, Shown } isShown; - - KdmItem *buttonParent; -}; - -#endif diff --git a/kdm/kfrontend/themer/kdmlabel.cpp b/kdm/kfrontend/themer/kdmlabel.cpp deleted file mode 100644 index 5239d48dc..000000000 --- a/kdm/kfrontend/themer/kdmlabel.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (C) 2003 by Unai Garro - * Copyright (C) 2004 by Enrico Ros - * Copyright (C) 2004 by Stephan Kulow - * Copyright (C) 2004 by Oswald Buddenhagen - * - * 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 -#include "tdmlabel.h" -#include "tdmconfig.h" -#include "../kgreeter.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#if !defined(HAVE_GETDOMAINNAME) && defined(HAVE_SYSINFO) -# include -#endif - -KdmLabel::KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name ) - : KdmItem( parent, node, name ), myAccel(0) -{ - itemType = "label"; - - // Set default values for label (note: strings are already Null) - label.active.color.setRgb( 0xFFFFFF ); - label.active.present = false; - label.prelight.present = false; - label.maximumWidth = -1; - - const TQString locale = KGlobal::locale()->language(); - - // Read LABEL ID - TQDomNode n = node; - TQDomElement elLab = n.toElement(); - // ID types: clock, pam-error, pam-message, pam-prompt, - // pam-warning, timed-label - label.id = elLab.attribute( "id", "" ); - label.hasId = !(label.id).isEmpty(); - - // Read LABEL TAGS - TQDomNodeList childList = node.childNodes(); - bool stockUsed = false; - for (uint nod = 0; nod < childList.count(); nod++) { - TQDomNode child = childList.item( nod ); - TQDomElement el = child.toElement(); - TQString tagName = el.tagName(); - - if (tagName == "pos") - label.maximumWidth = el.attribute( "max-width", "-1" ).toInt(); - else if (tagName == "normal") { - parseColor( el.attribute( "color", "#ffffff" ), label.normal.color ); - parseFont( el.attribute( "font", "Sans 14" ), label.normal.font ); - } else if (tagName == "active") { - label.active.present = true; - parseColor( el.attribute( "color", "#ffffff" ), label.active.color ); - parseFont( el.attribute( "font", "Sans 14" ), label.active.font ); - } else if (tagName == "prelight") { - label.prelight.present = true; - parseColor( el.attribute( "color", "#ffffff" ), label.prelight.color ); - parseFont( el.attribute( "font", "Sans 14" ), label.prelight.font ); - } else if (tagName == "text" && el.attributes().count() == 0 && !stockUsed) { - label.text = el.text(); - } else if (tagName == "text" && !stockUsed) { - TQString lang = el.attribute( "xml:lang", "" ); - if (lang == locale) - label.text = el.text(); - } else if (tagName == "stock") { - label.text = lookupStock( el.attribute( "type", "" ) ); - stockUsed = true; - } - } - - // Check if this is a timer label) - label.isTimer = label.text.find( "%c" ) >= 0; - if (label.isTimer) { - timer = new TQTimer( this ); - timer->start( 1000 ); - connect( timer, TQT_SIGNAL(timeout()), TQT_SLOT(update()) ); - } - setTextInt( lookupText( label.text ) ); -} - -void -KdmLabel::setTextInt( const TQString &txt) -{ - // TODO: catch && - cText = txt; - cAccel = txt.find('&'); - delete myAccel; - myAccel = 0; - if (cAccel != -1) { - cText.remove('&'); - myAccel = new TQAccel(parentWidget()); - myAccel->insertItem(ALT + UNICODE_ACCEL + cText.at(cAccel).lower().unicode()); - connect(myAccel, TQT_SIGNAL(activated(int)), TQT_SLOT(slotAccel())); - } -} - -void -KdmLabel::slotAccel() -{ - if (buttonParent) - emit activated(buttonParent->getId()); - else - emit activated(id); -} - -void -KdmLabel::setText( const TQString &txt ) -{ - label.text = txt; - setTextInt( lookupText( label.text ) ); -} - -TQSize -KdmLabel::sizeHint() -{ - // choose the correct label class - struct LabelStruct::LabelClass *l = &label.normal; - if (state == Sactive && label.active.present) - l = &label.active; - else if (state == Sprelight && label.prelight.present) - l = &label.prelight; - // get the hint from font metrics - TQSize hint = TQFontMetrics( l->font ).size( AlignLeft | SingleLine, cText ); - // clip the result using the max-width label(pos) parameter - if (label.maximumWidth > 0 && hint.width() > label.maximumWidth) - hint.setWidth( label.maximumWidth ); - return hint; -} - -void -KdmLabel::drawContents( TQPainter *p, const TQRect &/*r*/ ) -{ - // choose the correct label class - struct LabelStruct::LabelClass *l = &label.normal; - if (state == Sactive && label.active.present) - l = &label.active; - else if (state == Sprelight && label.prelight.present) - l = &label.prelight; - // draw the label - p->setFont( l->font ); - p->setPen( l->color ); - //TODO paint clipped (tested but not working..) - if (cAccel != -1 && (!id.isEmpty() || buttonParent) ) { - TQString left = cText.left(cAccel); - TQString right = cText.mid(cAccel + 1); - p->drawText( area, AlignLeft | SingleLine, left ); - TQRect tarea = area; - TQFontMetrics fm(l->font); - tarea.rLeft() += fm.width(left); - TQFont f(l->font); - f.setUnderline(true); - p->setFont ( f ); - p->drawText( tarea, AlignLeft | SingleLine, TQString(cText.at(cAccel))); - tarea.rLeft() += fm.width(cText.at(cAccel)); - p->setFont( l->font ); - p->drawText( tarea, AlignLeft | SingleLine, right); - } else { - p->drawText( area, AlignLeft | SingleLine, cText); - } -} - -void -KdmLabel::statusChanged() -{ - KdmItem::statusChanged(); - if (!label.active.present && !label.prelight.present) - return; - if ((state == Sprelight && !label.prelight.present) || - (state == Sactive && !label.active.present)) - return; - needUpdate(); -} - -void -KdmLabel::update() -{ - TQString text = lookupText( label.text ); - if (text != cText) { - setTextInt(text); - needUpdate(); - } -} - -static const struct { - const char *type, *text; -} stocks[] = { - { "language", I18N_NOOP("Language") }, - { "session", I18N_NOOP("Session Type") }, - { "system", I18N_NOOP("Menu") }, // i18n("Actions"); - { "admin", I18N_NOOP("&Administration") }, - { "disconnect", I18N_NOOP("Disconnect") }, - { "quit", I18N_NOOP("Quit") }, - { "halt", I18N_NOOP("Power Off") }, - { "suspend", I18N_NOOP("Suspend") }, - { "reboot", I18N_NOOP("Reboot") }, - { "chooser", I18N_NOOP("XDMCP Chooser") }, - { "config", I18N_NOOP("Configure") }, - { "caps-lock-warning", I18N_NOOP("Caps Lock is enabled.") }, - { "timed-label", I18N_NOOP("User %s will login in %d seconds") }, - { "welcome-label", I18N_NOOP("Welcome to %h") }, // _greetString - { "username-label", I18N_NOOP("Username:") }, - { "password-label", I18N_NOOP("Password:") }, - { "domain-label", I18N_NOOP("Domain:") }, - { "login", I18N_NOOP("Login") } -}; - -TQString -KdmLabel::lookupStock( const TQString &stock ) -{ - //FIXME add key accels! - TQString type( stock.lower() ); - - for (uint i = 0; i < sizeof(stocks)/sizeof(stocks[0]); i++) - if (type == stocks[i].type) - return i18n(stocks[i].text); - - kdDebug() << timestamp() << " Invalid element. Check your theme!" << endl; - return stock; -} - -TQString -KdmLabel::lookupText( const TQString &t ) -{ - TQString text = t; - - text.replace( '_', '&' ); - - TQMap m; - struct utsname uts; - uname( &uts ); - m['n'] = TQString::fromLocal8Bit( uts.nodename ); - char buf[256]; - buf[sizeof(buf) - 1] = '\0'; - m['h'] = gethostname( buf, sizeof(buf) - 1 ) ? "localhost" : TQString::fromLocal8Bit( buf ); -#ifdef HAVE_GETDOMAINNAME - m['o'] = getdomainname( buf, sizeof(buf) - 1 ) ? "localdomain" : TQString::fromLocal8Bit( buf ); -#elif defined(HAVE_SYSINFO) - m['o'] = (unsigned)sysinfo( SI_SRPC_DOMAIN, buf, sizeof(buf) ) > sizeof(buf) ? "localdomain" : TQString::fromLocal8Bit( buf ); -#endif - m['d'] = TQString::number( KThemedGreeter::timedDelay ); - m['s'] = KThemedGreeter::timedUser; - // xgettext:no-c-format - KGlobal::locale()->setDateFormat( i18n("date format", "%a %d %B") ); - m['c'] = KGlobal::locale()->formatDateTime( TQDateTime::currentDateTime(), false, false ); - - return KMacroExpander::expandMacros( text, m ); -} - -#include "tdmlabel.moc" diff --git a/kdm/kfrontend/themer/kdmlabel.h b/kdm/kfrontend/themer/kdmlabel.h deleted file mode 100644 index 8b955fca5..000000000 --- a/kdm/kfrontend/themer/kdmlabel.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2003 by Unai Garro - * Copyright (C) 2004 by Enrico Ros - * Copyright (C) 2004 by Stephan Kulow - * Copyright (C) 2004 by Oswald Buddenhagen - * - * 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. - */ - -#ifndef KDELABEL_H -#define KDELABEL_H - -#include "tdmitem.h" - -#include -#include - -class TQTimer; - -/* - * KdmLabel. A label element - */ - -class KdmLabel : public KdmItem { - Q_OBJECT - -public: - KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name = 0 ); - void setText( const TQString &txt ); - -protected: - // reimplemented; returns the minimum size of rendered text - virtual TQSize sizeHint(); - - // draw the label - virtual void drawContents( TQPainter *p, const TQRect &r ); - - // handle switching between normal / active / prelight configurations - virtual void statusChanged(); - -public: - struct LabelStruct { - TQString text; - bool isTimer; - bool hasId; - TQString id; - struct LabelClass { - TQColor color; - TQFont font; - bool present; - } normal, active, prelight; - int maximumWidth; - } label; - - TQTimer *timer; - -public slots: - void update(); - void slotAccel(); - -private: - /* Method to lookup the caption associated with an item */ - TQString lookupStock( const TQString &stock ); - - /* Lookup variables in the text */ - TQString lookupText( const TQString &t ); - - TQString cText; - int cAccel; - TQAccel *myAccel; - - void setTextInt(const TQString &); -}; - -#endif diff --git a/kdm/kfrontend/themer/kdmlayout.cpp b/kdm/kfrontend/themer/kdmlayout.cpp deleted file mode 100644 index 9a277a7a3..000000000 --- a/kdm/kfrontend/themer/kdmlayout.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2003 by Unai Garro - * Copyright (C) 2004 by Enrico Ros - * Copyright (C) 2004 by Stephan Kulow - * Copyright (C) 2004 by Oswald Buddenhagen - * - * 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 "tdmlayout.h" -#include "tdmconfig.h" -#include "tdmitem.h" - -#include - -#include -#include - -KdmLayoutFixed::KdmLayoutFixed( const TQDomNode &/*node*/ ) -{ - //Parsing FIXED parameters on 'node' [NONE!] -} - -void -KdmLayoutFixed::update( const TQRect &parentGeometry, bool force ) -{ - kdDebug() << timestamp() << " KdmLayoutFixed::update " << parentGeometry << endl; - - // I can't layout children if the parent rectangle is not valid - if (parentGeometry.width() < 0 || parentGeometry.height() < 0) { - kdDebug() << timestamp() << " invalid\n"; - return; - } - // For each child in list I ask their hinted size and set it! - for (TQValueList::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) - (*it)->setGeometry( (*it)->placementHint( parentGeometry ), force ); -} - -KdmLayoutBox::KdmLayoutBox( const TQDomNode &node ) -{ - //Parsing BOX parameters - TQDomNode n = node; - TQDomElement el = n.toElement(); - box.isVertical = el.attribute( "orientation", "vertical" ) != "horizontal"; - box.xpadding = el.attribute( "xpadding", "0" ).toInt(); - box.ypadding = el.attribute( "ypadding", "0" ).toInt(); - box.spacing = el.attribute( "spacing", "0" ).toInt(); - box.minwidth = el.attribute( "min-width", "0" ).toInt(); - box.minheight = el.attribute( "min-height", "0" ).toInt(); - box.homogeneous = el.attribute( "homogeneous", "false" ) == "true"; -} - -void -KdmLayoutBox::update( const TQRect &parentGeometry, bool force ) -{ - kdDebug() << this << " update " << parentGeometry << endl; - - // I can't layout children if the parent rectangle is not valid - if (!parentGeometry.isValid() || parentGeometry.isEmpty()) - return; - - // Check if box size was computed. If not compute it - // TODO check if this prevents updating changing items -// if (!hintedSize.isValid()) -// sizeHint(); - -// kdDebug() << this << " hintedSize " << hintedSize << endl; - - //XXX why was this asymmetric? it broke things big time. - TQRect childrenRect = /*box.isVertical ? TQRect( parentGeometry.topLeft(), hintedSize ) :*/ parentGeometry; - // Begin cutting the parent rectangle to attach children on the right place - childrenRect.addCoords( box.xpadding, box.ypadding, -box.xpadding, -box.ypadding ); - - kdDebug() << this << " childrenRect " << childrenRect << endl; - - // For each child in list ... - if (box.homogeneous) { - int ccnt = 0; - for (TQValueList::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) - if (!(*it)->isExplicitlyHidden()) - ccnt++; - int height = (childrenRect.height() - (ccnt - 1) * box.spacing) / ccnt; - int width = (childrenRect.width() - (ccnt - 1) * box.spacing) / ccnt; - - for (TQValueList::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) { - if ((*it)->isExplicitlyHidden()) - continue; - if (box.isVertical) { - TQRect temp( childrenRect.left(), childrenRect.top(), childrenRect.width(), height ); - (*it)->setGeometry( temp, force ); - childrenRect.setTop( childrenRect.top() + height + box.spacing ); - } else { - TQRect temp( childrenRect.left(), childrenRect.top(), width, childrenRect.height() ); - kdDebug() << timestamp() << " placement " << *it << " " << temp << " " << (*it)->placementHint( temp ) << endl; - temp = (*it)->placementHint( temp ); - (*it)->setGeometry( temp, force ); - childrenRect.setLeft( childrenRect.left() + width + box.spacing ); - } - } - } else { - for (TQValueList::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) { - if ((*it)->isExplicitlyHidden()) - continue; - - TQRect temp = childrenRect, itemRect; - if (box.isVertical) { - temp.setHeight( 0 ); - itemRect = (*it)->placementHint( temp ); - temp.setHeight( itemRect.height() ); - childrenRect.setTop( childrenRect.top() + itemRect.size().height() + box.spacing ); - } else { - temp.setWidth( 0 ); - itemRect = (*it)->placementHint( temp ); - kdDebug() << this << " placementHint " << *it << " " << temp << " " << itemRect << endl; - temp.setWidth( itemRect.width() ); - childrenRect.setLeft( childrenRect.left() + itemRect.size().width() + box.spacing ); - kdDebug() << timestamp() << " childrenRect after " << *it << " " << childrenRect << endl; - } - itemRect = (*it)->placementHint( temp ); - kdDebug() << this << " placementHint2 " << *it << " " << temp << " " << itemRect << endl; - (*it)->setGeometry( itemRect, force ); - } - } -} - -//FIXME truly experimental (is so close to greeter_geometry.c) -TQSize -KdmLayoutBox::sizeHint() -{ - // Sum up area taken by children - int w = 0, h = 0; - for (TQValueList::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) { - TQSize s = (*it)->placementHint( TQRect() ).size(); - if (box.isVertical) { - if (s.width() > w) - w = s.width(); - h += s.height(); - } else { - if (s.height() > h) - h = s.height(); - w += s.width(); - } - } - - // Add padding and items spacing - w += 2 * box.xpadding; - h += 2 * box.ypadding; - if (box.isVertical) - h += box.spacing * (m_children.count() - 1); - else - w += box.spacing * (m_children.count() - 1); - - // Make hint at least equal to minimum size (if set) - return TQSize( w < box.minwidth ? box.minwidth : w, - h < box.minheight ? box.minheight : h ); -} diff --git a/kdm/kfrontend/themer/kdmlayout.h b/kdm/kfrontend/themer/kdmlayout.h deleted file mode 100644 index c147fd329..000000000 --- a/kdm/kfrontend/themer/kdmlayout.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2003 by Unai Garro - * Copyright (C) 2004 by Enrico Ros - * Copyright (C) 2004 by Stephan Kulow - * Copyright (C) 2004 by Oswald Buddenhagen - * - * 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. - */ - -#ifndef TDMLAYOUT_H -#define TDMLAYOUT_H - -/** - * this is a container for a lot of other stuff - * but can be treated like a usual widget - */ - -#include -#include - -class KdmItem; - -class TQDomNode; -class TQRect; - -class KdmLayout { - -public: -// virtual ~KdmLayout() {}; - - // Adds an item that will be managed - void addItem( KdmItem *item ) { m_children.append( item ); } - - // Return false if any item are managed by this layouter - bool isEmpty() { return m_children.isEmpty(); } - - // Updates the layout of all items knowing that the parent - // has the @p parentGeometry geometry -// virtual void update( const TQRect &parentGeometry ) = 0; - -protected: - TQValueList m_children; -}; - -class KdmLayoutFixed : public KdmLayout { - -public: - KdmLayoutFixed( const TQDomNode &node ); - - // Updates the layout of all boxed items knowing that the parent - // has the @p parentGeometry geometry - void update( const TQRect &parentGeometry, bool force ); -}; - -/** - * this is a container for a lot of other stuff - * but can be treated like a usual widget - */ - -class KdmLayoutBox : public KdmLayout { - -public: - KdmLayoutBox( const TQDomNode &node ); - - // Updates the layout of all boxed items knowing that they - // should fit into @p parentGeometry container - void update( const TQRect &parentGeometry, bool force ); - - // Computes the size hint of the box, telling which is the - // smallest size inside which boxed items will fit - TQSize sizeHint(); - -private: - struct { - bool isVertical; - int spacing; - int xpadding; - int ypadding; - int minwidth; - int minheight; - bool homogeneous; - } box; -// TQSize hintedSize; -}; - -#endif diff --git a/kdm/kfrontend/themer/kdmpixmap.cpp b/kdm/kfrontend/themer/kdmpixmap.cpp deleted file mode 100644 index 7a8d1a3d2..000000000 --- a/kdm/kfrontend/themer/kdmpixmap.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (C) 2003 by Unai Garro - * Copyright (C) 2004 by Enrico Ros - * Copyright (C) 2004 by Stephan Kulow - * Copyright (C) 2004 by Oswald Buddenhagen - * - * 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 - -#include "tdmpixmap.h" -#include - -#include -#ifdef HAVE_LIBART -#include -#endif - -#include -#include - -#include -#include -#include -#include - -extern bool argb_visual_available; - -KdmPixmap::KdmPixmap( KdmItem *parent, const TQDomNode &node, const char *name ) - : KdmItem( parent, node, name ) -{ - itemType = "pixmap"; - - // Set default values for pixmap (note: strings are already Null) - pixmap.normal.tint.setRgb( 0x800000 ); - pixmap.normal.alpha = 0.0; - pixmap.active.present = false; - pixmap.prelight.present = false; - bool true_transparency = false; - - // Read PIXMAP ID - // it rarely happens that a pixmap can be a button too! - TQDomNode n = node; - TQDomElement elPix = n.toElement(); - - // Read PIXMAP TAGS - TQDomNodeList childList = node.childNodes(); - for (uint nod = 0; nod < childList.count(); nod++) { - TQDomNode child = childList.item( nod ); - TQDomElement el = child.toElement(); - TQString tagName = el.tagName(); - - if (tagName == "normal") { - pixmap.normal.fullpath = fullPath( el.attribute( "file", "" ) ); - parseColor( el.attribute( "tint", "#ffffff" ), pixmap.normal.tint ); - pixmap.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat(); - - if (el.attribute( "file", "" ) == "@@@TDMBACKGROUND@@@") { - if ((_compositor.isEmpty()) || (!argb_visual_available)) { - // Software blend only (no compositing support) - // Use the preset TDM background... - KStandardDirs *m_pDirs = KGlobal::dirs(); - KSimpleConfig *config = new KSimpleConfig( TQFile::decodeName( _backgroundCfg ) ); - config->setGroup("Desktop0"); - pixmap.normal.fullpath = m_pDirs->findResource("wallpaper", config->readPathEntry("Wallpaper")); - // TODO: Detect when there is no wallpaper and use the background settings instead - delete config; - } - else { - true_transparency = true; - pixmap.normal.alpha = 0.0; - } - } - - } else if (tagName == "active") { - pixmap.active.present = true; - pixmap.active.fullpath = fullPath( el.attribute( "file", "" ) ); - parseColor( el.attribute( "tint", "#ffffff" ), pixmap.active.tint ); - pixmap.active.alpha = el.attribute( "alpha", "1.0" ).toFloat(); - } else if (tagName == "prelight") { - pixmap.prelight.present = true; - pixmap.prelight.fullpath = fullPath(el.attribute( "file", "" ) ); - parseColor( el.attribute( "tint", "#ffffff" ), pixmap.prelight.tint ); - pixmap.prelight.alpha = el.attribute( "alpha", "1.0" ).toFloat(); - } - } - - // look if we have to have the aspect ratio ready - if (((pos.wType == DTnone && pos.hType != DTnone) || - (pos.wType != DTnone && pos.hType == DTnone) || - (pos.wType == DTnone && pos.hType == DTnone)) && - !pixmap.normal.fullpath.endsWith( ".svg" )) - loadPixmap( &pixmap.normal ); -} - -TQSize -KdmPixmap::sizeHint() -{ - // choose the correct pixmap class - PixmapStruct::PixmapClass * pClass = &pixmap.normal; - if (state == Sactive && pixmap.active.present) - pClass = &pixmap.active; - if (state == Sprelight && pixmap.prelight.present) - pClass = &pixmap.prelight; - // use the pixmap size as the size hint - if (!pClass->pixmap.isNull()) - return pClass->pixmap.size(); - return KdmItem::sizeHint(); -} - -void -KdmPixmap::setGeometry( const TQRect &newGeometry, bool force ) -{ - KdmItem::setGeometry( newGeometry, force ); - pixmap.active.readyPixmap.resize( 0, 0 ); - pixmap.prelight.readyPixmap.resize( 0, 0 ); - pixmap.normal.readyPixmap.resize( 0, 0 ); -} - - -TQString -KdmPixmap::fullPath( const TQString &fileName) -{ - if (fileName.isEmpty()) - return TQString::null; - - TQString fullName = fileName; - if (fullName.at( 0 ) != '/') - fullName = baseDir() + "/" + fileName; - return fullName; -} - -void -KdmPixmap::renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area ) -{ -#ifdef HAVE_LIBART - // Special stuff for SVG icons - KSVGIconEngine *svgEngine = new KSVGIconEngine(); - - if (svgEngine->load( area.width(), area.height(), pClass->fullpath )) { - TQImage *t = svgEngine->image(); - pClass->pixmap = *t; - pClass->readyPixmap.resize( 0, 0 ); - delete t; - } else { - kdWarning() << "failed to load " << pClass->fullpath << endl; - pClass->fullpath = TQString::null; - } - - delete svgEngine; -#else - Q_UNUSED(pClass); - Q_UNUSED(area); -#endif -} - -void -KdmPixmap::loadPixmap( PixmapStruct::PixmapClass *pClass ) -{ - TQString fullpath = pClass->fullpath; - - kdDebug() << timestamp() << " load " << fullpath << endl; - int index = fullpath.findRev('.'); - TQString ext = fullpath.right(fullpath.length() - index); - fullpath = fullpath.left(index); - kdDebug() << timestamp() << " ext " << ext << " " << fullpath << endl; - TQString testpath = TQString("-%1x%2").arg(area.width()).arg(area.height()) + ext; - kdDebug() << timestamp() << " testing for " << fullpath + testpath << endl; - if (KStandardDirs::exists(fullpath + testpath)) - pClass->pixmap.load(fullpath + testpath); - else - pClass->pixmap.load( fullpath + ext ); - kdDebug() << timestamp() << " done\n"; -} - -void -KdmPixmap::drawContents( TQPainter *p, const TQRect &r ) -{ - // choose the correct pixmap class - PixmapStruct::PixmapClass *pClass = &pixmap.normal; - if (state == Sactive && pixmap.active.present) - pClass = &pixmap.active; - if (state == Sprelight && pixmap.prelight.present) - pClass = &pixmap.prelight; - - kdDebug() << "draw " << id << " " << pClass->pixmap.isNull() << endl; - - if (pClass->pixmap.isNull()) { - if (pClass->fullpath.isEmpty()) // if neither is set, we're empty - return; - - if (!pClass->fullpath.endsWith( ".svg" ) ) { - loadPixmap(pClass); - } else { - kdDebug() << timestamp() << " renderSVG\n"; - renderSvg( pClass, area ); - kdDebug() << timestamp() << " done\n"; - } - } - - int px = area.left() + r.left(); - int py = area.top() + r.top(); - int sx = r.x(); - int sy = r.y(); - int sw = r.width(); - int sh = r.height(); - if (px < 0) { - px *= -1; - sx += px; - px = 0; - } - if (py < 0) { - py *= -1; - sy += py; - py = 0; - } - - - if (pClass->readyPixmap.isNull()) { - - bool haveTint = pClass->tint.rgb() != 0xFFFFFF; - bool haveAlpha = pClass->alpha < 1.0; - - TQImage scaledImage; - - // use the loaded pixmap or a scaled version if needed - - kdDebug() << timestamp() << " prepare readyPixmap " << pClass->fullpath << " " << area.size() << " " << pClass->pixmap.size() << endl; - if (area.size() != pClass->pixmap.size()) { - if (pClass->fullpath.endsWith( ".svg" )) { - kdDebug() << timestamp() << " renderSVG\n"; - renderSvg( pClass, area ); - scaledImage = pClass->pixmap.convertToImage(); - } else { - kdDebug() << timestamp() << " convertFromImage smoothscale\n"; - if (pClass->pixmap.isNull()) { - scaledImage = TQImage(); - } - else { - TQImage tempImage = pClass->pixmap.convertToImage(); - kdDebug() << timestamp() << " convertToImage done\n"; - scaledImage = tempImage.smoothScale( area.width(), area.height() ); - } - kdDebug() << timestamp() << " done\n"; - } - } else { - if (haveTint || haveAlpha) - { - scaledImage = pClass->pixmap.convertToImage(); - // enforce rgba values for the latter - if (!scaledImage.isNull()) scaledImage = scaledImage.convertDepth( 32 ); - } - else - pClass->readyPixmap = pClass->pixmap; - } - - if (haveTint || haveAlpha) { - // blend image(pix) with the given tint - - if (!scaledImage.isNull()) scaledImage = scaledImage.convertDepth( 32 ); - int w = scaledImage.width(); - int h = scaledImage.height(); - float tint_red = float( pClass->tint.red() ) / 255; - float tint_green = float( pClass->tint.green() ) / 255; - float tint_blue = float( pClass->tint.blue() ) / 255; - float tint_alpha = pClass->alpha; - - for (int y = 0; y < h; ++y) { - QRgb *ls = (QRgb *)scaledImage.scanLine( y ); - for (int x = 0; x < w; ++x) { - QRgb l = ls[x]; - int r = int( tqRed( l ) * tint_red ); - int g = int( tqGreen( l ) * tint_green ); - int b = int( tqBlue( l ) * tint_blue ); - int a = int( tqAlpha( l ) * tint_alpha ); - ls[x] = tqRgba( r, g, b, a ); - } - } - } - if ((_compositor.isEmpty()) || (!argb_visual_available)) { - // Software blend only (no compositing support) - } - else { - // We have a compositor! - // Apply the alpha in the same manner as above, exept we are now - // using the hardware blending engine for all painting - scaledImage = pClass->readyPixmap; - if (!scaledImage.isNull()) scaledImage = scaledImage.convertDepth( 32 ); - int w = scaledImage.width(); - int h = scaledImage.height(); - - for (int y = 0; y < h; ++y) { - QRgb *ls = (QRgb *)scaledImage.scanLine( y ); - for (int x = 0; x < w; ++x) { - QRgb l = ls[x]; - float alpha_adjust = (tqAlpha( l )/256.0); - int r = int( tqRed( l ) * alpha_adjust ); - int g = int( tqGreen( l ) * alpha_adjust ); - int b = int( tqBlue( l ) * alpha_adjust ); - int a = int( tqAlpha( l ) * 1 ); - ls[x] = tqRgba( r, g, b, a ); - } - } - } - - if (!scaledImage.isNull()) { - kdDebug() << timestamp() << " convertFromImage " << id << " " << area << endl; - pClass->readyPixmap.convertFromImage( scaledImage ); - } - } - kdDebug() << timestamp() << " Pixmap::drawContents " << pClass->readyPixmap.size() << " " << px << " " << py << " " << sx << " " << sy << " " << sw << " " << sh << endl; - p->drawPixmap( px, py, pClass->readyPixmap, sx, sy, sw, sh ); -} - -void -KdmPixmap::statusChanged() -{ - KdmItem::statusChanged(); - if (!pixmap.active.present && !pixmap.prelight.present) - return; - if ((state == Sprelight && !pixmap.prelight.present) || - (state == Sactive && !pixmap.active.present)) - return; - needUpdate(); -} - -#include "tdmpixmap.moc" diff --git a/kdm/kfrontend/themer/kdmpixmap.h b/kdm/kfrontend/themer/kdmpixmap.h deleted file mode 100644 index faa71a034..000000000 --- a/kdm/kfrontend/themer/kdmpixmap.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2003 by Unai Garro - * Copyright (C) 2004 by Enrico Ros - * Copyright (C) 2004 by Stephan Kulow - * Copyright (C) 2004 by Oswald Buddenhagen - * - * 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. - */ - -#ifndef TDMPIXMAP_H -#define TDMPIXMAP_H - -#include "tdmitem.h" - -//#include -#include - -#include -#include - -/* - * KdmPixmap. A pixmap element - */ - -class KdmPixmap : public KdmItem { - Q_OBJECT - -public: - KdmPixmap( KdmItem *parent, const TQDomNode &node, const char *name = 0 ); - -protected: - // reimplemented; returns the size of loaded pixmap - virtual TQSize sizeHint(); - - // draw the pixmap - virtual void drawContents( TQPainter *p, const TQRect &r ); - - // handle switching between normal / active / prelight configurations - virtual void statusChanged(); - - virtual void setGeometry( const TQRect &newGeometry, bool force ); - - struct PixmapStruct { - struct PixmapClass { - TQString fullpath; - TQPixmap pixmap; - TQPixmap readyPixmap; - TQColor tint; - float alpha; //TODO added: not in greeter.dtd - bool present; - } normal, active, prelight; - } pixmap; - -private: - // Method to load the pixmap path given by the theme - TQString fullPath( const TQString &fileName ); - void renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area ); - void loadPixmap( PixmapStruct::PixmapClass *pClass ); -}; - -#endif diff --git a/kdm/kfrontend/themer/kdmrect.cpp b/kdm/kfrontend/themer/kdmrect.cpp deleted file mode 100644 index 9056a513c..000000000 --- a/kdm/kfrontend/themer/kdmrect.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2003 by Unai Garro - * Copyright (C) 2004 by Enrico Ros - * Copyright (C) 2004 by Stephan Kulow - * Copyright (C) 2004 by Oswald Buddenhagen - * - * 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 "tdmrect.h" -#include "tdmthemer.h" -#include "tdmconfig.h" - -#include -#include - -#include -#include -#include -#include - -extern bool argb_visual_available; - -KdmRect::KdmRect( KdmItem *parent, const TQDomNode &node, const char *name ) - : KdmItem( parent, node, name ) -{ - init( node, name ); -} - -KdmRect::KdmRect( TQWidget *parent, const TQDomNode &node, const char *name ) - : KdmItem( parent, node, name ) -{ - init( node, name ); -} - -void -KdmRect::init( const TQDomNode &node, const char * ) -{ - itemType = "rect"; - - // Set default values for rect (note: strings are already Null) - rect.normal.alpha = 1; - rect.active.present = false; - rect.prelight.present = false; - rect.hasBorder = false; - - // A rect can have no properties (defaults to parent ones) - if (node.isNull()) - return; - - // Read RECT ID - TQDomNode n = node; - TQDomElement elRect = n.toElement(); - - // Read RECT TAGS - TQDomNodeList childList = node.childNodes(); - for (uint nod = 0; nod < childList.count(); nod++) { - TQDomNode child = childList.item( nod ); - TQDomElement el = child.toElement(); - TQString tagName = el.tagName(); - - if (tagName == "normal") { - parseColor( el.attribute( "color", TQString::null ), rect.normal.color ); - rect.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat(); - parseFont( el.attribute( "font", "Sans 14" ), rect.normal.font ); - } else if (tagName == "active") { - rect.active.present = true; - parseColor( el.attribute( "color", TQString::null ), rect.active.color ); - rect.active.alpha = el.attribute( "alpha", "1.0" ).toFloat(); - parseFont( el.attribute( "font", "Sans 14" ), rect.active.font ); - } else if (tagName == "prelight") { - rect.prelight.present = true; - parseColor( el.attribute( "color", TQString::null ), rect.prelight.color ); - rect.prelight.alpha = el.attribute( "alpha", "1.0" ).toFloat(); - parseFont( el.attribute( "font", "Sans 14" ), rect.prelight.font ); - } else if (tagName == "border") - rect.hasBorder = true; - } -} - -void -KdmRect::drawContents( TQPainter *p, const TQRect &r ) -{ - // choose the correct rect class - RectStruct::RectClass *rClass = &rect.normal; - if (state == Sactive && rect.active.present) - rClass = &rect.active; - if (state == Sprelight && rect.prelight.present) - rClass = &rect.prelight; - - if (rClass->alpha <= 0 || !rClass->color.isValid()) - return; - - if (rClass->alpha == 1) - p->fillRect( area, TQBrush( rClass->color ) ); - else { -// if ((_compositor.isEmpty()) || (!argb_visual_available)) { - // Software blend only (no compositing support) - TQRect backRect = r; - backRect.moveBy( area.x(), area.y() ); - TQPixmap backPixmap( backRect.size() ); - bitBlt( &backPixmap, TQPoint( 0, 0 ), p->device(), backRect ); - TQImage backImage = backPixmap.convertToImage(); - KImageEffect::blend( rClass->color, backImage, rClass->alpha ); - p->drawImage( backRect.x(), backRect.y(), backImage ); - // area.moveBy(1,1); -// } -// else { -// // We have compositing support! -// } - } -} - -void -KdmRect::statusChanged() -{ - KdmItem::statusChanged(); - if (!rect.active.present && !rect.prelight.present) - return; - if ((state == Sprelight && !rect.prelight.present) || - (state == Sactive && !rect.active.present)) - return; - needUpdate(); -} - -/* -void -KdmRect::setAttribs( TQWidget *widget ) -{ - widget->setFont( rect.normal.font ); -} - -void -KdmRect::recursiveSetAttribs( TQLayoutItem *li ) -{ - TQWidget *w; - TQLayout *l; - - if ((w = li->widget())) - setAttribs( w ); - else if ((l = li->layout())) { - TQLayoutIterator it = l->iterator(); - for (TQLayoutItem *itm = it.current(); itm; itm = ++it) - recursiveSetAttribs( itm ); - } -} - -void -KdmRect::setLayoutItem( TQLayoutItem *item ) -{ - KdmItem::setLayoutItem( item ); - recursiveSetAttribs( item ); -} -*/ - -void -KdmRect::setWidget( TQWidget *widget ) -{ - if ( rect.normal.color.isValid() && widget ) - { - TQPalette p = widget->palette(); - p.setColor( TQPalette::Normal, TQColorGroup::Text, rect.normal.color ); - widget->setPalette(p); - } - KdmItem::setWidget( widget ); - //setAttribs( widget ); -} - -#include "tdmrect.moc" diff --git a/kdm/kfrontend/themer/kdmrect.h b/kdm/kfrontend/themer/kdmrect.h deleted file mode 100644 index 6dfdc126a..000000000 --- a/kdm/kfrontend/themer/kdmrect.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2003 by Unai Garro - * Copyright (C) 2004 by Enrico Ros - * Copyright (C) 2004 by Stephan Kulow - * Copyright (C) 2004 by Oswald Buddenhagen - * - * 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. - */ - -#ifndef TDMRECT_H -#define TDMRECT_H - -#include "tdmitem.h" - -#include -#include - -/* - * KdmRect: A themed rectangular element - */ - -class KdmRect : public KdmItem { - Q_OBJECT - -public: - KdmRect( KdmItem *parent, const TQDomNode &node, const char *name = 0 ); - KdmRect( TQWidget *parent, const TQDomNode &node, const char *name = 0 ); - -protected: - // draw the rect - virtual void drawContents( TQPainter *p, const TQRect &r ); - - // handle switching between normal / active / prelight configurations - virtual void statusChanged(); - - struct RectStruct { - struct RectClass { - float alpha; - TQColor color; - bool present; - TQFont font; - } normal, active, prelight; - bool hasBorder; - } rect; - - virtual void setWidget( TQWidget *widget ); -// virtual void setLayoutItem( TQLayoutItem *item ); - void init( const TQDomNode &node, const char *name ); - -private: - void setAttribs( TQWidget *widget ); - void recursiveSetAttribs( TQLayoutItem *item ); -}; - -#endif diff --git a/kdm/kfrontend/themer/kdmthemer.cpp b/kdm/kfrontend/themer/kdmthemer.cpp deleted file mode 100644 index d2dc77935..000000000 --- a/kdm/kfrontend/themer/kdmthemer.cpp +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Copyright (C) 2003 by Unai Garro - * Copyright (C) 2004 by Enrico Ros - * Copyright (C) 2004 by Stephan Kulow - * Copyright (C) 2004 by Oswald Buddenhagen - * - * 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 "tdmthemer.h" -#include "tdmitem.h" -#include "tdmpixmap.h" -#include "tdmrect.h" -#include "tdmlabel.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include // animation timer - TODO -#include -#include -#include -#include -#include -#include - -#include - -extern bool argb_visual_available; - -/* - * KdmThemer. The main theming interface - */ -KdmThemer::KdmThemer( const TQString &_filename, const TQString &mode, TQWidget *parent ) - : TQObject( parent ) - , rootItem( 0 ) - , backBuffer( 0 ) -{ - // Set the mode we're working in - m_currentMode = mode; - - // read the XML file and create DOM tree - TQString filename = _filename; - if (!::access( TQFile::encodeName( filename + "/GdmGreeterTheme.desktop" ), R_OK )) { - KSimpleConfig cfg( filename + "/GdmGreeterTheme.desktop" ); - cfg.setGroup( "GdmGreeterTheme" ); - filename += '/' + cfg.readEntry( "Greeter" ); - } - TQFile opmlFile( filename ); - if (!opmlFile.open( IO_ReadOnly )) { - FDialog::box( widget(), errorbox, i18n( "Cannot open theme file %1" ).arg(filename) ); - return; - } - if (!domTree.setContent( &opmlFile )) { - FDialog::box( widget(), errorbox, i18n( "Cannot parse theme file %1" ).arg(filename) ); - return; - } - // Set the root (screen) item - rootItem = new KdmRect( parent, TQDomNode(), "tdm root" ); - - connect( rootItem, TQT_SIGNAL(needUpdate( int, int, int, int )), - widget(), TQT_SLOT(update( int, int, int, int )) ); - - rootItem->setBaseDir( TQFileInfo( filename ).dirPath( true ) ); - - // generate all the items defined in the theme - generateItems( rootItem ); - - connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SIGNAL(activated( const TQString & )) ); - connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SLOT(slotActivated( const TQString & )) ); - - TQTimer::singleShot(800, this, TQT_SLOT(slotPaintRoot())); - -/* *TODO* - // Animation timer - TQTimer *time = new TQTimer( this ); - time->start( 500 ); - connect( time, TQT_SIGNAL(timeout()), TQT_SLOT(update()) ) -*/ -} - -KdmThemer::~KdmThemer() -{ - delete rootItem; - delete backBuffer; -} - -inline TQWidget * -KdmThemer::widget() -{ - return static_cast(parent()); -} - -KdmItem * -KdmThemer::findNode( const TQString &item ) const -{ - return rootItem->findNode( item ); -} - -void -KdmThemer::updateGeometry( bool force ) -{ - rootItem->setGeometry( TQRect( TQPoint(), widget()->size() ), force ); -} - -// BEGIN other functions - -void -KdmThemer::widgetEvent( TQEvent *e ) -{ - if (!rootItem) - return; - switch (e->type()) { - case TQEvent::MouseMove: - { - TQMouseEvent *me = TQT_TQMOUSEEVENT(e); - rootItem->mouseEvent( me->x(), me->y() ); - } - break; - case TQEvent::MouseButtonPress: - { - TQMouseEvent *me = TQT_TQMOUSEEVENT(e); - rootItem->mouseEvent( me->x(), me->y(), true ); - } - break; - case TQEvent::MouseButtonRelease: - { - TQMouseEvent *me = TQT_TQMOUSEEVENT(e); - rootItem->mouseEvent( me->x(), me->y(), false, true ); - } - break; - case TQEvent::Show: - rootItem->show(); - break; - case TQEvent::Resize: - updateGeometry( false ); - showStructure( rootItem ); - break; - case TQEvent::Paint: - { - TQRect paintRect = TQT_TQPAINTEVENT(e)->rect(); - kdDebug() << timestamp() << " paint on: " << paintRect << endl; - - if ((_compositor.isEmpty()) || (!argb_visual_available)) { - // Software blend only (no compositing support) - if (!backBuffer) - backBuffer = new TQPixmap( widget()->size() ); - if (backBuffer->size() != widget()->size()) - backBuffer->resize( widget()->size() ); - - TQPainter p; - p.begin( backBuffer ); - rootItem->paint( &p, paintRect ); - p.end(); - - bitBlt( widget(), paintRect.topLeft(), backBuffer, paintRect ); - } - else { - // We have compositing support! - TQRgb blend_color = tqRgba(0, 0, 0, 0); // RGBA - float alpha = tqAlpha(blend_color) / 255.; - int pixel = tqAlpha(blend_color) << 24 | - int(tqRed(blend_color) * alpha) << 16 | - int(tqGreen(blend_color) * alpha) << 8 | - int(tqBlue(blend_color) * alpha); - TQPainter p1; - p1.begin( widget() ); - p1.fillRect( paintRect, TQColor(blend_color, pixel) ); - rootItem->paint( &p1, paintRect ); - p1.end(); - } - - } - break; - default: - break; - } -} - -/* -void -KdmThemer::pixmap( const TQRect &r, TQPixmap *px ) -{ - bitBlt( px, TQPoint( 0, 0 ), widget(), r ); -} -*/ - -void -KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node ) -{ - if (!parent) - return; - - TQDomNodeList subnodeList; //List of subnodes of this node - - /* - * Get the child nodes - */ - if (node.isNull()) { // It's the first node, get its child nodes - TQDomElement theme = domTree.documentElement(); - - // Get its tag, and check it's correct ("greeter") - if (theme.tagName() != "greeter") { - kdDebug() << timestamp() << " This does not seem to be a correct theme file." << endl; - return; - } - // Get the list of child nodes - subnodeList = theme.childNodes(); - } else - subnodeList = node.childNodes(); - - /* - * Go through each of the child nodes - */ - for (uint nod = 0; nod < subnodeList.count(); nod++) { - TQDomNode subnode = subnodeList.item( nod ); - TQDomElement el = subnode.toElement(); - TQString tagName = el.tagName(); - - if (tagName == "item") { - if (!willDisplay( subnode )) - continue; - TQString id = el.attribute("id"); - if (id.startsWith("plugin-specific-")) { - id = id.mid(strlen("plugin-specific-")); - if (!_pluginsLogin.contains(id)) - continue; - } - - // It's a new item. Draw it - TQString type = el.attribute( "type" ); - - KdmItem *newItem = 0; - - if (type == "label") - newItem = new KdmLabel( parent, subnode ); - else if (type == "pixmap") - newItem = new KdmPixmap( parent, subnode ); - else if (type == "rect") - newItem = new KdmRect( parent, subnode ); - else if (type == "entry" || type == "list") { - newItem = new KdmRect( parent, subnode ); - newItem->setType( type ); - } - // newItem = new KdmEntry( parent, subnode ); - else if (type == "svg") - newItem = new KdmPixmap( parent, subnode ); - if (newItem) { - generateItems( newItem, subnode ); - if (el.attribute( "button", "false" ) == "true") - newItem->inheritFromButton( newItem ); - } - } else if (tagName == "box") { - if (!willDisplay( subnode )) - continue; - // It's a new box. Draw it - parent->setBoxLayout( subnode ); - generateItems( parent, subnode ); - } else if (tagName == "fixed") { - if (!willDisplay( subnode )) - continue; - // It's a new box. Draw it - parent->setFixedLayout( subnode ); - generateItems( parent, subnode ); - } - } -} - -bool KdmThemer::willDisplay( const TQDomNode &node ) -{ - TQDomNode showNode = node.namedItem( "show" ); - - // No "show" node means this item can be displayed at all times - if (showNode.isNull()) - return true; - - TQDomElement el = showNode.toElement(); - - TQString modes = el.attribute( "modes" ); - if (!modes.isNull()) { - TQStringList modeList = TQStringList::split( ",", modes ); - - // If current mode isn't in this list, do not display item - if (modeList.find( m_currentMode ) == modeList.end()) - return false; - } - - TQString type = el.attribute( "type" ); - if (type == "config" || type == "suspend") - return false; // not implemented (yet) - if (type == "timed") - return _autoLoginDelay != 0; - if (type == "chooser") -#ifdef XDMCP - return _loginMode != LOGIN_LOCAL_ONLY; -#else - return false; -#endif - if (type == "halt" || type == "reboot") - return _allowShutdown != SHUT_NONE; - else if (type == "userlist") - return _userList; - else if ( type == "!userlist" ) - return !_userList; - -// if (type == "system") -// return true; - - // All tests passed, item will be displayed - return true; -} - -void -KdmThemer::showStructure( TQObject *obj ) -{ - - const TQObjectList wlist = obj->childrenListObject(); - static int counter = 0; - if (counter == 0) - kdDebug() << timestamp() << " \n\n<======= Widget tree =================" << endl; - if (!wlist.isEmpty()) { - counter++; - TQObjectListIterator it( wlist ); - TQObject *object; - - while ((object = it.current()) != 0) { - ++it; - TQString node; - for (int i = 1; i < counter; i++) - node += "-"; - - if (object->inherits( "KdmItem" )) { - KdmItem *widget = (KdmItem *)object; - kdDebug() << node << "|" << widget->type() << " me=" << widget->id << " " << widget->area << endl; - } - - showStructure( object ); - } - counter--; - } - if (counter == 0) - kdDebug() << timestamp() << " \n\n<======= Widget tree =================\n\n" << endl; -} - -void -KdmThemer::slotActivated( const TQString &id ) -{ - TQString toactivate; - if (id == "username-label") - toactivate = "user-entry"; - else if (id == "password-label") - toactivate = "pw-entry"; - else - return; - - KdmItem *item = findNode(toactivate); - if (!item || !item->widget()) - return; - - item->widget()->setFocus(); - TQLineEdit *le = (TQLineEdit*)item->widget()->qt_cast(TQLINEEDIT_OBJECT_NAME_STRING); - if (le) - le->selectAll(); -} - -void -KdmThemer::slotPaintRoot() -{ - KdmItem *back_item = findNode("background"); - if (!back_item) - return; - - TQRect screen = TQApplication::desktop()->screenGeometry(0); - TQPixmap pm(screen.size()); - - TQPainter painter( &pm, true ); - back_item->paint( &painter, back_item->rect()); - painter.end(); - - TQT_TQWIDGET(TQApplication::desktop()->screen())->setErasePixmap(pm); - TQT_TQWIDGET(TQApplication::desktop()->screen())->erase(); -} - -#include "tdmthemer.moc" diff --git a/kdm/kfrontend/themer/kdmthemer.h b/kdm/kfrontend/themer/kdmthemer.h deleted file mode 100644 index 2b8865b4d..000000000 --- a/kdm/kfrontend/themer/kdmthemer.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2003 by Unai Garro - * Copyright (C) 2004 by Enrico Ros - * Copyright (C) 2004 by Stephan Kulow - * Copyright (C) 2004 by Oswald Buddenhagen - * - * 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. - */ - -#ifndef TDMTHEMER_H -#define TDMTHEMER_H - -#include -#include -#include - -class KdmThemer; -class KdmItem; -class KdmPixmap; -class KdmRect; -class KdmBox; - -class TQRect; -class TQWidget; -class TQEvent; - -/** -* @author Unai Garro -*/ - - - -/* -* The themer widget. Whatever drawn here is just themed -* according to a XML file set by the user. -*/ - - -class KdmThemer : public TQObject { - Q_OBJECT - -public: - /* - * Construct and destruct the interface - */ - - KdmThemer( const TQString &path, const TQString &mode, TQWidget *parent ); - ~KdmThemer(); - - bool isOK() { return rootItem != 0; } - /* - * Gives a sizeHint to the widget (parent size) - */ - //TQSize sizeHint() const{ return parentWidget()->size(); } - - /* - * Takes a shot of the current widget - */ -// void pixmap( const TQRect &r, TQPixmap *px ); - - virtual // just to put the reference in the vmt - KdmItem *findNode( const TQString & ) const; - - void updateGeometry( bool force ); // force = true for external calls - - // must be called by parent widget - void widgetEvent( TQEvent *e ); - -signals: - void activated( const TQString &id ); - -protected slots: - void slotActivated( const TQString &id ); - void slotPaintRoot(); - -private: - /* - * Our display mode (e.g. console, remote, ...) - */ - TQString m_currentMode; - - /* - * The config file being used - */ - TQDomDocument domTree; - - /* - * Stores the root of the theme - */ - KdmItem *rootItem; - - /* - * The backbuffer - */ - TQPixmap *backBuffer; - - // methods - - /* - * Test whether item needs to be displayed - */ - bool willDisplay( const TQDomNode &node ); - - /* - * Parses the XML file looking for the - * item list and adds those to the themer - */ - void generateItems( KdmItem *parent = 0, const TQDomNode &node = TQDomNode() ); - - void showStructure( TQObject *obj ); - - TQWidget *widget(); -}; - - -#endif diff --git a/kdm/kfrontend/themes/CMakeLists.txt b/kdm/kfrontend/themes/CMakeLists.txt deleted file mode 100644 index f1dd26e15..000000000 --- a/kdm/kfrontend/themes/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -add_subdirectory( circles ) -add_subdirectory( o2_enterprise ) diff --git a/kdm/kfrontend/themes/Makefile.am b/kdm/kfrontend/themes/Makefile.am deleted file mode 100644 index 7d13b5174..000000000 --- a/kdm/kfrontend/themes/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = circles o2_enterprise diff --git a/kdm/kfrontend/themes/circles/CMakeLists.txt b/kdm/kfrontend/themes/circles/CMakeLists.txt deleted file mode 100644 index 9122c13ea..000000000 --- a/kdm/kfrontend/themes/circles/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -install( FILES - GdmGreeterTheme.desktop circles.xml background.svg - flower.png help.png options.png screenshot.png - DESTINATION ${DATA_INSTALL_DIR}/tdm/themes/circles ) diff --git a/kdm/kfrontend/themes/circles/GdmGreeterTheme.desktop b/kdm/kfrontend/themes/circles/GdmGreeterTheme.desktop deleted file mode 100644 index 72be02f41..000000000 --- a/kdm/kfrontend/themes/circles/GdmGreeterTheme.desktop +++ /dev/null @@ -1,135 +0,0 @@ -# This is not really a .desktop file like the rest, but it's useful to treat -# it as such - -[GdmGreeterTheme] -Greeter=circles.xml -Name=Circles -Name[ar]=الدوائر -Name[bn]=সার্কল্‌স -Name[br]=Kelc'hioù -Name[bs]=Krugovi -Name[ca]=Cercles -Name[cs]=Kruhy -Name[csb]=Kółka -Name[cy]=Cylchoedd -Name[da]=Cirkler -Name[de]=Kreise -Name[el]=Κύκλοι -Name[eo]=cirkloj -Name[es]=Círculos -Name[et]=Ringid -Name[fa]=دایره‌ها -Name[fi]=Ympyrät -Name[fy]=Cirkels -Name[ga]=Ciorcail -Name[he]=מעגלים -Name[hi]=वृत्त -Name[hr]=Krugovi -Name[hu]=Körök -Name[is]=Hringir -Name[it]=Cerchi -Name[ja]=サークル -Name[ka]=წრეები -Name[kk]=Дөңгелектер -Name[km]=រង្វង់ -Name[ko]=원 -Name[lt]=Skrituliai -Name[mk]=Кругови -Name[ms]=Bulatan -Name[nb]=Sirkler -Name[nds]=Krinken -Name[ne]=वृत्त -Name[nl]=Cirkels -Name[nn]=Sirklar -Name[pa]=ਚੱਕਰ -Name[pl]=Kółka -Name[pt]=Círculos -Name[pt_BR]=Círculos -Name[ro]=Cercuri -Name[ru]=Круги -Name[rw]=Inziga -Name[se]=Gearddut -Name[sk]=Kruhy -Name[sl]=Krogi -Name[sr]=Кругови -Name[sr@Latn]=Krugovi -Name[sv]=Cirklar -Name[ta]=வட்டங்கள் -Name[te]=వృత్తాలు -Name[tg]=Доираҳо -Name[tr]=Çemberler -Name[uk]=Кола -Name[uz]=Aylanalar -Name[uz@cyrillic]=Айланалар -Name[vi]=Vòng tròn -Name[wa]=Cekes -Name[zh_CN]=圆环 -Description=Theme with blue circles -Description[af]=Tema met blou sirkels -Description[ar]=سمة بلدوائر الزرقاء -Description[be]=Тэма з блакітнымі коламі -Description[bn]=নীল বৃত্ত সম্বলিত থীম -Description[bs]=Tema sa plavim krugovima -Description[ca]=Tema amb cercles blaus -Description[cs]=Motiv s modrými kruhy -Description[csb]=Téma z mòdrima kółkama -Description[da]=Tema med blå cirkler -Description[de]=Thema mit blauen Kreisen -Description[el]=Θέμα με μπλε κύκλους -Description[eo]=Etoso kun bluaj cirkloj -Description[es]=Tema con círculos azules -Description[et]=Siniste ringidega teema -Description[eu]=Biribil urdindun gaia -Description[fa]=چهره با دایره‌های آبی -Description[fi]=Teema sinisillä ympyröillä -Description[fr]=Thème avec des cercles bleus -Description[fy]=Tema mei blauwe sirkels -Description[gl]=Tema con círculos azuis -Description[he]=ערכת נושא עם מעגלים כחולים -Description[hi]=नीले वृत्तों के साथ प्रसंग -Description[hr]=Tema s plavim krugovima -Description[hu]=Téma kék körökkel -Description[is]=Þema með bláum hringjum -Description[it]=Tema con cerchi blu -Description[ja]=青い丸のテーマ -Description[ka]=ლურჯ წრეებიანი თემა -Description[kk]=Көк дөңгелекті нақыш -Description[km]=ស្បែក​មាន​រង្វង់​ពណ៌​ខៀវ -Description[ko]=파란 원이 있는 테마 -Description[lt]=Tema su melsvais skrituliais -Description[lv]=Tēma ar ziliem riņķiem -Description[mk]=Тема со сини кругови -Description[ms]=Tema dengan bulatan biru -Description[nb]=Tema med blå sirkler -Description[nds]=Muster mit blage Krinken -Description[ne]=निलो वृत्तसँग विषयवस्तु -Description[nl]=Thema met blauwe cirkels -Description[nn]=Tema med blåe sirklar -Description[pa]=ਨੀਲੇ ਚੱਕਰਾਂ ਵਾਲਾ ਸਰੂਪ -Description[pl]=Motyw z niebieskimi kółkami -Description[pt]=Tema com círculos azuis -Description[pt_BR]=Tema com círculos azuis -Description[ro]=Temă cu cercuri albastre -Description[ru]=Тема с синими кругами -Description[rw]=Insanganyamatsiko ifite inziga z'ubururu -Description[se]=Fáddá mas lea alit gearddut -Description[sk]=Téma s modrými kruhmi -Description[sl]=Tema z modrimi krogi -Description[sr]=Тема са плавим круговима -Description[sr@Latn]=Tema sa plavim krugovima -Description[sv]=Tema med blåa cirklar -Description[ta]=நீல வட்டங்களுடன் தலைப்பு -Description[tg]=Мавзӯъ бо доираҳои кабуд -Description[th]=ชุดตกแต่งมาพร้อมวงกลมสีน้ำเงิน -Description[tr]=Mavi çemberli tema -Description[tt]=Zäñgär tügäräklär belän tışlaw -Description[uk]=Тема з синіми колами -Description[uz]=Koʻk aylanalarli mavzu -Description[uz@cyrillic]=Кўк айланаларли мавзу -Description[vi]=Sắc thái với các vòng tròn xanh lam -Description[wa]=Tinme avou des bleus cekes -Description[zh_CN]=带蓝环的主题 -Description[zh_TW]=有藍色圓圈的佈景主題 -Author=Bond, James Bond -Copyright=(c) 2002 Bond, James Bond -Screenshot=screenshot.png diff --git a/kdm/kfrontend/themes/circles/Makefile.am b/kdm/kfrontend/themes/circles/Makefile.am deleted file mode 100644 index d88c407c2..000000000 --- a/kdm/kfrontend/themes/circles/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -circlesdir = $(kde_datadir)/tdm/themes/circles -circles_DATA = \ - GdmGreeterTheme.desktop \ - circles.xml \ - background.svg \ - flower.png \ - help.png \ - options.png \ - screenshot.png - -EXTRA_DIST = $(circles_DATA) diff --git a/kdm/kfrontend/themes/circles/background.svg b/kdm/kfrontend/themes/circles/background.svg deleted file mode 100644 index 11abc4f43..000000000 --- a/kdm/kfrontend/themes/circles/background.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/kdm/kfrontend/themes/circles/circles.xml b/kdm/kfrontend/themes/circles/circles.xml deleted file mode 100644 index 0596e0ee7..000000000 --- a/kdm/kfrontend/themes/circles/circles.xml +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/kdm/kfrontend/themes/circles/flower.png b/kdm/kfrontend/themes/circles/flower.png deleted file mode 100644 index 92d25f32d..000000000 Binary files a/kdm/kfrontend/themes/circles/flower.png and /dev/null differ diff --git a/kdm/kfrontend/themes/circles/help.png b/kdm/kfrontend/themes/circles/help.png deleted file mode 100644 index b38b48a6d..000000000 Binary files a/kdm/kfrontend/themes/circles/help.png and /dev/null differ diff --git a/kdm/kfrontend/themes/circles/options.png b/kdm/kfrontend/themes/circles/options.png deleted file mode 100644 index 3c08e02d4..000000000 Binary files a/kdm/kfrontend/themes/circles/options.png and /dev/null differ diff --git a/kdm/kfrontend/themes/circles/screenshot.png b/kdm/kfrontend/themes/circles/screenshot.png deleted file mode 100644 index 7120b03d5..000000000 Binary files a/kdm/kfrontend/themes/circles/screenshot.png and /dev/null differ diff --git a/kdm/kfrontend/themes/o2_enterprise/CMakeLists.txt b/kdm/kfrontend/themes/o2_enterprise/CMakeLists.txt deleted file mode 100644 index bf9f738a0..000000000 --- a/kdm/kfrontend/themes/o2_enterprise/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -install( FILES - Dialog.png enter_normal.png enter_over.png enter_pressed.png - enterprise.xml GdmGreeterTheme.desktop preview.png - system_normal.png system_over.png system_pressed.png - DESTINATION ${DATA_INSTALL_DIR}/tdm/themes/o2_enterprise ) diff --git a/kdm/kfrontend/themes/o2_enterprise/Dialog.png b/kdm/kfrontend/themes/o2_enterprise/Dialog.png deleted file mode 100644 index d38a35983..000000000 Binary files a/kdm/kfrontend/themes/o2_enterprise/Dialog.png and /dev/null differ diff --git a/kdm/kfrontend/themes/o2_enterprise/GdmGreeterTheme.desktop b/kdm/kfrontend/themes/o2_enterprise/GdmGreeterTheme.desktop deleted file mode 100644 index 10ce5cc52..000000000 --- a/kdm/kfrontend/themes/o2_enterprise/GdmGreeterTheme.desktop +++ /dev/null @@ -1,10 +0,0 @@ -# This is not really a .desktop file like the rest, but it's useful to treat -# it as such - -[GdmGreeterTheme] -Encoding=UTF-8 -Greeter=enterprise.xml -Name=O2 Enterprise -Description=A sleek and professional looking TDM theme for Trinity -Author=Ken Wimer (wimer@kde.org) and Timothy Pearson (kb9vqf@pearsoncomputing.net) -Screenshot=preview.png diff --git a/kdm/kfrontend/themes/o2_enterprise/Makefile.am b/kdm/kfrontend/themes/o2_enterprise/Makefile.am deleted file mode 100644 index 078e370a5..000000000 --- a/kdm/kfrontend/themes/o2_enterprise/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -o2_enterprisedir = $(kde_datadir)/tdm/themes/o2_enterprise -o2_enterprise_DATA = \ - Dialog.png \ - enter_normal.png \ - enter_over.png \ - enter_pressed.png \ - enterprise.xml \ - GdmGreeterTheme.desktop \ - preview.png \ - system_normal.png \ - system_over.png \ - system_pressed.png - -EXTRA_DIST = $(o2_enterprise_DATA) diff --git a/kdm/kfrontend/themes/o2_enterprise/enter_normal.png b/kdm/kfrontend/themes/o2_enterprise/enter_normal.png deleted file mode 100644 index c859ce5df..000000000 Binary files a/kdm/kfrontend/themes/o2_enterprise/enter_normal.png and /dev/null differ diff --git a/kdm/kfrontend/themes/o2_enterprise/enter_over.png b/kdm/kfrontend/themes/o2_enterprise/enter_over.png deleted file mode 100644 index f1252a55a..000000000 Binary files a/kdm/kfrontend/themes/o2_enterprise/enter_over.png and /dev/null differ diff --git a/kdm/kfrontend/themes/o2_enterprise/enter_pressed.png b/kdm/kfrontend/themes/o2_enterprise/enter_pressed.png deleted file mode 100644 index c859ce5df..000000000 Binary files a/kdm/kfrontend/themes/o2_enterprise/enter_pressed.png and /dev/null differ diff --git a/kdm/kfrontend/themes/o2_enterprise/enterprise.xml b/kdm/kfrontend/themes/o2_enterprise/enterprise.xml deleted file mode 100644 index cf8aecd32..000000000 --- a/kdm/kfrontend/themes/o2_enterprise/enterprise.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - %c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/kdm/kfrontend/themes/o2_enterprise/gpl.txt b/kdm/kfrontend/themes/o2_enterprise/gpl.txt deleted file mode 100644 index b6f92f3db..000000000 --- a/kdm/kfrontend/themes/o2_enterprise/gpl.txt +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/kdm/kfrontend/themes/o2_enterprise/preview.png b/kdm/kfrontend/themes/o2_enterprise/preview.png deleted file mode 100644 index f7712d7d2..000000000 Binary files a/kdm/kfrontend/themes/o2_enterprise/preview.png and /dev/null differ diff --git a/kdm/kfrontend/themes/o2_enterprise/system_normal.png b/kdm/kfrontend/themes/o2_enterprise/system_normal.png deleted file mode 100644 index ea9b1bdfa..000000000 Binary files a/kdm/kfrontend/themes/o2_enterprise/system_normal.png and /dev/null differ diff --git a/kdm/kfrontend/themes/o2_enterprise/system_over.png b/kdm/kfrontend/themes/o2_enterprise/system_over.png deleted file mode 100644 index 7d535efc8..000000000 Binary files a/kdm/kfrontend/themes/o2_enterprise/system_over.png and /dev/null differ diff --git a/kdm/kfrontend/themes/o2_enterprise/system_pressed.png b/kdm/kfrontend/themes/o2_enterprise/system_pressed.png deleted file mode 100644 index ea9b1bdfa..000000000 Binary files a/kdm/kfrontend/themes/o2_enterprise/system_pressed.png and /dev/null differ diff --git a/kdmlib/CMakeLists.txt b/kdmlib/CMakeLists.txt deleted file mode 100644 index a2565fe1d..000000000 --- a/kdmlib/CMakeLists.txt +++ /dev/null @@ -1,85 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/tdm/kfrontend - ${CMAKE_BINARY_DIR} - ${TDE_INCLUDE_DIR} - ${TQT_INCLUDE_DIRS} -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - -if( BUILD_TDM ) - - -##### headers ################################### - -install( FILES kgreeterplugin.h DESTINATION ${INCLUDE_INSTALL_DIR} ) - - -##### kgreet_classic (module) ################### - -tde_add_kpart( kgreet_classic AUTOMOC - SOURCES kgreet_classic.cpp - LINK tdeui-shared - DESTINATION ${PLUGIN_INSTALL_DIR} -) - - -##### kgreet_pam (module) ####################### - -tde_add_kpart( kgreet_pam AUTOMOC - SOURCES kgreet_pam.cpp - LINK tdeui-shared - DESTINATION ${PLUGIN_INSTALL_DIR} -) - - -##### kgreet_winbind (module) ################### - -tde_add_kpart( kgreet_winbind AUTOMOC - SOURCES kgreet_winbind.cpp - LINK tdeui-shared - DESTINATION ${PLUGIN_INSTALL_DIR} -) - - - -endif( BUILD_TDM ) - - -##### dmctl (static) ############################ - -if( BUILD_KICKER OR BUILD_KDESKTOP OR BUILD_TDM OR BUILD_KSMSERVER ) - - tde_add_library( dmctl STATIC_PIC - SOURCES dmctl.cpp - LINK Xau - ) - -endif( ) - -##### tdmtsak (executable) ####################### - -if( BUILD_TSAK ) - tde_add_executable( tdmtsak - SOURCES tdmtsak.cpp - LINK ${TQT_LIBRARIES} - DESTINATION ${BIN_INSTALL_DIR} - SETUID - DESCRIPTION "Secure Attention Key interface for TDM" - AUTHORS "Timothy Pearson" - ) -endif( BUILD_TSAK ) diff --git a/kdmlib/Makefile.am b/kdmlib/Makefile.am deleted file mode 100644 index f21f59bd5..000000000 --- a/kdmlib/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -AM_CPPFLAGS = -I$(top_srcdir)/tdm/kfrontend $(all_includes) - -kde_module_LTLIBRARIES = kgreet_classic.la kgreet_pam.la kgreet_winbind.la - -kgreet_classic_la_SOURCES = kgreet_classic.cpp -kgreet_classic_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries) -kgreet_classic_la_LIBADD = $(LIB_TDEUI) - -kgreet_pam_la_SOURCES = kgreet_pam.cpp -kgreet_pam_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries) -kgreet_pam_la_LIBADD = $(LIB_TDEUI) - -kgreet_winbind_la_SOURCES = kgreet_winbind.cpp -kgreet_winbind_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries) -kgreet_winbind_la_LIBADD = $(LIB_TDEUI) - -noinst_LTLIBRARIES = libdmctl.la -libdmctl_la_SOURCES = dmctl.cpp -libdmctl_la_LDFLAGS = $(all_libraries) -no-undefined -libdmctl_la_LIBADD = $(LIB_TDECORE) -lXau - -METASOURCES = AUTO - -noinst_HEADERS = dmctl.h kgreet_classic.h kgreet_winbind.h -include_HEADERS = kgreeterplugin.h - -messages: - $(XGETTEXT) $(kgreet_classic_la_SOURCES) -o $(podir)/kgreet_classic.pot - $(XGETTEXT) $(kgreet_winbind_la_SOURCES) -o $(podir)/kgreet_winbind.pot - $(XGETTEXT) $(libdmctl_la_SOURCES) -o $(podir)/libdmctl.pot diff --git a/kdmlib/dmctl.cpp b/kdmlib/dmctl.cpp deleted file mode 100644 index 41a5cb206..000000000 --- a/kdmlib/dmctl.cpp +++ /dev/null @@ -1,442 +0,0 @@ -/* - Copyright (C) 2004 Oswald Buddenhagen - - This program is free software; you can redistribute it and/or - modify it under the terms of the Lesser 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 Lesser GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "dmctl.h" - -#ifdef Q_WS_X11 - -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -static enum { Dunno, NoDM, NewTDM, OldTDM, GDM } DMType = Dunno; -static const char *ctl, *dpy; - -DM::DM() : fd( -1 ) -{ - char *ptr; - struct sockaddr_un sa; - - if (DMType == Dunno) { - if (!(dpy = ::getenv( "DISPLAY" ))) - DMType = NoDM; - else if ((ctl = ::getenv( "DM_CONTROL" ))) - DMType = NewTDM; - else if ((ctl = ::getenv( "XDM_MANAGED" )) && ctl[0] == '/') - DMType = OldTDM; - else if (::getenv( "GDMSESSION" )) - DMType = GDM; - else - DMType = NoDM; - } - switch (DMType) { - default: - return; - case NewTDM: - case GDM: - if ((fd = ::socket( PF_UNIX, SOCK_STREAM, 0 )) < 0) - return; - sa.sun_family = AF_UNIX; - if (DMType == GDM) { - strcpy( sa.sun_path, "/var/run/gdm_socket" ); - if (::connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) { - strcpy( sa.sun_path, "/tmp/.gdm_socket" ); - if (::connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) { - ::close( fd ); - fd = -1; - break; - } - } - GDMAuthenticate(); - } else { - if ((ptr = const_cast(strchr( dpy, ':' )))) - ptr = strchr( ptr, '.' ); - snprintf( sa.sun_path, sizeof(sa.sun_path), - "%s/dmctl-%.*s/socket", - ctl, ptr ? int(ptr - dpy) : 512, dpy ); - if (::connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) { - ::close( fd ); - fd = -1; - } - } - break; - case OldTDM: - { - TQString tf( ctl ); - tf.truncate( tf.find( ',' ) ); - fd = ::open( tf.latin1(), O_WRONLY ); - } - break; - } -} - -DM::~DM() -{ - if (fd >= 0) - close( fd ); -} - -bool -DM::exec( const char *cmd ) -{ - TQCString buf; - - return exec( cmd, buf ); -} - -/** - * Execute a TDM/GDM remote control command. - * @param cmd the command to execute. FIXME: undocumented yet. - * @param buf the result buffer. - * @return result: - * @li If true, the command was successfully executed. - * @p ret might contain addional results. - * @li If false and @p ret is empty, a communication error occurred - * (most probably TDM is not running). - * @li If false and @p ret is non-empty, it contains the error message - * from TDM. - */ -bool -DM::exec( const char *cmd, TQCString &buf ) -{ - bool ret = false; - int tl; - unsigned len = 0; - - if (fd < 0) - goto busted; - - tl = strlen( cmd ); - if (::write( fd, cmd, tl ) != tl) { - bust: - ::close( fd ); - fd = -1; - busted: - buf.resize( 0 ); - return false; - } - if (DMType == OldTDM) { - buf.resize( 0 ); - return true; - } - for (;;) { - if (buf.size() < 128) - buf.resize( 128 ); - else if (buf.size() < len * 2) - buf.resize( len * 2 ); - if ((tl = ::read( fd, buf.data() + len, buf.size() - len)) <= 0) { - if (tl < 0 && errno == EINTR) - continue; - goto bust; - } - len += tl; - if (buf[len - 1] == '\n') { - buf[len - 1] = 0; - if (len > 2 && (buf[0] == 'o' || buf[0] == 'O') && - (buf[1] == 'k' || buf[1] == 'K') && buf[2] <= 32) - ret = true; - break; - } - } - return ret; -} - -bool -DM::canShutdown() -{ - if (DMType == OldTDM) - return strstr( ctl, ",maysd" ) != 0; - - TQCString re; - - if (DMType == GDM) - return exec( "QUERY_LOGOUT_ACTION\n", re ) && re.find("HALT") >= 0; - - return exec( "caps\n", re ) && re.find( "\tshutdown" ) >= 0; -} - -void -DM::shutdown( KApplication::ShutdownType shutdownType, - KApplication::ShutdownMode shutdownMode, /* NOT Default */ - const TQString &bootOption ) -{ - if (shutdownType == KApplication::ShutdownTypeNone) - return; - - bool cap_ask; - if (DMType == NewTDM) { - TQCString re; - cap_ask = exec( "caps\n", re ) && re.find( "\tshutdown ask" ) >= 0; - } else { - if (!bootOption.isEmpty()) - return; - cap_ask = false; - } - if (!cap_ask && shutdownMode == KApplication::ShutdownModeInteractive) - shutdownMode = KApplication::ShutdownModeForceNow; - - TQCString cmd; - if (DMType == GDM) { - cmd.append( shutdownMode == KApplication::ShutdownModeForceNow ? - "SET_LOGOUT_ACTION " : "SET_SAFE_LOGOUT_ACTION " ); - cmd.append( shutdownType == KApplication::ShutdownTypeReboot ? - "REBOOT\n" : "HALT\n" ); - } else { - cmd.append( "shutdown\t" ); - cmd.append( shutdownType == KApplication::ShutdownTypeReboot ? - "reboot\t" : "halt\t" ); - if (!bootOption.isEmpty()) - cmd.append( "=" ).append( bootOption.local8Bit() ).append( "\t" ); - cmd.append( shutdownMode == KApplication::ShutdownModeInteractive ? - "ask\n" : - shutdownMode == KApplication::ShutdownModeForceNow ? - "forcenow\n" : - shutdownMode == KApplication::ShutdownModeTryNow ? - "trynow\n" : "schedule\n" ); - } - exec( cmd.data() ); -} - -bool -DM::bootOptions( TQStringList &opts, int &defopt, int ¤t ) -{ - if (DMType != NewTDM) - return false; - - TQCString re; - if (!exec( "listbootoptions\n", re )) - return false; - - opts = TQStringList::split( '\t', TQString::fromLocal8Bit( re.data() ) ); - if (opts.size() < 4) - return false; - - bool ok; - defopt = opts[2].toInt( &ok ); - if (!ok) - return false; - current = opts[3].toInt( &ok ); - if (!ok) - return false; - - opts = TQStringList::split( ' ', opts[1] ); - for (TQStringList::Iterator it = opts.begin(); it != opts.end(); ++it) - (*it).replace( "\\s", " " ); - - return true; -} - -void -DM::setLock( bool on ) -{ - if (DMType != GDM) - exec( on ? "lock\n" : "unlock\n" ); -} - -bool -DM::isSwitchable() -{ - if (DMType == OldTDM) - return dpy[0] == ':'; - - if (DMType == GDM) - return exec( "QUERY_VT\n" ); - - TQCString re; - - return exec( "caps\n", re ) && re.find( "\tlocal" ) >= 0; -} - -int -DM::numReserve() -{ - if (DMType == GDM) - return 1; /* Bleh */ - - if (DMType == OldTDM) - return strstr( ctl, ",rsvd" ) ? 1 : -1; - - TQCString re; - int p; - - if (!(exec( "caps\n", re ) && (p = re.find( "\treserve " )) >= 0)) - return -1; - return atoi( re.data() + p + 9 ); -} - -void -DM::startReserve() -{ - if (DMType == GDM) - exec("FLEXI_XSERVER\n"); - else - exec("reserve\n"); -} - -bool -DM::localSessions( SessList &list ) -{ - if (DMType == OldTDM) - return false; - - TQCString re; - - if (DMType == GDM) { - if (!exec( "CONSOLE_SERVERS\n", re )) - return false; - TQStringList sess = TQStringList::split( TQChar(';'), re.data() + 3 ); - for (TQStringList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { - TQStringList ts = TQStringList::split( TQChar(','), *it, true ); - SessEnt se; - se.display = ts[0]; - se.user = ts[1]; - se.vt = ts[2].toInt(); - se.session = ""; - se.self = ts[0] == ::getenv( "DISPLAY" ); /* Bleh */ - se.tty = false; - list.append( se ); - } - } else { - if (!exec( "list\talllocal\n", re )) - return false; - TQStringList sess = TQStringList::split( TQChar('\t'), re.data() + 3 ); - for (TQStringList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { - TQStringList ts = TQStringList::split( TQChar(','), *it, true ); - SessEnt se; - se.display = ts[0]; - if (ts[1][0] == '@') - se.from = ts[1].mid( 1 ), se.vt = 0; - else - se.vt = ts[1].mid( 2 ).toInt(); - se.user = ts[2]; - se.session = ts[3]; - se.self = (ts[4].find( '*' ) >= 0); - se.tty = (ts[4].find( 't' ) >= 0); - list.append( se ); - } - } - return true; -} - -void -DM::sess2Str2( const SessEnt &se, TQString &user, TQString &loc ) -{ - if (se.tty) { - user = i18n("user: ...", "%1: TTY login").arg( se.user ); - loc = se.vt ? TQString(TQString("vt%1").arg( se.vt )) : se.display ; - } else { - user = - se.user.isEmpty() ? - se.session.isEmpty() ? - i18n("Unused") : - se.session == "" ? - i18n("X login on remote host") : - TQString(i18n("... host", "X login on %1").arg( se.session )) : - se.session == "" ? - se.user : - TQString(i18n("user: session type", "%1: %2") - .arg( se.user ).arg( se.session )); - loc = - se.vt ? - TQString(TQString("%1, vt%2").arg( se.display ).arg( se.vt )) : - se.display; - } -} - -TQString -DM::sess2Str( const SessEnt &se ) -{ - TQString user, loc; - - sess2Str2( se, user, loc ); - return i18n("session (location)", "%1 (%2)").arg( user ).arg( loc ); -} - -bool -DM::switchVT( int vt ) -{ - if (DMType == GDM) - return exec( TQString(TQString("SET_VT %1\n").arg(vt)).latin1() ); - - return exec( TQString(TQString("activate\tvt%1\n").arg(vt)).latin1() ); -} - -void -DM::lockSwitchVT( int vt ) -{ - if (switchVT( vt )) - kapp->dcopClient()->send( "kdesktop", "KScreensaverIface", "lock()", TQString("") ); -} - -void -DM::GDMAuthenticate() -{ - FILE *fp; - const char *dpy, *dnum, *dne; - int dnl; - Xauth *xau; - - dpy = DisplayString( TQPaintDevice::x11AppDisplay() ); - if (!dpy) { - dpy = ::getenv( "DISPLAY" ); - if (!dpy) - return; - } - dnum = strchr( dpy, ':' ) + 1; - dne = strchr( dpy, '.' ); - dnl = dne ? dne - dnum : strlen( dnum ); - - /* XXX should do locking */ - if (!(fp = fopen( XauFileName(), "r" ))) - return; - - while ((xau = XauReadAuth( fp ))) { - if (xau->family == FamilyLocal && - xau->number_length == dnl && !memcmp( xau->number, dnum, dnl ) && - xau->data_length == 16 && - xau->name_length == 18 && !memcmp( xau->name, "MIT-MAGIC-COOKIE-1", 18 )) - { - TQString cmd( "AUTH_LOCAL " ); - for (int i = 0; i < 16; i++) - cmd += TQString::number( (uchar)xau->data[i], 16 ).rightJustify( 2, '0'); - cmd += "\n"; - if (exec( cmd.latin1() )) { - XauDisposeAuth( xau ); - break; - } - } - XauDisposeAuth( xau ); - } - - fclose (fp); -} - -#endif // Q_WS_X11 diff --git a/kdmlib/dmctl.h b/kdmlib/dmctl.h deleted file mode 100644 index da5aa2b0b..000000000 --- a/kdmlib/dmctl.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright (C) 2004,2005 Oswald Buddenhagen - Copyright (C) 2005 Stephan Kulow - - This program is free software; you can redistribute it and/or - modify it under the terms of the Lesser 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 Lesser GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef DMCTL_H -#define DMCTL_H - -#include - -struct SessEnt { - TQString display, from, user, session; - int vt; - bool self:1, tty:1; -}; - -typedef TQValueList SessList; - -class DM { - -#ifdef Q_WS_X11 - -public: - DM(); - ~DM(); - - bool canShutdown(); - void shutdown( KApplication::ShutdownType shutdownType, - KApplication::ShutdownMode shutdownMode, - const TQString &bootOption = TQString::null ); - - void setLock( bool on ); - - bool isSwitchable(); - int numReserve(); - void startReserve(); - bool localSessions( SessList &list ); - bool switchVT( int vt ); - void lockSwitchVT( int vt ); - - bool bootOptions( TQStringList &opts, int &dflt, int &curr ); - - static TQString sess2Str( const SessEnt &se ); - static void sess2Str2( const SessEnt &se, TQString &user, TQString &loc ); - -private: - int fd; - - bool exec( const char *cmd, TQCString &ret ); - bool exec( const char *cmd ); - - void GDMAuthenticate(); - -#else // Q_WS_X11 - -public: - DM() {} - - bool canShutdown() { return false; } - void shutdown( KApplication::ShutdownType shutdownType, - KApplication::ShutdownMode shutdownMode, - const TQString &bootOption = TQString::null ) {} - - void setLock( bool ) {} - - bool isSwitchable() { return false; } - int numReserve() { return -1; } - void startReserve() {} - bool localSessions( SessList &list ) { return false; } - void switchVT( int vt ) {} - - bool bootOptions( TQStringList &opts, int &dflt, int &curr ); - -#endif // Q_WS_X11 - -}; // class DM - -#endif // DMCTL_H diff --git a/kdmlib/kdmtsak.cpp b/kdmlib/kdmtsak.cpp deleted file mode 100644 index 18acd05d2..000000000 --- a/kdmlib/kdmtsak.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - This file is part of the TDE project - Copyright (C) 2011 Timothy Pearson - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "tdmtsak.h" - -#include - -#define FIFO_FILE "/tmp/ksocket-global/tsak" - -TQString exec(const char * cmd) { - FILE* pipe = popen(cmd, "r"); - if (!pipe) return "ERROR"; - char buffer[128]; - TQString result = ""; - while(!feof(pipe)) { - if(fgets(buffer, 128, pipe) != NULL) - result += buffer; - } - pclose(pipe); - return result; -} - -bool is_vt_local() { - const char * currentDisplay; - currentDisplay = getenv ("DISPLAY"); - if (currentDisplay == NULL) { - return false; - } - else { - TQString cvtName = ""; - TQString output = exec("tdmctl list"); - TQStringList sessionList = TQStringList::split('\t', output, false); - // See if the current session is local - for ( TQStringList::Iterator it = sessionList.begin(); it != sessionList.end(); ++it ) { - TQStringList sessionInfoList = TQStringList::split(',', *it, true); - if ((*(sessionInfoList.at(0))).startsWith(":")) { - if (TQString(currentDisplay).startsWith(*(sessionInfoList.at(0)))) { - return true; - } - } - } - // Not local - return false; - } -} - -bool is_vt_active() { - const char * currentDisplay; - currentDisplay = getenv ("DISPLAY"); - if (currentDisplay == NULL) { - return true; - } - else { - TQString cvtName = ""; - TQString output = exec("tdmctl list"); - TQString curConsole = exec("fgconsole"); - bool intFound; - int curConsoleNum = curConsole.toInt(&intFound); - if (intFound == false) { - return true; - } - curConsole = TQString("vt%1").arg(curConsoleNum);; - TQStringList sessionList = TQStringList::split('\t', output, false); - for ( TQStringList::Iterator it = sessionList.begin(); it != sessionList.end(); ++it ) { - TQStringList sessionInfoList = TQStringList::split(',', *it, true); - if ((*(sessionInfoList.at(0))).startsWith(":")) { - if ((*(sessionInfoList.at(1))) == TQString(curConsole)) { - cvtName = (*(sessionInfoList.at(0))); - } - } - } - if (cvtName != "") { - if (TQString(currentDisplay).startsWith(cvtName)) { - return true; - } - else { - return false; - } - } - else { - // See if the current session is local - // If it is, then the VT is not currently active and the SAK must be requested later when it is active - for ( TQStringList::Iterator it = sessionList.begin(); it != sessionList.end(); ++it ) { - TQStringList sessionInfoList = TQStringList::split(',', *it, true); - if ((*(sessionInfoList.at(0))).startsWith(":")) { - if (TQString(currentDisplay).startsWith(*(sessionInfoList.at(0)))) { - return false; - } - } - } - // Hmm, not local - // Do not reject the SAK - return true; - } - } -} - -int main (int argc, char *argv[]) -{ - int mPipe_fd; - char readbuf[128]; - int numread; - - int verifier_result = tde_sak_verify_calling_process(); - - bool isdm = false; - if (argc == 2) { - if (strcmp(argv[1], "dm") == 0) { - isdm = true; - } - } - - if (!isdm) { - // Verify that the session is local - // Remote sessions cannot press the SAK for obvious reasons - if (!is_vt_local()) { - return 6; // SAK not available - } - } - - if (verifier_result == 0) { - // OK, the calling process is authorized to retrieve SAK data - // First, flush the buffer - mPipe_fd = open(FIFO_FILE, O_RDONLY | O_NONBLOCK); - numread = 1; - while (numread > 0) { - numread = read(mPipe_fd, readbuf, 6); - } - close(mPipe_fd); - // Now wait for SAK press - mPipe_fd = open(FIFO_FILE, O_RDONLY); - while (mPipe_fd > -1) { - numread = read(mPipe_fd, readbuf, 6); - readbuf[numread] = 0; - readbuf[127] = 0; - if (strcmp(readbuf, "SAK\n\r") == 0) { - close(mPipe_fd); - if (is_vt_active()) { - return 0; - } - else { - usleep(100); - // Flush the buffer - mPipe_fd = open(FIFO_FILE, O_RDONLY | O_NONBLOCK); - numread = 1; - while (numread > 0) { - numread = read(mPipe_fd, readbuf, 6); - } - close(mPipe_fd); - mPipe_fd = open(FIFO_FILE, O_RDONLY); - } - } - else { - usleep(100); - } - } - close(mPipe_fd); - return 6; - } - else { - return verifier_result; - } -} \ No newline at end of file diff --git a/kdmlib/kdmtsak.h b/kdmlib/kdmtsak.h deleted file mode 100644 index 1987a8218..000000000 --- a/kdmlib/kdmtsak.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - This file is part of the TDE project - Copyright (C) 2011 Timothy Pearson - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "config.h" - -// #define DEBUG - -inline int tde_sak_verify_calling_process() -{ - bool authorized = false; - - // Root always has access to everything... - if (getuid() == 0) { - return 0; - } - - pid_t parentproc = getppid(); -#ifdef DEBUG - printf("Parent pid is: %d\n\r", parentproc); -#endif - - char parentexecutable[8192]; - TQString procparent = TQString("/proc/%1/exe").arg(parentproc); - int chars = readlink(procparent.ascii(), parentexecutable, sizeof(parentexecutable)); - parentexecutable[chars] = 0; - parentexecutable[8191] = 0; - procparent = parentexecutable; -#ifdef DEBUG - printf("Parent executable name and full path is: %s\n\r", procparent.ascii()); -#endif - - TQString tdeBinaryPath = TQString(KDE_BINDIR "/"); -#ifdef DEBUG - printf("The TDE binary path is: %s\n\r", tdeBinaryPath.ascii()); -#endif - - if (!procparent.startsWith(tdeBinaryPath)) { - printf("Unauthorized path detected in calling process\n\r"); - return 2; - } - else { - procparent = procparent.mid(tdeBinaryPath.length()); -#ifdef DEBUG - printf("Parent executable name is: %s\n\r", procparent.ascii()); -#endif - if ((procparent == "kdesktop") || (procparent == "kdesktop_lock") || (procparent == "tdm")) { - authorized = true; - } - else if (procparent == "tdeinit") { - printf("tdeinit detected\n\r"); - // A bit more digging is needed to see if this is an authorized process or not - // Get the tdeinit command - char tdeinitcmdline[8192]; - FILE *fp = fopen(TQString("/proc/%1/cmdline").arg(parentproc).ascii(),"r"); - if (fp != NULL) { - if (fgets (tdeinitcmdline, 8192, fp) != NULL) - fclose (fp); - } - tdeinitcmdline[8191] = 0; - TQString tdeinitCommand = tdeinitcmdline; - - // Also get the environment, specifically the path - TQString tdeinitEnvironment; - char tdeinitenviron[8192]; - fp = fopen(TQString("/proc/%1/environ").arg(parentproc).ascii(),"r"); - if (fp != NULL) { - int c; - int pos = 0; - do { - c = fgetc(fp); - tdeinitenviron[pos] = c; - pos++; - if (c == 0) { - TQString curEnvLine = tdeinitenviron; - if (curEnvLine.startsWith("PATH=")) { - tdeinitEnvironment = curEnvLine.mid(5); - } - pos = 0; - } - } while ((c != EOF) && (pos < 8192)); - fclose (fp); - } - tdeinitenviron[8191] = 0; - -#ifdef DEBUG - printf("Called executable name is: %s\n\r", tdeinitCommand.ascii()); - printf("Environment is: %s\n\r", tdeinitEnvironment.ascii()); -#endif - - if ((tdeinitCommand == "kdesktop [tdeinit]") && (tdeinitEnvironment.startsWith(KDE_BINDIR))) { - authorized = true; - } - else { - return 4; - } - } - else { - printf("Unauthorized calling process detected\n\r"); - return 3; - } - - if (authorized == true) { - return 0; - } - } - - return 5; -} - -#undef DEBUG \ No newline at end of file diff --git a/kdmlib/kgreet_classic.cpp b/kdmlib/kgreet_classic.cpp deleted file mode 100644 index b37f2bab7..000000000 --- a/kdmlib/kgreet_classic.cpp +++ /dev/null @@ -1,513 +0,0 @@ -/* - -Conversation widget for tdm greeter - -Copyright (C) 1997, 1998, 2000 Steffen Hansen -Copyright (C) 2000-2003 Oswald Buddenhagen - - -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 "kgreet_classic.h" -#include "themer/tdmthemer.h" -#include "themer/tdmitem.h" - -#include -#include -#include -#include - -#include -#include -#include - -class TDMPasswordEdit : public KPasswordEdit { -public: - TDMPasswordEdit( TQWidget *parent ) : KPasswordEdit( parent, 0 ) {} - TDMPasswordEdit( KPasswordEdit::EchoModes echoMode, TQWidget *parent ) : KPasswordEdit( echoMode, parent, 0 ) {} -protected: - virtual void contextMenuEvent( TQContextMenuEvent * ) {} -}; - -static int echoMode; - -KClassicGreeter::KClassicGreeter( KGreeterPluginHandler *_handler, - KdmThemer *themer, - TQWidget *parent, TQWidget *pred, - const TQString &_fixedEntity, - Function _func, Context _ctx ) : - TQObject(), - KGreeterPlugin( _handler ), - fixedUser( _fixedEntity ), - func( _func ), - ctx( _ctx ), - exp( -1 ), - pExp( -1 ), - running( false ) -{ - KdmItem *user_entry = 0, *pw_entry = 0; - TQGridLayout *grid = 0; - int line = 0; - - layoutItem = 0; - - if (themer && - (!(user_entry = themer->findNode( "user-entry" )) || - !(pw_entry = themer->findNode( "pw-entry" )))) - themer = 0; - - if (!themer) - grid = new TQGridLayout( 0, 0, 10 ); - layoutItem = TQT_TQLAYOUTITEM(grid); - - loginLabel = passwdLabel = passwd1Label = passwd2Label = 0; - loginEdit = 0; - passwdEdit = passwd1Edit = passwd2Edit = 0; - if (ctx == ExUnlock || ctx == ExChangeTok) - fixedUser = KUser().loginName(); - if (func != ChAuthTok) { - if (fixedUser.isEmpty()) { - loginEdit = new KLineEdit( parent ); - loginEdit->setContextMenuEnabled( false ); - connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotLoginLostFocus()) ); - connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); - connect( loginEdit, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotActivity()) ); - connect( loginEdit, TQT_SIGNAL(selectionChanged()), TQT_SLOT(slotActivity()) ); - if (pred) { - parent->setTabOrder( pred, loginEdit ); - pred = loginEdit; - } - if (!grid) { - loginEdit->adjustSize(); - user_entry->setWidget( loginEdit ); - } else { - loginLabel = new TQLabel( loginEdit, i18n("&Username:"), parent ); - grid->addWidget( loginLabel, line, 0 ); - grid->addWidget( loginEdit, line++, 1 ); - } - } else if (ctx != Login && ctx != Shutdown && grid) { - loginLabel = new TQLabel( i18n("Username:"), parent ); - grid->addWidget( loginLabel, line, 0 ); - grid->addWidget( new TQLabel( fixedUser, parent ), line++, 1 ); - } - if (echoMode == -1) - passwdEdit = new TDMPasswordEdit( parent ); - else - passwdEdit = new TDMPasswordEdit( (KPasswordEdit::EchoModes)echoMode, - parent ); - connect( passwdEdit, TQT_SIGNAL(textChanged( const TQString & )), - TQT_SLOT(slotActivity()) ); - connect( passwdEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); - if (pred) { - parent->setTabOrder( pred, passwdEdit ); - pred = passwdEdit; - } - if (!grid) { - passwdEdit->adjustSize(); - pw_entry->setWidget( passwdEdit ); - } else { - passwdLabel = new TQLabel( passwdEdit, - func == Authenticate ? - i18n("&Password:") : - i18n("Current &password:"), - parent ); - grid->addWidget( passwdLabel, line, 0 ); - grid->addWidget( passwdEdit, line++, 1 ); - } - if (loginEdit) - loginEdit->setFocus(); - else - passwdEdit->setFocus(); - } - if (func != Authenticate) { - if (echoMode == -1) { - passwd1Edit = new TDMPasswordEdit( (KPasswordEdit::EchoModes)echoMode, parent ); - passwd2Edit = new TDMPasswordEdit( (KPasswordEdit::EchoModes)echoMode, parent ); - } else { - passwd1Edit = new TDMPasswordEdit( parent ); - passwd2Edit = new TDMPasswordEdit( parent ); - } - passwd1Label = new TQLabel( passwd1Edit, i18n("&New password:"), parent ); - passwd2Label = new TQLabel( passwd2Edit, i18n("Con&firm password:"), parent ); - if (pred) { - parent->setTabOrder( pred, passwd1Edit ); - parent->setTabOrder( passwd1Edit, passwd2Edit ); - } - if (grid) { - grid->addWidget( passwd1Label, line, 0 ); - grid->addWidget( passwd1Edit, line++, 1 ); - grid->addWidget( passwd2Label, line, 0 ); - grid->addWidget( passwd2Edit, line, 1 ); - } - if (!passwdEdit) - passwd1Edit->setFocus(); - } -} - -// virtual -KClassicGreeter::~KClassicGreeter() -{ - abort(); - if (!layoutItem) { - delete loginEdit; - delete passwdEdit; - return; - } - TQLayoutIterator it = TQT_TQLAYOUT(layoutItem)->iterator(); - for (TQLayoutItem *itm = it.current(); itm; itm = ++it) - delete itm->widget(); - delete layoutItem; -} - -void // virtual -KClassicGreeter::loadUsers( const TQStringList &users ) -{ - KCompletion *userNamesCompletion = new KCompletion; - userNamesCompletion->setItems( users ); - loginEdit->setCompletionObject( userNamesCompletion ); - loginEdit->setAutoDeleteCompletionObject( true ); - loginEdit->setCompletionMode( KGlobalSettings::CompletionAuto ); -} - -void // virtual -KClassicGreeter::presetEntity( const TQString &entity, int field ) -{ - loginEdit->setText( entity ); - if (field == 1) - passwdEdit->setFocus(); - else { - loginEdit->setFocus(); - loginEdit->selectAll(); - if (field == -1) { - passwdEdit->setText( " " ); - passwdEdit->setEnabled( false ); - authTok = false; - } - } - curUser = entity; -} - -TQString // virtual -KClassicGreeter::getEntity() const -{ - return fixedUser.isEmpty() ? loginEdit->text() : fixedUser; -} - -void // virtual -KClassicGreeter::setUser( const TQString &user ) -{ - // assert( fixedUser.isEmpty() ); - curUser = user; - loginEdit->setText( user ); - passwdEdit->setFocus(); - passwdEdit->selectAll(); -} - -void // virtual -KClassicGreeter::setPassword( const TQString &pass ) -{ - passwdEdit->erase(); - passwdEdit->insert( pass ); -} - -void // virtual -KClassicGreeter::setEnabled( bool enable ) -{ - // assert( !passwd1Label ); - // assert( func == Authenticate && ctx == Shutdown ); -// if (loginLabel) -// loginLabel->setEnabled( enable ); - passwdLabel->setEnabled( enable ); - setActive( enable ); - if (enable) - passwdEdit->setFocus(); -} - -void // private -KClassicGreeter::returnData() -{ - switch (exp) { - case 0: - handler->gplugReturnText( (loginEdit ? loginEdit->text() : - fixedUser).local8Bit(), - KGreeterPluginHandler::IsUser ); - break; - case 1: - handler->gplugReturnText( passwdEdit->password(), - KGreeterPluginHandler::IsPassword | - KGreeterPluginHandler::IsSecret ); - break; - case 2: - handler->gplugReturnText( passwd1Edit->password(), - KGreeterPluginHandler::IsSecret ); - break; - default: // case 3: - handler->gplugReturnText( passwd2Edit->password(), - KGreeterPluginHandler::IsNewPassword | - KGreeterPluginHandler::IsSecret ); - break; - } -} - -bool // virtual -KClassicGreeter::textMessage( const char *text, bool err ) -{ - if (!err && - TQString( text ).find( TQRegExp( "^Changing password for [^ ]+$" ) ) >= 0) - return true; - return false; -} - -void // virtual -KClassicGreeter::textPrompt( const char *prompt, bool echo, bool nonBlocking ) -{ - pExp = exp; - if (echo) - exp = 0; - else if (!authTok) - exp = 1; - else { - TQString pr( prompt ); - if (pr.find( TQRegExp( "\\bpassword\\b", false ) ) >= 0) { - if (pr.find( TQRegExp( "\\b(re-?(enter|type)|again|confirm|repeat)\\b", - false ) ) >= 0) - exp = 3; - else if (pr.find( TQRegExp( "\\bnew\\b", false ) ) >= 0) - exp = 2; - else { // TQRegExp( "\\b(old|current)\\b", false ) is too strict - handler->gplugReturnText( "", - KGreeterPluginHandler::IsOldPassword | - KGreeterPluginHandler::IsSecret ); - return; - } - } else { - handler->gplugMsgBox( TQMessageBox::Critical, - i18n("Unrecognized prompt \"%1\"") - .arg( prompt ) ); - handler->gplugReturnText( 0, 0 ); - exp = -1; - return; - } - } - - if (pExp >= 0 && pExp >= exp) { - revive(); - has = -1; - } - - if (has >= exp || nonBlocking) - returnData(); -} - -bool // virtual -KClassicGreeter::binaryPrompt( const char *, bool ) -{ - // this simply cannot happen ... :} - return true; -} - -void // virtual -KClassicGreeter::start() -{ - authTok = !(passwdEdit && passwdEdit->isEnabled()); - exp = has = -1; - running = true; -} - -void // virtual -KClassicGreeter::suspend() -{ -} - -void // virtual -KClassicGreeter::resume() -{ -} - -void // virtual -KClassicGreeter::next() -{ - // assert( running ); - if (loginEdit && loginEdit->hasFocus()) { - passwdEdit->setFocus(); // will cancel running login if necessary - has = 0; - } else if (passwdEdit && passwdEdit->hasFocus()) { - if (passwd1Edit) - passwd1Edit->setFocus(); - has = 1; - } else if (passwd1Edit) { - if (passwd1Edit->hasFocus()) { - passwd2Edit->setFocus(); - has = 1; // sic! - } else - has = 3; - } else - has = 1; - if (exp < 0) - handler->gplugStart(); - else if (has >= exp) - returnData(); -} - -void // virtual -KClassicGreeter::abort() -{ - running = false; - if (exp >= 0) { - exp = -1; - handler->gplugReturnText( 0, 0 ); - } -} - -void // virtual -KClassicGreeter::succeeded() -{ - // assert( running || timed_login ); - if (!authTok) { - setActive( false ); - if (passwd1Edit) { - authTok = true; - return; - } - } else - setActive2( false ); - exp = -1; - running = false; -} - -void // virtual -KClassicGreeter::failed() -{ - // assert( running || timed_login ); - setActive( false ); - setActive2( false ); - exp = -1; - running = false; -} - -void // virtual -KClassicGreeter::revive() -{ - // assert( !running ); - setActive2( true ); - if (authTok) { - passwd1Edit->erase(); - passwd2Edit->erase(); - passwd1Edit->setFocus(); - } else { - passwdEdit->erase(); - if (loginEdit && loginEdit->isEnabled()) - passwdEdit->setEnabled( true ); - else { - setActive( true ); - if (loginEdit && loginEdit->text().isEmpty()) - loginEdit->setFocus(); - else - passwdEdit->setFocus(); - } - } -} - -void // virtual -KClassicGreeter::clear() -{ - // assert( !running && !passwd1Edit ); - passwdEdit->erase(); - if (loginEdit) { - loginEdit->clear(); - loginEdit->setFocus(); - curUser = TQString::null; - } else - passwdEdit->setFocus(); -} - - -// private - -void -KClassicGreeter::setActive( bool enable ) -{ - if (loginEdit) - loginEdit->setEnabled( enable ); - if (passwdEdit) - passwdEdit->setEnabled( enable ); -} - -void -KClassicGreeter::setActive2( bool enable ) -{ - if (passwd1Edit) { - passwd1Edit->setEnabled( enable ); - passwd2Edit->setEnabled( enable ); - } -} - -void -KClassicGreeter::slotLoginLostFocus() -{ - if (!running) - return; - if (exp > 0) { - if (curUser == loginEdit->text()) - return; - exp = -1; - handler->gplugReturnText( 0, 0 ); - } - curUser = loginEdit->text(); - handler->gplugSetUser( curUser ); -} - -void -KClassicGreeter::slotActivity() -{ - if (running) - handler->gplugActivity(); -} - -// factory - -static bool init( const TQString &, - TQVariant (*getConf)( void *, const char *, const TQVariant & ), - void *ctx ) -{ - echoMode = getConf( ctx, "EchoMode", TQVariant( -1 ) ).toInt(); - KGlobal::locale()->insertCatalogue( "kgreet_classic" ); - return true; -} - -static void done( void ) -{ - KGlobal::locale()->removeCatalogue( "kgreet_classic" ); -} - -static KGreeterPlugin * -create( KGreeterPluginHandler *handler, KdmThemer *themer, - TQWidget *parent, TQWidget *predecessor, - const TQString &fixedEntity, - KGreeterPlugin::Function func, - KGreeterPlugin::Context ctx ) -{ - return new KClassicGreeter( handler, themer, parent, predecessor, fixedEntity, func, ctx ); -} - -KDE_EXPORT kgreeterplugin_info kgreeterplugin_info = { - I18N_NOOP("Username + password (classic)"), "classic", - kgreeterplugin_info::Local | kgreeterplugin_info::Presettable, - init, done, create -}; - -#include "kgreet_classic.moc" diff --git a/kdmlib/kgreet_classic.h b/kdmlib/kgreet_classic.h deleted file mode 100644 index 1f467a528..000000000 --- a/kdmlib/kgreet_classic.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - -Conversation widget for tdm greeter - -Copyright (C) 1997, 1998 Steffen Hansen -Copyright (C) 2000-2003 Oswald Buddenhagen - - -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. - -*/ - - -#ifndef KGREET_CLASSIC_H -#define KGREET_CLASSIC_H - -#include "kgreeterplugin.h" - -#include - -class KLineEdit; -class KPasswordEdit; -class KSimpleConfig; -class TQGridLayout; -class TQLabel; - -class KClassicGreeter : public TQObject, public KGreeterPlugin { - Q_OBJECT - - public: - KClassicGreeter( KGreeterPluginHandler *handler, - KdmThemer *themer, - TQWidget *parent, TQWidget *predecessor, - const TQString &fixedEntitiy, - Function func, Context ctx ); - ~KClassicGreeter(); - virtual void loadUsers( const TQStringList &users ); - virtual void presetEntity( const TQString &entity, int field ); - virtual TQString getEntity() const; - virtual void setUser( const TQString &user ); - virtual void setPassword( const TQString &pass ); - virtual void setEnabled( bool on ); - virtual bool textMessage( const char *message, bool error ); - virtual void textPrompt( const char *prompt, bool echo, bool nonBlocking ); - virtual bool binaryPrompt( const char *prompt, bool nonBlocking ); - virtual void start(); - virtual void suspend(); - virtual void resume(); - virtual void next(); - virtual void abort(); - virtual void succeeded(); - virtual void failed(); - virtual void revive(); - virtual void clear(); - - public slots: - void slotLoginLostFocus(); - void slotActivity(); - - private: - void setActive( bool enable ); - void setActive2( bool enable ); - void returnData(); - - TQLabel *loginLabel, *passwdLabel, *passwd1Label, *passwd2Label; - KLineEdit *loginEdit; - KPasswordEdit *passwdEdit, *passwd1Edit, *passwd2Edit; - KSimpleConfig *stsFile; - TQString fixedUser, curUser; - Function func; - Context ctx; - int exp, pExp, has; - bool running, authTok; -}; - -#endif /* KGREET_CLASSIC_H */ diff --git a/kdmlib/kgreet_pam.cpp b/kdmlib/kgreet_pam.cpp deleted file mode 100644 index 82506fb43..000000000 --- a/kdmlib/kgreet_pam.cpp +++ /dev/null @@ -1,675 +0,0 @@ -/* - -Conversation widget for tdm greeter - -Copyright (C) 2008 Dirk Mueller - -based on classic tdm greeter: - - Copyright (C) 1997, 1998, 2000 Steffen Hansen - Copyright (C) 2000-2003 Oswald Buddenhagen - - -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 "kgreet_pam.h" -#include "themer/tdmthemer.h" -#include "themer/tdmlabel.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -//#define PAM_GREETER_DEBUG - -class TDMPasswordEdit : public KPasswordEdit { -public: - TDMPasswordEdit( TQWidget *parent ) : KPasswordEdit( parent, 0 ) {} - TDMPasswordEdit( KPasswordEdit::EchoModes echoMode, TQWidget *parent ) : KPasswordEdit( echoMode, parent, 0 ) {} -protected: - virtual void contextMenuEvent( TQContextMenuEvent * ) {} -}; - -static FILE* log; -static void kg_debug(const char* fmt, ...) -{ - va_list lst; - va_start(lst, fmt); - -#ifdef PAM_GREETER_DEBUG -#if 0 - vfprintf(log, fmt, lst); - fflush(log); -#else - char buf[6000]; - sprintf(buf, "*** %s\n", fmt); - vsyslog(LOG_WARNING, buf, lst); -#endif -#endif - va_end(lst); -} - -static KPasswordEdit::EchoModes echoMode; - -KPamGreeter::KPamGreeter( KGreeterPluginHandler *_handler, - KdmThemer *themer, - TQWidget *parent, TQWidget *pred, - const TQString &_fixedEntity, - Function _func, Context _ctx ) : - TQObject(), - KGreeterPlugin( _handler ), - fixedUser( _fixedEntity ), - func( _func ), - ctx( _ctx ), - exp( -1 ), - pExp( -1 ), - running( false ) -{ - ctx = Login; - - kg_debug("KPamGreeter constructed\n"); - - m_parentWidget = parent; - - KdmItem *user_entry = 0, *pw_entry = 0; - int line = 0; - - layoutItem = 0; - - if (themer && - (!(user_entry = themer->findNode( "user-entry" )) || - !(pw_entry = themer->findNode( "pw-entry" )))) - themer = 0; - - m_themer = themer; - - if (!themer) - layoutItem = TQT_TQLAYOUTITEM(new TQGridLayout( 0, 0, 10 )); - - loginLabel = 0; - authLabel.clear(); - authEdit.clear(); - loginLabel = 0; - loginEdit = 0; - if (ctx == ExUnlock || ctx == ExChangeTok) - fixedUser = KUser().loginName(); - if (func != ChAuthTok) { - kg_debug("func != ChAuthTok\n"); - kg_debug("fixedUser: *%s*\n", fixedUser.latin1()); - - if (fixedUser.isEmpty()) { - loginEdit = new KLineEdit( parent ); - loginEdit->setContextMenuEnabled( false ); - connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotLoginLostFocus()) ); - connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); - connect( loginEdit, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotActivity()) ); - connect( loginEdit, TQT_SIGNAL(selectionChanged()), TQT_SLOT(slotActivity()) ); - if (pred) { - parent->setTabOrder( pred, loginEdit ); - pred = loginEdit; - } - if (!getLayoutItem()) { - loginEdit->adjustSize(); - user_entry->setWidget( loginEdit ); - } else { - loginLabel = new TQLabel( loginEdit, i18n("Username:"), parent ); - getLayoutItem()->addWidget( loginLabel, line, 0 ); - getLayoutItem()->addWidget( loginEdit, line++, 1 ); - } - } else if (ctx != Login && ctx != Shutdown && getLayoutItem()) { - loginLabel = new TQLabel( i18n("Username:"), parent ); - getLayoutItem()->addWidget( loginLabel, line, 0 ); - getLayoutItem()->addWidget( new TQLabel( fixedUser, parent ), line++, 1 ); - } -#if 0 - if (echoMode == -1) - passwdEdit = new TDMPasswordEdit( parent ); - else - passwdEdit = new TDMPasswordEdit( echoMode, - parent ); - connect( passwdEdit, TQT_SIGNAL(textChanged( const TQString & )), - TQT_SLOT(slotActivity()) ); - connect( passwdEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); - if (pred) { - parent->setTabOrder( pred, passwdEdit ); - pred = passwdEdit; - } - if (!getLayoutItem()) { - passwdEdit->adjustSize(); - pw_entry->setWidget( passwdEdit ); - } else { - passwdLabel = new TQLabel( passwdEdit, - func == Authenticate ? - i18n("hello &Password:") : - i18n("Current &password:"), - parent ); - getLayoutItem()->addWidget( passwdLabel, line, 0 ); - getLayoutItem()->addWidget( passwdEdit, line++, 1 ); - } -#endif - if (loginEdit) - loginEdit->setFocus(); - } - if (func != Authenticate) { - if (echoMode == -1) { - authEdit << new TDMPasswordEdit( echoMode, parent ); - authEdit << new TDMPasswordEdit( echoMode, parent ); - } else { - authEdit << new TDMPasswordEdit( parent ); - authEdit << new TDMPasswordEdit( parent ); - } - authLabel << new TQLabel( authEdit[0], i18n("&New password:"), parent ); - authLabel << new TQLabel( authEdit[1], i18n("Con&firm password:"), parent ); - if (pred) { - parent->setTabOrder( pred, authEdit[0] ); - parent->setTabOrder( authEdit[0], authEdit[1] ); - } - if (getLayoutItem()) { - getLayoutItem()->addWidget( authLabel[0], line, 0 ); - getLayoutItem()->addWidget( authEdit[0], line++, 1 ); - getLayoutItem()->addWidget( authLabel[1], line, 0 ); - getLayoutItem()->addWidget( authEdit[1], line, 1 ); - } - if (authEdit.size() >= 2) - authEdit[1]->setFocus(); - } -} - -// virtual -KPamGreeter::~KPamGreeter() -{ - kg_debug("KPamGreeter::~KPamGreeter"); - abort(); - if (!layoutItem) { - delete loginEdit; - return; - } - TQLayoutIterator it = TQT_TQLAYOUT(layoutItem)->iterator(); - for (TQLayoutItem *itm = it.current(); itm; itm = ++it) - delete itm->widget(); - delete layoutItem; - kg_debug("destructor finished, good bye"); -} - -void // virtual -KPamGreeter::loadUsers( const TQStringList &users ) -{ - KCompletion *userNamesCompletion = new KCompletion; - userNamesCompletion->setItems( users ); - loginEdit->setCompletionObject( userNamesCompletion ); - loginEdit->setAutoDeleteCompletionObject( true ); - loginEdit->setCompletionMode( KGlobalSettings::CompletionAuto ); -} - -void // virtual -KPamGreeter::presetEntity( const TQString &entity, int field ) -{ - kg_debug("presetEntity(%s,%d) called!\n", entity.latin1(), field); - loginEdit->setText( entity ); - if (field == 1 && authEdit.size() >= 1) - authEdit[0]->setFocus(); - else { - loginEdit->setFocus(); - loginEdit->selectAll(); - if (field == -1 && authEdit.size() >= 1) { - authEdit[0]->setText( " " ); - authEdit[0]->setEnabled( false ); - authTok = false; - } - } - curUser = entity; -} - -TQString // virtual -KPamGreeter::getEntity() const -{ - return fixedUser.isEmpty() ? loginEdit->text() : fixedUser; -} - -void // virtual -KPamGreeter::setUser( const TQString &user ) -{ - // assert( fixedUser.isEmpty() ); - curUser = user; - loginEdit->setText( user ); - if (authEdit.size() >= 1) { - authEdit[0]->setFocus(); - authEdit[0]->selectAll(); - } -} - -void // virtual -KPamGreeter::setPassword( const TQString &pass ) -{ - authEdit[0]->erase(); - authEdit[0]->insert( pass ); -} - -void // virtual -KPamGreeter::setEnabled(bool enable) -{ - // assert( !passwd1Label ); - // assert( func == Authenticate && ctx == Shutdown ); -// if (loginLabel) -// loginLabel->setEnabled( enable ); - authEdit[0]->setEnabled( enable ); - setActive( enable ); - if (enable) - authEdit[0]->setFocus(); - } - -void // private -KPamGreeter::returnData() -{ - kg_debug("*************** returnData called with exp %d\n", exp); - - - switch (exp) { - case 0: - handler->gplugReturnText( (loginEdit ? loginEdit->text() : - fixedUser).local8Bit(), - KGreeterPluginHandler::IsUser ); - break; - case 1: - handler->gplugReturnText( authEdit[0]->password(), - KGreeterPluginHandler::IsPassword | - KGreeterPluginHandler::IsSecret ); - break; - case 2: - handler->gplugReturnText( authEdit[1]->password(), - KGreeterPluginHandler::IsSecret ); - break; - default: // case 3: - handler->gplugReturnText( authEdit[2]->password(), - KGreeterPluginHandler::IsNewPassword | - KGreeterPluginHandler::IsSecret ); - break; - } -} - -bool // virtual -KPamGreeter::textMessage( const char *text, bool err ) -{ - kg_debug(" ************** textMessage(%s, %d)\n", text, err); - - if (!authEdit.size()) - return false; - - if (getLayoutItem()) { - TQLabel* label = new TQLabel(TQString::fromUtf8(text), m_parentWidget); - getLayoutItem()->addWidget(label, state+1, 0, 0); - } - - return true; -} - -void // virtual -KPamGreeter::textPrompt( const char *prompt, bool echo, bool nonBlocking ) -{ - kg_debug("textPrompt called with prompt %s echo %d nonBlocking %d", prompt, echo, nonBlocking); - kg_debug("state is %d, authEdit.size is %d\n", state, authEdit.size()); - - if (state == 0 && echo) { - if (loginLabel) - loginLabel->setText(TQString::fromUtf8(prompt)); - else if (m_themer) { - KdmLabel *tdmlabel = static_cast(m_themer->findNode("user-label")); - if (tdmlabel) { - //userLabel->setText(TQString::fromUtf8(prompt)); - tdmlabel->label.text = TQString::fromUtf8(prompt); - TQTimer::singleShot(0, tdmlabel, TQT_SLOT(update())); - } - } - } - else if (state >= authEdit.size()) { - if (getLayoutItem()) { - TQLabel* label = new TQLabel(TQString::fromUtf8(prompt), m_parentWidget); - getLayoutItem()->addWidget(label, state+1, 0, 0); - kg_debug("added label widget to layout"); - } - else if (m_themer) { - kg_debug("themer found!"); - KdmItem *pw_label = 0; - - KdmLabel *tdmlabel = static_cast(m_themer->findNode("pw-label")); - if (tdmlabel) { - //userLabel->setText(TQString::fromUtf8(prompt)); - TQString str = TQString::fromUtf8(prompt); - tdmlabel->label.text = str; - TQTimer::singleShot(0, tdmlabel, TQT_SLOT(update())); - } - } - - TDMPasswordEdit* passwdEdit; - - if (echoMode == -1) - passwdEdit = new TDMPasswordEdit( m_parentWidget ); - else - passwdEdit = new TDMPasswordEdit( echoMode, m_parentWidget); - connect( passwdEdit, TQT_SIGNAL(textChanged( const TQString & )), - TQT_SLOT(slotActivity()) ); - connect( passwdEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); - authEdit << passwdEdit; - -#if 1 - for(TQValueList::iterator it = authEdit.begin(); - it != authEdit.end(); - ++it) { - if ((*it)->isEnabled() && (*it)->text().isEmpty()) { - (*it)->setFocus(); - break; - } - } -#endif - if (getLayoutItem()) - getLayoutItem()->addWidget(passwdEdit, state+1, 1, 0); - - if (m_themer) { - kg_debug("themer found!"); - KdmItem *pw_entry = 0; - - pw_entry = m_themer->findNode("pw-entry"); - - if (pw_entry && passwdEdit) - pw_entry->setWidget(passwdEdit); - - if (0) { - //userLabel->setText(TQString::fromUtf8(prompt)); - //tdmlabel->label.text = TQString::fromUtf8(prompt); - //TQTimer::singleShot(0, tdmlabel, TQT_SLOT(update())); - } - } - else - kg_debug("no themer found!"); - } - ++state; - pExp = exp; - - exp = authEdit.size(); - kg_debug("state %d exp: %d, has %d\n", state, exp, has); - - if (has >= exp || nonBlocking) - returnData(); -} - -bool // virtual -KPamGreeter::binaryPrompt( const char *, bool ) -{ - // this simply cannot happen ... :} - return true; -} - -void // virtual -KPamGreeter::start() -{ - kg_debug("******* start() called\n"); - - while(authEdit.begin() != authEdit.end()) { - KPasswordEdit* item = *authEdit.remove(authEdit.begin()); - delete item; - } - - while(authLabel.begin() != authLabel.end()) { - TQLabel* item = *authLabel.remove(authLabel.begin()); - delete item; - } - - authTok = !(authEdit.size() >= 2 && authEdit[1]->isEnabled()); - exp = has = -1; - state = 0; - running = true; - handler->gplugStart(); -} - -void // virtual -KPamGreeter::suspend() -{ -} - -void // virtual -KPamGreeter::resume() -{ -} - -void // virtual -KPamGreeter::next() -{ - kg_debug("********* next() called state %d\n", state); - - if (state == 0 && running && handler) { - kg_debug(" **** returned text!\n"); - handler->gplugReturnText( (loginEdit ? loginEdit->text() : - fixedUser).local8Bit(), - KGreeterPluginHandler::IsUser ); - setActive(false); - } - - has = 0; - - for(TQValueList::iterator it = authEdit.begin(); - it != authEdit.end(); - ++it) { - - has++; - if ((*it)->hasFocus()) { - ++it; - if (it != authEdit.end()) - (*it)->setFocus(); - break; - } - if (it == authEdit.end()) - has = -1; - } - - kg_debug(" has %d and exp %d\n", has, exp); - -#if 0 - // assert( running ); - if (loginEdit && loginEdit->hasFocus()) { - passwdEdit->setFocus(); // will cancel running login if necessary - has = 0; - } else if (passwdEdit && passwdEdit->hasFocus()) { - if (passwd1Edit) - passwd1Edit->setFocus(); - has = 1; - } else if (passwd1Edit) { - if (passwd1Edit->hasFocus()) { - passwd2Edit->setFocus(); - has = 1; // sic! - } else - has = 3; - } else - has = 1; - if (exp < 0) - handler->gplugStart(); -#endif - if (has >= exp) - returnData(); -} - -void // virtual -KPamGreeter::abort() -{ - kg_debug("***** abort() called\n"); - - running = false; - if (exp >= 0) { - exp = -1; - handler->gplugReturnText( 0, 0 ); - } -} - -void // virtual -KPamGreeter::succeeded() -{ - kg_debug("**** succeeded() called\n"); - - // assert( running || timed_login ); - if (!authTok) - setActive( false ); - else - setAllActive( false ); - exp = -1; - running = false; -} - -void // virtual -KPamGreeter::failed() -{ - // assert( running || timed_login ); - setActive( false ); - setAllActive( false ); - exp = -1; - running = false; -} - -#include -void // virtual -KPamGreeter::revive() -{ - // assert( !running ); - setAllActive( true ); - -#if 1 - if (authEdit.size() < 1) - return; -#endif - - assert(authEdit.size() >= 1); - if (authTok) { - authEdit[0]->erase(); - if(authEdit.size() >= 2) - authEdit[1]->erase(); - authEdit[0]->setFocus(); - } else { - authEdit[0]->erase(); - if (loginEdit && loginEdit->isEnabled()) - authEdit[0]->setEnabled( true ); - else { - setActive( true ); - if (loginEdit && loginEdit->text().isEmpty()) - loginEdit->setFocus(); - else - authEdit[0]->setFocus(); - } - } -} - -void // virtual -KPamGreeter::clear() -{ - // assert( !running && !passwd1Edit ); - authEdit[0]->erase(); - if (loginEdit) { - loginEdit->clear(); - loginEdit->setFocus(); - curUser = TQString::null; - } else - authEdit[0]->setFocus(); -} - - -// private - -void -KPamGreeter::setActive( bool enable ) -{ - if (loginEdit) - loginEdit->setEnabled( enable ); -} - -void -KPamGreeter::setAllActive( bool enable ) -{ - for(TQValueList::iterator it = authEdit.begin(); - it != authEdit.end(); - ++it) - (*it)->setEnabled( enable ); -} - -void -KPamGreeter::slotLoginLostFocus() -{ - if (!running) - return; - if (exp > 0) { - if (curUser == loginEdit->text()) - return; - exp = -1; - handler->gplugReturnText( 0, 0 ); - } - curUser = loginEdit->text(); - kg_debug("curUser is %s", curUser.latin1()); - handler->gplugSetUser( curUser ); -} - -void -KPamGreeter::slotActivity() -{ - kg_debug("slotActivity"); - - if (running) - handler->gplugActivity(); -} - -// factory - -static bool init( const TQString &, - TQVariant (*getConf)( void *, const char *, const TQVariant & ), - void *ctx ) -{ - echoMode = (KPasswordEdit::EchoModes) getConf( ctx, "EchoMode", TQVariant( -1 ) ).toInt(); - KGlobal::locale()->insertCatalogue( "kgreet_pam" ); - return true; -} - -static void done( void ) -{ - KGlobal::locale()->removeCatalogue( "kgreet_pam" ); - if (log && log != stderr) - fclose(log); - log = 0; -} - -static KGreeterPlugin * -create( KGreeterPluginHandler *handler, KdmThemer *themer, - TQWidget *parent, TQWidget *predecessor, - const TQString &fixedEntity, - KGreeterPlugin::Function func, - KGreeterPlugin::Context ctx ) -{ - return new KPamGreeter( handler, themer, parent, predecessor, fixedEntity, func, ctx ); -} - -KDE_EXPORT kgreeterplugin_info kgreeterplugin_info = { - I18N_NOOP("Pam conversation plugin"), "pam", - kgreeterplugin_info::Local | kgreeterplugin_info::Presettable, - init, done, create -}; - -#include "kgreet_pam.moc" diff --git a/kdmlib/kgreet_pam.h b/kdmlib/kgreet_pam.h deleted file mode 100644 index 03c404c1e..000000000 --- a/kdmlib/kgreet_pam.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - -Conversation widget for tdm greeter - -Copyright (C) 2008 Dirk Mueller - - -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. - -*/ - - -#ifndef KGREET_CLASSIC_H -#define KGREET_CLASSIC_H - -#include "kgreeterplugin.h" - -#include -#include - -class KLineEdit; -class KPasswordEdit; -class KSimpleConfig; -class TQGridLayout; -class TQLabel; - -class KPamGreeter : public TQObject, public KGreeterPlugin { - Q_OBJECT - - public: - KPamGreeter( KGreeterPluginHandler *handler, - KdmThemer *themer, - TQWidget *parent, TQWidget *predecessor, - const TQString &fixedEntitiy, - Function func, Context ctx ); - ~KPamGreeter(); - virtual void loadUsers( const TQStringList &users ); - virtual void presetEntity( const TQString &entity, int field ); - virtual TQString getEntity() const; - virtual void setUser( const TQString &user ); - virtual void setPassword( const TQString &pass ); - virtual void setEnabled( bool on ); - virtual bool textMessage( const char *message, bool error ); - virtual void textPrompt( const char *prompt, bool echo, bool nonBlocking ); - virtual bool binaryPrompt( const char *prompt, bool nonBlocking ); - virtual void start(); - virtual void suspend(); - virtual void resume(); - virtual void next(); - virtual void abort(); - virtual void succeeded(); - virtual void failed(); - virtual void revive(); - virtual void clear(); - - TQGridLayout *getLayoutItem() const { return static_cast(TQT_TQLAYOUT(layoutItem)); } - - public slots: - void slotLoginLostFocus(); - void slotActivity(); - - private: - void setActive( bool enable ); - void setAllActive( bool enable ); - void returnData(); - - TQLabel *loginLabel; - TQValueList authLabel; - KLineEdit *loginEdit; - TQWidget* m_parentWidget; - TQValueList authEdit; - KSimpleConfig *stsFile; - KdmThemer *m_themer; - TQString fixedUser, curUser; - Function func; - Context ctx; - int exp, pExp, has; - unsigned state; - bool running, authTok; -}; - -#endif /* KGREET_CLASSIC_H */ diff --git a/kdmlib/kgreet_winbind.cpp b/kdmlib/kgreet_winbind.cpp deleted file mode 100644 index d5626a3fd..000000000 --- a/kdmlib/kgreet_winbind.cpp +++ /dev/null @@ -1,679 +0,0 @@ -/* - -Conversation widget for tdm greeter - -Copyright (C) 1997, 1998, 2000 Steffen Hansen -Copyright (C) 2000-2004 Oswald Buddenhagen - - -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 "kgreet_winbind.h" -#include "themer/tdmthemer.h" -#include "themer/tdmitem.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -class TDMPasswordEdit : public KPasswordEdit { -public: - TDMPasswordEdit( TQWidget *parent ) : KPasswordEdit( parent, 0 ) {} - TDMPasswordEdit( KPasswordEdit::EchoModes echoMode, TQWidget *parent ) : KPasswordEdit( echoMode, parent, 0 ) {} -protected: - virtual void contextMenuEvent( TQContextMenuEvent * ) {} -}; - -static int echoMode; -static char separator; -static TQStringList staticDomains; -static TQString defaultDomain; - -static void -splitEntity( const TQString &ent, TQString &dom, TQString &usr ) -{ - int pos = ent.find( separator ); - if (pos < 0) - dom = "", usr = ent; - else - dom = ent.left( pos ), usr = ent.mid( pos + 1 ); -} - -KWinbindGreeter::KWinbindGreeter( KGreeterPluginHandler *_handler, - KdmThemer *themer, - TQWidget *parent, TQWidget *pred, - const TQString &_fixedEntity, - Function _func, Context _ctx ) : - TQObject(), - KGreeterPlugin( _handler ), - func( _func ), - ctx( _ctx ), - exp( -1 ), - pExp( -1 ), - running( false ) -{ - KdmItem *user_entry = 0, *pw_entry = 0, *domain_entry = 0; - TQGridLayout *grid = 0; - - int line = 0; - layoutItem = 0; - - if (themer && - (!(user_entry = themer->findNode( "user-entry" )) || - !(pw_entry = themer->findNode( "pw-entry" )) || - !(domain_entry = themer->findNode( "domain-entry" )))) - themer = 0; - - if (!themer) - grid = new TQGridLayout( 0, 0, 10 ); - layoutItem = TQT_TQLAYOUTITEM(grid); - - domainLabel = loginLabel = passwdLabel = passwd1Label = passwd2Label = 0; - domainCombo = 0; - loginEdit = 0; - passwdEdit = passwd1Edit = passwd2Edit = 0; - m_domainLister = 0; - if (ctx == ExUnlock || ctx == ExChangeTok) - splitEntity( KUser().loginName(), fixedDomain, fixedUser ); - else - splitEntity( _fixedEntity, fixedDomain, fixedUser ); - if (func != ChAuthTok) { - if (fixedUser.isEmpty()) { - domainCombo = new KComboBox( parent ); - connect( domainCombo, TQT_SIGNAL(activated( const TQString & )), - TQT_SLOT(slotChangedDomain( const TQString & )) ); - connect( domainCombo, TQT_SIGNAL(activated( const TQString & )), - TQT_SLOT(slotLoginLostFocus()) ); - connect( domainCombo, TQT_SIGNAL(activated( const TQString & )), - TQT_SLOT(slotActivity()) ); - // should handle loss of focus - loginEdit = new KLineEdit( parent ); - loginEdit->setContextMenuEnabled( false ); - - if (pred) { - parent->setTabOrder( pred, domainCombo ); - parent->setTabOrder( domainCombo, loginEdit ); - pred = loginEdit; - } - if (!grid) { - loginEdit->adjustSize(); - domainCombo->adjustSize(); - user_entry->setWidget( loginEdit ); - domain_entry->setWidget( domainCombo ); - } else { - domainLabel = new TQLabel( domainCombo, i18n("&Domain:"), parent ); - loginLabel = new TQLabel( loginEdit, i18n("&Username:"), parent ); - grid->addWidget( domainLabel, line, 0 ); - grid->addWidget( domainCombo, line++, 1 ); - grid->addWidget( loginLabel, line, 0 ); - grid->addWidget( loginEdit, line++, 1 ); - } - connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotLoginLostFocus()) ); - connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); - connect( loginEdit, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotActivity()) ); - connect( loginEdit, TQT_SIGNAL(selectionChanged()), TQT_SLOT(slotActivity()) ); - connect(&mDomainListTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotStartDomainList())); - domainCombo->insertStringList( staticDomains ); - TQTimer::singleShot(0, this, TQT_SLOT(slotStartDomainList())); - } else if (ctx != Login && ctx != Shutdown && grid) { - domainLabel = new TQLabel( i18n("Domain:"), parent ); - grid->addWidget( domainLabel, line, 0 ); - grid->addWidget( new TQLabel( fixedDomain, parent ), line++, 1 ); - loginLabel = new TQLabel( i18n("Username:"), parent ); - grid->addWidget( loginLabel, line, 0 ); - grid->addWidget( new TQLabel( fixedUser, parent ), line++, 1 ); - } - if (echoMode == -1) - passwdEdit = new TDMPasswordEdit( parent ); - else - passwdEdit = new TDMPasswordEdit( (KPasswordEdit::EchoModes)echoMode, - parent ); - connect( passwdEdit, TQT_SIGNAL(textChanged( const TQString & )), - TQT_SLOT(slotActivity()) ); - connect( passwdEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); - - if (!grid) { - passwdEdit->adjustSize(); - pw_entry->setWidget( passwdEdit ); - } else { - passwdLabel = new TQLabel( passwdEdit, - func == Authenticate ? - i18n("&Password:") : - i18n("Current &password:"), - parent ); - if (pred) { - parent->setTabOrder( pred, passwdEdit ); - pred = passwdEdit; - } - grid->addWidget( passwdLabel, line, 0 ); - grid->addWidget( passwdEdit, line++, 1 ); - } - - if (loginEdit) - loginEdit->setFocus(); - else - passwdEdit->setFocus(); - } - if (func != Authenticate) { - if (echoMode == -1) { - passwd1Edit = new TDMPasswordEdit( (KPasswordEdit::EchoModes)echoMode, parent ); - passwd2Edit = new TDMPasswordEdit( (KPasswordEdit::EchoModes)echoMode, parent ); - } else { - passwd1Edit = new TDMPasswordEdit( parent ); - passwd2Edit = new TDMPasswordEdit( parent ); - } - passwd1Label = new TQLabel( passwd1Edit, i18n("&New password:"), parent ); - passwd2Label = new TQLabel( passwd2Edit, i18n("Con&firm password:"), parent ); - if (pred) { - parent->setTabOrder( pred, passwd1Edit ); - parent->setTabOrder( passwd1Edit, passwd2Edit ); - } - if (grid) { - grid->addWidget( passwd1Label, line, 0 ); - grid->addWidget( passwd1Edit, line++, 1 ); - grid->addWidget( passwd2Label, line, 0 ); - grid->addWidget( passwd2Edit, line, 1 ); - } - if (!passwdEdit) - passwd1Edit->setFocus(); - } -} - -// virtual -KWinbindGreeter::~KWinbindGreeter() -{ - abort(); - if (!layoutItem) { - delete loginEdit; - delete passwdEdit; - delete domainCombo; - return; - } - TQLayoutIterator it = TQT_TQLAYOUT(layoutItem)->iterator(); - for (TQLayoutItem *itm = it.current(); itm; itm = ++it) - delete itm->widget(); - delete layoutItem; - delete m_domainLister; -} - -void -KWinbindGreeter::slotChangedDomain( const TQString &dom ) -{ - if (!loginEdit->completionObject()) - return; - TQStringList users; - if (dom == "") { - for (TQStringList::ConstIterator it = allUsers.begin(); it != allUsers.end(); ++it) - if ((*it).find( separator ) < 0) - users << *it; - } else { - TQString st( dom + separator ); - for (TQStringList::ConstIterator it = allUsers.begin(); it != allUsers.end(); ++it) - if ((*it).startsWith( st )) - users << (*it).mid( st.length() ); - } - loginEdit->completionObject()->setItems( users ); -} - -void // virtual -KWinbindGreeter::loadUsers( const TQStringList &users ) -{ - allUsers = users; - KCompletion *userNamesCompletion = new KCompletion; - loginEdit->setCompletionObject( userNamesCompletion ); - loginEdit->setAutoDeleteCompletionObject( true ); - loginEdit->setCompletionMode( KGlobalSettings::CompletionAuto ); - slotChangedDomain( defaultDomain ); -} - -void // virtual -KWinbindGreeter::presetEntity( const TQString &entity, int field ) -{ - TQString dom, usr; - splitEntity( entity, dom, usr ); - domainCombo->setCurrentItem( dom, true ); - slotChangedDomain( dom ); - loginEdit->setText( usr ); - if (field > 1) - passwdEdit->setFocus(); - else if (field == 1 || field == -1) { - if (field == -1) { - passwdEdit->setText( " " ); - passwdEdit->setEnabled( false ); - authTok = false; - } - loginEdit->setFocus(); - loginEdit->selectAll(); - } - curUser = entity; -} - -TQString // virtual -KWinbindGreeter::getEntity() const -{ - TQString dom, usr; - if (fixedUser.isEmpty()) - dom = domainCombo->currentText(), usr = loginEdit->text(); - else - dom = fixedDomain, usr = fixedUser; - return dom == "" ? usr : dom + separator + usr; -} - -void // virtual -KWinbindGreeter::setUser( const TQString &user ) -{ - // assert (fixedUser.isEmpty()); - curUser = user; - TQString dom, usr; - splitEntity( user, dom, usr ); - domainCombo->setCurrentItem( dom, true ); - slotChangedDomain( dom ); - loginEdit->setText( usr ); - passwdEdit->setFocus(); - passwdEdit->selectAll(); -} - -void // virtual -KWinbindGreeter::setPassword( const TQString &pass ) -{ - passwdEdit->erase(); - passwdEdit->insert( pass ); -} - -void // virtual -KWinbindGreeter::setEnabled( bool enable ) -{ - // assert( !passwd1Label ); - // assert( func == Authenticate && ctx == Shutdown ); -// if (domainCombo) -// domainCombo->setEnabled( enable ); -// if (loginLabel) -// loginLabel->setEnabled( enable ); - passwdLabel->setEnabled( enable ); - setActive( enable ); - if (enable) - passwdEdit->setFocus(); -} - -void // private -KWinbindGreeter::returnData() -{ - switch (exp) { - case 0: - handler->gplugReturnText( getEntity().local8Bit(), - KGreeterPluginHandler::IsUser ); - break; - case 1: - handler->gplugReturnText( passwdEdit->password(), - KGreeterPluginHandler::IsPassword | - KGreeterPluginHandler::IsSecret ); - break; - case 2: - handler->gplugReturnText( passwd1Edit->password(), - KGreeterPluginHandler::IsSecret ); - break; - default: // case 3: - handler->gplugReturnText( passwd2Edit->password(), - KGreeterPluginHandler::IsNewPassword | - KGreeterPluginHandler::IsSecret ); - break; - } -} - -bool // virtual -KWinbindGreeter::textMessage( const char *text, bool err ) -{ - if (!err && - TQString( text ).find( TQRegExp( "^Changing password for [^ ]+$" ) ) >= 0) - return true; - return false; -} - -void // virtual -KWinbindGreeter::textPrompt( const char *prompt, bool echo, bool nonBlocking ) -{ - pExp = exp; - if (echo) - exp = 0; - else if (!authTok) - exp = 1; - else { - TQString pr( prompt ); - if (pr.find( TQRegExp( "\\b(old|current)\\b", false ) ) >= 0) { - handler->gplugReturnText( "", - KGreeterPluginHandler::IsOldPassword | - KGreeterPluginHandler::IsSecret ); - return; - } else if (pr.find( TQRegExp( "\\b(re-?(enter|type)|again|confirm|repeat)\\b", - false ) ) >= 0) - exp = 3; - else if (pr.find( TQRegExp( "\\bnew\\b", false ) ) >= 0) - exp = 2; - else { - handler->gplugMsgBox( TQMessageBox::Critical, - i18n("Unrecognized prompt \"%1\"") - .arg( prompt ) ); - handler->gplugReturnText( 0, 0 ); - exp = -1; - return; - } - } - - if (pExp >= 0 && pExp >= exp) { - revive(); - has = -1; - } - - if (has >= exp || nonBlocking) - returnData(); -} - -bool // virtual -KWinbindGreeter::binaryPrompt( const char *, bool ) -{ - // this simply cannot happen ... :} - return true; -} - -void // virtual -KWinbindGreeter::start() -{ - authTok = !(passwdEdit && passwdEdit->isEnabled()); - exp = has = -1; - running = true; -} - -void // virtual -KWinbindGreeter::suspend() -{ -} - -void // virtual -KWinbindGreeter::resume() -{ -} - -void // virtual -KWinbindGreeter::next() -{ - // assert( running ); - if (domainCombo && domainCombo->hasFocus()) - loginEdit->setFocus(); - else if (loginEdit && loginEdit->hasFocus()) { - passwdEdit->setFocus(); // will cancel running login if necessary - has = 0; - } else if (passwdEdit && passwdEdit->hasFocus()) { - if (passwd1Edit) - passwd1Edit->setFocus(); - has = 1; - } else if (passwd1Edit) { - if (passwd1Edit->hasFocus()) { - passwd2Edit->setFocus(); - has = 1; // sic! - } else - has = 3; - } else - has = 1; - if (exp < 0) - handler->gplugStart(); - else if (has >= exp) - returnData(); -} - -void // virtual -KWinbindGreeter::abort() -{ - running = false; - if (exp >= 0) { - exp = -1; - handler->gplugReturnText( 0, 0 ); - } -} - -void // virtual -KWinbindGreeter::succeeded() -{ - // assert( running || timed_login ); - if (!authTok) { - setActive( false ); - if (passwd1Edit) { - authTok = true; - return; - } - } else - setActive2( false ); - exp = -1; - running = false; -} - -void // virtual -KWinbindGreeter::failed() -{ - // assert( running || timed_login ); - setActive( false ); - setActive2( false ); - exp = -1; - running = false; -} - -void // virtual -KWinbindGreeter::revive() -{ - // assert( !running ); - setActive2( true ); - if (authTok) { - passwd1Edit->erase(); - passwd2Edit->erase(); - passwd1Edit->setFocus(); - } else { - passwdEdit->erase(); - if (loginEdit && loginEdit->isEnabled()) - passwdEdit->setEnabled( true ); - else { - setActive( true ); - if (loginEdit && loginEdit->text().isEmpty()) - loginEdit->setFocus(); - else - passwdEdit->setFocus(); - } - } -} - -void // virtual -KWinbindGreeter::clear() -{ - // assert( !running && !passwd1Edit ); - passwdEdit->erase(); - if (loginEdit) { - domainCombo->setCurrentItem( defaultDomain ); - slotChangedDomain( defaultDomain ); - loginEdit->clear(); - loginEdit->setFocus(); - curUser = TQString::null; - } else - passwdEdit->setFocus(); -} - - -// private - -void -KWinbindGreeter::setActive( bool enable ) -{ - if (domainCombo) - domainCombo->setEnabled( enable ); - if (loginEdit) - loginEdit->setEnabled( enable ); - if (passwdEdit) - passwdEdit->setEnabled( enable ); -} - -void -KWinbindGreeter::setActive2( bool enable ) -{ - if (passwd1Edit) { - passwd1Edit->setEnabled( enable ); - passwd2Edit->setEnabled( enable ); - } -} - -void -KWinbindGreeter::slotLoginLostFocus() -{ - if (!running) - return; - TQString ent( getEntity() ); - if (exp > 0) { - if (curUser == ent) - return; - exp = -1; - handler->gplugReturnText( 0, 0 ); - } - curUser = ent; - handler->gplugSetUser( curUser ); -} - -void -KWinbindGreeter::slotActivity() -{ - if (running) - handler->gplugActivity(); -} - -void -KWinbindGreeter::slotStartDomainList() -{ - mDomainListTimer.stop(); - mDomainListing.clear(); - - m_domainLister = new KProcIO; - connect(m_domainLister, TQT_SIGNAL(readReady(KProcIO*)), TQT_SLOT(slotReadDomainList())); - connect(m_domainLister, TQT_SIGNAL(processExited(KProcess*)), TQT_SLOT(slotEndDomainList())); - - (*m_domainLister) << "wbinfo" << "--own-domain" << "--trusted-domains"; - m_domainLister->setComm (KProcess::Stdout); - m_domainLister->start(); -} - -void -KWinbindGreeter::slotReadDomainList() -{ - TQString line; - - while ( m_domainLister->readln( line ) != -1 ) { - mDomainListing.append(line); - } -} - -void -KWinbindGreeter::slotEndDomainList() -{ - delete m_domainLister; - m_domainLister = 0; - - TQStringList domainList; - domainList = staticDomains; - - for (TQStringList::const_iterator it = mDomainListing.begin(); - it != mDomainListing.end(); ++it) { - - if (!domainList.contains(*it)) - domainList.append(*it); - } - - TQString current = domainCombo->currentText(); - - for (int i = 0; i < domainList.count(); ++i) { - if (i < domainCombo->count()) - domainCombo->changeItem(domainList[i], i); - else - domainCombo->insertItem(domainList[i], i); - } - - while (domainCombo->count() > domainList.count()) - domainCombo->removeItem(domainCombo->count()-1); - - domainCombo->setCurrentItem( current ); - - if (domainCombo->currentText() != current) - domainCombo->setCurrentItem( defaultDomain ); - - mDomainListTimer.start(5 * 1000); -} - -// factory - -static bool init( const TQString &, - TQVariant (*getConf)( void *, const char *, const TQVariant & ), - void *ctx ) -{ - echoMode = getConf( ctx, "EchoMode", TQVariant( -1 ) ).toInt(); - staticDomains = TQStringList::split( ':', getConf( ctx, "winbind.Domains", TQVariant( "" ) ).toString() ); - if (!staticDomains.contains("")) - staticDomains << ""; - - defaultDomain = getConf( ctx, "winbind.DefaultDomain", TQVariant( staticDomains.first() ) ).toString(); - TQString sepstr = getConf( ctx, "winbind.Separator", TQVariant( TQString::null ) ).toString(); - if (sepstr.isNull()) { - FILE *sepfile = popen( "wbinfo --separator 2>/dev/null", "r" ); - if (sepfile) { - TQTextIStream( sepfile ) >> sepstr; - if (pclose( sepfile )) - sepstr = "\\"; - } else - sepstr = "\\"; - } - separator = sepstr[0].latin1(); - KGlobal::locale()->insertCatalogue( "kgreet_winbind" ); - return true; -} - -static void done( void ) -{ - KGlobal::locale()->removeCatalogue( "kgreet_winbind" ); - // avoid static deletion problems ... hopefully - staticDomains.clear(); - defaultDomain = TQString::null; -} - -static KGreeterPlugin * -create( KGreeterPluginHandler *handler, KdmThemer *themer, - TQWidget *parent, TQWidget *predecessor, - const TQString &fixedEntity, - KGreeterPlugin::Function func, - KGreeterPlugin::Context ctx ) -{ - return new KWinbindGreeter( handler, themer, parent, predecessor, fixedEntity, func, ctx ); -} - -KDE_EXPORT kgreeterplugin_info kgreeterplugin_info = { - I18N_NOOP("Winbind / Samba"), "classic", - kgreeterplugin_info::Local | kgreeterplugin_info::Fielded | kgreeterplugin_info::Presettable, - init, done, create -}; - -#include "kgreet_winbind.moc" diff --git a/kdmlib/kgreet_winbind.h b/kdmlib/kgreet_winbind.h deleted file mode 100644 index 54f2653fc..000000000 --- a/kdmlib/kgreet_winbind.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - -Conversation widget for tdm greeter - -Copyright (C) 1997, 1998 Steffen Hansen -Copyright (C) 2000-2003 Oswald Buddenhagen - - -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. - -*/ - - -#ifndef KGREET_WINBIND_H -#define KGREET_WINBIND_H - -#include "kgreeterplugin.h" - -#include -#include - -class KComboBox; -class KLineEdit; -class KPasswordEdit; -class KSimpleConfig; -class TQGridLayout; -class TQLabel; -class KdmThemer; -class KProcIO; - -class KWinbindGreeter : public TQObject, public KGreeterPlugin { - Q_OBJECT - - public: - KWinbindGreeter( KGreeterPluginHandler *handler, - KdmThemer *themer, - TQWidget *parent, TQWidget *predecessor, - const TQString &fixedEntitiy, - Function func, Context ctx ); - ~KWinbindGreeter(); - virtual void loadUsers( const TQStringList &users ); - virtual void presetEntity( const TQString &entity, int field ); - virtual TQString getEntity() const; - virtual void setUser( const TQString &user ); - virtual void setPassword( const TQString &pass ); - virtual void setEnabled( bool on ); - virtual bool textMessage( const char *message, bool error ); - virtual void textPrompt( const char *prompt, bool echo, bool nonBlocking ); - virtual bool binaryPrompt( const char *prompt, bool nonBlocking ); - virtual void start(); - virtual void suspend(); - virtual void resume(); - virtual void next(); - virtual void abort(); - virtual void succeeded(); - virtual void failed(); - virtual void revive(); - virtual void clear(); - - public slots: - void slotLoginLostFocus(); - void slotChangedDomain( const TQString &dom ); - void slotActivity(); - void slotStartDomainList(); - void slotReadDomainList(); - void slotEndDomainList(); - - private: - void setActive( bool enable ); - void setActive2( bool enable ); - void returnData(); - - TQLabel *domainLabel, *loginLabel, *passwdLabel, *passwd1Label, *passwd2Label; - KComboBox *domainCombo; - KLineEdit *loginEdit; - KPasswordEdit *passwdEdit, *passwd1Edit, *passwd2Edit; - KSimpleConfig *stsFile; - TQString fixedDomain, fixedUser, curUser; - TQStringList allUsers, mDomainListing; - KProcIO* m_domainLister; - TQTimer mDomainListTimer; - - Function func; - Context ctx; - int exp, pExp, has; - bool running, authTok; -}; - -#endif /* KGREET_WINBIND_H */ diff --git a/kdmlib/kgreeterplugin.h b/kdmlib/kgreeterplugin.h deleted file mode 100644 index edf67f141..000000000 --- a/kdmlib/kgreeterplugin.h +++ /dev/null @@ -1,407 +0,0 @@ -/* - - Authentication method specific conversation plugin for KDE's greeter widgets - - Copyright (C) 2003 Oswald Buddenhagen - Copyright (C) 2003 Fabian Kaiser - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KGREETERPLUGIN_H -#define KGREETERPLUGIN_H - -#include -#include -#include - -class KdmThemer; - -class TQWidget; -class TQLayoutItem; - -class KGreeterPluginHandler { -public: - /* keep in sync with V_IS_* */ - enum { IsSecret = 1, IsUser = 2, IsPassword = 4, IsOldPassword = 8, - IsNewPassword = 16 }; - /** - * Reply to textPrompt(). - * @param text text to return to core; null to abort auth cycle - * @param tag zero or one of Is* - */ - virtual void gplugReturnText( const char *text, int tag ) = 0; - /** - * Reply to binaryPrompt(). - * @param data data in pam_client format to return to the core; - * null to abort auth cycle - */ - virtual void gplugReturnBinary( const char *data ) = 0; - /** - * Tell the greeter who is logging in. - * Call this preferably before gplugStart, as otherwise the .dmrc - * load will be delayed. Don't call at all if your plugin doesn't - * have the Local flag set. Call only for internally generated - * user changes. - * @param user the user logging in - */ - virtual void gplugSetUser( const TQString &user ) = 0; - /** - * Start processing. - */ - virtual void gplugStart() = 0; - /** - * Plugins that expect user input from a different device than the mouse or - * keyboard must call this when user activity is detected to prevent the - * greeter from resetting/going away. Events should be compressed to no - * more than ten per second; one every five seconds is actually enough. - * Events should be actual changes to the input fields, not random motion. - */ - virtual void gplugActivity() = 0; - /** - * Show a message box on behalf of the talker. - * @param type message severity - * @param text message text - */ - virtual void gplugMsgBox( TQMessageBox::Icon type, const TQString &text ) = 0; -}; - -/** - * Abstract base class for conversation plugins ("talkers") to be used with - * TDM, kdesktop_lock, etc. - * The authentication method used by a particular instance of a plugin - * may be configurable, but the instance must handle exactly one method, - * i.e., info->method must be determined at the latest at init() time. - */ -class KGreeterPlugin { -public: - KGreeterPlugin( KGreeterPluginHandler *h ) : handler( h ) {} - virtual ~KGreeterPlugin() {} - - /** - * Variations of the talker: - * - Authenticate: authentication - * - AuthChAuthTok: authentication and password change - * - ChAuthTok: password change - */ - enum Function { Authenticate, AuthChAuthTok, ChAuthTok }; - - /** - * Contexts the talker can be used in: - * - Login: tdm login dialog - * - Shutdown: tdm shutdown dialog - * - Unlock: tdm unlock dialog (TODO) - * - ChangeTok: tdm password change dialog (TODO) - * - ExUnlock: kdesktop_lock unlock dialog - * - ExChangeTok: kdepasswd password change dialog (TODO) - * - * The Ex* contexts exist within a running session; the talker must know - * how to obtain the currently logged in user (+ domain/realm, etc.) - * itself (i.e., fixedEntity will be null). The non-Ex variants will have - * a fixedEntity passed in. - */ - enum Context { Login, Shutdown, Unlock, ChangeTok, - ExUnlock, ExChangeTok }; - - /** - * Provide the talker with a list of selectable users. This can be used - * for autocompletion, etc. - * Will be called only when not running. - * @param users the users to load. - */ - virtual void loadUsers( const TQStringList &users ) = 0; - - /** - * Preload the talker with an (opaque to the greeter) entity. - * Will be called only when not running. - * @param entity the entity to preload the talker with. That - * will usually be something like "user" or "user@domain". - * @param field the sub-widget (probably line edit) to put the cursor into. - * If -1, preselect the user for timed login. This means pre-filling - * the password field with anything, disabling it, and placing the - * cursor in the user name field. - */ - virtual void presetEntity( const TQString &entity, int field ) = 0; - - /** - * Obtain the actually logged in entity. - * Will be called only after succeeded() was called. - */ - virtual TQString getEntity() const = 0; - - /** - * "Push" a user into the talker. That can be a click into the user list - * or successful authentication without the talker calling gplugSetUser. - * Will be called only when running. - * @param user the user to set. Note that this is a UNIX login, not a - * canonical entity - */ - virtual void setUser( const TQString &user ) = 0; - - /** - * "Push" a password into the talker. - * @param pass the password to set. - */ - virtual void setPassword( const TQString &pass ) = 0; - - /** - * En-/disable any widgets contained in the talker. - * Will be called only when not running. - * @param on the state to set - */ - virtual void setEnabled( bool on ) = 0; - - /** - * Called when a message from the authentication backend arrives. - * @param message the message received from the backend - * @param error if true, @p message is an error message, otherwise it's - * an informational message - * @return true means that the talker already handled the message, false - * that the greeter should display it in a message box - * - * FIXME: Filtering a message usually means that the backend issued a - * prompt and obtains the authentication data itself. However, in that - * state the backend is unresponsive, e.g., no shutdown is possible. - * The frontend could send the backend a signal, but the "escape path" - * within the backend is unclear (PAM won't like simply longjmp()ing - * out of it). - */ - virtual bool textMessage( const char *message, bool error ) = 0; - - /** - * Prompt the user for data. Reply by calling handler->gplugReturnText(). - * @param propmt the prompt to display. It may be null, in which case - * "Username"/"Password" should be shown and the replies should be tagged - * with the respective Is* flag. - * @param echo if true, a normal input widget can be used, otherwise one that - * visually obscures the user's input. - * @param nonBlocking if true, report whatever is already available, - * otherwise wait for user input. - */ - virtual void textPrompt( const char *prompt, bool echo, bool nonBlocking ) = 0; - - /** - * Request binary authentication data from the talker. Reply by calling - * handler->gplugReturnBinary(). - * @param prompt prompt in pam_client format - * @param nonBlocking if true, report whatever is already available, - * otherwise wait for user input. - * @return always true for now - * - * TODO: - * @return if true, the prompt was handled by the talker, otherwise the - * handler has to use libpam_client to obtain the authentication data. - * In that state the talker still can abort the data fetch by - * gplugReturn()ing a null array. When the data was obtained, another - * binaryPrompt with a null prompt will be issued. - */ - virtual bool binaryPrompt( const char *prompt, bool nonBlocking ) = 0; - - /** - * This can either - * - Start a processing cycle. Will be called only when not running. - * - Restart authTok cycle - will be called while running and implies - * revive(). PAM is a bit too clever, so we need this. - * In any case the talker is running afterwards. - */ - virtual void start() = 0; - - /** - * Request to suspend the auth. Make sure that a second talker of any - * type will be able to operate while this one is suspended (no busy - * device nodes, etc.). - * Will be called only if running within Login context. (Actually it - * won't be called at all, but be prepared.) - */ - virtual void suspend() = 0; - - /** - * Request to resume the auth from the point it was suspended at. - * Will be called only when suspended. - */ - virtual void resume() = 0; - - /** - * The "login" button was pressed in the greeter. - * This might call gplugReturn* or gplugStart. - * Will be called only when running. - */ - virtual void next() = 0; - - /** - * Abort auth cycle. Note that this should _not_ clear out already - * entered auth tokens if they are still on the screen. - * Will be called only when running and stops it. - */ - virtual void abort() = 0; - - /** - * Indicate successful end of the current phase. - * This is more or less a request to disable editable widgets - * responsible for the that phase. - * There will be no further attempt to enter that phase until the - * widget is destroyed. - * Will be called only when running and stops it. - */ - virtual void succeeded() = 0; - - /** - * Indicate unsuccessful end of the current phase. - * This is mostly a request to disable all editable widgets. - * The widget will be treated as dead until revive() is called. - * Will be called only when running and stops it. - */ - virtual void failed() = 0; - - /** - * Prepare retrying the previously failed phase. - * This is mostly a request to re-enable all editable widgets failed() - * disabled previously, clear the probably incorrect authentication tokens - * and to set the input focus appropriately. - * Will be called only after failed() (possibly with clear() in between), - * or after presetEntity() with field -1. - */ - virtual void revive() = 0; - - /** - * Clear any edit widgets, particularily anything set by setUser. - * Will be called only when not running. - */ - virtual void clear() = 0; - - /** - * Obtain the TQLayoutItem containg the widget(s) to actually handle the - * conversation. See TQLayout and TQWidgetItem for possible implementations. - */ - TQLayoutItem *getLayoutItem() const { return layoutItem; } - -protected: - KGreeterPluginHandler *handler; - TQLayoutItem *layoutItem; -}; - -struct KDE_EXPORT kgreeterplugin_info { - /** - * Human readable name of this plugin (should be a little more - * informative than just the libary name). Must be I18N_NOOP()ed. - */ - const char *name; - - /** - * The authentication method to use - the meaning is up to the backend, - * but will usually be related to the PAM service. - */ - const char *method; - - /** - * Capabilities. - */ - enum { - /** - * All users exist on the local system permanently (will be listed - * by getpwent()); an entity corresponds to a UNIX user. - */ - Local = 1, - /** - * The entities consist of multiple fields. - * PluginOptions/.FocusField is used instead of FocusPasswd. - */ - Fielded = 2, - /** - * An entity can be preset, the talker has a widget where a user can - * be selected explicitly. If the method is "classic", timed login - * is possible, too. - * This also means that setUser/gplugSetUser can be used and a - * userlist can be shown at all - provided Local is set as well. - */ - Presettable = 4 - }; - - /* - * Capability flags. - */ - int flags; - - /** - * Call after loading the plugin. - * - * @param method if non-empty and the plugin is unable to handle that - * method, return false. If the plugin has a constant method defined - * above, it can ignore this parameter. - * @param getConf can be used to obtain configuration items from the - * greeter; you have to pass it the @p ctx pointer. - * The only predefined key (in TDM) is "EchoMode", which is an int - * (in fact, KPasswordEdit::EchoModes). - * Other keys are obtained from the PluginOptions option; see tdmrc - * for details. - * If the key is unknown, dflt is returned. - * @param ctx context pointer for @p getConf - * @return if false, unload the plugin again (don't call done() first) - */ - bool (*init)( const TQString &method, - TQVariant (*getConf)( void *ctx, const char *key, - const TQVariant &dflt ), - void *ctx ); - - /** - * Call before unloading the plugin. - * This pointer can be null. - */ - void (*done)( void ); - - /** - * Factory method to create an instance of the plugin. - * Note that multiple instances can exist at one time, but only - * one of them is active at any moment (the others would be suspended - * or not running at all). - * @param handler the object offering the necessary callbacks - * @param parent parent widget - * @param predecessor the focus widget before the conversation widget - * @param fixedEntity see below - * @param func see below - * @param ctx see below - * @return an instance of this conversation plugin - * - * Valid combinations of Function and Context: - * - Authenticate:Login - init - * - Authenticate:Shutdown - init, for now "root" is passed as fixedEntitiy - * and it is not supposed to be displayed. Plugins with Local not set - * might have to conjure something up to make getEntity() return a - * canonical entitiy. FIXME: don't restrict shutdown to root. - * - AuthChAuthTok:Login, AuthChAuthTok:Shutdown - cont/cont, - * only relevant for classic method (as it is relevant only for password- - * less logins, which always use classic). The login should not be shown - - * it is known to the user already; the backend won't ask for it, either. - * - ChAuthTok:Login & ChAuthTok:Shutdown - cont - * - Authenticate:Unlock & Authenticate:ExUnlock - init, - * AuthChAuthTok:ChangeTok & AuthChAuthTok:ExChangeTok - init/cont, - * display fixedEntity as labels. The backend does not ask for the UNIX - * login, as it already knows it - but it will ask for all components of - * the entity if it is no UNIX login. - * - * "init" means that the plugin is supposed to call gplugStart, "cont" - * that the backend is already in a cycle of the method the plugin was - * initialized with. - */ - KGreeterPlugin *(*create)( KGreeterPluginHandler *handler, - KdmThemer *themer, - TQWidget *parent, TQWidget *predecessor, - const TQString &fixedEntity, - KGreeterPlugin::Function func, - KGreeterPlugin::Context ctx ); -}; - -#endif diff --git a/tdm/CMakeLists.txt b/tdm/CMakeLists.txt new file mode 100644 index 000000000..08096f84c --- /dev/null +++ b/tdm/CMakeLists.txt @@ -0,0 +1,23 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +# FIXME initial work, only PAM +# FIXME needs more checks (for kerberos, etc) +# FIXME Xsession need some improvements + +if( NOT DEFINED TDM_PAM_SERVICE ) + set( TDM_PAM_SERVICE "kde" CACHE INTERNAL "" ) +endif( ) + +include( ConfigureChecks.cmake ) + +add_subdirectory( backend ) +add_subdirectory( kfrontend ) diff --git a/tdm/ChangeLog b/tdm/ChangeLog new file mode 100644 index 000000000..58a3014f6 --- /dev/null +++ b/tdm/ChangeLog @@ -0,0 +1,540 @@ +This change log contains only changes relevant to the TDM configuration, +startup and packaging. Bug fixes are not listed, and feature changes only +if they affect the configuration. + +2005-08-21 Oswald Buddenhagen + + * Added timed login. Option AutoLoginDelay. + * Added persistent auto-login. Option AutoLoginAgain. + +2005-02-01 Oswald Buddenhagen + + * Made the word splitter more sh-like. Affects HaltCmd, RebootCmd, + Setup, Startup, Reset, Session and Xrdb. + * Replaced option Xservers with StaticServers, ReserveServers, + ServerCmd, ServerArgsLocal, ServerArgsRemote, ServerVT and ServerTTY. + +2005-01-31 Oswald Buddenhagen + + * Added console mode that is suitable for systems with VTs (Linux). + Option ConsoleTTYs. The @tty spec in Xservers is irrelevant on + those systems now. + +2005-01-23 Oswald Buddenhagen + + * Added Grub support to boot options. Option UseLilo replaced + with BootManager { None, Grub, Lilo }. Removed options LiloCmd + and LiloMap. + +2005-01-09 Oswald Buddenhagen + + * Merged sessreg into tdm. Option UseSessReg. + +2004-08-14 Oswald Buddenhagen + + * Replaced dysfunct InteractiveSd with working + ScheduledSd { Never, Optional, Always } + +2004-07-28 Oswald Buddenhagen + + * Added control sockets. Control FiFos are now obsolete. + Added control socket command line client 'tdmctl'. + * The Setup program is now run even for automatic logins. + Setup, Startup and Reset have the arg "auto" for automatic logins. + +2004-07-23 Oswald Buddenhagen + + * Dynamic VT allocation added; option ServerVTs; no need to specify + vtX in Xservers any more. + +2004-07-10 Oswald Buddenhagen + + * GreeterPosX, GreeterPosY and GreeterPosFixed replaced with + single GreeterPos which is a pair of relative coordinates + +2004-07-01 Oswald Buddenhagen + + * The greeter can now run a "session preloader"; option Preloader + +2004-04-15 Oswald Buddenhagen + + * Merge from XDM: + - IPv6 support + - LISTEN keyword in Xaccess + - Changes to Enable and Port in [Xdmcp] now take effect when HUPed + - Support for EGD/PRNGD; options PrngdPort and PrngdSocket + +2004-04-14 Oswald Buddenhagen + + * -debug now groks additional bits for stracing and valgrinding + helper processes and disabling syslog usage. + +2004-04-09 Oswald Buddenhagen + + * NoPassUsers now accepts an asterisk ("*") meaning all users + +2004-04-08 Oswald Buddenhagen + + * Changes to FifoDir and FifoGroup now take effect on the global + command FiFo when HUPed. + +2004-03-16 Oswald Buddenhagen + + * Changed AllowClose default to true; only the default tdmrc + disables it for local display now. + +2004-03-11 Chris Cheney + + * Sanitized UserPath and SystemPath defaults. + +2004-03-07 Oswald Buddenhagen + + * Add user name autocompletion to greeter; option UserCompletion. + As a side effect, "None" is gone from ShowUsers and UserList + appeared; ShowUsers & SortUsers affect both the user list and + the completion list. + +2004-02-28 Oswald Buddenhagen + + * The default Xsession no longer tries to merge tdm's PATH into the + one set up by the shell startup scripts. Instead, kde.desktop + contains a full pathname and starttde fixes up PATH if necessary. + * The default Xsession will emulate the startup behaviour of more + shells, in particular bash, zsh and csh/tcsh. + * Setting up the session log is now done by tdm, not the Session + script; option ClientLogFile. + +2004-01-25 Oswald Buddenhagen + + * Add support for specifying groups in SelectedUsers, HiddenUsers and + NoPassUsers. Prefix group names with a @. + +2003-12-17 Oswald Buddenhagen + + * XDMCP initiated local displays are now treated as remote displays + (on localhost) by the config reader. + +2003-11-09 Oswald Buddenhagen + + * Sanitized display restart behaviour; option StartInterval is gone. + +2003-11-04 Oswald Buddenhagen + + * Conversation plugins can be configured now; option PluginOptions. + * The "Restart X Server"/"Close Connection" action can be configured + away; option AllowClose. + * The "Console Login" action can be configured away without touching + Xservers; option AllowConsole. + +2003-10-27 Oswald Buddenhagen + + * TDM now complies with the input model of PAM. The greeter has an + interface for conversation plugins, so alternative authentication + mechanisms can be handled; options PluginsLogin & PluginsShutdown. + * Password-less and automatic logins now use a separate PAM service + (${TDM_PAM_SERVICE}-np). + +2003-10-17 Oswald Buddenhagen + + * Add --with-tdm-xconsole configure switch. No need to patch + Makefile.am to enable the built-in xconsole anymore. + +2003-09-23 Oswald Buddenhagen + + * Session types are now defined with .desktop files; consequently the + SessionTypes option is gone and we got SessionsDirs instead. + * The default Xsession now hard-wires the session types + - "default" to starttde + - "custom" to ~/.xsession + * The previous session type choice is now saved in a different file + (~/.dmrc) in a different format (ini-file); the SessSaveFile option + is gone. Optionally TDM can be configured to store all .dmrc files + in a common directory (option DmrcDir); this can be useful for AFS + based installations. + * The location of the administratively set user faces is now specified + by the FaceDir option and the pictures have a .face.icon extension + (or .face for "natural" images, possibly photos). + + The spec for the above changes is shared with GDM, so packagers should + choose common directories. + + * The tdmsts file moved to /var/lib/tdm by default; option DataDir. + * Nuked the AutoLoginSession option; i don't think it was useful at all + and it can be emulated anyway. + +2003-09-03 Oswald Buddenhagen + + * Add option RandomDevice to override the OS specific default + entropy source. + +2003-08-26 Oswald Buddenhagen + + * Add random seed to forged "previous" session type calculation; + option ForgingSeed. + +2003-07-15 Malte Starostik + + * ColorScheme is now interpreted as the base name of the .kcsrc file, + not the contents of its Name field. + +2003-05-11 Oswald Buddenhagen + + * GUIStyle & ColorScheme now accept an empty string, meaning + "built-in default". Made defaults empty, consequently. + +2002-12-01 Oswald Buddenhagen + + * Integrated chooser into greeter; external 'chooser' executable + and the Chooser option are gone. + * The chooser can be started locally (without an XDMCP query); + options LoginMode and ChooserHosts. + * Added built-in xconsole to greeter; options ShowLog and LogSource. + This code is not built by default; uncomment the first three lines + in kfrontend/Makefile.am to enable it. + * The DaemonMode option is gone. The command line switches -daemon and + -nodaemon still exist, but are mostly unnecessary, as TDM can decide + what to do based on the parent process ID. + * The AutoLogin option and the -autolog/-noautolog switches are gone. + * The AutoLogin1st option is gone. + * The position of the -debug and -logfile command line options is + irrelevant again. The -xrm option is back, but is ignored by the + KDE frontend. + +2002-08-28 Oswald Buddenhagen + + * Made it possible to specify the color scheme for the greeter; + option ColorScheme + +2002-08-10 Oswald Buddenhagen + + * Renamed tdmdesktop to krootimage, moved it back into the TDM source + tree, and changed its command line + * krootimage will be automatically invoked by the greeter by default; + option UseBackground + * Chucked out the [Desktop0] section from tdmrc. Instead, the + location of the config file containing such a section is specified + with the BackgroundRc option. + * User images can now be optionally fetched from the users's home + directories; option FaceSource + * The default of the KeyFile option is now empty again + * GreeterScreen now groks -2, meaning upper-right screen + +2002-08-06 Oswald Buddenhagen + + * Automatically don't daemonize if started by init. + +2002-03-19 Oswald Buddenhagen + + * The default Xsession will emulate the startup behaviour of sh/ksh + by sourcing /etc/profile and ~/.profile. + +2002-03-10 Oswald Buddenhagen + + * Added InteractiveSd option. This is not really implemented yet, + so enabling it just makes TDM deny the existence of the shutdown + condition/timing options. + * The Setup script is now executed synchronously. Long-lasting + commands should be put in the background explicitly. + +2002-02-28 George Staikos + + * GreeterScreen now groks -1, meaning upper-left screen. + +2002-01-14 Oswald Buddenhagen + + * Added option NumLock {On,Off,Keep} to preset the NumLock modifier + state for the greeter + +2001-12-11 Oswald Buddenhagen + + * Added AntiAliasing option to disable antialiasing in the greeter + +2001-11-30 Oswald Buddenhagen + + * Added GreeterScreen option to put the greeter on a particular + screen in multi-headed setups. + * Changed the default of Language from "C" to "en_US" + +2001-11-22 Oswald Buddenhagen + + * The defaults of the options Xservers, Session, Setup, Startup, + Reset and PidFile are now back to the saner XDM defaults, + so TDM works even without config files. + * Changed option ShowUsers: All -> NotHidden + * Renamed the option Users to SelectedUsers and NoUsers to HiddenUsers. + * The GUIStyle option now groks all installed widget styles. + Note that Motif+ and KDE are now called MotifPlus resp. Default. + +2001-11-02 Oswald Buddenhagen + + * Added conditional/scheduled shutdown modes; options + DefaultSdMode and AllowSdForceNow; moved AllowShutdown from + [X--Greeter] to [X--Core]. + * Added reserve display support; extension to Xservers. + * Added command FiFo support (see README); options FifoDir, + FifoGroup, [ShutDown]/AllowFifo, and [ShutDown]/AllowFifoNow. + FiFo location and capabilities are exported in $XDM_MANAGED. + +2001-10-04 Oswald Buddenhagen + + * Xauth files are now created in AuthDir, not AuthDir/authdir. + Changed AuthDir default to /var/run/xauth. + +2001-07-12 Oswald Buddenhagen + + * Renamed the option Xwilling to Willing + * The RandomFile option is not recognized on Linux and OpenBSD any + longer, as they have better entropy sources + +2001-07-10 Oswald Buddenhagen + + * Added the tool 'gentdmconf'. It's supposed to create a suitable + configuration for TDM during 'make install' by merging new defaults + with a previous XDM/TDM config (if any is found). + +2001-07-03 Oswald Buddenhagen + + * Added counterpart to the MinShowUID option: MaxShowUID + +2001-06-23 Oswald Buddenhagen + + * Xauth files are now created in AuthDir/authfiles, not + AuthDir/authdir/authfiles + +2001-06-16 Oswald Buddenhagen + + * Optionally put the cursor right in the "Password" field when + a user is preselected in the "Login" field; option FocusPasswd + +2001-06-15 Oswald Buddenhagen + + * Replaced the ShutdownButton + ShutdownNeedsRoot option pair with + the AllowShutdown {None,Root,All} option + +2001-06-10 Oswald Buddenhagen + + * The source directory structure changed entirely + * The argument to the -debug command line option is now a bit field; + the DebugLevel resource is gone + * The ErrorLogFile resource is gone + * The greeter module libKdmGreet.so has been converted to an + executable named tdm_greet; the external config parser is now + named tdm_config. The resource GreeterLib and the command line + option -getcfg (and -cfg2get) are gone, as the locations of the + config parser and greeter are derived from the location of the + tdm executable + * The config files are all located in ${kde_confdir}/tdm now; the + defaults for Setup & Session were adapted to this. + * The keys in tdmrc were reorganized: + - [TDM]/ShutdownButton -> [X--Greeter]/(ShutdownButton & + ShutdownNeedsRoot) + - [TDM]/Shutdown -> [Shutdown]/HaltCmd + - [TDM]/Restart -> [Shutdown]/RebootCmd + - [TDM]/LogoArea -> [X-*-Greeter]/ {None,Logo,Clock} + - remaining keys from [TDM] -> [X-*-Greeter]/ + - [Lilo]/Lilo -> [Shutdown]/UseLilo + - [Lilo]/LiloCommand -> [Shutdown]/LiloCmd + - [Lilo]/LiloMap -> [Shutdown]/ + - [Locale]/Language -> [X-*-Greeter]/ (Country key dropped) + * TDM will no longer use tdm-config; most of its resources were + absorbed into tdmrc: + - Servers -> [General]/Xservers + - RequestPort -> [Xdmcp]/(Port & Enable) + - DaemonMode -> [General]/ + - PidFile -> [General]/ + - LockPidFile -> [General]/ + - AuthDir -> [General]/ + - AutoRescan -> [General]/ + - RemoveDomainname -> [Xdmcp]/ + - KeyFile -> [Xdmcp]/ + - AccessFile -> [Xdmcp]/Xaccess/ + - ExportList -> [General]/ + - RandomFile -> [General]/ + - ChoiceTimeout -> [Xdmcp]/ + - SourceAddress -> [Xdmcp]/ + - Willing -> [Xdmcp]/Xwilling + - AutoLogin -> [General]/ + - GrabServer -> [X--Greeter]/ + - GrabTimeout -> [X--Greeter]/ + - AuthComplain -> [X--Greeter]/ + - AuthName -> [X--Core]/AuthNames + - NoPassUsers -> [X--Core]/ & [X--Core]/NoPassEnable + - AutoUser -> [X--Core]/(AutoLoginUser & AutoLoginEnable) + - AutoPass -> [X--Core]/AutoLoginPass + - AutoString -> [X--Core]/AutoLoginSession + - remaining server & session resources -> [X--Core]/ + * In GreetString the HOSTNAME substitution was replaced with the + %%, %d, %h, %n, %s, %r & %m expandos + * EchoMode does not understand "NoStars" any more. Use "NoEcho". + * Defaults changed: AuthDir to /var/lib/tdm, KeyFile to + $tdm_confdir/tdmkeys, Xservers to $tdm_confdir/Xservers, Xaccess to + $tdm_confdir/Xaccess, Startup to $tdm_confdir/Xstartup, Reset to + $tdm_confdir/Xreset, removed kde2 from SessionTypes + * The previous user is now saved in $tdm_confdir/tdmsts, not tdmrc + * Added option SessSaveFile, defaulting to .wmrc + * Command line option changes: + - -server, -udpPort, -resources, -session and -xrm are gone + - -error is aliased to -logfile + - -debug and -error/-logfile must be specified first + - options are now accepted with both one and two leading dashes + * The default Xsession will now + - source ~/.xprofile if present + - try harder to determine what executable $1 corresponds to + - interpret "default" as ~/.xsession + +2001-03-19 Oswald Buddenhagen + + * %DMNAME% and %DMPATH% are expanded in string resources; + changed the defaults for PidFile and ConfigFile accordingly - + the latter resulting in TDM now using tdm-config, NOT xdm-config + * Use external config parser to merge platform-specific (that is, + KDE-like) configuration data into the XDM resources; command line + options -getcfg (default %DMPATH%_getcfg) and -cfg2get (no default, + meaning tdm_getcfg will use $kde_confdir/tdmrc). + * Changed "kde" to "kde2" in the default SessionTypes + * Stolen idea for console mode handling from dtlogin; options + ConsoleMode and AllowConsoleMode are gone; extension to Xservers + +2001-01-19 Oswald Buddenhagen + + * Added resources AllowRootLogin and AllowNullPasswd + +2001-01-15 Oswald Buddenhagen + + * Renamed UserIDLow option to MinShowUID + * The LogoArea option now accepts the value "None" + +2001-01-13 Oswald Buddenhagen + + * The GUIStyle option now works again and groks all of Qt's + built-in widget styles and the "KDE" style + +2001-01-11 Oswald Buddenhagen + + * Added placing of the greeter at fixed coordinates; options + GreeterPosFixed, GreeterPosX, and GreeterPosY. + * Added "default" to the default SessionTypes + +2000-01-06 Oswald Buddenhagen + + * Added option AllowConsoleMode + +2000-12-09 Oswald Buddenhagen + + * Added auto-login; options AutoLoginEnable, AutoLoginUser & + AutoLogin1st; resources AutoUser, AutoPass, AutoString & AutoLogin1st + * Added password-less login; options NoPassEnable & NoPassUsers; + resource NoPassUsers + * Added auto-re-login on XServer crash; resource & option AutoReLogin + + The tdmrc options and xdm-config resources are "ORed", i.e., if + either is enabled, the function is enabled. + The command line options -autolog/-noautolog and the resource AutoLogin + can be used to disable auto-login and password-less login at once. + + * Added displaying the previously logged in user in the "Login" + field; option ShowPrevious. The previous user is saved in tdmrc, + section [Previous]. + +2000-12-07 Oswald Buddenhagen + + * New XDM port from XFree86 4.0.1 + - new resources SourceAddress & Willing + - /authdir/authfiles is now automatically appended to AuthDir + * Default for PidFile and Setup changed back to empty + * Displays restarting too fast are disabled; resource StartInterval + * Option UserView, and NoUsers dependency on Users being empty + replaced with explicit option ShowUsers {All,Selected,None} + * Made the greeter dynamically loadable (libKdmGreet.so) + * Moved chooser and greeter to separate directories, + same for unused stuff (misc/) + + * Added half-baked support for command FiFos; resources + FifoCreate, FifoGroup, FifoMode. Replaced on 2001-11-02 + +2000-10-10 Steffen Hansen + + * Made tdmdesktop read the [Desktop0] section from tdmrc instead + of tdmdesktoprc. + +2000-09-07 Waldo Bastian + + * Make password echo mode configurable; + option EchoMode {OneStar,ThreeStars,NoEcho} + +2000-08-07 Christopher Molnar + + * The minimal user ID to show in the user view can be specified now; + option UserIDLow. + +2000-06-04 Espen Sand + + * The logo area can now display either a clock or a pixmap; + option LogoArea {KdmClock,KdmLogo} + +1999-12-12 Jaromir Dolecek + + * Use OS-specific defaults for Shutdown & Restart + * Make PidFile, UserPath & SystemPath defaults on NetBSD match FreeBSD + +1999-11-17 Harald Hoyer + + * Made kchooser + +1999-11-15 Matthias Hoelzer-Kluepfel + + * tdmdesktop replaced with ../kdesktop/tdmdesktop. Uses new config + file (tdmdesktoprc) with new options (all in section [Desktop0]): + +1999-07-01 Steffen Hansen + + * Xaccess now accepts NOBROADCAST + +1999-06-07 Matthias Hoelzer-Kluepfel + + * Added next boot OS selection via LiLo; options [Lilo] Lilo, + LiloCommand & LiloMap + * Added button to switch to console mode; option [TDM] ConsoleMode + +1999-03-01 Stephan Kulow + + * Option GUIStyle temporarily removed + +1998-10-08 Thomas Tanghus + + * [TDMDESKTOP] option changes: + - BackgroundPictureTile, BackgroundPictureCenter, FancyBackground -> + BackgroundPictureMode {None,Tile,Center,Scale, + TopLeft,TopRight,BottomLeft,BottomRight,Fancy} + - add BackGroundColorMode {Plain,Horizontal,Vertical} + - BackgroundColor -> BackGroundColor1, BackGroundColor2 + +1998-09-20 Hans Petter Bieker + + * Change defaults: + - Setup: "" -> XDMDIR/Xsetup + - PidFile: "" -> FreeBSD: /var/run/tdm.pid, others: XDMDIR/tdm-pid + - Session: "XBINDIR/xterm -ls" -> XDMDIR/Xsession + - UserPath & SystemPath: no /usr/ucb for Linux & FreeBSD + +1998-09-11 Hans Petter Bieker + + * Replace hard-coded paths with XBINDIR/XDMDIR in various defaults + +1998-09-06 Hans Petter Bieker + + * Default Xsession now searches $1 in PATH and execs it + +1998-03-26 Stephan Kulow + + * Nuke -tdedir cmdline option and Kdedir resource + +1997-09-09 Steffen Hansen + + * Change defaults: + - AuthDir: XDMDIR/authDir -> XDMDIR/authdir + +1997-09-04 kdecvs + + * Change defaults: + - AuthDir: XDMDIR -> XDMDIR/authDir diff --git a/tdm/ConfigureChecks.cmake b/tdm/ConfigureChecks.cmake new file mode 100644 index 000000000..ae7ea8b6c --- /dev/null +++ b/tdm/ConfigureChecks.cmake @@ -0,0 +1,139 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +find_library( UTIL_LIBRARY util ) + +check_function_exists( getdomainname HAVE_GETDOMAINNAME ) +check_function_exists( initgroups HAVE_INITGROUPS ) +check_function_exists( mkstemp HAVE_MKSTEMP ) +check_function_exists( setproctitle HAVE_SETPROCTITLE ) +check_function_exists( sysinfo HAVE_SYSINFO ) +check_function_exists( strnlen HAVE_STRNLEN ) +check_function_exists( getifaddrs HAVE_GETIFADDRS ) + +tde_save( CMAKE_REQUIRED_LIBRARIES ) +set( CMAKE_REQUIRED_LIBRARIES ${UTIL_LIBRARY} ) +check_function_exists( setusercontext HAVE_SETUSERCONTEXT ) +check_function_exists( getusershell HAVE_GETUSERSHELL ) +check_function_exists( login_getclass HAVE_LOGIN_GETCLASS ) +check_function_exists( auth_timeok HAVE_AUTH_TIMEOK ) +tde_restore( CMAKE_REQUIRED_LIBRARIES ) + +check_function_exists( crypt LIBC_HAVE_CRYPT ) +if( LIBC_HAVE_CRYPT ) + set( HAVE_CRYPT 1 CACHE INTERNAL "" FORCE ) +else( ) + check_library_exists( crypt crypt "" HAVE_CRYPT ) + if( HAVE_CRYPT ) + set( CRYPT_LIBRARY crypt ) + endif( ) +endif( ) + +check_include_file( lastlog.h HAVE_LASTLOG_H ) +check_include_file( termio.h HAVE_TERMIO_H ) + +check_struct_has_member( "struct sockaddr_in" "sin_len" "sys/socket.h;netinet/in.h" HAVE_STRUCT_SOCKADDR_IN_SIN_LEN ) +check_struct_has_member( "struct passwd" "pw_expire" "pwd.h" HAVE_STRUCT_PASSWD_PW_EXPIRE ) +check_struct_has_member( "struct utmp" "ut_user" "utmp.h" HAVE_STRUCT_UTMP_UT_USER ) + +check_c_source_runs( " + #include + #include + int main() + { + setlogin(0); + return errno == ENOSYS; + } +" HAVE_SETLOGIN ) + +check_c_source_runs( " + #include + #include + #include + #include + #include + #include + #include + int main() + { + int fd, fd2; + struct sockaddr_un sa; + + if((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) + return 2; + sa.sun_family = AF_UNIX; + strcpy(sa.sun_path, \"testsock\"); + unlink(sa.sun_path); + if(bind(fd, (struct sockaddr *)&sa, sizeof(sa))) + return 2; + chmod(sa.sun_path, 0); + setuid(getuid() + 1000); + if((fd2 = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) + return 2; + connect(fd2, (struct sockaddr *)&sa, sizeof(sa)); + return errno != EACCES; + } +" HONORS_SOCKET_PERMS ) + +if( CMAKE_SYSTEM_NAME MATCHES Linux OR CMAKE_SYSTEM_NAME MATCHES Darwin OR CMAKE_SYSTEM_NAME MATCHES GNU/FreeBSD ) + unset( HAVE_UTMPX ) + unset( HAVE_LASTLOGX ) +else( ) + check_function_exists( getutxent HAVE_UTMPX ) + check_function_exists( updlastlogx HAVE_LASTLOGX ) +endif( ) + +unset( BSD_UTMP ) +if( NOT HAVE_UTMPX ) + check_function_exists( getutent have_getutent ) + if( NOT have_getutent ) + set( BSD_UTMP 1 ) + endif( ) +endif( ) + +check_function_exists( arc4random HAVE_ARC4RANDOM ) +if( NOT HAVE_ARC4RANDOM ) + # assume that /dev/random is non-blocking if /dev/urandom does not exist + if( EXISTS /dev/urandom ) + set( DEV_RANDOM "/dev/urandom" CACHE INTERNAL "" FORCE ) + elseif( EXISTS /dev/random ) + set( DEV_RANDOM "/dev/random" CACHE INTERNAL "" FORCE ) + endif( ) +endif (NOT HAVE_ARC4RANDOM) + +# Xau +pkg_search_module( XAU xau ) +if( NOT XAU_FOUND ) + tde_message_fatal( "Xau are required, but not found on your system" ) +endif() + + +# xdmcp +if( WITH_XDMCP ) + pkg_search_module( XDMCP xdmcp ) + if( XDMCP_FOUND ) + set( XDMCP 1 CACHE INTERNAL "" FORCE ) + else() + tde_message_fatal( "xdmcp is requested, but was not found on your system" ) + endif() +endif() + + +if( WITH_PAM ) + + set( USE_PAM 1 CACHE INTERNAL "" FORCE ) + +elseif( WITH_SHADOW ) + + set( HAVE_SHADOW 1 CACHE INTERNAL "" FORCE ) + set( USESHADOW 1 CACHE INTERNAL "" FORCE ) + +endif( ) diff --git a/tdm/Makefile.am b/tdm/Makefile.am new file mode 100644 index 000000000..0f038d4a7 --- /dev/null +++ b/tdm/Makefile.am @@ -0,0 +1,20 @@ +SUBDIRS = . backend kfrontend + +PAM = @TDM_PAM_SERVICE@ + +noinst_DATA=config.ci + +tdmdocdir = $(datadir)/doc/tdm +tdmdoc_DATA = README + +install-data-local: + -@test -n "$(DESTDIR)" || test -z "$(PAM)" || { $(top_srcdir)/mkpamserv $(PAM) && $(top_srcdir)/mkpamserv -P $(PAM)-np; } + +config.ci: $(srcdir)/config.def $(srcdir)/confproc.pl + $(PERL) -w $(srcdir)/confproc.pl $(srcdir)/config.def $@ + +CLEANFILES = config.ci + +### this is *only* for the tdm home page maintainer! ### +hp: + scp README ChangeLog TODO devel-home:files/tdm diff --git a/tdm/README b/tdm/README new file mode 100644 index 000000000..6c0fce18b --- /dev/null +++ b/tdm/README @@ -0,0 +1,454 @@ +This is the K Display Manager (TDM) for KDE 3.4, +the KDE replacement for the X Display Manager (XDM). + +Semi-official home page: http://devel-home.kde.org/~ossi/sw/tdm.html + + +configure options that affect TDM +--------------------------------- + +--with-pam[=service] + Compile TDM (and other parts of tdebase) with PAM support. The default + service is "kde". PAM is automatically used if found. + +--with-tdm-pam=service + Override the PAM service used specifically by TDM. Depends on --with-pam. + +--with-shadow + Compile TDM (and other parts of tdebase) with shadow password support. + Shadow passwords are automatically used if found. This affects TDM only + if PAM is not used. + +--with-krb4[=path] + Compile TDM (and the LDAP KIO slave) with KTH Kerberos 4 support. Note + that this does not work with the Kerberos 4 compatibility layer found in + MIT Kerberos 5. This affects TDM only if PAM is not used. + +--with-afs + Compile TDM with AFS support. Depends on --with-krb4. + +--with-krb5auth[=path] +--with-rpcauth + Compile TDM with Kerberos 5 resp. secure RPC support for X authorization + cookies. It's pretty pointless to enable this if you don't use an X server + that supports it. + + If you want user authentication against a Kerberos realm, compile TDM with + PAM support and use the appropriate module. + +--without-xdmcp + Compile TDM without XDMCP support. + +--with-tdm-xconsole + Compile TDM with a builtin "xconsole" replacement in the greeter. I don't + consider this too useful, but SuSE wanted it, so it's there. ;) + + +TDM's file system layout +------------------------ + +${kde_confdir} is usually ${prefix}/share/config +${kde_datadir} is usually ${prefix}/share/apps +The indented locations are envisioned for a configuration shared with GDM. + +${kde_confdir}/tdm/{tdmrc,Xservers,Xaccess,Xwilling,...} +${kde_datadir}/tdm/sessions/*.desktop + /etc/X11/sessions/,/usr/share/xsessions/ +${kde_datadir}/tdm/pics/users/ +${kde_datadir}/tdm/pics/ +${kde_datadir}/tdm/faces/*.face{,.icon} + /usr/share/faces/ +/var/run/xauth/A* +/var/run/xdmctl/xdmctl* +/var/run/tdm.pid +/var/lib/tdm/tdmsts +/*.dmrc +$HOME/.face{,.icon} +$HOME/.dmrc + + +How to setup TDM +---------------- + +TDM's config files are all located in ${kde_confdir}/tdm. +"make install" will create a probably working configuration, either by +deriving it from an already present TDM/XDM installation or by using +defaults if no previous installation is found. + +You can change the configuration from the KDE Control Center. You will +find the "Login Manager" module in the "System Administration" group. + +Have a look at README.pam in the tdebase top level directory if your +system uses PAM. + + +Configuring session types +------------------------- + +The way session types are configured changed drastically in KDE 3.2. +Session types are now represented by .desktop files in appropriate locations. +The format of the .desktop files is (not yet) defined in the FreeDesktop.org +desktop entry spec. Differences to "standard" .desktop files are: +- the Type is fixed to XSession and can be omitted +- the Encoding is fixed to UTF-8 and can be omitted +- the Exec field will be passed to "eval exec" in a bourne shell; no macro + expansion is performed on it. "default", "custom" and "failsafe" are magic + constants that cause special actions. +- Name, Comment, TryExec and Hidden are supported +- the remaining keys have no meaning currently +Session types are internally identified by filename (without extension); +that's what will be saved to ~/.dmrc and what DESKTOP_SESSION will be set to. +For every magic Exec constant a session type of the same name exists. + +Unless your system is configured differently already, you should create a +directory ${kde_confdir}/tdm/sessions and add this to tdmrc: + +[X-*-Core] +SessionsDirs=${kde_confdir}/tdm/sessions,${kde_datadir}/tdm/sessions + +(Note that you must use actual paths instead of variables, see the section +about TDM's file system layout.) +Do any changes only in the config directory - any changes in the data +directory will be lost after the next KDE update. + +To override a session type, copy the .desktop file from the data dir to the +config dir and edit it at will. Removing the shipped session types can be +accomplished by "shadowing" them with .desktop files containing Hidden=true. +For the magic session types no .desktop files exist by default, but TDM +pretends they would, so you can override them like any other type. +I guess you already know how to add a new session type by now. ;-) + + +Running TDM from init +--------------------- + +NOTE, that this description applies to RedHat 5.x and must be adapted for +other distributions/systems. Generally I'd advise _against_ starting TDM +directly from init - better use a proper init script, possibly by slightly +modifying the XDM init script shipped by your distribution. + + Edit (as root) /etc/inittab. + + Look for the line: + + x:5:respawn:/usr/X11/bin/xdm -nodaemon + + Replace it with: + + x:5:respawn:/opt/kde/bin/tdm + + This tells init(8) to respawn TDM, the KDE display manager, when + the system is in run level 5. + Note that TDM does not need the -nodaemon option. + + To start TDM, either run (as root) /sbin/telinit 5 (to switch to + run level 5), or (this is risky! don't do it until you _know_ you + want the system to boot into this every time!) edit /etc/inittab + and change the line: + + id:3:initdefault: + + to + + id:5:initdefault: + + If you do the latter step, then every time your system boots + successfully it will go into run level 5 and run TDM, + presenting you the exceedingly cute KDE login screen. + + +The command sockets +------------------- + +This is a feature you can use to remote-control TDM. It's mostly intended +for use by ksmserver and kdesktop from a running session, but other +applications are possible as well. + +The sockets are UNIX domain sockets which live in subdirectories of the +directory specified by FifoDir=. The subdir is the key to addressing and +security; the sockets all have the file name "socket" and file permissions +rw-rw-rw- (0666). This is because some systems don't care for the file +permissions of the socket files. +There are two types of sockets: the global one (dmctl) and the per-display +ones (dmctl-). +The global one's subdir is owned by root, the subdirs of the per-display +ones' are owned by the user currently owning the session (root or the +logged in user). Group ownership of the subdirs can be set via FifoGroup=, +otherwise it's root. The file permissions of the subdirs are rwxr-x--- (0750). + +The fields of a command are separated by tabs (\t), the fields of a list +are separated by spaces, literal spaces in list fields are denoted by "\s". +The command is terminated by a newline (\n). +The same applies to replies. The reply on success is "ok", possibly followed +by the requested information. The reply on error is an errno-style word (e.g., +"perm", "noent", etc.) followed by a longer explanation. + +Global commands: + +"login" display ("now"|"schedule") user password [session_arguments] + - login user at specified display. if "now" is specified, a possibly + running session is killed, otherwise the login is done after the + session exits. + session_arguments are printf-like escaped contents for .dmrc. Unlisted + keys will default to previously saved values. + +Per-display commands: + +"lock" + - The display is marked as locked. If the X-Server crashes in this state, + no auto-relogin will be performed even if the option is on. + +"unlock" + - Reverse the effect of "lock": re-enable auto-relogin. + +"suicide" + - The currently running session is forcibly terminated. No auto-relogin is + attempted, but a scheduled "login" command will be executed. + +Commands for all sockets: + +"caps" + - Returns a list this socket's capabilities: + "tdm" - identifies tdm, in case some other DM implements this protocol, too. + "list", "activate", "lock", "suicide", "login" - the respective command + is supported. + "bootoptions" - the "listbootoptions" command and the "=" option to + "shutdown" are supported. + "shutdown " - "shutdown" is supported and allowed to the listed users + (comma-separated). "*" means all authenticated users. + "shutdown" - "shutdown" is supported and allowed to everybody. + "nuke " - forced shutdown is allowed to the listed users. + "nuke" - forced shutdown is allowed to everybody. + "reserve " - reserve displays are configured and are + available at this time. + +"list" ["all"|"alllocal"] + - Return a list of running sessions. By default all active sessions are + listed. If "all" is specified, passive sessions are listed as well. If + "alllocal" is specified, passive sessions are listed as well, but all + incoming remote sessions are skipped. + Each session entry is a comma-separated tuple of: + - Display or TTY name + - VT name for local sessions + - Logged in user's name, empty for passive sessions and outgoing remote + sessions (local chooser mode) + - Session type or remote host for outgoing remote sessions, empty for + passive sessions + - A flag field: + - "t" for tty sessions + - "*" for the display belonging to the requesting socket + - "!" for sessions that cannot be killed by the requesting socket + - New flags might be added later + - New fields might be added later + +"reserve" [timeout in seconds] + - Start a reserve login screen. If nobody logs in within the specified amount + of time (one minute by default), the display is removed again. When the + session on the display exits, the display is removed, too. + - Permitted only on sockets of local displays and the global socket. + +"activate" (vt|display) + - Switch to a particular VT (virtual terminal). The VT may be specified + either directly (e.g., vt3) or by a display using it (e.g., :2). + - Permitted only on sockets of local displays and the global socket. + +"listbootoptions" + - List available boot options. + => "ok" list default current + default and current are indices into the list and are -1 if unset or + undeterminable. + +"shutdown" ("reboot"|"halt") ["="bootchoice] \ + ("ask"|"trynow"|"forcenow"|"schedule"|\ + start ("-1"|end ("force"|"forcemy"|"cancel"))) + - Request a system shutdown, either a reboot or a halt/poweroff. + - An OS choice for the next boot may be specified from the list returned by + "listbootoptions". + - Shutdowns requested from per-display sockets are executed when the current + session on that display exits. Such a request may pop up a dialog asking + for confirmation and/or authentication. + - start is the time for which the shutdown is scheduled. If it starts with + a plus-sign, the current time is added. Zero means immediately. + - end is the latest time at which the shutdown should be performed if active + sessions are still running. If it starts with a plus-sign, the start time + is added. Minus one means wait infinitely. If end is through and active + sessions are still running, TDM can do one of the following: + * "cancel" - give up the shutdown. + * "force" - shut down nonetheless. + * "forcemy" - shut down nonetheless if all active sessions belong to the + requesting user. Only for per-display sockets. + - start and end are specified in seconds since the UNIX epoch. + - "trynow" is a synonym for "0 0 cancel", "forcenow" for "0 0 force" and + "schedule" for "0 -1". + - "ask" attempts an immediate shutdown and interacts with the user if active + sessions are still running. Only for per-display sockets. + +"shutdown" "cancel" ["local"|"global"] + - Cancel a scheduled shutdown. The global socket always cancels the currently + pending shutdown, while per-display sockets default to cancelling their + queued request. + +"shutdown" "status" + - Return a list with information about shutdowns. + The entries are comma-separated tuples of: + - ("global"|"local") - pending vs. queued shutdown. A local entry can be + returned only by a per-display socket. + - ("halt"|"reboot") + - start + - end + - ("ask"|"force"|"forcemy"|"cancel") + - Numeric user ID of the requesting user, -1 for the global socket. + - The next boot OS choice or "-" for none. + - New fields might be added later. + +There are two ways of using the sockets: +- Connecting them directly. FifoDir is exported as $DM_CONTROL; the name + of per-display sockets can be derived from $DISPLAY. +- By using the tdmctl command (e.g., from within a shell script). + Try "tdmctl -h" to find out more. + +Here is an example bash script "reboot into FreeBSD": + +if tdmctl | grep -q shutdown; then + IFS=$'\t' + set -- `tdmctl listbootoptions` + if [ "$1" = ok ]; then + fbsd=$(echo "$2" | tr ' ' '\n' | sed -ne 's,\\s, ,g;/freebsd/I{p;q}') + if [ -n "$fbsd" ]; then + tdmctl shutdown reboot "=$fbsd" ask > /dev/null + else + echo "FreeBSD boot unavailable." + fi + else + echo "Boot options unavailable." + fi +else + echo "Cannot reboot system." +fi + + +"It doesn't work!!" +------------------- + +More input! ;-) + +TDM accepts two command line options related to logging: + + -debug + is a decimal or hexadecimal (prefix 0x) number. + The number is a bitfield, i.e., it is formed by summing up the + required values from this table: + 1 (0x1) - core debugging. Probably the most useful one. + 2 (0x2) - config reader debugging. + 4 (0x4) - greeter debugging. + 8 (0x8) - IPC debugging. This logs _all_ communication between the + core, the config reader and the greeter - including the + passwords you type, so edit the log before showing it to + somebody. + This attempts to synchronize the processes to interleave the + log messages optimally, but will probably fail unless you use + -debug 0x80 as well. + 16 (0x10) - wait after forking session sub-daemon. + 32 (0x20) - wait after starting config reader. + 64 (0x40) - wait after starting greeter. + The wait options are only useful if you need to attach a debugger + to a process, but it crashes before you are able to do so without + the delay. See below. + 128 (0x80) - don't use syslog for internally generated messages. + 256 (0x100) - core Xauth debugging. + 1024 (0x400) - run config reader and greeter through valgrind. + 2048 (0x800) - run config reader and greeter through strace. + + Logs from "-debug 7" are usually a good start. + + -logfile + is the file to log various messages to. The default log file is + /var/log/tdm.log. For internal reasons there is no option in tdmrc to + permanently specify the log file location. If you redirect TDM's + standard error output to a file, TDM will log there. + If TDM is configured to use syslog (and it _very_ probably is on any + modern system), all internally generated messages are logged to the + "daemon" facility. The log usually can be found in /var/log/debug.log + and /var/log/daemon.log; make sure that daemon.* is logged (look at + /etc/syslog.conf). + If you have problems logging in and your system uses PAM (also quite + probable on modern systems), the "auth" and "authpriv" syslog facilities + are interesting, too. + +Send me all the logs together with a detailed description of what you did +and what happened. If your problem is related to a specific configuration, +you should also attach a tar.gz archive of your TDM config directory. + +If I request a backtrace from you and TDM didn't create one yet via the +usual drkonqi procedure, you'll have to do that yourself. The keyphrase +is "attaching gdb". How exactly this is done depends on the part that +crashes: +- master daemon. Actually you should never need to attach to it, as + you can start it within the debugger already: + # gdb --args tdm -nodaemon -debug 7 + (gdb) run +- display subdaemon. Find (using ps) the process with a name like + "-:0" (where :0 is actually the display this process is for). This + process' PPID is the master daemon. Attach to it this way: + # gdb tdm + (gdb) cont + If the subdaemon crashes before you can attach, add 16 to the debug flags + when you start TDM. +- config reader. You will have to add 32 to the debug flags almost certainly. + The PPID will be the master daemon as well. + # gdb tdm_config $(pidof tdm_config) + (gdb) cont +- greeter. If it's too fast, add 64 to -debug. The PPID will be the subdaemon. + # gdb tdm_greet $(pidof tdm_greet) + (gdb) cont + The simplification with "pidof" works only if you have only one display, + otherwise you have to find the PID manually (by using ps -fx). +Once you got gdb attached to the offending process, do whatever is needed +to make it crash (probably nothing, if you had to use a delay parameter). +Once it crashed, gdb will tell you a signal name, like SIGSEGV - that's the +first interesting part for me. Then you have to create the actual backtrace: + (gdb) bt +The output of this command is interesting for me. +I might request a backtrace even if nothing crashes, but instead hangs. In +this case don't use "cont" after attaching, but use "bt" right away. If the +process is already running, interrupt it with ctrl-c. +For obvious reasons you have to run gdb on a different virtual terminal than +the X server. To get there, press alt-ctrl-f1 and log in as root. To +switch to the X server's vt, press alt-ctrl-f7 (the exact function key may +be different on your system). You may also use a remote login from a +second machine. In any case it is advantageous to have mouse support on the +debugging console for copying the backtrace. +Note that a backtrace is usually _much_ more useful if the binary contains +debugging info, so you should install from source with the --enable-debug +configure flag if at all possible. + + +Random rambings and license information +--------------------------------------- + +Version 0.1 of TDM is copyright + Matthias Ettrich +All later versions copyright: + (C) 1997-2000 Steffen Hansen +Since version 0.90 (KDE 2.1) copyright: + (C) 2000-2003 Oswald Buddenhagen + +The files in the backend directory are licensed under the X licence +(see http://www.x.org/Downloads_terms.html for more info). +The files in the kfrontend directory are licensed under the GNU GPL. + +Thanks to (in no particular order): +Michael Bach Jensen and Torsten Rahn for drawing icons. +Duncan Haldane for investigation of PAM issues. +Stephan Kulow for helping with the autoconf stuff. +Martin Baehr for intensive testing and writing the sample Xsession scripts. +Harald Hoyer for the (now obsoleted) chooser. +SuSE for employing me (ossi) for three months to work on tdm. +BasysKom for sponsoring my (ossi's) work on the conversation plugin stuff. +... and _many_ others ... + + +-- +Have fun with it (and feel free to comment), + + Oswald Buddenhagen diff --git a/tdm/TODO b/tdm/TODO new file mode 100644 index 000000000..75518b779 --- /dev/null +++ b/tdm/TODO @@ -0,0 +1,243 @@ +theming (#37349): +- maybe add a Themable plugin flag. if not set and no talker, abort. +- minor: show QWidgets only when the layout is ready and the theme was painted. + but one can't hide the widgets in a QLayout, as they have no size then. +- add attribute inheritance. apply attributes extracted from particular + elements of the (hidden) talker. +- make plugin return a QDom instead of embedding a QLayoutItem (QLabels look + just awful in the themed greeter). big problem: there is no KdmGrid ... try + to (ab)use QLayout. +- extract background from theme. use explicit node-id "background", i think. +- automatic talker node detection/creation. same for background, possibly. + +- remote login can have the chosen host as the sessName +- popup menu grabs keyboard. that means it is ungrabbed afterwards ... +- error label uses fixed colors. red might be ok, but not black. + +- message after switching to text mode + +- handle non-linux VTs: + on systems without VT_GETSTATE, try activating all consoles in turn to + find free ones. wow, this sucks so much. + - BSD: 1st: pcvt, /dev/ttyC[0] (OpenBSD), /dev/ttyv[0] (other), + also emulated by wscons on /dev/ttyE. + 2nd: syscons, /dev/ttyv[0], fallback /dev/vga + - Lynx, /dev/atc[0] + - Solaris, /dev/vt[00] + - SVR4, /dev/vc[00] (ESIX), /dev/vt[00] (other) + - SCO, /dev/tty[00], query current with CONS_GETINFO, counts 0-based + ref: xorg/programs/Xserver/hw/xfree86/os-support/xf86_OSlib.h +- act on BSD_INIT +- before nuking X server on other vt, save current vt and restore it before + disallocating server vt. or just make the xserver not switch wildly. + +- possibly parse Xserver log to find failure cause. this is very hacky. + +- try harder to get rid of processes, see X servers failure cleanup path + +- make auto-re-login a per-user option; save in .dmrc. + +- add Xserver option set selection (#56329) +- add support for XRandR (#48602) +save these options to .dmrc? + +- per-display sections in .dmrc. read-only, as far as tdm is concerned, as + otherwise the GUI would become insanely complex. + +- make config position independent +- parse /etc/kderc? +- merge multiple tdmrcs in the style of kconfig. how to set section priorities? +- gentdmconf: treat backgroundrc as an ini file, not as a text blob +- add proper quoting and dequoting to gentdmconf ini parser & writer + +- write generic conversation plugin +- write modern conv plugin. or maybe this should be a parallel vs. serial + setting of the classic plugin? + +- actually implement the libpam_client support + +- check if pam works before trying to authenticate +- test whether nis, kerberos4 & kerberos5 work +- sync BSD_AUTH from xdm, sync osfc2 from kcheckpass + +- swap pam_setcred and pam_open_session order. +- check how the system specific functions like setpcred (AIX) and + setusercontext (BSD) combine with pam_setcred. + +- Move clock from greeter dialog to desktop +- add more clock types (#18178) +- add icons to action menu. icon theme selection! + +- Add XDMCP _client_ to core (for remote login like in dtlogin). + Currently this is done by simply restarting the x-server with -query. + +- add login restrictions for reserve displays (#59353) + +- possibly do the authentication for the reserve display on the display it + is launched from (relates #59353) + +- remote-accessible command sockets for remote shutdown, etc. + or maybe implement it as an xdmcp extension? +- LoginMode=DirectQuery + +- "XDMCP over FiFo" - or at least a "manage []" command +- the per-display sockets are in fact nonsense; gdm's approach is better + +- add bgset to XDM_MANAGED + add FiFo command "background\t{inprogress,aborted,done}" + +- lilo boot option , i.e., -R with no argument +- support lilo -A mode + +- support sleep/suspend in the shutdown menu. should this be really treated + like a shutdown? (#33839) + +- add language selection (export as LC_*). kde should respect this until the + language is explicitly configured. and later? option "use system setting"? + integrate with $KDE_LANG somehow. (#55379, #63804) +- add keymap selection (via xkb) (#51245, #64642) +for both, one would preset a list of available options and make one entry +the greeter's own setting. explicitly setting it sets it for both the greeter +and the session. .dmrc later affects only the session, not the greeter. + +- handle failsafe internally, take care of focus. see #32973 + +- TryExec for "custom" session type. always show the entry, but disable it + if it is unavailable for the selected user. + +- cursor theming support via Xcursor (#66829) + +- add screensaver (#41941) +- support DPMS (#18597) + +- add a minimalistic window manager to the greeter (#17716, #51039) + +- write a separate configurator application, as kcontrol does not scale well + enough to cover all of tdm's options. + +- Different logos for each session type (see #74500) +- User pictures in logo field +- display user's .plan/.project (or .person? .userinfo?) in the greeter? + text area/label would suck -> tooltip? + +- allow disabling full names or login names in userview (#54110) +- user list loading in the background (after first few to get a reasonable + width estimate) + +- faking session parameters (type, language, etc.) of nonexistent users based + on statistical analysis of actual users ... severe overkill!? + +- export password to the startup/session scripts. somehow ... (#35396) + +- maybe reset CapsLock in the greeter. there is some CapsLock vs. ShiftLock + confusion, though. + +- maybe add kiosk mode: the user and his options are preset and locked in + the greeter. i doubt it's usefulness, though. + +- make builtin xconsole hideable; it should free the device when invisible. + possibly auto-hide it on vt switch - see kdesktop_lock for the x event + handling. + +- ssh-agent/gpg-agent integration (#44177, #65709) + +- lbxproxy integration (tell ghakko) + +- in kcm_tdm, detach backgroundrc change status from tdmrc change status. + +- when a shutdown is scheduled, don't remove all login possibilities. + instead, display a warning in the greeter. use SIGUSR1 to notify already + running greeters about changes. +- user notification about scheduled shutdown (and cancelled forced shutdown): + - wall + - greeter popup + - d-bus message. this would be best, particularly because screen savers + would need no special handling then. +- maybe bomb DefaultSdMode, save in state file instead. compare with ksmserver. + +- gdm changelog indicates that PAM sometimes + - continues despite PAM_CONV_ERR + - asks user name twice +- gdm avoids the PAM_MESSAGE message box vs. prompt problem by displaying + everything in one "error area". all messages are simply appended; an empty + message clears the area. +- gdm stops cursor blinking on not used (remote) displays after 20 secs to + save bandwidth. + +internal stuff: +- improve signal handling in the subdaemon, it's incredibly racy (GOpen/GClose). + depends on proper main loop. + alternative extreme measure: launch greeter from master daemon? +- the process reaping from GClose should be in sync with the main loop. +- kill warning on AIX - see bug #13628 (really present?) +- implement auto-re-login by keeping the display subdaemon alive instead + of starting a new one and feeding it the old auth data. +- options for running the greeter and the core unprivileged. problem: xauth. +- rethink the coupling of the tdm components, particularily the config reader. + options: + - keep things basically as-is, make the Xaccess interface even more flexible, + add capability flags. + - as previous, but don't use #defines, but textual constants. even more + flexible, but slower, bigger, no compile-time checking, and the typing + system would have to be more core-based. keys in the rc are considered + invalid if they were not queried. + - completely opposite: no explicit queries, but hard-code everything. that + kills the idea of having one backend binary for multiple frontends, but + that's a BlueSkyDream anyway. + following that path, the config reader could be nuked at all. + +ralf says: +- put the kmenu sidebar image on the left of the greeter +- enable the clock by default + +thoughts (not really todo): +- PAM sucks. big time. + historically, it is completely incapable of operating in event-driven contexts + when it comes to non-console authentication schemes. the module just hangs in + pam_sm_authenticate() (pam_authenticate() to the outside), waiting for input + from its device. + then came linux-pam 0.58, introducing PAM_BINARY_{MSG,PROMPT} to the + conversation function interface. no conversation function could handle the + binary prompts generically, of course. so came linux-pam 0.63 with a client + library that would add another layer of indirection, so the conversation + function could simply call into it and it would do whatever was configured + by the admin. and everbody was happy, right? wrong! i've yet to see a single + module (except for the demo module in linux-pam, of course) that actually + uses this feature. not to mention the non-existing portability (you don't + seriously expect TOG to extend the PAM standard within the next decade, do + you?). so we're right where we started from. + this imposes problems in two use cases: + - cancelling authentication alltogether. this happens when the user changes + the authentication method or when the greeter exits for some reason. if + the process waits in the conversation function, it can simply return + PAM_CONV_ABORT. if the module hangs, we're screwed. + - suspending authentication. this is needed for shutdowns that need auth. + if the module hangs, we're screwed, of course. if we're waiting in the + conversation function, we have three options: 1) just abort the auth + cycle and start a new one. this is what is done currently. 2) just open + a second pam handle and authenticate with it, all from within the "outer" + pam_authenticate(). if we're lucky, no involved modules use static variables + and things work out. 3) linux-pam 0.65 introduced the following: the + conversation function can return PAM_CONV_AGAIN. this in turn makes the + module and consequently libpam return PAM_INCOMPLETE, requesting the + application to call the resp. libpam function again. in theory this + guarantees that authentication with a second pam handle is safe. of course, + PAM_INCOMPLETE is just as popular and thus useful as PAM_BINARY_PROMPT. + we could just longjmp() out of hanging modules from a signal handler. + however, this might lead to resource leaks and even leave us with an unstable + libpam. killing the hanging process seems like the most viable solution. + however, for this we first need to make the greeter a child of the master + daemon. also, the display sub-daemon (which happens to do the main auth.) + is responsible for keeping the initial X connection open. killing it would + terminate the session according to the XDMCP spec. other issues are probable. +- multiple conv. plugins could be used in a row, each serving a pam module. + the plugins would have to detect that it's their turn by filtering messages + and prompts. +- consider making the menu an actions-only menu again and put an "options >>" + button somewhere. relates #63401, #61492 +- pipe .xsession-errors through the daemon and put a size limit on it. + remove old logs in disk-full situation. +- set LC_ALL in the backend for i18n-capable PAM libs - does one exist? + + +last sync with XFree86 HEAD: 2004-04-02 diff --git a/tdm/backend/CMakeLists.txt b/tdm/backend/CMakeLists.txt new file mode 100644 index 000000000..cd98b3a9c --- /dev/null +++ b/tdm/backend/CMakeLists.txt @@ -0,0 +1,48 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +# FIXME this is far from complete!!! + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR} + ${DBUS_TQT_INCLUDE_DIRS} +) + +link_directories( + ${DBUS_TQT_LIBRARY_DIRS} +) + +##### tdm (executable) ########################## + +add_custom_command( OUTPUT config.ci + COMMAND perl -w ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def config.ci + DEPENDS ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def ) + +set_property( SOURCE auth.c APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/config.ci ) + +if( WITH_XDMCP ) + set( XDMCP_LIBRARIES "Xdmcp" ) +else() + set( XDMCP_LIBRARIES "" ) +endif() + +tde_add_executable( tdm + SOURCES + access.c auth.c bootman.c choose.c client.c consolekit.c + ctrl.c daemon.c dm.c dpylist.c error.c genauth.c + inifile.c krb5auth.c mitauth.c netaddr.c policy.c + process.c protodpy.c reset.c resource.c rpcauth.c + server.c session.c sessreg.c socket.c streams.c + util.c xdmauth.c xdmcp.c + LINK X11 ${XAU_LIBRARIES} ${DBUS_TQT_LIBRARIES} ${CRYPT_LIBRARY} ${PAM_LIBRARY} ${XDMCP_LIBRARIES} + DESTINATION ${BIN_INSTALL_DIR} +) diff --git a/tdm/backend/Imakefile b/tdm/backend/Imakefile new file mode 100644 index 000000000..f3b4e0050 --- /dev/null +++ b/tdm/backend/Imakefile @@ -0,0 +1,203 @@ +/* well, we have no subdirs ... +#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' +*/ + +#ifdef DEBUG +CDEBUGFLAGS := $(CDEBUGFLAGS) -g +#endif + +#ifndef BuildBoth +#define BuildBoth (defined(LinuxArchitecture) && !UseElfFormat) +#endif + +#ifndef LinuxShadowSuite +#define LinuxShadowSuite NO +#endif + +#if FSUseSyslog +LOG_DEFINES = -DUSE_SYSLOG +#endif + +#ifdef NoXDMCP +XDMCPLIB = +#else +XDMCP_DEFINES = -DXDMCP +#endif + +#if HasXdmAuth +XDMAUTH_DEFINES = -DHASXDMAUTH +XDMAUTHOBJS = xdmauth.o +XDMAUTHSRCS = xdmauth.c +#endif + +#if HasSecureRPC +RPC_DEFINES = -DSECURE_RPC +RPCOBJS = rpcauth.o +RPCSRCS = rpcauth.c +RPCLIB = -lrpcsvc +#endif + +#if HasKrbIV +#if NOAFS +KRBIV_DEFINES = KrbIVDefines -DNO_AFS +#else +KRBIV_DEFINES = KrbIVDefines +#endif +KRBIV_INCLUDES = KrbIVIncludes +KRBIVLIB = KrbIVLibraries +#endif + +#if HasKrb5 +KRB5_DEFINES = Krb5Defines +KRB5_INCLUDE = Krb5Includes +KRB5OBJS = krb5auth.o +KRB5SRCS = krb5auth.c +#endif + +/* This is correct for Linux and FreeBSD */ +#if HasPam +PAM_LIBRARIES = PamLibraries +PAM_DEFINES = -DUSE_PAM +#endif + +#if HasPam +#undef HasShadowPasswd +#define HasShadowPasswd NO +#undef HasLibCrypt +#define HasLibCrypt NO +#endif + +/* +#if HasBSDAuth +BSDAUTH_DEFINES = -DUSE_BSDAUTH +#endif +*/ + +#if SystemV4 || HasShadowPasswd + +#if !LinuxShadowSuite +PWD_DEFINES = -DUSESHADOW +#else +PWD_DEFINES = -DUSESHADOW -DSHADOWSUITE +#endif + +#if !defined(i386IscArchitecture) && !defined(i386ScoArchitecture) && !defined(LinuxArchitecture) && !defined(NTOArchitecture) && !defined(SGIArchitecture) +SYS_LIBRARIES3 = -lresolv +#endif +#if SystemV || defined(SequentArchitecture) +SYS_LIBRARIES1 = -lsec +#endif +#if defined(LinuxArchitecture) && (!UseElfFormat || LinuxShadowSuite) +SYS_LIBRARIES1 = -lshadow +#endif + +#endif + +#if defined(UltrixArchitecture) +SYS_LIBRARIES1 = -lauth +#endif + +#if (defined(AIXArchitecture) && (OSMajorVersion >= 3)) +SYS_LIBRARIES1 = -ls +#endif + +#if HasLibCrypt +#ifdef SpecialLibCrypt +CRYPT_LIBRARIES = SpecialLibCrypt +#else +CRYPT_LIBRARIES = -lcrypt +#if defined(LynxOSArchitecture) +CRYPT_DEFINES = -DHAS_CRYPT +#endif +#endif +#endif + +#if HasBSD44Sockets +SOCK_DEFINES = -DBSD44SOCKETS +#endif + +#if defined(i386Architecture) || defined(AmigaArchitecture) +FRAGILE_DEFINES = -DFRAGILE_DEV_MEM +#endif + +#ifdef RandomDefines +RANDOM_DEFINES = RandomDefines +#elif defined(OpenBSDArchitecture) +RANDOM_DEFINES = -DARC4_RANDOM +#elif defined(LinuxArchitecture) +RANDOM_DEFINES = -DDEV_RANDOM=\"/dev/urandom\" +#elif defined(NetBSDArchitecture) && \ + ((OSMajorVersion > 1) || \ + (OSMajorVersion == 1 && OSMinorVersion > 3)) +RANDOM_DEFINES = -DDEV_RANDOM=\"/dev/urandom\" +#endif + + +#if HasSetUserContext +USER_CONTEXT_DEFINES = -DHAS_SETUSERCONTEXT +# XXX - only FreeBSD has this in libutil +SYS_LIBRARIES1 = -lutil +#endif + +#if HasSetProcTitle +PROCTITLE_DEFINES = -DHAS_SETPROCTITLE +#endif + + SYS_LIBRARIES = $(SYS_LIBRARIES1) $(SYS_LIBRARIES2) $(SYS_LIBRARIES3) + + INCLUDES = $(KRB5_INCLUDE) + DEPLIBS = $(DEPXLIB) $(DEPXAUTHLIB) $(DEPXDMCPLIB) + LOCAL_LIBRARIES = $(XLIB) $(XAUTHLIB) \ + $(XDMCPLIB) $(RPCLIB) $(PAM_LIBRARIES) \ + $(CRYPT_LIBRARIES) $(KRBIVLIB) + + COMMSRCS = auth.c daemon.c server.c dpylist.c dm.c error.c \ + netaddr.c reset.c resource.c protodpy.c policy.c \ + session.c socket.c streams.c util.c xdmcp.c \ + process.c mitauth.c \ + genauth.c access.c choose.c consolekit.c \ + $(XDMAUTHSRCS) $(RPCSRCS) $(KRB5SRCS) + COMMOBJS = auth.o daemon.o server.o dpylist.o dm.o error.o \ + netaddr.o reset.o resource.o protodpy.o policy.o \ + session.o socket.o streams.o util.o xdmcp.o \ + process.o mitauth.o \ + genauth.o access.o choose.o consolekit.o \ + $(XDMAUTHOBJS) $(RPCOBJS) $(KRB5OBJS) + + SRCS1 = $(COMMSRCS) client.c + OBJS1 = $(COMMOBJS) client.o + +#if BuildBoth + SRCS2 = $(COMMSRCS) clientsh.c + OBJS2 = $(COMMOBJS) clientsh.o + + XDM_SHADOW = xdm-shadow +#endif + + PROGRAMS = xdm $(XDM_SHADOW) + + + OSMAJORVERSION = OSMajorVersion + OSMINORVERSION = OSMinorVersion + CONN_DEFINES = $(CONNECTION_FLAGS) + DEFINES = $(SIGNAL_DEFINES) $(LOG_DEFINES) \ + $(CRYPT_DEFINES)$(PWD_DEFINES) \ + $(BSDAUTH_DEFINES) $(PAM_DEFINES) $(USER_CONTEXT_DEFINES) \ + $(XDMAUTH_DEFINES) $(RPC_DEFINES) $(KRB5_DEFINES) \ + $(XDMCP_DEFINES) $(SOCK_DEFINES) $(CONN_DEFINES) \ + $(FRAGILE_DEFINES) $(RANDOM_DEFINES) $(PROCTITLE_DEFINES) \ + -DOSMAJORVERSION=$(OSMAJORVERSION) -DOSMINORVERSION=$(OSMINORVERSION) \ + -Dconst= + +ComplexProgramTarget_1(xdm,$(LOCAL_LIBRARIES),NullParameter) +#if BuildBoth +NormalProgramTarget(xdm-shadow,$(OBJS2),$(DEPLIBS),$(LOCAL_LIBRARIES),-lshadow) +InstallProgram(xdm-shadow,$(BINDIR)) +ObjectFromSpecialSource(clientsh,client,-DUSESHADOW) +#endif + +#if defined(FreeBSDArchitecture) && (OSMajorVersion < 2) +XCOMM only for daemon.c? it's used in some other places, too. +SpecialCObjectRule(daemon,$(ICONFIGFILES),-UCSRG_BASED) +#endif + diff --git a/tdm/backend/Makefile.am b/tdm/backend/Makefile.am new file mode 100644 index 000000000..6b5779d51 --- /dev/null +++ b/tdm/backend/Makefile.am @@ -0,0 +1,47 @@ +# forcibly remove thread-related defines & flags +AUTOMAKE_OPTIONS = foreign +CPPFLAGS = $(USER_INCLUDES) $(X_INCLUDES) $(KRB4_INCS) $(KRB5_INCS) $(DBUS_INCS) -I.. -I../.. +LDFLAGS = $(USER_LDFLAGS) $(X_LDFLAGS) $(X_RPATH) $(KRB4_RPATH) $(KRB5_RPATH) +LDADD = $(LIB_X11) -lXau $(LIBXDMCP) $(PASSWDLIBS) $(LIBSHADOW) $(LIBGEN) \ + $(LIB_LIBS) $(KRB4_LIBS) $(KRB5_LIBS) $(DBUS_LIBS) $(LIBSOCKET) $(LIBRESOLV) \ + $(LIBUCB) $(LIBUTIL) $(LIBPOSIX4) + +bin_PROGRAMS = tdm +tdm_SOURCES = \ + access.c \ + auth.c \ + bootman.c \ + choose.c \ + client.c \ + consolekit.c \ + ctrl.c \ + daemon.c \ + dm.c \ + dpylist.c \ + error.c \ + genauth.c \ + inifile.c \ + krb5auth.c \ + mitauth.c \ + netaddr.c \ + policy.c \ + process.c \ + protodpy.c \ + reset.c \ + resource.c \ + rpcauth.c \ + server.c \ + session.c \ + sessreg.c \ + socket.c \ + streams.c \ + util.c \ + xdmauth.c \ + xdmcp.c + +EXTRA_DIST = printf.c + +noinst_HEADERS = dm.h dm_socket.h dm_error.h dm_auth.h greet.h + +# for unsermake (automake is handled by SUBDIRS in ../) +tdm_COMPILE_FIRST = ../config.ci diff --git a/tdm/backend/access.c b/tdm/backend/access.c new file mode 100644 index 000000000..82736be57 --- /dev/null +++ b/tdm/backend/access.c @@ -0,0 +1,468 @@ +/* + +Copyright 1990, 1998 The Open Group +Copyright 2001,2004 Oswald Buddenhagen +Copyright 2002 Sun Microsystems, Inc. All rights reserved. + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * Access control for XDMCP - keep a database of allowable display addresses + * and (potentially) a list of hosts to send ForwardQuery packets to + */ + +#include + +#ifdef XDMCP + +#include "dm.h" +#include "dm_error.h" +#include "dm_socket.h" + +#include +#include + +#include +#if defined(IPv6) && defined(AF_INET6) +# include +#endif + +typedef struct { + short int type; + union { + char *aliasPattern; + char *hostPattern; + struct _displayAddress { + CARD16 connectionType; + ARRAY8 hostAddress; + } displayAddress; + } entry; +} HostEntry; + +typedef struct { + short int iface; + short int mcasts; + short int nmcasts; +} ListenEntry; + +typedef struct { + char *name; + short int hosts; + short int nhosts; +} AliasEntry; + +typedef struct { + short int entries; + short int nentries; + short int hosts; + short int nhosts; + short int flags; +} AclEntry; + +typedef struct { + HostEntry *hostList; + ListenEntry *listenList; + AliasEntry *aliasList; + AclEntry *acList; + short int nHosts, nListens, nAliases, nAcls; + CfgDep dep; +} AccArr; + +static AccArr accData[1]; + + +static ARRAY8 localAddress; + +ARRAY8Ptr +getLocalAddress( void ) +{ + static int haveLocalAddress; + + if (!haveLocalAddress) { +#if defined(IPv6) && defined(AF_INET6) + struct addrinfo *ai; + + if (getaddrinfo( localHostname(), NULL, NULL, &ai )) { + XdmcpAllocARRAY8( &localAddress, 4 ); + localAddress.data[0] = 127; + localAddress.data[1] = 0; + localAddress.data[2] = 0; + localAddress.data[3] = 1; + } else { + if (ai->ai_family == AF_INET) { + XdmcpAllocARRAY8( &localAddress, sizeof(struct in_addr) ); + memcpy( localAddress.data, + &((struct sockaddr_in *)ai->ai_addr)->sin_addr, + sizeof(struct in_addr) ); + } else /* if (ai->ai_family == AF_INET6) */ { + XdmcpAllocARRAY8( &localAddress, sizeof(struct in6_addr) ); + memcpy( localAddress.data, + &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, + sizeof(struct in6_addr) ); + } + freeaddrinfo( ai ); +#else + struct hostent *hostent; + + if ((hostent = gethostbyname( localHostname() ))) { + XdmcpAllocARRAY8( &localAddress, hostent->h_length ); + memmove( localAddress.data, hostent->h_addr, hostent->h_length ); +#endif + haveLocalAddress = 1; + } + } + return &localAddress; +} + + +void +ScanAccessDatabase( int force ) +{ + struct _displayAddress *da; + char *cptr; + int nChars, i; + + Debug( "ScanAccessDatabase\n" ); + if (Setjmp( cnftalk.errjmp )) + return; /* may memleak */ + if (startConfig( GC_gXaccess, &accData->dep, force ) <= 0) + return; + if (accData->hostList) + free( accData->hostList ); + accData->nHosts = GRecvInt(); + accData->nListens = GRecvInt(); + accData->nAliases = GRecvInt(); + accData->nAcls = GRecvInt(); + nChars = GRecvInt(); + if (!(accData->hostList = (HostEntry *) + Malloc( accData->nHosts * sizeof(HostEntry) + + accData->nListens * sizeof(ListenEntry) + + accData->nAliases * sizeof(AliasEntry) + + accData->nAcls * sizeof(AclEntry) + + nChars ))) + { + CloseGetter(); + return; + } + accData->listenList = (ListenEntry *)(accData->hostList + accData->nHosts); + accData->aliasList = (AliasEntry *)(accData->listenList + accData->nListens); + accData->acList = (AclEntry *)(accData->aliasList + accData->nAliases); + cptr = (char *)(accData->acList + accData->nAcls); + for (i = 0; i < accData->nHosts; i++) { + switch ((accData->hostList[i].type = GRecvInt())) { + case HOST_ALIAS: + accData->hostList[i].entry.aliasPattern = cptr; + cptr += GRecvStrBuf( cptr ); + break; + case HOST_PATTERN: + accData->hostList[i].entry.hostPattern = cptr; + cptr += GRecvStrBuf( cptr ); + break; + case HOST_ADDRESS: + da = &accData->hostList[i].entry.displayAddress; + da->hostAddress.data = (unsigned char *)cptr; + cptr += (da->hostAddress.length = GRecvArrBuf( cptr )); + switch (GRecvInt()) + { +#ifdef AF_INET + case AF_INET: + da->connectionType = FamilyInternet; + break; +#endif +#if defined(IPv6) && defined(AF_INET6) + case AF_INET6: + da->connectionType = FamilyInternet6; + break; +#endif +#ifdef AF_DECnet + case AF_DECnet: + da->connectionType = FamilyDECnet; + break; +#endif +/*#ifdef AF_UNIX + case AF_UNIX: +#endif*/ + default: + da->connectionType = FamilyLocal; + break; + } + break; + case HOST_BROADCAST: + break; + default: + LogError( "Received unknown host type %d from config reader\n", accData->hostList[i].type ); + return; + } + } + for (i = 0; i < accData->nListens; i++) { + accData->listenList[i].iface = GRecvInt(); + accData->listenList[i].mcasts = GRecvInt(); + accData->listenList[i].nmcasts = GRecvInt(); + } + for (i = 0; i < accData->nAliases; i++) { + accData->aliasList[i].name = cptr; + cptr += GRecvStrBuf( cptr ); + accData->aliasList[i].hosts = GRecvInt(); + accData->aliasList[i].nhosts = GRecvInt(); + } + for (i = 0; i < accData->nAcls; i++) { + accData->acList[i].entries = GRecvInt(); + accData->acList[i].nentries = GRecvInt(); + accData->acList[i].hosts = GRecvInt(); + accData->acList[i].nhosts = GRecvInt(); + accData->acList[i].flags = GRecvInt(); + } +} + + +/* Returns non-0 if string is matched by pattern. Does case folding. + */ +static int +patternMatch( const char *string, const char *pattern ) +{ + int p, s; + + if (!string) + string = ""; + + for (;;) { + s = *string++; + switch (p = *pattern++) { + case '*': + if (!*pattern) + return 1; + for (string--; *string; string++) + if (patternMatch( string, pattern )) + return 1; + return 0; + case '?': + if (s == '\0') + return 0; + break; + case '\0': + return s == '\0'; + case '\\': + p = *pattern++; + /* fall through */ + default: + if (tolower( p ) != tolower( s )) + return 0; + } + } +} + + +#define MAX_DEPTH 32 + +static void +scanHostlist( int fh, int nh, + ARRAY8Ptr clientAddress, CARD16 connectionType, + ChooserFunc function, char *closure, + int broadcast, int *haveLocalhost ) +{ + HostEntry *h; + AliasEntry *a; + int na; + + for (h = accData->hostList + fh; nh; nh--, h++) { + switch (h->type) { + case HOST_ALIAS: + for (a = accData->aliasList, na = accData->nAliases; na; na--, a++) + if (patternMatch( a->name, h->entry.aliasPattern )) /* XXX originally swapped, no wildcards in alias name matching */ + scanHostlist( a->hosts, a->nhosts, + clientAddress, connectionType, + function, closure, broadcast, + haveLocalhost ); + break; + case HOST_ADDRESS: + if (XdmcpARRAY8Equal( getLocalAddress(), &h->entry.displayAddress.hostAddress )) + *haveLocalhost = 1; + else if (function) + (*function)( connectionType, &h->entry.displayAddress.hostAddress, closure ); + break; + case HOST_BROADCAST: + if (broadcast && function) + (*function)( FamilyBroadcast, 0, closure ); + break; + default: + break; + } + } +} + +static int +scanEntrylist( int fh, int nh, + ARRAY8Ptr clientAddress, CARD16 connectionType, + char **clientName ) +{ + HostEntry *h; + AliasEntry *a; + int na; + + for (h = accData->hostList + fh; nh; nh--, h++) { + switch (h->type) { + case HOST_ALIAS: + for (a = accData->aliasList, na = accData->nAliases; na; na--, a++) + if (patternMatch( a->name, h->entry.aliasPattern )) + if (scanEntrylist( a->hosts, a->nhosts, + clientAddress, connectionType, + clientName )) + return 1; + break; + case HOST_PATTERN: + if (!*clientName) + *clientName = NetworkAddressToHostname( connectionType, + clientAddress ); + if (patternMatch( *clientName, h->entry.hostPattern )) + return 1; + break; + case HOST_ADDRESS: + if (h->entry.displayAddress.connectionType == connectionType && + XdmcpARRAY8Equal( &h->entry.displayAddress.hostAddress, + clientAddress )) + return 1; + break; + default: + break; + } + } + return 0; +} + +static AclEntry * +matchAclEntry( ARRAY8Ptr clientAddress, CARD16 connectionType, int direct ) +{ + AclEntry *e, *re; + char *clientName = 0; + int ne; + + for (e = accData->acList, ne = accData->nAcls, re = 0; ne; ne--, e++) + if (!e->nhosts == direct) + if (scanEntrylist( e->entries, e->nentries, + clientAddress, connectionType, + &clientName )) + { + re = e; + break; + } + if (clientName) + free( clientName ); + return re; +} + +/* + * calls the given function for each valid indirect entry. Returns TRUE if + * the local host exists on any of the lists, else FALSE + */ +int +ForEachMatchingIndirectHost( ARRAY8Ptr clientAddress, + CARD16 connectionType, + ChooserFunc function, char *closure ) +{ + AclEntry *e; + int haveLocalhost = 0; + + e = matchAclEntry( clientAddress, connectionType, 0 ); + if (e && !(e->flags & a_notAllowed)) { + if (e->flags & a_useChooser) { + ARRAY8Ptr choice; + + choice = IndirectChoice( clientAddress, connectionType ); + if (!choice || XdmcpARRAY8Equal( getLocalAddress(), choice )) + haveLocalhost = 1; + else + (*function)( connectionType, choice, closure ); + } else + scanHostlist( e->hosts, e->nhosts, clientAddress, connectionType, + function, closure, FALSE, &haveLocalhost ); + } + return haveLocalhost; +} + +int +UseChooser( ARRAY8Ptr clientAddress, CARD16 connectionType ) +{ + AclEntry *e; + + e = matchAclEntry( clientAddress, connectionType, 0 ); + return e && !(e->flags & a_notAllowed) && (e->flags & a_useChooser) && + !IndirectChoice( clientAddress, connectionType ); +} + +void +ForEachChooserHost( ARRAY8Ptr clientAddress, CARD16 connectionType, + ChooserFunc function, char *closure ) +{ + AclEntry *e; + int haveLocalhost = 0; + + e = matchAclEntry( clientAddress, connectionType, 0 ); + if (e && !(e->flags & a_notAllowed) && (e->flags & a_useChooser)) + scanHostlist( e->hosts, e->nhosts, clientAddress, connectionType, + function, closure, TRUE, &haveLocalhost ); + if (haveLocalhost) + (*function)( connectionType, getLocalAddress(), closure ); +} + +/* + * returns TRUE if the given client is acceptable to the local host. The + * given display client is acceptable if it occurs without a host list. + */ +int +AcceptableDisplayAddress( ARRAY8Ptr clientAddress, CARD16 connectionType, + xdmOpCode type ) +{ + AclEntry *e; + + if (type == INDIRECT_QUERY) + return 1; + + e = matchAclEntry( clientAddress, connectionType, 1 ); + return e && !(e->flags & a_notAllowed) && + (type != BROADCAST_QUERY || !(e->flags & a_notBroadcast)); +} + +void +ForEachListenAddr( ListenFunc listenfunction, ListenFunc mcastfunction, + void **closure ) +{ + int i, j, ifc, mc, nmc; + + for (i = 0; i < accData->nListens; i++) { + ifc = accData->listenList[i].iface; + (*listenfunction)( ifc < 0 ? 0 : + &accData->hostList[ifc].entry.displayAddress.hostAddress, + closure ); + mc = accData->listenList[i].mcasts; + nmc = accData->listenList[i].nmcasts; + for (j = 0; j < nmc; j++, mc++) + (*mcastfunction)( &accData->hostList[mc].entry.displayAddress.hostAddress, + closure ); + } +} +#endif /* XDMCP */ diff --git a/tdm/backend/auth.c b/tdm/backend/auth.c new file mode 100644 index 000000000..bd183142c --- /dev/null +++ b/tdm/backend/auth.c @@ -0,0 +1,1238 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2000-2004 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * maintain the authorization generation daemon + */ + +#include "dm.h" +#include "dm_auth.h" +#include "dm_error.h" + +#include +#include +#include + +#include + +#include "dm_socket.h" +#ifdef DNETCONN +# include +#endif + +#if (defined(_POSIX_SOURCE) && !defined(_AIX) && !defined(__QNX__)) || defined(__hpux) || defined(__svr4__) /* XXX */ +# define NEED_UTSNAME +# include +#endif + +#ifdef __GNU__ +# include +# undef SIOCGIFCONF +#else /* __GNU__ */ +# include +# ifdef __svr4__ +# include +# include +# include +# endif +# ifdef __EMX__ +# define link rename +# define chown(a,b,c) +# include +# endif +#endif /* __GNU__ */ + +struct AuthProtocol { + unsigned short name_length; + const char *name; + void (*InitAuth)( unsigned short len, const char *name ); + Xauth *(*GetAuth)( unsigned short len, const char *name ); +#ifdef XDMCP + void (*GetXdmcpAuth)( struct protoDisplay *pdpy, + unsigned short authorizationNameLen, + const char *authorizationName ); +#endif + int inited; +}; + +#ifdef XDMCP +# define xdmcpauth(arg) , arg +#else +# define xdmcpauth(arg) +#endif + +static struct AuthProtocol AuthProtocols[] = { +{ (unsigned short)18, "MIT-MAGIC-COOKIE-1", + MitInitAuth, MitGetAuth xdmcpauth(NULL), 0 +}, +#ifdef HASXDMAUTH +{ (unsigned short)19, "XDM-AUTHORIZATION-1", + XdmInitAuth, XdmGetAuth xdmcpauth(XdmGetXdmcpAuth), 0 +}, +#endif +#ifdef SECURE_RPC +{ (unsigned short)9, "SUN-DES-1", + SecureRPCInitAuth, SecureRPCGetAuth xdmcpauth(NULL), 0 +}, +#endif +#ifdef K5AUTH +{ (unsigned short)14, "MIT-KERBEROS-5", + Krb5InitAuth, Krb5GetAuth xdmcpauth(NULL), 0 +}, +#endif +}; + +static struct AuthProtocol * +findProtocol( unsigned short name_length, const char *name ) +{ + unsigned i; + + for (i = 0; i < as(AuthProtocols); i++) + if (AuthProtocols[i].name_length == name_length && + memcmp( AuthProtocols[i].name, name, name_length ) == 0) + { + return &AuthProtocols[i]; + } + return (struct AuthProtocol *)0; +} + +int +ValidAuthorization( unsigned short name_length, const char *name ) +{ + if (findProtocol( name_length, name )) + return TRUE; + return FALSE; +} + +static Xauth * +GenerateAuthorization( unsigned short name_length, const char *name ) +{ + struct AuthProtocol *a; + Xauth *auth = 0; + + Debug( "GenerateAuthorization %s\n", name ); + if ((a = findProtocol( name_length, name ))) { + if (!a->inited) { + (*a->InitAuth)( name_length, name ); + a->inited = TRUE; + } + auth = (*a->GetAuth)( name_length, name ); + if (auth) { + Debug( "got %p (%d %.*s) %02[*hhx\n", auth, + auth->name_length, auth->name_length, auth->name, + auth->data_length, auth->data ); + } else + Debug( "got (null)\n" ); + } else + Debug( "unknown authorization %s\n", name ); + return auth; +} + +#ifdef XDMCP + +void +SetProtoDisplayAuthorization( struct protoDisplay *pdpy, + unsigned short authorizationNameLen, + const char *authorizationName ) +{ + struct AuthProtocol *a; + Xauth *auth; + + a = findProtocol( authorizationNameLen, authorizationName ); + pdpy->xdmcpAuthorization = pdpy->fileAuthorization = 0; + if (a) { + if (!a->inited) { + (*a->InitAuth)( authorizationNameLen, authorizationName ); + a->inited = TRUE; + } + if (a->GetXdmcpAuth) { + (*a->GetXdmcpAuth)( pdpy, authorizationNameLen, authorizationName ); + auth = pdpy->xdmcpAuthorization; + } else { + auth = (*a->GetAuth)( authorizationNameLen, authorizationName ); + pdpy->fileAuthorization = auth; + pdpy->xdmcpAuthorization = 0; + } + if (auth) + Debug( "got %p (%d %.*s)\n", auth, + auth->name_length, auth->name_length, auth->name ); + else + Debug( "got (null)\n" ); + } +} + +#endif /* XDMCP */ + +void +CleanUpFileName( const char *src, char *dst, int len ) +{ + while (*src) { + if (--len <= 0) + break; + switch (*src & 0x7f) { + case '/': + *dst++ = '_'; + break; + case '-': + *dst++ = '.'; + break; + default: + *dst++ = (*src & 0x7f); + } + ++src; + } + *dst = '\0'; +} + + +static FILE * +fdOpenW( int fd ) +{ + FILE *f; + + if (fd >= 0) { + if ((f = fdopen( fd, "w" ))) + return f; + close( fd ); + } + return 0; +} + +static FILE * +mkTempFile( char *nambuf, int namelen ) +{ + FILE *f; + int r; + + for (r = 0; r < 100; r++) { + randomStr( nambuf + namelen ); + if ((f = fdOpenW( open( nambuf, O_WRONLY | O_CREAT | O_EXCL, 0600 ) ))) + return f; + if (errno != EEXIST) + break; + } + return 0; +} + +#define NAMELEN 255 + +static FILE * +MakeServerAuthFile( struct display *d ) +{ + FILE *f; + int i; + char cleanname[NAMELEN], nambuf[NAMELEN+128]; + + /* + * Some paranoid, but still not sufficient (DoS was still possible) + * checks used to be here. I removed all this stuff because + * a) authDir is supposed to be /var/run/xauth (=safe) or similar and + * b) even if it's not (say, /tmp), we create files safely (hopefully). + */ + if (mkdir( authDir, 0755 ) < 0 && errno != EEXIST) + return 0; + CleanUpFileName( d->name, cleanname, NAMELEN - 8 ); + i = sprintf( nambuf, "%s/A%s-", authDir, cleanname ); + if ((f = mkTempFile( nambuf, i ))) { + StrDup( &d->authFile, nambuf ); + return f; + } + return 0; +} + +int +SaveServerAuthorizations( struct display *d, Xauth **auths, int count ) +{ + FILE *auth_file; + int i; + + if (!d->authFile && d->clientAuthFile && *d->clientAuthFile) + StrDup( &d->authFile, d->clientAuthFile ); + if (d->authFile) { + if (!(auth_file = fdOpenW( creat( d->authFile, 0600 ) ))) { + LogError( "Cannot open X server authorization file %s\n", d->authFile ); + free( d->authFile ); + d->authFile = NULL; + return FALSE; + } + } else { + if (!(auth_file = MakeServerAuthFile( d ))) { + LogError( "Cannot create X server authorization file\n" ); + return FALSE; + } + } + Debug( "file: %s auth: %p\n", d->authFile, auths ); + for (i = 0; i < count; i++) { + /* + * User-based auths may not have data until + * a user logs in. In which case don't write + * to the auth file so xrdb and setup programs don't fail. + */ + if (auths[i]->data_length > 0) + if (!XauWriteAuth( auth_file, auths[i] ) || + fflush( auth_file ) == EOF) + { + fclose( auth_file ); + LogError( "Cannot write X server authorization file %s\n", + d->authFile ); + free( d->authFile ); + d->authFile = NULL; + return FALSE; + } + } + fclose( auth_file ); + return TRUE; +} + +void +SetLocalAuthorization( struct display *d ) +{ + Xauth *auth, **auths; + int i, j; + + if (d->authorizations) + { + for (i = 0; i < d->authNum; i++) + XauDisposeAuth( d->authorizations[i] ); + free( (char *)d->authorizations ); + d->authorizations = (Xauth **)NULL; + d->authNum = 0; + } + Debug( "SetLocalAuthorization %s, auths %[s\n", d->name, d->authNames ); + if (!d->authNames) + return; + for (i = 0; d->authNames[i]; i++) + ; + d->authNameNum = i; + if (d->authNameLens) + free( (char *)d->authNameLens ); + d->authNameLens = (unsigned short *)Malloc( d->authNameNum * sizeof(unsigned short) ); + if (!d->authNameLens) + return; + for (i = 0; i < d->authNameNum; i++) + d->authNameLens[i] = strlen( d->authNames[i] ); + auths = (Xauth **)Malloc( d->authNameNum * sizeof(Xauth *) ); + if (!auths) + return; + j = 0; + for (i = 0; i < d->authNameNum; i++) { + auth = GenerateAuthorization( d->authNameLens[i], d->authNames[i] ); + if (auth) + auths[j++] = auth; + } + if (SaveServerAuthorizations( d, auths, j )) { + d->authorizations = auths; + d->authNum = j; + } else { + for (i = 0; i < j; i++) + XauDisposeAuth( auths[i] ); + free( (char *)auths ); + } +} + +/* + * Set the authorization to use for xdm's initial connection + * to the X server. Cannot use user-based authorizations + * because no one has logged in yet, so we don't have any + * user credentials. + * Well, actually we could use SUN-DES-1 because we tell the server + * to allow root in. This is bogus and should be fixed. + */ +void +SetAuthorization( struct display *d ) +{ + register Xauth **auth = d->authorizations; + int i; + + for (i = 0; i < d->authNum; i++) { + if (auth[i]->name_length == 9 && + memcmp( auth[i]->name, "SUN-DES-1", 9 ) == 0) + continue; + if (auth[i]->name_length == 14 && + memcmp( auth[i]->name, "MIT-KERBEROS-5", 14 ) == 0) + continue; + XSetAuthorization( auth[i]->name, (int)auth[i]->name_length, + auth[i]->data, (int)auth[i]->data_length ); + } +} + +static int +openFiles( const char *name, char *new_name, FILE **oldp, FILE **newp ) +{ + strcat( strcpy( new_name, name ), "-n" ); + if (!(*newp = + fdOpenW( creat( new_name, 0600 ) ))) { + Debug( "can't open new file %s\n", new_name ); + return 0; + } + *oldp = fopen( name, "r" ); + Debug( "opens succeeded %s %s\n", name, new_name ); + return 1; +} + +struct addrList { + struct addrList *next; + unsigned short family, address_length, number_length; + char data[1]; +}; + +static struct addrList *addrs; + +static void +initAddrs( void ) +{ + addrs = 0; +} + +static void +doneAddrs( void ) +{ + struct addrList *a, *n; + for (a = addrs; a; a = n) { + n = a->next; + free( a ); + } +} + +static void +saveEntry( Xauth *auth ) +{ + struct addrList *new; + + if (!(new = Malloc( offsetof(struct addrList, data) + + auth->address_length + auth->number_length ))) + return; + new->address_length = auth->address_length; + new->number_length = auth->number_length; + memcpy( new->data, auth->address, (int)auth->address_length ); + memcpy( new->data + (int)auth->address_length, + auth->number, (int)auth->number_length ); + new->family = auth->family; + new->next = addrs; + addrs = new; +} + +static int +checkEntry( Xauth *auth ) +{ + struct addrList *a; + + for (a = addrs; a; a = a->next) + if (a->family == auth->family && + a->address_length == auth->address_length && + !memcmp( a->data, auth->address, auth->address_length ) && + a->number_length == auth->number_length && + !memcmp( a->data + a->address_length, + auth->number, auth->number_length )) + return 1; + return 0; +} + +static void +writeAuth( FILE *file, Xauth *auth, int *ok ) +{ + if (debugLevel & DEBUG_AUTH) /* normally too verbose */ + Debug( "writeAuth: doWrite = %d\n" + "family: %d\n" + "addr: %02[*:hhx\n" + "number: %02[*:hhx\n" + "name: %02[*:hhx\n" + "data: %02[*:hhx\n", + ok != 0, auth->family, + auth->address_length, auth->address, + auth->number_length, auth->number, + auth->name_length, auth->name, + auth->data_length, auth->data ); + if (ok && !XauWriteAuth( file, auth )) + *ok = FALSE; +} + +static void +writeAddr( int family, int addr_length, char *addr, + FILE *file, Xauth *auth, int *ok ) +{ + auth->family = (unsigned short)family; + auth->address_length = addr_length; + auth->address = addr; + Debug( "writeAddr: writing and saving an entry\n" ); + writeAuth( file, auth, ok ); + if (!checkEntry( auth )) + saveEntry( auth ); +} + +static void +DefineLocal( FILE *file, Xauth *auth, int *ok ) +{ +#if !defined(NEED_UTSNAME) || defined(__hpux) + char displayname[100]; +#endif +#ifdef NEED_UTSNAME + struct utsname name; +#endif + + /* stolen from xinit.c */ + +/* Make sure this produces the same string as _XGetHostname in lib/X/XlibInt.c. + * Otherwise, Xau will not be able to find your cookies in the Xauthority file. + * + * Note: POSIX says that the ``nodename'' member of utsname does _not_ have + * to have sufficient information for interfacing to the network, + * and so, you may be better off using gethostname (if it exists). + */ + +#ifdef NEED_UTSNAME + + /* hpux: + * Why not use gethostname()? Well, at least on my system, I've had to + * make an ugly kernel patch to get a name longer than 8 characters, and + * uname() lets me access to the whole string (it smashes release, you + * see), whereas gethostname() kindly truncates it for me. + */ + uname( &name ); + writeAddr( FamilyLocal, strlen( name.nodename ), name.nodename, + file, auth, ok ); +#endif + +#if !defined(NEED_UTSNAME) || defined(__hpux) + /* _AIX: + * In _AIX, _POSIX_SOURCE is defined, but uname gives only first + * field of hostname. Thus, we use gethostname instead. + */ + + /* + * For HP-UX, HP's Xlib expects a fully-qualified domain name, which + * is achieved by using gethostname(). For compatability, we must + * also still create the entry using uname() above. + */ + displayname[0] = 0; + if (!gethostname( displayname, sizeof(displayname) )) + displayname[sizeof(displayname) - 1] = 0; + +# ifdef NEED_UTSNAME + /* + * If gethostname and uname both returned the same name, + * do not write a duplicate entry. + */ + if (strcmp( displayname, name.nodename )) +# endif + writeAddr( FamilyLocal, strlen( displayname ), displayname, + file, auth, ok ); +#endif +} + +#ifdef SYSV_SIOCGIFCONF + +/* Deal with different SIOCGIFCONF ioctl semantics on SYSV, SVR4 */ + +int +ifioctl (int fd, int cmd, char *arg) +{ + struct strioctl ioc; + int ret; + + bzero( (char *)&ioc, sizeof(ioc) ); + ioc.ic_cmd = cmd; + ioc.ic_timout = 0; + if (cmd == SIOCGIFCONF) { + ioc.ic_len = ((struct ifconf *)arg)->ifc_len; + ioc.ic_dp = ((struct ifconf *)arg)->ifc_buf; + } else { + ioc.ic_len = sizeof(struct ifreq); + ioc.ic_dp = arg; + } + ret = ioctl( fd, I_STR, (char *)&ioc ); + if (ret >= 0 && cmd == SIOCGIFCONF) + ((struct ifconf *)arg)->ifc_len = ioc.ic_len; + return (ret); +} + +#endif /* SYSV_SIOCGIFCONF */ + +#ifdef HAVE_GETIFADDRS +# include + +static void +DefineSelf( FILE *file, Xauth *auth, int *ok ) +{ + struct ifaddrs *ifap, *ifr; + char *addr; + int family, len; + + if (getifaddrs( &ifap ) < 0) + return; + for (ifr = ifap; ifr; ifr = ifr->ifa_next) { + if (!ifr->ifa_addr) + continue; + family = ConvertAddr( (char *)(ifr->ifa_addr), &len, &addr ); + if (family == -1 || family == FamilyLocal) + continue; + /* + * don't write out 'localhost' entries, as + * they may conflict with other local entries. + * DefineLocal will always be called to add + * the local entry anyway, so this one can + * be tossed. + */ + if (family == FamilyInternet && + addr[0] == 127 && addr[1] == 0 && addr[2] == 0 && addr[3] == 1) + { + Debug( "Skipping localhost address\n" ); + continue; + } +# if defined(IPv6) && defined(AF_INET6) + if (family == FamilyInternet6) { + if (IN6_IS_ADDR_LOOPBACK( ((struct in6_addr *)addr) )) { + Debug( "Skipping IPv6 localhost address\n" ); + continue; + } + /* Also skip XDM-AUTHORIZATION-1 */ + if (auth->name_length == 19 && + !memcmp( auth->name, "XDM-AUTHORIZATION-1", 19 )) { + Debug( "Skipping IPv6 XDM-AUTHORIZATION-1\n" ); + continue; + } + } +# endif + writeAddr( family, len, addr, file, auth, ok ); + } + freeifaddrs( ifap ); +} +#else /* GETIFADDRS */ + +#if defined(STREAMSCONN) && !defined(SYSV_SIOCGIFCONF) && !defined(WINTCP) + +#include + +/* Define this host for access control. Find all the hosts the OS knows about + * for this fd and add them to the selfhosts list. + * TLI version, written without sufficient documentation. + */ +static void +DefineSelf( int fd, FILE *file, Xauth *auth, int *ok ) +{ + struct netbuf netb; + char addrret[1024]; /* easier than t_alloc */ + + netb.maxlen = sizeof(addrret); + netb.buf = addrret; + if (t_getname( fd, &netb, LOCALNAME ) == -1) + t_error( "t_getname" ); + /* what a kludge */ + writeAddr( FamilyInternet, 4, netb.buf+4, file, auth, ok ); +} + +#else + +#ifdef WINTCP /* NCR with Wollongong TCP */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +static void +DefineSelf( int fd, FILE *file, Xauth *auth, int *ok ) +{ + /* + * The Wollongong drivers used by NCR SVR4/MP-RAS don't understand the + * socket IO calls that most other drivers seem to like. Because of + * this, this routine must be special cased for NCR. Eventually, + * this will be cleared up. + */ + + struct ipb ifnet; + struct in_ifaddr ifaddr; + struct strioctl str; + unsigned char *addr; + int len, ipfd; + + if ((ipfd = open( "/dev/ip", O_RDWR, 0 )) < 0) { + LogError( "Trouble getting interface configuration\n" ); + return; + } + + /* Indicate that we want to start at the begining */ + ifnet.ib_next = (struct ipb *)1; + + while (ifnet.ib_next) { + str.ic_cmd = IPIOC_GETIPB; + str.ic_timout = 0; + str.ic_len = sizeof(struct ipb); + str.ic_dp = (char *)&ifnet; + + if (ioctl( ipfd, (int)I_STR, (char *)&str ) < 0) { + close( ipfd ); + LogError( "Trouble getting interface configuration\n" ); + return; + } + + ifaddr.ia_next = (struct in_ifaddr *)ifnet.if_addrlist; + str.ic_cmd = IPIOC_GETINADDR; + str.ic_timout = 0; + str.ic_len = sizeof(struct in_ifaddr); + str.ic_dp = (char *)&ifaddr; + + if (ioctl( ipfd, (int)I_STR, (char *)&str ) < 0) { + close( ipfd ); + LogError( "Trouble getting interface configuration\n" ); + return; + } + + /* + * Ignore the 127.0.0.1 entry. + */ + if (IA_SIN( &ifaddr )->sin_addr.s_addr == htonl( 0x7f000001 ) ) + continue; + + writeAddr( FamilyInternet, 4, (char *)&(IA_SIN( &ifaddr )->sin_addr), + file, auth, ok ); + + } + close( ipfd ); +} + +#else /* WINTCP */ + +/* Solaris provides an extended interface SIOCGLIFCONF. Other systems + * may have this as well, but the code has only been tested on Solaris + * so far, so we only enable it there. Other platforms may be added as + * needed. + * + * Test for Solaris commented out -- TSI @ UQV 2003.06.13 + */ +#ifdef SIOCGLIFCONF +/* #if defined(sun) */ +# define USE_SIOCGLIFCONF +/* #endif */ +#endif + +#if defined(SIOCGIFCONF) || defined (USE_SIOCGLIFCONF) + +#if !defined(SYSV_SIOCGIFCONF) || defined(USE_SIOCGLIFCONF) +# define ifioctl ioctl +#endif + +#ifdef USE_SIOCGLIFCONF +# define ifr_type struct lifreq +#else +# define ifr_type struct ifreq +#endif + +/* Handle variable length ifreq in BNR2 and later */ +#ifdef VARIABLE_IFREQ +# define ifr_size(p) (sizeof(struct ifreq) + \ + (p->ifr_addr.sa_len > sizeof(p->ifr_addr) ? \ + p->ifr_addr.sa_len - sizeof(p->ifr_addr) : 0)) +#else +# define ifr_size(p) (sizeof(ifr_type)) +#endif + +#ifdef USE_SIOCGLIFCONF +# define IFC_IOCTL_REQ SIOCGLIFCONF +# define IFC_REQ(ifc) ifc.lifc_req +# define IFC_LEN(ifc) ifc.lifc_len +# define IFR_ADDR(ifr) ifr->lifr_addr +# define IFR_NAME(ifr) ifr->lifr_name +#else +# define IFC_IOCTL_REQ SIOCGIFCONF +# define IFC_REQ(ifc) ifc.ifc_req +# define IFC_LEN(ifc) ifc.ifc_len +# define IFR_ADDR(ifr) ifr->ifr_addr +# define IFR_NAME(ifr) ifr->ifr_name +#endif + +/* Define this host for access control. Find all the hosts the OS knows about + * for this fd and add them to the selfhosts list. + */ +static void +DefineSelf( int fd, FILE *file, Xauth *auth, int *ok ) +{ + char buf[2048], *cp, *cplim; + int len; + char *addr; + int family; + ifr_type *ifr; +#ifdef USE_SIOCGLIFCONF + int n; + void * bufptr = buf; + size_t buflen = sizeof(buf); + struct lifconf ifc; +# ifdef SIOCGLIFNUM + struct lifnum ifn; +# endif +#else + struct ifconf ifc; +#endif + +#if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF) + ifn.lifn_family = AF_UNSPEC; + ifn.lifn_flags = 0; + if (ioctl( fd, (int)SIOCGLIFNUM, (char *)&ifn ) < 0) + LogError( "Failed getting interface count\n" ); + if (buflen < (ifn.lifn_count * sizeof(struct lifreq))) { + buflen = ifn.lifn_count * sizeof(struct lifreq); + bufptr = Malloc( buflen ); + } +#endif + +#ifdef USE_SIOCGLIFCONF + ifc.lifc_family = AF_UNSPEC; + ifc.lifc_flags = 0; + ifc.lifc_len = buflen; + ifc.lifc_buf = bufptr; +#else + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; +#endif + if (ifioctl (fd, IFC_IOCTL_REQ, (char *)&ifc) < 0) { + LogError( "Trouble getting network interface configuration\n" ); +#if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF) + if (bufptr != buf) + free( bufptr ); +#endif + return; + } + + cplim = (char *)IFC_REQ( ifc ) + IFC_LEN( ifc ); + + for (cp = (char *)IFC_REQ( ifc ); cp < cplim; cp += ifr_size (ifr)) { + ifr = (ifr_type *) cp; +#ifdef DNETCONN + /* + * this is ugly but SIOCGIFCONF returns decnet addresses in + * a different form from other decnet calls + */ + if (IFR_ADDR( ifr ).sa_family == AF_DECnet) { + len = sizeof(struct dn_naddr); + addr = (char *)IFR_ADDR( ifr ).sa_data; + family = FamilyDECnet; + } else +#endif + { + family = ConvertAddr( (char *)&IFR_ADDR( ifr ), &len, &addr ); + if (family < 0) + continue; + + if (len == 0) { + Debug( "skipping zero length address\n" ); + continue; + } + /* + * don't write out 'localhost' entries, as + * they may conflict with other local entries. + * DefineLocal will always be called to add + * the local entry anyway, so this one can + * be tossed. + */ + if (family == FamilyInternet && + addr[0] == 127 && addr[1] == 0 && + addr[2] == 0 && addr[3] == 1) + { + Debug( "skipping localhost address\n" ); + continue; + } +#if defined(IPv6) && defined(AF_INET6) + if (family == FamilyInternet6) { + if (IN6_IS_ADDR_LOOPBACK( ((struct in6_addr *)addr) )) { + Debug( "Skipping IPv6 localhost address\n" ); + continue; + } + /* Also skip XDM-AUTHORIZATION-1 */ + if (auth->name_length == 19 && + !memcmp( auth->name, "XDM-AUTHORIZATION-1", 19 )) { + Debug( "Skipping IPv6 XDM-AUTHORIZATION-1\n" ); + continue; + } + } +#endif + } + Debug( "DefineSelf: write network address, length %d\n", len ); + writeAddr( family, len, addr, file, auth, ok ); + } +#if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF) + if (bufptr != buf) + free( bufptr ); +#endif +} + +#else /* SIOCGIFCONF */ + +/* Define this host for access control. Find all the hosts the OS knows about + * for this fd and add them to the selfhosts list. + */ +static void +DefineSelf( int fd, int file, int auth, int *ok ) +{ + int len; + caddr_t addr; + int family; + + struct utsname name; + register struct hostent *hp; + + union { + struct sockaddr sa; + struct sockaddr_in in; + } saddr; + + struct sockaddr_in *inetaddr; + + /* hpux: + * Why not use gethostname()? Well, at least on my system, I've had to + * make an ugly kernel patch to get a name longer than 8 characters, and + * uname() lets me access to the whole string (it smashes release, you + * see), whereas gethostname() kindly truncates it for me. + */ + uname( &name ); + if ((hp = gethostbyname( name.nodename ))) { + saddr.sa.sa_family = hp->h_addrtype; + inetaddr = (struct sockaddr_in *)(&(saddr.sa)); + memmove( (char *)&(inetaddr->sin_addr), (char *)hp->h_addr, + (int)hp->h_length ); + if ( (family = ConvertAddr( &(saddr.sa), &len, &addr )) >= 0) + writeAddr( FamilyInternet, sizeof(inetaddr->sin_addr), + (char *)(&inetaddr->sin_addr), file, auth, ok ); + } +} + +#endif /* SIOCGIFCONF else */ +#endif /* WINTCP else */ +#endif /* STREAMSCONN && !SYSV_SIOCGIFCONF else */ +#endif /* HAVE_GETIFADDRS */ + +static void +setAuthNumber( Xauth *auth, const char *name ) +{ + char *colon; + char *dot; + + Debug( "setAuthNumber %s\n", name ); + colon = strrchr( name, ':' ); + if (colon) { + ++colon; + dot = strchr( colon, '.' ); + if (dot) + auth->number_length = dot - colon; + else + auth->number_length = strlen( colon ); + if (!StrNDup( &auth->number, colon, auth->number_length )) + auth->number_length = 0; + Debug( "setAuthNumber: %s\n", auth->number ); + } +} + +static void +writeLocalAuth( FILE *file, Xauth *auth, const char *name, int *ok ) +{ +#if defined(STREAMSCONN) || !defined(HAVE_GETIFADDRS) + int fd; +#endif + + Debug( "writeLocalAuth: %s %.*s\n", name, auth->name_length, auth->name ); + setAuthNumber( auth, name ); +# ifdef STREAMSCONN + fd = t_open( "/dev/tcp", O_RDWR, 0 ); + t_bind( fd, NULL, NULL ); + DefineSelf( fd, file, auth, ok ); + t_unbind( fd ); + t_close( fd ); +# elif defined(HAVE_GETIFADDRS) + DefineSelf( file, auth, ok ); +# else +# ifdef TCPCONN +# if defined(IPv6) && defined(AF_INET6) + fd = socket( AF_INET6, SOCK_STREAM, 0 ); + if (fd < 0) +# endif + fd = socket( AF_INET, SOCK_STREAM, 0 ); + DefineSelf( fd, file, auth, ok ); + close( fd ); +# endif +# ifdef DNETCONN + fd = socket( AF_DECnet, SOCK_STREAM, 0 ); + DefineSelf( fd, file, auth, ok ); + close( fd ); +# endif +# endif /* HAVE_GETIFADDRS */ + DefineLocal( file, auth, ok ); +} + +#ifdef XDMCP + +/* + * Call ConvertAddr(), and if it returns an IPv4 localhost, convert it + * to a local display name. Meets the _XTransConvertAddress's localhost + * hack. + */ + +static int +ConvertAuthAddr( char *saddr, int *len, char **addr ) +{ + int ret = ConvertAddr( saddr, len, addr ); + if (ret == FamilyInternet && + ((struct in_addr *)*addr)->s_addr == htonl( 0x7F000001L )) + ret = FamilyLocal; + return ret; +} + +static void +writeRemoteAuth( FILE *file, Xauth *auth, XdmcpNetaddr peer, int peerlen, + const char *name, int *ok ) +{ + int family = FamilyLocal; + char *addr; + + Debug( "writeRemoteAuth: %s %.*s\n", name, auth->name_length, auth->name ); + if (!peer || peerlen < 2) + return; + setAuthNumber( auth, name ); + family = ConvertAuthAddr( peer, &peerlen, &addr ); + Debug( "writeRemoteAuth: family %d\n", family ); + if (family != FamilyLocal) { + Debug( "writeRemoteAuth: %d, %02[*:hhx\n", + family, peerlen, addr ); + writeAddr( family, peerlen, addr, file, auth, ok ); + } else + writeLocalAuth( file, auth, name, ok ); +} + +#endif /* XDMCP */ + +#define NBSIZE 1024 + +static void +startUserAuth( char *buf, char *nbuf, FILE **old, FILE **new ) +{ + const char *home; + int lockStatus; + + initAddrs(); + *new = 0; + if ((home = getEnv( userEnviron, "HOME" )) && strlen( home ) < NBSIZE - 12) { + sprintf( buf, "%s/.Xauthority", home ); + Debug( "XauLockAuth %s\n", buf ); + lockStatus = XauLockAuth( buf, 1, 2, 10 ); + Debug( "lock is %d\n", lockStatus ); + if (lockStatus == LOCK_SUCCESS) + if (!openFiles( buf, nbuf, old, new )) + XauUnlockAuth( buf ); + } + if (!*new) + LogWarn( "Can't update authorization file in home dir %s\n", home ); +} + +static int +endUserAuth( FILE *old, FILE *new, const char *nname, int ok ) +{ + Xauth *entry; + struct stat statb; + + if (old) { + if (fstat( fileno( old ), &statb ) != -1) + chmod( nname, (int)(statb.st_mode & 0777) ); + /*SUPPRESS 560*/ + while ((entry = XauReadAuth( old ))) { + if (!checkEntry( entry )) { + Debug( "writing an entry\n" ); + writeAuth( new, entry, &ok ); + } + XauDisposeAuth( entry ); + } + fclose( old ); + } + if (fclose( new ) == EOF) + ok = FALSE; + doneAddrs(); + return ok; +} + +static void +undoUserAuth( const char *name, const char *new_name ) +{ + LogWarn( "Can't save user authorization in home dir\n" ); + unlink( new_name ); + XauUnlockAuth( name ); +} + +static char * +moveUserAuth( const char *name, char *new_name, char *envname ) +{ + if (unlink( name )) + Debug( "unlink %s failed\n", name ); + if (link( new_name, name )) { + Debug( "link failed %s %s\n", new_name, name ); + LogError( "Can't move user authorization into place\n" ); + envname = new_name; + } else { + Debug( "new authorization moved into place\n" ); + unlink( new_name ); + } + XauUnlockAuth( name ); + return envname; +} + +void +SetUserAuthorization( struct display *d ) +{ + FILE *old, *new; + char *name; + char *envname; + Xauth **auths; + int i, ok; + int magicCookie; + int data_len; + char name_buf[NBSIZE], new_name[NBSIZE + 2]; + + Debug( "SetUserAuthorization\n" ); + auths = d->authorizations; + if (auths) { + startUserAuth( name_buf, new_name, &old, &new ); + if (new) { + envname = 0; + name = name_buf; + } else { + fallback: + if (strlen( d->userAuthDir ) >= NBSIZE - 13) + return; + /* + * Note, that we don't lock the auth file here, as it's + * temporary - we can assume, that we are the only ones + * knowing about this file anyway. + */ + i = sprintf( name_buf, "%s/.Xauth", d->userAuthDir ); + new = mkTempFile( name_buf, i ); + if (!new) { + LogError( "Can't create authorization file in %s\n", + d->userAuthDir ); + return; + } + name = 0; + envname = name_buf; + old = 0; + } + ok = TRUE; + Debug( "%d authorization protocols for %s\n", d->authNum, d->name ); + /* + * Write MIT-MAGIC-COOKIE-1 authorization first, so that + * R4 clients which only knew that, and used the first + * matching entry will continue to function + */ + magicCookie = -1; + for (i = 0; i < d->authNum; i++) { + if (auths[i]->name_length == 18 && + !memcmp( auths[i]->name, "MIT-MAGIC-COOKIE-1", 18 )) + { + magicCookie = i; + if ((d->displayType & d_location) == dLocal) + writeLocalAuth( new, auths[i], d->name, &ok ); +#ifdef XDMCP + else + writeRemoteAuth( new, auths[i], (XdmcpNetaddr)d->peer.data, + d->peer.length, d->name, &ok ); +#endif + break; + } + } + /* now write other authorizations */ + for (i = 0; i < d->authNum; i++) { + if (i != magicCookie) { + data_len = auths[i]->data_length; + /* client will just use default Kerberos cache, so don't + * even write cache info into the authority file. + */ + if (auths[i]->name_length == 14 && + !strncmp( auths[i]->name, "MIT-KERBEROS-5", 14 )) + auths[i]->data_length = 0; + if ((d->displayType & d_location) == dLocal) + writeLocalAuth( new, auths[i], d->name, &ok ); +#ifdef XDMCP + else + writeRemoteAuth( new, auths[i], (XdmcpNetaddr)d->peer.data, + d->peer.length, d->name, &ok ); +#endif + auths[i]->data_length = data_len; + } + } + if (!endUserAuth( old, new, new_name, ok )) { + if (!name) { + LogError( "Can't save user authorization\n" ); + return; + } + undoUserAuth( name, new_name ); + initAddrs(); + goto fallback; + } + if (name) + envname = moveUserAuth( name, new_name, envname ); + if (envname) { + userEnviron = setEnv( userEnviron, "XAUTHORITY", envname ); + systemEnviron = setEnv( systemEnviron, "XAUTHORITY", envname ); + } + /* a chown() used to be here, but this code runs as user anyway */ + } + Debug( "done SetUserAuthorization\n" ); +} + +void +RemoveUserAuthorization( struct display *d ) +{ + Xauth **auths; + FILE *old, *new; + int i; + char name[NBSIZE], new_name[NBSIZE + 2]; + + if (!(auths = d->authorizations)) + return; + Debug( "RemoveUserAuthorization\n" ); + startUserAuth( name, new_name, &old, &new ); + if (new) { + for (i = 0; i < d->authNum; i++) { + if ((d->displayType & d_location) == dLocal) + writeLocalAuth( new, auths[i], d->name, 0 ); +#ifdef XDMCP + else + writeRemoteAuth( new, auths[i], (XdmcpNetaddr)d->peer.data, + d->peer.length, d->name, 0 ); +#endif + } + if (endUserAuth( old, new, new_name, TRUE )) + (void)moveUserAuth( name, new_name, 0 ); + else + undoUserAuth( name, new_name ); + } + Debug( "done RemoveUserAuthorization\n" ); +} diff --git a/tdm/backend/bootman.c b/tdm/backend/bootman.c new file mode 100644 index 000000000..291164ea7 --- /dev/null +++ b/tdm/backend/bootman.c @@ -0,0 +1,277 @@ +/* + +Copyright 2005 Stephan Kulow +Copyright 2005 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * Boot options + */ + +#include "dm.h" +#include "dm_error.h" + +#include +#include +#include +#include + +extern char **environ; + +static int +getNull( char ***opts ATTR_UNUSED, int *def ATTR_UNUSED, int *cur ATTR_UNUSED ) +{ + return BO_NOMAN; +} + +static int +setNull( const char *opt ATTR_UNUSED, SdRec *sdr ATTR_UNUSED ) +{ + return BO_NOMAN; +} + +static char * +match( char *obuf, int *blen, const char *key, int klen ) +{ + char *buf = obuf; + if (memcmp( buf, key, klen ) || !isspace( buf[klen] )) + return 0; + buf += klen + 1; + for (; isspace( *buf ); buf++); + if (!*buf) + return 0; + *blen -= buf - obuf; + return buf; +} + +#define GRUB_MENU "/boot/grub/menu.lst" + +static char *grub; + +static int +getGrub( char ***opts, int *def, int *cur ) +{ + FILE *f; + char *ptr, *linp; + int len; + char line[1000]; + + if (!grub && !(grub = locate( "grub-set-default" ))) + return BO_NOMAN; + + *def = 0; + *cur = -1; + *opts = initStrArr( 0 ); + + if (!(f = fopen( GRUB_MENU, "r" ))) + return errno == ENOENT ? BO_NOMAN : BO_IO; + while ((len = fGets( line, sizeof(line), f )) != -1) { + for (linp = line; isspace(*linp); linp++, len--); + if ((ptr = match( linp, &len, "default", 7 ))) + *def = atoi( ptr ); + else if ((ptr = match( linp, &len, "title", 5 ))) { + for (; isspace( ptr[len - 1] ); len--); + *opts = addStrArr( *opts, ptr, len ); + } + } + fclose( f ); + + return BO_OK; +} + +static int +setGrub( const char *opt, SdRec *sdr ) +{ + FILE *f; + char *ptr; + int len, i; + char line[1000]; + + if (!(f = fopen( GRUB_MENU, "r" ))) + return errno == ENOENT ? BO_NOMAN : BO_IO; + for (i = 0; (len = fGets( line, sizeof(line), f )) != -1; ) + if ((ptr = match( line, &len, "title", 5 ))) { + if (!strcmp( ptr, opt )) { + fclose( f ); + sdr->osindex = i; + sdr->bmstamp = mTime( GRUB_MENU ); + return BO_OK; + } + i++; + } + fclose( f ); + return BO_NOENT; +} + +static void +commitGrub( void ) +{ + char command[256]; + + if (sdRec.bmstamp != mTime( GRUB_MENU ) && + setGrub( sdRec.osname, &sdRec ) != BO_OK) + return; + + sprintf(command, "%s %d", grub, sdRec.osindex); + system(command); +} + +static char *lilo; + +static int +getLilo( char ***opts, int *def, int *cur ) +{ + FILE *f; + int cdef, pid, len, ret = BO_OK; + static const char *args[5] = { 0, "-w", "-v", "-q", 0 }; + char buf[256], next[256]; + + if (!lilo && !(lilo = locate( "lilo" ))) + return BO_NOMAN; + + args[0] = lilo; + if (!(f = pOpen( (char **)args, 'r', &pid ))) + return BO_IO; + *opts = 0; + next[0] = 0; + for (;;) { + if ((len = fGets( buf, sizeof(buf), f)) == -1) { + ret = BO_NOMAN; + goto out; + } + if (!memcmp( buf, "Images:", 7 )) + break; +#define Ldeflin " Default boot command line:" + if (!memcmp( buf, Ldeflin, strlen(Ldeflin) )) { + memcpy( next, buf + strlen(Ldeflin) + 2, len - strlen(Ldeflin) - 3 ); + next[len - strlen(Ldeflin) - 3] = 0; + } + } + cdef = *def = 0; + *cur = -1; + *opts = initStrArr( 0 ); + while ((len = fGets( buf, sizeof(buf), f)) != -1) + if (buf[0] == ' ' && buf[1] == ' ' && buf[2] != ' ') { + if (buf[len - 1] == '*') { + *def = cdef; + len--; + } + for (; buf[len - 1] == ' '; len--); + *opts = addStrArr( *opts, buf + 2, len - 2 ); + if (!strcmp( (*opts)[cdef], next )) + *cur = cdef; + cdef++; + } + out: + if (pClose( f, pid )) { + if (*opts) + freeStrArr( *opts ); + return BO_IO; + } + return ret; +} + +static int +setLilo( const char *opt, SdRec *sdr ATTR_UNUSED ) +{ + char **opts; + int def, cur, ret, i; + + if ((ret = getLilo( &opts, &def, &cur )) != BO_OK) + return ret; + if (!*opt) + opt = 0; + else { + for (i = 0; opts[i]; i++) + if (!strcmp( opts[i], opt )) + goto oke; + freeStrArr( opts ); + return BO_NOENT; + } + oke: + freeStrArr( opts ); + return BO_OK; +} + +static void +commitLilo( void ) +{ + static const char *args[5] = { 0, "-w", "-R", 0, 0 }; + + args[0] = lilo; + args[3] = sdRec.osname; + runAndWait( (char **)args, environ ); +} + +static struct { + int (*get)( char ***, int *, int * ); + int (*set)( const char *, SdRec * ); + void (*commit)( void ); +} bootOpts[] = { + { getNull, setNull, 0 }, + { getGrub, setGrub, commitGrub }, + { getLilo, setLilo, commitLilo }, +}; + +int +getBootOptions( char ***opts, int *def, int *cur ) +{ + return bootOpts[bootManager].get( opts, def, cur ); +} + +int +setBootOption( const char *opt, SdRec *sdr ) +{ + int ret; + + if (sdr->osname) { + free( sdr->osname ); + sdr->osname = 0; + } + if (opt) { + if ((ret = bootOpts[bootManager].set( opt, sdr )) != BO_OK) + return ret; + if (!StrDup( &sdr->osname, opt )) + return BO_IO; /* BO_NOMEM */ + } + return BO_OK; +} + +void +commitBootOption( void ) +{ + if (sdRec.osname) { + bootOpts[bootManager].commit(); +/* + free( sdRec.osname ); + sdRec.osname = 0; +*/ + } +} + diff --git a/tdm/backend/choose.c b/tdm/backend/choose.c new file mode 100644 index 000000000..ead841228 --- /dev/null +++ b/tdm/backend/choose.c @@ -0,0 +1,1051 @@ +/* + +Copyright 1990, 1998 The Open Group +Copyright 2002-2004 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * chooser backend + */ + +#include + +#ifdef XDMCP + +#include "dm.h" +#include "dm_error.h" +#include "dm_socket.h" + +#include + +#ifdef __svr4__ +# include +#endif +#include + +#include +#ifdef STREAMSCONN +# ifdef WINTCP /* NCR with Wollongong TCP */ +# include +# endif +# include +# include +# include +# include +#endif + +#if !defined(__GNU__) && !defined(__hpux) /* XXX __hpux might be wrong */ +# include +#endif + +#include + +typedef struct _IndirectUsers { + struct _IndirectUsers *next; + ARRAY8 client; + CARD16 connectionType; +} IndirectUsersRec, *IndirectUsersPtr; + +static IndirectUsersPtr indirectUsers; + +int +RememberIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ) +{ + IndirectUsersPtr i; + + for (i = indirectUsers; i; i = i->next) + if (XdmcpARRAY8Equal( clientAddress, &i->client ) && + connectionType == i->connectionType) + return 1; + if (!(i = (IndirectUsersPtr)Malloc( sizeof(IndirectUsersRec) ))) + return 0; + if (!XdmcpCopyARRAY8( clientAddress, &i->client )) { + free( (char *)i ); + return 0; + } + i->connectionType = connectionType; + i->next = indirectUsers; + indirectUsers = i; + return 1; +} + +void +ForgetIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ) +{ + IndirectUsersPtr *i, ni; + + for (i = &indirectUsers; *i; i = &(*i)->next) + if (XdmcpARRAY8Equal( clientAddress, &(*i)->client ) && + connectionType == (*i)->connectionType) + { + ni = (*i)->next; + XdmcpDisposeARRAY8( &(*i)->client ); + free( (char *)(*i) ); + (*i) = ni; + break; + } +} + +int +IsIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ) +{ + IndirectUsersPtr i; + + for (i = indirectUsers; i; i = i->next) + if (XdmcpARRAY8Equal( clientAddress, &i->client ) && + connectionType == i->connectionType) + return 1; + return 0; +} + +typedef struct _Choices { + struct _Choices *next; + ARRAY8 client; + CARD16 connectionType; + ARRAY8 choice; + Time_t time; +} ChoiceRec, *ChoicePtr; + +static ChoicePtr choices; + +ARRAY8Ptr +IndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType ) +{ + ChoicePtr c, next, prev; + + prev = 0; + for (c = choices; c; c = next) { + next = c->next; + Debug( "choice checking timeout: %ld >? %d\n", + (long)(now - c->time), choiceTimeout ); + if (now - c->time > (Time_t)choiceTimeout) { + Debug( "timeout choice %ld > %d\n", + (long)(now - c->time), choiceTimeout ); + if (prev) + prev->next = next; + else + choices = next; + XdmcpDisposeARRAY8( &c->client ); + XdmcpDisposeARRAY8( &c->choice ); + free( (char *)c ); + } else { + if (XdmcpARRAY8Equal( clientAddress, &c->client ) && + connectionType == c->connectionType) + return &c->choice; + prev = c; + } + } + return 0; +} + +int +RegisterIndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType, + ARRAY8Ptr choice ) +{ + ChoicePtr c; + int insert; +#if 0 + int found = 0; +#endif + + Debug( "got indirect choice back\n" ); + for (c = choices; c; c = c->next) { + if (XdmcpARRAY8Equal( clientAddress, &c->client ) && + connectionType == c->connectionType) { +#if 0 + found = 1; +#endif + break; + } + } +#if 0 + if (!found) + return 0; +#endif + + insert = 0; + if (!c) { + insert = 1; + c = (ChoicePtr)Malloc( sizeof(ChoiceRec) ); + if (!c) + return 0; + c->connectionType = connectionType; + if (!XdmcpCopyARRAY8( clientAddress, &c->client )) { + free( (char *)c ); + return 0; + } + } else + XdmcpDisposeARRAY8( &c->choice ); + if (!XdmcpCopyARRAY8( choice, &c->choice )) { + XdmcpDisposeARRAY8( &c->client ); + free( (char *)c ); + return 0; + } + if (insert) { + c->next = choices; + choices = c; + } + c->time = now; + return 1; +} + +#if 0 +static void +RemoveIndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType ) +{ + ChoicePtr c, prev; + + prev = 0; + for (c = choices; c; c = c->next) { + if (XdmcpARRAY8Equal( clientAddress, &c->client ) && + connectionType == c->connectionType) + { + if (prev) + prev->next = c->next; + else + choices = c->next; + XdmcpDisposeARRAY8( &c->client ); + XdmcpDisposeARRAY8( &c->choice ); + free( (char *)c ); + return; + } + prev = c; + } +} +#endif + + +/* ####################### */ + + +typedef struct _hostAddr { + struct _hostAddr *next; + struct sockaddr *addr; + int addrlen; + xdmOpCode type; +} HostAddr; + +static HostAddr *hostAddrdb; + +typedef struct _hostName { + struct _hostName *next; + unsigned willing:1, alive:1; + ARRAY8 hostname, status; + CARD16 connectionType; + ARRAY8 hostaddr; +} HostName; + +static HostName *hostNamedb; + +static XdmcpBuffer directBuffer, broadcastBuffer; +static XdmcpBuffer buffer; + +static int socketFD; +#if defined(IPv6) && defined(AF_INET6) +static int socket6FD; +#endif + + +static void +doPingHosts() +{ + HostAddr *hosts; + + for (hosts = hostAddrdb; hosts; hosts = hosts->next) +#if defined(IPv6) && defined(AF_INET6) + XdmcpFlush( hosts->addr->sa_family == AF_INET6 ? socket6FD : socketFD, +#else + XdmcpFlush( socketFD, +#endif + hosts->type == QUERY ? &directBuffer : &broadcastBuffer, + (XdmcpNetaddr)hosts->addr, hosts->addrlen ); +} + +static int +addHostname( ARRAY8Ptr hostname, ARRAY8Ptr status, + struct sockaddr *addr, int will ) +{ + HostName **names, *name; + ARRAY8 hostAddr; + CARD16 connectionType; + + switch (addr->sa_family) { + case AF_INET: + hostAddr.data = + (CARD8 *)& ((struct sockaddr_in *)addr)->sin_addr; + hostAddr.length = 4; + connectionType = FamilyInternet; + break; +#if defined(IPv6) && defined(AF_INET6) + case AF_INET6: + hostAddr.data = + (CARD8 *)&((struct sockaddr_in6 *)addr)->sin6_addr; + hostAddr.length = 16; + connectionType = FamilyInternet6; + break; +#endif + default: + hostAddr.data = (CARD8 *)""; + hostAddr.length = 0; + connectionType = FamilyLocal; + break; + } + for (names = &hostNamedb; *names; names = &(*names)->next) { + name = *names; + if (connectionType == name->connectionType && + XdmcpARRAY8Equal( &hostAddr, &name->hostaddr )) + { + if (XdmcpARRAY8Equal( status, &name->status )) + return 0; + XdmcpDisposeARRAY8( &name->status ); + XdmcpDisposeARRAY8( hostname ); + + GSendInt( G_Ch_ChangeHost ); + goto gotold; + } + } + if (!(name = (HostName *)Malloc( sizeof(*name) ))) + return 0; + if (hostname->length) { + switch (addr->sa_family) { + case AF_INET: +#if defined(IPv6) && defined(AF_INET6) + case AF_INET6: +#endif + { + struct hostent *hostent; + char *host; + + hostent = gethostbyaddr( (char *)hostAddr.data, + hostAddr.length, addr->sa_family ); + if (hostent) { + XdmcpDisposeARRAY8( hostname ); + host = hostent->h_name; + XdmcpAllocARRAY8( hostname, strlen( host ) ); + memmove( hostname->data, host, hostname->length ); + } + } + } + } + if (!XdmcpAllocARRAY8( &name->hostaddr, hostAddr.length )) { + free( (char *)name ); + return 0; + } + memmove( name->hostaddr.data, hostAddr.data, hostAddr.length ); + name->connectionType = connectionType; + name->hostname = *hostname; + + *names = name; + name->next = 0; + + GSendInt( G_Ch_AddHost ); + gotold: + name->alive = 1; + name->willing = will; + name->status = *status; + + GSendInt( (int)name ); /* just an id */ + GSendNStr( (char *)name->hostname.data, name->hostname.length ); + GSendNStr( (char *)name->status.data, name->status.length ); + GSendInt( will ); + + return 1; +} + +static void +disposeHostname( HostName *host ) +{ + XdmcpDisposeARRAY8( &host->hostname ); + XdmcpDisposeARRAY8( &host->hostaddr ); + XdmcpDisposeARRAY8( &host->status ); + free( (char *)host ); +} + +static void +emptyHostnames( void ) +{ + HostName *host, *nhost; + + for (host = hostNamedb; host; host = nhost) { + nhost = host->next; + disposeHostname( host ); + } + hostNamedb = 0; +} + +static void +receivePacket( int sfd ) +{ + XdmcpHeader header; + ARRAY8 authenticationName; + ARRAY8 hostname; + ARRAY8 status; + int saveHostname = 0; +#if defined(IPv6) && defined(AF_INET6) + struct sockaddr_storage addr; +#else + struct sockaddr addr; +#endif + int addrlen; + + addrlen = sizeof(addr); + if (!XdmcpFill( sfd, &buffer, (XdmcpNetaddr)&addr, &addrlen )) + return; + if (!XdmcpReadHeader( &buffer, &header )) + return; + if (header.version != XDM_PROTOCOL_VERSION) + return; + hostname.data = 0; + status.data = 0; + authenticationName.data = 0; + switch (header.opcode) { + case WILLING: + if (XdmcpReadARRAY8( &buffer, &authenticationName ) && + XdmcpReadARRAY8( &buffer, &hostname ) && + XdmcpReadARRAY8( &buffer, &status )) { + if (header.length == 6 + authenticationName.length + + hostname.length + status.length) { + if (addHostname( &hostname, &status, + (struct sockaddr *)&addr, 1 )) + saveHostname = 1; + } + } + XdmcpDisposeARRAY8( &authenticationName ); + break; + case UNWILLING: + if (XdmcpReadARRAY8( &buffer, &hostname ) && + XdmcpReadARRAY8( &buffer, &status )) { + if (header.length == 4 + hostname.length + status.length) { + if (addHostname( &hostname, &status, + (struct sockaddr *)&addr, 0 )) + saveHostname = 1; + } + } + break; + default: + break; + } + if (!saveHostname) { + XdmcpDisposeARRAY8( &hostname ); + XdmcpDisposeARRAY8( &status ); + } +} + +static void +addHostaddr( HostAddr **hosts, struct sockaddr *addr, int len, xdmOpCode type ) +{ + HostAddr *host; + + Debug( "adding host %[*hhu, type %d\n", len, addr, type ); + for (host = *hosts; host; host = host->next) + if (host->type == type && host->addr->sa_family == addr->sa_family) + switch (addr->sa_family) { + case AF_INET: + { + struct sockaddr_in *na = (struct sockaddr_in *)addr; + struct sockaddr_in *oa = (struct sockaddr_in *)host->addr; + if (na->sin_port == oa->sin_port && + na->sin_addr.s_addr == oa->sin_addr.s_addr) + return; + break; + } +#if defined(IPv6) && defined(AF_INET6) + case AF_INET6: + { + struct sockaddr_in6 *na = (struct sockaddr_in6 *)addr; + struct sockaddr_in6 *oa = (struct sockaddr_in6 *)host->addr; + if (na->sin6_port == oa->sin6_port && + !memcmp( &na->sin6_addr, &oa->sin6_addr, 16 )) + return; + break; + } +#endif + default: /* ... */ + break; + } + Debug( " not dupe\n" ); + if (!(host = (HostAddr *)Malloc( sizeof(*host) ))) + return; + if (!(host->addr = (struct sockaddr *)Malloc( len ))) { + free( (char *)host ); + return; + } + memcpy( (char *)host->addr, (char *)addr, len ); + host->addrlen = len; + host->type = type; + host->next = *hosts; + *hosts = host; +} + +static void +registerHostaddr( struct sockaddr *addr, int len, xdmOpCode type ) +{ + addHostaddr( &hostAddrdb, addr, len, type ); +} + +static void +emptyPingHosts( void ) +{ + HostAddr *host, *nhost; + + for (host = hostAddrdb; host; host = nhost) { + nhost = host->next; + free( host->addr ); + free( host ); + } + hostAddrdb = 0; +} + +/* Handle variable length ifreq in BNR2 and later */ +#ifdef VARIABLE_IFREQ +# define ifr_size(p) \ + (sizeof(struct ifreq) + \ + (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \ + p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0)) +#else +# define ifr_size(p) (sizeof(struct ifreq)) +#endif + +#define IFC_REQ(ifc) ifc.ifc_req + +#ifndef SYSV_SIOCGIFCONF +# define ifioctl ioctl +#endif + +static void +registerBroadcastForPing( void ) +{ + struct sockaddr_in in_addr; + +#ifdef __GNU__ + in_addr.sin_addr.s_addr = htonl( 0xFFFFFFFF ); + in_addr.sin_port = htons( XDM_UDP_PORT ); + registerHostaddr( (struct sockaddr *)&in_addr, sizeof(in_addr), + BROADCAST_QUERY ); +#else /* __GNU__ */ + struct ifconf ifc; + register struct ifreq *ifr; + struct sockaddr broad_addr; + char buf[2048], *cp, *cplim; +# ifdef WINTCP /* NCR with Wollongong TCP */ + int ipfd; + struct ifconf *ifcp; + struct strioctl ioc; + int n; + + ifcp = (struct ifconf *)buf; + ifcp->ifc_buf = buf + 4; + ifcp->ifc_len = sizeof(buf) - 4; + + if ((ipfd = open( "/dev/ip", O_RDONLY )) < 0) { + t_error( "RegisterBroadcastForPing() t_open(/dev/ip) failed" ); + return; + } + + ioc.ic_cmd = IPIOC_GETIFCONF; + ioc.ic_timout = 60; + ioc.ic_len = sizeof(buf); + ioc.ic_dp = (char *)ifcp; + + if (ioctl( ipfd, (int)I_STR, (char *)&ioc ) < 0) { + perror( "RegisterBroadcastForPing() ioctl(I_STR(IPIOC_GETIFCONF)) failed" ); + close( ipfd ); + return; + } + + for (ifr = ifcp->ifc_req, n = ifcp->ifc_len / sizeof(struct ifreq); + --n >= 0; ifr++) +# else /* WINTCP */ + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + if (ifioctl(socketFD, (int)SIOCGIFCONF, (char *)&ifc) < 0) + return; + + cplim = (char *)IFC_REQ( ifc ) + ifc.ifc_len; + + for (cp = (char *)IFC_REQ( ifc ); cp < cplim; cp += ifr_size(ifr)) +# endif /* WINTCP */ + { +# ifndef WINTCP + ifr = (struct ifreq *)cp; +# endif + if (ifr->ifr_addr.sa_family != AF_INET) + continue; + + broad_addr = ifr->ifr_addr; + ((struct sockaddr_in *)&broad_addr)->sin_addr.s_addr = + htonl( INADDR_BROADCAST ); +# ifdef SIOCGIFBRDADDR + { + struct ifreq broad_req; + + broad_req = *ifr; +# ifdef WINTCP /* NCR with Wollongong TCP */ + ioc.ic_cmd = IPIOC_GETIFFLAGS; + ioc.ic_timout = 0; + ioc.ic_len = sizeof(broad_req); + ioc.ic_dp = (char *)&broad_req; + + if (ioctl (ipfd, I_STR, (char *) &ioc ) != -1 && +# else /* WINTCP */ + if (ifioctl( socketFD, SIOCGIFFLAGS, (char *)&broad_req ) != + -1 && +# endif /* WINTCP */ + (broad_req.ifr_flags & IFF_BROADCAST) && + (broad_req.ifr_flags & IFF_UP)) + { + broad_req = *ifr; +# ifdef WINTCP /* NCR with Wollongong TCP */ + ioc.ic_cmd = IPIOC_GETIFBRDADDR; + ioc.ic_timout = 0; + ioc.ic_len = sizeof(broad_req); + ioc.ic_dp = (char *)&broad_req; + + if (ioctl( ipfd, I_STR, (char *) &ioc) != -1 ) +# else /* WINTCP */ + if (ifioctl( socketFD, SIOCGIFBRDADDR, (char *)&broad_req ) + != -1) +# endif /* WINTCP */ + broad_addr = broad_req.ifr_addr; + else + continue; + } else + continue; + } +# endif + in_addr = *((struct sockaddr_in *)&broad_addr); + in_addr.sin_port = htons( XDM_UDP_PORT ); +# ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + in_addr.sin_len = sizeof(in_addr); +# endif + registerHostaddr( (struct sockaddr *)&in_addr, sizeof(in_addr), + BROADCAST_QUERY ); + } +#endif +} + +static int +makeSockAddrs( const char *name, HostAddr **hosts ) +{ +#if defined(IPv6) && defined(AF_INET6) + struct addrinfo *ai, *nai, hints; + bzero( &hints, sizeof(hints) ); + hints.ai_socktype = SOCK_DGRAM; + if (getaddrinfo( name, stringify( XDM_UDP_PORT ), &hints, &ai )) + return 0; + for (nai = ai; nai; nai = nai->ai_next) + if ((nai->ai_family == AF_INET) || (nai->ai_family == AF_INET6)) + addHostaddr( hosts, nai->ai_addr, nai->ai_addrlen, + (nai->ai_family == AF_INET ? + IN_MULTICAST( ((struct sockaddr_in *)nai->ai_addr)->sin_addr.s_addr ) : + IN6_IS_ADDR_MULTICAST( &((struct sockaddr_in6 *)nai->ai_addr)->sin6_addr )) ? + BROADCAST_QUERY : QUERY ); +#else + struct sockaddr_in in_addr; + /* Per RFC 1123, check first for IP address in dotted-decimal form */ + if ((in_addr.sin_addr.s_addr = inet_addr( name )) == (unsigned)-1) { + struct hostent *hostent; + if (!(hostent = gethostbyname( name )) || + hostent->h_addrtype != AF_INET) + return 0; + memcpy( &in_addr.sin_addr, hostent->h_addr, 4 ); + } + in_addr.sin_family = AF_INET; + in_addr.sin_port = htons( XDM_UDP_PORT ); +# ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + in_addr.sin_len = sizeof(in_addr); +# endif + addHostaddr( hosts, (struct sockaddr *)&in_addr, sizeof(in_addr), +# ifdef IN_MULTICAST + IN_MULTICAST( in_addr.sin_addr.s_addr ) ? + BROADCAST_QUERY : +# endif + QUERY ); +#endif + return 1; +} + +/* + * Register the address for this host. + * Called for interactively specified hosts. + * The special names "BROADCAST" and "*" look up all the broadcast + * addresses on the local host. + */ + +static int +registerForPing( const char *name ) +{ + Debug( "manual host registration: %s\n", name ); + if (!strcmp( name, "BROADCAST" ) || !strcmp( name, "*" )) + registerBroadcastForPing(); + else if (!makeSockAddrs( name, &hostAddrdb )) + return 0; + return 1; +} + +/*ARGSUSED*/ +static void +AddChooserHost( + CARD16 connectionType, + ARRAY8Ptr addr, + char *closure ATTR_UNUSED ) +{ + if (connectionType == FamilyBroadcast) { + registerBroadcastForPing(); + return; + } + Debug( "internal host registration: %[*hhu, family %hx\n", + addr->length, addr->data, connectionType ); + if (connectionType == FamilyInternet) { + struct sockaddr_in in_addr; + in_addr.sin_family = AF_INET; + memmove( &in_addr.sin_addr, addr->data, 4 ); + in_addr.sin_port = htons( XDM_UDP_PORT ); +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + in_addr.sin_len = sizeof(in_addr); +#endif + registerHostaddr( (struct sockaddr *)&in_addr, sizeof(in_addr), +#ifdef IN_MULTICAST + IN_MULTICAST( in_addr.sin_addr.s_addr ) ? + BROADCAST_QUERY : +#endif + QUERY ); + } +#if defined(IPv6) && defined(AF_INET6) + else if (connectionType == FamilyInternet6) { + struct sockaddr_in6 in6_addr; + in6_addr.sin6_family = AF_INET6; + memmove( &in6_addr.sin6_addr, addr->data, 16 ); + in6_addr.sin6_port = htons( XDM_UDP_PORT ); +#ifdef SIN6_LEN + in6_addr.sin6_len = sizeof(in6_addr); +#endif + registerHostaddr( (struct sockaddr *)&in6_addr, sizeof(in6_addr), + IN6_IS_ADDR_MULTICAST( &in6_addr.sin6_addr ) ? + BROADCAST_QUERY : QUERY ); + } +#endif +} + +static ARRAYofARRAY8 AuthenticationNames; + +#if 0 +static void RegisterAuthenticationName( char *name, int namelen ) +{ + ARRAY8Ptr authName; + if (!XdmcpReallocARRAYofARRAY8( &AuthenticationNames, + AuthenticationNames.length + 1 )) + return; + authName = &AuthenticationNames.data[AuthenticationNames.length - 1]; + if (!XdmcpAllocARRAY8( authName, namelen )) + return; + memmove( authName->data, name, namelen ); +} +#endif + +static int +initXDMCP() +{ + XdmcpHeader header; +#if 0 + int i; +#endif +#ifndef STREAMSCONN +#ifdef SO_BROADCAST + int soopts; +#endif +#endif + + header.version = XDM_PROTOCOL_VERSION; + header.length = 1; +#if 0 + for (i = 0; i < (int)AuthenticationNames.length; i++) + header.length += 2 + AuthenticationNames.data[i].length; +#endif + + header.opcode = (CARD16)BROADCAST_QUERY; + XdmcpWriteHeader( &broadcastBuffer, &header ); + XdmcpWriteARRAYofARRAY8( &broadcastBuffer, &AuthenticationNames ); + + header.opcode = (CARD16)QUERY; + XdmcpWriteHeader( &directBuffer, &header ); + XdmcpWriteARRAYofARRAY8( &directBuffer, &AuthenticationNames ); + +#if defined(STREAMSCONN) + if ((socketFD = t_open( "/dev/udp", O_RDWR, 0 )) < 0) + return 0; + + if (t_bind( socketFD, NULL, NULL ) < 0) { + t_close( socketFD ); + return 0; + } + + /* + * This part of the code looks contrived. It will actually fit in nicely + * when the CLTS part of Xtrans is implemented. + */ + { + struct netconfig *nconf; + + if ((nconf = getnetconfigent( "udp" )) == NULL) { + t_unbind( socketFD ); + t_close( socketFD ); + return 0; + } + + if (netdir_options( nconf, ND_SET_BROADCAST, socketFD, NULL )) { + freenetconfigent( nconf ); + t_unbind( socketFD ); + t_close( socketFD ); + return 0; + } + + freenetconfigent( nconf ); + } +#else + if ((socketFD = socket( AF_INET, SOCK_DGRAM, 0 )) < 0) + return 0; +#if defined(IPv6) && defined(AF_INET6) + socket6FD = socket( AF_INET6, SOCK_DGRAM, 0 ); +#endif +# ifdef SO_BROADCAST + soopts = 1; + if (setsockopt( socketFD, SOL_SOCKET, SO_BROADCAST, (char *)&soopts, + sizeof(soopts) ) < 0) + perror( "setsockopt" ); +# endif +#endif + + return 1; +} + +static void ATTR_NORETURN +chooseHost( int hid ) +{ + HostName *h; +#if defined(IPv6) && defined(AF_INET6) + char addr[64]; +#endif + + for (h = hostNamedb; h; h = h->next) + if ((int)h == hid) { + /* XXX error handling */ + GSet( &mstrtalk ); + if ((td->displayType & d_location) == dLocal) { + GSendInt( D_RemoteHost ); +#if defined(IPv6) && defined(AF_INET6) + switch (h->connectionType) { + case FamilyInternet6: + inet_ntop( AF_INET6, h->hostaddr.data, addr, sizeof(addr) ); + break; + default: /* FamilyInternet */ + inet_ntop( AF_INET, h->hostaddr.data, addr, sizeof(addr) ); + break; + } + GSendStr( addr ); +#else + GSendStr( inet_ntoa( *(struct in_addr *)h->hostaddr.data ) ); +#endif + CloseGreeter( FALSE ); + SessionExit( EX_REMOTE ); + } else { + GSendInt( D_ChooseHost ); + GSendArr( td->clientAddr.length, (char *)td->clientAddr.data ); + GSendInt( td->connectionType ); + GSendArr( h->hostaddr.length, (char *)h->hostaddr.data ); + CloseGreeter( FALSE ); + goto bout; + } + break; + } +/* LogError( "Internal error: chose unexisting host\n" ); */ + bout: + SessionExit( EX_NORMAL ); +} + +static void +directChooseHost( const char *name ) +{ + HostAddr *hosts = 0; + + if (!makeSockAddrs( name, &hosts )) + return; + GSendInt( G_Ch_Exit ); + /* XXX error handling */ + GSet( &mstrtalk ); + if ((td->displayType & d_location) == dLocal) { + GSendInt( D_RemoteHost ); + GSendStr( name ); + CloseGreeter( FALSE ); + SessionExit( EX_REMOTE ); + } else { + GSendInt( D_ChooseHost ); + GSendArr( td->clientAddr.length, (char *)td->clientAddr.data ); + GSendInt( td->connectionType ); + GSendArr( hosts->addrlen, (char *)hosts->addr ); + CloseGreeter( FALSE ); + SessionExit( EX_NORMAL ); + } +} + +#define PING_TRIES 3 + +int +DoChoose() +{ + HostName **hp, *h; + char *host, **hostp; + struct timeval *to, tnow, nextPing; + int pingTry, n, cmd; + FD_TYPE rfds; + static int xdmcpInited; + + OpenGreeter(); + GSendInt( G_Choose ); + switch (cmd = CtrlGreeterWait( TRUE )) { + case G_Ready: + break; + default: /* error */ + return cmd; + } + + if (!xdmcpInited) { + if (!initXDMCP()) + SessionExit( EX_UNMANAGE_DPY ); + xdmcpInited = 1; + } + if ((td->displayType & d_location) == dLocal) { + /* XXX the config reader should do the lookup already */ + for (hostp = td->chooserHosts; *hostp; hostp++) + if (!registerForPing( *hostp )) + LogError( "Unkown host %\"s specified for local chooser preload of display %s\n", *hostp, td->name ); + } else + ForEachChooserHost( &td->clientAddr, td->connectionType, + AddChooserHost, 0 ); + + GSendInt( 0 ); /* entering async mode signal */ + + reping: + for (h = hostNamedb; h; h = h->next) + h->alive = 0; + pingTry = 0; + goto pingen; + + for (;;) { + to = 0; + if (pingTry <= PING_TRIES) { + gettimeofday( &tnow, 0 ); + if (nextPing.tv_sec < tnow.tv_sec || + (nextPing.tv_sec == tnow.tv_sec && + nextPing.tv_usec < tnow.tv_usec)) { + if (pingTry < PING_TRIES) { + pingen: + pingTry++; + doPingHosts(); + gettimeofday( &tnow, 0 ); + nextPing = tnow; + nextPing.tv_sec++; + } else { + for (hp = &hostNamedb; *hp; ) + if (!(*hp)->alive) { + h = (*hp)->next; + disposeHostname( *hp ); + GSendInt( G_Ch_RemoveHost ); + GSendInt( (int)*hp ); /* just an id */ + *hp = h; + } else + hp = &(*hp)->next; + goto noto; + } + } + to = &tnow; + tnow.tv_sec = nextPing.tv_sec - tnow.tv_sec; + tnow.tv_usec = nextPing.tv_usec - tnow.tv_usec; + if (tnow.tv_usec < 0) { + tnow.tv_usec += 1000000; + tnow.tv_sec--; + } + } + noto: + FD_ZERO( &rfds ); + FD_SET( grtproc.pipe.rfd, &rfds ); + FD_SET( socketFD, &rfds ); +#if defined(IPv6) && defined(AF_INET6) + if (socket6FD >= 0) + FD_SET( socket6FD, &rfds ); +#endif + n = grtproc.pipe.rfd; + if (socketFD > n) + n = socketFD; +#if defined(IPv6) && defined(AF_INET6) + if (socket6FD > n) + n = socket6FD; +#endif + if (select( n + 1, &rfds, 0, 0, to ) > 0) { + if (FD_ISSET( grtproc.pipe.rfd, &rfds )) + switch (cmd = CtrlGreeterWait( FALSE )) { + case -1: + break; + case G_Ch_Refresh: + goto reping; + case G_Ch_RegisterHost: + host = GRecvStr(); + if (!registerForPing( host )) { + GSendInt( G_Ch_BadHost ); + GSendStr( host ); + } + free( host ); + goto reping; + case G_Ch_DirectChoice: + host = GRecvStr(); + directChooseHost( host ); + GSendInt( G_Ch_BadHost ); + GSendStr( host ); + free( host ); + break; + case G_Ready: + chooseHost( GRecvInt() ); + /* NOTREACHED */ + default: + emptyHostnames(); + emptyPingHosts(); + return cmd; + } + if (FD_ISSET( socketFD, &rfds )) + receivePacket( socketFD ); +#if defined(IPv6) && defined(AF_INET6) + if (socket6FD >= 0 && FD_ISSET( socket6FD, &rfds )) + receivePacket( socket6FD ); +#endif + } + } + +} + +#endif /* XDMCP */ diff --git a/tdm/backend/client.c b/tdm/backend/client.c new file mode 100644 index 000000000..0cf4e216b --- /dev/null +++ b/tdm/backend/client.c @@ -0,0 +1,1865 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2000-2004 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * user verification and session initiation. + */ + +#include "dm.h" +#include "dm_auth.h" +#include "dm_error.h" + +#include +#include +#include +#ifdef SECURE_RPC +# include +# include +extern int key_setnet( struct key_netstarg *arg ); +#endif +#ifdef K5AUTH +# include +#endif +#ifdef HAVE_SETUSERCONTEXT +# include +#endif +#ifdef USE_PAM +# ifdef HAVE_PAM_PAM_APPL_H +# include +# else +# include +# endif +#elif defined(_AIX) /* USE_PAM */ +# include +# include +extern int loginrestrictions( const char *Name, const int Mode, const char *Tty, char **Msg ); +extern int loginfailed( const char *User, const char *Host, const char *Tty ); +extern int loginsuccess( const char *User, const char *Host, const char *Tty, char **Msg ); +#else /* USE_PAM || _AIX */ +# ifdef KERBEROS +# include +# include +# ifndef NO_AFS +# include +# endif +# endif +/* for nologin */ +# include +# include +/* for expiration */ +# include +#endif /* USE_PAM || _AIX */ +#ifdef HAVE_SHADOW +# include +#endif +#include + +#ifdef WITH_CONSOLE_KIT +#include "consolekit.h" +#endif + +#define AU_FAILED 0 +#define AU_SUCCESS 1 +#ifdef HAVE_LIBAUDIT +#include +#else +#define log_to_audit_system(l,h,d,s) do { ; } while (0) +#endif + +#ifdef WITH_CONSOLE_KIT +#include "consolekit.h" +#endif + +/* + * Session data, mostly what struct verify_info was for + */ +char *curuser; +char *curpass; +char *curtype; +char *newpass; +char **userEnviron; +char **systemEnviron; +static int curuid; +static int curgid; +int cursource; + +char *dmrcuser; +char *curdmrc; +char *newdmrc; + +static struct passwd *p; +#ifdef HAVE_SETUSERCONTEXT +# ifdef HAVE_LOGIN_GETCLASS +login_cap_t *lc; +# else +struct login_cap *lc; +# endif +#endif +#ifdef USE_PAM +static pam_handle_t *pamh; +#elif defined(_AIX) +static char tty[16], hostname[100]; +#else +# ifdef USESHADOW +static struct spwd *sp; +# endif +# ifdef KERBEROS +static char krbtkfile[MAXPATHLEN]; +# endif +#endif + +#define V_RET_AUTH \ + do { \ + PrepErrorGreet (); \ + GSendInt (V_AUTH); \ + return 0; \ + } while(0) + +#define V_RET_FAIL(m) \ + do { \ + PrepErrorGreet (); \ + GSendInt (V_MSG_ERR); \ + GSendStr (m); \ + GSendInt (V_FAIL); \ + return 0; \ + } while(0) + +#ifdef USE_PAM + +# ifdef PAM_MESSAGE_NONCONST +typedef struct pam_message pam_message_type; +typedef void *pam_gi_type; +# else +typedef const struct pam_message pam_message_type; +typedef const void *pam_gi_type; +# endif + +struct pam_data { + GConvFunc gconv; + int usecur; + int abort; +}; + +static int +PAM_conv( int num_msg, + pam_message_type **msg, + struct pam_response **resp, + void *appdata_ptr ) +{ + int count; + struct pam_response *reply; + struct pam_data *pd = (struct pam_data *)appdata_ptr; + + if (!(reply = Calloc( num_msg, sizeof(*reply) ))) + return PAM_CONV_ERR; + + ReInitErrorLog(); + Debug( "PAM_conv\n" ); + for (count = 0; count < num_msg; count++) + switch (msg[count]->msg_style) { + case PAM_TEXT_INFO: + Debug( " PAM_TEXT_INFO: %s\n", msg[count]->msg ); + PrepErrorGreet(); + GSendInt( V_MSG_INFO ); + GSendStr( msg[count]->msg ); + continue; + case PAM_ERROR_MSG: + Debug( " PAM_ERROR_MSG: %s\n", msg[count]->msg ); + PrepErrorGreet(); + GSendInt( V_MSG_ERR ); + GSendStr( msg[count]->msg ); + continue; + default: + /* could do better error handling here, but see below ... */ + if (pd->usecur) { + switch (msg[count]->msg_style) { + /* case PAM_PROMPT_ECHO_ON: cannot happen */ + case PAM_PROMPT_ECHO_OFF: + Debug( " PAM_PROMPT_ECHO_OFF (usecur): %s\n", msg[count]->msg ); + if (!curpass) + pd->gconv( GCONV_PASS, 0 ); + StrDup( &reply[count].resp, curpass ); + break; + default: + LogError( "Unknown PAM message style <%d>\n", msg[count]->msg_style ); + goto conv_err; + } + } else { + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_ON: + Debug( " PAM_PROMPT_ECHO_ON: %s\n", msg[count]->msg ); + reply[count].resp = pd->gconv( GCONV_NORMAL, msg[count]->msg ); + break; + case PAM_PROMPT_ECHO_OFF: + Debug( " PAM_PROMPT_ECHO_OFF: %s\n", msg[count]->msg ); + reply[count].resp = pd->gconv( GCONV_HIDDEN, msg[count]->msg ); + break; +#ifdef PAM_BINARY_PROMPT + case PAM_BINARY_PROMPT: + Debug( " PAM_BINARY_PROMPT\n" ); + reply[count].resp = pd->gconv( GCONV_BINARY, msg[count]->msg ); + break; +#endif + default: + LogError( "Unknown PAM message style <%d>\n", msg[count]->msg_style ); + goto conv_err; + } + } + if (!reply[count].resp) { + Debug( " PAM_conv aborted\n" ); + pd->abort = TRUE; + goto conv_err; + } + reply[count].resp_retcode = PAM_SUCCESS; /* unused in linux-pam */ + } + Debug( " PAM_conv success\n" ); + *resp = reply; + return PAM_SUCCESS; + + conv_err: + for (; count >= 0; count--) + if (reply[count].resp) + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_ON: + case PAM_PROMPT_ECHO_OFF: /* could wipe ... */ +#ifdef PAM_BINARY_PROMPT + case PAM_BINARY_PROMPT: /* ... that too ... */ +#endif + free( reply[count].resp ); + break; + } + free( reply ); + return PAM_CONV_ERR; +} + +static int +PAM_conv_null( int num_msg, + pam_message_type **msg, + struct pam_response **resp, + void *appdata_ptr ATTR_UNUSED ) +{ + int count; + struct pam_response *reply; + + if (!(reply = Calloc( num_msg, sizeof(*reply) ))) + return PAM_CONV_ERR; + + ReInitErrorLog(); + Debug( "PAM_conv_null\n" ); + for (count = 0; count < num_msg; count++) { + switch (msg[count]->msg_style) { + case PAM_TEXT_INFO: + Debug( " PAM_TEXT_INFO: %s\n", msg[count]->msg ); + continue; + case PAM_ERROR_MSG: + LogError( "PAM error message: %s\n", msg[count]->msg ); + continue; + default: + /* unknown */ + Debug( " PAM_<%d>\n", msg[count]->msg_style ); + free( reply ); + return PAM_CONV_ERR; + } + reply[count].resp_retcode = PAM_SUCCESS; /* unused in linux-pam */ + } + Debug( " PAM_conv_null success\n" ); + *resp = reply; + return PAM_SUCCESS; +} + +# ifdef PAM_FAIL_DELAY +static void +fail_delay( int retval ATTR_UNUSED, unsigned usec_delay ATTR_UNUSED, + void *appdata_ptr ATTR_UNUSED ) +{} +# endif + + /** + * log_to_audit_system: + * @login: Name of user + * @hostname: Name of host machine + * @tty: Name of display + * @success: 1 for success, 0 for failure + * + * Logs the success or failure of the login attempt with the linux kernel + * audit system. The intent is to capture failed events where the user + * fails authentication or otherwise is not permitted to login. There are + * many other places where pam could potentially fail and cause login to + * fail, but these are system failures rather than the signs of an account + * being hacked. + * + * Returns nothing. + */ + +#ifdef HAVE_LIBAUDIT +static void +log_to_audit_system (const char *loginname, + const char *hostname, + const char *tty, + int success) +{ + struct passwd *pw; + char buf[64]; + int audit_fd; + + audit_fd = audit_open(); + if (loginname) + pw = getpwnam(loginname); + else { + loginname = "unknown"; + pw = NULL; + } + Debug("log_to_audit %p %s\n", pw, loginname); + + if (pw) { + snprintf(buf, sizeof(buf), "uid=%d", pw->pw_uid); + audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, + buf, hostname, NULL, tty, (int)success); + } else { + snprintf(buf, sizeof(buf), "acct=%s", loginname); + audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, + buf, hostname, NULL, tty, (int)success); + } + close(audit_fd); +} +#endif + +static int +doPAMAuth( const char *psrv, struct pam_data *pdata ) +{ + pam_gi_type pitem; + struct pam_conv pconv; + int pretc; + + pdata->abort = FALSE; + pconv.conv = PAM_conv; + pconv.appdata_ptr = (void *)pdata; + Debug( " PAM service %s\n", psrv ); + if ((pretc = pam_start( psrv, curuser, &pconv, &pamh )) != PAM_SUCCESS) + goto pam_bail2; + if ((pretc = pam_set_item( pamh, PAM_TTY, td->name )) != PAM_SUCCESS) { + pam_bail: + pam_end( pamh, pretc ); + pamh = 0; + pam_bail2: + ReInitErrorLog(); + LogError( "PAM error: %s\n", pam_strerror( 0, pretc ) ); + V_RET_FAIL( 0 ); + } + if ((td->displayType & d_location) == dForeign) { + char *cp = strchr( td->name, ':' ); + *cp = 0; + pretc = pam_set_item( pamh, PAM_RHOST, td->name ); + *cp = ':'; + if (pretc != PAM_SUCCESS) + goto pam_bail; + } +# ifdef __sun__ /* Only Solaris <= 9, but checking it does not seem worth it. */ + else if (pam_set_item( pamh, PAM_RHOST, 0 ) != PAM_SUCCESS) + goto pam_bail; +# endif +# ifdef PAM_FAIL_DELAY + pam_set_item( pamh, PAM_FAIL_DELAY, (void *)fail_delay ); +# endif + ReInitErrorLog(); + + Debug( " pam_authenticate() ...\n" ); + pretc = pam_authenticate( pamh, + td->allowNullPasswd ? 0 : PAM_DISALLOW_NULL_AUTHTOK ); + ReInitErrorLog(); + Debug( " pam_authenticate() returned: %s\n", pam_strerror( pamh, pretc ) ); + if (pdata->abort) { + pam_end( pamh, PAM_SUCCESS ); + pamh = 0; + return 0; + } + if (!curuser) { + Debug( " asking PAM for user ...\n" ); + pam_get_item( pamh, PAM_USER, &pitem ); + ReInitErrorLog(); + StrDup( &curuser, (const char *)pitem ); + GSendInt( V_PUT_USER ); + GSendStr( curuser ); + } + if (pretc != PAM_SUCCESS) { + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); + switch (pretc) { + case PAM_USER_UNKNOWN: + case PAM_AUTH_ERR: + case PAM_MAXTRIES: /* should handle this better ... */ + case PAM_AUTHINFO_UNAVAIL: /* returned for unknown users ... bogus */ + pam_end( pamh, pretc ); + pamh = 0; + V_RET_AUTH; + default: + pam_end( pamh, pretc ); + pamh = 0; + V_RET_FAIL( 0 ); + } + } + return 1; +} + +#endif /* USE_PAM */ + +static int +#if defined(USE_PAM) || defined(_AIX) +AccNoPass( const char *un ) +{ + struct passwd *pw = 0; +# ifdef HAVE_SHADOW /* (sic!) - not USESHADOW */ + struct spwd *spw; +# endif +#else +AccNoPass( const char *un, struct passwd *pw ) +{ +#endif + struct group *gr; + char **fp; + int hg; + + if (!*un) + return 0; + + if (cursource != PWSRC_MANUAL) + return 1; + + for (hg = 0, fp = td->noPassUsers; *fp; fp++) + if (**fp == '@') + hg = 1; + else if (!strcmp( un, *fp )) + return 1; + else if (!strcmp( "*", *fp )) { +#if defined(USE_PAM) || defined(_AIX) + if (!(pw = getpwnam( un ))) + return 0; + if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*') + continue; +# ifdef HAVE_SHADOW /* (sic!) - not USESHADOW */ + if ((spw = getspnam( un )) && + (spw->sp_pwdp[0] == '!' || spw->sp_pwdp[0] == '*')) + continue; +# endif +#endif + if (pw->pw_uid) + return 1; + } + +#if defined(USE_PAM) || defined(_AIX) + if (hg && (pw || (pw = getpwnam( un )))) { +#else + if (hg) { +#endif + for (setgrent(); (gr = getgrent()); ) + for (fp = td->noPassUsers; *fp; fp++) + if (**fp == '@' && !strcmp( gr->gr_name, *fp + 1 )) { + if (pw->pw_gid == gr->gr_gid) { + endgrent(); + return 1; + } + for (; *gr->gr_mem; gr->gr_mem++) + if (!strcmp( un, *gr->gr_mem )) { + endgrent(); + return 1; + } + } + endgrent(); + } + + return 0; +} + +#if !defined(USE_PAM) && !defined(_AIX) && defined(HAVE_SETUSERCONTEXT) +# define LC_RET0 do { login_close(lc); return 0; } while(0) +#else +# define LC_RET0 return 0 +#endif + +int +Verify( GConvFunc gconv, int rootok ) +{ +#ifdef USE_PAM + const char *psrv; + struct pam_data pdata; + int pretc, pnopass; + char psrvb[64]; +#elif defined(_AIX) + char *msg, *curret; + int i, reenter; +#else + struct stat st; + const char *nolg; + char *buf; + int fd; +# ifdef HAVE_GETUSERSHELL + char *s; +# endif +# if defined(HAVE_STRUCT_PASSWD_PW_EXPIRE) || defined(USESHADOW) + int tim, expir, warntime, quietlog; +# endif +#endif + + Debug( "Verify ...\n" ); + +#ifdef USE_PAM + + pnopass = FALSE; + if (!strcmp( curtype, "classic" )) { + if (!gconv( GCONV_USER, 0 )) + return 0; + if (AccNoPass( curuser )) { + gconv( GCONV_PASS_ND, 0 ); + if (!*curpass) { + pnopass = TRUE; + sprintf( psrvb, "%.31s-np", PAMService ); + psrv = psrvb; + } else + psrv = PAMService; + } else + psrv = PAMService; + pdata.usecur = TRUE; + } else if (!strcmp( curtype, "pam" )) { + psrv = PAMService; + pdata.usecur = FALSE; + } else { + sprintf( psrvb, "%.31s-%.31s", PAMService, curtype ); + psrv = psrvb; + pdata.usecur = FALSE; + } + pdata.gconv = gconv; + if (!doPAMAuth( psrv, &pdata )) + return 0; + +#elif defined(_AIX) + + if ((td->displayType & d_location) == dForeign) { + char *tmpch; + strncpy( hostname, td->name, sizeof(hostname) - 1 ); + hostname[sizeof(hostname)-1] = '\0'; + if ((tmpch = strchr( hostname, ':' ))) + *tmpch = '\0'; + } else + hostname[0] = '\0'; + + /* tty names should only be 15 characters long */ +# if 0 + for (i = 0; i < 15 && td->name[i]; i++) { + if (td->name[i] == ':' || td->name[i] == '.') + tty[i] = '_'; + else + tty[i] = td->name[i]; + } + tty[i] = '\0'; +# else + memcpy( tty, "/dev/xdm/", 9 ); + for (i = 0; i < 6 && td->name[i]; i++) { + if (td->name[i] == ':' || td->name[i] == '.') + tty[9 + i] = '_'; + else + tty[9 + i] = td->name[i]; + } + tty[9 + i] = '\0'; +# endif + + if (!strcmp( curtype, "classic" )) { + if (!gconv( GCONV_USER, 0 )) + return 0; + if (AccNoPass( curuser )) { + gconv( GCONV_PASS_ND, 0 ); + if (!*curpass) { + Debug( "accepting despite empty password\n" ); + goto done; + } + } else + if (!gconv( GCONV_PASS, 0 )) + return 0; + enduserdb(); + msg = NULL; + if ((i = authenticate( curuser, curpass, &reenter, &msg ))) { + Debug( "authenticate() failed: %s\n", msg ); + if (msg) + free( msg ); + loginfailed( curuser, hostname, tty ); + if (i == ENOENT || i == ESAD) + V_RET_AUTH; + else + V_RET_FAIL( 0 ); + } + if (reenter) { + LogError( "authenticate() requests more data: %s\n", msg ); + free( msg ); + V_RET_FAIL( 0 ); + } + } else if (!strcmp( curtype, "generic" ) || !strcmp(curtype, "pam")) { + if (!gconv( GCONV_USER, 0 )) + return 0; + for (curret = 0;;) { + msg = NULL; + if ((i = authenticate( curuser, curret, &reenter, &msg ))) { + Debug( "authenticate() failed: %s\n", msg ); + if (msg) + free( msg ); + loginfailed( curuser, hostname, tty ); + if (i == ENOENT || i == ESAD) + V_RET_AUTH; + else + V_RET_FAIL( 0 ); + } + if (curret) + free( curret ); + if (!reenter) + break; + if (!(curret = gconv( GCONV_HIDDEN, msg ))) + return 0; + free( msg ); + } + } else { + LogError( "Unsupported authentication type %\"s requested\n", curtype ); + V_RET_FAIL( 0 ); + } + if (msg) { + PrepErrorGreet(); + GSendInt( V_MSG_INFO ); + GSendStr( msg ); + free( msg ); + } + + done: + +#else + + if (strcmp( curtype, "classic" )) { + LogError( "Unsupported authentication type %\"s requested\n", curtype ); + V_RET_FAIL( 0 ); + } + + if (!gconv( GCONV_USER, 0 )) + return 0; + + if (!(p = getpwnam( curuser ))) { + Debug( "getpwnam() failed.\n" ); + gconv( GCONV_PASS, 0 ); + V_RET_AUTH; + } + if (p->pw_passwd[0] == '!' || p->pw_passwd[0] == '*') { + Debug( "account is locked\n" ); + gconv( GCONV_PASS, 0 ); + V_RET_AUTH; + } + +# ifdef USESHADOW + if ((sp = getspnam( curuser ))) { + p->pw_passwd = sp->sp_pwdp; + if (p->pw_passwd[0] == '!' || p->pw_passwd[0] == '*') { + Debug( "account is locked\n" ); + gconv( GCONV_PASS, 0 ); + V_RET_AUTH; + } + } else + Debug( "getspnam() failed: %m. Are you root?\n" ); +# endif + + if (!*p->pw_passwd) { + if (!td->allowNullPasswd) { + Debug( "denying user with empty password\n" ); + gconv( GCONV_PASS, 0 ); + V_RET_AUTH; + } + goto nplogin; + } + + if (AccNoPass( curuser, p )) { + nplogin: + gconv( GCONV_PASS_ND, 0 ); + if (!*curpass) { + Debug( "accepting password-less login\n" ); + goto done; + } + } else + if (!gconv( GCONV_PASS, 0 )) + return 0; + +# ifdef KERBEROS + if (p->pw_uid) { + int ret; + char realm[REALM_SZ]; + + if (krb_get_lrealm( realm, 1 )) { + LogError( "Can't get KerberosIV realm.\n" ); + V_RET_FAIL( 0 ); + } + + sprintf( krbtkfile, "%s.%.*s", TKT_ROOT, MAXPATHLEN - strlen( TKT_ROOT ) - 2, td->name ); + krb_set_tkt_string( krbtkfile ); + unlink( krbtkfile ); + + ret = krb_verify_user( curuser, "", realm, curpass, 1, "rcmd" ); + if (ret == KSUCCESS) { + chown( krbtkfile, p->pw_uid, p->pw_gid ); + Debug( "KerberosIV verify succeeded\n" ); + goto done; + } else if (ret != KDC_PR_UNKNOWN && ret != SKDC_CANT) { + LogError( "KerberosIV verification failure %\"s for %s\n", + krb_get_err_text( ret ), curuser ); + krbtkfile[0] = '\0'; + V_RET_FAIL( 0 ); + } + Debug( "KerberosIV verify failed: %s\n", krb_get_err_text( ret ) ); + } + krbtkfile[0] = '\0'; +# endif /* KERBEROS */ + +# if defined(ultrix) || defined(__ultrix__) + if (authenticate_user( p, curpass, NULL ) < 0) +# elif defined(HAVE_CRYPT) + if (strcmp( crypt( curpass, p->pw_passwd ), p->pw_passwd )) +# else + if (strcmp( curpass, p->pw_passwd )) +# endif + { + Debug( "password verify failed\n" ); + V_RET_AUTH; + } + + done: + +#endif /* !defined(USE_PAM) && !defined(_AIX) */ + + Debug( "restrict %s ...\n", curuser ); + +#if defined(USE_PAM) || defined(_AIX) + if (!(p = getpwnam( curuser ))) { + LogError( "getpwnam(%s) failed.\n", curuser ); + V_RET_FAIL( 0 ); + } +#endif + if (!p->pw_uid) { + if (!rootok && !td->allowRootLogin) + V_RET_FAIL( "Root logins are not allowed" ); + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); + return 1; /* don't deny root to log in */ + } + +#ifdef USE_PAM + + Debug( " pam_acct_mgmt() ...\n" ); + pretc = pam_acct_mgmt( pamh, 0 ); + ReInitErrorLog(); + Debug( " pam_acct_mgmt() returned: %s\n", pam_strerror( pamh, pretc ) ); + if (pretc == PAM_NEW_AUTHTOK_REQD) { + pdata.usecur = FALSE; + pdata.gconv = conv_interact; + /* pam will have output a message already, so no PrepErrorGreet () */ + if (gconv != conv_interact || pnopass) { + pam_end( pamh, PAM_SUCCESS ); + pamh = 0; + GSendInt( V_CHTOK_AUTH ); + /* this cannot auth the wrong user, as only classic auths get here */ + while (!doPAMAuth( PAMService, &pdata )) + if (pdata.abort) + return 0; + GSendInt( V_PRE_OK ); + } else + GSendInt( V_CHTOK ); + for (;;) { + Debug( " pam_chauthtok() ...\n" ); + pretc = pam_chauthtok( pamh, PAM_CHANGE_EXPIRED_AUTHTOK ); + ReInitErrorLog(); + Debug( " pam_chauthtok() returned: %s\n", pam_strerror( pamh, pretc ) ); + if (pdata.abort) { + pam_end( pamh, PAM_SUCCESS ); + pamh = 0; + return 0; + } + if (pretc == PAM_SUCCESS) + break; + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); + /* effectively there is only PAM_AUTHTOK_ERR */ + GSendInt( V_FAIL ); + } + if (curpass) + free( curpass ); + curpass = newpass; + newpass = 0; + } else if (pretc != PAM_SUCCESS) { + pam_end( pamh, pretc ); + pamh = 0; + V_RET_AUTH; + } + +#elif defined(_AIX) /* USE_PAM */ + + msg = NULL; + if (loginrestrictions( curuser, + ((td->displayType & d_location) == dForeign) ? S_RLOGIN : S_LOGIN, + tty, &msg ) == -1) + { + Debug( "loginrestrictions() - %s\n", msg ? msg : "error" ); + loginfailed( curuser, hostname, tty ); + PrepErrorGreet(); + if (msg) { + GSendInt( V_MSG_ERR ); + GSendStr( msg ); + } + GSendInt( V_AUTH ); + return 0; + } + if (msg) + free( (void *)msg ); + +#endif /* USE_PAM || _AIX */ + +#ifndef _AIX + +# ifdef HAVE_SETUSERCONTEXT +# ifdef HAVE_LOGIN_GETCLASS + lc = login_getclass( p->pw_class ); +# else + lc = login_getpwclass( p ); +# endif + if (!lc) + V_RET_FAIL( 0 ); + + p->pw_shell = login_getcapstr( lc, "shell", p->pw_shell, p->pw_shell ); +# endif + +# ifndef USE_PAM + +/* restrict_expired */ +# if defined(HAVE_STRUCT_PASSWD_PW_EXPIRE) || defined(USESHADOW) + +# if !defined(HAVE_STRUCT_PASSWD_PW_EXPIRE) || (!defined(HAVE_SETUSERCONTEXT) && defined(USESHADOW)) + if (sp) +# endif + { + +# define DEFAULT_WARN (2L * 7L) /* Two weeks */ + + tim = time( NULL ) / 86400L; + +# ifdef HAVE_SETUSERCONTEXT + quietlog = login_getcapbool( lc, "hushlogin", 0 ); + warntime = login_getcaptime( lc, "warnexpire", + DEFAULT_WARN * 86400L, + DEFAULT_WARN * 86400L ) / 86400L; +# else + quietlog = 0; +# ifdef USESHADOW + warntime = sp->sp_warn != -1 ? sp->sp_warn : DEFAULT_WARN; +# else + warntime = DEFAULT_WARN; +# endif +# endif + +# ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE + if (p->pw_expire) { + expir = p->pw_expire / 86400L; +# else + if (sp->sp_expire != -1) { + expir = sp->sp_expire; +# endif + if (tim > expir) { + PrepErrorGreet(); + GSendInt( V_MSG_ERR ); + GSendStr( "Your account has expired;" + " please contact your system administrator" ); + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); + GSendInt( V_FAIL ); + LC_RET0; + } else if (tim > (expir - warntime) && !quietlog) { + ASPrintf( &buf, + "Warning: your account will expire in %d day(s)", + expir - tim ); + if (buf) { + PrepErrorGreet(); + GSendInt( V_MSG_INFO ); + GSendStr( buf ); + free( buf ); + } + } + } + +# ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE + if (p->pw_change) { + expir = p->pw_change / 86400L; +# else + if (!sp->sp_lstchg) { + PrepErrorGreet(); + GSendInt( V_MSG_ERR ); + GSendStr( "You are required to change your password immediately" + " (root enforced)" ); + /* XXX todo password change */ + GSendInt( V_FAIL ); + LC_RET0; + } else if (sp->sp_max != -1) { + expir = sp->sp_lstchg + sp->sp_max; + if (sp->sp_inact != -1 && tim > expir + sp->sp_inact) { + PrepErrorGreet(); + GSendInt( V_MSG_ERR ); + GSendStr( "Your account has expired;" + " please contact your system administrator" ); + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); + GSendInt( V_FAIL ); + LC_RET0; + } +# endif + if (tim > expir) { + PrepErrorGreet(); + GSendInt( V_MSG_ERR ); + GSendStr( "You are required to change your password immediately" + " (password aged)" ); + /* XXX todo password change */ + GSendInt( V_FAIL ); + LC_RET0; + } else if (tim > (expir - warntime) && !quietlog) { + ASPrintf( &buf, + "Warning: your password will expire in %d day(s)", + expir - tim ); + if (buf) { + PrepErrorGreet(); + GSendInt( V_MSG_INFO ); + GSendStr( buf ); + free( buf ); + } + } + } + + } + +# endif /* HAVE_STRUCT_PASSWD_PW_EXPIRE || USESHADOW */ + +/* restrict_nologin */ +# ifndef _PATH_NOLOGIN +# define _PATH_NOLOGIN "/etc/nologin" +# endif + + if (( +# ifdef HAVE_SETUSERCONTEXT + /* Do we ignore a nologin file? */ + !login_getcapbool( lc, "ignorenologin", 0 )) && + (!stat( (nolg = login_getcapstr( lc, "nologin", "", NULL )), &st ) || +# endif + !stat( (nolg = _PATH_NOLOGIN), &st ))) + { + PrepErrorGreet(); + GSendInt( V_MSG_ERR ); + if (st.st_size && (fd = open( nolg, O_RDONLY )) >= 0) { + if ((buf = Malloc( st.st_size + 1 ))) { + if (read( fd, buf, st.st_size ) == st.st_size) { + buf[st.st_size] = 0; + GSendStr( buf ); + free( buf ); + close( fd ); + GSendInt( V_FAIL ); + LC_RET0; + } + free( buf ); + } + close( fd ); + } + GSendStr( "Logins are not allowed at the moment.\nTry again later" ); + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); + GSendInt( V_FAIL ); + LC_RET0; + } + +/* restrict_time */ +# if defined(HAVE_SETUSERCONTEXT) && defined(HAVE_AUTH_TIMEOK) + if (!auth_timeok( lc, time( NULL ) )) { + PrepErrorGreet(); + GSendInt( V_MSG_ERR ); + GSendStr( "You are not allowed to login at the moment" ); + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); + GSendInt( V_FAIL ); + LC_RET0; + } +# endif + +# ifdef HAVE_GETUSERSHELL + for (;;) { + if (!(s = getusershell())) { + Debug( "shell not in /etc/shells\n" ); + endusershell(); + V_RET_FAIL( "Your login shell is not listed in /etc/shells" ); + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); + } + if (!strcmp( s, p->pw_shell )) { + endusershell(); + break; + } + } +# endif + +# endif /* !USE_PAM */ + +/* restrict_nohome */ +# ifdef HAVE_SETUSERCONTEXT + if (login_getcapbool( lc, "requirehome", 0 )) { + struct stat st; + if (!*p->pw_dir || stat( p->pw_dir, &st ) || st.st_uid != p->pw_uid) { + PrepErrorGreet(); + GSendInt( V_MSG_ERR ); + GSendStr( "Home folder not available" ); + GSendInt( V_FAIL ); + LC_RET0; + } + } +# endif + +#endif /* !_AIX */ + + return 1; + +} + + +static const char *envvars[] = { + "TZ", /* SYSV and SVR4, but never hurts */ +#ifdef _AIX + "AUTHSTATE", /* for kerberos */ +#endif + NULL +}; + + +#if defined(USE_PAM) && defined(HAVE_INITGROUPS) +static int num_saved_gids; +static gid_t *saved_gids; + +static int +saveGids( void ) +{ + num_saved_gids = getgroups( 0, 0 ); + if (!(saved_gids = Malloc( sizeof(gid_t) * num_saved_gids ))) + return 0; + if (getgroups( num_saved_gids, saved_gids ) < 0) { + LogError( "saving groups failed: %m\n" ); + return 0; + } + return 1; +} + +static int +restoreGids( void ) +{ + if (setgroups( num_saved_gids, saved_gids ) < 0) { + LogError( "restoring groups failed: %m\n" ); + return 0; + } + if (setgid( p->pw_gid ) < 0) { + LogError( "restoring gid failed: %m\n" ); + return 0; + } + return 1; +} +#endif /* USE_PAM && HAVE_INITGROUPS */ + +static int +resetGids( void ) +{ +#ifdef HAVE_INITGROUPS + if (setgroups( 0, &p->pw_gid /* anything */ ) < 0) { + LogError( "restoring groups failed: %m\n" ); + return 0; + } +#endif + if (setgid( 0 ) < 0) { + LogError( "restoring gid failed: %m\n" ); + return 0; + } + return 1; +} + +static int +SetGid( const char *name, int gid ) +{ + if (setgid( gid ) < 0) { + LogError( "setgid(%d) (user %s) failed: %m\n", gid, name ); + return 0; + } +#ifdef HAVE_INITGROUPS + if (initgroups( name, gid ) < 0) { + LogError( "initgroups for %s failed: %m\n", name ); + setgid( 0 ); + return 0; + } +#endif /* QNX4 doesn't support multi-groups, no initgroups() */ + return 1; +} + +static int +SetUid( const char *name, int uid ) +{ + if (setuid( uid ) < 0) { + LogError( "setuid(%d) (user %s) failed: %m\n", uid, name ); + return 0; + } + return 1; +} + +static int +SetUser( const char *name, int uid, int gid ) +{ + if (SetGid( name, gid )) { + if (SetUid( name, uid )) + return 1; + resetGids(); + } + return 0; +} + +#if defined(SECURE_RPC) || defined(K5AUTH) +static void +NukeAuth( int len, const char *name ) +{ + int i; + + for (i = 0; i < td->authNum; i++) + if (td->authorizations[i]->name_length == len && + !memcmp( td->authorizations[i]->name, name, len )) + { + memcpy( &td->authorizations[i], &td->authorizations[i+1], + sizeof(td->authorizations[i]) * (--td->authNum - i) ); + break; + } +} +#endif + +static void +mergeSessionArgs( int cansave ) +{ + char *mfname; + const char *fname; + int i, needsave; + + mfname = 0; + fname = ".dmrc"; + if ((!curdmrc || newdmrc) && *dmrcDir) + if (StrApp( &mfname, dmrcDir, "/", curuser, fname, (char *)0 )) + fname = mfname; + needsave = 0; + if (!curdmrc) { + curdmrc = iniLoad( fname ); + if (!curdmrc) { + StrDup( &curdmrc, "[Desktop]\nSession=default\n" ); + needsave = 1; + } + } + if (newdmrc) { + curdmrc = iniMerge( curdmrc, newdmrc ); + needsave = 1; + } + if (needsave && cansave) + if (!iniSave( curdmrc, fname ) && errno == ENOENT && mfname) { + for (i = 0; mfname[i]; i++) + if (mfname[i] == '/') { + mfname[i] = 0; + mkdir( mfname, 0755 ); + mfname[i] = '/'; + } + iniSave( curdmrc, mfname ); + } + if (mfname) + free( mfname ); +} + +static int removeAuth; +#ifdef USE_PAM +static int removeSession; +static int removeCreds; +#endif + +#ifdef WITH_CONSOLE_KIT +int +StartClient( const char *ck_session_cookie ) +#else +int +StartClient() +#endif +{ + const char *home, *sessargs, *desksess; + char **env, *xma; + char **argv, *fname, *str; +#ifdef USE_PAM + char **pam_env; +# ifdef _AIX + char **saved_env; +# endif + struct pam_conv pconv; + int pretc; +#else +# ifdef _AIX + char *msg; + char **theenv; + extern char **newenv; /* from libs.a, this is set up by setpenv */ +# endif +#endif +#ifdef HAVE_SETUSERCONTEXT + extern char **environ; +#endif + char *failsafeArgv[2], *lname; + int i, pid, lfd; + + if (StrCmp( dmrcuser, curuser )) { + if (curdmrc) { free( curdmrc ); curdmrc = 0; } + if (dmrcuser) { free( dmrcuser ); dmrcuser = 0; } + } + +#if defined(USE_PAM) || defined(_AIX) + if (!(p = getpwnam( curuser ))) { + LogError( "getpwnam(%s) failed.\n", curuser ); + return 0; + } +#endif + +#ifndef USE_PAM +# ifdef _AIX + msg = NULL; + loginsuccess( curuser, hostname, tty, &msg ); + if (msg) { + Debug( "loginsuccess() - %s\n", msg ); + free( (void *)msg ); + } +# else /* _AIX */ +# if defined(KERBEROS) && !defined(NO_AFS) + if (krbtkfile[0] != '\0') { + if (k_hasafs()) { + if (k_setpag() == -1) + LogError( "setpag() for %s failed\n", curuser ); + if ((ret = k_afsklog( NULL, NULL )) != KSUCCESS) + LogError( "AFS Warning: %s\n", krb_get_err_text( ret ) ); + } + } +# endif /* KERBEROS && AFS */ +# endif /* _AIX */ +#endif /* !PAM */ + + curuid = p->pw_uid; + curgid = p->pw_gid; + + env = baseEnv( curuser ); + xma = 0; + if (td->ctrl.fpath && StrDup( &xma, td->ctrl.fpath )) { + if ((td->allowShutdown == SHUT_ALL || + (td->allowShutdown == SHUT_ROOT && !curuser)) && + StrApp( &xma, ",maysd", (char *)0 )) + { + if (td->allowNuke == SHUT_ALL || + (td->allowNuke == SHUT_ROOT && !curuser)) + StrApp( &xma, ",mayfn", (char *)0 ); + StrApp( &xma, td->defSdMode == SHUT_FORCENOW ? ",fn" : + td->defSdMode == SHUT_TRYNOW ? ",tn" : ",sched", + (char *)0 ); + } + if ((td->displayType & d_location) == dLocal && AnyReserveDisplays()) + StrApp( &xma, ",rsvd", (char *)0 ); + } else + StrDup( &xma, "true" ); + StrApp( &xma, ",method=", curtype, (char *)0 ); + if (td_setup) + StrApp( &xma, ",auto", (char *)0 ); + if (xma) { + env = setEnv( env, "XDM_MANAGED", xma ); + free( xma ); + } + if (td->autoLock && cursource == PWSRC_AUTOLOGIN) + env = setEnv( env, "DESKTOP_LOCKED", "true" ); + env = setEnv( env, "PATH", curuid ? td->userPath : td->systemPath ); + env = setEnv( env, "SHELL", p->pw_shell ); + env = setEnv( env, "HOME", p->pw_dir ); + if (cursource == PWSRC_AUTOLOGIN) + env = setEnv (env, "TDM_AUTOLOGIN", curuser); +#if !defined(USE_PAM) && !defined(_AIX) && defined(KERBEROS) + if (krbtkfile[0] != '\0') + env = setEnv( env, "KRBTKFILE", krbtkfile ); +#endif +#ifdef WITH_CONSOLE_KIT + if (ck_session_cookie != NULL) { + env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie ); + } +#endif +#ifdef WITH_CONSOLE_KIT + if (ck_session_cookie != NULL) { + env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie ); + } +#endif + userEnviron = inheritEnv( env, envvars ); + env = systemEnv( p->pw_name ); + systemEnviron = setEnv( env, "HOME", p->pw_dir ); + Debug( "user environment:\n%[|''>'\n's" + "system environment:\n%[|''>'\n's" + "end of environments\n", + userEnviron, + systemEnviron ); + + /* + * for user-based authorization schemes, + * add the user to the server's allowed "hosts" list. + */ + for (i = 0; i < td->authNum; i++) { +#ifdef SECURE_RPC + if (td->authorizations[i]->name_length == 9 && + !memcmp( td->authorizations[i]->name, "SUN-DES-1", 9 )) + { + XHostAddress addr; + char netname[MAXNETNAMELEN+1]; + char domainname[MAXNETNAMELEN+1]; + + getdomainname( domainname, sizeof(domainname) ); + user2netname( netname, curuid, domainname ); + addr.family = FamilyNetname; + addr.length = strlen( netname ); + addr.address = netname; + XAddHost( dpy, &addr ); + } +#endif +#ifdef K5AUTH + if (td->authorizations[i]->name_length == 14 && + !memcmp( td->authorizations[i]->name, "MIT-KERBEROS-5", 14 )) + { + /* Update server's auth file with user-specific info. + * Don't need to AddHost because X server will do that + * automatically when it reads the cache we are about + * to point it at. + */ + XauDisposeAuth( td->authorizations[i] ); + td->authorizations[i] = + Krb5GetAuthFor( 14, "MIT-KERBEROS-5", td->name ); + SaveServerAuthorizations( td, td->authorizations, td->authNum ); + } +#endif + } + + if (*dmrcDir) + mergeSessionArgs( TRUE ); + + Debug( "now starting the session\n" ); + +#ifdef USE_PAM + /* the greeter is gone by now ... */ + pconv.conv = PAM_conv_null; + pconv.appdata_ptr = 0; + if ((pretc = pam_set_item( pamh, PAM_CONV, &pconv )) != PAM_SUCCESS) { + ReInitErrorLog(); + LogError( "pam_set_item() for %s failed: %s\n", + curuser, pam_strerror( pamh, pretc ) ); + return 0; + } + ReInitErrorLog(); +#endif + +#ifdef USE_PAM + +# ifdef HAVE_SETUSERCONTEXT + if (setusercontext( lc, p, p->pw_uid, LOGIN_SETGROUP )) { + LogError( "setusercontext(groups) for %s failed: %m\n", + curuser ); + return 0; + } +# else + if (!SetGid( curuser, curgid )) + return 0; +# endif + +# ifdef _AIX + if (!(pam_env = initStrArr( 0 ))) { + resetGids(); + return 0; + } + saved_env = environ; + environ = pam_env; +# endif + removeCreds = 1; /* set it first - i don't trust PAM's rollback */ + pretc = pam_setcred( pamh, 0 ); + ReInitErrorLog(); +# ifdef _AIX + pam_env = environ; + environ = saved_env; +# endif +# ifdef HAVE_INITGROUPS + /* This seems to be a strange place for it, but do it: + - after the initial groups are set + - after pam_setcred might have set something, even in the error case + - before pam_setcred(DELETE_CRED) might need it + */ + if (!saveGids()) + return 0; +# endif + if (pretc != PAM_SUCCESS) { + LogError( "pam_setcred() for %s failed: %s\n", + curuser, pam_strerror( pamh, pretc ) ); + resetGids(); + return 0; + } + + removeSession = 1; /* set it first - same as above */ + pretc = pam_open_session( pamh, 0 ); + ReInitErrorLog(); + if (pretc != PAM_SUCCESS) { + LogError( "pam_open_session() for %s failed: %s\n", + curuser, pam_strerror( pamh, pretc ) ); + resetGids(); + return 0; + } + + /* we don't want sessreg and the startup/reset scripts run with user + credentials. unfortunately, we can reset only the gids. */ + resetGids(); + +# define D_LOGIN_SETGROUP LOGIN_SETGROUP +#else /* USE_PAM */ +# define D_LOGIN_SETGROUP 0 +#endif /* USE_PAM */ + + /* Login succeeded */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_SUCCESS); + + removeAuth = 1; + chownCtrl( &td->ctrl, curuid ); + endpwent(); +#if !defined(USE_PAM) && defined(USESHADOW) && !defined(_AIX) + endspent(); +#endif + ClearCloseOnFork( mstrtalk.pipe->wfd ); + switch (pid = Fork()) { + case 0: + + sessreg( td, getpid(), curuser, curuid ); + + if (source( systemEnviron, td->startup, td_setup )) { + LogError( "Cannot execute startup script %\"s\n", td->startup ); + exit( 1 ); + } + + if (Setjmp( mstrtalk.errjmp )) + exit( 1 ); + GSet( &mstrtalk ); + + setsid(); + Signal( SIGINT, SIG_DFL ); + + /* Memory leaks are ok here as we exec() soon. */ + +#if defined(USE_PAM) || !defined(_AIX) + +# ifdef USE_PAM + /* pass in environment variables set by libpam and modules it called */ +# ifndef _AIX + pam_env = pam_getenvlist( pamh ); + ReInitErrorLog(); +# endif + if (pam_env) + for (; *pam_env; pam_env++) + userEnviron = putEnv( *pam_env, userEnviron ); +# endif + +# ifdef HAVE_SETLOGIN + if (setlogin( curuser ) < 0) { + LogError( "setlogin for %s failed: %m\n", curuser ); + exit( 1 ); + } +# define D_LOGIN_SETLOGIN LOGIN_SETLOGIN +# else +# define D_LOGIN_SETLOGIN 0 +# endif + +# if defined(USE_PAM) && defined(HAVE_INITGROUPS) + if (!restoreGids()) + exit( 1 ); +# endif + +# ifndef HAVE_SETUSERCONTEXT + +# ifdef USE_PAM + if (!SetUid( curuser, curuid )) + exit( 1 ); +# else + if (!SetUser( curuser, curuid, curgid )) + exit( 1 ); +# endif + +# else /* !HAVE_SETUSERCONTEXT */ + + /* + * Destroy environment. + * We need to do this before setusercontext() because that may + * set or reset some environment variables. + */ + if (!(environ = initStrArr( 0 ))) + exit( 1 ); + + /* + * Set the user's credentials: uid, gid, groups, + * environment variables, resource limits, and umask. + */ + if (setusercontext( lc, p, p->pw_uid, + LOGIN_SETALL & ~(D_LOGIN_SETGROUP|D_LOGIN_SETLOGIN) ) < 0) + { + LogError( "setusercontext for %s failed: %m\n", curuser ); + exit( 1 ); + } + + for (i = 0; environ[i]; i++) + userEnviron = putEnv( environ[i], userEnviron ); + +# endif /* !HAVE_SETUSERCONTEXT */ + +#else /* PAM || !_AIX */ + /* + * Set the user's credentials: uid, gid, groups, + * audit classes, user limits, and umask. + */ + if (setpcred( curuser, NULL ) == -1) { + LogError( "setpcred for %s failed: %m\n", curuser ); + exit( 1 ); + } + + /* + * Set the users process environment. Store protected variables and + * obtain updated user environment list. This call will initialize + * global 'newenv'. + */ + if (setpenv( curuser, PENV_INIT | PENV_ARGV | PENV_NOEXEC, + userEnviron, NULL ) != 0) + { + LogError( "Can't set %s's process environment\n", curuser ); + exit( 1 ); + } + userEnviron = newenv; + +#endif /* _AIX */ + + /* + * for user-based authorization schemes, + * use the password to get the user's credentials. + */ +#ifdef SECURE_RPC + /* do like "keylogin" program */ + if (!curpass[0]) + LogInfo( "No password for NIS provided.\n" ); + else { + char netname[MAXNETNAMELEN+1], secretkey[HEXKEYBYTES+1]; + int nameret, keyret; + int len; + int key_set_ok = 0; + struct key_netstarg netst; + + nameret = getnetname( netname ); + Debug( "user netname: %s\n", netname ); + len = strlen( curpass ); + if (len > 8) + bzero( curpass + 8, len - 8 ); + keyret = getsecretkey( netname, secretkey, curpass ); + Debug( "getsecretkey returns %d, key length %d\n", + keyret, strlen( secretkey ) ); + netst.st_netname = netname; + memcpy( netst.st_priv_key, secretkey, HEXKEYBYTES ); + memset( netst.st_pub_key, 0, HEXKEYBYTES ); + if (key_setnet( &netst ) < 0) + Debug( "Could not set secret key.\n" ); + /* is there a key, and do we have the right password? */ + if (keyret == 1) { + if (*secretkey) { + keyret = key_setsecret( secretkey ); + Debug( "key_setsecret returns %d\n", keyret ); + if (keyret == -1) + LogError( "Failed to set NIS secret key\n" ); + else + key_set_ok = 1; + } else { + /* found a key, but couldn't interpret it */ + LogError( "Password incorrect for NIS principal %s\n", + nameret ? netname : curuser ); + } + } + if (!key_set_ok) + NukeAuth( 9, "SUN-DES-1" ); + bzero( secretkey, strlen( secretkey ) ); + } +#endif +#ifdef K5AUTH + /* do like "kinit" program */ + if (!curpass[0]) + LogInfo( "No password for Kerberos5 provided.\n" ); + else + if ((str = Krb5Init( curuser, curpass, td->name ))) + userEnviron = setEnv( userEnviron, "KRB5CCNAME", str ); + else + NukeAuth( 14, "MIT-KERBEROS-5" ); +#endif /* K5AUTH */ + if (td->autoReLogin) { + GSendInt( D_ReLogin ); + GSendStr( curuser ); + GSendStr( curpass ); + GSendStr( newdmrc ); + } + if (curpass) + bzero( curpass, strlen( curpass ) ); + SetUserAuthorization( td ); + home = getEnv( userEnviron, "HOME" ); + if (home) { + if (chdir( home ) < 0) { + LogError( "Cannot chdir to %s's home %s: %m, using /\n", + curuser, home ); + home = 0; + userEnviron = setEnv( userEnviron, "HOME", "/" ); + goto cdroot; + } + ASPrintf( &lname, td->clientLogFile, td->name ); + if ((lfd = creat( lname, 0600 )) < 0) { + LogWarn( "Cannot create session log file %s: %m\n", lname ); + free( lname ); + goto tmperr; + } + } else { + cdroot: + chdir( "/" ); + tmperr: + ASPrintf( &lname, "/tmp/xerr-%s-%s", curuser, td->name ); + unlink( lname ); + if ((lfd = open( lname, O_WRONLY|O_CREAT|O_EXCL, 0600 )) < 0) { + LogError( "Cannot create fallback session log file %s: %m\n", + lname ); + goto logerr; + } + } + dup2( lfd, 1 ); + dup2( lfd, 2 ); + close( lfd ); + logerr: + free( lname ); + if (!*dmrcDir) + mergeSessionArgs( home != 0 ); + if (!(desksess = iniEntry( curdmrc, "Desktop", "Session", 0 ))) + desksess = "failsafe"; /* only due to OOM */ + GSendInt( D_User ); + GSendInt( curuid ); + GSendStr( curuser ); + GSendStr( desksess ); + close( mstrtalk.pipe->wfd ); + userEnviron = setEnv( userEnviron, "DESKTOP_SESSION", desksess ); + for (i = 0; td->sessionsDirs[i]; i++) { + fname = 0; + if (StrApp( &fname, td->sessionsDirs[i], "/", desksess, ".desktop", (char *)0 )) { + if ((str = iniLoad( fname ))) { + if (!StrCmp( iniEntry( str, "Desktop Entry", "Hidden", 0 ), "true" ) || + !(sessargs = iniEntry( str, "Desktop Entry", "Exec", 0 ))) + sessargs = ""; + free( str ); + free( fname ); + goto gotit; + } + free( fname ); + } + } + if (!strcmp( desksess, "failsafe" ) || + !strcmp( desksess, "default" ) || + !strcmp( desksess, "custom" )) + sessargs = desksess; + else + sessargs = ""; + gotit: + if (!(argv = parseArgs( (char **)0, td->session )) || + !(argv = addStrArr( argv, sessargs, -1 ))) + exit( 1 ); + if (argv[0] && *argv[0]) { + Debug( "executing session %\"[s\n", argv ); + execute( argv, userEnviron ); + LogError( "Session %\"s execution failed: %m\n", argv[0] ); + } else + LogError( "Session has no command/arguments\n" ); + failsafeArgv[0] = td->failsafeClient; + failsafeArgv[1] = 0; + execute( failsafeArgv, userEnviron ); + LogError( "Failsafe client %\"s execution failed: %m\n", + failsafeArgv[0] ); + exit( 1 ); + case -1: + RegisterCloseOnFork( mstrtalk.pipe->wfd ); + LogError( "Forking session on %s failed: %m\n", td->name ); + return 0; + default: + RegisterCloseOnFork( mstrtalk.pipe->wfd ); + Debug( "StartSession, fork succeeded %d\n", pid ); + return pid; + } +} + +void +SessionExit( int status ) +{ + int pid; +#ifdef USE_PAM + int pretc; +#endif + + Signal( SIGTERM, SIG_IGN ); + + if (removeAuth) { + if (source( systemEnviron, td->reset, td_setup )) + LogError( "Cannot execute reset script %\"s\n", td->reset ); + sessreg( td, 0, 0, 0 ); + + switch ((pid = Fork())) { + case 0: +#if defined(USE_PAM) && defined(HAVE_INITGROUPS) + if (restoreGids() && SetUid( curuser, curuid )) +#else + if (SetUser( curuser, curuid, curgid )) +#endif + + { + RemoveUserAuthorization( td ); +#ifdef K5AUTH + Krb5Destroy( td->name ); +#endif /* K5AUTH */ +#if !defined(USE_PAM) && !defined(_AIX) +# ifdef KERBEROS + if (krbtkfile[0]) { + (void)dest_tkt(); +# ifndef NO_AFS + if (k_hasafs()) + (void)k_unlog(); +# endif + } +# endif +#endif /* !USE_PAM && !_AIX*/ + } + exit( 0 ); + case -1: + LogError( "Cannot clean up session: fork() failed: %m" ); + break; + default: + Wait4( pid ); + break; + } + } + +#ifdef USE_PAM + if (removeCreds) { +# ifdef HAVE_INITGROUPS + restoreGids(); +# endif + if (removeSession) + if ((pretc = pam_close_session( pamh, 0 )) != PAM_SUCCESS) + LogError( "pam_close_session() failed: %s\n", + pam_strerror( pamh, pretc ) ); + if ((pretc = pam_setcred( pamh, PAM_DELETE_CRED )) != PAM_SUCCESS) + LogError( "pam_setcred(DELETE_CRED) failed: %s\n", + pam_strerror( pamh, pretc ) ); + resetGids(); + } + if (pamh) { + pam_end( pamh, PAM_SUCCESS ); + ReInitErrorLog(); + } +#endif + + /* make sure the server gets reset after the session is over */ + if (td->serverPid >= 2) { + if (!td->terminateServer && td->resetSignal) + TerminateProcess( td->serverPid, td->resetSignal ); + } else + ResetServer( td ); + Debug( "display %s exiting with status %d\n", td->name, status ); + exit( status ); +} + +int +ReadDmrc() +{ + char *data, *fname = 0; + int len, pid, pfd[2], err; + + if (!dmrcuser || !dmrcuser[0] || !(p = getpwnam( dmrcuser ))) + return GE_NoUser; + + if (*dmrcDir) { + if (!StrApp( &fname, dmrcDir, "/", dmrcuser, ".dmrc", (char *)0 )) + return GE_Error; + if (!(curdmrc = iniLoad( fname ))) { + free( fname ); + return GE_Ok; + } + free( fname ); + return GE_NoFile; + } + + if (!StrApp( &fname, p->pw_dir, "/.dmrc", (char *)0 )) + return GE_Error; + if (pipe( pfd )) + return GE_Error; + if ((pid = Fork()) < 0) { + close( pfd[0] ); + close( pfd[1] ); + return GE_Error; + } + if (!pid) { + if (!SetUser( p->pw_name, p->pw_uid, p->pw_gid )) + exit( 0 ); + if (!(data = iniLoad( fname ))) { + static const int m1 = -1; + write( pfd[1], &m1, sizeof(int) ); + exit( 0 ); + } + len = strlen( data ); + write( pfd[1], &len, sizeof(int) ); + write( pfd[1], data, len + 1 ); + exit( 0 ); + } + close( pfd[1] ); + free( fname ); + err = GE_Error; + if (Reader( pfd[0], &len, sizeof(int) ) == sizeof(int)) { + if (len == -1) + err = GE_Denied; + else if ((curdmrc = Malloc( len + 1 ))) { + if (Reader( pfd[0], curdmrc, len + 1 ) == len + 1) + err = GE_Ok; + else { + free( curdmrc ); + curdmrc = 0; + } + } + } + close( pfd[0] ); + (void)Wait4( pid ); + return err; +} diff --git a/tdm/backend/consolekit.c b/tdm/backend/consolekit.c new file mode 100644 index 000000000..61d0b165e --- /dev/null +++ b/tdm/backend/consolekit.c @@ -0,0 +1,557 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + + Copyright (C) 2006-2007 William Jon McCann + Copyright (C) 2007 Kevin Kofler + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include "dm.h" +#include "dm_auth.h" +#include "dm_error.h" + +#include +#include +#include + +#define DBUS_API_SUBJECT_TO_CHANGE +#include + +#include "consolekit.h" + + +#define CK_NAME "org.freedesktop.ConsoleKit" +#define CK_PATH "/org/freedesktop/ConsoleKit" +#define CK_INTERFACE "org.freedesktop.ConsoleKit" +#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" +#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" +#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" + +static DBusConnection *private_connection = NULL; + +static void +add_param_int (DBusMessageIter *iter_struct, + const char *key, + int value) +{ + DBusMessageIter iter_struct_entry; + DBusMessageIter iter_var; + + dbus_message_iter_open_container (iter_struct, + DBUS_TYPE_STRUCT, + NULL, + &iter_struct_entry); + + dbus_message_iter_append_basic (&iter_struct_entry, + DBUS_TYPE_STRING, + &key); + + dbus_message_iter_open_container (&iter_struct_entry, + DBUS_TYPE_VARIANT, + DBUS_TYPE_INT32_AS_STRING, + &iter_var); + + dbus_message_iter_append_basic (&iter_var, + DBUS_TYPE_INT32, + &value); + + dbus_message_iter_close_container (&iter_struct_entry, + &iter_var); + + dbus_message_iter_close_container (iter_struct, &iter_struct_entry); +} + +static void +add_param_boolean (DBusMessageIter *iter_struct, + const char *key, + int value) +{ + DBusMessageIter iter_struct_entry; + DBusMessageIter iter_var; + + dbus_message_iter_open_container (iter_struct, + DBUS_TYPE_STRUCT, + NULL, + &iter_struct_entry); + + dbus_message_iter_append_basic (&iter_struct_entry, + DBUS_TYPE_STRING, + &key); + + dbus_message_iter_open_container (&iter_struct_entry, + DBUS_TYPE_VARIANT, + DBUS_TYPE_BOOLEAN_AS_STRING, + &iter_var); + + dbus_message_iter_append_basic (&iter_var, + DBUS_TYPE_BOOLEAN, + &value); + + dbus_message_iter_close_container (&iter_struct_entry, + &iter_var); + + dbus_message_iter_close_container (iter_struct, &iter_struct_entry); +} + +static void +add_param_string (DBusMessageIter *iter_struct, + const char *key, + const char *value) +{ + DBusMessageIter iter_struct_entry; + DBusMessageIter iter_var; + + dbus_message_iter_open_container (iter_struct, + DBUS_TYPE_STRUCT, + NULL, + &iter_struct_entry); + + dbus_message_iter_append_basic (&iter_struct_entry, + DBUS_TYPE_STRING, + &key); + + dbus_message_iter_open_container (&iter_struct_entry, + DBUS_TYPE_VARIANT, + DBUS_TYPE_STRING_AS_STRING, + &iter_var); + + dbus_message_iter_append_basic (&iter_var, + DBUS_TYPE_STRING, + &value); + + dbus_message_iter_close_container (&iter_struct_entry, + &iter_var); + + dbus_message_iter_close_container (iter_struct, &iter_struct_entry); +} + +static int +session_get_x11_display (DBusConnection *connection, + const char *ssid, + char **str) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + const char *value; + + if (str != NULL) { + *str = NULL; + } + + message = dbus_message_new_method_call (CK_NAME, + ssid, + CK_SESSION_INTERFACE, + "GetX11Display"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + return FALSE; + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, + message, + -1, &error); + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + reply = NULL; + } + + dbus_connection_flush (connection); + dbus_message_unref (message); + + if (reply == NULL) { + return FALSE; + } + + dbus_message_iter_init (reply, &iter); + dbus_message_iter_get_basic (&iter, &value); + if (str != NULL) { + *str = strdup (value); + } + dbus_message_unref (reply); + + return TRUE; +} + +static int +session_unlock (DBusConnection *connection, + const char *ssid) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + + Debug ("ConsoleKit: Unlocking session %s", ssid); + message = dbus_message_new_method_call (CK_NAME, + ssid, + CK_SESSION_INTERFACE, + "Unlock"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + return FALSE; + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, + message, + -1, &error); + dbus_message_unref (message); + dbus_message_unref (reply); + dbus_connection_flush (connection); + + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + return FALSE; + } + + return TRUE; +} + +/* from libhal */ +static char ** +get_path_array_from_iter (DBusMessageIter *iter, + int *num_elements) +{ + int count; + char **buffer; + + count = 0; + buffer = (char **)malloc (sizeof (char *) * 8); + + if (buffer == NULL) + goto oom; + + buffer[0] = NULL; + while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_OBJECT_PATH) { + const char *value; + char *str; + + if ((count % 8) == 0 && count != 0) { + buffer = realloc (buffer, sizeof (char *) * (count + 8)); + if (buffer == NULL) + goto oom; + } + + dbus_message_iter_get_basic (iter, &value); + str = strdup (value); + if (str == NULL) + goto oom; + + buffer[count] = str; + + dbus_message_iter_next (iter); + count++; + } + + if ((count % 8) == 0) { + buffer = realloc (buffer, sizeof (char *) * (count + 1)); + if (buffer == NULL) + goto oom; + } + + buffer[count] = NULL; + if (num_elements != NULL) + *num_elements = count; + return buffer; + +oom: + LogWarn ("%s %d : error allocating memory\n", __FILE__, __LINE__); + return NULL; + +} + +static char ** +get_sessions_for_user (DBusConnection *connection, + const char *user, + const char *x11_display) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter iter_reply; + DBusMessageIter iter_array; + struct passwd *pwent; + char **sessions; + + sessions = NULL; + message = NULL; + reply = NULL; + + pwent = getpwnam (user); + + dbus_error_init (&error); + message = dbus_message_new_method_call (CK_NAME, + CK_MANAGER_PATH, + CK_MANAGER_INTERFACE, + "GetSessionsForUser"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + goto out; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, + DBUS_TYPE_UINT32, + &pwent->pw_uid); + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, + message, + -1, &error); + dbus_connection_flush (connection); + + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + goto out; + } + + if (reply == NULL) { + Debug ("ConsoleKit: No reply for GetSessionsForUser"); + goto out; + } + + dbus_message_iter_init (reply, &iter_reply); + if (dbus_message_iter_get_arg_type (&iter_reply) != DBUS_TYPE_ARRAY) { + Debug ("ConsoleKit: Wrong reply for GetSessionsForUser - expecting an array."); + goto out; + } + + dbus_message_iter_recurse (&iter_reply, &iter_array); + sessions = get_path_array_from_iter (&iter_array, NULL); + + out: + if (message != NULL) { + dbus_message_unref (message); + } + if (reply != NULL) { + dbus_message_unref (reply); + } + + return sessions; +} + +void +unlock_ck_session (const char *user, + const char *x11_display) +{ + DBusError error; + DBusConnection *connection; + char **sessions; + int i; + + Debug ("ConsoleKit: Unlocking session for %s on %s", user, x11_display); + + dbus_error_init (&error); + connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { + Debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message); + dbus_error_free (&error); + return; + } + + sessions = get_sessions_for_user (connection, user, x11_display); + if (sessions == NULL || sessions[0] == NULL) { + Debug ("ConsoleKit: no sessions found"); + return; + } + + for (i = 0; sessions[i] != NULL; i++) { + char *ssid; + char *xdisplay; + + ssid = sessions[i]; + session_get_x11_display (connection, ssid, &xdisplay); + Debug ("ConsoleKit: session %s has DISPLAY %s", ssid, xdisplay); + + if (xdisplay != NULL + && x11_display != NULL + && strcmp (xdisplay, x11_display) == 0) { + int res; + + res = session_unlock (connection, ssid); + if (! res) { + LogError ("ConsoleKit: Unable to unlock %s", ssid); + } + } + + free (xdisplay); + } + + freeStrArr (sessions); +} + +char * +open_ck_session (struct passwd *pwent, + struct display *d) +{ + DBusConnection *connection; + DBusError error; + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter iter_struct; + char *cookie; + + cookie = NULL; + + if (pwent == NULL) { + Debug ("ConsoleKit: NULL user passed as parameter"); + return NULL; + } + + Debug ("ConsoleKit: Opening session for %s", pwent->pw_name); + + dbus_error_init (&error); + connection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error); + private_connection = connection; + + if (connection == NULL) { + Debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message); + dbus_error_free (&error); + return NULL; + } + + dbus_connection_set_exit_on_disconnect (connection, FALSE); + /* FIXME: What to do about these? + dbus_connection_set_watch_functions( connection, + dbusAddWatch, + dbusRemoveWatch, + dbusToggleWatch, + data, 0 ); + dbus_connection_set_timeout_functions( connection, + dbusAddTimeout, + dbusRemoveTimeout, + dbusToggleTimeout, + data, 0 ); + dbus_connection_set_wakeup_main_function( connection, + dbusWakeupMain, + data, 0 ); */ + + dbus_error_init (&error); + message = dbus_message_new_method_call (CK_NAME, + CK_MANAGER_PATH, + CK_MANAGER_INTERFACE, + "OpenSessionWithParameters"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + return NULL; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_open_container (&iter, + DBUS_TYPE_ARRAY, + DBUS_STRUCT_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_STRUCT_END_CHAR_AS_STRING, + &iter_struct); + + add_param_int (&iter_struct, "user", pwent->pw_uid); + add_param_string (&iter_struct, "x11-display", d->name); + add_param_boolean (&iter_struct, "is-local", ((d->displayType & d_location) == dLocal)); +#ifdef XDMCP + if ((d->displayType & d_location) != dLocal) { + add_param_string (&iter_struct, "remote-host-name", d->remoteHost); + } +#endif + +#ifdef HAVE_VTS + if (d->serverVT > 0) { + char device[20]; + + /* FIXME: how does xorg construct this */ + sprintf(device, "/dev/tty%d", d->serverVT); + add_param_string (&iter_struct, "x11-display-device", device); + } +#endif + + dbus_message_iter_close_container (&iter, &iter_struct); + + reply = dbus_connection_send_with_reply_and_block (connection, + message, + -1, &error); + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + reply = NULL; + } + + dbus_connection_flush (connection); + + dbus_message_unref (message); + dbus_error_free (&error); + + if (reply != NULL) { + const char *value; + + dbus_message_iter_init (reply, &iter); + dbus_message_iter_get_basic (&iter, &value); + cookie = strdup (value); + dbus_message_unref (reply); + } + + return cookie; +} + +void +close_ck_session (const char *cookie) +{ + DBusError error; + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + + if (cookie == NULL) { + return; + } + + if (private_connection == NULL) { + return; + } + + dbus_error_init (&error); + message = dbus_message_new_method_call (CK_NAME, + CK_MANAGER_PATH, + CK_MANAGER_INTERFACE, + "CloseSession"); + if (message == NULL) { + Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + return; + } + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, + DBUS_TYPE_STRING, + &cookie); + + reply = dbus_connection_send_with_reply_and_block (private_connection, + message, + -1, &error); + if (dbus_error_is_set (&error)) { + Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); + reply = NULL; + } + + dbus_connection_flush (private_connection); + + dbus_message_unref (message); + dbus_error_free (&error); + + dbus_connection_close (private_connection); + private_connection = NULL; +} diff --git a/tdm/backend/consolekit.h b/tdm/backend/consolekit.h new file mode 100644 index 000000000..e385e3f91 --- /dev/null +++ b/tdm/backend/consolekit.h @@ -0,0 +1,36 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + + Copyright (C) 2006 William Jon McCann + Copyright (C) 2007 Kevin Kofler + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + + +#ifndef __CONSOLE_KIT_H +#define __CONSOLE_KIT_H + +#include + +struct display; + +char * open_ck_session (struct passwd *pwent, + struct display *display); +void close_ck_session (const char *cookie); +void unlock_ck_session (const char *user, + const char *x11_display); + +#endif /* __CONSOLE_KIT_H */ diff --git a/tdm/backend/ctrl.c b/tdm/backend/ctrl.c new file mode 100644 index 000000000..622c9370d --- /dev/null +++ b/tdm/backend/ctrl.c @@ -0,0 +1,1015 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2001-2005 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * display manager + */ + +#include "dm.h" +#include "dm_socket.h" +#include "dm_error.h" + +#include +#include +#include + +static void +acceptSock( CtrlRec *cr ) +{ + struct cmdsock *cs; + int fd; + + if ((fd = accept( cr->fd, 0, 0 )) < 0) { + bust: + LogError( "Error accepting command connection\n" ); + return; + } + if (!(cs = Malloc( sizeof(*cs) ))) { + close( fd ); + goto bust; + } + cs->sock.fd = fd; + cs->sock.buffer = 0; + cs->sock.buflen = 0; + cs->next = cr->css; + cr->css = cs; + fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ); + RegisterCloseOnFork( fd ); + RegisterInput( fd ); +} + +static void +nukeSock( struct cmdsock *cs ) +{ + UnregisterInput( cs->sock.fd ); + CloseNClearCloseOnFork( cs->sock.fd ); + if (cs->sock.buffer) + free( cs->sock.buffer ); + free( cs ); +} + +#ifdef HONORS_SOCKET_PERMS +static CtrlRec ctrl = { 0, 0, -1, 0, 0, { -1, 0, 0 } }; +#else +static CtrlRec ctrl = { 0, 0, 0, -1, 0, 0, { -1, 0, 0 } }; + +static int mkTempDir( char *dir ) +{ + int i, l = strlen( dir ) - 6; + + for (i = 0; i < 100; i++) { + randomStr( dir + l ); + if (!mkdir( dir, 0700 )) + return True; + if (errno != EEXIST) + break; + } + return False; +} +#endif + +void +openCtrl( struct display *d ) +{ + CtrlRec *cr; + const char *dname; + char *sockdir; + struct sockaddr_un sa; + + if (!*fifoDir) + return; + if (d) { + cr = &d->ctrl, dname = d->name; + if (!memcmp( dname, "localhost:", 10 )) + dname += 9; + } else + cr = &ctrl, dname = 0; + if (cr->fifo.fd < 0) { + if (mkdir( fifoDir, 0755 )) { + if (errno != EEXIST) { + LogError( "mkdir %\"s failed; no control FiFos will be available\n", + fifoDir ); + return; + } + } else + chmod( fifoDir, 0755 ); /* override umask */ + StrApp( &cr->fpath, fifoDir, dname ? "/xdmctl-" : "/xdmctl", + dname, (char *)0 ); + if (cr->fpath) { + unlink( cr->fpath ); + if (mkfifo( cr->fpath, 0 ) < 0) + LogError( "Cannot create control FiFo %\"s\n", cr->fpath ); + else { + cr->gid = fifoGroup; + if (!d) + chown( cr->fpath, -1, fifoGroup ); + chmod( cr->fpath, 0620 ); + if ((cr->fifo.fd = open( cr->fpath, O_RDWR | O_NONBLOCK )) >= 0) { + RegisterCloseOnFork( cr->fifo.fd ); + RegisterInput( cr->fifo.fd ); + goto fifok; + } + unlink( cr->fpath ); + LogError( "Cannot open control FiFo %\"s\n", cr->fpath ); + } + free( cr->fpath ); + cr->fpath = 0; + } + } + fifok: + if (cr->fd < 0) { + /* fifoDir is created above already */ + sockdir = 0; + StrApp( &sockdir, fifoDir, dname ? "/dmctl-" : "/dmctl", + dname, (char *)0 ); + if (sockdir) { + StrApp( &cr->path, sockdir, "/socket", (char *)0 ); + if (cr->path) { + if (strlen( cr->path ) >= sizeof(sa.sun_path)) + LogError( "path %\"s too long; no control sockets will be available\n", + cr->path ); +#ifdef HONORS_SOCKET_PERMS + else if (mkdir( sockdir, 0700 ) && errno != EEXIST) + LogError( "mkdir %\"s failed; no control sockets will be available\n", + sockdir ); + else if (unlink( cr->path ) && errno != ENOENT) + LogError( "unlink %\"s failed: %m; control socket will not be available\n", + cr->path ); + else { +#else + else if (unlink( sockdir ) && errno != ENOENT) + LogError( "unlink %\"s failed: %m; control socket will not be available\n", + sockdir ); + else if (!StrApp( &cr->realdir, sockdir, "-XXXXXX", (char *)0)) + ; + else if (!mkTempDir( cr->realdir )) { + LogError( "mkdir %\"s failed: %m; control socket will not be available\n", + cr->realdir ); + free( cr->realdir ); + cr->realdir = 0; + } else if (symlink( cr->realdir, sockdir )) { + LogError( "symlink %\"s => %\"s failed: %m; control socket will not be available\n", + sockdir, cr->realdir ); + rmdir( cr->realdir ); + free( cr->realdir ); + cr->realdir = 0; + } else { + chown( sockdir, 0, d ? 0 : fifoGroup ); + chmod( sockdir, 0750 ); +#endif + if ((cr->fd = socket( PF_UNIX, SOCK_STREAM, 0 )) < 0) + LogError( "Cannot create control socket\n" ); + else { + sa.sun_family = AF_UNIX; + strcpy( sa.sun_path, cr->path ); + if (!bind( cr->fd, (struct sockaddr *)&sa, sizeof(sa) )) { + if (!listen( cr->fd, 5 )) { +#ifdef HONORS_SOCKET_PERMS + chmod( cr->path, 0660 ); + if (!d) + chown( cr->path, -1, fifoGroup ); + chmod( sockdir, 0755 ); +#else + chmod( cr->path, 0666 ); +#endif + RegisterCloseOnFork( cr->fd ); + RegisterInput( cr->fd ); + free( sockdir ); + return; + } + unlink( cr->path ); + LogError( "Cannot listen on control socket %\"s\n", + cr->path ); + } else + LogError( "Cannot bind control socket %\"s\n", + cr->path ); + close( cr->fd ); + cr->fd = -1; + } +#ifdef HONORS_SOCKET_PERMS + rmdir( sockdir ); +#else + unlink( sockdir ); + rmdir( cr->realdir ); + free( cr->realdir ); + cr->realdir = 0; +#endif + } + free( cr->path ); + cr->path = 0; + } + free( sockdir ); + } + } +} + +void +closeCtrl( struct display *d ) +{ + CtrlRec *cr = d ? &d->ctrl : &ctrl; + + if (cr->fd >= 0) { + UnregisterInput( cr->fd ); + CloseNClearCloseOnFork( cr->fd ); + cr->fd = -1; + unlink( cr->path ); + *strrchr( cr->path, '/' ) = 0; +#ifdef HONORS_SOCKET_PERMS + rmdir( cr->path ); +#else + unlink( cr->path ); + rmdir( cr->realdir ); + free( cr->realdir ); + cr->realdir = 0; +#endif + free( cr->path ); + cr->path = 0; + while (cr->css) { + struct cmdsock *cs = cr->css; + cr->css = cs->next; + nukeSock( cs ); + } + } + if (cr->fifo.fd >= 0) { + UnregisterInput( cr->fifo.fd ); + CloseNClearCloseOnFork( cr->fifo.fd ); + cr->fifo.fd = -1; + unlink( cr->fpath ); + free( cr->fpath ); + cr->fpath = 0; + if (cr->fifo.buffer) + free( cr->fifo.buffer ); + cr->fifo.buffer = 0; + cr->fifo.buflen = 0; + } +} + +void +chownCtrl( CtrlRec *cr, int uid ) +{ + if (cr->fpath) + chown( cr->fpath, uid, -1 ); + if (cr->path) +#ifdef HONORS_SOCKET_PERMS + chown( cr->path, uid, -1 ); +#else + chown( cr->realdir, uid, -1 ); +#endif +} + +void +updateCtrl( void ) +{ + unsigned ffl, slc; + + ffl = 0; + if (ctrl.path) + for (ffl = strlen( ctrl.path ), slc = 2; ;) + if (ctrl.path[--ffl] == '/') + if (!--slc) + break; + if (ffl != strlen( fifoDir ) || memcmp( fifoDir, ctrl.path, ffl ) || + ctrl.gid != fifoGroup) + { + closeCtrl( 0 ); + openCtrl( 0 ); + } +} + + +static void +fLog( struct display *d, int fd, const char *sts, const char *msg, ... ) +{ + char *fmsg, *otxt; + const char *what; + int olen; + va_list va; + + va_start( va, msg ); + VASPrintf( &fmsg, msg, va ); + va_end( va ); + if (!fmsg) + return; + if (fd >= 0) { + olen = ASPrintf( &otxt, "%s\t%\\s\n", sts, fmsg ); + if (otxt) { + Writer( fd, otxt, olen ); + free( otxt ); + } + what = "socket"; + } else + what = "FiFo"; + if (d) + Debug( "control %s for %s: %s - %s", what, d->name, sts, fmsg ); + else + Debug( "global control %s: %s - %s", what, sts, fmsg ); + free( fmsg ); +} + + +static char * +unQuote( const char *str ) +{ + char *ret, *adp; + + if (!(ret = Malloc( strlen( str ) + 1 ))) + return 0; + for (adp = ret; *str; str++, adp++) + if (*str == '\\') + switch (*++str) { + case 0: str--; /* fallthrough */ + case '\\': *adp = '\\'; break; + case 'n': *adp = '\n'; break; + case 't': *adp = '\t'; break; + default: *adp++ = '\\'; *adp = *str; break; + } + else + *adp = *str; + *adp = 0; + return ret; +} + +static void +str_cat_l( char **bp, const char *str, int max ) +{ + int dnl = StrNLen( str, max ); + memcpy( *bp, str, dnl ); + *bp += dnl; +} + +static void +str_cat( char **bp, const char *str ) +{ + int dnl = strlen( str ); + memcpy( *bp, str, dnl ); + *bp += dnl; +} + +static void +sd_cat( char **bp, SdRec *sdr ) +{ + if (sdr->how == SHUT_HALT) + str_cat( bp, "halt," ); + else + str_cat( bp, "reboot," ); + if (sdr->start == TO_INF) + str_cat( bp, "0," ); + else + *bp += sprintf( *bp, "%d,", sdr->start ); + if (sdr->timeout == TO_INF) + str_cat( bp, "-1," ); + else + *bp += sprintf( *bp, "%d,", sdr->timeout ); + if (sdr->force == SHUT_ASK) + str_cat( bp, "ask" ); + else if (sdr->force == SHUT_FORCE) + str_cat( bp, "force" ); + else if (sdr->force == SHUT_FORCEMY) + str_cat( bp, "forcemy" ); + else + str_cat( bp, "cancel" ); + *bp += sprintf( *bp, ",%d,%s", sdr->uid, sdr->osname ? sdr->osname : "-" ); +} + +static void +emitXSessC( struct display *di, struct display *d, void *ctx ) +{ + char *dname, *bp; + char cbuf[1024]; + + bp = cbuf; + *bp++ = '\t'; + dname = di->name; + if (!memcmp( dname, "localhost:", 10 )) + dname += 9; + str_cat_l( &bp, dname, sizeof(cbuf)/2 ); + *bp++ = ','; +#ifdef HAVE_VTS + if (di->serverVT) + bp += sprintf( bp, "vt%d", di->serverVT ); +#endif + *bp++ = ','; +#ifdef XDMCP + if (di->status == remoteLogin) { + *bp++ = ','; + str_cat_l( &bp, di->remoteHost, sizeof(cbuf)/3 ); + } else +#endif + { + if (di->userName) + str_cat_l( &bp, di->userName, sizeof(cbuf)/5 ); + *bp++ = ','; + if (di->sessName) + str_cat_l( &bp, di->sessName, sizeof(cbuf)/5 ); + } + *bp++ = ','; + if (di == d) + *bp++ = '*'; + if (di->userSess >= 0 && + (d ? (d->userSess != di->userSess && + (d->allowNuke == SHUT_NONE || + (d->allowNuke == SHUT_ROOT && d->userSess))) : + !fifoAllowNuke)) + *bp++ = '!'; + Writer( (int)ctx, cbuf, bp - cbuf ); +} + +static void +emitTTYSessC( STRUCTUTMP *ut, struct display *d, void *ctx ) +{ + struct passwd *pw; + char *bp; + int vt, l; + char cbuf[sizeof(ut->ut_line) + sizeof(ut->ut_user) + sizeof(ut->ut_host) + 16]; + char user[sizeof(ut->ut_user) + 1]; + +#ifndef BSD_UTMP + if (ut->ut_type != USER_PROCESS) + l = 0; + else +#endif + { + l = StrNLen( ut->ut_user, sizeof(ut->ut_user) ); + memcpy( user, ut->ut_user, l ); + } + user[l] = 0; + bp = cbuf; + *bp++ = '\t'; + str_cat_l( &bp, ut->ut_line, sizeof(ut->ut_line) ); + *bp++ = ','; + if (*ut->ut_host) { + *bp++ = '@'; + str_cat_l( &bp, ut->ut_host, sizeof(ut->ut_host) ); + } +#ifdef HAVE_VTS + else if ((vt = TTYtoVT( ut->ut_line ))) + bp += sprintf( bp, "vt%d", vt ); +#endif + *bp++ = ','; + str_cat( &bp, user ); + *bp++ = ','; + /* blank: session type unknown */ + *bp++ = ','; + /* blank: certainly not querying display */ + *bp++ = 't'; + if (*user && + (d ? ((d->allowNuke == SHUT_NONE || + (d->allowNuke == SHUT_ROOT && d->userSess)) && + (!(pw = getpwnam( user )) || d->userSess != (int)pw->pw_uid)) : + !fifoAllowNuke)) + *bp++ = '!'; + Writer( (int)ctx, cbuf, bp - cbuf ); +} + +static void +processCtrl( const char *string, int len, int fd, struct display *d ) +{ +#define Reply(t) Writer (fd, t, strlen (t)) + + struct display *di; + const char *word; + char **ar, **ap, *args, *bp; + SdRec sdr; + char cbuf[1024]; + + if (!(ar = initStrArr( 0 ))) + return; + for (word = string; ; string++, len--) + if (!len || *string == '\t') { + if (!(ar = addStrArr( ar, word, string - word ))) + return; + if (!len) + break; + word = string + 1; + } + word = fd >= 0 ? "socket" : "FiFo"; + if (d) + Debug( "control %s for %s received %'[s\n", word, d->name, ar ); + else + Debug( "global control %s received %'[s\n", word, ar ); + if (ar[0]) { + if (fd >= 0 && !strcmp( ar[0], "caps" )) { + if (ar[1]) + goto exce; + Reply( "ok\ttdm\tlist\t" ); + if (bootManager != BO_NONE) + Reply( "bootoptions\t" ); + if (d) { + if ((d->displayType & d_location) == dLocal) +#ifdef HAVE_VTS + Reply( "local\tactivate\t" ); +#else + Reply( "local\t" ); +#endif + if (d->allowShutdown != SHUT_NONE) { + if (d->allowShutdown == SHUT_ROOT && d->userSess) + Reply( "shutdown root\t" ); + else + Reply( "shutdown\t" ); + Reply( "shutdown ask\t" ); + if (d->allowNuke != SHUT_NONE) { + if (d->allowNuke == SHUT_ROOT && d->userSess) + Reply( "nuke root\t" ); + else + Reply( "nuke\t" ); + } + } + if ((d->displayType & d_location) == dLocal && + AnyReserveDisplays()) + Writer( fd, cbuf, sprintf( cbuf, "reserve %d\t", + idleReserveDisplays() ) ); + Reply( "lock\tsuicide\n" ); + } else { + if (fifoAllowShutdown) { + Reply( "shutdown\t" ); + if (fifoAllowNuke) + Reply( "nuke\t" ); + } + if (AnyReserveDisplays()) + Writer( fd, cbuf, sprintf( cbuf, "reserve %d\t", + idleReserveDisplays() ) ); +#ifdef HAVE_VTS + Reply( "login\tactivate\n" ); +#else + Reply( "login\n" ); +#endif + } + goto bust; + } else if (fd >= 0 && !strcmp( ar[0], "list" )) { + int flags = lstRemote | lstTTY; + if (ar[1]) { + if (!strcmp( ar[1], "all" )) + flags = lstRemote | lstPassive | lstTTY; + else if (!strcmp( ar[1], "alllocal" )) + flags = lstPassive | lstTTY; + else { + fLog( d, fd, "bad", "invalid list scope %\"s", ar[1] ); + goto bust; + } + if (ar[2]) + goto exce; + } + Reply( "ok" ); + ListSessions( flags, d, (void *)fd, emitXSessC, emitTTYSessC ); + Reply( "\n" ); + goto bust; + } else if (!strcmp( ar[0], "reserve" )) { + int lt = 60; /* XXX make default timeout configurable? */ + if (ar[1]) { + lt = strtol( ar[1], &bp, 10 ); + if (lt < 15 || *bp) { + fLog( d, fd, "bad", "invalid timeout %\"s", ar[1] ); + goto bust; + } + if (ar[2]) + goto exce; + } + if (d && (d->displayType & d_location) != dLocal) { + fLog( d, fd, "perm", "display is not local" ); + goto bust; + } + if (!StartReserveDisplay( lt )) { + fLog( d, fd, "noent", "no reserve display available" ); + goto bust; + } +#ifdef HAVE_VTS + } else if (!strcmp( ar[0], "activate" )) { + int vt; + if (!ar[1]) + goto miss; + if (ar[2]) + goto exce; + if (d && (d->displayType & d_location) != dLocal) { + fLog( d, fd, "perm", "display is not local" ); + goto bust; + } + if (ar[1][0] != 'v' || ar[1][1] != 't' || + (vt = atoi( ar[1] + 2 )) <= 0) + { + if (!(di = FindDisplayByName( ar[1] ))) { + fLog( d, fd, "noent", "display not found" ); + goto bust; + } + if ((di->displayType & d_location) != dLocal) { + fLog( d, fd, "inval", "target display is not local" ); + goto bust; + } + if (!di->serverVT) { + fLog( d, fd, "noent", "target display has no VT assigned" ); + goto bust; + } + vt = di->serverVT; + } + if (!activateVT( vt )) { + fLog( d, fd, "inval", "VT switch failed" ); + goto bust; + } +#endif + } else if (!strcmp( ar[0], "shutdown" )) { + ap = ar; + if (!*++ap) + goto miss; + sdr.force = SHUT_CANCEL; + sdr.osname = 0; + if (!strcmp( *ap, "status" )) { + if (fd < 0) + goto bust; + if (*++ap) + goto exce; + bp = cbuf; + *bp++ = 'o'; + *bp++ = 'k'; + if (sdRec.how) { + str_cat( &bp, "\tglobal," ); + sd_cat( &bp, &sdRec ); + } + if (d && d->hstent->sdRec.how) { + str_cat( &bp, "\tlocal," ); + sd_cat( &bp, &d->hstent->sdRec ); + } + *bp++ = '\n'; + Writer( fd, cbuf, bp - cbuf ); + goto bust; + } else if (!strcmp( *ap, "cancel" )) { + sdr.how = 0; + sdr.start = 0; + if (ap[1]) { + if (!d) + goto exce; + if (!strcmp( *++ap, "global" )) + sdr.start = TO_INF; + else if (strcmp( *ap, "local" )) { + fLog( d, fd, "bad", "invalid cancel scope %\"s", *ap ); + goto bust; + } + } + } else { + if (!strcmp( *ap, "reboot" )) + sdr.how = SHUT_REBOOT; + else if (!strcmp( *ap, "halt" )) + sdr.how = SHUT_HALT; + else { + fLog( d, fd, "bad", "invalid type %\"s", *ap ); + goto bust; + } + sdr.uid = -1; + if (!*++ap) + goto miss; + if (**ap == '=') { + switch (setBootOption( *ap + 1, &sdr )) { + case BO_NOMAN: + fLog( d, fd, "notsup", "boot options unavailable" ); + goto bust; + case BO_NOENT: + fLog( d, fd, "noent", "no such boot option" ); + goto bust; + case BO_IO: + fLog( d, fd, "io", "io error" ); + goto bust; + } + if (!*++ap) + goto miss; + } + sdr.start = strtol( *ap, &bp, 10 ); + if (bp != *ap && !*bp) { + if (**ap == '+') + sdr.start += now; + if (!*++ap) + goto miss; + sdr.timeout = strtol( *ap, &bp, 10 ); + if (bp == *ap || *bp) { + fLog( d, fd, "bad", "invalid timeout %\"s", ar[3] ); + goto bust; + } + if (**ap == '+') + sdr.timeout += sdr.start ? sdr.start : now; + if (sdr.timeout < 0) + sdr.timeout = TO_INF; + else { + if (!*++ap) + goto miss; + if (!strcmp( *ap, "force" )) + sdr.force = SHUT_FORCE; + else if (d && !strcmp( *ap, "forcemy" )) + sdr.force = SHUT_FORCEMY; + else if (strcmp( *ap, "cancel" )) { + fLog( d, fd, "bad", "invalid timeout action %\"s", + *ap ); + goto bust; + } + } + } else { + sdr.timeout = 0; + if (d && !strcmp( *ap, "ask" )) + sdr.force = SHUT_ASK; + else if (!strcmp( *ap, "forcenow" )) + sdr.force = SHUT_FORCE; + else if (!strcmp( *ap, "schedule" )) + sdr.timeout = TO_INF; + else if (strcmp( *ap, "trynow" )) { + fLog( d, fd, "bad", "invalid mode %\"s", *ap ); + goto bust; + } + } + } + if (*++ap) + goto exce; + if (d) { + sdr.uid = d->userSess >= 0 ? d->userSess : 0; + if (d->allowShutdown == SHUT_NONE || + (d->allowShutdown == SHUT_ROOT && sdr.uid && + sdr.force != SHUT_ASK)) + { + fLog( d, fd, "perm", "shutdown forbidden" ); + goto bust; + } + if (!sdr.how && !sdr.start) { + if (d->hstent->sdRec.osname) + free( d->hstent->sdRec.osname ); + d->hstent->sdRec = sdr; + } else { + if (sdRec.how && sdRec.force == SHUT_FORCE && + ((d->allowNuke == SHUT_NONE && sdRec.uid != sdr.uid) || + (d->allowNuke == SHUT_ROOT && sdr.uid))) + { + fLog( d, fd, "perm", "overriding forced shutdown forbidden" ); + goto bust; + } + if (sdr.force == SHUT_FORCE && + (d->allowNuke == SHUT_NONE || + (d->allowNuke == SHUT_ROOT && sdr.uid))) + { + fLog( d, fd, "perm", "forced shutdown forbidden" ); + goto bust; + } + if (!sdr.start) { + if (d->hstent->sdRec.osname) + free( d->hstent->sdRec.osname ); + d->hstent->sdRec = sdr; + } else { + if (!sdr.how) + cancelShutdown(); + else { + if (sdRec.osname) + free( sdRec.osname ); + sdRec = sdr; + } + } + } + } else { + if (!fifoAllowShutdown) { + fLog( d, fd, "perm", "shutdown forbidden" ); + goto bust; + } + if (sdRec.how && sdRec.force == SHUT_FORCE && + sdRec.uid != -1 && !fifoAllowNuke) + { + fLog( d, fd, "perm", "overriding forced shutdown forbidden" ); + goto bust; + } + if (!sdr.how) + cancelShutdown(); + else { + if (sdr.force != SHUT_CANCEL) { + if (!fifoAllowNuke) { + fLog( d, fd, "perm", "forced shutdown forbidden" ); + goto bust; + } + } else { + if (!sdr.start && !sdr.timeout && AnyActiveDisplays()) { + fLog( d, fd, "busy", "user sessions running" ); + goto bust; + } + } + sdr.uid = -1; + if (sdRec.osname) + free( sdRec.osname ); + sdRec = sdr; + } + } + } else if (fd >= 0 && !strcmp( ar[0], "listbootoptions" )) { + char **opts; + int def, cur, i, j; + + if (ar[1]) + goto exce; + switch (getBootOptions( &opts, &def, &cur )) { + case BO_NOMAN: + fLog( d, fd, "notsup", "boot options unavailable" ); + goto bust; + case BO_IO: + fLog( d, fd, "io", "io error" ); + goto bust; + } + Reply( "ok\t" ); + for (i = 0; opts[i]; i++) { + bp = cbuf; + if (i) + *bp++ = ' '; + for (j = 0; opts[i][j]; j++) + if (opts[i][j] == ' ') { + *bp++ = '\\'; + *bp++ = 's'; + } else + *bp++ = opts[i][j]; + Writer( fd, cbuf, bp - cbuf ); + } + freeStrArr( opts ); + Writer( fd, cbuf, sprintf( cbuf, "\t%d\t%d\n", def, cur ) ); + goto bust; + } else if (d) { + if (!strcmp( ar[0], "lock" )) { + if (ar[1]) + goto exce; + d->hstent->lock = 1; + } else if (!strcmp( ar[0], "unlock" )) { + if (ar[1]) + goto exce; + d->hstent->lock = 0; + } else if (!strcmp( ar[0], "suicide" )) { + if (ar[1]) + goto exce; + if (d->status == running && d->pid != -1) { + TerminateProcess( d->pid, SIGTERM ); + d->status = raiser; + } + } else { + fLog( d, fd, "nosys", "unknown command" ); + goto bust; + } + } else { + if (!strcmp( ar[0], "login" )) { + int nuke; + if (arrLen( ar ) < 5) { + miss: + fLog( d, fd, "bad", "missing argument(s)" ); + goto bust; + } + if (!(di = FindDisplayByName( ar[1] ))) { + fLog( d, fd, "noent", "display %s not found", ar[1] ); + goto bust; + } + if (ar[5]) { + if (!(args = unQuote( ar[5] ))) { + fLog( d, fd, "nomem", "out of memory" ); + goto bust; + } + if (ar[6]) { + free( args ); + exce: + fLog( d, fd, "bad", "excess argument(s)" ); + goto bust; + } + setNLogin( di, ar[3], ar[4], args, 2 ); + free( args ); + } else + setNLogin( di, ar[3], ar[4], 0, 2 ); + nuke = !strcmp( ar[2], "now" ); + switch (di->status) { + case running: + if (di->pid != -1 && (di->userSess < 0 || nuke)) { + TerminateProcess( di->pid, SIGTERM ); + di->status = raiser; + } + break; + case remoteLogin: + if (di->serverPid != -1 && nuke) + TerminateProcess( di->serverPid, di->termSignal ); + break; + case reserve: + di->status = notRunning; + break; + case textMode: +#ifndef HAVE_VTS + SwitchToX( di ); +#endif + break; + default: + break; + } + } else { + fLog( d, fd, "nosys", "unknown command" ); + goto bust; + } + } + if (fd >= 0) + Reply( "ok\n" ); + } + bust: + freeStrArr( ar ); +} + +static int +handleChan( struct display *d, struct bsock *cs, int fd, FD_TYPE *reads ) +{ + char *bufp, *nbuf, *obuf, *eol; + int len, bl, llen; + char buf[1024]; + + bl = cs->buflen; + obuf = cs->buffer; + if (bl <= 0 && FD_ISSET( cs->fd, reads )) { + FD_CLR( cs->fd, reads ); + bl = -bl; + memcpy( buf, obuf, bl ); + if ((len = Reader( cs->fd, buf + bl, sizeof(buf) - bl )) <= 0) + return -1; + bl += len; + bufp = buf; + } else { + len = 0; + bufp = obuf; + } + if (bl > 0) { + if ((eol = memchr( bufp, '\n', bl ))) { + llen = eol - bufp + 1; + bl -= llen; + if (bl) { + if (!(nbuf = Malloc( bl ))) + return -1; + memcpy( nbuf, bufp + llen, bl ); + } else + nbuf = 0; + cs->buffer = nbuf; + cs->buflen = bl; + processCtrl( bufp, llen - 1, fd, d ); + if (obuf) + free( obuf ); + return 1; + } else if (!len) { + if (fd >= 0) + cs->buflen = -bl; + else + fLog( d, -1, "bad", "unterminated command" ); + } + } + return 0; +} + +int +handleCtrl( FD_TYPE *reads, struct display *d ) +{ + CtrlRec *cr = d ? &d->ctrl : &ctrl; + struct cmdsock *cs, **csp; + + if (cr->fifo.fd >= 0) { + switch (handleChan( d, &cr->fifo, -1, reads )) { + case -1: + if (cr->fifo.buffer) + free( cr->fifo.buffer ); + cr->fifo.buflen = 0; + break; + case 1: + return 1; + default: + break; + } + } + if (cr->fd >= 0 && FD_ISSET( cr->fd, reads )) + acceptSock( cr ); + else { + for (csp = &cr->css; (cs = *csp); ) { + switch (handleChan( d, &cs->sock, cs->sock.fd, reads )) { + case -1: + *csp = cs->next; + nukeSock( cs ); + continue; + case 1: + return 1; + default: + break; + } + csp = &cs->next; + } + } + return 0; +} diff --git a/tdm/backend/daemon.c b/tdm/backend/daemon.c new file mode 100644 index 000000000..79d9e47ff --- /dev/null +++ b/tdm/backend/daemon.c @@ -0,0 +1,78 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2000,2001,2003 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + */ + +#include "dm.h" +#include "dm_error.h" + +void +BecomeDaemon( void ) +{ + int pfd[2]; + + /* + * fork so that the process goes into the background automatically. Also + * has a nice side effect of having the child process get inherited by + * init (pid 1). + * Create a pipe and block on it, so the parent knows when the child is + * done with detaching. This eliminates the possibility that the child + * might get killed when the init script that's running xdm exits. + */ + + if (pipe( pfd )) + pfd[0] = pfd[1] = -1; /* so what ...? */ + switch (fork ()) { + case 0: + /* child */ + break; + case -1: + /* error */ + LogError( "Daemon fork failed: %m\n" ); + break; + + default: + /* parent */ + close( pfd[1] ); + read( pfd[0], &pfd[1] /* dummy */, 1 ); + exit( 0 ); + } + + /* don't use daemon() - it doesn't buy us anything but an additional fork */ + + setsid(); + + close( pfd[0] ); + close( pfd[1] ); /* tell parent that we're done with detaching */ + + chdir( "/" ); +} diff --git a/tdm/backend/dm.c b/tdm/backend/dm.c new file mode 100644 index 000000000..d372dd472 --- /dev/null +++ b/tdm/backend/dm.c @@ -0,0 +1,1669 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2000-2005 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * display manager + */ + +#include "dm.h" +#include "dm_auth.h" +#include "dm_error.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_VTS +# include +# include +#endif + +static void SigHandler( int n ); +static int ScanConfigs( int force ); +static void StartDisplays( void ); +#define XS_KEEP 0 +#define XS_RESTART 1 +#define XS_RETRY 2 +static void ExitDisplay( struct display *d, int endState, int serverCmd, int goodExit ); +static void rStopDisplay( struct display *d, int endState ); +static void MainLoop( void ); + +static int signalFds[2]; + +#if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE) +static char *Title; +static int TitleLen; +#endif + +static int StorePid( void ); + +static int Stopping; +SdRec sdRec = { 0, 0, 0, TO_INF, TO_INF, 0, 0, 0 }; + +time_t now; + +char *prog, *progpath; + +int +main( int argc, char **argv ) +{ + int oldpid, oldumask, fd, noDaemonMode; + char *pt, *errorLogFile, **opts; + + /* make sure at least world write access is disabled */ + if (((oldumask = umask( 022 )) & 002) == 002) + (void)umask( oldumask ); + + /* give /dev/null as stdin */ + if ((fd = open( "/dev/null", O_RDONLY )) > 0) { + dup2( fd, 0 ); + close( fd ); + } + if (fcntl( 1, F_GETFD ) < 0) + dup2( 0, 1 ); + if (fcntl( 2, F_GETFD ) < 0) + dup2( 0, 2 ); + + if (argv[0][0] == '/') { + if (!StrDup( &progpath, argv[0] )) + Panic( "Out of memory" ); + } else +#ifdef __linux__ + { + /* note that this will resolve symlinks ... */ + int len; + char fullpath[PATH_MAX]; + if ((len = readlink( "/proc/self/exe", fullpath, sizeof(fullpath) )) < 0) + Panic( "Invoke with full path specification or mount /proc" ); + if (!StrNDup( &progpath, fullpath, len )) + Panic( "Out of memory" ); + } +#else +# if 0 + Panic( "Must be invoked with full path specification" ); +# else + { + char directory[PATH_MAX+1]; + if (!getcwd( directory, sizeof(directory) )) + Panic( "Can't find myself (getcwd failed)" ); + if (strchr( argv[0], '/' )) + StrApp( &progpath, directory, "/", argv[0], (char *)0 ); + else { + int len; + char *path, *name, *thenam, nambuf[PATH_MAX+1]; + char *pathe; + + if (!(path = getenv( "PATH" ))) + Panic( "Can't find myself (no PATH)" ); + len = strlen( argv[0] ); + name = nambuf + PATH_MAX - len; + memcpy( name, argv[0], len + 1 ); + *--name = '/'; + do { + if (!(pathe = strchr( path, ':' ))) + pathe = path + strlen( path ); + len = pathe - path; + if (!len || (len == 1 && *path == '.')) { + len = strlen( directory ); + path = directory; + } + thenam = name - len; + if (thenam >= nambuf) { + memcpy( thenam, path, len ); + if (!access( thenam, X_OK )) + goto found; + } + path = pathe; + } while (*path++ != '\0'); + Panic( "Can't find myself (not in PATH)" ); + found: + if (!StrDup( &progpath, thenam )) + Panic( "Out of memory" ); + } + } +# endif +#endif + prog = strrchr( progpath, '/' ) + 1; + +#if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE) + Title = argv[0]; + TitleLen = (argv[argc - 1] + strlen( argv[argc - 1] )) - Title; +#endif + + /* + * Parse command line options + */ + noDaemonMode = getppid(); + errorLogFile = 0; + if (!(opts = Malloc( 2 * sizeof(char *) ))) + return 1; + opts[0] = (char *)""; + opts[1] = 0; + while (*++argv) { + if (**argv != '-') + break; + pt = *argv + 1; + if (*pt == '-') + pt++; + if (!strcmp( pt, "help" ) || !strcmp( pt, "h" )) { + printf( "Usage: %s [options] [tty]\n" +" -daemon\t - Daemonize even when started by init\n" +" -nodaemon\t - Don't daemonize even when started from command line\n" +" -config - Use alternative master configuration file\n" +" -xrm \t - Override frontend-specific resource\n" +" -error \t - Use alternative log file\n" +" -debug \t - Debug option bitfield:\n" +"\t\t\t0x1 - core log\n" +"\t\t\t0x2 - config reader log\n" +"\t\t\t0x4 - greeter log\n" +"\t\t\t0x8 - IPC log\n" +"\t\t\t0x10 - session sub-daemon post-fork delay\n" +"\t\t\t0x20 - config reader post-start delay\n" +"\t\t\t0x40 - greeter post-start delay\n" +"\t\t\t0x80 - don't use syslog\n" +"\t\t\t0x100 - core Xauth log\n" +"\t\t\t0x400 - valgrind config reader and greeter\n" +"\t\t\t0x800 - strace config reader and greeter\n" + , prog ); + exit( 0 ); + } else if (!strcmp( pt, "daemon" )) + noDaemonMode = 0; + else if (!strcmp( pt, "nodaemon" )) + noDaemonMode = 1; + else if (argv[1] && !strcmp( pt, "config" )) + StrDup( opts, *++argv ); + else if (argv[1] && !strcmp( pt, "xrm" )) + opts = addStrArr( opts, *++argv, -1 ); + else if (argv[1] && !strcmp( pt, "debug" )) + sscanf( *++argv, "%i", &debugLevel ); + else if (argv[1] && (!strcmp( pt, "error" ) || !strcmp( pt, "logfile" ))) + errorLogFile = *++argv; + else { + fprintf( stderr, "\"%s\" is an unknown option or is missing a parameter\n", *argv ); + exit( 1 ); + } + } + + /* + * Only allow root to run in non-debug mode to avoid problems + */ + if (!debugLevel && getuid()) { + fprintf( stderr, "Only root wants to run %s\n", prog ); + exit( 1 ); + } + + InitErrorLog( errorLogFile ); + + if (noDaemonMode != 1) + BecomeDaemon(); + + /* + * Step 1 - load configuration parameters + */ + if (!InitResources( opts ) || ScanConfigs( FALSE ) < 0) + LogPanic( "Config reader failed. Aborting ...\n" ); + + /* SUPPRESS 560 */ + if ((oldpid = StorePid())) { + if (oldpid == -1) + LogError( "Can't create/lock pid file %s\n", pidFile ); + else + LogError( "Can't lock pid file %s, another xdm is running (pid %d)\n", + pidFile, oldpid ); + exit( 1 ); + } + +#ifdef NEED_ENTROPY + AddOtherEntropy(); +#endif + + /* + * We used to clean up old authorization files here. As authDir is + * supposed to be /var/run/xauth or /tmp, we needn't to care for it. + */ + +#ifdef XDMCP + init_session_id(); +#else + Debug( "not compiled for XDMCP\n" ); +#endif + if (pipe( signalFds )) + LogPanic( "Unable to create signal notification pipe.\n" ); + RegisterInput( signalFds[0] ); + RegisterCloseOnFork( signalFds[0] ); + RegisterCloseOnFork( signalFds[1] ); + (void)Signal( SIGTERM, SigHandler ); + (void)Signal( SIGINT, SigHandler ); + (void)Signal( SIGHUP, SigHandler ); + (void)Signal( SIGCHLD, SigHandler ); + (void)Signal( SIGUSR1, SigHandler ); + + /* + * Step 2 - run a sub-daemon for each entry + */ +#ifdef XDMCP + UpdateListenSockets(); +#endif + openCtrl( 0 ); + MainLoop(); + closeCtrl( 0 ); + if (sdRec.how) { + commitBootOption(); + if (Fork() <= 0) { + char *cmd = sdRec.how == SHUT_HALT ? cmdHalt : cmdReboot; + execute( parseArgs( (char **)0, cmd ), (char **)0 ); + LogError( "Failed to execute shutdown command %\"s\n", cmd ); + exit( 1 ); + } else { + sigset_t mask; + sigemptyset( &mask ); + sigaddset( &mask, SIGCHLD ); + sigaddset( &mask, SIGHUP ); + sigsuspend( &mask ); + } + } + Debug( "nothing left to do, exiting\n" ); + return 0; +} + + +#ifdef HAVE_VTS +int +TTYtoVT( const char *tty ) +{ + return memcmp( tty, "tty", 3 ) ? 0 : atoi( tty + 3 ); +} + +int +activateVT( int vt ) +{ + int ret = 0; + int con = open( "/dev/console", O_RDONLY ); + if (con >= 0) { + if (!ioctl( con, VT_ACTIVATE, vt )) + ret = 1; + close( con ); + } + return ret; +} + + +static void +WakeDisplay( struct display *d ) +{ + if (d->status == textMode) + d->status = (d->displayType & d_lifetime) == dReserve ? reserve : notRunning; +} +#endif + +enum utState { UtDead, UtWait, UtActive }; + +struct utmps { + struct utmps *next; +#ifndef HAVE_VTS + struct display *d; +#endif + time_t time; + enum utState state; + int hadSess; +}; + +#define TIME_LOG 40 +#define TIME_RELOG 10 + +static struct utmps *utmpList; +static time_t utmpTimeout = TO_INF; + +static void +bombUtmp( void ) +{ + struct utmps *utp; + + while ((utp = utmpList)) { +#ifdef HAVE_VTS + ForEachDisplay( WakeDisplay ); +#else + utp->d->status = notRunning; +#endif + utmpList = utp->next; + free( utp ); + } +} + +static void +CheckUtmp( void ) +{ + static time_t modtim; + time_t nck; + time_t ends; + struct utmps *utp, **utpp; + struct stat st; +#ifdef BSD_UTMP + int fd; + struct utmp ut[1]; +#else + STRUCTUTMP *ut; +#endif + + if (!utmpList) + return; + if (stat( UTMP_FILE, &st )) { + LogError( UTMP_FILE " not found - cannot use console mode\n" ); + bombUtmp(); + return; + } + if (modtim != st.st_mtime) { + Debug( "rescanning " UTMP_FILE "\n" ); + for (utp = utmpList; utp; utp = utp->next) + utp->state = UtDead; +#ifdef BSD_UTMP + if ((fd = open( UTMP_FILE, O_RDONLY )) < 0) { + LogError( "Cannot open " UTMP_FILE " - cannot use console mode\n" ); + bombUtmp(); + return; + } + while (Reader( fd, ut, sizeof(ut[0]) ) == sizeof(ut[0])) +#else + SETUTENT(); + while ((ut = GETUTENT())) +#endif + { + for (utp = utmpList; utp; utp = utp->next) { +#ifdef HAVE_VTS + char **line; + for (line = consoleTTYs; *line; line++) + if (!strncmp( *line, ut->ut_line, sizeof(ut->ut_line) )) + goto hitlin; + continue; + hitlin: +#else + if (strncmp( utp->d->console, ut->ut_line, sizeof(ut->ut_line) )) + continue; +#endif +#ifdef BSD_UTMP + if (!*ut->ut_user) { +#else + if (ut->ut_type != USER_PROCESS) { +#endif +#ifdef HAVE_VTS + if (utp->state == UtActive) + break; +#endif + utp->state = UtWait; + } else { + utp->hadSess = 1; + utp->state = UtActive; + } + if (utp->time < ut->ut_time) /* theoretically superfluous */ + utp->time = ut->ut_time; + break; + } + } +#ifdef BSD_UTMP + close( fd ); +#else + ENDUTENT(); +#endif + modtim = st.st_mtime; + } + for (utpp = &utmpList; (utp = *utpp); ) { + if (utp->state != UtActive) { + if (utp->state == UtDead) /* shouldn't happen ... */ + utp->time = 0; + ends = utp->time + (utp->hadSess ? TIME_RELOG : TIME_LOG); + if (ends <= now) { +#ifdef HAVE_VTS + ForEachDisplay( WakeDisplay ); + Debug( "console login timed out\n" ); +#else + utp->d->status = notRunning; + Debug( "console login for %s at %s timed out\n", + utp->d->name, utp->d->console ); +#endif + *utpp = utp->next; + free( utp ); + continue; + } else + nck = ends; + } else + nck = TIME_RELOG + now; + if (nck < utmpTimeout) + utmpTimeout = nck; + utpp = &(*utpp)->next; + } +} + +static void +#ifdef HAVE_VTS +SwitchToTty( void ) +#else +SwitchToTty( struct display *d ) +#endif +{ + struct utmps *utp; +#ifdef HAVE_VTS + int vt; +#endif + + if (!(utp = Malloc( sizeof(*utp) ))) { +#ifdef HAVE_VTS + ForEachDisplay( WakeDisplay ); +#else + d->status = notRunning; +#endif + return; + } +#ifndef HAVE_VTS + d->status = textMode; + utp->d = d; +#endif + utp->time = now; + utp->hadSess = 0; + utp->next = utmpList; + utmpList = utp; + CheckUtmp(); + +#ifdef HAVE_VTS + if ((vt = TTYtoVT( *consoleTTYs ))) + activateVT( vt ); +#endif + + /* XXX output something useful here */ +} + +#ifdef HAVE_VTS +static void +StopToTTY( struct display *d ) +{ + if ((d->displayType & d_location) == dLocal) + switch (d->status) { + default: + rStopDisplay( d, DS_TEXTMODE | 0x100 ); + case reserve: + case textMode: + break; + } +} + +static void +CheckTTYMode( void ) +{ + struct display *d; + + for (d = displays; d; d = d->next) + if (d->status == zombie) + return; + + SwitchToTty(); +} + +#else + +void +SwitchToX( struct display *d ) +{ + struct utmps *utp, **utpp; + + for (utpp = &utmpList; (utp = *utpp); utpp = &(*utpp)->next) + if (utp->d == d) { + *utpp = utp->next; + free( utp ); + d->status = notRunning; + return; + } +} +#endif + +#ifdef XDMCP +static void +StartRemoteLogin( struct display *d ) +{ + char **argv; + int pid; + + Debug( "StartRemoteLogin for %s\n", d->name ); + /* HACK: omitting LoadDisplayResources( d ) here! */ + switch (pid = Fork()) { + case 0: + argv = PrepServerArgv( d, d->serverArgsRemote ); + if (!(argv = addStrArr( argv, "-once", 5 )) || + !(argv = addStrArr( argv, "-query", 6 )) || + !(argv = addStrArr( argv, d->remoteHost, -1 ))) + exit( 1 ); + Debug( "exec %\"[s\n", argv ); + (void)execv( argv[0], argv ); + LogError( "X server %\"s cannot be executed\n", argv[0] ); + + /* Let's try again with some standard paths */ + argv[0] = (char *)realloc(argv[0], strlen("/usr/X11R6/bin/X") + 1); + if (argv[0] != NULL) { + argv[0] = "/usr/X11R6/bin/X"; + Debug( "exec %\"[s\n", argv ); + (void)execv( argv[0], argv ); + LogError( "X server %\"s cannot be executed\n", argv[0] ); + + argv[0] = "/usr/bin/X"; /* Shorter than the previous file name */ + Debug( "exec %\"[s\n", argv ); + (void)execv( argv[0], argv ); + LogError( "X server %\"s cannot be executed\n", argv[0] ); + } + + exit( 1 ); + case -1: + LogError( "Forking X server for remote login failed: %m" ); + d->status = notRunning; + return; + default: + break; + } + Debug( "X server forked, pid %d\n", pid ); + d->serverPid = pid; + + d->status = remoteLogin; +} +#endif + + +static void +StopInactiveDisplay( struct display *d ) +{ + if (d->status != remoteLogin && d->userSess < 0) + StopDisplay( d ); +} + +static void +stoppen( int force ) +{ +#ifdef XDMCP + request_port = 0; + UpdateListenSockets(); +#endif + if (force) + ForEachDisplay( StopDisplay ); + else + ForEachDisplay( StopInactiveDisplay ); + Stopping = 1; +} + + +void +setNLogin( struct display *d, + const char *nuser, const char *npass, char *nargs, int rl ) +{ + struct disphist *he = d->hstent; + he->rLogin = + (ReStr( &he->nuser, nuser ) && + ReStr( &he->npass, npass ) && + ReStr( &he->nargs, nargs )) ? rl : 0; + Debug( "set next login for %s, level %d\n", nuser, rl ); +} + +static void +processDPipe( struct display *d ) +{ + char *user, *pass, *args; + int cmd; + GTalk dpytalk; +#ifdef XDMCP + int ct, len; + ARRAY8 ca, ha; +#endif + + dpytalk.pipe = &d->pipe; + if (Setjmp( dpytalk.errjmp )) { + StopDisplay( d ); + return; + } + GSet( &dpytalk ); + if (!GRecvCmd( &cmd )) { + /* process already exited */ + UnregisterInput( d->pipe.rfd ); + return; + } + switch (cmd) { + case D_User: + d->userSess = GRecvInt(); + d->userName = GRecvStr(); + d->sessName = GRecvStr(); + break; + case D_ReLogin: + user = GRecvStr(); + pass = GRecvStr(); + args = GRecvStr(); + setNLogin( d, user, pass, args, 1 ); + free( args ); + free( pass ); + free( user ); + break; +#ifdef XDMCP + case D_ChooseHost: + ca.data = (unsigned char *)GRecvArr( &len ); + ca.length = (CARD16)len; + ct = GRecvInt(); + ha.data = (unsigned char *)GRecvArr( &len ); + ha.length = (CARD16)len; + RegisterIndirectChoice( &ca, ct, &ha ); + XdmcpDisposeARRAY8( &ha ); + XdmcpDisposeARRAY8( &ca ); + break; + case D_RemoteHost: + if (d->remoteHost) + free( d->remoteHost ); + d->remoteHost = GRecvStr(); + break; +#endif + case D_XConnOk: + startingServer = 0; + break; + default: + LogError( "Internal error: unknown D_* command %d\n", cmd ); + StopDisplay( d ); + break; + } +} + +static void +emitXSessG( struct display *di, struct display *d, void *ctx ATTR_UNUSED ) +{ + GSendStr( di->name ); + GSendStr( "" ); +#ifdef HAVE_VTS + GSendInt( di->serverVT ); +#endif +#ifdef XDMCP + if (di->status == remoteLogin) { + GSendStr( "" ); + GSendStr( di->remoteHost ); + } else +#endif + { + GSendStr( di->userName ); + GSendStr( di->sessName ); + } + GSendInt( di == d ? isSelf : 0 ); +} + +static void +emitTTYSessG( STRUCTUTMP *ut, struct display *d ATTR_UNUSED, void *ctx ATTR_UNUSED ) +{ + GSendStrN( ut->ut_line, sizeof(ut->ut_line) ); + GSendStrN( ut->ut_host, sizeof(ut->ut_host) ); +#ifdef HAVE_VTS + GSendInt( TTYtoVT( ut->ut_line ) ); +#endif +#ifdef BSD_UTMP + GSendStrN( *ut->ut_user ? ut->ut_user : 0, sizeof(ut->ut_user) ); +#else + GSendStrN( ut->ut_type == USER_PROCESS ? ut->ut_user : 0, sizeof(ut->ut_user) ); +#endif + GSendStr( 0 ); /* session type unknown */ + GSendInt( isTTY ); +} + +static void +processGPipe( struct display *d ) +{ + char **opts, *option; + int cmd, ret, dflt, curr; + GTalk dpytalk; + + dpytalk.pipe = &d->gpipe; + if (Setjmp( dpytalk.errjmp )) { + StopDisplay( d ); + return; + } + GSet( &dpytalk ); + if (!GRecvCmd( &cmd )) { + /* process already exited */ + UnregisterInput( d->gpipe.rfd ); + return; + } + switch (cmd) { + case G_ListBootOpts: + ret = getBootOptions( &opts, &dflt, &curr ); + GSendInt( ret ); + if (ret == BO_OK) { + GSendArgv( opts ); + freeStrArr( opts ); + GSendInt( dflt ); + GSendInt( curr ); + } + break; + case G_Shutdown: + sdRec.how = GRecvInt(); + sdRec.start = GRecvInt(); + sdRec.timeout = GRecvInt(); + sdRec.force = GRecvInt(); + sdRec.uid = GRecvInt(); + option = GRecvStr(); + setBootOption( option, &sdRec ); + if (option) + free( option ); + break; + case G_QueryShutdown: + GSendInt( sdRec.how ); + GSendInt( sdRec.start ); + GSendInt( sdRec.timeout ); + GSendInt( sdRec.force ); + GSendInt( sdRec.uid ); + GSendStr( sdRec.osname ); + break; + case G_List: + ListSessions( GRecvInt(), d, 0, emitXSessG, emitTTYSessG ); + GSendInt( 0 ); + break; +#ifdef HAVE_VTS + case G_Activate: + activateVT( GRecvInt() ); + break; +#endif + case G_Console: +#ifdef HAVE_VTS + if (*consoleTTYs) { /* sanity check against greeter */ + ForEachDisplay( StopToTTY ); + CheckTTYMode(); + } +#else + if (*d->console) /* sanity check against greeter */ + rStopDisplay( d, DS_TEXTMODE ); +#endif + break; + default: + LogError( "Internal error: unknown G_* command %d\n", cmd ); + StopDisplay( d ); + break; + } +} + + +static int +ScanConfigs( int force ) +{ + int ret; + + if ((ret = LoadDMResources( force )) <= 0) + return ret; + ScanServers(); +#ifdef XDMCP + ScanAccessDatabase( force ); +#endif + return 1; +} + +static void +MarkDisplay( struct display *d ) +{ + d->stillThere = 0; +} + +static void +RescanConfigs( int force ) +{ + if (ScanConfigs( force ) > 0) { +#ifdef XDMCP + UpdateListenSockets(); +#endif + updateCtrl(); + } +} + +void +cancelShutdown( void ) +{ + sdRec.how = 0; + if (sdRec.osname) { + free( sdRec.osname ); + sdRec.osname = 0; + } + Stopping = 0; + RescanConfigs( TRUE ); +} + + +static void +ReapChildren( void ) +{ + int pid; + struct display *d; + waitType status; + + while ((pid = waitpid( -1, &status, WNOHANG )) > 0) + { + Debug( "manager wait returns pid %d sig %d core %d code %d\n", + pid, waitSig( status ), waitCore( status ), waitCode( status ) ); + /* SUPPRESS 560 */ + if ((d = FindDisplayByPid( pid ))) { + d->pid = -1; + UnregisterInput( d->pipe.rfd ); + GClosen (&d->pipe); + UnregisterInput( d->gpipe.rfd ); + GClosen (&d->gpipe); + closeCtrl( d ); + switch (waitVal( status )) { +#ifdef XDMCP + case EX_REMOTE: + Debug( "display exited with EX_REMOTE\n" ); + ExitDisplay( d, DS_REMOTE, 0, 0 ); + break; +#endif + case EX_NORMAL: + /* (any type of) session ended */ + Debug( "display exited with EX_NORMAL\n" ); + if ((d->displayType & d_lifetime) == dReserve) + ExitDisplay( d, DS_RESERVE, 0, 0 ); + else + ExitDisplay( d, DS_RESTART, XS_KEEP, TRUE ); + break; +#if 0 + case EX_REMANAGE_DPY: + /* user session ended */ + Debug( "display exited with EX_REMANAGE_DPY\n" ); + ExitDisplay( d, DS_RESTART, XS_KEEP, TRUE ); + break; +#endif + case EX_OPENFAILED_DPY: + /* WaitForServer() failed */ + LogError( "Display %s cannot be opened\n", d->name ); +#ifdef XDMCP + /* + * no display connection was ever made, tell the + * terminal that the open attempt failed + */ + if ((d->displayType & d_origin) == dFromXDMCP) + SendFailed( d, "cannot open display" ); +#endif + ExitDisplay( d, DS_RESTART, XS_RETRY, FALSE ); + break; + case waitCompose( SIGTERM,0,0 ): + /* killed before/during WaitForServer() + - local Xserver died + - display stopped (is zombie) + - "login now" and "suicide" pipe commands (is raiser) + */ + Debug( "display exited on SIGTERM\n" ); + ExitDisplay( d, DS_RESTART, XS_RETRY, FALSE ); + break; + case EX_AL_RESERVER_DPY: + /* - killed after WaitForServer() + - Xserver dead after remote session exit + */ + Debug( "display exited with EX_AL_RESERVER_DPY\n" ); + ExitDisplay( d, DS_RESTART, XS_RESTART, FALSE ); + break; + case EX_RESERVER_DPY: + /* induced by greeter: + - could not secure display + - requested by user + */ + Debug( "display exited with EX_RESERVER_DPY\n" ); + ExitDisplay( d, DS_RESTART, XS_RESTART, TRUE ); + break; + case EX_UNMANAGE_DPY: + /* some fatal error */ + Debug( "display exited with EX_UNMANAGE_DPY\n" ); + ExitDisplay( d, DS_REMOVE, 0, 0 ); + break; + default: + /* prolly crash */ + LogError( "Unknown session exit code %d (sig %d) from manager process\n", + waitCode( status ), waitSig( status ) ); + ExitDisplay( d, DS_REMOVE, 0, 0 ); + break; + } + } else if ((d = FindDisplayByServerPid( pid ))) { + d->serverPid = -1; + switch (d->status) { + case zombie: + Debug( "zombie X server for display %s reaped\n", d->name ); +#ifdef HAVE_VTS + if (d->serverVT && d->zstatus != DS_REMOTE) { + if (d->follower) { + d->follower->serverVT = d->serverVT; + d->follower = 0; + } else { + int con = open( "/dev/console", O_RDONLY ); + if (con >= 0) { + struct vt_stat vtstat; + ioctl( con, VT_GETSTATE, &vtstat ); + if (vtstat.v_active == d->serverVT) { + int vt = 1; + struct display *di; + for (di = displays; di; di = di->next) + if (di != d && di->serverVT) + vt = di->serverVT; + for (di = displays; di; di = di->next) + if (di != d && di->serverVT && + (di->userSess >= 0 || + di->status == remoteLogin)) + vt = di->serverVT; + ioctl( con, VT_ACTIVATE, vt ); + } + ioctl( con, VT_DISALLOCATE, d->serverVT ); + close( con ); + } + } + d->serverVT = 0; + } +#endif + rStopDisplay( d, d->zstatus ); + break; + case phoenix: + Debug( "phoenix X server arises, restarting display %s\n", + d->name ); + d->status = notRunning; + break; + case remoteLogin: + Debug( "remote login X server for display %s exited\n", + d->name ); + d->status = ((d->displayType & d_lifetime) == dReserve) ? + reserve : notRunning; + break; + case raiser: + LogError( "X server for display %s terminated unexpectedly\n", + d->name ); + /* don't kill again */ + break; + case running: + if (startingServer == d && d->serverStatus != ignore) { + if (d->serverStatus == starting && waitCode( status ) != 47) + LogError( "X server died during startup\n" ); + StartServerFailed(); + break; + } + LogError( "X server for display %s terminated unexpectedly\n", + d->name ); + if (d->pid != -1) { + Debug( "terminating session pid %d\n", d->pid ); + TerminateProcess( d->pid, SIGTERM ); + } + break; + case notRunning: + case textMode: + case reserve: + /* this cannot happen */ + Debug( "X server exited for passive (%d) session on display %s\n", + (int)d->status, d->name ); + break; + } + } else + Debug( "unknown child termination\n" ); + } +#ifdef NEED_ENTROPY + AddOtherEntropy(); +#endif +} + +static int +wouldShutdown( void ) +{ + struct display *d; + + if (sdRec.force != SHUT_CANCEL) { + if (sdRec.force == SHUT_FORCEMY) + for (d = displays; d; d = d->next) + if (d->status == remoteLogin || + (d->userSess >= 0 && d->userSess != sdRec.uid)) + return 0; + return 1; + } + return !AnyActiveDisplays(); +} + +FD_TYPE WellKnownSocketsMask; +int WellKnownSocketsMax; +int WellKnownSocketsCount; + +void +RegisterInput( int fd ) +{ + /* can be omited, as it is always called right after opening a socket + if (!FD_ISSET (fd, &WellKnownSocketsMask)) + */ + { + FD_SET( fd, &WellKnownSocketsMask ); + if (fd > WellKnownSocketsMax) + WellKnownSocketsMax = fd; + WellKnownSocketsCount++; + } +} + +void +UnregisterInput( int fd ) +{ + /* the check _is_ necessary, as some handles are unregistered before + the regular close sequence. + */ + if (FD_ISSET( fd, &WellKnownSocketsMask )) { + FD_CLR( fd, &WellKnownSocketsMask ); + WellKnownSocketsCount--; + } +} + +static void +SigHandler( int n ) +{ + int olderrno = errno; + char buf = (char)n; + /* Debug( "caught signal %d\n", n ); this hangs in syslog() */ + write( signalFds[1], &buf, 1 ); +#ifdef __EMX__ + (void)Signal( n, SigHandler ); +#endif + errno = olderrno; +} + +static void +MainLoop( void ) +{ + struct display *d; + struct timeval *tvp, tv; + time_t to; + int nready; + char buf; + FD_TYPE reads; + + Debug( "MainLoop\n" ); + time( &now ); + while ( +#ifdef XDMCP + AnyListenSockets() || +#endif + (Stopping ? AnyRunningDisplays() : AnyDisplaysLeft())) + { + if (!Stopping) + StartDisplays(); + to = TO_INF; + if (sdRec.how) { + if (sdRec.start != TO_INF && now < sdRec.start) { + /*if (sdRec.start < to)*/ + to = sdRec.start; + } else { + sdRec.start = TO_INF; + if (now >= sdRec.timeout) { + sdRec.timeout = TO_INF; + if (wouldShutdown()) + stoppen( TRUE ); + else + cancelShutdown(); + } else { + stoppen( FALSE ); + /*if (sdRec.timeout < to)*/ + to = sdRec.timeout; + } + } + } + if (serverTimeout < to) + to = serverTimeout; + if (utmpTimeout < to) + to = utmpTimeout; + if (to == TO_INF) + tvp = 0; + else { + to -= now; + if (to < 0) + to = 0; + tv.tv_sec = to; + tv.tv_usec = 0; + tvp = &tv; + } + reads = WellKnownSocketsMask; + nready = select( WellKnownSocketsMax + 1, &reads, 0, 0, tvp ); + Debug( "select returns %d\n", nready ); + time( &now ); +#ifdef NEED_ENTROPY + AddTimerEntropy(); +#endif + if (now >= serverTimeout) { + serverTimeout = TO_INF; + StartServerTimeout(); + } + if (now >= utmpTimeout) { + utmpTimeout = TO_INF; + CheckUtmp(); + } + if (nready > 0) { + /* + * we restart after the first handled fd, as + * a) it makes things simpler + * b) the probability that multiple fds trigger at once is + * ridiculously small. we handle it in the next iteration. + */ + /* XXX a cleaner solution would be a callback mechanism */ + if (FD_ISSET( signalFds[0], &reads )) { + if (read( signalFds[0], &buf, 1 ) != 1) + LogPanic( "Signal notification pipe broken.\n" ); + switch (buf) { + case SIGTERM: + case SIGINT: + Debug( "shutting down entire manager\n" ); + stoppen( TRUE ); + break; + case SIGHUP: + LogInfo( "Rescanning all config files\n" ); + ForEachDisplay( MarkDisplay ); + RescanConfigs( TRUE ); + break; + case SIGCHLD: + ReapChildren(); + if (!Stopping && autoRescan) + RescanConfigs( FALSE ); + break; + case SIGUSR1: + if (startingServer && + startingServer->serverStatus == starting) + StartServerSuccess(); + break; + } + continue; + } +#ifdef XDMCP + if (ProcessListenSockets( &reads )) + continue; +#endif /* XDMCP */ + if (handleCtrl( &reads, 0 )) + continue; + /* Must be last (because of the breaks)! */ + again: + for (d = displays; d; d = d->next) { + if (handleCtrl( &reads, d )) + goto again; + if (d->pipe.rfd >= 0 && FD_ISSET( d->pipe.rfd, &reads )) { + processDPipe( d ); + break; + } + if (d->gpipe.rfd >= 0 && FD_ISSET( d->gpipe.rfd, &reads )) { + processGPipe( d ); + break; + } + } + } + } +} + +static void +CheckDisplayStatus( struct display *d ) +{ + if ((d->displayType & d_origin) == dFromFile && !d->stillThere) + StopDisplay( d ); + else if ((d->displayType & d_lifetime) == dReserve && + d->status == running && d->userSess < 0 && !d->idleTimeout) + rStopDisplay( d, DS_RESERVE ); + else if (d->status == notRunning) + if (LoadDisplayResources( d ) < 0) { + LogError( "Unable to read configuration for display %s; " + "stopping it.\n", d->name ); + StopDisplay( d ); + return; + } +} + +static void +KickDisplay( struct display *d ) +{ + if (d->status == notRunning) + StartDisplay( d ); + if (d->serverStatus == awaiting && !startingServer) + StartServer( d ); +} + +#ifdef HAVE_VTS +static int active_vts; + +static int +GetBusyVTs( void ) +{ + struct vt_stat vtstat; + int con; + + if (active_vts == -1) { + vtstat.v_state = 0; + if ((con = open( "/dev/console", O_RDONLY )) >= 0) { + ioctl( con, VT_GETSTATE, &vtstat ); + close( con ); + } + active_vts = vtstat.v_state; + } + return active_vts; +} + +static void +AllocateVT( struct display *d ) +{ + struct display *cd; + int i, tvt, volun; + + if ((d->displayType & d_location) == dLocal && + d->status == notRunning && !d->serverVT && d->reqSrvVT >= 0) + { + if (d->reqSrvVT && d->reqSrvVT < 16) + d->serverVT = d->reqSrvVT; + else { + for (i = tvt = 0;;) { + if (serverVTs[i]) { + tvt = atoi( serverVTs[i++] ); + volun = 0; + if (tvt < 0) { + tvt = -tvt; + volun = 1; + } + if (!tvt || tvt >= 16) + continue; + } else { + if (++tvt >= 16) + break; + volun = 1; + } + for (cd = displays; cd; cd = cd->next) { + if (cd->reqSrvVT == tvt && /* protect from lusers */ + (cd->status != zombie || cd->zstatus != DS_REMOVE)) + goto next; + if (cd->serverVT == tvt) { + if (cd->status != zombie || cd->zstatus == DS_REMOTE) + goto next; + if (!cd->follower) { + d->serverVT = -1; + cd->follower = d; + return; + } + } + } + if (!volun || !((1 << tvt) & GetBusyVTs())) { + d->serverVT = tvt; + return; + } + next: ; + } + } + } +} +#endif + +static void +StartDisplays( void ) +{ + ForEachDisplay( CheckDisplayStatus ); + CloseGetter(); +#ifdef HAVE_VTS + active_vts = -1; + ForEachDisplayRev( AllocateVT ); +#endif + ForEachDisplay( KickDisplay ); +} + +void +StartDisplay( struct display *d ) +{ + if (Stopping) { + Debug( "stopping display %s because shutdown is scheduled\n", d->name ); + StopDisplay( d ); + return; + } + +#ifdef HAVE_VTS + if (d->serverVT < 0) + return; +#endif + + d->status = running; + if ((d->displayType & d_location) == dLocal) { + Debug( "StartDisplay %s\n", d->name ); + /* don't bother pinging local displays; we'll + * certainly notice when they exit + */ + d->pingInterval = 0; + if (d->authorize) { + SetLocalAuthorization( d ); + /* + * reset the server after writing the authorization information + * to make it read the file (for compatibility with old + * servers which read auth file only on reset instead of + * at first connection) + */ + if (d->serverPid != -1 && d->resetForAuth && d->resetSignal) + kill( d->serverPid, d->resetSignal ); + } + if (d->serverPid == -1) { + d->serverStatus = awaiting; + return; + } + } else { + Debug( "StartDisplay %s, try %d\n", d->name, d->startTries + 1 ); + /* this will only happen when using XDMCP */ + if (d->authorizations) + SaveServerAuthorizations( d, d->authorizations, d->authNum ); + } + StartDisplayP2( d ); +} + +void +StartDisplayP2( struct display *d ) +{ + char *cname, *cgname; + int pid; + + openCtrl( d ); + Debug( "forking session\n" ); + ASPrintf( &cname, "sub-daemon for display %s", d->name ); + ASPrintf( &cgname, "greeter for display %s", d->name ); + pid = GFork( &d->pipe, "master daemon", cname, + &d->gpipe, cgname ); + switch (pid) { + case 0: + SetTitle( d->name ); + if (debugLevel & DEBUG_WSESS) + sleep( 100 ); + mstrtalk.pipe = &d->pipe; + (void)Signal( SIGPIPE, SIG_IGN ); + SetAuthorization( d ); + WaitForServer( d ); + if ((d->displayType & d_location) == dLocal) { + GSet( &mstrtalk ); + GSendInt( D_XConnOk ); + } + ManageSession( d ); + /* NOTREACHED */ + case -1: + closeCtrl( d ); + d->status = notRunning; + break; + default: + Debug( "forked session, pid %d\n", pid ); + + /* (void) fcntl (d->pipe.rfd, F_SETFL, O_NONBLOCK); */ + /* (void) fcntl (d->gpipe.rfd, F_SETFL, O_NONBLOCK); */ + RegisterInput( d->pipe.rfd ); + RegisterInput( d->gpipe.rfd ); + + d->pid = pid; + d->hstent->lock = d->hstent->rLogin = d->hstent->goodExit = + d->hstent->sdRec.how = 0; + d->lastStart = now; + break; + } +} + +/* + * transition from running to zombie, textmode, reserve or deleted + */ + +static void +rStopDisplay( struct display *d, int endState ) +{ + Debug( "stopping display %s to state %d\n", d->name, endState ); + AbortStartServer( d ); + d->idleTimeout = 0; + if (d->serverPid != -1 || d->pid != -1) { + if (d->pid != -1) + TerminateProcess( d->pid, SIGTERM ); + if (d->serverPid != -1) + TerminateProcess( d->serverPid, d->termSignal ); + d->status = zombie; + d->zstatus = endState & 0xff; + Debug( " zombiefied\n" ); + } else if (endState == DS_TEXTMODE) { +#ifdef HAVE_VTS + d->status = textMode; + CheckTTYMode(); + } else if (endState == (DS_TEXTMODE | 0x100)) { + d->status = textMode; +#else + SwitchToTty( d ); +#endif + } else if (endState == DS_RESERVE) + d->status = reserve; +#ifdef XDMCP + else if (endState == DS_REMOTE) + StartRemoteLogin( d ); +#endif + else { +#ifndef HAVE_VTS + SwitchToX( d ); +#endif + RemoveDisplay( d ); + } +} + +void +StopDisplay( struct display *d ) +{ + rStopDisplay( d, DS_REMOVE ); +} + +static void +ExitDisplay( + struct display *d, + int endState, + int serverCmd, + int goodExit ) +{ + struct disphist *he; + + if (d->status == raiser) { + serverCmd = XS_KEEP; + goodExit = TRUE; + } + + Debug( "ExitDisplay %s, " + "endState = %d, serverCmd = %d, GoodExit = %d\n", + d->name, endState, serverCmd, goodExit ); + + d->userSess = -1; + if (d->userName) + free( d->userName ); + d->userName = 0; + if (d->sessName) + free( d->sessName ); + d->sessName = 0; + he = d->hstent; + he->lastExit = now; + he->goodExit = goodExit; + if (he->sdRec.how) { + if (he->sdRec.force == SHUT_ASK && + (AnyActiveDisplays() || d->allowShutdown == SHUT_ROOT)) + { + endState = DS_RESTART; + } else { + if (!sdRec.how || sdRec.force != SHUT_FORCE || + !((d->allowNuke == SHUT_NONE && sdRec.uid != he->sdRec.uid) || + (d->allowNuke == SHUT_ROOT && he->sdRec.uid))) + { + if (sdRec.osname) + free( sdRec.osname ); + sdRec = he->sdRec; + if (now < sdRec.timeout || wouldShutdown()) + endState = DS_REMOVE; + } else if (he->sdRec.osname) + free( he->sdRec.osname ); + he->sdRec.how = 0; + he->sdRec.osname = 0; + } + } + if (d->status == zombie) + rStopDisplay( d, d->zstatus ); + else { + if (Stopping) { + StopDisplay( d ); + return; + } + if (endState != DS_RESTART || + (d->displayType & d_origin) != dFromFile) + { + rStopDisplay( d, endState ); + } else { + if (serverCmd == XS_RETRY) { + if ((d->displayType & d_location) == dLocal) { + if (he->lastExit - d->lastStart < 120) { + LogError( "Unable to fire up local display %s;" + " disabling.\n", d->name ); + StopDisplay( d ); + return; + } + } else { + if (++d->startTries > d->startAttempts) { + LogError( "Disabling foreign display %s" + " (too many attempts)\n", d->name ); + StopDisplay( d ); + return; + } + } + } else + d->startTries = 0; + if (d->serverPid != -1 && + (serverCmd != XS_KEEP || d->terminateServer)) + { + Debug( "killing X server for %s\n", d->name ); + TerminateProcess( d->serverPid, d->termSignal ); + d->status = phoenix; + } else + d->status = notRunning; + } + } +} + + +static int pidFd; +static FILE *pidFilePtr; + +static int +StorePid( void ) +{ + int oldpid; + + if (pidFile[0] != '\0') { + pidFd = open( pidFile, O_RDWR ); + if (pidFd == -1 && errno == ENOENT) + pidFd = open( pidFile, O_RDWR|O_CREAT, 0666 ); + if (pidFd == -1 || !(pidFilePtr = fdopen( pidFd, "r+" ))) { + LogError( "process-id file %s cannot be opened\n", + pidFile ); + return -1; + } + if (fscanf( pidFilePtr, "%d\n", &oldpid ) != 1) + oldpid = -1; + fseek( pidFilePtr, 0l, 0 ); + if (lockPidFile) { +#ifdef F_SETLK +# ifndef SEEK_SET +# define SEEK_SET 0 +# endif + struct flock lock_data; + lock_data.l_type = F_WRLCK; + lock_data.l_whence = SEEK_SET; + lock_data.l_start = lock_data.l_len = 0; + if (fcntl( pidFd, F_SETLK, &lock_data ) == -1) { + if (errno == EAGAIN) + return oldpid; + else + return -1; + } +#else +# ifdef LOCK_EX + if (flock( pidFd, LOCK_EX|LOCK_NB ) == -1) { + if (errno == EWOULDBLOCK) + return oldpid; + else + return -1; + } +# else + if (lockf( pidFd, F_TLOCK, 0 ) == -1) { + if (errno == EACCES) + return oldpid; + else + return -1; + } +# endif +#endif + } + fprintf( pidFilePtr, "%ld\n", (long)getpid() ); + (void)fflush( pidFilePtr ); + RegisterCloseOnFork( pidFd ); + } + return 0; +} + +#if 0 +void +UnlockPidFile( void ) +{ + if (lockPidFile) +# ifdef F_SETLK + { + struct flock lock_data; + lock_data.l_type = F_UNLCK; + lock_data.l_whence = SEEK_SET; + lock_data.l_start = lock_data.l_len = 0; + (void)fcntl( pidFd, F_SETLK, &lock_data ); + } +# else +# ifdef F_ULOCK + lockf( pidFd, F_ULOCK, 0 ); +# else + flock( pidFd, LOCK_UN ); +# endif +# endif + close( pidFd ); + fclose( pidFilePtr ); +} +#endif + +void +SetTitle( const char *name ) +{ +#if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE) + char *p; + int left; +#endif + + ASPrintf( &prog, "%s: %s", prog, name ); + ReInitErrorLog(); +#ifdef HAVE_SETPROCTITLE + setproctitle( "%s", name ); +#elif !defined(NOXDMTITLE) + p = Title; + left = TitleLen; + + *p++ = '-'; + --left; + while (*name && left > 0) { + *p++ = *name++; + --left; + } + while (left > 0) { + *p++ = '\0'; + --left; + } +#endif +} diff --git a/tdm/backend/dm.h b/tdm/backend/dm.h new file mode 100644 index 000000000..c05d4c865 --- /dev/null +++ b/tdm/backend/dm.h @@ -0,0 +1,630 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2000-2005 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * global xdm core declarations + */ + +#ifndef _DM_H_ +#define _DM_H_ 1 + +#define WITH_CONSOLE_KIT + +#include "greet.h" +#include + +#include /* FamilyInternet6 */ +#include +#include +#include +#include +#include + +#include +#ifdef HAVE_LIMITS_H +# include +#endif + +#include +#define Time_t time_t + +#include +#include + +#ifdef XDMCP +# if defined(__osf__) +/* someone somewhere defines QUERY under Tru64 which confuses Xdmcp.h */ +# undef QUERY +# endif +# include +#endif + +#ifndef PATH_MAX +# ifdef MAXPATHLEN +# define PATH_MAX MAXPATHLEN +# else +# define PATH_MAX 1024 +# endif +#endif + +#include +#define waitCode(w) (WIFEXITED(w) ? WEXITSTATUS(w) : 0) +#define waitSig(w) (WIFSIGNALED(w) ? WTERMSIG(w) : 0) +#ifdef WCOREDUMP +# define waitCore(w) (WCOREDUMP(w)) +#else +# define waitCore(w) 0 /* not in POSIX. so what? */ +#endif +typedef int waitType; + +#define waitCompose(sig,core,code) ((sig) * 256 + (core) * 128 + (code)) +#define waitVal(w) waitCompose(waitSig(w), waitCore(w), waitCode(w)) +#define WaitCode(w) ((w) & 0x7f) +#define WaitCore(w) (((w) >> 7) & 1) +#define WaitSig(w) (((w) >> 8) & 0xff) + +#include +#define FD_TYPE fd_set + +#include +#if defined(__EMX__) || (defined(__NetBSD__) && defined(__sparc__)) /* XXX netbsd? */ +# define Setjmp(e) setjmp(e) +# define Longjmp(e,v) longjmp(e,v) +# define Jmp_buf jmp_buf +#else +# define Setjmp(e) sigsetjmp(e,1) +# define Longjmp(e,v) siglongjmp(e,v) +# define Jmp_buf sigjmp_buf +#endif + +#include +#ifdef HAVE_UTMPX +# include +# define STRUCTUTMP struct utmpx +# define UTMPNAME utmpxname +# define SETUTENT setutxent +# define GETUTENT getutxent +# define PUTUTLINE pututxline +# define ENDUTENT endutxent +# define LASTLOG lastlogx +# define ut_time ut_tv.tv_sec +# define ll_time ll_tv.tv_sec +#else +# define STRUCTUTMP struct utmp +# define UTMPNAME utmpname +# define SETUTENT setutent +# define GETUTENT getutent +# define PUTUTLINE pututline +# define ENDUTENT endutent +# define LASTLOG lastlog +#endif +#ifndef HAVE_STRUCT_UTMP_UT_USER +# define ut_user ut_name +#endif +#ifndef WTMP_FILE +# ifdef _PATH_WTMPX +# define WTMP_FILE _PATH_WTMPX +# elif defined(_PATH_WTMP) +# define WTMP_FILE _PATH_WTMP +# else +# define WTMP_FILE "/usr/adm/wtmp" +# endif +#endif +#ifndef UTMP_FILE +# ifdef _PATH_UTMPX +# define UTMP_FILE _PATH_UTMPX +# elif defined(_PATH_UTMP) +# define UTMP_FILE _PATH_UTMP +# else +# define UTMP_FILE "/etc/utmp" +# endif +#endif + +#ifdef HAVE_NETCONFIG_H +# define STREAMSCONN +#else +# define UNIXCONN +# define TCPCONN +# ifdef FamilyInternet6 +# define IPv6 +# endif +# ifdef HAVE_NETDNET_DN_H +# define DNETCONN +# endif +#endif + +#if !defined(HAVE_ARC4RANDOM) && !defined(DEV_RANDOM) +# define NEED_ENTROPY +#endif + +typedef struct GPipe { + int wfd, rfd; + char *who; +} GPipe; + +typedef struct GTalk { + GPipe *pipe; + Jmp_buf errjmp; +} GTalk; + +typedef struct GProc { + GPipe pipe; + int pid; +} GProc; + +typedef enum displayStatus { notRunning = 0, running, zombie, phoenix, raiser, + textMode, reserve, remoteLogin } DisplayStatus; + +typedef enum serverStatus { ignore = 0, awaiting, starting, + terminated, killed, pausing } ServerStatus; + +typedef struct RcStr { + struct RcStr *next; + char *str; + int cnt; +} RcStr; + +typedef struct CfgDep { + RcStr *name; + long time; +} CfgDep; + +typedef struct CfgArr { + char *data; /* config value array; allocated */ + long *idx; /* config index array; alias */ + CfgDep dep; /* filestamp */ + int numCfgEnt; /* number of config entries */ +} CfgArr; + +struct bsock { + int fd; + int buflen; + char *buffer; +}; + +struct cmdsock { + struct cmdsock *next; + struct bsock sock; /* buffered fd of the socket */ +}; + +typedef struct { + struct cmdsock *css; /* open connections */ + + char *path; /* filename of the socket */ +#ifndef HONORS_SOCKET_PERMS + char *realdir; /* real dirname of the socket */ +#endif + int fd; /* fd of the socket */ + int gid; /* owner group of the socket */ + + char *fpath; /* filename of the fifo */ + struct bsock fifo; /* buffered fd of the fifo */ +} CtrlRec; + +struct display { + struct display *next; + struct disphist *hstent; /* display history entry */ + + /* basic display information */ + char *name; /* DISPLAY name -- also referenced in hstent */ + char *class2; /* display class (may be NULL) */ + int displayType; /* location/origin/lifetime */ + CfgArr cfg; /* config data array */ + + /* display state */ + DisplayStatus status; /* current status */ + int zstatus; /* substatus while zombie */ + int pid; /* process id of child */ + int serverPid; /* process id of server (-1 if none) */ +#ifdef HAVE_VTS + int serverVT; /* server VT (0 = none, -1 = pending) */ + struct display *follower; /* on exit, hand VT to this display */ +#endif + ServerStatus serverStatus; /* X server startup state */ + Time_t lastStart; /* time of last display start */ + int startTries; /* current start try */ + int stillThere; /* state during HUP processing */ + int userSess; /* -1=nobody, otherwise uid */ + char *userName; + char *sessName; + CtrlRec ctrl; /* command socket & fifo */ + GPipe pipe; /* comm master <-> slave */ + GPipe gpipe; /* comm master <-> greeter */ +#ifdef XDMCP + char *remoteHost; /* for X -query type remote login */ + /* XDMCP state */ + unsigned sessionID; /* ID of active session */ + ARRAY8 peer; /* display peer address */ + ARRAY8 from; /* XDMCP port of display */ + unsigned displayNumber; /* numerical part of name */ + int useChooser; /* Run the chooser for this display */ + ARRAY8 clientAddr; /* for chooser picking */ + unsigned connectionType; /* ... */ + int xdmcpFd; +#endif + + CONF_CORE_LOCAL_DEFS + + int idleTimeout; /* abort login after that time */ + + unsigned short *authNameLens; /* authorization protocol name lens */ + + /* information potentially derived from resources */ + int authNameNum; /* number of protocol names */ + Xauth **authorizations; /* authorization data */ + int authNum; /* number of authorizations */ + char *authFile; /* file to store authorization in */ +}; + +typedef struct { + unsigned how:2, /* 0=none 1=reboot 2=halt (SHUT_*) */ + force:2; + int uid; + int start; + int timeout; + char *osname; + time_t bmstamp; + int osindex; +} SdRec; + +struct disphist { + struct disphist *next; + char *name; + Time_t lastExit; /* time of last display exit */ + unsigned rLogin:2, /* 0=nothing 1=relogin 2=login */ + lock:1, /* screen locker running */ + goodExit:1; /* was the last exit "peaceful"? */ + SdRec sdRec; + char *nuser, *npass, *nargs; +}; + +#ifdef XDMCP + +#define PROTO_TIMEOUT (30 * 60) /* 30 minutes should be long enough */ + +struct protoDisplay { + struct protoDisplay *next; + XdmcpNetaddr address; /* UDP address */ + int addrlen; /* UDP address length */ + unsigned long date; /* creation date */ + CARD16 displayNumber; + CARD16 connectionType; + ARRAY8 connectionAddress; + CARD32 sessionID; + Xauth *fileAuthorization; + Xauth *xdmcpAuthorization; + ARRAY8 authenticationName; + ARRAY8 authenticationData; + XdmAuthKeyRec key; +}; +#endif /* XDMCP */ + +/* status code for RStopDisplay */ +#define DS_RESTART 0 +#define DS_TEXTMODE 1 +#define DS_RESERVE 2 +#define DS_REMOTE 3 +#define DS_REMOVE 4 + +/* command codes dpy process -> master process */ +#define D_User 1 +#define D_ReLogin 2 +#define D_ChooseHost 4 +#define D_RemoteHost 5 +#define D_XConnOk 6 + +extern int debugLevel; + +CONF_CORE_GLOBAL_DECLS + +/* in daemon.c */ +void BecomeDaemon( void ); + +/* in dm.c */ +extern char *prog, *progpath; +extern time_t now; +extern SdRec sdRec; +void StartDisplay( struct display *d ); +void StartDisplayP2( struct display *d ); +void StopDisplay( struct display *d ); +void SetTitle( const char *name ); +void SwitchToX( struct display *d ); +void setNLogin( struct display *d, + const char *nuser, const char *npass, char *nargs, + int rl ); +void cancelShutdown( void ); +int TTYtoVT( const char *tty ); +int activateVT( int vt ); + +/* in ctrl.c */ +void openCtrl( struct display *d ); +void closeCtrl( struct display *d ); +int handleCtrl( FD_TYPE *reads, struct display *d ); +void chownCtrl( CtrlRec *cr, int uid ); +void updateCtrl( void ); + +/* in dpylist.c */ +extern struct display *displays; /* that's ugly ... */ +int AnyDisplaysLeft( void ); +void ForEachDisplay( void (*f)( struct display * ) ); +#ifdef HAVE_VTS +void ForEachDisplayRev( void (*f)( struct display * ) ); +#endif +void RemoveDisplay( struct display *old ); +struct display + *FindDisplayByName( const char *name ), +#ifdef XDMCP + *FindDisplayBySessionID( CARD32 sessionID ), + *FindDisplayByAddress( XdmcpNetaddr addr, int addrlen, CARD16 displayNumber ), +#endif /* XDMCP */ + *FindDisplayByPid( int pid ), + *FindDisplayByServerPid( int serverPid ), + *NewDisplay( const char *name ); +int AnyActiveDisplays( void ); +int AnyRunningDisplays( void ); +int AnyReserveDisplays( void ); +int idleReserveDisplays( void ); +int AllLocalDisplaysLocked( struct display *dp ); +int StartReserveDisplay( int lt ); +void ReapReserveDisplays( void ); + +/* in reset.c */ +void pseudoReset( void ); + +/* in resource.c */ +char **FindCfgEnt( struct display *d, int id ); +int InitResources( char **argv ); +int LoadDMResources( int force ); +int LoadDisplayResources( struct display *d ); +void ScanServers( void ); +void CloseGetter( void ); +int startConfig( int what, CfgDep *dep, int force ); +RcStr *newStr( char *str ); +void delStr( RcStr *str ); +extern GTalk cnftalk; + +/* in session.c */ +extern struct display *td; +extern const char *td_setup; +char **baseEnv( const char *user ); +char **inheritEnv( char **env, const char **what ); +char **systemEnv( const char *user ); +int source( char **env, const char *file, const char *arg ); +void ManageSession( struct display *d ); + +extern GTalk mstrtalk, grttalk; +extern GProc grtproc; +void OpenGreeter( void ); +int CloseGreeter( int force ); +int CtrlGreeterWait( int wreply ); +void PrepErrorGreet( void ); +char *conv_interact( int what, const char *prompt ); + +/* process.c */ +typedef void (*SIGFUNC)( int ); +SIGFUNC Signal( int, SIGFUNC Handler ); + +void RegisterInput( int fd ); +void UnregisterInput( int fd ); +void RegisterCloseOnFork( int fd ); +void ClearCloseOnFork( int fd ); +void CloseNClearCloseOnFork( int fd ); +int Fork( void ); +int Wait4( int pid ); +void execute( char **argv, char **env ); +int runAndWait( char **args, char **env ); +FILE *pOpen( char **what, char m, int *pid ); +int pClose( FILE *f, int pid ); +char *locate( const char *exe ); +void TerminateProcess( int pid, int sig ); + +void GSet( GTalk *talk); /* call before GOpen! */ +int GFork( GPipe *pajp, const char *pname, char *cname, + GPipe *ogp, char *cgname ); +void GClosen( GPipe *pajp ); +int GOpen( GProc *proc, + char **argv, const char *what, char **env, char *cname, + GPipe *gp ); +int GClose( GProc *proc, GPipe *gp, int force ); + +void GSendInt( int val ); +int GRecvInt( void ); +int GRecvCmd( int *cmd ); +void GSendArr( int len, const char *data ); +char *GRecvArr( int *len ); +int GRecvStrBuf( char *buf ); +int GRecvArrBuf( char *buf ); +void GSendStr( const char *buf ); +void GSendNStr( const char *buf, int len ); /* exact len, buf != 0 */ +void GSendStrN( const char *buf, int len ); /* maximal len */ +char *GRecvStr( void ); +void GSendArgv( char **argv ); +void GSendStrArr( int len, char **data ); +char **GRecvStrArr( int *len ); +char **GRecvArgv( void ); + +/* client.c */ +#define GCONV_NORMAL 0 +#define GCONV_HIDDEN 1 +#define GCONV_USER 2 +#define GCONV_PASS 3 +#define GCONV_PASS_ND 4 +#define GCONV_BINARY 5 +typedef char *(*GConvFunc)( int what, const char *prompt ); +int Verify( GConvFunc gconv, int rootok ); +#ifdef WITH_CONSOLE_KIT +int StartClient( const char *ck_session_cookie ); +#else +int StartClient( void ); +#endif +void SessionExit( int status ) ATTR_NORETURN; +int ReadDmrc( void ); +extern char **userEnviron, **systemEnviron; +extern char *curuser, *curpass, *curtype, *newpass, + *dmrcuser, *curdmrc, *newdmrc; +extern int cursource; +#define PWSRC_MANUAL 0 +#define PWSRC_AUTOLOGIN 1 +#define PWSRC_RELOGIN 2 + +/* server.c */ +char **PrepServerArgv( struct display *d, const char *args ); +void StartServer( struct display *d ); +void AbortStartServer( struct display *d ); +void StartServerSuccess( void ); +void StartServerFailed( void ); +void StartServerTimeout( void ); +extern struct display *startingServer; +extern time_t serverTimeout; + +void WaitForServer( struct display *d ); +void ResetServer( struct display *d ); +int PingServer(struct display *d ); +extern Display *dpy; + +/* in util.c */ +void *Calloc( size_t nmemb, size_t size ); +void *Malloc( size_t size ); +void *Realloc( void *ptr, size_t size ); +void WipeStr( char *str ); +int StrCmp( const char *s1, const char *s2 ); +#ifdef HAVE_STRNLEN +# define StrNLen(s, m) strnlen(s, m) +#else +int StrNLen( const char *s, int max ); +#endif +int StrNDup( char **dst, const char *src, int len ); +int StrDup( char **dst, const char *src ); +int arrLen( char **arr ); +void freeStrArr( char **arr ); +char **initStrArr( char **arr ); +char **xCopyStrArr( int rn, char **arr ); +/* Note: the following functions free the old data even in case of failure */ +int ReStrN( char **dst, const char *src, int len ); +int ReStr( char **dst, const char *src ); +int StrApp( char **dst, ... ); +char **addStrArr( char **arr, const char *str, int len ); +char **parseArgs( char **argv, const char *string ); +/* End note */ +char **setEnv( char **e, const char *name, const char *value ); +char **putEnv( const char *string, char **env ); +const char *getEnv( char **e, const char *name ); +const char *localHostname( void ); +int Reader( int fd, void *buf, int len ); +int Writer( int fd, const void *buf, int len ); +int fGets( char *buf, int max, FILE *f ); +void randomStr( char *s ); +time_t mTime( const char *fn ); +void ListSessions( int flags, struct display *d, void *ctx, + void (*emitXSess)( struct display *, struct display *, void * ), + void (*emitTTYSess)( STRUCTUTMP *, struct display *, void * ) ); + +/* in inifile.c */ +char *iniLoad( const char *fname ); +int iniSave( const char *data, const char *fname ); +char *iniEntry( char *data, const char *section, const char *key, const char *value ); +char *iniMerge( char *data, const char *newdata ); + +/* in bootman.c */ +int getBootOptions( char ***opts, int *def, int *cur ); +int setBootOption( const char *opt, SdRec *sdr ); +void commitBootOption( void ); + +/* in netaddr.c */ +char *NetaddrAddress( char *netaddrp, int *lenp ); +char *NetaddrPort( char *netaddrp, int *lenp ); +int ConvertAddr( char *saddr, int *len, char **addr ); +int NetaddrFamily( char *netaddrp ); +int addressEqual( char *a1, int len1, char *a2, int len2 ); + +#ifdef XDMCP + +/* in xdmcp.c */ +char *NetworkAddressToHostname( CARD16 connectionType, ARRAY8Ptr connectionAddress ); +void SendFailed( struct display *d, const char *reason ); +void init_session_id( void ); + +/* in policy.c */ +struct sockaddr; +ARRAY8Ptr Accept( struct sockaddr *from, int fromlen, CARD16 displayNumber ); +ARRAY8Ptr ChooseAuthentication( ARRAYofARRAY8Ptr authenticationNames ); +int CheckAuthentication( struct protoDisplay *pdpy, ARRAY8Ptr displayID, ARRAY8Ptr name, ARRAY8Ptr data ); +int SelectAuthorizationTypeIndex( ARRAY8Ptr authenticationName, ARRAYofARRAY8Ptr authorizationNames ); +int SelectConnectionTypeIndex( ARRAY16Ptr connectionTypes, ARRAYofARRAY8Ptr connectionAddresses ); +int Willing( ARRAY8Ptr addr, CARD16 connectionType, ARRAY8Ptr authenticationName, ARRAY8Ptr status, xdmOpCode type ); + +/* in protodpy.c */ +void DisposeProtoDisplay( struct protoDisplay *pdpy ); + +struct protoDisplay *FindProtoDisplay( XdmcpNetaddr address, int addrlen, + CARD16 displayNumber ); +struct protoDisplay *NewProtoDisplay( XdmcpNetaddr address, int addrlen, + CARD16 displayNumber, + CARD16 connectionType, + ARRAY8Ptr connectionAddress, + CARD32 sessionID ); + +#define FamilyBroadcast 0xffff +typedef void (*ChooserFunc)( CARD16 connectionType, ARRAY8Ptr addr, char *closure ); +typedef void (*ListenFunc)( ARRAY8Ptr addr, void **closure ); + +/* in access.c */ +ARRAY8Ptr getLocalAddress( void ); +int AcceptableDisplayAddress( ARRAY8Ptr clientAddress, CARD16 connectionType, xdmOpCode type ); +int ForEachMatchingIndirectHost( ARRAY8Ptr clientAddress, CARD16 connectionType, ChooserFunc function, char *closure ); +void ScanAccessDatabase( int force ); +int UseChooser( ARRAY8Ptr clientAddress, CARD16 connectionType ); +void ForEachChooserHost( ARRAY8Ptr clientAddress, CARD16 connectionType, ChooserFunc function, char *closure ); +void ForEachListenAddr( ListenFunc listenfunction, ListenFunc mcastfcuntion, void **closure ); + +/* in choose.c */ +ARRAY8Ptr IndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType ); +int IsIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ); +int RememberIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ); +void ForgetIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ); +int RegisterIndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType, ARRAY8Ptr choice ); +int DoChoose( void ); + +/* socket.c or streams.c */ +void UpdateListenSockets( void ); +int AnyListenSockets( void ); +int ProcessListenSockets( FD_TYPE *reads ); + +/* in xdmcp.c */ +void ProcessRequestSocket( int fd ); + +#endif /* XDMCP */ + +/* in sessreg.c */ +void sessreg( struct display *d, int pid, const char *user, int uid ); + +#endif /* _DM_H_ */ diff --git a/tdm/backend/dm_auth.h b/tdm/backend/dm_auth.h new file mode 100644 index 000000000..28725ee8d --- /dev/null +++ b/tdm/backend/dm_auth.h @@ -0,0 +1,105 @@ +/************************************************************ + +Copyright 1998 by Thomas E. Dickey + + All Rights Reserved + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name(s) of the above copyright +holders shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Software without prior written +authorization. + +********************************************************/ + +#ifndef _DM_AUTH_H_ +#define _DM_AUTH_H_ 1 + +#include "dm.h" + +void MitInitAuth( unsigned short name_len, const char *name ); +Xauth *MitGetAuth( unsigned short namelen, const char *name ); + +#ifdef HASXDMAUTH +void XdmInitAuth( unsigned short name_len, const char *name ); +Xauth *XdmGetAuth( unsigned short namelen, const char *name ); +# ifdef XDMCP +void XdmGetXdmcpAuth( struct protoDisplay *pdpy, + unsigned short authorizationNameLen, + const char *authorizationName ); +int XdmCheckAuthentication( struct protoDisplay *pdpy, + ARRAY8Ptr displayID, + ARRAY8Ptr authenticationName, + ARRAY8Ptr authenticationData ); +# else +# define XdmGetXdmcpAuth NULL +# endif +#endif + +#ifdef SECURE_RPC +void SecureRPCInitAuth( unsigned short name_len, const char *name ); +Xauth *SecureRPCGetAuth( unsigned short name_len, const char *name ); +#endif + +#ifdef K5AUTH +void Krb5InitAuth( unsigned short name_len, const char *name ); +Xauth *Krb5GetAuth( unsigned short name_len, const char *name ); + +Xauth *Krb5GetAuthFor( unsigned short name_len, const char *name, const char *dname ); +char *Krb5Init( const char *user, const char *passwd, const char *dname ); +void Krb5Destroy( const char *dname ); +#endif + +/* auth.c */ +int ValidAuthorization( unsigned short name_length, const char *name ); + + +#ifdef XDMCP + +void +SetProtoDisplayAuthorization( struct protoDisplay *pdpy, + unsigned short authorizationNameLen, + const char *authorizationName ); + +#endif /* XDMCP */ + +int SaveServerAuthorizations( struct display *d, Xauth **auths, int count ); +void CleanUpFileName( const char *src, char *dst, int len ); +void RemoveUserAuthorization( struct display *d ); +void SetAuthorization( struct display *d ); +void SetLocalAuthorization( struct display *d ); +void SetUserAuthorization( struct display *d ); + +/* genauth.c */ +int GenerateAuthData( char *auth, int len ); +#ifdef NEED_ENTROPY +void AddPreGetEntropy( void ); +void AddOtherEntropy( void ); +void AddTimerEntropy( void ); +#endif + +#ifdef HAVE_ARC4RANDOM +# define secureRandom() arc4random() +#else +int secureRandom( void ); +#endif + +#endif /* _DM_AUTH_H_ */ diff --git a/tdm/backend/dm_error.h b/tdm/backend/dm_error.h new file mode 100644 index 000000000..3570c18fc --- /dev/null +++ b/tdm/backend/dm_error.h @@ -0,0 +1,58 @@ +/************************************************************ + +Copyright 1998 by Thomas E. Dickey + + All Rights Reserved + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name(s) of the above copyright +holders shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Software without prior written +authorization. + +********************************************************/ + + +#ifndef _DM_ERROR_H_ +#define _DM_ERROR_H_ 1 + +#include "greet.h" + +#include + +void GDebug( const char *fmt, ... ); +void Debug( const char *fmt, ... ); +void LogInfo( const char *fmt, ... ); +void LogWarn( const char *fmt, ... ); +void LogError( const char *fmt, ... ); +void LogPanic( const char *fmt, ... ) ATTR_NORETURN; +void LogOutOfMem( void ); +void Panic( const char *mesg ) ATTR_NORETURN; +void InitErrorLog( const char *errorLogFile ); +#ifdef USE_SYSLOG +void ReInitErrorLog( void ); +#else +# define ReInitErrorLog() while(0) +#endif +int ASPrintf( char **strp, const char *fmt, ... ); +int VASPrintf( char **strp, const char *fmt, va_list args ); + +#endif /* _DM_ERROR_H_ */ diff --git a/tdm/backend/dm_socket.h b/tdm/backend/dm_socket.h new file mode 100644 index 000000000..56a39fd0e --- /dev/null +++ b/tdm/backend/dm_socket.h @@ -0,0 +1,72 @@ +/************************************************************ + +Copyright 1998 by Thomas E. Dickey +Copyright 2002-2004 Oswald Buddenhagen + + All Rights Reserved + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name(s) of the above copyright +holders shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Software without prior written +authorization. + +********************************************************/ + +#ifndef _DM_SOCKET_H_ +#define _DM_SOCKET_H_ 1 + +#ifndef __Lynx__ +# include +#else +# include +#endif + +#ifdef TCPCONN +# include +#endif + +#ifdef UNIXCONN +# ifndef __Lynx__ +# include +# else +# include +# endif +#endif + +#ifdef DNETCONN +# include +#endif + +#if (defined(__svr4__) && !defined(__sun__)) && defined(SIOCGIFCONF) +# define SYSV_SIOCGIFCONF +int ifioctl( int fd, int cmd, char *arg ); +#else +# define ifioctl ioctl +#endif + +#ifdef BSD +# if (BSD >= 199103) +# define VARIABLE_IFREQ +# endif +#endif + +#endif /* _DM_SOCKET_H_ */ diff --git a/tdm/backend/dpylist.c b/tdm/backend/dpylist.c new file mode 100644 index 000000000..b512293f7 --- /dev/null +++ b/tdm/backend/dpylist.c @@ -0,0 +1,294 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2000-2005 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * a simple linked list of known displays + */ + +#include "dm.h" +#include "dm_error.h" + +struct display *displays; +static struct disphist *disphist; + +int +AnyDisplaysLeft( void ) +{ + return displays != (struct display *)0; +} + +int +AnyActiveDisplays( void ) +{ + struct display *d; + + for (d = displays; d; d = d->next) + if (d->status == remoteLogin || d->userSess >= 0) + return 1; + return 0; +} + +int +AnyRunningDisplays( void ) +{ + struct display *d; + + for (d = displays; d; d = d->next) + switch (d->status) { + case notRunning: + case textMode: + case reserve: + break; + default: + return 1; + } + return 0; +} + +int +AnyReserveDisplays( void ) +{ + struct display *d; + + for (d = displays; d; d = d->next) + if ((d->displayType & d_lifetime) == dReserve) + return 1; + return 0; +} + +int +idleReserveDisplays( void ) +{ + struct display *d; + int cnt = 0; + + for (d = displays; d; d = d->next) + if (d->status == reserve) + cnt++; + return cnt; +} + +int +StartReserveDisplay( int lt ) +{ + struct display *d, *rd; + + for (rd = 0, d = displays; d; d = d->next) + if (d->status == reserve) + rd = d; + if (rd) { + rd->idleTimeout = lt; + rd->status = notRunning; + return 1; + } + return 0; +} + +void +ForEachDisplay( void (*f)( struct display * ) ) +{ + struct display *d, *next; + + for (d = displays; d; d = next) { + next = d->next; + (*f)( d ); + } +} + +#ifdef HAVE_VTS +static void +_forEachDisplayRev( struct display *d, void (*f)( struct display * ) ) +{ + if (d) { + if (d->next) + _forEachDisplayRev( d->next, f ); + (*f)( d ); + } +} + +void +ForEachDisplayRev( void (*f)( struct display * ) ) +{ + _forEachDisplayRev( displays, f ); +} +#endif + +struct display * +FindDisplayByName( const char *name ) +{ + struct display *d; + + for (d = displays; d; d = d->next) + if (!strcmp( name, d->name )) + return d; + return 0; +} + +struct display * +FindDisplayByPid( int pid ) +{ + struct display *d; + + for (d = displays; d; d = d->next) + if (pid == d->pid) + return d; + return 0; +} + +struct display * +FindDisplayByServerPid( int serverPid ) +{ + struct display *d; + + for (d = displays; d; d = d->next) + if (serverPid == d->serverPid) + return d; + return 0; +} + +#ifdef XDMCP + +struct display * +FindDisplayBySessionID( CARD32 sessionID ) +{ + struct display *d; + + for (d = displays; d; d = d->next) + if (sessionID == d->sessionID) + return d; + return 0; +} + +struct display * +FindDisplayByAddress( XdmcpNetaddr addr, int addrlen, CARD16 displayNumber ) +{ + struct display *d; + + for (d = displays; d; d = d->next) + if ((d->displayType & d_origin) == dFromXDMCP && + d->displayNumber == displayNumber && + addressEqual( (XdmcpNetaddr)d->from.data, d->from.length, + addr, addrlen )) + return d; + return 0; +} + +#endif /* XDMCP */ + +#define IfFree(x) if (x) free( (char *)x ) + +void +RemoveDisplay( struct display *old ) +{ + struct display *d, **dp; + int i; + + for (dp = &displays; (d = *dp); dp = &(*dp)->next) { + if (d == old) { + Debug( "Removing display %s\n", d->name ); + *dp = d->next; + IfFree( d->class2 ); + IfFree( d->cfg.data ); + delStr( d->cfg.dep.name ); +#ifdef XDMCP + IfFree( d->remoteHost ); +#endif + if (d->authorizations) { + for (i = 0; i < d->authNum; i++) + XauDisposeAuth( d->authorizations[i] ); + free( (char *)d->authorizations ); + } + if (d->authFile) { + (void)unlink( d->authFile ); + free( d->authFile ); + } + IfFree( d->authNameLens ); +#ifdef XDMCP + XdmcpDisposeARRAY8( &d->peer ); + XdmcpDisposeARRAY8( &d->from ); + XdmcpDisposeARRAY8( &d->clientAddr ); +#endif + free( (char *)d ); + break; + } + } +} + +static struct disphist * +FindHist( const char *name ) +{ + struct disphist *hstent; + + for (hstent = disphist; hstent; hstent = hstent->next) + if (!strcmp( hstent->name, name )) + return hstent; + return 0; +} + +struct display * +NewDisplay( const char *name ) +{ + struct display *d; + struct disphist *hstent; + + if (!(hstent = FindHist( name ))) { + if (!(hstent = Calloc( 1, sizeof(*hstent) ))) + return 0; + if (!StrDup( &hstent->name, name )) { + free( hstent ); + return 0; + } + hstent->next = disphist; disphist = hstent; + } + + if (!(d = (struct display *)Calloc( 1, sizeof(*d) ))) + return 0; + d->next = displays; + d->hstent = hstent; + d->name = hstent->name; + /* initialize fields (others are 0) */ + d->pid = -1; + d->serverPid = -1; + d->ctrl.fd = -1; + d->ctrl.fifo.fd = -1; + d->pipe.rfd = -1; + d->pipe.wfd = -1; + d->gpipe.rfd = -1; + d->gpipe.wfd = -1; + d->userSess = -1; +#ifdef XDMCP + d->xdmcpFd = -1; +#endif + displays = d; + Debug( "created new display %s\n", d->name ); + return d; +} diff --git a/tdm/backend/error.c b/tdm/backend/error.c new file mode 100644 index 000000000..93ec40e70 --- /dev/null +++ b/tdm/backend/error.c @@ -0,0 +1,130 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2000-2004 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * Log display manager errors to a file as + * we generally do not have a terminal to talk to + * or use syslog if it exists + */ + +#include "dm.h" +#include "dm_error.h" + +#include +#include + +#define PRINT_QUOTES +#define PRINT_ARRAYS +#define LOG_DEBUG_MASK DEBUG_CORE +#define LOG_PANIC_EXIT 1 +#define NEED_ASPRINTF +#define STATIC +#include "printf.c" + +void +GDebug( const char *fmt, ... ) +{ + va_list args; + + if (debugLevel & DEBUG_HLPCON) { + va_start( args, fmt ); + Logger( DM_DEBUG, fmt, args ); + va_end( args ); + } +} + +void +Panic( const char *mesg ) +{ + int fd = open( "/dev/console", O_WRONLY ); + write( fd, "xdm panic: ", 11 ); + write( fd, mesg, strlen( mesg ) ); + write( fd, "\n", 1 ); +#ifdef USE_SYSLOG + ReInitErrorLog(); + syslog( LOG_ALERT, "%s", mesg ); +#endif + exit( 1 ); +} + +#ifdef USE_SYSLOG +void +ReInitErrorLog() +{ + if (!(debugLevel & DEBUG_NOSYSLOG)) + InitLog(); +} +#endif + +void +InitErrorLog( const char *errorLogFile ) +{ + int fd; + char buf[128]; + +#ifdef USE_SYSLOG + ReInitErrorLog(); +#endif + /* We do this independently of using syslog, as we cannot redirect + * the output of external programs to syslog. + */ + if (!errorLogFile || strcmp( errorLogFile, "-" )) { + if (!errorLogFile) { + sprintf( buf, "/var/log/%s.log", prog ); + errorLogFile = buf; + } + if ((fd = open( errorLogFile, O_CREAT | O_APPEND | O_WRONLY, 0666 )) < 0) + LogError( "Cannot open log file %s\n", errorLogFile ); + else { +#ifdef USE_SYSLOG +# ifdef USE_PAM +# define PAMLOG " PAM logs messages related to authentication to authpriv.*." +# else +# define PAMLOG +# endif +# define WARNMSG \ + "********************************************************************************\n" \ + "Note that your system uses syslog. All of tdm's internally generated messages\n" \ + "(i.e., not from libraries and external programs/scripts it uses) go to the\n" \ + "daemon.* syslog facility; check your syslog configuration to find out to which\n" \ + "file(s) it is logged." PAMLOG "\n" \ + "********************************************************************************\n\n" + if (!lseek( fd, 0, SEEK_END )) + write( fd, WARNMSG, sizeof(WARNMSG) - 1 ); +#endif + dup2( fd, 1 ); + close( fd ); + dup2( 1, 2 ); + } + } +} + diff --git a/tdm/backend/genauth.c b/tdm/backend/genauth.c new file mode 100644 index 000000000..6da95cce0 --- /dev/null +++ b/tdm/backend/genauth.c @@ -0,0 +1,500 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2003-2004 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + */ + +#include "dm.h" +#include "dm_auth.h" +#include "dm_error.h" + +#ifdef NEED_ENTROPY + +# include + +/* ####################################################################### */ + +/* + * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. + * Copyright (c) 2001-2002 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "dm_socket.h" + +#include + +#ifndef INADDR_LOOPBACK +# define INADDR_LOOPBACK 0x7F000001U +#endif + +#ifndef offsetof +# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +static int +getPrngdBytes( char *buf, int len, + unsigned short tcp_port, const char *socket_path ) +{ + int fd, addr_len, rval, errors; + char msg[2]; + struct sockaddr *addr; + struct sockaddr_in addr_in; + struct sockaddr_un addr_un; + int af; + SIGFUNC old_sigpipe; + + if (tcp_port) { + memset( &addr_in, 0, sizeof(addr_in) ); + af = addr_in.sin_family = AF_INET; + addr_in.sin_addr.s_addr = htonl( INADDR_LOOPBACK ); + addr_in.sin_port = htons( tcp_port ); + addr_len = sizeof(addr_in); + addr = (struct sockaddr *)&addr_in; + } else if (*socket_path) { + unsigned spl = strlen( socket_path ); + if (spl >= sizeof(addr_un.sun_path)) { + LogError( "get_random_prngd: " + "Random pool path is too long\n" ); + return -1; + } + af = addr_un.sun_family = AF_UNIX; + strncpy( addr_un.sun_path, socket_path, + sizeof(addr_un.sun_path) ); + addr_len = offsetof( struct sockaddr_un, sun_path ) + spl + 1; + addr = (struct sockaddr *)&addr_un; + } else + return -1; + + old_sigpipe = Signal( SIGPIPE, SIG_IGN ); + + errors = 0; + rval = -1; +reopen: + if ((fd = socket( af, SOCK_STREAM, 0 )) < 0) { + LogError( "Couldn't create socket: %m\n" ); + goto done; + } + + if (connect( fd, (struct sockaddr *)addr, addr_len )) { + if (af == AF_INET) + LogError( "Couldn't connect to PRNGD port %d: %m\n", + tcp_port ); + else + LogError( "Couldn't connect to PRNGD socket %\"s: %m\n", + socket_path ); + goto done; + } + + /* Send blocking read request to PRNGD */ + msg[0] = 0x02; + msg[1] = len; + + if (Writer( fd, msg, sizeof(msg) ) != sizeof(msg)) { + if (errno == EPIPE && errors < 10) { + close( fd ); + errors++; + goto reopen; + } + LogError( "Couldn't write to PRNGD socket: %m\n" ); + goto done; + } + + if (Reader( fd, buf, len ) != len) { + if (errno == EPIPE && errors < 10) { + close( fd ); + errors++; + goto reopen; + } + LogError( "Couldn't read from PRNGD socket: %m\n" ); + goto done; + } + + rval = 0; +done: + Signal( SIGPIPE, old_sigpipe ); + if (fd != -1) + close( fd ); + return rval; +} + +/* ####################################################################### */ + +/* + * Stolen from the Linux kernel. + * + * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All + * rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +static unsigned epool[32], erotate, eadd_ptr; + +static void +add_entropy( unsigned const *in, int nwords ) +{ + static unsigned const twist_table[8] = { + 0, 0x3b6e20c8, 0x76dc4190, 0x4db26158, + 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; + unsigned i, w; + int new_rotate; + + while (nwords--) { + w = *in++; + w = (w<>(32-erotate)) & 0xffffffff; + i = eadd_ptr = (eadd_ptr - 1) & 31; + new_rotate = erotate + 14; + if (i) + new_rotate = erotate + 7; + erotate = new_rotate & 31; + w ^= epool[(i + 26) & 31]; + w ^= epool[(i + 20) & 31]; + w ^= epool[(i + 14) & 31]; + w ^= epool[(i + 7) & 31]; + w ^= epool[(i + 1) & 31]; + w ^= epool[i]; + epool[i] = (w >> 3) ^ twist_table[w & 7]; + } +} + +/* ####################################################################### */ + +/* + * This code implements something close to the MD5 message-digest + * algorithm. This code is based on code written by Colin Plumb + * in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + */ + +/* The four core functions - F1 is optimized somewhat */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1 (z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define pmd5_step(f, w, x, y, z, data, s) \ + (w += (f(x, y, z) + data) & 0xffffffff, w = w<>(32-s), w += x) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. + */ +static void +pmd5_hash( unsigned *out, unsigned const in[16] ) +{ + unsigned a, b, c, d; + + a = out[0]; + b = out[1]; + c = out[2]; + d = out[3]; + + pmd5_step( F1, a, b, c, d, in[0] + 0xd76aa478, 7 ); + pmd5_step( F1, d, a, b, c, in[1] + 0xe8c7b756, 12 ); + pmd5_step( F1, c, d, a, b, in[2] + 0x242070db, 17 ); + pmd5_step( F1, b, c, d, a, in[3] + 0xc1bdceee, 22 ); + pmd5_step( F1, a, b, c, d, in[4] + 0xf57c0faf, 7 ); + pmd5_step( F1, d, a, b, c, in[5] + 0x4787c62a, 12 ); + pmd5_step( F1, c, d, a, b, in[6] + 0xa8304613, 17 ); + pmd5_step( F1, b, c, d, a, in[7] + 0xfd469501, 22 ); + pmd5_step( F1, a, b, c, d, in[8] + 0x698098d8, 7 ); + pmd5_step( F1, d, a, b, c, in[9] + 0x8b44f7af, 12 ); + pmd5_step( F1, c, d, a, b, in[10] + 0xffff5bb1, 17 ); + pmd5_step( F1, b, c, d, a, in[11] + 0x895cd7be, 22 ); + pmd5_step( F1, a, b, c, d, in[12] + 0x6b901122, 7 ); + pmd5_step( F1, d, a, b, c, in[13] + 0xfd987193, 12 ); + pmd5_step( F1, c, d, a, b, in[14] + 0xa679438e, 17 ); + pmd5_step( F1, b, c, d, a, in[15] + 0x49b40821, 22 ); + + pmd5_step( F2, a, b, c, d, in[1] + 0xf61e2562, 5 ); + pmd5_step( F2, d, a, b, c, in[6] + 0xc040b340, 9 ); + pmd5_step( F2, c, d, a, b, in[11] + 0x265e5a51, 14 ); + pmd5_step( F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20 ); + pmd5_step( F2, a, b, c, d, in[5] + 0xd62f105d, 5 ); + pmd5_step( F2, d, a, b, c, in[10] + 0x02441453, 9 ); + pmd5_step( F2, c, d, a, b, in[15] + 0xd8a1e681, 14 ); + pmd5_step( F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20 ); + pmd5_step( F2, a, b, c, d, in[9] + 0x21e1cde6, 5 ); + pmd5_step( F2, d, a, b, c, in[14] + 0xc33707d6, 9 ); + pmd5_step( F2, c, d, a, b, in[3] + 0xf4d50d87, 14 ); + pmd5_step( F2, b, c, d, a, in[8] + 0x455a14ed, 20 ); + pmd5_step( F2, a, b, c, d, in[13] + 0xa9e3e905, 5 ); + pmd5_step( F2, d, a, b, c, in[2] + 0xfcefa3f8, 9 ); + pmd5_step( F2, c, d, a, b, in[7] + 0x676f02d9, 14 ); + pmd5_step( F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20 ); + + pmd5_step( F3, a, b, c, d, in[5] + 0xfffa3942, 4 ); + pmd5_step( F3, d, a, b, c, in[8] + 0x8771f681, 11 ); + pmd5_step( F3, c, d, a, b, in[11] + 0x6d9d6122, 16 ); + pmd5_step( F3, b, c, d, a, in[14] + 0xfde5380c, 23 ); + pmd5_step( F3, a, b, c, d, in[1] + 0xa4beea44, 4 ); + pmd5_step( F3, d, a, b, c, in[4] + 0x4bdecfa9, 11 ); + pmd5_step( F3, c, d, a, b, in[7] + 0xf6bb4b60, 16 ); + pmd5_step( F3, b, c, d, a, in[10] + 0xbebfbc70, 23 ); + pmd5_step( F3, a, b, c, d, in[13] + 0x289b7ec6, 4 ); + pmd5_step( F3, d, a, b, c, in[0] + 0xeaa127fa, 11 ); + pmd5_step( F3, c, d, a, b, in[3] + 0xd4ef3085, 16 ); + pmd5_step( F3, b, c, d, a, in[6] + 0x04881d05, 23 ); + pmd5_step( F3, a, b, c, d, in[9] + 0xd9d4d039, 4 ); + pmd5_step( F3, d, a, b, c, in[12] + 0xe6db99e5, 11 ); + pmd5_step( F3, c, d, a, b, in[15] + 0x1fa27cf8, 16 ); + pmd5_step( F3, b, c, d, a, in[2] + 0xc4ac5665, 23 ); + + pmd5_step( F4, a, b, c, d, in[0] + 0xf4292244, 6 ); + pmd5_step( F4, d, a, b, c, in[7] + 0x432aff97, 10 ); + pmd5_step( F4, c, d, a, b, in[14] + 0xab9423a7, 15 ); + pmd5_step( F4, b, c, d, a, in[5] + 0xfc93a039, 21 ); + pmd5_step( F4, a, b, c, d, in[12] + 0x655b59c3, 6 ); + pmd5_step( F4, d, a, b, c, in[3] + 0x8f0ccc92, 10 ); + pmd5_step( F4, c, d, a, b, in[10] + 0xffeff47d, 15 ); + pmd5_step( F4, b, c, d, a, in[1] + 0x85845dd1, 21 ); + pmd5_step( F4, a, b, c, d, in[8] + 0x6fa87e4f, 6 ); + pmd5_step( F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10 ); + pmd5_step( F4, c, d, a, b, in[6] + 0xa3014314, 15 ); + pmd5_step( F4, b, c, d, a, in[13] + 0x4e0811a1, 21 ); + pmd5_step( F4, a, b, c, d, in[4] + 0xf7537e82, 6 ); + pmd5_step( F4, d, a, b, c, in[11] + 0xbd3af235, 10 ); + pmd5_step( F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15 ); + pmd5_step( F4, b, c, d, a, in[9] + 0xeb86d391, 21 ); + + out[0] += a; + out[1] += b; + out[2] += c; + out[3] += d; +} + +/* ####################################################################### */ + + +static int +sumFile( const char *name, int len, int whence, long offset ) +{ + int fd, i, cnt, readlen = 0; + unsigned char buf[0x1000]; + + if ((fd = open( name, O_RDONLY )) < 0) { + Debug( "cannot open entropy source %\"s: %m\n", name ); + return -1; + } + lseek( fd, offset, whence ); + while (readlen < len) { + if (!(cnt = read( fd, buf, sizeof(buf) ))) + break; + if (cnt < 0) { + close( fd ); + Debug( "cannot read entropy source %\"s: %m\n", name ); + return -1; + } + readlen += cnt; + if (sizeof(unsigned) == 4) + add_entropy( (unsigned *)buf, (cnt + 3) / 4 ); + else { + unsigned buf2[sizeof(buf) / 4]; + for (i = 0; i < cnt; i += 8) { + buf2[i / 4] = *(unsigned *)(buf + i) & 0xffffffff; + buf2[i / 4 + 1] = *(unsigned *)(buf + i) >> 32; + } + add_entropy( buf2, (cnt + 3) / 4 ); + } + } + close( fd ); + Debug( "read %d bytes from entropy source %\"s\n", readlen, name ); + return readlen; +} + +void +AddTimerEntropy( void ) +{ + struct timeval now; + gettimeofday( &now, 0 ); + add_entropy( (unsigned *)&now, sizeof(now)/sizeof(unsigned) ); +} + +#define BSIZ 0x10000 + +void +AddOtherEntropy( void ) +{ + AddTimerEntropy(); + /* XXX -- setup-specific ... use some common ones */ + sumFile( "/var/log/messages", 0x1000, SEEK_END, -0x1000 ); + sumFile( "/var/log/syslog", 0x1000, SEEK_END, -0x1000 ); + sumFile( "/var/log/debug", 0x1000, SEEK_END, -0x1000 ); + sumFile( "/var/log/kern.log", 0x1000, SEEK_END, -0x1000 ); + sumFile( "/var/log/daemon.log", 0x1000, SEEK_END, -0x1000 ); +/* root hardly ever has an own box ... maybe pick a random mailbox instead? eek ... + sumFile( "/var/spool/mail/root", 0x1000, SEEK_END, -0x1000 ); +*/ +} + +void +AddPreGetEntropy( void ) +{ + static long offset; + int readlen; + + AddTimerEntropy(); + if ((readlen = sumFile( randomFile, BSIZ, SEEK_SET, offset )) == BSIZ) { + offset += readlen; +#if defined(__i386__) || defined(amiga) + if (!strcmp( randomFile, "/dev/mem" )) { + if (offset == 0xa0000) /* skip 640kB-1MB ROM mappings */ + offset = 0x100000; + else if (offset == 0xf00000) /* skip 15-16MB memory hole */ + offset = 0x1000000; + } +#endif + return; + } else if (readlen >= 0 && offset) { + if ((offset = sumFile( randomFile, BSIZ, SEEK_SET, 0 )) == BSIZ) + return; + } + LogError( "Cannot read randomFile %\"s; " + "X cookies may be easily guessable\n", randomFile ); +} +#endif + +/* ONLY 8 or 16 bytes! */ +/* auth MUST be sizeof(unsigned)-aligned! */ +int +GenerateAuthData( char *auth, int len ) +{ +#ifdef HAVE_ARC4RANDOM + int i; + unsigned *rnd = (unsigned *)auth; + if (sizeof(unsigned) == 4) + for (i = 0; i < len; i += 4) + rnd[i / 4] = arc4random(); + else + for (i = 0; i < len; i += 8) + rnd[i / 8] = arc4random() | (arc4random() << 32); + return 1; +#else + int fd; + const char *rd = randomDevice; +# ifdef DEV_RANDOM + if (!*rd) + rd = DEV_RANDOM; +# else + if (*rd) { +# endif + if ((fd = open( rd, O_RDONLY )) >= 0) { + if (read( fd, auth, len ) == len) { + close( fd ); + return 1; + } + close( fd ); + LogError( "Cannot read randomDevice %\"s: %m\n", rd ); + } else + LogError( "Cannot open randomDevice %\"s: %m\n", rd ); +# ifdef DEV_RANDOM + return 0; +# else + } + + if (!getPrngdBytes( auth, len, prngdPort, prngdSocket )) + return 1; + + { + unsigned *rnd = (unsigned *)auth; + unsigned tmp[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + AddPreGetEntropy(); + pmd5_hash( tmp, epool ); + add_entropy( tmp, 1 ); + pmd5_hash( tmp, epool + 16 ); + add_entropy( tmp + 2, 1 ); + if (sizeof(unsigned) == 4) + memcpy( auth, tmp, len ); + else { + int i; + for (i = 0; i < len; i += 8) + rnd[i / 8] = tmp[i / 4] | (tmp[i / 4 + 1] << 32); + } + } + return 1; +# endif +#endif +} + +#ifndef HAVE_ARC4RANDOM +int +secureRandom( void ) +{ + int rslt; + GenerateAuthData( (char *)&rslt, sizeof(int) ); + return rslt & 0x7fffffff; +} +#endif \ No newline at end of file diff --git a/tdm/backend/greet.h b/tdm/backend/greet.h new file mode 100644 index 000000000..985edc29c --- /dev/null +++ b/tdm/backend/greet.h @@ -0,0 +1,278 @@ +/* + +Copyright 2001-2005 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * interface to xdm's external greeter and config reader + */ + +#ifndef GREET_H +#define GREET_H + +#include + +#define DEBUG_CORE 0x01 +#define DEBUG_CONFIG 0x02 +#define DEBUG_GREET 0x04 +#define DEBUG_HLPCON 0x08 +#define DEBUG_WSESS 0x10 +#define DEBUG_WCONFIG 0x20 +#define DEBUG_WGREET 0x40 +#define DEBUG_NOSYSLOG 0x80 +#define DEBUG_AUTH 0x100 +#define DEBUG_VALGRIND 0x400 +#define DEBUG_STRACE 0x800 + +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +# define ATTR_UNUSED __attribute__((unused)) +# define ATTR_NORETURN __attribute__((noreturn)) +# define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var))) +#else +# define ATTR_UNUSED +# define ATTR_NORETURN +# define ATTR_PRINTFLIKE(fmt,var) +#endif + +#define as(ar) ((int)(sizeof(ar)/sizeof(ar[0]))) + +#define __stringify(x) #x +#define stringify(x) __stringify(x) + +/* + * Exit codes for fork()ed session process, greeter, and config reader + */ +#define EX_NORMAL 30 /* do whatever seems appropriate */ +#define EX_REMANAGE_DPY 31 /* force remanage; same as EX_NORMAL, but cannot return to reserve mode immediately */ +#define EX_UNMANAGE_DPY 32 /* force deletion */ +#define EX_RESERVER_DPY 33 /* force server termination */ +#define EX_AL_RESERVER_DPY 34 /* reserver; maybe, auto-(re-)login */ +#define EX_OPENFAILED_DPY 35 /* XOpenDisplay failed, retry */ +#define EX_RESERVE 37 /* put in reserve mode */ +#ifdef XDMCP +#define EX_REMOTE 38 /* start -query-ing X-server */ +#define EX_MAX EX_REMOTE +#else +#define EX_MAX EX_RESERVE +#endif + +/* + * Command codes core -> greeter + */ +#define G_Greet 1 /* get login; bidi */ +#define G_ErrorGreet 2 /* print failed auto-login */ +#ifdef XDMCP +#define G_Choose 3 /* run chooser; bidi */ +# define G_Ch_AddHost 301 +# define G_Ch_ChangeHost 302 +# define G_Ch_RemoveHost 303 +# define G_Ch_BadHost 304 +# define G_Ch_Exit 305 +#endif +#define G_SessMan 4 /* start "session manager" */ +#define G_ConfShutdown 5 /* confirm forced shutdown */ +#define G_GreetTimed 6 /* get login; timed login permitted */ + +#ifdef XDMCP +#define G_Ch_Refresh 10 /* XXX change */ +#define G_Ch_RegisterHost 11 /* str name XXX change */ +#define G_Ch_DirectChoice 12 /* str name XXX change */ +#endif + +/* + * Status/command codes greeter -> core + */ +#define G_Ready 0 /* nop */ +#define G_Cancel 1 /* abort login, etc. */ + +#define G_DGreet 2 /* get login */ +#ifdef XDMCP +#define G_DChoose 3 /* run chooser */ +#endif + +#define G_Shutdown 101 /* 5*int, string; async */ +# define SHUT_REBOOT 1 /* how */ +# define SHUT_HALT 2 +# define SHUT_CONSOLE -1 /* pseudo-code */ +# define SHUT_SCHEDULE 0 /* when; config only */ +# define SHUT_TRYNOW 1 +# define SHUT_FORCENOW 2 +# define SHUT_CANCEL 0 /* force */ +# define SHUT_FORCEMY 1 +# define SHUT_FORCE 2 +# define SHUT_ASK 3 +# define TO_INF 0x7fffffff +#define G_SessionExit 102 /* int code; async */ +#define G_GetCfg 103 /* int what; int sts, */ +#define G_SetupDpy 104 /* ; int */ +#define G_ReadDmrc 105 /* str user; int sts - curdmrc */ +#define G_GetDmrc 106 /* str key; str value - curdmrc */ +/*#define G_ResetDmrc 107*/ /* ; async - newdmrc */ +#define G_PutDmrc 108 /* str key, str value; async - newdmrc */ +#define G_Verify 109 /* str type; ..., int V_ret */ +#define G_VerifyRootOK 110 /* str type; ..., int V_ret */ +#define G_List 111 /* int flags; ?*(str,str,[int,]str,str,int), int 0 */ +# define lstRemote 1 +# define lstPassive 2 +# define lstTTY 4 +# define isSelf 1 +# define isTTY 2 +#define G_QueryShutdown 112 /* ; 5*int; string */ +#define G_Activate 113 /* int vt; async */ +#define G_ListBootOpts 114 /* ; int sts, [argv opts, int dflt, int cur] */ +# define BO_OK 0 +# define BO_NOMAN -1 +# define BO_NOENT -2 +# define BO_IO -3 +#define G_Console 116 /* ; async */ +#define G_AutoLogin 117 /* ; async */ + +/* + * Command codes core -> config reader + */ +#define GC_Files 1 /* get file list */ +#define GC_GetConf 2 /* get a config group */ +# define GC_gGlobal 1 /* get global config array */ +#ifdef XDMCP +# define GC_gXaccess 3 /* get Xaccess equivalent */ +#endif +# define GC_gDisplay 4 /* get per-display config array */ + +/* + * Error code core -> greeter + */ +#define GE_Ok 0 +#define GE_NoFkt 1 /* no such function (only for extensions!) */ +#define GE_Error 2 /* internal error, like OOM */ +/* for config reading */ +#define GE_NoEnt 10 /* no such config entry */ +#define GE_BadType 11 /* unknown config entry type */ +/* for dmrc reading */ +#define GE_NoUser 20 /* no such user */ +#define GE_NoFile 21 /* no such file */ +#define GE_Denied 22 /* permission denied */ + +/* + * Log levels. + * Used independently in core, greeter & config reader. + */ +#define DM_DEBUG 0 +#define DM_INFO 1 +#define DM_WARN 2 +#define DM_ERR 3 +#define DM_PANIC 4 + +/* + * Status codes from Verify + */ +/* terminal status codes */ +#define V_OK 0 +#define V_FAIL 10 /* whatever, already reported with V_MSG_* */ +#define V_AUTH 11 /* authentication failed */ +/* non-terminal status codes */ +#define V_MSG_INFO 110 /* info message attached */ +#define V_MSG_ERR 111 /* error message attached (null for generic) */ +#define V_PUT_USER 112 /* user name attached; only with pam & no user send */ +#define V_CHTOK 113 /* password expired; change now */ +#define V_CHTOK_AUTH 114 /* password expired; change now, but authenticate first */ +#define V_PRE_OK 115 /* authentication succeeded, continue with password change */ +/* queries */ +#define V_GET_TEXT 200 /* str prompt, int echo, int ndelay; str return, int tag */ +# define V_IS_SECRET 1 +# define V_IS_USER 2 +# define V_IS_PASSWORD 4 +# define V_IS_OLDPASSWORD 8 +# define V_IS_NEWPASSWORD 16 +#define V_GET_BINARY 201 /* array prompt, int ndelay; array return */ + +/* + * Config/Runtime data keys + */ +#define C_WHO_MASK 0x00ff0000 /* Non-zero for proprietary extensions (see manufacturer table [to be written]) */ +#define C_TYPE_MASK 0x0f000000 /* Type of the value */ +# define C_TYPE_INT 0x00000000 /* Integer */ +# define C_TYPE_STR 0x01000000 /* String */ +# define C_TYPE_ARGV 0x02000000 /* 0-terminated Array of Strings */ +# define C_TYPE_ARR 0x03000000 /* Array (only when XDCMP is enabled) */ +#define C_PRIVATE 0xf0000000 /* Private, don't make it visible to interfaces! */ + +/* display variables */ +#define C_isLocal (C_TYPE_INT | 0x200) +#define C_hasConsole (C_TYPE_INT | 0x201) +#define C_isAuthorized (C_TYPE_INT | 0x202) + +/** + ** for struct display + **/ + +#define d_location 1 +#define dLocal 1 /* server runs on local host */ +#define dForeign 0 /* server runs on remote host */ + +#define d_lifetime 6 +#define dPermanent 4 /* display restarted when session exits */ +#define dReserve 2 /* display not restarted when session exits */ +#define dTransient 0 /* display removed when session exits */ + +#ifdef XDMCP +#define d_origin 8 +#else +#define d_origin 0 /* clever, huh? :) */ +#endif +#define dFromXDMCP 8 /* started with XDMCP */ +#define dFromFile 0 /* started via entry in servers file */ + +#ifdef XDMCP +/** + ** for xdmcp acls + **/ + +/* + * flags in acl entries + */ +#define a_notAllowed 1 /* both direct and indirect */ +#define a_notBroadcast 2 /* only direct */ +#define a_useChooser 2 /* only indirect */ + +/* + * type of host entries + */ +#define HOST_ALIAS 0 +#define HOST_ADDRESS 1 +#define HOST_PATTERN 2 +#define HOST_BROADCAST 3 + +#endif + +#endif /* GREET_H */ diff --git a/tdm/backend/inifile.c b/tdm/backend/inifile.c new file mode 100644 index 000000000..b5426de75 --- /dev/null +++ b/tdm/backend/inifile.c @@ -0,0 +1,255 @@ +/* + +Copyright 2003 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * load, save and manipulate ini-style config files + */ + +#include "dm.h" +#include "dm_error.h" + +#include +#include +#include +#include +#include +#include + +char * +iniLoad( const char *fname ) +{ + char *data; + int fd, len; + struct stat st; + + if ((fd = open( fname, O_RDONLY | O_NONBLOCK )) < 0) { + Debug( "cannot open ini-file %\"s: %m", fname ); + return 0; + } + if (fstat( fd, &st ) || !S_ISREG( st.st_mode )) { + LogWarn( "Ini-file %\"s is no regular file\n", fname ); + close( fd ); + return 0; + } + if (st.st_size >= 0x10000) { + LogWarn( "Ini-file %\"s is too big\n", fname ); + close( fd ); + return 0; + } + len = st.st_size; + if (!(data = Malloc( len + 2 ))) { + close( fd ); + return 0; + } + if (read( fd, data, len ) != len) { + Debug( "cannot read ini-file %\"s: %m", fname ); + free( data ); + close( fd ); + return 0; + } + close( fd ); + if (data[len - 1] != '\n') + data[len++] = '\n'; + data[len] = 0; + return data; +} + +int +iniSave( const char *data, const char *fname ) +{ + int fd, cnt, len; + + if ((fd = open( fname, O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, 0600 )) < 0) { + Debug( "cannot create ini-file %\"s: %m", fname ); + return 0; + } + len = strlen( data ); + if ((cnt = write( fd, data, len )) == len) { + close( fd ); + return 1; + } + if (cnt == -1) + Debug( "cannot write ini-file %\"s: %m", fname ); + else + Debug( "cannot write ini-file %\"s: partial write", fname ); + close( fd ); + return 0; +} + +#define apparr(d,s,n) do { memcpy (d, s, n); d += n; } while(0) +#define appbyte(d,b) *d++ = b + +char * +iniEntry( char *data, const char *section, const char *key, const char *value ) +{ + char *p = data, *secinsert = 0, *pastinsert = 0, *cb, *ce, *ndata; + const char *t; + int insect = 0, ll, sl, kl, vl, len, nlen; + + if (p) { + while (*p) { + for (; *p == ' ' || *p == '\t'; p++); + if (*p == '\n') { + p++; + continue; + } + if (*p == '[') { + for (t = section; *++p == *t; t++); + insect = !*t && *p == ']'; + } else if (insect) { + for (t = key; *p == *t; t++, p++); + for (; *p == ' ' || *p == '\t'; p++); + if (!*t && *p == '=') { + for (p++; *p == ' ' || *p == '\t'; p++); + cb = p; + while (*p++ != '\n'); + ce = p; + if (value) { + ll = sl = kl = 0; + len = (ce - data) + strlen( ce ); + goto insert; + } else { + for (ce--; ce != cb && (*(ce - 1) == ' ' || *(ce - 1) == '\t'); ce--); + if (!StrNDup( &p, cb, ce - cb )) + return 0; + return p; + } + } + } + for (; *p != '\n'; p++); + p++; + if (insect) + secinsert = p; + else + pastinsert = p; + } + } + if (!value) + return 0; + len = p - data; + if (secinsert) { + ce = cb = secinsert; + sl = ll = 0; + } else { + sl = strlen( section ) + 3; + if (pastinsert) { + ce = cb = pastinsert; + ll = 1; + } else { + ce = cb = data; + ll = 0; + } + } + kl = strlen( key ) + 1; + insert: + vl = strlen( value ); + nlen = len - (ce - cb) + ll + sl + kl + vl + 1; + if (!(p = ndata = Malloc( nlen + 1 ))) + return data; + apparr( p, data, cb - data ); + if (kl) { + if (sl) { + if (ll) + appbyte( p, '\n' ); + appbyte( p, '[' ); + apparr( p, section, sl - 3 ); + appbyte( p, ']' ); + appbyte( p, '\n' ); + } + apparr( p, key, kl - 1 ); + appbyte( p, '=' ); + } + apparr( p, value, vl ); + appbyte( p, '\n' ); + if (data) { + apparr( p, ce, len - (ce - data) ); + free( data ); + } + appbyte( p, 0 ); + return ndata; +} + +char * +iniMerge( char *data, const char *newdata ) +{ + const char *p, *cb, *ce; + char *section = 0, *key, *value; + + if (!newdata) + return data; + for (p = newdata;;) { + for (; *p == ' ' || *p == '\t'; p++); + if (!*p) + break; + if (*p == '\n') { + p++; + continue; + } + if (*p == '#') { + for (p++; *p != '\n'; p++) + if (!*p) + goto bail; + p++; + continue; + } + if (*p == '[') { + cb = ++p; + for (; *p != ']'; p++) + if (!*p || *p == '\n') /* missing ] */ + goto bail; + if (!ReStrN( §ion, cb, p - cb )) + break; + p++; + } else { + cb = p; + for (; *p != '='; p++) + if (!*p || *p == '\n') /* missing = */ + goto bail; + for (ce = p; ce != cb && (*(ce - 1) == ' ' || *(ce - 1) == '\t'); ce--); + if (!StrNDup( &key, cb, ce - cb )) + break; + for (p++; *p == ' ' || *p == '\t'; p++); + cb = p; + for (; *p && *p != '\n'; p++); + for (ce = p; ce != cb && (*(ce - 1) == ' ' || *(ce - 1) == '\t'); ce--); + if (!StrNDup( &value, cb, ce - cb )) + break; + if (section) + data = iniEntry( data, section, key, value ); + free( value ); + free( key ); + } + } + bail: + if (section) + free( section ); + return data; +} diff --git a/tdm/backend/krb5auth.c b/tdm/backend/krb5auth.c new file mode 100644 index 000000000..16b640a35 --- /dev/null +++ b/tdm/backend/krb5auth.c @@ -0,0 +1,248 @@ +/* + +Copyright 1994, 1998 The Open Group +Copyright 2003 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Stephen Gildea, The Open Group + * + * generate Kerberos Version 5 authorization records + */ + +#include + +#ifdef K5AUTH + +#include "dm.h" +#include "dm_auth.h" +#include "dm_error.h" + +#include +#include + +#include + +static krb5_context ctx; + +/*ARGSUSED*/ +void +Krb5InitAuth( unsigned short name_len ATTR_UNUSED, const char *name ATTR_UNUSED ) +{ + if (krb5_init_context( &ctx )) + LogError( "Error while initializing Krb5 context\n" ); +} + +/* + * Returns malloc'ed string that is the credentials cache name. + * name should be freed by caller. + */ +static char * +Krb5CCacheName( const char *dname ) +{ + char *name; + const char *tmpdir; + int dnl, nl; + + tmpdir = getenv( "TMPDIR" ); + if (!tmpdir) + tmpdir = "/tmp"; + dnl = strlen( dname ); + name = Malloc( strlen( tmpdir ) + dnl + 20 ); + if (!name) + return NULL; + nl = sprintf( name, "FILE:%s/K5C", tmpdir ); + CleanUpFileName( dname, name + nl, dnl + 1 ); + return name; +} + +Xauth * +Krb5GetAuthFor( unsigned short namelen, const char *name, const char *dname ) +{ + Xauth *new; + char *filename; + + if (!(new = (Xauth *)Malloc( sizeof(*new) ))) + return (Xauth *)0; + new->family = FamilyWild; + new->address_length = 0; + new->address = 0; + new->number_length = 0; + new->number = 0; + + if (dname) { + if (!(filename = Krb5CCacheName( dname ))) { + free( (char *)new ); + return (Xauth *)0; + } + new->data = 0; + if (!StrApp( &new->data, "UU:", filename, (char *)0 )) { + free( filename ); + free( (char *)new ); + return (Xauth *)0; + } + free( filename ); + new->data_length = strlen( new->data ); + } else { + new->data = NULL; + new->data_length = 0; + } + + if (!(new->name = (char *)Malloc( namelen ))) { + free( (char *)new->data ); + free( (char *)new ); + return (Xauth *)0; + } + memmove( new->name, name, namelen ); + new->name_length = namelen; + return new; +} + + +Xauth * +Krb5GetAuth( unsigned short namelen, const char *name ) +{ + return Krb5GetAuthFor( namelen, name, NULL ); +} + + +static krb5_error_code +Krb5DisplayCCache( const char *dname, krb5_ccache *ccache_return, char **name ) +{ + char *ccname; + krb5_error_code code; + + if (!(ccname = Krb5CCacheName( dname ))) + return ENOMEM; + Debug( "resolving Kerberos cache %s\n", ccname ); + if ((code = krb5_cc_resolve( ctx, ccname, ccache_return )) || !name) + free( ccname ); + else + *name = ccname; + return code; +} + +char * +Krb5Init( const char *user, const char *passwd, const char *dname ) +{ + krb5_error_code code; + krb5_get_init_creds_opt options; + krb5_principal me; + krb5_creds my_creds; + krb5_ccache ccache; + char *ccname; + + if (!ctx) + return 0; + + if ((code = krb5_parse_name( ctx, user, &me ))) { + LogError( "%s while parsing Krb5 user %\"s\n", + error_message( code ), user ); + return 0; + } + + krb5_get_init_creds_opt_init( &options ); + /*krb5_get_init_creds_opt_set_tkt_life (&options, 60*60*8);*/ /* 8 hours */ + + if ((code = krb5_get_init_creds_password( ctx, &my_creds, + me, /* principal */ + (char * /* for MIT */) passwd, + 0, /* prompter */ + 0, /* prompter ctx */ + 0, /* start time delta */ + 0, /* service */ + &options ))) + { + char *my_name = NULL; + int code2 = krb5_unparse_name( ctx, me, &my_name ); + if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) + LogError( "Password incorrect for Krb5 principal %\"s\n", + code2 ? user : my_name ); + else + LogError( "%s while getting initial Krb5 credentials for %\"s\n", + error_message( code ), code2 ? user : my_name ); + if (my_name) + free( my_name ); + goto err3; + } + + if ((code = Krb5DisplayCCache( dname, &ccache, &ccname ))) { + LogError( "%s while getting Krb5 ccache for %\"s\n", + error_message( code ), dname ); + goto err2; + } + + if ((code = krb5_cc_initialize( ctx, ccache, me ))) { + LogError( "%s while initializing Krb5 cache %\"s\n", + error_message( code ), ccname ); + goto err1; + } + + if ((code = krb5_cc_store_cred( ctx, ccache, &my_creds ))) { + LogError( "%s while storing Krb5 credentials to cache %\"s\n", + error_message( code ), ccname ); + err1: + krb5_cc_close( ctx, ccache ); + free( ccname ); + err2: + krb5_free_cred_contents( ctx, &my_creds ); + err3: + krb5_free_principal( ctx, me ); + return 0; + } + + krb5_cc_close( ctx, ccache ); + krb5_free_cred_contents( ctx, &my_creds ); + krb5_free_principal( ctx, me ); + return ccname; +} + +void +Krb5Destroy( const char *dname ) +{ + krb5_error_code code; + krb5_ccache ccache; + + if (!ctx) + return; + + if ((code = Krb5DisplayCCache( dname, &ccache, 0 ))) + LogError( "%s while getting Krb5 ccache to destroy\n", + error_message( code ) ); + else { + if ((code = krb5_cc_destroy( ctx, ccache ))) { + if (code == KRB5_FCC_NOFILE) + Debug( "no Kerberos ccache file found to destroy\n" ); + else + LogError( "%s while destroying Krb5 credentials cache\n", + error_message( code ) ); + } else + Debug( "kerberos ccache destroyed\n" ); + } +} + +#endif diff --git a/tdm/backend/mitauth.c b/tdm/backend/mitauth.c new file mode 100644 index 000000000..fd18d41df --- /dev/null +++ b/tdm/backend/mitauth.c @@ -0,0 +1,87 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2003 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * generate authorization keys + * for MIT-MAGIC-COOKIE-1 type authorization + */ + +#include "dm.h" +#include "dm_auth.h" + +#define AUTH_DATA_LEN 16 /* bytes of authorization data */ +static char auth_name[256]; + +void +MitInitAuth( unsigned short name_len, const char *name ) +{ + if (name_len > 256) + name_len = 256; + memmove( auth_name, name, name_len ); +} + +Xauth * +MitGetAuth( unsigned short namelen, const char *name ) +{ + Xauth *new; + new = (Xauth *)Malloc( sizeof(Xauth) ); + + if (!new) + return (Xauth *)0; + new->family = FamilyWild; + new->address_length = 0; + new->address = 0; + new->number_length = 0; + new->number = 0; + + new->data = (char *)Malloc( AUTH_DATA_LEN ); + if (!new->data) { + free( (char *)new ); + return (Xauth *)0; + } + new->name = (char *)Malloc( namelen ); + if (!new->name) { + free( (char *)new->data ); + free( (char *)new ); + return (Xauth *)0; + } + memmove( (char *)new->name, name, namelen ); + new->name_length = namelen; + if (!GenerateAuthData( new->data, AUTH_DATA_LEN )) { + free( (char *)new->name ); + free( (char *)new->data ); + free( (char *)new ); + return (Xauth *)0; + } + new->data_length = AUTH_DATA_LEN; + return new; +} diff --git a/tdm/backend/netaddr.c b/tdm/backend/netaddr.c new file mode 100644 index 000000000..349a53528 --- /dev/null +++ b/tdm/backend/netaddr.c @@ -0,0 +1,219 @@ +/* + +Copyright 1991, 1998 The Open Group +Copyright 2002 Sun Microsystems, Inc. All rights reserved. + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * netaddr.c - Interpretation of XdmcpNetaddr object. + */ + +#include "dm.h" +#include "dm_socket.h" +#include "dm_error.h" + +/* given an char *, returns the socket protocol family used, + e.g., AF_INET */ + +int +NetaddrFamily( char *netaddrp ) +{ +#ifdef STREAMSCONN + short family = *(short *)netaddrp; + return family; +#else + return ((struct sockaddr *)netaddrp)->sa_family; +#endif +} + + +/* given an char *, returns a pointer to the TCP/UDP port used + and sets *lenp to the length of the address + or 0 if not using TCP or UDP. */ + +char * +NetaddrPort( char *netaddrp, int *lenp ) +{ +#ifdef STREAMSCONN + *lenp = 2; + return netaddrp+2; +#else + switch (NetaddrFamily( netaddrp )) + { + case AF_INET: + *lenp = 2; + return (char *)&(((struct sockaddr_in *)netaddrp)->sin_port); +#if defined(IPv6) && defined(AF_INET6) + case AF_INET6: + *lenp = 2; + return (char *)&(((struct sockaddr_in6 *)netaddrp)->sin6_port); +#endif + default: + *lenp = 0; + return NULL; + } +#endif +} + + +/* given an char *, returns a pointer to the network address + and sets *lenp to the length of the address */ + +char * +NetaddrAddress( char *netaddrp, int *lenp ) +{ +#ifdef STREAMSCONN + *lenp = 4; + return netaddrp+4; +#else + switch (NetaddrFamily( netaddrp )) { +#ifdef UNIXCONN + case AF_UNIX: + *lenp = strlen( ((struct sockaddr_un *)netaddrp)->sun_path ); + return (char *)(((struct sockaddr_un *)netaddrp)->sun_path); +#endif +#ifdef TCPCONN + case AF_INET: + *lenp = sizeof(struct in_addr); + return (char *)&(((struct sockaddr_in *)netaddrp)->sin_addr); +#if defined(IPv6) && defined(AF_INET6) + case AF_INET6: + { + struct in6_addr *a = &(((struct sockaddr_in6 *)netaddrp)->sin6_addr); + if (IN6_IS_ADDR_V4MAPPED( a )) { + *lenp = sizeof(struct in_addr); + return ((char *)&(a->s6_addr))+12; + } else { + *lenp = sizeof(struct in6_addr); + return (char *)&(a->s6_addr); + } + } +#endif +#endif +#ifdef DNETCONN + case AF_DECnet: + *lenp = sizeof(struct dn_naddr); + return (char *)&(((struct sockaddr_dn *)netaddrp)->sdn_add); +#endif +#ifdef AF_CHAOS + case AF_CHAOS: +#endif + default: + *lenp = 0; + return NULL; + } +#endif /* STREAMSCONN else */ +} + + +/* given an char *, sets *addr to the network address used and + sets *len to the number of bytes in addr. + Returns the X protocol family used, e.g., FamilyInternet */ + +int +ConvertAddr( char *saddr, int *len, char **addr ) +{ + int retval; + + if (len == NULL) + return -1; + *addr = NetaddrAddress( saddr, len ); +#ifdef STREAMSCONN + /* kludge */ + if (NetaddrFamily( saddr ) == 2) + retval = FamilyInternet; +#else + switch (NetaddrFamily( saddr )) { +#ifdef AF_UNSPEC + case AF_UNSPEC: + retval = FamilyLocal; + break; +#endif +#ifdef AF_UNIX +#ifndef __hpux + case AF_UNIX: + retval = FamilyLocal; + break; +#endif +#endif +#ifdef TCPCONN + case AF_INET: + retval = FamilyInternet; + break; +#if defined(IPv6) && defined(AF_INET6) + case AF_INET6: + if (*len == sizeof(struct in_addr)) + retval = FamilyInternet; + else + retval = FamilyInternet6; + break; +#endif +#endif +#ifdef DNETCONN + case AF_DECnet: + retval = FamilyDECnet; + break; +#endif +#ifdef AF_CHAOS + case AF_CHAOS: + retval = FamilyChaos; + break; +#endif + default: + retval = -1; + break; + } +#endif /* STREAMSCONN else */ + Debug( "ConvertAddr returning %d for family %d\n", retval, + NetaddrFamily( saddr ) ); + return retval; +} + +#ifdef XDMCP +int +addressEqual( char *a1, int len1, char *a2, int len2 ) +{ + int partlen1, partlen2; + char *part1, *part2; + + if (len1 != len2) + return FALSE; + if (NetaddrFamily( a1 ) != NetaddrFamily( a2 )) + return FALSE; + part1 = NetaddrPort( a1, &partlen1 ); + part2 = NetaddrPort( a2, &partlen2 ); + if (partlen1 != partlen2 || memcmp( part1, part2, partlen1 ) != 0) + return FALSE; + part1 = NetaddrAddress( a1, &partlen1 ); + part2 = NetaddrAddress( a2, &partlen2 ); + if (partlen1 != partlen2 || memcmp( part1, part2, partlen1 ) != 0) + return FALSE; + return TRUE; +} +#endif diff --git a/tdm/backend/policy.c b/tdm/backend/policy.c new file mode 100644 index 000000000..cabee7088 --- /dev/null +++ b/tdm/backend/policy.c @@ -0,0 +1,278 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2001 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * policy.c. Implement site-dependent policy for XDMCP connections + */ + +#include + +#ifdef XDMCP + +#include "dm.h" +#include "dm_auth.h" +#include "dm_socket.h" + +static ARRAY8 noAuthentication = { (CARD16)0, (CARD8Ptr) 0 }; + +typedef struct _XdmAuth { + ARRAY8 authentication; + ARRAY8 authorization; +} XdmAuthRec, *XdmAuthPtr; + +static XdmAuthRec auth[] = { +#ifdef HASXDMAUTH +{ {(CARD16)20, (CARD8 *)"XDM-AUTHENTICATION-1"}, + {(CARD16)19, (CARD8 *)"XDM-AUTHORIZATION-1"}, +}, +#endif +{ {(CARD16)0, (CARD8 *)0}, + {(CARD16)0, (CARD8 *)0}, +} +}; + +#define NumAuth as(auth) + +ARRAY8Ptr +ChooseAuthentication( ARRAYofARRAY8Ptr authenticationNames ) +{ + int i, j; + + for (i = 0; i < (int)authenticationNames->length; i++) + for (j = 0; j < NumAuth; j++) + if (XdmcpARRAY8Equal( &authenticationNames->data[i], + &auth[j].authentication )) + return &authenticationNames->data[i]; + return &noAuthentication; +} + +int +CheckAuthentication( + struct protoDisplay *pdpy ATTR_UNUSED, + ARRAY8Ptr displayID ATTR_UNUSED, + ARRAY8Ptr name ATTR_UNUSED, + ARRAY8Ptr data ATTR_UNUSED ) +{ +#ifdef HASXDMAUTH + if (name->length && !memcmp( (char *)name->data, "XDM-AUTHENTICATION-1", 20 )) + return XdmCheckAuthentication( pdpy, displayID, name, data ); +#endif + return TRUE; +} + +int +SelectAuthorizationTypeIndex( ARRAY8Ptr authenticationName, + ARRAYofARRAY8Ptr authorizationNames ) +{ + int i, j; + + for (j = 0; j < NumAuth; j++) + if (XdmcpARRAY8Equal( authenticationName, + &auth[j].authentication )) + break; + if (j < NumAuth) + for (i = 0; i < (int)authorizationNames->length; i++) + if (XdmcpARRAY8Equal( &authorizationNames->data[i], + &auth[j].authorization )) + return i; + for (i = 0; i < (int)authorizationNames->length; i++) + if (ValidAuthorization( authorizationNames->data[i].length, + (char *)authorizationNames->data[i].data )) + return i; + return -1; +} + + +/*#define WILLING_INTERNAL*/ + +#ifdef WILLING_INTERNAL +/* Report the loadavg to chooser. Nice feature ... + * + * Wed Mar 10 1999 -- Steffen Hansen + */ +static void +Willing_msg( char *mbuf ) +{ +#ifdef __linux__ + int fd; + int numcpu; + const char *fail_msg = "Willing to manage"; + FILE *f; + float load[3]; + float mhz = 0.0; + char buf[1024]; + + fd = open( "/proc/loadavg", O_RDONLY ); + if (fd == -1) { + sprintf( mbuf, fail_msg ); + return; + } else if (read( fd, buf, 100 ) < 4) { + close( fd ); + sprintf( mbuf, fail_msg ); + return; + } + close( fd ); + + sscanf( buf, "%f %f %f", &load[0], &load[1], &load[2] ); + sprintf( mbuf, "Available (load: %0.2f, %0.2f, %0.2f)", + load[0], load[1], load[2] ); + + numcpu = 0; + + if (!(f = fopen( "/proc/cpuinfo", "r" ))) + return; + + while (fGets( buf, sizeof(buf), f ) != -1) { + float m; + if (sscanf( buf, "cpu MHz : %f", &m )) { + numcpu++; + mhz = m; + } + } + + fclose( f ); + + if (numcpu) { + if (numcpu > 1) + sprintf( buf, " %d*%0.0f MHz", numcpu, mhz ); + else + sprintf( buf, " %0.0f MHz", mhz ); + + strncat( mbuf, buf, 256 ); + + mbuf[255] = 0; + } +#elif HAVE_GETLOADAVG /* !__linux__ */ +#ifdef __GNUC__ +# warning This code is untested... +#endif + double load[3]; + getloadavg( load, 3 ); + sprintf( mbuf, "Available (load: %0.2f, %0.2f, %0.2f)", load[0], + load[1], load[2] ); +#else /* !__linux__ && !GETLOADAVG */ + strcpy( mbuf, "Willing to manage" ); +#endif +} +#endif + +/*ARGSUSED*/ +int +Willing( ARRAY8Ptr addr, CARD16 connectionType, + ARRAY8Ptr authenticationName ATTR_UNUSED, + ARRAY8Ptr status, xdmOpCode type ) +{ + int ret; + char statusBuf[256]; + static time_t lastscan; + + if (autoRescan && lastscan + 15 < now) { + lastscan = now; + ScanAccessDatabase( FALSE ); + } + ret = AcceptableDisplayAddress( addr, connectionType, type ); + if (!ret) + sprintf( statusBuf, "Display not authorized to connect" ); + else { + if (*willing) { + FILE *fd; + int len, ok = 0; + if ((fd = popen( willing, "r" ))) { + for (;;) { + if ((len = fGets( statusBuf, sizeof(statusBuf), fd )) != -1) { + if (len) { + ok = 1; + break; + } + } + if (feof( fd ) || errno != EINTR) + break; + } + pclose( fd ); + } + if (!ok) + sprintf( statusBuf, "Willing, but %.*s failed", + sizeof(statusBuf) - 21, willing ); + } else +#ifdef WILLING_INTERNAL + Willing_msg( statusBuf ); +#else + strcpy( statusBuf, "Willing to manage" ); +#endif + } + status->length = strlen( statusBuf ); + status->data = (CARD8Ptr) Malloc( status->length ); + if (!status->data) + status->length = 0; + else + memmove( status->data, statusBuf, status->length ); + return ret; +} + +/*ARGSUSED*/ +ARRAY8Ptr +Accept( struct sockaddr *from ATTR_UNUSED, int fromlen ATTR_UNUSED, + CARD16 displayNumber ATTR_UNUSED ) +{ + return 0; +} + +/*ARGSUSED*/ +int +SelectConnectionTypeIndex( ARRAY16Ptr connectionTypes, + ARRAYofARRAY8Ptr connectionAddresses ATTR_UNUSED ) +{ + int i; + + /* + * Select one supported connection type + */ + + for (i = 0; i < connectionTypes->length; i++) { + switch (connectionTypes->data[i]) { + case FamilyLocal: +#if defined(TCPCONN) + case FamilyInternet: +# if defined(IPv6) && defined(AF_INET6) + case FamilyInternet6: +# endif /* IPv6 */ +#endif /* TCPCONN */ +#if defined(DNETCONN) + case FamilyDECnet: +#endif /* DNETCONN */ + return i; + } + } /* for */ + return -1; +} + +#endif /* XDMCP */ diff --git a/tdm/backend/printf.c b/tdm/backend/printf.c new file mode 100644 index 000000000..d7220642b --- /dev/null +++ b/tdm/backend/printf.c @@ -0,0 +1,872 @@ +/* + +Copyright 2001,2002,2004 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * printf.c - working horse of error.c + */ + +/* + * NOTE: this file is meant to be included, not linked, + * so it can be used in the helper programs without much voodoo. + */ + +/* ########## printf core implementation with some extensions ########## */ +/* + * How to use the extensions: + * - put ' or " in the flags field to quote a string with this char and + * escape special characters (only available, if PRINT_QUOTES is defined) + * - put \\ in the flags field to quote special characters and leading and + * trailing spaces (only available, if PRINT_QUOTES is defined) + * - arrays (only available, if PRINT_ARRAYS is defined) + * - the array modifier [ comes after the maximal field width specifier + * - the array length can be specified literally, with the '*' modifier + * (in which case an argument is expected) or will be automatically + * determined (stop values are -1 for ints and 0 for strings) + * - these modifiers expect their argument to be an in-line string quoted + * with an arbitrary character: + * - (, ) -> array pre-/suf-fix; default "" + * - <, > -> element pre-/suf-fix; default "" + * - | -> element separator; default " " + * - these modifiers expect no argument: + * - : -> print ': ' before an array + * - , -> short for |',' + * - { -> short for ('{')' }'<' '|'' + * - the pointer to the array is the last argument to the format + * - the %m conversion from syslog() is supported + */ + +/************************************************************** + * Partially stolen from OpenSSH's OpenBSD compat directory. + * (C) Patrick Powell, Brandon Long, Thomas Roessler, + * Michael Elkins, Ben Lindstrom + **************************************************************/ + +#include +#include +#include + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UPCASE (1 << 5) +#define DP_F_UNSIGNED (1 << 6) +#define DP_F_SQUOTE (1 << 7) +#define DP_F_DQUOTE (1 << 8) +#define DP_F_BACKSL (1 << 9) +#define DP_F_ARRAY (1 << 10) +#define DP_F_COLON (1 << 11) + +/* Conversion Flags */ +#define DP_C_INT 0 +#define DP_C_BYTE 1 +#define DP_C_SHORT 2 +#define DP_C_LONG 3 +#define DP_C_STR 10 + +typedef void (*OutCh)( void *bp, char c ); + + +static void +fmtint( OutCh dopr_outch, void *bp, + long value, int base, int min, int max, int flags ) +{ + const char *ctab; + unsigned long uvalue; + int signvalue = 0; + int place = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + char convert[20]; + + if (max < 0) + max = 0; + + uvalue = value; + + if (!(flags & DP_F_UNSIGNED)) { + if (value < 0) { + signvalue = '-'; + uvalue = -value; + } else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + } + + ctab = (flags & DP_F_UPCASE) ? "0123456789ABCDEF" : "0123456789abcdef"; + do { + convert[place++] = ctab[uvalue % (unsigned)base]; + uvalue = uvalue / (unsigned)base; + } while (uvalue); + + zpadlen = max - place; + spadlen = min - (max > place ? max : place) - + (signvalue ? 1 : 0) - ((flags & DP_F_NUM) ? 2 : 0); + if (zpadlen < 0) + zpadlen = 0; + if (spadlen < 0) + spadlen = 0; + if (flags & DP_F_ZERO) { + zpadlen = zpadlen > spadlen ? zpadlen : spadlen; + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ + + + /* Spaces */ + while (spadlen > 0) { + dopr_outch( bp, ' ' ); + --spadlen; + } + + /* Sign */ + if (signvalue) + dopr_outch( bp, signvalue ); + + /* Prefix */ + if (flags & DP_F_NUM) { + dopr_outch( bp, '0' ); + dopr_outch( bp, 'x' ); + } + + /* Zeros */ + if (zpadlen > 0) + while (zpadlen > 0) { + dopr_outch( bp, '0' ); + --zpadlen; + } + + /* Digits */ + while (place > 0) + dopr_outch( bp, convert[--place] ); + + /* Left Justified spaces */ + while (spadlen < 0) { + dopr_outch( bp, ' ' ); + ++spadlen; + } +} + +typedef struct { + const char *str; + size_t len; +} str_t; + +static void +putstr( OutCh dopr_outch, void *bp, str_t *st ) +{ + size_t pt; + + for (pt = 0; pt < st->len; pt++) + dopr_outch( bp, st->str[pt] ); +} + +static str_t _null_parents = { "(null)", 6 }; +#ifdef PRINT_ARRAYS +static str_t _null_dparents = { "((null))", 8 }; +#endif +#if defined(PRINT_QUOTES) || defined(PRINT_ARRAYS) +static str_t _null_caps = { "NULL", 4 }; +#endif + +static void +fmtstr( OutCh dopr_outch, void *bp, + const char *value, int flags, int min, int max ) +{ + int padlen, strln, curcol; +#ifdef PRINT_QUOTES + int lastcol; +#endif + char ch; + + if (!value) { +#ifdef PRINT_QUOTES + if (flags & (DP_F_SQUOTE | DP_F_DQUOTE)) + putstr( dopr_outch, bp, &_null_caps ); + else +#endif + putstr( dopr_outch, bp, &_null_parents ); + return; + } + + for (strln = 0; (unsigned)strln < (unsigned)max && value[strln]; strln++); + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + for (; padlen > 0; padlen--) + dopr_outch( bp, ' ' ); +#ifdef PRINT_QUOTES +# if 0 /* gcc's flow analyzer is not the smartest ... */ + lastcol = 0; +# endif + if (flags & DP_F_SQUOTE) + dopr_outch( bp, '\'' ); + else if (flags & DP_F_DQUOTE) + dopr_outch( bp, '"'); + else if (flags & DP_F_BACKSL) + for (lastcol = strln; lastcol && value[lastcol - 1] == ' '; lastcol--); +#endif + for (curcol = 0; curcol < strln; curcol++) { + ch = value[curcol]; +#ifdef PRINT_QUOTES + if (flags & (DP_F_SQUOTE | DP_F_DQUOTE | DP_F_BACKSL)) { + switch (ch) { + case '\r': ch = 'r'; break; + case '\n': ch = 'n'; break; + case '\t': ch = 't'; break; + case '\a': ch = 'a'; break; + case '\b': ch = 'b'; break; + case '\v': ch = 'v'; break; + case '\f': ch = 'f'; break; + default: + if (ch < 32 || + ((unsigned char)ch >= 0x7f && (unsigned char)ch < 0xa0)) + { + dopr_outch( bp, '\\' ); + fmtint( dopr_outch, bp, (unsigned char)ch, 8, 3, 3, DP_F_ZERO ); + continue; + } else { + if ((ch == '\'' && (flags & DP_F_SQUOTE)) || + (ch == '"' && (flags & DP_F_DQUOTE) ) || + (ch == ' ' && (flags & DP_F_BACKSL) && + (!curcol || curcol >= lastcol)) || + ch == '\\') + dopr_outch( bp, '\\' ); + dopr_outch( bp, ch ); + continue; + } + } + dopr_outch( bp, '\\' ); + } +#endif + dopr_outch( bp, ch ); + } +#ifdef PRINT_QUOTES + if (flags & DP_F_SQUOTE) + dopr_outch( bp, '\'' ); + else if (flags & DP_F_DQUOTE) + dopr_outch( bp, '"' ); +#endif + for (; padlen < 0; padlen++) + dopr_outch( bp, ' ' ); +} + +static void +DoPr( OutCh dopr_outch, void *bp, const char *format, va_list args ) +{ + const char *strvalue; +#ifdef PRINT_ARRAYS + str_t arpr, arsf, arepr, aresf, aresp, *arp; + void *arptr; +#endif + unsigned long value; + int radix, min, max, flags, cflags, errn; +#ifdef PRINT_ARRAYS + int arlen; + unsigned aridx; + char sch; +#endif + char ch; +#define NCHR if (!(ch = *format++)) return + +#if 0 /* gcc's flow analyzer is not the smartest ... */ +# ifdef PRINT_ARRAYS + arlen = 0; +# endif + radix = 0; +#endif + errn = errno; + for (;;) { + for (;;) { + NCHR; + if (ch == '%') + break; + dopr_outch (bp, ch); + } + flags = cflags = min = 0; + max = -1; + for (;;) { + NCHR; + switch (ch) { + case '#': flags |= DP_F_NUM; continue; + case '-': flags |= DP_F_MINUS; continue; + case '+': flags |= DP_F_PLUS; continue; + case ' ': flags |= DP_F_SPACE; continue; + case '0': flags |= DP_F_ZERO; continue; +#ifdef PRINT_QUOTES + case '"': flags |= DP_F_DQUOTE; continue; + case '\'': flags |= DP_F_SQUOTE; continue; + case '\\': flags |= DP_F_BACKSL; continue; +#endif + } + break; + } + for (;;) { + if (isdigit( (unsigned char)ch )) { + min = 10 * min + (ch - '0'); + NCHR; + continue; + } else if (ch == '*') { + min = va_arg( args, int ); + NCHR; + } + break; + } + if (ch == '.') { + max = 0; + for (;;) { + NCHR; + if (isdigit( (unsigned char)ch )) { + max = 10 * max + (ch - '0'); + continue; + } else if (ch == '*') { + max = va_arg( args, int ); + NCHR; + } + break; + } + } +#ifdef PRINT_ARRAYS + if (ch == '[') { + flags |= DP_F_ARRAY; + arlen = -1; + arpr.len = arsf.len = arepr.len = aresf.len = 0; + aresp.len = 1, aresp.str = " "; + for (;;) { + NCHR; + if (isdigit( (unsigned char)ch )) { + arlen = 0; + for (;;) { + arlen += (ch - '0'); + NCHR; + if (!isdigit( (unsigned char)ch )) + break; + arlen *= 10; + } + } + switch (ch) { + case ':': flags |= DP_F_COLON; continue; + case '*': arlen = va_arg( args, int ); continue; + case '(': arp = &arpr; goto rar; + case ')': arp = &arsf; goto rar; + case '<': arp = &arepr; goto rar; + case '>': arp = &aresf; goto rar; + case '|': arp = &aresp; + rar: + NCHR; + sch = ch; + arp->str = format; + do { + NCHR; + } while (ch != sch); + arp->len = format - arp->str - 1; + continue; + case ',': + aresp.len = 1, aresp.str = ","; + continue; + case '{': + aresp.len = 0, arpr.len = arepr.len = 1, arsf.len = 2; + arpr.str = "{", arepr.str = " ", arsf.str = " }"; + continue; + } + break; + } + } +#endif + for (;;) { + switch (ch) { + case 'h': + cflags = DP_C_SHORT; + NCHR; + if (ch == 'h') { + cflags = DP_C_BYTE; + NCHR; + } + continue; + case 'l': + cflags = DP_C_LONG; + NCHR; + continue; + } + break; + } + switch (ch) { + case '%': + dopr_outch( bp, ch ); + break; + case 'm': + fmtstr( dopr_outch, bp, strerror( errn ), flags, min, max ); + break; + case 'c': + dopr_outch( bp, va_arg( args, int ) ); + break; + case 's': +#ifdef PRINT_ARRAYS + cflags = DP_C_STR; + goto printit; +#else + strvalue = va_arg( args, char * ); + fmtstr( dopr_outch, bp, strvalue, flags, min, max ); + break; +#endif + case 'u': + flags |= DP_F_UNSIGNED; + case 'd': + case 'i': + radix = 10; + goto printit; + case 'X': + flags |= DP_F_UPCASE; + case 'x': + flags |= DP_F_UNSIGNED; + radix = 16; + printit: +#ifdef PRINT_ARRAYS + if (flags & DP_F_ARRAY) { + if (!(arptr = va_arg( args, void * ))) + putstr( dopr_outch, bp, + arpr.len ? &_null_caps : &_null_dparents ); + else { + if (arlen == -1) { + arlen = 0; + switch (cflags) { + case DP_C_STR: while (((char **)arptr)[arlen]) arlen++; break; + case DP_C_BYTE: while (((unsigned char *)arptr)[arlen] != (unsigned char)-1) arlen++; break; + case DP_C_SHORT: while (((unsigned short int *)arptr)[arlen] != (unsigned short int)-1) arlen++; break; + case DP_C_LONG: while (((unsigned long int *)arptr)[arlen] != (unsigned long int)-1) arlen++; break; + default: while (((unsigned int *)arptr)[arlen] != (unsigned int)-1) arlen++; break; + } + } + if (flags & DP_F_COLON) { + fmtint( dopr_outch, bp, (long)arlen, 10, 0, -1, DP_F_UNSIGNED ); + dopr_outch( bp, ':' ); + dopr_outch( bp, ' ' ); + } + putstr( dopr_outch, bp, &arpr ); + for (aridx = 0; aridx < (unsigned)arlen; aridx++) { + if (aridx) + putstr( dopr_outch, bp, &aresp ); + putstr( dopr_outch, bp, &arepr ); + if (cflags == DP_C_STR) { + strvalue = ((char **)arptr)[aridx]; + fmtstr( dopr_outch, bp, strvalue, flags, min, max ); + } else { + if (flags & DP_F_UNSIGNED) { + switch (cflags) { + case DP_C_BYTE: value = ((unsigned char *)arptr)[aridx]; break; + case DP_C_SHORT: value = ((unsigned short int *)arptr)[aridx]; break; + case DP_C_LONG: value = ((unsigned long int *)arptr)[aridx]; break; + default: value = ((unsigned int *)arptr)[aridx]; break; + } + } else { + switch (cflags) { + case DP_C_BYTE: value = ((signed char *)arptr)[aridx]; break; + case DP_C_SHORT: value = ((short int *)arptr)[aridx]; break; + case DP_C_LONG: value = ((long int *)arptr)[aridx]; break; + default: value = ((int *)arptr)[aridx]; break; + } + } + fmtint( dopr_outch, bp, value, radix, min, max, flags ); + } + putstr( dopr_outch, bp, &aresf ); + } + putstr( dopr_outch, bp, &arsf ); + } + } else { + if (cflags == DP_C_STR) { + strvalue = va_arg( args, char * ); + fmtstr( dopr_outch, bp, strvalue, flags, min, max ); + } else { +#endif + if (flags & DP_F_UNSIGNED) { + switch (cflags) { + case DP_C_LONG: value = va_arg( args, unsigned long int ); break; + default: value = va_arg( args, unsigned int ); break; + } + } else { + switch (cflags) { + case DP_C_LONG: value = va_arg( args, long int ); break; + default: value = va_arg( args, int ); break; + } + } + fmtint( dopr_outch, bp, value, radix, min, max, flags ); +#ifdef PRINT_ARRAYS + } + } +#endif + break; + case 'p': + value = (long)va_arg( args, void * ); + fmtint( dopr_outch, bp, value, 16, sizeof(long) * 2 + 2, + max, flags | DP_F_UNSIGNED | DP_F_ZERO | DP_F_NUM ); + break; + } + } +} + +/* ########## end of printf core implementation ########## */ + + +/* + * Logging function for xdm and helper programs. + */ +#ifndef NO_LOGGER + +#include +#include + +#ifdef USE_SYSLOG +# include +# ifdef LOG_NAME +# define InitLog() openlog(LOG_NAME, LOG_PID, LOG_DAEMON) +# else +# define InitLog() openlog(prog, LOG_PID, LOG_DAEMON) +# endif +static int lognums[] = { LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_CRIT }; +#else +# define InitLog() while(0) +#endif + +static const char *lognams[] = { "debug", "info", "warning", "error", "panic" }; + +static void +logTime( char *dbuf ) +{ + time_t tim; + (void)time( &tim ); + strftime( dbuf, 20, "%b %e %H:%M:%S", localtime( &tim ) ); +} + +#if defined(LOG_DEBUG_MASK) || defined(USE_SYSLOG) +STATIC int debugLevel; +#endif + +#define OOMSTR "Out of memory. Expect problems.\n" + +STATIC void +LogOutOfMem( void ) +{ + static time_t last; + time_t tnow; + + time( &tnow ); + if (last + 100 > tnow) { /* don't log bursts */ + last = tnow; + return; + } + last = tnow; +#ifdef USE_SYSLOG + if (!(debugLevel & DEBUG_NOSYSLOG)) + syslog( LOG_CRIT, OOMSTR ); + else +#endif + { + int el; + char dbuf[24], sbuf[128]; + logTime( dbuf ); + el = sprintf( sbuf, "%s " +#ifdef LOG_NAME + LOG_NAME "[%ld]: " OOMSTR, dbuf, +#else + "%s[%ld]: " OOMSTR, dbuf, prog, +#endif + (long)getpid() ); + write( 2, sbuf, el ); + } +} + +typedef struct { + char *buf; + int clen, blen, type; + char lmbuf[128]; +} OCLBuf; + +static void +OutChLFlush( OCLBuf *oclbp ) +{ + if (oclbp->clen) { +#ifdef USE_SYSLOG + if (!(debugLevel & DEBUG_NOSYSLOG)) + syslog( lognums[oclbp->type], "%.*s", oclbp->clen, oclbp->buf ); + else +#endif + { + oclbp->buf[oclbp->clen] = '\n'; + write( 2, oclbp->buf, oclbp->clen + 1 ); + } + oclbp->clen = 0; + } +} + +static void +OutChL( void *bp, char c ) +{ + OCLBuf *oclbp = (OCLBuf *)bp; + char *nbuf; + int nlen; + + if (c == '\n') + OutChLFlush( oclbp ); + else { + if (oclbp->clen >= oclbp->blen - 1) { + if (oclbp->buf == oclbp->lmbuf) { + OutChLFlush( oclbp ); + oclbp->buf = 0; + oclbp->blen = 0; + } + nlen = oclbp->blen * 3 / 2 + 128; + nbuf = Realloc( oclbp->buf, nlen ); + if (nbuf) { + oclbp->buf = nbuf; + oclbp->blen = nlen; + } else { + OutChLFlush( oclbp ); + oclbp->buf = oclbp->lmbuf; + oclbp->blen = sizeof(oclbp->lmbuf); + } + } +#ifdef USE_SYSLOG + if (!oclbp->clen && (debugLevel & DEBUG_NOSYSLOG)) { +#else + if (!oclbp->clen) { +#endif + char dbuf[24]; + logTime( dbuf ); + oclbp->clen = sprintf( oclbp->buf, "%s " +#ifdef LOG_NAME + LOG_NAME "[%ld] %s: ", dbuf, +#else + "%s[%ld] %s: ", dbuf, prog, +#endif + (long)getpid(), lognams[oclbp->type] ); + } + oclbp->buf[oclbp->clen++] = c; + } +} + +static void +Logger( int type, const char *fmt, va_list args ) +{ + OCLBuf oclb; + + oclb.buf = 0; + oclb.blen = oclb.clen = 0; + oclb.type = type; + DoPr( OutChL, &oclb, fmt, args ); + /* no flush, every message is supposed to be \n-terminated */ + if (oclb.buf && oclb.buf != oclb.lmbuf) + free( oclb.buf ); +} + +#ifdef LOG_DEBUG_MASK +STATIC void +Debug( const char *fmt, ... ) +{ + if (debugLevel & LOG_DEBUG_MASK) { + va_list args; + int olderrno = errno; + va_start( args, fmt ); + Logger( DM_DEBUG, fmt, args ); + va_end( args ); + errno = olderrno; + } +} +#endif + +#ifndef LOG_NO_INFO +STATIC void +LogInfo( const char *fmt, ... ) +{ + va_list args; + + va_start( args, fmt ); + Logger( DM_INFO, fmt, args ); + va_end( args ); +} +#endif + +#ifndef LOG_NO_WARN +STATIC void +LogWarn( const char *fmt, ... ) +{ + va_list args; + + va_start( args, fmt ); + Logger( DM_WARN, fmt, args ); + va_end( args ); +} +#endif + +#ifndef LOG_NO_ERROR +STATIC void +LogError( const char *fmt, ... ) +{ + va_list args; + + va_start( args, fmt ); + Logger( DM_ERR, fmt, args ); + va_end( args ); +} +#endif + +#ifdef LOG_PANIC_EXIT +STATIC void +LogPanic( const char *fmt, ... ) +{ + va_list args; + + va_start( args, fmt ); + Logger( DM_PANIC, fmt, args ); + va_end( args ); + exit( LOG_PANIC_EXIT ); +} +#endif + +#endif /* NO_LOGGER */ + +#ifdef NEED_FDPRINTF + +typedef struct { + char *buf; + int clen, blen, tlen; +} OCFBuf; + +static void +OutCh_OCF( void *bp, char c ) +{ + OCFBuf *ocfbp = (OCFBuf *)bp; + char *nbuf; + int nlen; + + ocfbp->tlen++; + if (ocfbp->clen >= ocfbp->blen) { + if (ocfbp->blen < 0) + return; + nlen = ocfbp->blen * 3 / 2 + 100; + nbuf = Realloc( ocfbp->buf, nlen ); + if (!nbuf) { + free( ocfbp->buf ); + ocfbp->blen = -1; + ocfbp->buf = 0; + ocfbp->clen = 0; + return; + } + ocfbp->blen = nlen; + ocfbp->buf = nbuf; + } + ocfbp->buf[ocfbp->clen++] = c; +} + +STATIC int +FdPrintf( int fd, const char *fmt, ... ) +{ + va_list args; + OCFBuf ocfb = { 0, 0, 0, -1 }; + + va_start( args, fmt ); + DoPr( OutCh_OCF, &ocfb, fmt, args ); + va_end( args ); + if (ocfb.buf) { + Debug( "FdPrintf %\".*s to %d\n", ocfb.clen, ocfb.buf, fd ); + (void)write( fd, ocfb.buf, ocfb.clen ); + free( ocfb.buf ); + } + return ocfb.tlen; +} + +#endif /* NEED_FDPRINTF */ + +#ifdef NEED_ASPRINTF + +typedef struct { + char *buf; + int clen, blen, tlen; +} OCABuf; + +static void +OutCh_OCA( void *bp, char c ) +{ + OCABuf *ocabp = (OCABuf *)bp; + char *nbuf; + int nlen; + + ocabp->tlen++; + if (ocabp->clen >= ocabp->blen) { + if (ocabp->blen < 0) + return; + nlen = ocabp->blen * 3 / 2 + 100; + nbuf = Realloc( ocabp->buf, nlen ); + if (!nbuf) { + free( ocabp->buf ); + ocabp->blen = -1; + ocabp->buf = 0; + ocabp->clen = 0; + return; + } + ocabp->blen = nlen; + ocabp->buf = nbuf; + } + ocabp->buf[ocabp->clen++] = c; +} + +STATIC int +VASPrintf( char **strp, const char *fmt, va_list args ) +{ + OCABuf ocab = { 0, 0, 0, -1 }; + + DoPr( OutCh_OCA, &ocab, fmt, args ); + OutCh_OCA( &ocab, 0 ); + *strp = Realloc( ocab.buf, ocab.clen ); + if (!*strp) + *strp = ocab.buf; + return ocab.tlen; +} + +STATIC int +ASPrintf( char **strp, const char *fmt, ... ) +{ + va_list args; + int len; + + va_start( args, fmt ); + len = VASPrintf( strp, fmt, args ); + va_end( args ); + return len; +} + +#endif /* NEED_ASPRINTF */ diff --git a/tdm/backend/process.c b/tdm/backend/process.c new file mode 100644 index 000000000..f9d34fe7f --- /dev/null +++ b/tdm/backend/process.c @@ -0,0 +1,762 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2001-2004 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * subdaemon and external process management and communication + */ + +#include "dm.h" +#include "dm_error.h" + +#include +#include +#include +#include +#include +#ifdef _POSIX_PRIORITY_SCHEDULING +# include +#endif + +extern char **environ; + + +SIGFUNC Signal( int sig, SIGFUNC handler ) +{ +#ifndef __EMX__ + struct sigaction sigact, osigact; + sigact.sa_handler = handler; + sigemptyset( &sigact.sa_mask ); +# ifdef SA_RESTART + sigact.sa_flags = SA_RESTART; +# else + sigact.sa_flags = 0; +# endif + sigaction( sig, &sigact, &osigact ); + return osigact.sa_handler; +#else + return signal( sig, handler ); +#endif +} + + +void +TerminateProcess( int pid, int sig ) +{ + kill( pid, sig ); +#ifdef SIGCONT + kill( pid, SIGCONT ); +#endif +} + + +static FD_TYPE CloseMask; +static int max = -1; + +void +RegisterCloseOnFork( int fd ) +{ + FD_SET( fd, &CloseMask ); + if (fd > max) + max = fd; +} + +void +ClearCloseOnFork( int fd ) +{ + FD_CLR( fd, &CloseMask ); +} + +void +CloseNClearCloseOnFork( int fd ) +{ + close( fd ); + FD_CLR( fd, &CloseMask ); +} + +static void +CloseOnFork( void ) +{ + int fd; + + for (fd = 0; fd <= max; fd++) + if (FD_ISSET( fd, &CloseMask )) + close( fd ); + FD_ZERO( &CloseMask ); + max = -1; +} + +int +Fork() +{ + int pid; + + sigset_t ss, oss; + sigfillset( &ss ); + sigprocmask( SIG_SETMASK, &ss, &oss ); + + if (!(pid = fork())) { +#ifdef SIGCHLD + (void)Signal( SIGCHLD, SIG_DFL ); +#endif + (void)Signal( SIGTERM, SIG_DFL ); + (void)Signal( SIGINT, SIG_IGN ); /* for -nodaemon */ + (void)Signal( SIGPIPE, SIG_DFL ); + (void)Signal( SIGALRM, SIG_DFL ); + (void)Signal( SIGHUP, SIG_DFL ); + sigemptyset( &ss ); + sigprocmask( SIG_SETMASK, &ss, NULL ); + CloseOnFork(); + return 0; + } + + sigprocmask( SIG_SETMASK, &oss, 0 ); + + return pid; +} + +int +Wait4( int pid ) +{ + waitType result; + + while (waitpid( pid, &result, 0 ) < 0) + if (errno != EINTR) { + Debug( "Wait4(%d) failed: %m\n", pid ); + return 0; + } + return waitVal( result ); +} + + +void +execute( char **argv, char **env ) +{ + Debug( "execute: %[s ; %[s\n", argv, env ); + execve( argv[0], argv, env ); + /* + * In case this is a shell script which hasn't been + * made executable (or this is a SYSV box), do + * a reasonable thing + */ + if (errno != ENOENT) { + char **newargv; + FILE *f; + int nu; + char program[1024]; + + /* + * emulate BSD kernel behaviour -- read + * the first line; check if it starts + * with "#!", in which case it uses + * the rest of the line as the name of + * program to run. Else use "/bin/sh". + */ + if (!(f = fopen( argv[0], "r" ))) + return; + if (!fGets( program, sizeof(program), f )) { + fclose( f ); + return; + } + fclose( f ); + if (!strncmp( program, "#!", 2 )) + newargv = parseArgs( 0, program + 2 ); + else + newargv = addStrArr( 0, "/bin/sh", 7 ); + if (!newargv) + return; + nu = arrLen( newargv ); + if (!(argv = xCopyStrArr( nu, argv ))) + return; + memcpy( argv, newargv, sizeof(char *) * nu ); + Debug( "shell script execution: %[s\n", argv ); + execve( argv[0], argv, env ); + } +} + +int +runAndWait( char **args, char **env ) +{ + int pid, ret; + + switch (pid = Fork()) { + case 0: + execute( args, env ); + LogError( "Can't execute %\"s: %m\n", args[0] ); + exit( 127 ); + case -1: + LogError( "Can't fork to execute %\"s: %m\n", args[0] ); + return 1; + } + ret = Wait4( pid ); + return waitVal( ret ); +} + +FILE * +pOpen( char **what, char m, int *pid ) +{ + int dp[2]; + + if (pipe( dp )) + return 0; + switch ((*pid = Fork())) { + case 0: + if (m == 'r') + dup2( dp[1], 1 ); + else + dup2( dp[0], 0 ); + close( dp[0] ); + close( dp[1] ); + execute( what, environ ); + LogError( "Can't execute %\"s: %m\n", what[0] ); + exit( 127 ); + case -1: + close( dp[0] ); + close( dp[1] ); + LogError( "Can't fork to execute %\"s: %m\n", what[0] ); + return 0; + } + if (m == 'r') { + close( dp[1] ); + return fdopen( dp[0], "r" ); + } else { + close( dp[0] ); + return fdopen( dp[1], "w" ); + } +} + +int +pClose( FILE *f, int pid ) +{ + fclose( f ); + return Wait4( pid ); +} + +char * +locate( const char *exe ) +{ + int len; + char *path, *name, *thenam, nambuf[PATH_MAX+1]; + char *pathe; + + if (!(path = getenv( "PATH" ))) { + LogError( "Can't execute %'s: $PATH not set.\n", exe ); + return 0; + } + len = strlen( exe ); + name = nambuf + PATH_MAX - len; + memcpy( name, exe, len + 1 ); + *--name = '/'; + do { + if (!(pathe = strchr( path, ':' ))) + pathe = path + strlen( path ); + len = pathe - path; + if (len && !(len == 1 && *path == '.')) { + thenam = name - len; + if (thenam >= nambuf) { + memcpy( thenam, path, len ); + if (!access( thenam, X_OK )) { + StrDup( &name, thenam ); + return name; + } + } + } + path = pathe; + } while (*path++ != '\0'); + LogError( "Can't execute %'s: not in $PATH.\n", exe ); + return 0; +} + + +static GTalk *curtalk; + +void +GSet( GTalk *tlk ) +{ + curtalk = tlk; +} + +int +GFork( GPipe *pajp, const char *pname, char *cname, + GPipe *ogp, char *cgname ) +{ + int opipe[2], ipipe[2], ogpipe[2], igpipe[2], pid; + + if (pipe( opipe )) + goto badp1; + if (pipe( ipipe )) + goto badp2; + if (ogp) { + if (pipe( ogpipe )) + goto badp3; + if (pipe( igpipe )) { + close( ogpipe[0] ); + close( ogpipe[1] ); + badp3: + close( ipipe[0] ); + close( ipipe[1] ); + badp2: + close( opipe[0] ); + close( opipe[1] ); + badp1: + LogError( "Cannot start %s, pipe() failed", cname ); + if (cname) + free( cname ); + return -1; + } + } + RegisterCloseOnFork( opipe[1] ); + RegisterCloseOnFork( ipipe[0] ); + if (ogp) { + RegisterCloseOnFork( ogpipe[1] ); + RegisterCloseOnFork( igpipe[0] ); + } + switch (pid = Fork()) { + case -1: + close( opipe[0] ); + close( ipipe[1] ); + CloseNClearCloseOnFork( opipe[1] ); + CloseNClearCloseOnFork( ipipe[0] ); + if (ogp) { + close( ogpipe[0] ); + close( igpipe[1] ); + CloseNClearCloseOnFork( ogpipe[1] ); + CloseNClearCloseOnFork( igpipe[0] ); + } + LogError( "Cannot start %s, fork() failed\n", cname ); + if (cname) + free( cname ); + return -1; + case 0: + pajp->wfd = ipipe[1]; + RegisterCloseOnFork( ipipe[1] ); + pajp->rfd = opipe[0]; + RegisterCloseOnFork( opipe[0] ); + pajp->who = (char *)pname; + if (ogp) { + ogp->wfd = igpipe[1]; + RegisterCloseOnFork( igpipe[1] ); + ogp->rfd = ogpipe[0]; + RegisterCloseOnFork( ogpipe[0] ); + ogp->who = (char *)pname; + } + break; + default: + close( opipe[0] ); + close( ipipe[1] ); + pajp->rfd = ipipe[0]; + pajp->wfd = opipe[1]; + pajp->who = cname; + if (ogp) { + close( ogpipe[0] ); + close( igpipe[1] ); + ogp->rfd = igpipe[0]; + ogp->wfd = ogpipe[1]; + ogp->who = cgname; + } + break; + } + return pid; +} + +int +GOpen( GProc *proc, char **argv, const char *what, char **env, char *cname, + GPipe *gp ) +{ + char **margv; + int pip[2]; + char coninfo[32]; + +/* ### GSet (proc->pipe); */ + if (proc->pid) { + LogError( "%s already running\n", cname ); + if (cname) + free( cname ); + return -1; + } + if (!(margv = xCopyStrArr( 1, argv ))) { + if (cname) + free( cname ); + return -1; + } + if (!StrApp( margv, progpath, what, (char *)0 )) { + free( margv ); + if (cname) + free( cname ); + return -1; + } + if (pipe( pip )) { + LogError( "Cannot start %s, pipe() failed\n", cname ); + if (cname) + free( cname ); + goto fail; + } + if (gp) { + ClearCloseOnFork( gp->rfd ); + ClearCloseOnFork( gp->wfd ); + } + proc->pid = GFork( &proc->pipe, 0, cname, 0, 0 ); + if (proc->pid) { + close( pip[1] ); + if (gp) { + RegisterCloseOnFork( gp->rfd ); + RegisterCloseOnFork( gp->wfd ); + } + } + switch (proc->pid) { + case -1: + fail1: + close( pip[0] ); + fail: + free( margv[0] ); + free( margv ); + return -1; + case 0: + (void)Signal( SIGPIPE, SIG_IGN ); + close( pip[0] ); + fcntl( pip[1], F_SETFD, FD_CLOEXEC ); + if (gp) + sprintf( coninfo, "CONINFO=%d %d %d %d", + proc->pipe.rfd, proc->pipe.wfd, gp->rfd, gp->wfd ); + else + sprintf( coninfo, "CONINFO=%d %d", + proc->pipe.rfd, proc->pipe.wfd ); + env = putEnv( coninfo, env ); + if (debugLevel & DEBUG_VALGRIND) { + char **nmargv = xCopyStrArr( 1, margv ); + nmargv[0] = locate( "valgrind" ); + execute( nmargv, env ); + } else if (debugLevel & DEBUG_STRACE) { + char **nmargv = xCopyStrArr( 1, margv ); + nmargv[0] = locate( "strace" ); + execute( nmargv, env ); + } else + execute( margv, env ); + write( pip[1], "", 1 ); + exit( 1 ); + default: + (void)Signal( SIGPIPE, SIG_IGN ); + if (Reader( pip[0], coninfo, 1 )) { + Wait4( proc->pid ); + LogError( "Cannot execute %\"s (%s)\n", margv[0], cname ); + GClosen (&proc->pipe); + goto fail1; + } + close( pip[0] ); + Debug( "started %s (%\"s), pid %d\n", cname, margv[0], proc->pid ); + free( margv[0] ); + free( margv ); + GSendInt( debugLevel ); + return 0; + } +} + +static void +iGClosen( GPipe *pajp ) +{ + CloseNClearCloseOnFork( pajp->rfd ); + CloseNClearCloseOnFork( pajp->wfd ); + pajp->rfd = pajp->wfd = -1; +} + +void +GClosen (GPipe *pajp) +{ + iGClosen( pajp ); + if (pajp->who) + free( pajp->who ); + pajp->who = 0; +} + +int +GClose (GProc *proc, GPipe *gp, int force) +{ + int ret; + + if (!proc->pid) { + Debug( "whoops, GClose while helper not running\n" ); + return 0; + } + iGClosen( &proc->pipe ); + if (gp) + GClosen (gp); + if (force) + TerminateProcess( proc->pid, SIGTERM ); + ret = Wait4( proc->pid ); + proc->pid = 0; + if (WaitSig( ret ) ? WaitSig( ret ) != SIGTERM : + (WaitCode( ret ) < EX_NORMAL || WaitCode( ret ) > EX_MAX)) + LogError( "Abnormal termination of %s, code %d, signal %d\n", + proc->pipe.who, WaitCode( ret ), WaitSig( ret ) ); + Debug( "closed %s\n", proc->pipe.who ); + if (proc->pipe.who) + free( proc->pipe.who ); + proc->pipe.who = 0; + return ret; +} + +static void ATTR_NORETURN +GErr( void ) +{ + Longjmp( curtalk->errjmp, 1 ); +} + +static void +GRead( void *buf, int len ) +{ + if (Reader( curtalk->pipe->rfd, buf, len ) != len) { + LogError( "Cannot read from %s\n", curtalk->pipe->who ); + GErr(); + } +} + +static void +GWrite( const void *buf, int len ) +{ + if (Writer( curtalk->pipe->wfd, buf, len ) != len) { + LogError( "Cannot write to %s\n", curtalk->pipe->who ); + GErr(); + } +#ifdef _POSIX_PRIORITY_SCHEDULING + if ((debugLevel & DEBUG_HLPCON)) + sched_yield(); +#endif +} + +void +GSendInt( int val ) +{ + GDebug( "sending int %d (%#x) to %s\n", val, val, curtalk->pipe->who ); + GWrite( &val, sizeof(val) ); +} + +int +GRecvInt() +{ + int val; + + GDebug( "receiving int from %s ...\n", curtalk->pipe->who ); + GRead( &val, sizeof(val) ); + GDebug( " -> %d (%#x)\n", val, val ); + return val; +} + +int +GRecvCmd( int *cmd ) +{ + GDebug( "receiving command from %s ...\n", curtalk->pipe->who ); + if (Reader( curtalk->pipe->rfd, cmd, sizeof(*cmd) ) == sizeof(*cmd)) { + GDebug( " -> %d\n", *cmd ); + return 1; + } + GDebug( " -> no data\n" ); + return 0; +} + +void +GSendArr( int len, const char *data ) +{ + GDebug( "sending array[%d] %02[*{hhx to %s\n", + len, len, data, curtalk->pipe->who ); + GWrite( &len, sizeof(len) ); + GWrite( data, len ); +} + +static char * +iGRecvArr( int *rlen ) +{ + int len; + char *buf; + + GRead( &len, sizeof(len) ); + *rlen = len; + GDebug( " -> %d bytes\n", len ); + if (!len) + return (char *)0; + if (!(buf = Malloc( len ))) + GErr(); + GRead( buf, len ); + return buf; +} + +char * +GRecvArr( int *rlen ) +{ + char *buf; + + GDebug( "receiving array from %s ...\n", curtalk->pipe->who ); + buf = iGRecvArr( rlen ); + GDebug( " -> %02[*{hhx\n", *rlen, buf ); + return buf; +} + +static int +iGRecvArrBuf( char *buf ) +{ + int len; + + GRead( &len, sizeof(len) ); + GDebug( " -> %d bytes\n", len ); + if (len) + GRead( buf, len ); + return len; +} + +int +GRecvArrBuf( char *buf ) +{ + int len; + + GDebug( "receiving already allocated array from %s ...\n", + curtalk->pipe->who ); + len = iGRecvArrBuf( buf ); + GDebug( " -> %02[*{hhx\n", len, buf ); + return len; +} + +int +GRecvStrBuf( char *buf ) +{ + int len; + + GDebug( "receiving already allocated string from %s ...\n", + curtalk->pipe->who ); + len = iGRecvArrBuf( buf ); + GDebug( " -> %\".*s\n", len, buf ); + return len; +} + +void +GSendStr( const char *buf ) +{ + int len; + + GDebug( "sending string %\"s to %s\n", buf, curtalk->pipe->who ); + if (buf) { + len = strlen( buf ) + 1; + GWrite( &len, sizeof(len) ); + GWrite( buf, len ); + } else + GWrite( &buf, sizeof(int) ); +} + +void +GSendNStr( const char *buf, int len ) +{ + int tlen = len + 1; + GDebug( "sending string %\".*s to %s\n", len, buf, curtalk->pipe->who ); + GWrite( &tlen, sizeof(tlen) ); + GWrite( buf, len ); + GWrite( "", 1 ); +} + +void +GSendStrN( const char *buf, int len ) +{ + if (buf) + GSendNStr( buf, StrNLen( buf, len ) ); + else + GSendStr( buf ); +} + +char * +GRecvStr() +{ + int len; + char *buf; + + GDebug( "receiving string from %s ...\n", curtalk->pipe->who ); + buf = iGRecvArr( &len ); + GDebug( " -> %\".*s\n", len, buf ); + return buf; +} + +static void +iGSendStrArr( int num, char **data ) +{ + char **cdata; + + GWrite( &num, sizeof(num) ); + for (cdata = data; --num >= 0; cdata++) + GSendStr( *cdata ); +} + +/* +void +GSendStrArr (int num, char **data) +{ + GDebug( "sending string array[%d] to %s\n", num, curtalk->pipe->who ); + iGSendStrArr( num, data ); +} +*/ + +char ** +GRecvStrArr( int *rnum ) +{ + int num; + char **argv, **cargv; + + GDebug( "receiving string array from %s ...\n", curtalk->pipe->who ); + GRead( &num, sizeof(num) ); + GDebug( " -> %d strings\n", num ); + *rnum = num; + if (!num) + return (char **)0; + if (!(argv = Malloc( num * sizeof(char *) ))) + GErr(); + for (cargv = argv; --num >= 0; cargv++) + *cargv = GRecvStr(); + return argv; +} + +void +GSendArgv( char **argv ) +{ + int num; + + if (argv) { + for (num = 0; argv[num]; num++); + GDebug( "sending argv[%d] to %s ...\n", num, curtalk->pipe->who ); + iGSendStrArr( num + 1, argv ); + } else { + GDebug( "sending NULL argv to %s\n", curtalk->pipe->who ); + GWrite( &argv, sizeof(int) ); + } +} + +char ** +GRecvArgv() +{ + int num; + + return GRecvStrArr( &num ); +} + diff --git a/tdm/backend/protodpy.c b/tdm/backend/protodpy.c new file mode 100644 index 000000000..08c38fbd1 --- /dev/null +++ b/tdm/backend/protodpy.c @@ -0,0 +1,141 @@ +/* + +Copyright 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * manage a collection of proto-displays. These are displays for + * which sessionID's have been generated, but no session has been + * started. + */ + +#include + +#ifdef XDMCP + +#include "dm.h" +#include "dm_error.h" + +static struct protoDisplay *protoDisplays; + +struct protoDisplay * +FindProtoDisplay( + XdmcpNetaddr address, + int addrlen, + CARD16 displayNumber ) +{ + struct protoDisplay *pdpy; + + Debug( "FindProtoDisplay\n" ); + for (pdpy = protoDisplays; pdpy; pdpy=pdpy->next) { + if (pdpy->displayNumber == displayNumber && + addressEqual( address, addrlen, pdpy->address, pdpy->addrlen )) + { + return pdpy; + } + } + return (struct protoDisplay *)0; +} + +static void +TimeoutProtoDisplays (void) +{ + struct protoDisplay *pdpy, *next; + + for (pdpy = protoDisplays; pdpy; pdpy = next) { + next = pdpy->next; + if (pdpy->date < (unsigned long)(now - PROTO_TIMEOUT)) + DisposeProtoDisplay( pdpy ); + } +} + +struct protoDisplay * +NewProtoDisplay( XdmcpNetaddr address, int addrlen, CARD16 displayNumber, + CARD16 connectionType, ARRAY8Ptr connectionAddress, + CARD32 sessionID ) +{ + struct protoDisplay *pdpy; + + Debug( "NewProtoDisplay\n" ); + TimeoutProtoDisplays (); + pdpy = (struct protoDisplay *)Malloc( sizeof(*pdpy) ); + if (!pdpy) + return NULL; + pdpy->address = (XdmcpNetaddr)Malloc( addrlen ); + if (!pdpy->address) { + free( (char *)pdpy ); + return NULL; + } + pdpy->addrlen = addrlen; + memmove( pdpy->address, address, addrlen ); + pdpy->displayNumber = displayNumber; + pdpy->connectionType = connectionType; + pdpy->date = now; + if (!XdmcpCopyARRAY8( connectionAddress, &pdpy->connectionAddress )) { + free( (char *)pdpy->address ); + free( (char *)pdpy ); + return NULL; + } + pdpy->sessionID = sessionID; + pdpy->fileAuthorization = (Xauth *)NULL; + pdpy->xdmcpAuthorization = (Xauth *)NULL; + pdpy->next = protoDisplays; + protoDisplays = pdpy; + return pdpy; +} + +void +DisposeProtoDisplay( pdpy ) + struct protoDisplay *pdpy; +{ + struct protoDisplay *p, *prev; + + prev = 0; + for (p = protoDisplays; p; p=p->next) { + if (p == pdpy) + break; + prev = p; + } + if (!p) + return; + if (prev) + prev->next = pdpy->next; + else + protoDisplays = pdpy->next; + bzero( &pdpy->key, sizeof(pdpy->key) ); + if (pdpy->fileAuthorization) + XauDisposeAuth( pdpy->fileAuthorization ); + if (pdpy->xdmcpAuthorization) + XauDisposeAuth( pdpy->xdmcpAuthorization ); + XdmcpDisposeARRAY8( &pdpy->connectionAddress ); + free( (char *)pdpy->address ); + free( (char *)pdpy ); +} + +#endif /* XDMCP */ diff --git a/tdm/backend/reset.c b/tdm/backend/reset.c new file mode 100644 index 000000000..2c2100870 --- /dev/null +++ b/tdm/backend/reset.c @@ -0,0 +1,111 @@ +/* + +Copyright 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * pseudoReset -- pretend to reset the server by killing all clients + * with windows. It will reset the server most of the time, unless + * a client remains connected with no windows. + */ + +#include "dm.h" +#include "dm_error.h" + +#include + +#include + +/*ARGSUSED*/ +static int +ignoreErrors( Display *dspl ATTR_UNUSED, XErrorEvent *event ATTR_UNUSED ) +{ + Debug( "ignoring error\n" ); + return 0; +} + +/* + * this is mostly bogus -- but quite useful. I wish the protocol + * had some way of enumerating and identifying clients, that way + * this code wouldn't have to be this kludgy. + */ + +static void +killWindows( Window window ) +{ + Window root, parent, *children; + unsigned int child, nchildren = 0; + + while (XQueryTree( dpy, window, &root, &parent, &children, &nchildren ) + && nchildren > 0) + { + for (child = 0; child < nchildren; child++) { + Debug( "XKillClient %p\n", children[child] ); + XKillClient( dpy, children[child] ); + } + XFree( (char *)children ); + } +} + +static Jmp_buf resetJmp; + +/* ARGSUSED */ +static void +abortReset( int n ATTR_UNUSED ) +{ + Longjmp( resetJmp, 1 ); +} + +/* + * this display connection better not have any windows... + */ + +void +pseudoReset() +{ + int screen; + + if (Setjmp( resetJmp )) { + LogError( "pseudoReset timeout\n" ); + } else { + (void)Signal( SIGALRM, abortReset ); + (void)alarm( 30 ); + XSetErrorHandler( ignoreErrors ); + for (screen = 0; screen < ScreenCount (dpy); screen++) { + Debug( "pseudoReset screen %d\n", screen ); + killWindows( RootWindow( dpy, screen ) ); + } + Debug( "before XSync\n" ); + XSync( dpy, False ); + (void)alarm( 0 ); + } + Signal( SIGALRM, SIG_DFL ); + XSetErrorHandler( (XErrorHandler)0 ); + Debug( "pseudoReset done\n" ); +} diff --git a/tdm/backend/resource.c b/tdm/backend/resource.c new file mode 100644 index 000000000..f17db78ec --- /dev/null +++ b/tdm/backend/resource.c @@ -0,0 +1,486 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2000-2005 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * obtain configuration data + */ + +#include "dm.h" +#include "dm_error.h" + +#include + + +static char **originalArgv; + +static GProc getter; +GTalk cnftalk; + +static void +OpenGetter() +{ + GSet( &cnftalk ); + if (!getter.pid) { + if (GOpen( &getter, + originalArgv, "_config", 0, strdup( "config reader" ), + 0 )) + LogPanic( "Cannot run config reader\n" ); + Debug( "getter now ready\n" ); + } +} + +void +CloseGetter() +{ + if (getter.pid) { + GSet( &cnftalk ); + (void)GClose (&getter, 0, 0); + Debug( "getter now closed\n" ); + } +} + +/* + * ref-counted, unique-instance strings + */ +static RcStr *strs; + +/* + * make a ref-counted string of the argument. the new string will + * have a ref-count of 1. the passed string pointer is no longer valid. + */ +RcStr * +newStr( char *str ) +{ + RcStr *cs; + + for (cs = strs; cs; cs = cs->next) + if (!strcmp( str, cs->str )) { + free( str ); + cs->cnt++; + return cs; + } + if (!(cs = Malloc( sizeof(*cs) ))) + return 0; + cs->cnt = 1; + cs->str = str; + cs->next = strs; + strs = cs; + return cs; +} + +/* + * decrement ref-count and delete string when count drops to 0. + */ +void +delStr( RcStr *str ) +{ + RcStr **cs; + + if (!str || --str->cnt) + return; + for (cs = &strs; *cs; cs = &((*cs)->next)) + if (str == *cs) { + *cs = (*cs)->next; + free( (*cs)->str ); + free( *cs ); + break; + } +} + + +typedef struct CfgFile { + RcStr *name; + int depidx; + long deptime; +} CfgFile; + +static int numCfgFiles; +static CfgFile *cfgFiles; + +static int cfgMapT[] = { + GC_gGlobal, + GC_gDisplay, +#ifdef XDMCP + GC_gXaccess, +#endif +}; +static int cfgMap[as(cfgMapT)]; + +static int +GetDeps() +{ + int ncf, i, dep, ret; + CfgFile *cf; + + OpenGetter(); + GSendInt( GC_Files ); + ncf = GRecvInt(); + if (!(cf = Malloc( ncf * sizeof(*cf) ))) { + CloseGetter(); + return 0; + } + for (i = 0; i < ncf; i++) { + cf[i].name = newStr( GRecvStr() ); + if ((dep = cf[i].depidx = GRecvInt()) != -1) + cf[i].deptime = mTime( cf[dep].name->str ); + } + if (cfgFiles) { + for (i = 0; i < numCfgFiles; i++) + delStr( cfgFiles[i].name ); + free( cfgFiles ); + } + ret = 1; + cfgFiles = cf; + numCfgFiles = ncf; + for (i = 0; i < as(cfgMapT); i++) { + GSendInt( cfgMapT[i] ); + if ((cfgMap[i] = GRecvInt()) < 0) { + LogError( "Config reader does not support config cathegory %#x\n", + cfgMapT[i] ); + ret = 0; + } + } + GSendInt( -1 ); + return ret; +} + +static int +checkDep( int idx ) +{ + int dep; + + if ((dep = cfgFiles[idx].depidx) == -1) + return 0; + if (checkDep( dep )) + return 1; + return mTime( cfgFiles[dep].name->str ) != cfgFiles[idx].deptime; +} + +static int +needsReScan( int what, CfgDep *dep ) +{ + int widx, idx; + long mt; + + for (widx = 0; cfgMapT[widx] != what; widx++); + idx = cfgMap[widx]; + if (checkDep( idx )) { + if (!GetDeps()) + return -1; + idx = cfgMap[widx]; + } + mt = mTime( cfgFiles[idx].name->str ); + if (dep->name != cfgFiles[idx].name) { + if (dep->name) + delStr( dep->name ); + dep->name = cfgFiles[idx].name; + dep->name->cnt++; + dep->time = mt; + return 1; + } else if (dep->time != mt) { + dep->time = mt; + return 1; + } else + return 0; +} + +int +startConfig( int what, CfgDep *dep, int force ) +{ + int ret; + + if ((ret = needsReScan( what, dep )) < 0 || (!ret && !force)) + return ret; + OpenGetter(); + GSendInt( GC_GetConf ); + GSendInt( what ); + GSendStr( dep->name->str ); + return 1; +} + +static void +LoadResources( CfgArr *conf ) +{ + char **vptr, **pptr, *cptr; + long *iptr, i, id, nu, j, nptr, nint, nchr; + + if (conf->data) + free( conf->data ); + conf->numCfgEnt = GRecvInt(); + nptr = GRecvInt(); + nint = GRecvInt(); + nchr = GRecvInt(); + if (!(conf->data = Malloc( conf->numCfgEnt * + (sizeof(long) + + sizeof(char *)) + + nptr * sizeof(char *) + + nint * sizeof(long) + + nchr ))) + { + CloseGetter(); + return; + } + vptr = (char **)conf->data; + pptr = vptr + conf->numCfgEnt; + conf->idx = (long *)(pptr + nptr); + iptr = conf->idx + conf->numCfgEnt; + cptr = (char *)(iptr + nint); + for (i = 0; i < conf->numCfgEnt; i++) { + id = GRecvInt(); + conf->idx[i] = id; + switch (id & C_TYPE_MASK) { + case C_TYPE_INT: + vptr[i] = (char *)((unsigned long)GRecvInt()); + break; + case C_TYPE_STR: + vptr[i] = cptr; + cptr += GRecvStrBuf( cptr ); + break; + case C_TYPE_ARGV: + nu = GRecvInt(); + vptr[i] = (char *)pptr; + for (j = 0; j < nu; j++) { + *pptr++ = cptr; + cptr += GRecvStrBuf( cptr ); + } + *pptr++ = (char *)0; + break; + default: + LogError( "Config reader supplied unknown data type in id %#x\n", + id ); + break; + } + } +} + +static void +ApplyResource( int id, char **src, char **dst ) +{ + switch (id & C_TYPE_MASK) { + case C_TYPE_INT: + *(int *)dst = *(long *)src; + break; + case C_TYPE_STR: + case C_TYPE_ARGV: + *dst = *src; + break; + } +} + + +#define boffset(f) XtOffsetOf(struct display, f) + +/* no global variables exported currently +struct globEnts { + int id; + char **off; +} globEnt[] = { +}; + */ + +/* no per-display variables exported currently +struct dpyEnts { + int id; + int off; +} dpyEnt[] = { +}; + */ + +CfgArr cfg; + +char ** +FindCfgEnt( struct display *d, int id ) +{ + int i; + +/* no global variables exported currently + for (i = 0; i < as(globEnt); i++) + if (globEnt[i].id == id) + return globEnt[i].off; + */ + for (i = 0; i < cfg.numCfgEnt; i++) + if (cfg.idx[i] == id) + return ((char **)cfg.data) + i; + if (d) { +/* no per-display variables exported currently + for (i = 0; i < as(dpyEnt); i++) + if (dpyEnt[i].id == id) + return (char **)(((char *)d) + dpyEnt[i].off); + */ + for (i = 0; i < d->cfg.numCfgEnt; i++) + if (d->cfg.idx[i] == id) + return ((char **)d->cfg.data) + i; + } + Debug( "unknown config entry %#x requested\n", id ); + return (char **)0; +} + + +CONF_CORE_GLOBAL_DEFS + +struct globVals { + int id; + char **off; +} globVal[] = { +CONF_CORE_GLOBALS +}; + +int +LoadDMResources( int force ) +{ + int i, ret; + char **ent; + + if (Setjmp( cnftalk.errjmp )) + return -1; /* may memleak, but we probably have to abort anyway */ + if ((ret = startConfig( GC_gGlobal, &cfg.dep, force )) <= 0) + return ret; + LoadResources( &cfg ); +/* Debug( "manager resources: %[*x\n", + cfg.numCfgEnt, ((char **)cfg.data) + cfg.numCfgEnt );*/ + ret = 1; + for (i = 0; i < as(globVal); i++) { + if (!(ent = FindCfgEnt( 0, globVal[i].id ))) + ret = -1; + else + ApplyResource( globVal[i].id, ent, globVal[i].off ); + } + if (ret < 0) + LogError( "Internal error: config reader supplied incomplete data\n" ); + return ret; +} + + +struct dpyVals { + int id; + int off; +} dpyVal[] = { +CONF_CORE_LOCALS +}; + +int +LoadDisplayResources( struct display *d ) +{ + int i, ret; + char **ent; + + if (Setjmp( cnftalk.errjmp )) + return -1; /* may memleak */ + if ((ret = startConfig( GC_gDisplay, &d->cfg.dep, FALSE )) <= 0) + return ret; + GSendStr( d->name ); + GSendStr( d->class2 ); + LoadResources( &d->cfg ); +/* Debug( "display(%s, %s) resources: %[*x\n", d->name, d->class2, + d->cfg.numCfgEnt, ((char **)d->cfg.data) + d->cfg.numCfgEnt );*/ + ret = 1; + for (i = 0; i < as(dpyVal); i++) { + if (!(ent = FindCfgEnt( d, dpyVal[i].id ))) + ret = -1; + else + ApplyResource( dpyVal[i].id, ent, + (char **)(((char *)d) + dpyVal[i].off) ); + } + if (ret < 0) + LogError( "Internal error: config reader supplied incomplete data\n" ); + return ret; +} + +int +InitResources( char **argv ) +{ + originalArgv = argv; + cnftalk.pipe = &getter.pipe; + if (Setjmp( cnftalk.errjmp )) + return 0; /* may memleak */ + return GetDeps(); +} + +static void +addServers( char **srv, int bType ) +{ + char *name, *class2; + const char *dtx, *cls; + struct display *d; + + for (; *srv; srv++) { + if ((cls = strchr( *srv, '_' ))) { + if (!StrNDup( &name, *srv, cls - *srv )) + return; + if (!StrDup( &class2, cls )) { + free( name ); + return; + } + } else { + if (!StrDup( &name, *srv )) + return; + class2 = 0; + } + if ((d = FindDisplayByName( name ))) { + if (d->class2) + free( d->class2 ); + dtx = "existing"; + } else { + if (!(d = NewDisplay( name ))) { + free( name ); + if (class2) + free( class2 ); + return; + } + dtx = "new"; + } + d->stillThere = 1; + d->class2 = class2; + d->displayType = (*name == ':' ? dLocal : dForeign) | bType; + if ((bType & d_lifetime) == dReserve) { + if (d->status == notRunning) + d->status = reserve; + } else { + if (d->status == reserve) + d->status = notRunning; + } + Debug( "found %s %s%s display: %s %s\n", dtx, + ((d->displayType & d_location) == dLocal) ? "local" : "foreign", + ((d->displayType & d_lifetime) == dReserve) ? " reserve" : "", + d->name, d->class2 ); + free( name ); + } +} + +void +ScanServers( void ) +{ + Debug( "ScanServers\n" ); + addServers( staticServers, dFromFile | dPermanent ); + addServers( reserveServers, dFromFile | dReserve ); +} + diff --git a/tdm/backend/rpcauth.c b/tdm/backend/rpcauth.c new file mode 100644 index 000000000..1186f72c2 --- /dev/null +++ b/tdm/backend/rpcauth.c @@ -0,0 +1,89 @@ +/* + +Copyright 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * generate SecureRPC authorization records + */ + +#include + +#ifdef SECURE_RPC + +#include "dm.h" +#include "dm_auth.h" +#include "dm_error.h" + +#include +#include + +/*ARGSUSED*/ +void +SecureRPCInitAuth( unsigned short name_len ATTR_UNUSED, + const char *name ATTR_UNUSED ) +{ +} + +Xauth * +SecureRPCGetAuth( unsigned short namelen, const char *name ) +{ + Xauth *new; + char key[MAXNETNAMELEN+1]; + + new = (Xauth *)Malloc( sizeof(*new) ); + if (!new) + return (Xauth *)0; + new->family = FamilyWild; + new->address_length = 0; + new->address = 0; + new->number_length = 0; + new->number = 0; + + getnetname( key ); + Debug( "system netname %s\n", key ); + new->data_length = strlen( key ); + new->data = (char *)Malloc( new->data_length ); + if (!new->data) { + free( (char *)new ); + return (Xauth *)0; + } + new->name = (char *)Malloc( namelen ); + if (!new->name) { + free( (char *)new->data ); + free( (char *)new ); + return (Xauth *)0; + } + memmove( new->name, name, namelen ); + new->name_length = namelen; + memmove( new->data, key, new->data_length ); + return new; +} + +#endif diff --git a/tdm/backend/server.c b/tdm/backend/server.c new file mode 100644 index 000000000..e78d8a66c --- /dev/null +++ b/tdm/backend/server.c @@ -0,0 +1,376 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2001,2003,2005 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * server.c - manage the X server + */ + +#include "dm.h" +#include "dm_error.h" +#include "dm_socket.h" + +#include + +#include +#include +#include + + +struct display *startingServer; +time_t serverTimeout = TO_INF; + +char ** +PrepServerArgv( struct display *d, const char *args ) +{ + char **argv; +#ifdef HAVE_VTS + char vtstr[8]; +#endif + + if (!(argv = parseArgs( 0, d->serverCmd )) || + !(argv = parseArgs( argv, args )) || + !(argv = addStrArr( argv, d->name, -1 ))) + exit( 47 ); +#ifdef HAVE_VTS + if (d->serverVT && + !(argv = addStrArr( argv, vtstr, + sprintf( vtstr, "vt%d", d->serverVT ) ))) + exit( 47 ); +#endif + return argv; +} + +static void +StartServerOnce( void ) +{ + struct display *d = startingServer; + char **argv; + int pid; + + Debug( "StartServerOnce for %s, try %d\n", d->name, ++d->startTries ); + d->serverStatus = starting; + switch (pid = Fork()) { + case 0: + argv = PrepServerArgv( d, d->serverArgsLocal ); + if (d->authFile) { + if (!(argv = addStrArr( argv, "-auth", 5 )) || + !(argv = addStrArr( argv, d->authFile, -1 ))) + exit( 47 ); + } + Debug( "exec %\"[s\n", argv ); + /* + * give the server SIGUSR1 ignored, + * it will notice that and send SIGUSR1 + * when ready + */ + (void)Signal( SIGUSR1, SIG_IGN ); + (void)execv( argv[0], argv ); + LogError( "X server %\"s cannot be executed\n", argv[0] ); + + /* Let's try again with some standard paths */ + argv[0] = (char *)realloc(argv[0], strlen("/usr/X11R6/bin/X") + 1); + if (argv[0] != NULL) { + argv[0] = "/usr/X11R6/bin/X"; + Debug( "exec %\"[s\n", argv ); + (void)execv( argv[0], argv ); + LogError( "X server %\"s cannot be executed\n", argv[0] ); + + argv[0] = "/usr/bin/X"; /* Shorter than the previous file name */ + Debug( "exec %\"[s\n", argv ); + (void)execv( argv[0], argv ); + LogError( "X server %\"s cannot be executed\n", argv[0] ); + } + + exit( 47 ); + case -1: + LogError( "X server fork failed\n" ); + StartServerFailed(); + break; + default: + Debug( "X server forked, pid %d\n", pid ); + d->serverPid = pid; + serverTimeout = d->serverTimeout + now; + break; + } +} + +void +StartServer( struct display *d ) +{ + startingServer = d; + d->startTries = 0; + StartServerOnce(); +} + +void +AbortStartServer( struct display *d ) +{ + if (startingServer == d) + { + if (d->serverStatus != ignore) + { + d->serverStatus = ignore; + serverTimeout = TO_INF; + Debug( "aborting X server start\n" ); + } + startingServer = 0; + } +} + +void +StartServerSuccess() +{ + struct display *d = startingServer; + d->serverStatus = ignore; + serverTimeout = TO_INF; + Debug( "X server ready, starting session\n" ); + StartDisplayP2( d ); +} + +void +StartServerFailed() +{ + struct display *d = startingServer; + if (!d->serverAttempts || d->startTries < d->serverAttempts) { + d->serverStatus = pausing; + serverTimeout = d->openDelay + now; + } else { + d->serverStatus = ignore; + serverTimeout = TO_INF; + startingServer = 0; + LogError( "X server for display %s can't be started," + " session disabled\n", d->name ); + StopDisplay( d ); + } +} + +void +StartServerTimeout() +{ + struct display *d = startingServer; + switch (d->serverStatus) { + case ignore: + case awaiting: + break; /* cannot happen */ + case starting: + LogError( "X server startup timeout, terminating\n" ); + kill( d->serverPid, d->termSignal ); + d->serverStatus = d->termSignal == SIGKILL ? killed : terminated; + serverTimeout = d->serverTimeout + now; + break; + case terminated: + LogInfo( "X server termination timeout, killing\n" ); + kill( d->serverPid, SIGKILL ); + d->serverStatus = killed; + serverTimeout = 10 + now; + break; + case killed: + LogInfo( "X server is stuck in D state; leaving it alone\n" ); + StartServerFailed(); + break; + case pausing: + StartServerOnce(); + break; + } +} + + +Display *dpy; + +/* + * this code is complicated by some TCP failings. On + * many systems, the connect will occasionally hang forever, + * this trouble is avoided by setting up a timeout to Longjmp + * out of the connect (possibly leaving piles of garbage around + * inside Xlib) and give up, terminating the server. + */ + +static Jmp_buf openAbort; + +/* ARGSUSED */ +static void +abortOpen( int n ATTR_UNUSED ) +{ + Longjmp( openAbort, 1 ); +} + +#ifdef XDMCP + +#ifdef STREAMSCONN +# include +#endif + +static void +GetRemoteAddress( struct display *d, int fd ) +{ + char buf[512]; + int len = sizeof(buf); +#ifdef STREAMSCONN + struct netbuf netb; +#endif + + XdmcpDisposeARRAY8( &d->peer ); +#ifdef STREAMSCONN + netb.maxlen = sizeof(buf); + netb.buf = buf; + t_getname( fd, &netb, REMOTENAME ); + len = 8; + /* lucky for us, t_getname returns something that looks like a sockaddr */ +#else + getpeername( fd, (struct sockaddr *)buf, (void *)&len ); +#endif + if (len && XdmcpAllocARRAY8( &d->peer, len )) + memmove( (char *)d->peer.data, buf, len ); + Debug( "got remote address %s %d\n", d->name, d->peer.length ); +} + +#endif /* XDMCP */ + +static int +openErrorHandler( Display *dspl ATTR_UNUSED ) +{ + LogError( "IO Error in XOpenDisplay\n" ); + exit( EX_OPENFAILED_DPY ); + /*NOTREACHED*/ + return (0); +} + +void +WaitForServer( struct display *d ) +{ + volatile int i; + /* static int i; */ + + i = 0; + do { + (void)Signal( SIGALRM, abortOpen ); + (void)alarm( (unsigned)d->openTimeout ); + if (!Setjmp( openAbort )) { + Debug( "before XOpenDisplay(%s)\n", d->name ); + errno = 0; + (void)XSetIOErrorHandler( openErrorHandler ); + dpy = XOpenDisplay( d->name ); +#ifdef STREAMSCONN + { + /* For some reason, the next XOpenDisplay we do is + going to fail, so we might as well get that out + of the way. There is something broken here. */ + Display *bogusDpy = XOpenDisplay( d->name ); + Debug( "bogus XOpenDisplay %s\n", + bogusDpy ? "succeeded" : "failed" ); + if (bogusDpy) XCloseDisplay( bogusDpy ); /* just in case */ + } +#endif + (void)alarm( (unsigned)0 ); + (void)Signal( SIGALRM, SIG_DFL ); + (void)XSetIOErrorHandler( (int (*)( Display * )) 0 ); + Debug( "after XOpenDisplay(%s)\n", d->name ); + if (dpy) { +#ifdef XDMCP + if ((d->displayType & d_location) == dForeign) + GetRemoteAddress( d, ConnectionNumber( dpy ) ); +#endif + RegisterCloseOnFork( ConnectionNumber( dpy ) ); + return; + } + Debug( "OpenDisplay(%s) attempt %d failed: %m\n", d->name, i + 1 ); + sleep( (unsigned)d->openDelay ); + } else { + LogError( "Hung in XOpenDisplay(%s), aborting\n", d->name ); + (void)Signal( SIGALRM, SIG_DFL ); + break; + } + } while (++i < d->openRepeat); + LogError( "Cannot connect to %s, giving up\n", d->name ); + exit( EX_OPENFAILED_DPY ); +} + + +void +ResetServer( struct display *d ) +{ + if (dpy && (d->displayType & d_origin) != dFromXDMCP) + pseudoReset(); +} + + +static Jmp_buf pingTime; + +static void +PingLost( void ) +{ + Longjmp( pingTime, 1 ); +} + +/* ARGSUSED */ +static int +PingLostIOErr( Display *dspl ATTR_UNUSED ) +{ + PingLost(); + return 0; +} + +/* ARGSUSED */ +static void +PingLostSig( int n ATTR_UNUSED ) +{ + PingLost(); +} + +int +PingServer( struct display *d ) +{ + int (*oldError)( Display * ); + void (*oldSig)( int ); + int oldAlarm; + + oldError = XSetIOErrorHandler( PingLostIOErr ); + oldAlarm = alarm( 0 ); + oldSig = Signal( SIGALRM, PingLostSig ); + (void)alarm( d->pingTimeout * 60 ); + if (!Setjmp( pingTime )) { + Debug( "ping X server\n" ); + XSync( dpy, 0 ); + } else { + Debug( "X server dead\n" ); + (void)alarm( 0 ); + (void)Signal( SIGALRM, SIG_DFL ); + XSetIOErrorHandler( oldError ); + return 0; + } + (void)alarm( 0 ); + (void)Signal( SIGALRM, oldSig ); + (void)alarm( oldAlarm ); + Debug( "X server alive\n" ); + XSetIOErrorHandler( oldError ); + return 1; +} diff --git a/tdm/backend/session.c b/tdm/backend/session.c new file mode 100644 index 000000000..9a12ce312 --- /dev/null +++ b/tdm/backend/session.c @@ -0,0 +1,813 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2000-2004 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * subdaemon event loop, etc. + */ + +#include "dm.h" +#include "dm_error.h" + +#include +#include +#include + +#include +#include +#include + +#ifdef WITH_CONSOLE_KIT +#include "consolekit.h" +#endif + +struct display *td; +const char *td_setup = "auto"; + +static void DeleteXloginResources( void ); +static void LoadXloginResources( void ); +static void SetupDisplay( const char *arg ); + + +static Jmp_buf pingTime; + +/* ARGSUSED */ +static void +catchAlrm( int n ATTR_UNUSED ) +{ + Longjmp( pingTime, 1 ); +} + +static Jmp_buf tenaciousClient; + +/* ARGSUSED */ +static void +waitAbort( int n ATTR_UNUSED ) +{ + Longjmp( tenaciousClient, 1 ); +} + +static void +AbortClient( int pid ) +{ + int sig = SIGTERM; + volatile int i; + int retId; + + for (i = 0; i < 4; i++) { + if (kill( -pid, sig ) == -1) { + switch (errno) { + case EPERM: + LogError( "Can't kill client\n" ); + case EINVAL: + case ESRCH: + return; + } + } + if (!Setjmp( tenaciousClient )) { + (void)Signal( SIGALRM, waitAbort ); + (void)alarm( (unsigned)10 ); + retId = wait( (waitType *)0 ); + (void)alarm( (unsigned)0 ); + (void)Signal( SIGALRM, SIG_DFL ); + if (retId == pid) + break; + } else + (void)Signal( SIGALRM, SIG_DFL ); + sig = SIGKILL; + } +} + + +static char * +conv_auto( int what, const char *prompt ATTR_UNUSED ) +{ + switch (what) { + case GCONV_USER: + return curuser; + case GCONV_PASS: + case GCONV_PASS_ND: + return curpass; + default: + LogError( "Unknown authentication data type requested for autologin.\n" ); + return 0; + } +} + +static void +DoAutoLogon( void ) +{ + ReStr( &curuser, td->autoUser ); + ReStr( &curpass, td->autoPass ); + ReStr( &curtype, "classic" ); + cursource = PWSRC_AUTOLOGIN; +} + +static int +AutoLogon( Time_t tdiff ) +{ + Debug( "autoLogon, tdiff = %d, rLogin = %d, goodexit = %d, nuser = %s\n", + tdiff, td->hstent->rLogin, td->hstent->goodExit, td->hstent->nuser ); + if (td->hstent->rLogin == 2 || + (td->hstent->rLogin == 1 && + tdiff <= 0 && !td->hstent->goodExit && !td->hstent->lock)) + { + curuser = td->hstent->nuser; + td->hstent->nuser = 0; + curpass = td->hstent->npass; + td->hstent->npass = 0; + newdmrc = td->hstent->nargs; + td->hstent->nargs = 0; + ReStr( &curtype, "classic" ); + cursource = (td->hstent->rLogin == 1) ? PWSRC_RELOGIN : PWSRC_MANUAL; + return 1; + } else if (*td->autoUser && !td->autoDelay && + ((tdiff > 0 && ((td->displayType & d_lifetime) == dTransient || + !td->hstent->lastExit)) || + td->autoAgain)) + { + unsigned int lmask; + Window dummy1, dummy2; + int dummy3, dummy4, dummy5, dummy6; + XQueryPointer( dpy, DefaultRootWindow( dpy ), + &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, + &lmask ); + if (lmask & ShiftMask) + return 0; + DoAutoLogon(); + return 1; + } + return 0; +} + + +static const struct { + int vcode, echo, ndelay; +} grqs[] = { + { V_GET_TEXT, TRUE, FALSE }, + { V_GET_TEXT, FALSE, FALSE }, + { V_GET_TEXT, TRUE, FALSE }, + { V_GET_TEXT, FALSE, FALSE }, + { V_GET_TEXT, FALSE, TRUE }, + { V_GET_BINARY, 0, 0 } +}; + +char * +conv_interact( int what, const char *prompt ) +{ + char *ret; + int tag; + + GSendInt( grqs[what].vcode ); + if (what == GCONV_BINARY) { + unsigned const char *up = (unsigned const char *)prompt; + int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24); + GSendArr( len, prompt ); + GSendInt( FALSE ); /* ndelay */ + return GRecvArr( &len ); + } else { + GSendStr( prompt ); + GSendInt( grqs[what].echo ); + GSendInt( grqs[what].ndelay ); + ret = GRecvStr(); + if (ret) { + tag = GRecvInt(); + switch (what) { + case GCONV_USER: + /* assert(tag & V_IS_USER); */ + if (curuser) + free( curuser ); + curuser = ret; + break; + case GCONV_PASS: + case GCONV_PASS_ND: + /* assert(tag & V_IS_PASSWORD); */ + if (curpass) + free( curpass ); + curpass = ret; + break; + default: + if (tag & V_IS_USER) + ReStr( &curuser, ret ); + else if (tag & V_IS_PASSWORD) + ReStr( &curpass, ret ); + else if (tag & V_IS_NEWPASSWORD) + ReStr( &newpass, ret ); + else if (tag & V_IS_OLDPASSWORD) + ReStr( &ret, curpass ); + } + } + return ret; + } +} + +static int greeter; +GProc grtproc; +GTalk grttalk; + +GTalk mstrtalk; /* make static; see dm.c */ + +int +CtrlGreeterWait( int wreply ) +{ + int i, cmd, type, rootok; + char *name, *pass, **avptr; +#ifdef XDMCP + ARRAY8Ptr aptr; +#endif + + if (Setjmp( mstrtalk.errjmp )) { + CloseGreeter( TRUE ); + SessionExit( EX_UNMANAGE_DPY ); + } + + while (GRecvCmd( &cmd )) { + switch (cmd) + { + case G_Ready: + Debug( "G_Ready\n" ); + return 0; + case G_GetCfg: + /*Debug ("G_GetCfg\n");*/ + type = GRecvInt(); + /*Debug (" index %#x\n", type);*/ + if (type == C_isLocal) + i = (td->displayType & d_location) == dLocal; + else if (type == C_hasConsole) +#ifdef HAVE_VTS + i = *consoleTTYs != 0; +#else + i = td->console != 0; +#endif + else if (type == C_isAuthorized) + i = td->authorizations != 0; + else + goto normal; + GSendInt( GE_Ok ); + /*Debug (" -> bool %d\n", i);*/ + GSendInt( i ); + break; + normal: + if (!(avptr = FindCfgEnt( td, type ))) { + /*Debug (" -> not found\n");*/ + GSendInt( GE_NoEnt ); + break; + } + switch (type & C_TYPE_MASK) { + default: + /*Debug (" -> unknown type\n");*/ + GSendInt( GE_BadType ); + break; + case C_TYPE_INT: + case C_TYPE_STR: + case C_TYPE_ARGV: +#ifdef XDMCP + case C_TYPE_ARR: +#endif + GSendInt( GE_Ok ); + switch (type & C_TYPE_MASK) { + case C_TYPE_INT: + /*Debug (" -> int %#x (%d)\n", *(int *)avptr, *(int *)avptr);*/ + GSendInt( *(long *)avptr ); + break; + case C_TYPE_STR: + /*Debug (" -> string %\"s\n", *avptr);*/ + GSendStr( *avptr ); + break; + case C_TYPE_ARGV: + /*Debug (" -> sending argv %\"[{s\n", *(char ***)avptr);*/ + GSendArgv( *(char ***)avptr ); + break; +#ifdef XDMCP + case C_TYPE_ARR: + aptr = *(ARRAY8Ptr *)avptr; + /*Debug (" -> sending array %02[*:hhx\n", + aptr->length, aptr->data);*/ + GSendArr( aptr->length, (char *)aptr->data ); + break; +#endif + } + break; + } + break; + case G_ReadDmrc: + Debug( "G_ReadDmrc\n" ); + name = GRecvStr(); + Debug( " user %\"s\n", name ); + if (StrCmp( dmrcuser, name )) { + if (curdmrc) { free( curdmrc ); curdmrc = 0; } + if (dmrcuser) + free( dmrcuser ); + dmrcuser = name; + i = ReadDmrc(); + Debug( " -> status %d\n", i ); + GSendInt( i ); + Debug( " => %\"s\n", curdmrc ); + } else { + if (name) + free( name ); + Debug( " -> status " stringify( GE_Ok ) "\n" ); + GSendInt( GE_Ok ); + Debug( " => keeping old\n" ); + } + break; + case G_GetDmrc: + Debug( "G_GetDmrc\n" ); + name = GRecvStr(); + Debug( " key %\"s\n", name ); + pass = iniEntry( curdmrc, "Desktop", name, 0 ); + Debug( " -> %\"s\n", pass ); + GSendStr( pass ); + if (pass) + free( pass ); + free( name ); + break; +/* case G_ResetDmrc: + Debug ("G_ResetDmrc\n"); + if (newdmrc) { free (newdmrc); newdmrc = 0; } + break; */ + case G_PutDmrc: + Debug( "G_PutDmrc\n" ); + name = GRecvStr(); + Debug( " key %\"s\n", name ); + pass = GRecvStr(); + Debug( " value %\"s\n", pass ); + newdmrc = iniEntry( newdmrc, "Desktop", name, pass ); + free( pass ); + free( name ); + break; + case G_VerifyRootOK: + Debug( "G_VerifyRootOK\n" ); + rootok = TRUE; + goto doverify; + case G_Verify: + Debug( "G_Verify\n" ); + rootok = FALSE; + doverify: + if (curuser) { free( curuser ); curuser = 0; } + if (curpass) { free( curpass ); curpass = 0; } + if (curtype) free( curtype ); + curtype = GRecvStr(); + Debug( " type %\"s\n", curtype ); + cursource = PWSRC_MANUAL; + if (Verify( conv_interact, rootok )) { + Debug( " -> return success\n" ); + GSendInt( V_OK ); + } else + Debug( " -> failure returned\n" ); + break; + case G_AutoLogin: + Debug( "G_AutoLogin\n" ); + DoAutoLogon(); + if (Verify( conv_auto, FALSE )) { + Debug( " -> return success\n" ); + GSendInt( V_OK ); + } else + Debug( " -> failure returned\n" ); + break; + case G_SetupDpy: + Debug( "G_SetupDpy\n" ); + SetupDisplay( 0 ); + td_setup = 0; + GSendInt( 0 ); + break; + default: + return cmd; + } + if (!wreply) + return -1; + } + Debug( "lost connection to greeter\n" ); + return -2; +} + +void +OpenGreeter() +{ + char *name, **env; + static Time_t lastStart; + int cmd; + Cursor xcursor; + + GSet( &grttalk ); + if (greeter) + return; + if (time( 0 ) < lastStart + 10) /* XXX should use some readiness indicator instead */ + SessionExit( EX_UNMANAGE_DPY ); + greeter = 1; + ASPrintf( &name, "greeter for display %s", td->name ); + Debug( "starting %s\n", name ); + + /* Hourglass cursor */ + if ((xcursor = XCreateFontCursor( dpy, XC_watch ))) { + XDefineCursor( dpy, DefaultRootWindow( dpy ), xcursor ); + XFreeCursor( dpy, xcursor ); + } + XFlush( dpy ); + + /* Load system default Resources (if any) */ + LoadXloginResources(); + + grttalk.pipe = &grtproc.pipe; + env = systemEnv( (char *)0 ); + if (GOpen( &grtproc, (char **)0, "_greet", env, name, &td->gpipe )) + SessionExit( EX_UNMANAGE_DPY ); + freeStrArr( env ); + if ((cmd = CtrlGreeterWait( TRUE ))) { + if (cmd != -2) + LogError( "Received unknown or unexpected command %d from greeter\n", cmd ); + CloseGreeter( TRUE ); + SessionExit( EX_UNMANAGE_DPY ); + } + Debug( "%s ready\n", name ); + time( &lastStart ); +} + +int +CloseGreeter( int force ) +{ + int ret; + + if (!greeter) + return EX_NORMAL; + greeter = 0; + ret = GClose (&grtproc, 0, force); + Debug( "greeter for %s stopped\n", td->name ); + if (WaitCode( ret ) > EX_NORMAL && WaitCode( ret ) <= EX_MAX) { + Debug( "greeter-initiated session exit, code %d\n", WaitCode( ret ) ); + SessionExit( WaitCode( ret ) ); + } + return ret; +} + +void +PrepErrorGreet() +{ + if (!greeter) { + OpenGreeter(); + GSendInt( G_ErrorGreet ); + GSendStr( curuser ); + } +} + +static Jmp_buf idleTOJmp; + +/* ARGSUSED */ +static void +IdleTOJmp( int n ATTR_UNUSED ) +{ + Longjmp( idleTOJmp, 1 ); +} + + +static Jmp_buf abortSession; + +/* ARGSUSED */ +static void +catchTerm( int n ATTR_UNUSED ) +{ + Signal( SIGTERM, SIG_IGN ); + Longjmp( abortSession, EX_AL_RESERVER_DPY ); +} + +/* + * We need our own error handlers because we can't be sure what exit code Xlib + * will use, and our Xlib does exit(1) which matches EX_REMANAGE_DPY, which + * can cause a race condition leaving the display wedged. We need to use + * EX_RESERVER_DPY for IO errors, to ensure that the manager waits for the + * server to terminate. For other X errors, we should give up. + */ + +/*ARGSUSED*/ +static int +IOErrorHandler( Display *dspl ATTR_UNUSED ) +{ + LogError( "Fatal X server IO error: %m\n" ); + /* The only X interaction during the session are pings, and those + have an own IOErrorHandler -> not EX_AL_RESERVER_DPY */ + Longjmp( abortSession, EX_RESERVER_DPY ); + /*NOTREACHED*/ + return 0; +} + +/*ARGSUSED*/ +static int +ErrorHandler( Display *dspl ATTR_UNUSED, XErrorEvent *event ) +{ + LogError( "X error\n" ); + if (event->error_code == BadImplementation) + Longjmp( abortSession, EX_UNMANAGE_DPY ); + return 0; +} + +void +ManageSession( struct display *d ) +{ + int ex, cmd; + volatile int clientPid = 0; + volatile Time_t tdiff = 0; +#ifdef WITH_CONSOLE_KIT + char *ck_session_cookie; +#endif + + + td = d; + Debug( "ManageSession %s\n", d->name ); + if ((ex = Setjmp( abortSession ))) { + CloseGreeter( TRUE ); + if (clientPid) + AbortClient( clientPid ); + SessionExit( ex ); + /* NOTREACHED */ + } + (void)XSetIOErrorHandler( IOErrorHandler ); + (void)XSetErrorHandler( ErrorHandler ); + (void)Signal( SIGTERM, catchTerm ); + + (void)Signal( SIGHUP, SIG_IGN ); + + if (Setjmp( grttalk.errjmp )) + Longjmp( abortSession, EX_RESERVER_DPY ); /* EX_RETRY_ONCE */ + +#ifdef XDMCP + if (d->useChooser) + DoChoose(); + /* NOTREACHED */ +#endif + + if (d->hstent->sdRec.how) { + OpenGreeter(); + GSendInt( G_ConfShutdown ); + GSendInt( d->hstent->sdRec.how ); + GSendInt( d->hstent->sdRec.uid ); + GSendStr( d->hstent->sdRec.osname ); + if ((cmd = CtrlGreeterWait( TRUE )) != G_Ready) { + LogError( "Received unknown command %d from greeter\n", cmd ); + CloseGreeter( TRUE ); + } + goto regreet; + } + + tdiff = time( 0 ) - td->hstent->lastExit - td->openDelay; + if (AutoLogon( tdiff )) { + if (!Verify( conv_auto, FALSE )) + goto gcont; + if (greeter) + GSendInt( V_OK ); + } else { + regreet: + OpenGreeter(); + if (Setjmp( idleTOJmp )) { + CloseGreeter( TRUE ); + SessionExit( EX_NORMAL ); + } + Signal( SIGALRM, IdleTOJmp ); + alarm( td->idleTimeout ); +#ifdef XDMCP + if (((d->displayType & d_location) == dLocal) && + d->loginMode >= LOGIN_DEFAULT_REMOTE) + goto choose; +#endif + for (;;) { + Debug( "ManageSession, greeting, tdiff = %d\n", tdiff ); + GSendInt( (*td->autoUser && td->autoDelay && + (tdiff > 0 || td->autoAgain)) ? + G_GreetTimed : G_Greet ); + gcont: + cmd = CtrlGreeterWait( TRUE ); +#ifdef XDMCP + recmd: + if (cmd == G_DChoose) { + choose: + cmd = DoChoose(); + goto recmd; + } + if (cmd == G_DGreet) + continue; +#endif + alarm( 0 ); + if (cmd == G_Ready) + break; + if (cmd == -2) + CloseGreeter( FALSE ); + else { + LogError( "Received unknown command %d from greeter\n", cmd ); + CloseGreeter( TRUE ); + } + goto regreet; + } + } + + if (CloseGreeter( FALSE ) != EX_NORMAL) + goto regreet; + + DeleteXloginResources(); + + if (td_setup) + SetupDisplay( td_setup ); + +#ifdef WITH_CONSOLE_KIT + ck_session_cookie = open_ck_session (getpwnam(curuser), d); + if (!(clientPid = StartClient(ck_session_cookie))) { +#else + if (!(clientPid = StartClient())) { +#endif + LogError( "Client start failed\n" ); + SessionExit( EX_NORMAL ); /* XXX maybe EX_REMANAGE_DPY? -- enable in dm.c! */ + } + Debug( "client Started\n" ); + + /* + * Wait for session to end, + */ + for (;;) { + if (!Setjmp( pingTime )) { + (void)Signal( SIGALRM, catchAlrm ); + (void)alarm( d->pingInterval * 60 ); /* may be 0 */ + (void)Wait4( clientPid ); + (void)alarm( 0 ); + break; + } else { + (void)alarm( 0 ); + if (!PingServer( d )) + catchTerm( SIGTERM ); + } + } + +#ifdef WITH_CONSOLE_KIT + if (ck_session_cookie != NULL) { + close_ck_session (ck_session_cookie); + free (ck_session_cookie); + } +#endif + + /* + * Sometimes the Xsession somehow manages to exit before + * a server crash is noticed - so we sleep a bit and wait + * for being killed. + */ + if (!PingServer( d )) { + Debug( "X server dead upon session exit.\n" ); + if ((d->displayType & d_location) == dLocal) + sleep( 10 ); + SessionExit( EX_AL_RESERVER_DPY ); + } + SessionExit( EX_NORMAL ); /* XXX maybe EX_REMANAGE_DPY? -- enable in dm.c! */ +} + +static int xResLoaded; + +void +LoadXloginResources() +{ + char **args; + char **env; + + if (!xResLoaded && td->resources[0] && access( td->resources, 4 ) == 0) { + env = systemEnv( (char *)0 ); + if ((args = parseArgs( (char **)0, td->xrdb )) && + (args = addStrArr( args, td->resources, -1 ))) + { + Debug( "loading resource file: %s\n", td->resources ); + (void)runAndWait( args, env ); + freeStrArr( args ); + } + freeStrArr( env ); + xResLoaded = TRUE; + } +} + +void +SetupDisplay( const char *arg ) +{ + char **env; + + env = systemEnv( (char *)0 ); + (void)source( env, td->setup, arg ); + freeStrArr( env ); +} + +void +DeleteXloginResources() +{ + int i; + Atom prop; + + if (!xResLoaded) + return; + xResLoaded = FALSE; + prop = XInternAtom( dpy, "SCREEN_RESOURCES", True ); + XDeleteProperty( dpy, RootWindow( dpy, 0 ), XA_RESOURCE_MANAGER ); + if (prop) + for (i = ScreenCount(dpy); --i >= 0; ) + XDeleteProperty( dpy, RootWindow( dpy, i ), prop ); + XSync( dpy, 0 ); +} + + +int +source( char **env, const char *file, const char *arg ) +{ + char **args; + int ret; + + if (file && file[0]) { + Debug( "source %s\n", file ); + if (!(args = parseArgs( (char **)0, file ))) + return waitCompose( 0,0,3 ); + if (arg && !(args = addStrArr( args, arg, -1 ))) + return waitCompose( 0,0,3 ); + ret = runAndWait( args, env ); + freeStrArr( args ); + return ret; + } + return 0; +} + +char ** +inheritEnv( char **env, const char **what ) +{ + char *value; + + for (; *what; ++what) + if ((value = getenv( *what ))) + env = setEnv( env, *what, value ); + return env; +} + +char ** +baseEnv( const char *user ) +{ + char **env; + + env = 0; + +#ifdef _AIX + /* we need the tags SYSENVIRON: and USRENVIRON: in the call to setpenv() */ + env = setEnv( env, "SYSENVIRON:", 0 ); +#endif + + if (user) { + env = setEnv( env, "USER", user ); +#ifdef _AIX + env = setEnv( env, "LOGIN", user ); +#endif + env = setEnv( env, "LOGNAME", user ); + } + +#ifdef _AIX + env = setEnv( env, "USRENVIRON:", 0 ); +#endif + + env = inheritEnv( env, (const char **)exportList ); + + env = setEnv( env, "DISPLAY", + memcmp( td->name, "localhost:", 10 ) ? + td->name : td->name + 9 ); + + if (td->ctrl.path) + env = setEnv( env, "DM_CONTROL", fifoDir ); + + return env; +} + +char ** +systemEnv( const char *user ) +{ + char **env; + + env = baseEnv( user ); + if (td->authFile) + env = setEnv( env, "XAUTHORITY", td->authFile ); + env = setEnv( env, "PATH", td->systemPath ); + env = setEnv( env, "SHELL", td->systemShell ); + return env; +} diff --git a/tdm/backend/sessreg.c b/tdm/backend/sessreg.c new file mode 100644 index 000000000..b507f8141 --- /dev/null +++ b/tdm/backend/sessreg.c @@ -0,0 +1,307 @@ +/* + +Copyright 1990, 1998 The Open Group +Copyright 2005 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +/* + + Author: Keith Packard, MIT X Consortium + Lastlog support and dynamic utmp entry allocation + by Andreas Stolcke + +*/ + +#define _FILE_OFFSET_BITS 64 +#include "dm.h" +#include "dm_error.h" + +#if defined(__svr4__) || defined(__Lynx__) || defined(__QNX__) || defined(__APPLE__) || defined(_SEQUENT_) /*|| defined(USE_PAM)*/ +# define NO_LASTLOG +#endif + +#ifndef NO_LASTLOG +# ifdef HAVE_LASTLOG_H +# include +# endif +# ifndef LLOG_FILE +# ifdef _PATH_LASTLOGX +# define LLOG_FILE _PATH_LASTLOGX +# elif defined(_PATH_LASTLOG) +# define LLOG_FILE _PATH_LASTLOG +# else +# define LLOG_FILE "/usr/adm/lastlog" +# endif +# endif +#endif + +#if !defined(__svr4__) && !defined(__QNX__) +# define SESSREG_HOST +#endif + +#ifdef BSD +# if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) +/* *BSD doesn't like a ':0' type entry in utmp */ +# define NO_UTMP +# endif +#endif + +#ifdef BSD_UTMP +# ifndef TTYS_FILE +# define TTYS_FILE "/etc/ttys" +# endif +#endif + +#ifdef _AIX +# define UTL_PFX "xdm/" +# define UTL_OFF strlen(UTL_PFX) +#else +# define UTL_OFF 0 +#endif + +#ifndef BSD_UTMP +static unsigned +crc32s( const unsigned char *str ) +{ + int b; + unsigned crc = 0xffffffff, by; + + for (; *str; str++) { + by = (crc & 255) ^ *str; + for (b = 0; b < 8; b++) + by = (by >> 1) ^ (-(by & 1) & 0xedb88320); + crc = (crc >> 8) ^ by; + } + return crc; +} +#endif + +void +sessreg( struct display *d, int pid, const char *user, int uid ) +{ + char *dot, *colon; + int left, clen; +#ifdef BSD_UTMP + FILE *ttys; + int utmp, slot, freeslot; + STRUCTUTMP entry; +#else + unsigned crc, i; +#endif + int wtmp, c; +#ifndef NO_LASTLOG + int llog; + struct LASTLOG ll; +#endif + STRUCTUTMP ut_ent; + + if (!d->useSessReg) + return; + + bzero( &ut_ent, sizeof(ut_ent) ); + + if (pid) { + strncpy( ut_ent.ut_user, user, sizeof(ut_ent.ut_user) ); +#ifndef BSD_UTMP + ut_ent.ut_pid = pid; + ut_ent.ut_type = USER_PROCESS; + } else { + ut_ent.ut_type = DEAD_PROCESS; +#endif + } + ut_ent.ut_time = time( 0 ); + + colon = strchr( d->name, ':' ); + clen = strlen( colon ); + if (clen > (int)(sizeof(ut_ent.ut_line) - UTL_OFF) - 2) + return; /* uhm, well ... */ + if (colon == d->name) { +#ifndef BSD_UTMP + strncpy( ut_ent.ut_id, d->name, sizeof(ut_ent.ut_id) ); +#endif + left = 0; + } else { +#ifdef SESSREG_HOST +# ifndef BSD_UTMP + if (pid) +# endif + { + if (colon - d->name > (int)sizeof(ut_ent.ut_host)) { + ut_ent.ut_host[0] = '~'; + memcpy( ut_ent.ut_host + 1, + colon - (sizeof(ut_ent.ut_host) - 1), + sizeof(ut_ent.ut_host) - 1 ); + } else + memcpy( ut_ent.ut_host, d->name, colon - d->name ); + } +#endif +#ifndef BSD_UTMP + crc = crc32s( d->name ); + ut_ent.ut_id[0] = crc % 26 + 'A'; + crc /= 26; + for (i = 1; i < sizeof(ut_ent.ut_id); i++) { + c = crc % 62; + crc /= 62; + ut_ent.ut_id[i] = c < 26 ? c + 'A' : + c < 52 ? c - 26 + 'a' : c - 52 + '0'; + } +#endif + left = sizeof(ut_ent.ut_line) - UTL_OFF - clen; + if (colon - d->name <= left) { + clen += colon - d->name; + colon = d->name; + left = 0; + } else { + dot = strchr( d->name, '.' ); + if (dot && dot - d->name < left) { + memcpy( ut_ent.ut_line + UTL_OFF, d->name, left - 1 ); + ut_ent.ut_line[UTL_OFF + left - 1] = '~'; + } else { + memcpy( ut_ent.ut_line + UTL_OFF, d->name, left/2 - 1 ); + ut_ent.ut_line[UTL_OFF + left/2 - 1] = '~'; + if (dot) { + memcpy( ut_ent.ut_line + UTL_OFF + left/2, + dot - (left - left/2 - 1), + left - left/2 - 1 ); + ut_ent.ut_line[UTL_OFF + left - 1] = '~'; + } else + memcpy( ut_ent.ut_line + UTL_OFF + left/2, + colon - (left - left/2), left - left/2 ); + } + } + } +#ifdef UTL_PFX + memcpy( ut_ent.ut_line, UTL_PFX, UTL_OFF ); +#endif + memcpy( ut_ent.ut_line + UTL_OFF + left, colon, clen ); + +#ifndef NO_UTMP +# ifdef BSD_UTMP + if ((utmp = open( UTMP_FILE, O_RDWR )) < 0) + Debug( "cannot open utmp file " UTMP_FILE ": %m\n" ); + else { + + slot = 1; + if (pid) { + if (!(ttys = fopen( TTYS_FILE, "r" ))) + LogWarn( "Cannot open tty file " TTYS_FILE ": %m\n" ); + else { + int column0 = 1; + while ((c = getc( ttys )) != EOF) + if (c == '\n') { + slot++; + column0 = 1; + } else + column0 = 0; + if (!column0) + slot++; + fclose( ttys ); + } + } + freeslot = -1; + lseek( utmp, slot * sizeof(entry), SEEK_SET ); + while (read( utmp, (char *)&entry, sizeof(entry) ) == sizeof(entry)) { + if (!strncmp( entry.ut_line, ut_ent.ut_line, + sizeof(entry.ut_line) )) +# ifdef SESSREG_HOST + if (!strncmp( entry.ut_host, ut_ent.ut_host, + sizeof(entry.ut_host) )) +# endif + goto found; + if (freeslot < 0 && *entry.ut_user == '\0') + freeslot = slot; + slot++; + } + if (!pid) { + Debug( "utmp entry for display %s vanished\n", d->name ); + goto skip; + } + if (freeslot >= 0) + slot = freeslot; + found: + +# ifdef SESSREG_HOST + if (!pid) + bzero( ut_ent.ut_host, sizeof(ut_ent.ut_host) ); +# endif + lseek( utmp, slot * sizeof(ut_ent), SEEK_SET ); + if (write( utmp, (char *)&ut_ent, sizeof(ut_ent) ) != sizeof(ut_ent)) + LogError( "Cannot write utmp file " UTMP_FILE ": %m\n" ); + skip: + close( utmp ); + } +# else + UTMPNAME( UTMP_FILE ); + SETUTENT(); + PUTUTLINE( &ut_ent ); + ENDUTENT(); +# endif +#endif + + if ((wtmp = open( WTMP_FILE, O_WRONLY|O_APPEND )) < 0) + Debug( "cannot open wtmp file " WTMP_FILE ": %m\n" ); + else { + if (write( wtmp, (char *)&ut_ent, sizeof(ut_ent) ) != sizeof(ut_ent)) + LogError( "Cannot write wtmp file " WTMP_FILE ": %m\n" ); + close( wtmp ); + } + +#ifndef NO_LASTLOG + if (pid) { + bzero( (char *)&ll, sizeof(ll) ); + ll.ll_time = ut_ent.ut_time; + memcpy( ll.ll_line, ut_ent.ut_line, sizeof(ll.ll_line) ); + memcpy( ll.ll_host, ut_ent.ut_host, sizeof(ll.ll_host) ); +# ifdef HAVE_UTMPX + updlastlogx( LLOG_FILE, uid, &ll ); +# else + if ((llog = open( LLOG_FILE, O_RDWR )) < 0) + Debug( "cannot open lastlog file " LLOG_FILE ": %m\n" ); + else { + lseek( llog, (off_t)uid * sizeof(ll), SEEK_SET ); + if (write( llog, (char *)&ll, sizeof(ll) ) != sizeof(ll)) + LogError( "Cannot write llog file " WTMP_FILE ": %m\n" ); + close( llog ); + } +# endif + } +#else + (void)uid; +#endif + +#ifdef UTL_PFX + { + char tmp[sizeof("/dev/") + sizeof(ut_ent.ut_line)]; + mkdir( "/dev/" UTL_PFX, 0755 ); + chmod( "/dev/" UTL_PFX, 0755 ); + sprintf( tmp, "/dev/%.*s", sizeof(ut_ent.ut_line), ut_ent.ut_line ); + if (pid) + close( creat( tmp, 0644 ) ); + else + unlink( tmp ); + } +#endif +} diff --git a/tdm/backend/socket.c b/tdm/backend/socket.c new file mode 100644 index 000000000..677a3d32f --- /dev/null +++ b/tdm/backend/socket.c @@ -0,0 +1,418 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2002 Sun Microsystems, Inc. All rights reserved. +Copyright 2002,2004 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * socket.c - Support for BSD sockets + */ + +#include "dm.h" + +#if defined(XDMCP) && !defined(STREAMSCONN) + +#include "dm_error.h" +#include "dm_socket.h" + +#include +#include + +static int c_request_port; + +static int +CreateListeningSocket( struct sockaddr *sock_addr, int salen ) +{ + int fd; +#if defined(IPv6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) + int on = 0; +#endif + const char *addrstring = "unknown"; +#if defined(IPv6) && defined(AF_INET6) + char addrbuf[INET6_ADDRSTRLEN]; +#endif + + if (!request_port) + return -1; + + if (debugLevel & DEBUG_CORE) { +#if defined(IPv6) && defined(AF_INET6) + void *ipaddr; + if (sock_addr->sa_family == AF_INET6) + ipaddr = & ((struct sockaddr_in6 *)sock_addr)->sin6_addr; + else + ipaddr = & ((struct sockaddr_in *)sock_addr)->sin_addr; + addrstring = + inet_ntop( sock_addr->sa_family, ipaddr, addrbuf, sizeof(addrbuf) ); + +#else + addrstring = inet_ntoa( ((struct sockaddr_in *)sock_addr)->sin_addr ); +#endif + + Debug( "creating socket to listen on port %d of address %s\n", + request_port, addrstring ); + } + + if ((fd = socket( sock_addr->sa_family, SOCK_DGRAM, 0 )) == -1) { + LogError( "XDMCP socket creation failed, errno %d\n", errno ); + return -1; + } +#if defined(IPv6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) + setsockopt( fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on) ); +#endif + + if (bind( fd, sock_addr, salen ) == -1) { + LogError( "error %d binding socket address %d\n", errno, request_port ); + close( fd ); + return -1; + } + + RegisterCloseOnFork( fd ); + RegisterInput( fd ); + return fd; +} + +struct socklist { + struct socklist *next; + struct socklist *mcastgroups; + struct sockaddr *addr; + int salen; + int addrlen; + int fd; + int ref; /* referenced bit - see UpdateListenSockets */ +}; + +static struct socklist *listensocks; + +static void +DestroyListeningSocket( struct socklist *s ) +{ + struct socklist *g, *n; + + if (s->fd >= 0) { + CloseNClearCloseOnFork( s->fd ); + UnregisterInput( s->fd ); + s->fd = -1; + } + if (s->addr) { + free( s->addr ); + s->addr = NULL; + } + for (g = s->mcastgroups; g; g = n) { + n = g->next; + if (g->addr) + free( g->addr ); + free( g ); + } + s->mcastgroups = NULL; +} + +static struct socklist* +FindInList( struct socklist *list, ARRAY8Ptr addr ) +{ + struct socklist *s; + + for (s = list; s; s = s->next) { + if (s->addrlen == addr->length) { + char *addrdata; + + switch (s->addr->sa_family) { + case AF_INET: + addrdata = (char *) + &(((struct sockaddr_in *)s->addr)->sin_addr.s_addr); + break; +#if defined(IPv6) && defined(AF_INET6) + case AF_INET6: + addrdata = (char *) + &(((struct sockaddr_in6 *)s->addr)->sin6_addr.s6_addr); + break; +#endif + default: + /* Unrecognized address family */ + continue; + } + if (!memcmp( addrdata, addr->data, addr->length )) + return s; + } + } + return NULL; +} + +static struct socklist * +CreateSocklistEntry( ARRAY8Ptr addr ) +{ + struct socklist *s; + + if (!(s = Calloc( 1, sizeof(struct socklist) ))) + return NULL; + + if (addr->length == 4) { /* IPv4 */ + struct sockaddr_in *sin4; + sin4 = Calloc( 1, sizeof(struct sockaddr_in) ); +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + sin4->sin_len = sizeof(struct sockaddr_in); +#endif + s->addr = (struct sockaddr *)sin4; + s->salen = sizeof(struct sockaddr_in); + s->addrlen = sizeof(struct in_addr); + sin4->sin_family = AF_INET; + sin4->sin_port = htons( (short)request_port ); + memcpy( &sin4->sin_addr, addr->data, addr->length ); + } +#if defined(IPv6) && defined(AF_INET6) + else if (addr->length == 16) { /* IPv6 */ + struct sockaddr_in6 *sin6; + sin6 = Calloc( 1, sizeof(struct sockaddr_in6) ); +#ifdef SIN6_LEN + sin6->sin6_len = sizeof(struct sockaddr_in6); +#endif + s->addr = (struct sockaddr *)sin6; + s->salen = sizeof(struct sockaddr_in6); + s->addrlen = sizeof(struct in6_addr); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = htons( (short)request_port ); + memcpy( &sin6->sin6_addr, addr->data, addr->length ); + } +#endif + else { + /* Unknown address type */ + free( s ); + s = NULL; + } + return s; +} + +static void +UpdateListener( ARRAY8Ptr addr, void **closure ) +{ + struct socklist *s; + + *closure = NULL; + + if (addr == NULL) { + ARRAY8 tmpaddr; + struct in_addr in; +#if defined(IPv6) && defined(AF_INET6) + struct in6_addr in6 = in6addr_any; + tmpaddr.length = sizeof(in6); + tmpaddr.data = (CARD8Ptr) &in6; + UpdateListener( &tmpaddr, closure ); + if (*closure) + return; +#endif + in.s_addr = htonl( INADDR_ANY ); + tmpaddr.length = sizeof(in); + tmpaddr.data = (CARD8Ptr) ∈ + UpdateListener( &tmpaddr, closure ); + return; + } + + if (c_request_port == request_port && + (s = FindInList( listensocks, addr ))) + { + *closure = (void *)s; + s->ref = 1; + return; + } + + if (!(s = CreateSocklistEntry( addr ))) + return; + + if ((s->fd = CreateListeningSocket( s->addr, s->salen )) < 0) { + free( s->addr ); + free( s ); + return; + } + s->ref = 1; + s->next = listensocks; + listensocks = s; + *closure = (void *)s; +} + +#define JOIN_MCAST_GROUP 0 +#define LEAVE_MCAST_GROUP 1 + +static void +ChangeMcastMembership( struct socklist *s, struct socklist *g, int op ) +{ + int sockopt; + + switch (s->addr->sa_family) + { + case AF_INET: + { + struct ip_mreq mreq; + memcpy( &mreq.imr_multiaddr, + &((struct sockaddr_in *)g->addr)->sin_addr, + sizeof(struct in_addr) ); + memcpy( &mreq.imr_interface, + &((struct sockaddr_in *)s->addr)->sin_addr, + sizeof(struct in_addr) ); + if (op == JOIN_MCAST_GROUP) + sockopt = IP_ADD_MEMBERSHIP; + else + sockopt = IP_DROP_MEMBERSHIP; + if (setsockopt( s->fd, IPPROTO_IP, sockopt, + &mreq, sizeof(mreq) ) < 0) { + LogError( "XDMCP socket multicast %s to %s failed, errno %d\n", + (op == JOIN_MCAST_GROUP) ? "join" : "drop", + inet_ntoa( ((struct sockaddr_in *)g->addr)->sin_addr ), + errno ); + } else if (debugLevel & DEBUG_CORE) { + Debug( "XDMCP socket multicast %s to %s succeeded\n", + (op == JOIN_MCAST_GROUP) ? "join" : "drop", + inet_ntoa( ((struct sockaddr_in *)g->addr)->sin_addr ) ); + } + return; + } +#if defined(IPv6) && defined(AF_INET6) +# ifndef IPV6_JOIN_GROUP +# define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP +# endif +# ifndef IPV6_LEAVE_GROUP +# define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP +# endif + case AF_INET6: + { + struct ipv6_mreq mreq6; + memcpy( &mreq6.ipv6mr_multiaddr, + &((struct sockaddr_in6 *)g->addr)->sin6_addr, + sizeof(struct in6_addr) ); + mreq6.ipv6mr_interface = 0; /* TODO: fix this */ + if (op == JOIN_MCAST_GROUP) + sockopt = IPV6_JOIN_GROUP; + else + sockopt = IPV6_LEAVE_GROUP; + if (setsockopt( s->fd, IPPROTO_IPV6, sockopt, + &mreq6, sizeof(mreq6) ) < 0) + { + int saveerr = errno; + char addrbuf[INET6_ADDRSTRLEN]; + + inet_ntop( s->addr->sa_family, + &((struct sockaddr_in6 *)g->addr)->sin6_addr, + addrbuf, sizeof(addrbuf) ); + + LogError( "XDMCP socket multicast %s to %s failed, errno %d\n", + (op == JOIN_MCAST_GROUP) ? "join" : "drop", addrbuf, + saveerr ); + } else if (debugLevel & DEBUG_CORE) { + char addrbuf[INET6_ADDRSTRLEN]; + + inet_ntop( s->addr->sa_family, + &((struct sockaddr_in6 *)g->addr)->sin6_addr, + addrbuf, sizeof(addrbuf) ); + + Debug( "XDMCP socket multicast %s to %s succeeded\n", + (op == JOIN_MCAST_GROUP) ? "join" : "drop", addrbuf ); + } + return; + } +#endif + } +} + +static void +UpdateMcastGroup( ARRAY8Ptr addr, void **closure ) +{ + struct socklist *s = (struct socklist *)*closure; + struct socklist *g; + + if (!s) + return; + + /* Already in the group, mark & continue */ + if ((g = FindInList( s->mcastgroups, addr ))) { + g->ref = 1; + return; + } + + /* Need to join the group */ + if (!(g = CreateSocklistEntry( addr ))) + return; + + ChangeMcastMembership( s, g, JOIN_MCAST_GROUP ); + free( g ); +} + +/* Open or close listening sockets to match the current settings read in + from the access database. */ +void +UpdateListenSockets( void ) +{ + struct socklist *s, *g, **ls, **lg; + void *tmpPtr = NULL; + + /* Clear Ref bits - any not marked by UpdateCallback will be closed */ + for (s = listensocks; s; s = s->next) { + s->ref = 0; + for (g = s->mcastgroups; g; g = g->next) + g->ref = 0; + } + ForEachListenAddr( UpdateListener, UpdateMcastGroup, &tmpPtr ); + c_request_port = request_port; + for (ls = &listensocks; (s = *ls); ) + if (!s->ref) { + DestroyListeningSocket( s ); + *ls = s->next; + free( s ); + } else { + ls = &s->next; + for (lg = &s->mcastgroups; (g = *lg); ) + if (!g->ref) { + ChangeMcastMembership( s, g, LEAVE_MCAST_GROUP ); + *lg = g->next; + free( g ); + } else + lg = &g->next; + } +} + +int +AnyListenSockets( void ) +{ + return listensocks != NULL; +} + +int +ProcessListenSockets( FD_TYPE *reads ) +{ + struct socklist *s; + int ret = 0; + + for (s = listensocks; s; s = s->next) + if (FD_ISSET( s->fd, reads )) { + ProcessRequestSocket( s->fd ); + ret = 1; + } + return ret; +} + +#endif /* !STREAMSCONN && XDMCP */ diff --git a/tdm/backend/streams.c b/tdm/backend/streams.c new file mode 100644 index 000000000..f60fb955e --- /dev/null +++ b/tdm/backend/streams.c @@ -0,0 +1,127 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2002,2004 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * streams.c - Support for STREAMS + */ + +#include "dm.h" + +#if defined(XDMCP) && defined(STREAMSCONN) + +#include "dm_error.h" + +#include +#include +#include +#include + +static int xdmcpFd = -1, c_request_port; + +void +UpdateListenSockets( void ) +{ + struct t_bind bind_addr; + struct netconfig *nconf; + struct nd_hostserv service; + struct nd_addrlist *servaddrs; + char bindbuf[15]; + int it; + + if (c_request_port == request_port) + return; + c_request_port = request_port; + + if (xdmcpFd != -1) { + CloseNClearCloseOnFork( xdmcpFd ); + UnregisterInput( xdmcpFd ); + xdmcpFd = -1; + } + + if (!request_port) + return; + + Debug( "creating UDP stream %d\n", request_port ); + + nconf = getnetconfigent( "udp" ); + if (!nconf) { + t_error( "getnetconfigent udp" ); + return; + } + + xdmcpFd = t_open( nconf->nc_device, O_RDWR, NULL ); + if (xdmcpFd == -1) { + LogError( "XDMCP stream creation failed\n" ); + t_error( "CreateWellKnownSockets(xdmcpFd): t_open failed" ); + return; + } + + service.h_host = HOST_SELF; + sprintf( bindbuf, "%d", request_port ); + service.h_serv = bindbuf; + netdir_getbyname( nconf, &service, &servaddrs ); + freenetconfigent( nconf ); + + bind_addr.qlen = 5; + bind_addr.addr.buf = servaddrs->n_addrs[0].buf; + bind_addr.addr.len = servaddrs->n_addrs[0].len; + bind_addr.addr.maxlen = servaddrs->n_addrs[0].len; + it = t_bind( xdmcpFd, &bind_addr, &bind_addr ); + netdir_free( (char *)servaddrs, ND_ADDRLIST ); + if (it < 0) { + LogError( "Error binding UDP port %d\n", request_port ); + t_error( "CreateWellKnownSockets(xdmcpFd): t_bind failed" ); + t_close( xdmcpFd ); + xdmcpFd = -1; + return; + } + RegisterCloseOnFork( xdmcpFd ); + RegisterInput( xdmcpFd ); +} + +int +AnyListenSockets( void ) +{ + return xdmcpFd != -1; +} + +int +ProcessRequestSockets( FD_TYPE *reads ) +{ + if (xdmcpFd >= 0 && FD_ISSET( xdmcpFd, reads )) { + ProcessRequestSocket( xdmcpFd ); + return 1; + } + return 0; +} + +#endif /* STREAMSCONN && XDMCP */ diff --git a/tdm/backend/util.c b/tdm/backend/util.c new file mode 100644 index 000000000..7dd58f031 --- /dev/null +++ b/tdm/backend/util.c @@ -0,0 +1,637 @@ +/* + +Copyright 1989, 1998 The Open Group +Copyright 2000-2005 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * various utility routines + */ + +#include "dm.h" +#include "dm_auth.h" +#include "dm_error.h" + +#include +#include +#include +#include +#include + +#if 0 /*def USG; this was hpux once upon a time */ +# define NEED_UTSNAME +#endif + +#ifdef NEED_UTSNAME +# include +#endif + +void * +Calloc( size_t nmemb, size_t size ) +{ + void *ret; + + if (!(ret = calloc( nmemb, size ))) + LogOutOfMem(); + return ret; +} + +void * +Malloc( size_t size ) +{ + void *ret; + + if (!(ret = malloc( size ))) + LogOutOfMem(); + return ret; +} + +void * +Realloc( void *ptr, size_t size ) +{ + void *ret; + + if (!(ret = realloc( ptr, size )) && size) + LogOutOfMem(); + return ret; +} + +int +StrCmp( const char *s1, const char *s2 ) +{ + if (s1 == s2) + return 0; + if (!s1) + return -1; + if (!s2) + return 1; + return strcmp( s1, s2 ); +} + +void +WipeStr( char *str ) +{ + if (str) { + bzero( str, strlen( str ) ); + free( str ); + } +} + +#ifndef HAVE_STRNLEN +int +StrNLen( const char *s, int max ) +{ + unsigned l; + + for (l = 0; l < (unsigned)max && s[l]; l++); + return l; +} +#endif + +/* duplicate src; wipe & free old dst string */ +int +ReStrN( char **dst, const char *src, int len ) +{ + char *ndst = 0; + + if (src) { + if (len < 0) + len = strlen( src ); + if (*dst && !memcmp( *dst, src, len ) && !(*dst)[len]) + return 1; + if (!(ndst = Malloc( len + 1 ))) { + WipeStr( *dst ); + *dst = 0; + return 0; + } + memcpy( ndst, src, len ); + ndst[len] = 0; + } + WipeStr( *dst ); /* make an option, if we should become heavily used */ + *dst = ndst; + return 2; +} + +int +ReStr( char **dst, const char *src ) +{ + return ReStrN( dst, src, -1 ); +} + +/* duplicate src */ +int +StrNDup( char **dst, const char *src, int len ) +{ + if (src) { + if (len < 0) + len = strlen( src ); + if (!(*dst = Malloc( len + 1 ))) + return 0; + memcpy( *dst, src, len ); + (*dst)[len] = 0; + } else + *dst = 0; + return 1; +} + +int +StrDup( char **dst, const char *src ) +{ + return StrNDup( dst, src, -1 ); +} + +/* append any number of strings to dst */ +int +StrApp( char **dst, ... ) +{ + int len; + char *bk, *pt, *dp; + va_list va; + + len = 1; + if (*dst) + len += strlen( *dst ); + va_start( va, dst ); + for (;;) { + pt = va_arg( va, char * ); + if (!pt) + break; + len += strlen( pt ); + } + va_end( va ); + if (!(bk = Malloc( len ))) { + if (*dst) { + free( *dst ); + *dst = 0; + } + return 0; + } + dp = bk; + if (*dst) { + len = strlen( *dst ); + memcpy( dp, *dst, len ); + dp += len; + free( *dst ); + } + va_start( va, dst ); + for (;;) { + pt = va_arg( va, char * ); + if (!pt) + break; + len = strlen( pt ); + memcpy( dp, pt, len ); + dp += len; + } + va_end( va ); + *dp = '\0'; + *dst = bk; + return 1; +} + + +char ** +initStrArr( char **arr ) +{ + if (!arr && (arr = Malloc( sizeof(char *) ))) + arr[0] = 0; + return arr; +} + +int +arrLen( char **arr ) +{ + int nu = 0; + if (arr) + for (; arr[nu]; nu++); + return nu; +} + +static char ** +extStrArr( char **arr, char ***strp ) +{ + char **rarr; + int nu; + + nu = arrLen( arr ); + if ((rarr = Realloc( arr, sizeof(char *) * (nu + 2) ))) { + rarr[nu + 1] = 0; + *strp = rarr + nu; + return rarr; + } + freeStrArr( arr ); + return 0; +} + +char ** +addStrArr( char **arr, const char *str, int len ) +{ + char **strp; + + if ((arr = extStrArr( arr, &strp ))) { + if (StrNDup( strp, str, len )) + return arr; + freeStrArr( arr ); + } + return 0; +} + +char ** +xCopyStrArr( int rn, char **arr ) +{ + char **rarr; + int nu; + + nu = arrLen( arr ); + if ((rarr = Calloc( sizeof(char *), nu + rn + 1 ))) + memcpy( rarr + rn, arr, sizeof(char *) * nu ); + return rarr; +} + +void +freeStrArr( char **arr ) +{ + char **a; + + if (arr) { + for (a = arr; *a; a++) + free( *a ); + free( arr ); + } +} + + +char ** +parseArgs( char **argv, const char *string ) +{ + const char *word; + char **strp, *str; + int wlen; + + if (!(argv = initStrArr( argv ))) + return 0; + while (*string) { + if (isspace( *string )) { + string++; + continue; + } + word = string; + wlen = 0; + do { + if (*string == '\\') { + if (!*++string) + string--; + wlen++; + } else if (*string == '\'') { + while (*++string != '\'' && *string) + wlen++; + } else if (*string == '"') { + while (*++string != '"' && *string) { + if (*string == '\\') { + if (!*++string) + string--; + } + wlen++; + } + } else + wlen++; + } while (*++string && !isspace( *string )); + if (!(argv = extStrArr( argv, &strp ))) + return 0; + if (!(*strp = str = Malloc( wlen + 1 ))) { + freeStrArr( argv ); + return 0; + } + do { + if (*word == '\\') { + if (!*++word) + word--; + *str++ = *word; + } else if (*word == '\'') { + while (*++word != '\'' && *word) + *str++ = *word; + } else if (*word == '"') { + while (*++word != '"' && *word) { + if (*word == '\\') { + if (!*++word) + word--; + } + *str++ = *word; + } + } else + *str++ = *word; + } while (*++word && !isspace( *word )); + *str = 0; + } + return argv; +} + + +const char * +getEnv( char **e, const char *name ) +{ + if (e) { + int l = strlen( name ); + for (; *e; e++) + if (!memcmp( *e, name, l ) && (*e)[l] == '=') + return (*e) + l + 1; + } + return 0; +} + +char ** +setEnv( char **e, const char *name, const char *value ) +{ + char **new, **old; + char *newe; + int envsize; + int l; + +#ifdef _AIX + /* setpenv() depends on "SYSENVIRON:", not "SYSENVIRON:=" */ + if (!value) { + if (!StrDup( &newe, name )) + return e; + } else +#endif + { + newe = 0; + if (!StrApp( &newe, name, "=", value, (char *)0 )) + return e; + } + envsize = 0; + if (e) { + l = strlen( name ); + for (old = e; *old; old++) + if (!memcmp( *old, name, l ) && ((*old)[l] == '=' || !(*old)[l])) + { + free( *old ); + *old = newe; + return e; + } + envsize = old - e; + } + if (!(new = (char **) + Realloc( (char *)e, (unsigned)((envsize + 2) * sizeof(char *)) ))) + { + free( newe ); + return e; + } + new[envsize] = newe; + new[envsize + 1] = 0; + return new; +} + +char ** +putEnv( const char *string, char **env ) +{ + char *n; + char *b; + + if (!(b = strchr( string, '=' ))) + return NULL; + if (!StrNDup( &n, string, b - string )) + return NULL; + env = setEnv( env, n, b + 1 ); + free( n ); + return env; +} + +static int +GetHostname( char *buf, int maxlen ) +{ + int len; + +#ifdef NEED_UTSNAME + /* + * same host name crock as in server and xinit. + */ + struct utsname name; + + uname( &name ); + len = strlen( name.nodename ); + if (len >= maxlen) len = maxlen - 1; + memcpy( buf, name.nodename, len ); + buf[len] = '\0'; +#else + buf[0] = '\0'; + (void)gethostname( buf, maxlen ); + buf[maxlen - 1] = '\0'; + len = strlen( buf ); +#endif /* NEED_UTSNAME */ + return len; +} + +static char localHostbuf[256]; +static int gotLocalHostname; + +const char * +localHostname( void ) +{ + if (!gotLocalHostname) + { + GetHostname( localHostbuf, sizeof(localHostbuf) - 1 ); + gotLocalHostname = 1; + } + return localHostbuf; +} + +static int +AtomicIO( ssize_t (*f)( int, void *, size_t ), int fd, void *buf, int count ) +{ + int ret, rlen; + + for (rlen = 0; rlen < count; ) { + dord: + ret = f( fd, (void *)((char *)buf + rlen), count - rlen ); + if (ret < 0) { + if (errno == EINTR) + goto dord; + if (errno == EAGAIN) + break; + return -1; + } + if (!ret) + break; + rlen += ret; + } + return rlen; +} + +int +Reader( int fd, void *buf, int count ) +{ + return AtomicIO( read, fd, buf, count ); +} + +int +Writer( int fd, const void *buf, int count ) +{ + return AtomicIO( (ssize_t(*)( int, void *, size_t ))write, + fd, (void *)buf, count ); +} + +int +fGets( char *buf, int max, FILE *f ) +{ + int len; + + if (!fgets( buf, max, f )) + return -1; + len = strlen( buf ); + if (len && buf[len - 1] == '\n') + buf[--len] = 0; + return len; +} + +time_t +mTime( const char *fn ) +{ + struct stat st; + + if (stat( fn, &st )) + return -1; + else + return st.st_mtime; +} + +void +randomStr( char *s ) +{ + static const char letters[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + unsigned i, rn = secureRandom(); + + for (i = 0; i < 6; i++) { + *s++ = letters[rn % 62]; + rn /= 62; + } + *s = 0; +} + +static int +StrNChrCnt( const char *s, int slen, char c ) +{ + int i, cnt; + + for (i = cnt = 0; i < slen && s[i]; i++) + if (s[i] == c) + cnt++; + return cnt; +} + +/* X -from ip6-addr does not work here, so i don't know whether this is needed. +#define IP6_MAGIC +*/ + +void +ListSessions( int flags, struct display *d, void *ctx, + void (*emitXSess)( struct display *, struct display *, void * ), + void (*emitTTYSess)( STRUCTUTMP *, struct display *, void * ) ) +{ + struct display *di; +#ifdef IP6_MAGIC + int le, dot; +#endif +#ifdef BSD_UTMP + int fd; + struct utmp ut[1]; +#else + STRUCTUTMP *ut; +#endif + + for (di = displays; di; di = di->next) + if (((flags & lstRemote) || (di->displayType & d_location) == dLocal) && + (di->status == remoteLogin || + ((flags & lstPassive) ? di->status == running : di->userSess >= 0))) + emitXSess( di, d, ctx ); + + if (!(flags & lstTTY)) + return; + +#ifdef BSD_UTMP + if ((fd = open( UTMP_FILE, O_RDONLY )) < 0) + return; + while (Reader( fd, ut, sizeof(ut[0]) ) == sizeof(ut[0])) { + if (*ut->ut_user) { /* no idea how to list passive TTYs on BSD */ +#else + SETUTENT(); + while ((ut = GETUTENT())) { + if (ut->ut_type == USER_PROCESS +# if 0 /* list passive TTYs at all? not too sensible, i think. */ + || ((flags & lstPassive) && ut->ut_type == LOGIN_PROCESS) +# endif + ) + { +#endif + if (*ut->ut_host) { /* from remote or x */ + if (!(flags & lstRemote)) + continue; + } else { + /* hack around broken konsole which does not set ut_host. */ + /* this check is probably linux-specific. */ + /* alternatively we could open the device and try VT_OPENQRY. */ + if (memcmp( ut->ut_line, "tty", 3 ) || + !isdigit( ut->ut_line[3] )) + continue; + } + if (StrNChrCnt( ut->ut_line, sizeof(ut->ut_line), ':' )) + continue; /* x login */ + switch (StrNChrCnt( ut->ut_host, sizeof(ut->ut_host), ':' )) { + case 1: /* x terminal */ + continue; + default: +#ifdef IP6_MAGIC + /* unknown - IPv6 makes things complicated */ + le = StrNLen( ut->ut_host, sizeof(ut->ut_host) ); + /* cut off screen number */ + for (dot = le; ut->ut_host[--dot] != ':'; ) + if (ut->ut_host[dot] == '.') { + le = dot; + break; + } + for (di = displays; di; di = di->next) + if (!memcmp( di->name, ut->ut_host, le ) && !di->name[le]) + goto cont; /* x terminal */ + break; + cont: + continue; + case 0: /* no x terminal */ +#endif + break; + } + emitTTYSess( ut, d, ctx ); + } + } +#ifdef BSD_UTMP + close( fd ); +#else + ENDUTENT(); +#endif +} + diff --git a/tdm/backend/xdmauth.c b/tdm/backend/xdmauth.c new file mode 100644 index 000000000..86257c651 --- /dev/null +++ b/tdm/backend/xdmauth.c @@ -0,0 +1,267 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2001,2003 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * generate authorization data for XDM-AUTHORIZATION-1 as per XDMCP spec + */ + +#include + +#ifdef HASXDMAUTH + +#include "dm.h" +#include "dm_auth.h" +#include "dm_error.h" + +static char auth_name[256]; +static int auth_name_len; + +void +XdmInitAuth( unsigned short name_len, const char *name ) +{ + if (name_len > 256) + name_len = 256; + auth_name_len = name_len; + memmove( auth_name, name, name_len ); +} + +/* + * Generate authorization for XDM-AUTHORIZATION-1 + * + * When being used with XDMCP, 8 bytes are generated for the session key + * (sigma), as the random number (rho) is already shared between xdm and + * the server. Otherwise, we'll prepend a random number to pass in the file + * between xdm and the server (16 bytes total) + */ + +static Xauth * +XdmGetAuthHelper( unsigned short namelen, const char *name, int includeRho ) +{ + Xauth *new; + + if (!(new = (Xauth *)Malloc( sizeof(Xauth) ))) + return (Xauth *)0; + new->family = FamilyWild; + new->address_length = 0; + new->address = 0; + new->number_length = 0; + new->number = 0; + if (includeRho) + new->data_length = 16; + else + new->data_length = 8; + + new->data = (char *)Malloc( new->data_length ); + if (!new->data) { + free( (char *)new ); + return (Xauth *)0; + } + new->name = (char *)Malloc( namelen ); + if (!new->name) { + free( (char *)new->data ); + free( (char *)new ); + return (Xauth *)0; + } + memmove( (char *)new->name, name, namelen ); + new->name_length = namelen; + if (!GenerateAuthData( (char *)new->data, new->data_length )) { + free( (char *)new->name ); + free( (char *)new->data ); + free( (char *)new ); + return (Xauth *)0; + } + /* + * set the first byte of the session key to zero as it + * is a DES key and only uses 56 bits + */ + ((char *)new->data)[new->data_length - 8] = '\0'; + Debug( "local server auth %02[*hhx\n", new->data_length, new->data ); + return new; +} + +Xauth * +XdmGetAuth( unsigned short namelen, const char *name ) +{ + return XdmGetAuthHelper( namelen, name, TRUE ); +} + +#ifdef XDMCP + +void +XdmGetXdmcpAuth( struct protoDisplay *pdpy, + unsigned short authorizationNameLen, + const char *authorizationName ) +{ + Xauth *fileauth, *xdmcpauth; + + if (pdpy->fileAuthorization && pdpy->xdmcpAuthorization) + return; + xdmcpauth = XdmGetAuthHelper( authorizationNameLen, authorizationName, + FALSE ); + if (!xdmcpauth) + return; + fileauth = (Xauth *)Malloc( sizeof(Xauth) ); + if (!fileauth) { + XauDisposeAuth( xdmcpauth ); + return; + } + /* build the file auth from the XDMCP auth */ + *fileauth = *xdmcpauth; + fileauth->name = Malloc( xdmcpauth->name_length ); + fileauth->data = Malloc( 16 ); + fileauth->data_length = 16; + if (!fileauth->name || !fileauth->data) { + XauDisposeAuth( xdmcpauth ); + if (fileauth->name) + free( (char *)fileauth->name ); + if (fileauth->data) + free( (char *)fileauth->data ); + free( (char *)fileauth ); + return; + } + /* + * for the file authorization, prepend the random number (rho) + * which is simply the number we've been passing back and + * forth via XDMCP + */ + memmove( fileauth->name, xdmcpauth->name, xdmcpauth->name_length ); + memmove( fileauth->data, pdpy->authenticationData.data, 8 ); + memmove( fileauth->data + 8, xdmcpauth->data, 8 ); + Debug( "accept packet auth %02[*hhx\nauth file auth %02[*hhx\n", + xdmcpauth->data_length, xdmcpauth->data, + fileauth->data_length, fileauth->data ); + /* encrypt the session key for its trip back to the server */ + XdmcpWrap( (unsigned char *)xdmcpauth->data, (unsigned char *)&pdpy->key, + (unsigned char *)xdmcpauth->data, 8 ); + pdpy->fileAuthorization = fileauth; + pdpy->xdmcpAuthorization = xdmcpauth; +} + +#define atox(c) ('0' <= c && c <= '9' ? c - '0' : \ + 'a' <= c && c <= 'f' ? c - 'a' + 10 : \ + 'A' <= c && c <= 'F' ? c - 'A' + 10 : -1) + +static int +HexToBinary( char *key ) +{ + char *out, *in; + int top, bottom; + + in = key + 2; + out= key; + while (in[0] && in[1]) { + top = atox( in[0] ); + if (top == -1) + return 0; + bottom = atox( in[1] ); + if (bottom == -1) + return 0; + *out++ = (top << 4) | bottom; + in += 2; + } + if (in[0]) + return 0; + *out++ = '\0'; + return 1; +} + +/* + * Search the Keys file for the entry matching this display. This + * routine accepts either plain ascii strings for keys, or hex-encoded numbers + */ + +static int +XdmGetKey( struct protoDisplay *pdpy, ARRAY8Ptr displayID ) +{ + FILE *keys; + char line[1024], id[1024], key[1024]; + int keylen; + + Debug( "lookup key for %.*s\n", displayID->length, displayID->data ); + keys = fopen( keyFile, "r" ); + if (!keys) + return FALSE; + while (fgets( line, sizeof(line), keys )) { + if (line[0] == '#' || sscanf( line, "%s %s", id, key ) != 2) + continue; + bzero( line, sizeof(line) ); + Debug( "key entry for %\"s %d bytes\n", id, strlen( key ) ); + if (strlen( id ) == displayID->length && + !strncmp( id, (char *)displayID->data, displayID->length )) + { + if (!strncmp( key, "0x", 2 ) || !strncmp( key, "0X", 2 )) + if (!HexToBinary( key )) + break; + keylen = strlen( key ); + while (keylen < 7) + key[keylen++] = '\0'; + pdpy->key.data[0] = '\0'; + memmove( pdpy->key.data + 1, key, 7 ); + bzero( key, sizeof(key) ); + fclose( keys ); + return TRUE; + } + } + bzero( line, sizeof(line) ); + bzero( key, sizeof(key) ); + fclose( keys ); + return FALSE; +} + +/*ARGSUSED*/ +int +XdmCheckAuthentication( struct protoDisplay *pdpy, + ARRAY8Ptr displayID, + ARRAY8Ptr authenticationName ATTR_UNUSED, + ARRAY8Ptr authenticationData ) +{ + XdmAuthKeyPtr incoming; + + if (!XdmGetKey( pdpy, displayID )) + return FALSE; + if (authenticationData->length != 8) + return FALSE; + XdmcpUnwrap( authenticationData->data, (unsigned char *)&pdpy->key, + authenticationData->data, 8 ); + Debug( "request packet auth %02[*hhx\n", + authenticationData->length, authenticationData->data ); + if (!XdmcpCopyARRAY8( authenticationData, &pdpy->authenticationData )) + return FALSE; + incoming = (XdmAuthKeyPtr)authenticationData->data; + XdmcpIncrementKey( incoming ); + XdmcpWrap( authenticationData->data, (unsigned char *)&pdpy->key, + authenticationData->data, 8 ); + return TRUE; +} + +#endif /* XDMCP */ +#endif /* HASXDMAUTH (covering the entire file) */ diff --git a/tdm/backend/xdmcp.c b/tdm/backend/xdmcp.c new file mode 100644 index 000000000..6abaf5fc8 --- /dev/null +++ b/tdm/backend/xdmcp.c @@ -0,0 +1,1165 @@ +/* + +Copyright 1988, 1998 The Open Group +Copyright 2002 Sun Microsystems, Inc. All rights reserved. +Copyright 2001-2004 Oswald Buddenhagen + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the copyright holder. + +*/ + +/* + * xdm - display manager daemon + * Author: Keith Packard, MIT X Consortium + * + * xdmcp.c - Support for XDMCP + */ + +#include + +#ifdef XDMCP + +#include "dm.h" +#include "dm_error.h" +#include "dm_auth.h" +#include "dm_socket.h" + +#include +#include + +#include +#if defined(IPv6) && defined(AF_INET6) +# include +#endif + +/* + * Forward reference + */ +static void broadcast_respond( struct sockaddr *from, int fromlen, int length, int fd ); +static void forward_respond (struct sockaddr *from, int fromlen, int length, int fd); +static void manage( struct sockaddr *from, int fromlen, int length, int fd ); +static void query_respond( struct sockaddr *from, int fromlen, int length, int fd ); +static void request_respond( struct sockaddr *from, int fromlen, int length, int fd ); +static void send_accept( struct sockaddr *to, int tolen, CARD32 sessionID, ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, ARRAY8Ptr authorizationName, ARRAY8Ptr authorizationData, int fd ); +static void send_alive( struct sockaddr *from, int fromlen, int length, int fd ); +static void send_decline( struct sockaddr *to, int tolen, ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, ARRAY8Ptr status, int fd ); +static void send_failed( struct sockaddr *from, int fromlen, const char *name, CARD32 sessionID, const char *reason, int fd ); +static void send_refuse( struct sockaddr *from, int fromlen, CARD32 sessionID, int fd ); +static void send_unwilling( struct sockaddr *from, int fromlen, ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd ); +static void send_willing( struct sockaddr *from, int fromlen, ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd ); + + +static XdmcpBuffer buffer; + +static void +sendForward( CARD16 connectionType, ARRAY8Ptr address, char *closure ) +{ +#ifdef AF_INET + struct sockaddr_in in_addr; +#endif +#if defined(IPv6) && defined(AF_INET6) + struct sockaddr_in6 in6_addr; +#endif +#ifdef AF_DECnet +#endif + struct sockaddr *addr; + int addrlen; + + switch (connectionType) { +#ifdef AF_INET + case FamilyInternet: + addr = (struct sockaddr *)&in_addr; + bzero( (char *)&in_addr, sizeof(in_addr) ); +# ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + in_addr.sin_len = sizeof(in_addr); +# endif + in_addr.sin_family = AF_INET; + in_addr.sin_port = htons( (short)XDM_UDP_PORT ); + if (address->length != 4) + return; + memmove( (char *)&in_addr.sin_addr, address->data, address->length ); + addrlen = sizeof(struct sockaddr_in); + break; +#endif +#if defined(IPv6) && defined(AF_INET6) + case FamilyInternet6: + addr = (struct sockaddr *)&in6_addr; + bzero( (char *)&in6_addr, sizeof(in6_addr) ); +# ifdef SIN6_LEN + in6_addr.sin6_len = sizeof(in6_addr); +# endif + in6_addr.sin6_family = AF_INET6; + in6_addr.sin6_port = htons( (short)XDM_UDP_PORT ); + if (address->length != 16) + return; + memmove( (char *)&in6_addr.sin6_addr, address->data, address->length ); + addrlen = sizeof(struct sockaddr_in6); + break; +#endif +#ifdef AF_DECnet + case FamilyDECnet: +#endif + default: + return; + } + XdmcpFlush( (int)closure, &buffer, (XdmcpNetaddr)addr, addrlen ); + return; +} + +static void +ClientAddress( struct sockaddr *from, + ARRAY8Ptr addr, /* return */ + ARRAY8Ptr port, /* return */ + CARD16 *type ) /* return */ +{ + int length, family; + char *data; + + data = NetaddrPort( (XdmcpNetaddr)from, &length ); + XdmcpAllocARRAY8( port, length ); + memmove( port->data, data, length ); + port->length = length; + + family = ConvertAddr( (XdmcpNetaddr)from, &length, &data ); + XdmcpAllocARRAY8( addr, length ); + memmove( addr->data, data, length ); + addr->length = length; + + *type = family; +} + +static void +all_query_respond( struct sockaddr *from, int fromlen, + ARRAYofARRAY8Ptr authenticationNames, + xdmOpCode type, int fd ) +{ + ARRAY8Ptr authenticationName; + ARRAY8 status; + ARRAY8 addr; + CARD16 connectionType; + int family; + int length; + + family = ConvertAddr( (XdmcpNetaddr)from, &length, &(addr.data) ); + addr.length = length; /* convert int to short */ + Debug( "all_query_respond: conntype=%d, addr=%02[*:hhx\n", + family, addr.length, addr.data ); + if (family < 0) + return; + connectionType = family; + + if (type == INDIRECT_QUERY) + RememberIndirectClient( &addr, connectionType ); + else + ForgetIndirectClient( &addr, connectionType ); + + authenticationName = ChooseAuthentication( authenticationNames ); + if (Willing( &addr, connectionType, authenticationName, &status, type )) + send_willing( from, fromlen, authenticationName, &status, fd ); + else + if (type == QUERY) + send_unwilling( from, fromlen, authenticationName, &status, fd ); + XdmcpDisposeARRAY8( &status ); +} + +static void +indirect_respond( struct sockaddr *from, int fromlen, int length, int fd ) +{ + ARRAYofARRAY8 queryAuthenticationNames; + ARRAY8 clientAddress; + ARRAY8 clientPort; + CARD16 connectionType; + int expectedLen; + int i; + XdmcpHeader header; + int localHostAsWell; + + Debug( " respond %d\n", length ); + if (!XdmcpReadARRAYofARRAY8( &buffer, &queryAuthenticationNames )) + return; + expectedLen = 1; + for (i = 0; i < (int)queryAuthenticationNames.length; i++) + expectedLen += 2 + queryAuthenticationNames.data[i].length; + if (length == expectedLen) { + ClientAddress( from, &clientAddress, &clientPort, &connectionType ); + /* + * set up the forward query packet + */ + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16)FORWARD_QUERY; + header.length = 0; + header.length += 2 + clientAddress.length; + header.length += 2 + clientPort.length; + header.length += 1; + for (i = 0; i < (int)queryAuthenticationNames.length; i++) + header.length += 2 + queryAuthenticationNames.data[i].length; + XdmcpWriteHeader( &buffer, &header ); + XdmcpWriteARRAY8( &buffer, &clientAddress ); + XdmcpWriteARRAY8( &buffer, &clientPort ); + XdmcpWriteARRAYofARRAY8( &buffer, &queryAuthenticationNames ); + + localHostAsWell = + ForEachMatchingIndirectHost( &clientAddress, connectionType, + sendForward, (char *)fd ); + + XdmcpDisposeARRAY8( &clientAddress ); + XdmcpDisposeARRAY8( &clientPort ); + if (localHostAsWell) + all_query_respond( from, fromlen, &queryAuthenticationNames, + INDIRECT_QUERY, fd ); + } else + Debug( " length error got %d expect %d\n", + length, expectedLen ); + XdmcpDisposeARRAYofARRAY8( &queryAuthenticationNames ); +} + +void +ProcessRequestSocket( int fd ) +{ + XdmcpHeader header; +#if defined(IPv6) && defined(AF_INET6) + struct sockaddr_storage addr; +#else + struct sockaddr addr; +#endif + int addrlen = sizeof(addr); + + Debug( "ProcessRequestSocket\n" ); + bzero( (char *)&addr, sizeof(addr) ); + if (!XdmcpFill( fd, &buffer, (XdmcpNetaddr)&addr, &addrlen )) { + Debug( "XdmcpFill failed\n" ); + return; + } + if (!XdmcpReadHeader( &buffer, &header )) { + Debug( "XdmcpReadHeader failed\n" ); + return; + } + if (header.version != XDM_PROTOCOL_VERSION) { + Debug( "XDMCP header version read was %d, expected %d\n", + header.version, XDM_PROTOCOL_VERSION ); + return; + } + Debug( "header: %d %d %d\n", header.version, header.opcode, header.length ); + switch (header.opcode) { + case BROADCAST_QUERY: + broadcast_respond( (struct sockaddr *)&addr, addrlen, header.length, fd ); + break; + case QUERY: + query_respond( (struct sockaddr *)&addr, addrlen, header.length, fd ); + break; + case INDIRECT_QUERY: + indirect_respond( (struct sockaddr *)&addr, addrlen, header.length, fd ); + break; + case FORWARD_QUERY: + forward_respond ((struct sockaddr *)&addr, addrlen, header.length, fd); + break; + case REQUEST: + request_respond( (struct sockaddr *)&addr, addrlen, header.length, fd ); + break; + case MANAGE: + manage( (struct sockaddr *)&addr, addrlen, header.length, fd ); + break; + case KEEPALIVE: + send_alive( (struct sockaddr *)&addr, addrlen, header.length, fd ); + break; + } +} + +/* + * respond to a request on the UDP socket. + */ + +static void +direct_query_respond( struct sockaddr *from, int fromlen, + int length, xdmOpCode type, int fd ) +{ + ARRAYofARRAY8 queryAuthenticationNames; + int expectedLen; + int i; + + if (!XdmcpReadARRAYofARRAY8( &buffer, &queryAuthenticationNames )) + return; + expectedLen = 1; + for (i = 0; i < (int)queryAuthenticationNames.length; i++) + expectedLen += 2 + queryAuthenticationNames.data[i].length; + if (length == expectedLen) + all_query_respond( from, fromlen, &queryAuthenticationNames, type, fd ); + XdmcpDisposeARRAYofARRAY8( &queryAuthenticationNames ); +} + +static void +query_respond( struct sockaddr *from, int fromlen, int length, int fd ) +{ + Debug( " respond %d\n", length ); + direct_query_respond( from, fromlen, length, QUERY, fd ); +} + +static void +broadcast_respond( struct sockaddr *from, int fromlen, int length, int fd ) +{ + direct_query_respond( from, fromlen, length, BROADCAST_QUERY, fd ); +} + +/* computes an X display name */ + +static char * +NetworkAddressToName( CARD16 connectionType, ARRAY8Ptr connectionAddress, + struct sockaddr *originalAddress, CARD16 displayNumber ) +{ + switch (connectionType) { + case FamilyInternet: +#if defined(IPv6) && defined(AF_INET6) + case FamilyInternet6: +#endif + { + CARD8 *data; + struct hostent *hostent; + char *hostname = NULL; + char *name; + const char *localhost; + int multiHomed = 0; + int type; +#if defined(IPv6) && defined(AF_INET6) + struct addrinfo *ai = NULL, *nai, hints; + char dotted[INET6_ADDRSTRLEN]; + + if (connectionType == FamilyInternet6) + type = AF_INET6; + else +#endif + type = AF_INET; + + data = connectionAddress->data; + hostent = gethostbyaddr( (char *)data, + connectionAddress->length, type ); + if (hostent) { + if (sourceAddress) { +#if defined(IPv6) && defined(AF_INET6) + bzero( &hints, sizeof(hints) ); + hints.ai_flags = AI_CANONNAME; + if (!getaddrinfo( hostent->h_name, NULL, &hints, &ai )) { + hostname = ai->ai_canonname; + for (nai = ai->ai_next; nai; nai = nai->ai_next) + if (ai->ai_protocol == nai->ai_protocol && + memcmp( ai->ai_addr, nai->ai_addr, + ai->ai_addrlen )) + multiHomed = 1; + } +#else + hostent = gethostbyname( hostent->h_name ); + if (hostent && hostent->h_addrtype == AF_INET) { + multiHomed = hostent->h_addr_list[1] != NULL; + hostname = hostent->h_name; + } +#endif + } else + hostname = hostent->h_name; + } + + localhost = localHostname(); + + /* + * protect against bogus host names + */ + if (hostname && *hostname && *hostname != '.' && !multiHomed) { + if (!strcmp( localhost, hostname )) + ASPrintf( &name, "localhost:%d", displayNumber ); + else { + if (removeDomainname) { + char *remoteDot; + char *localDot; + + /* check for a common domain name. This + * could reduce names by recognising common + * super-domain names as well, but I don't think + * this is as useful, and will confuse more + * people + */ + if ((localDot = strchr( localhost, '.' )) && + (remoteDot = strchr( hostname, '.' ))) + { + /* smash the name in place; it won't + * be needed later. + */ + if (!strcmp( localDot+1, remoteDot+1 )) + *remoteDot = '\0'; + } + } + + ASPrintf( &name, "%s:%d", hostname, displayNumber ); + } + } else { +#if defined(IPv6) && defined(AF_INET6) + if (multiHomed) { + if (connectionType == FamilyInternet) { + data = (CARD8 *) + &((struct sockaddr_in *)originalAddress)->sin_addr; + } else { + data = (CARD8 *) + &((struct sockaddr_in6 *)originalAddress)->sin6_addr; + } + } + inet_ntop( type, data, dotted, sizeof(dotted) ); + ASPrintf( &name, "%s:%d", dotted, displayNumber ); +#else + if (multiHomed) + data = (CARD8 *) + &((struct sockaddr_in *)originalAddress)->sin_addr; + ASPrintf( &name, "%[4|'.'hhu:%d", data, displayNumber ); +#endif + } +#if defined(IPv6) && defined(AF_INET6) + if (ai) + freeaddrinfo( ai ); +#endif + return name; + } +#ifdef DNET + case FamilyDECnet: + return NULL; +#endif /* DNET */ + default: + return NULL; + } +} + +/*ARGSUSED*/ +static void +forward_respond ( struct sockaddr *from, int fromlen ATTR_UNUSED, + int length, int fd) +{ + ARRAY8 clientAddress; + ARRAY8 clientPort; + ARRAYofARRAY8 authenticationNames; + struct sockaddr *client; + int clientlen; + int expectedLen; + int i; + + Debug( " respond %d\n", length ); + clientAddress.length = 0; + clientAddress.data = 0; + clientPort.length = 0; + clientPort.data = 0; + authenticationNames.length = 0; + authenticationNames.data = 0; + if (XdmcpReadARRAY8( &buffer, &clientAddress ) && + XdmcpReadARRAY8( &buffer, &clientPort ) && + XdmcpReadARRAYofARRAY8( &buffer, &authenticationNames )) + { + expectedLen = 0; + expectedLen += 2 + clientAddress.length; + expectedLen += 2 + clientPort.length; + expectedLen += 1; /* authenticationNames */ + for (i = 0; i < (int)authenticationNames.length; i++) + expectedLen += 2 + authenticationNames.data[i].length; + if (length == expectedLen) { + int j; + + j = 0; + for (i = 0; i < (int)clientPort.length; i++) + j = j * 256 + clientPort.data[i]; + Debug( " client address (port %d) %[*hhu\n", j, + clientAddress.length, clientAddress.data ); + switch (from->sa_family) { +#ifdef AF_INET + case AF_INET: + { + struct sockaddr_in in_addr; + + if (clientAddress.length != 4 || clientPort.length != 2) + goto badAddress; + bzero( (char *)&in_addr, sizeof(in_addr) ); +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + in_addr.sin_len = sizeof(in_addr); +#endif + in_addr.sin_family = AF_INET; + memmove( &in_addr.sin_addr, clientAddress.data, 4 ); + memmove( (char *)&in_addr.sin_port, clientPort.data, 2 ); + client = (struct sockaddr *)&in_addr; + clientlen = sizeof(in_addr); + all_query_respond( client, clientlen, &authenticationNames, + FORWARD_QUERY, fd ); + } + break; +#endif +#if defined(IPv6) && defined(AF_INET6) + case AF_INET6: + { + struct sockaddr_in6 in6_addr; + + if (clientAddress.length != 16 || clientPort.length != 2) + goto badAddress; + bzero( (char *)&in6_addr, sizeof(in6_addr) ); +#ifdef SIN6_LEN + in6_addr.sin6_len = sizeof(in6_addr); +#endif + in6_addr.sin6_family = AF_INET6; + memmove( &in6_addr,clientAddress.data,clientAddress.length ); + memmove( (char *)&in6_addr.sin6_port, clientPort.data, 2 ); + client = (struct sockaddr *)&in6_addr; + clientlen = sizeof(in6_addr); + all_query_respond( client, clientlen, &authenticationNames, + FORWARD_QUERY, fd ); + } + break; +#endif +#ifdef AF_UNIX + case AF_UNIX: + { + struct sockaddr_un un_addr; + + if (clientAddress.length >= sizeof(un_addr.sun_path)) + goto badAddress; + bzero( (char *)&un_addr, sizeof(un_addr) ); + un_addr.sun_family = AF_UNIX; + memmove( un_addr.sun_path, clientAddress.data, clientAddress.length ); + un_addr.sun_path[clientAddress.length] = '\0'; + client = (struct sockaddr *)&un_addr; +#if defined(HAVE_STRUCT_SOCKADDR_IN_SIN_LEN) && !defined(__Lynx__) && defined(UNIXCONN) + un_addr.sun_len = strlen( un_addr.sun_path ); + clientlen = SUN_LEN( &un_addr ); +#else + clientlen = sizeof(un_addr); +#endif + all_query_respond( client, clientlen, &authenticationNames, + FORWARD_QUERY, fd ); + } + break; +#endif +#ifdef AF_CHAOS + case AF_CHAOS: + goto badAddress; +#endif +#ifdef AF_DECnet + case AF_DECnet: + goto badAddress; +#endif + } + } else + Debug( " length error got %d expect %d\n", length, expectedLen ); + } + badAddress: + XdmcpDisposeARRAY8( &clientAddress ); + XdmcpDisposeARRAY8( &clientPort ); + XdmcpDisposeARRAYofARRAY8( &authenticationNames ); +} + +static ARRAY8 Hostname; + +static void +send_willing( struct sockaddr *from, int fromlen, + ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd ) +{ + XdmcpHeader header; + + Debug( "send %.*s %.*s\n", authenticationName->length, + authenticationName->data, + status->length, + status->data ); + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16)WILLING; + header.length = + 6 + authenticationName->length + Hostname.length + status->length; + XdmcpWriteHeader( &buffer, &header ); + XdmcpWriteARRAY8( &buffer, authenticationName ); + XdmcpWriteARRAY8( &buffer, &Hostname ); + XdmcpWriteARRAY8( &buffer, status ); + XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); +} + +static void +send_unwilling( struct sockaddr *from, int fromlen, + ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd ) +{ + XdmcpHeader header; + + Debug( "send %.*s %.*s\n", authenticationName->length, + authenticationName->data, + status->length, + status->data ); + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16)UNWILLING; + header.length = 4 + Hostname.length + status->length; + XdmcpWriteHeader( &buffer, &header ); + XdmcpWriteARRAY8( &buffer, &Hostname ); + XdmcpWriteARRAY8( &buffer, status ); + XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); +} + +static unsigned long globalSessionID; + +#define NextSessionID() (++globalSessionID) + +void init_session_id( void ) +{ + /* Set randomly so we are unlikely to reuse id's from a previous + * incarnation so we don't say "Alive" to those displays. + * Start with low digits 0 to make debugging easier. + */ + globalSessionID = (time( (Time_t *)0 ) & 0x7fff) * 16000; + + Hostname.data = (char *)localHostname(); + Hostname.length = strlen( Hostname.data ); +} + +static ARRAY8 outOfMemory = { (CARD16)13, (CARD8Ptr)"Out of memory" }; +static ARRAY8 noValidAddr = { (CARD16)16, (CARD8Ptr)"No valid address" }; +static ARRAY8 noValidAuth = { (CARD16)22, (CARD8Ptr)"No valid authorization" }; +static ARRAY8 noAuthentic = { (CARD16)29, (CARD8Ptr)"XDM has no authentication key" }; + +static void +request_respond( struct sockaddr *from, int fromlen, int length, int fd ) +{ + CARD16 displayNumber; + ARRAY16 connectionTypes; + ARRAYofARRAY8 connectionAddresses; + ARRAY8 authenticationName; + ARRAY8 authenticationData; + ARRAYofARRAY8 authorizationNames; + ARRAY8 manufacturerDisplayID; + ARRAY8Ptr reason = 0; + int expectlen; + int i, j; + struct protoDisplay *pdpy; + ARRAY8 authorizationName, authorizationData; + ARRAY8Ptr connectionAddress; + + Debug( " respond %d\n", length ); + connectionTypes.data = 0; + connectionAddresses.data = 0; + authenticationName.data = 0; + authenticationData.data = 0; + authorizationNames.data = 0; + authorizationName.length = 0; + authorizationData.length = 0; + manufacturerDisplayID.data = 0; + if (XdmcpReadCARD16( &buffer, &displayNumber ) && + XdmcpReadARRAY16( &buffer, &connectionTypes ) && + XdmcpReadARRAYofARRAY8( &buffer, &connectionAddresses ) && + XdmcpReadARRAY8( &buffer, &authenticationName ) && + XdmcpReadARRAY8( &buffer, &authenticationData ) && + XdmcpReadARRAYofARRAY8( &buffer, &authorizationNames ) && + XdmcpReadARRAY8( &buffer, &manufacturerDisplayID )) + { + expectlen = 0; + expectlen += 2; /* displayNumber */ + expectlen += 1 + 2 * connectionTypes.length; /* connectionTypes */ + expectlen += 1; /* connectionAddresses */ + for (i = 0; i < (int)connectionAddresses.length; i++) + expectlen += 2 + connectionAddresses.data[i].length; + expectlen += 2 + authenticationName.length; /* authenticationName */ + expectlen += 2 + authenticationData.length; /* authenticationData */ + expectlen += 1; /* authoriationNames */ + for (i = 0; i < (int)authorizationNames.length; i++) + expectlen += 2 + authorizationNames.data[i].length; + expectlen += 2 + manufacturerDisplayID.length; /* displayID */ + if (expectlen != length) { + Debug( " length error got %d expect %d\n", + length, expectlen ); + goto abort; + } + if (connectionTypes.length == 0 || + connectionAddresses.length != connectionTypes.length) + { + reason = &noValidAddr; + pdpy = 0; + goto decline; + } + pdpy = FindProtoDisplay( (XdmcpNetaddr)from, fromlen, displayNumber ); + if (!pdpy) { + + /* Check this Display against the Manager's policy */ + reason = Accept( from, fromlen, displayNumber ); + if (reason) + goto decline; + + /* Check the Display's stream services against Manager's policy */ + i = SelectConnectionTypeIndex( &connectionTypes, + &connectionAddresses ); + if (i < 0) { + reason = &noValidAddr; + goto decline; + } + + /* The Manager considers this a new session */ + connectionAddress = &connectionAddresses.data[i]; + pdpy = NewProtoDisplay( (XdmcpNetaddr)from, fromlen, displayNumber, + connectionTypes.data[i], connectionAddress, + NextSessionID() ); + Debug( "NewProtoDisplay %p\n", pdpy ); + if (!pdpy) { + reason = &outOfMemory; + goto decline; + } + } + if (authorizationNames.length == 0) + j = 0; + else + j = SelectAuthorizationTypeIndex( &authenticationName, + &authorizationNames ); + if (j < 0) { + reason = &noValidAuth; + goto decline; + } + if (!CheckAuthentication( pdpy, + &manufacturerDisplayID, + &authenticationName, + &authenticationData )) + { + reason = &noAuthentic; + goto decline; + } + if (j < (int)authorizationNames.length) { + Xauth *auth; + SetProtoDisplayAuthorization( pdpy, + (unsigned short)authorizationNames.data[j].length, + (char *)authorizationNames.data[j].data ); + auth = pdpy->xdmcpAuthorization; + if (!auth) + auth = pdpy->fileAuthorization; + if (auth) { + authorizationName.length = auth->name_length; + authorizationName.data = (CARD8Ptr) auth->name; + authorizationData.length = auth->data_length; + authorizationData.data = (CARD8Ptr) auth->data; + } + } + if (pdpy) { + send_accept( from, fromlen, pdpy->sessionID, + &authenticationName, + &authenticationData, + &authorizationName, + &authorizationData, fd ); + } else { + decline: + send_decline( from, fromlen, &authenticationName, + &authenticationData, + reason, fd ); + if (pdpy) + DisposeProtoDisplay( pdpy ); + } + } + abort: + XdmcpDisposeARRAY16( &connectionTypes ); + XdmcpDisposeARRAYofARRAY8( &connectionAddresses ); + XdmcpDisposeARRAY8( &authenticationName ); + XdmcpDisposeARRAY8( &authenticationData ); + XdmcpDisposeARRAYofARRAY8( &authorizationNames ); + XdmcpDisposeARRAY8( &manufacturerDisplayID ); +} + +static void +send_accept( struct sockaddr *to, int tolen, CARD32 sessionID, + ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, + ARRAY8Ptr authorizationName, ARRAY8Ptr authorizationData, + int fd ) +{ + XdmcpHeader header; + + Debug( " session ID %ld\n", (long)sessionID ); + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16)ACCEPT; + header.length = 4; /* session ID */ + header.length += 2 + authenticationName->length; + header.length += 2 + authenticationData->length; + header.length += 2 + authorizationName->length; + header.length += 2 + authorizationData->length; + XdmcpWriteHeader( &buffer, &header ); + XdmcpWriteCARD32( &buffer, sessionID ); + XdmcpWriteARRAY8( &buffer, authenticationName ); + XdmcpWriteARRAY8( &buffer, authenticationData ); + XdmcpWriteARRAY8( &buffer, authorizationName ); + XdmcpWriteARRAY8( &buffer, authorizationData ); + XdmcpFlush( fd, &buffer, (XdmcpNetaddr)to, tolen ); +} + +static void +send_decline( struct sockaddr *to, int tolen, + ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, + ARRAY8Ptr status, int fd ) +{ + XdmcpHeader header; + + Debug( " %.*s\n", status->length, status->data ); + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16)DECLINE; + header.length = 0; + header.length += 2 + status->length; + header.length += 2 + authenticationName->length; + header.length += 2 + authenticationData->length; + XdmcpWriteHeader( &buffer, &header ); + XdmcpWriteARRAY8( &buffer, status ); + XdmcpWriteARRAY8( &buffer, authenticationName ); + XdmcpWriteARRAY8( &buffer, authenticationData ); + XdmcpFlush( fd, &buffer, (XdmcpNetaddr)to, tolen ); +} + +static void +manage( struct sockaddr *from, int fromlen, int length, int fd ) +{ + CARD32 sessionID; + CARD16 displayNumber; + ARRAY8 displayClass; + int expectlen; + struct protoDisplay *pdpy; + struct display *d; + char *name = NULL; + char *class2 = NULL; + XdmcpNetaddr from_save; + ARRAY8 clientAddress, clientPort; + CARD16 connectionType; + + Debug( " %d\n", length ); + displayClass.data = 0; + displayClass.length = 0; + if (XdmcpReadCARD32( &buffer, &sessionID ) && + XdmcpReadCARD16( &buffer, &displayNumber ) && + XdmcpReadARRAY8( &buffer, &displayClass )) + { + expectlen = 4 + /* session ID */ + 2 + /* displayNumber */ + 2 + displayClass.length; /* displayClass */ + if (expectlen != length) { + Debug( " length error got %d expect %d\n", length, expectlen ); + goto abort; + } + pdpy = FindProtoDisplay( (XdmcpNetaddr)from, fromlen, displayNumber ); + Debug( " session ID %ld, pdpy %p\n", (long)sessionID, pdpy ); + if (!pdpy || pdpy->sessionID != sessionID) { + /* + * We may have already started a session for this display + * but it hasn't seen the response in the form of an + * XOpenDisplay() yet. So check if it is in the list of active + * displays, and if so check that the session id's match. + * If all this is true, then we have a duplicate request that + * can be ignored. + */ + if (!pdpy && + (d = FindDisplayByAddress( (XdmcpNetaddr)from, fromlen, + displayNumber )) && + d->sessionID == sessionID) + { + Debug( "manage: got duplicate pkt, ignoring\n" ); + goto abort; + } + Debug( "session ID %ld refused\n", (long)sessionID ); + if (pdpy) + Debug( "existing session ID %ld\n", (long)pdpy->sessionID ); + send_refuse( from, fromlen, sessionID, fd ); + } else { + name = NetworkAddressToName( pdpy->connectionType, + &pdpy->connectionAddress, + from, + pdpy->displayNumber ); + if (!name) { + Debug( "could not compute display name\n" ); + send_failed( from, fromlen, "(no name)", sessionID, + "out of memory", fd ); + goto abort; + } + Debug( "computed display name: %s\n", name ); + if ((d = FindDisplayByName( name ))) { + Debug( "terminating active session for %s\n", d->name ); + StopDisplay( d ); + } + if (displayClass.length) { + if (!StrNDup( &class2, (char *)displayClass.data, + displayClass.length )) + { + send_failed( from, fromlen, name, sessionID, + "out of memory", fd ); + goto abort; + } + } + if (!(from_save = (XdmcpNetaddr)Malloc( fromlen ))) { + send_failed( from, fromlen, name, sessionID, + "out of memory", fd ); + goto abort; + } + memmove( from_save, from, fromlen ); + if (!(d = NewDisplay( name ))) { + free( (char *)from_save ); + send_failed( from, fromlen, name, sessionID, + "out of memory", fd ); + goto abort; + } + d->class2 = class2; + class2 = 0; + d->displayType = dForeign | dTransient | dFromXDMCP; + d->sessionID = pdpy->sessionID; + d->from.data = (unsigned char *)from_save; + d->from.length = fromlen; + d->displayNumber = pdpy->displayNumber; + ClientAddress( from, &clientAddress, &clientPort, + &connectionType ); + d->useChooser = 0; + d->xdmcpFd = fd; + if (IsIndirectClient( &clientAddress, connectionType )) { + Debug( "IsIndirectClient\n" ); + ForgetIndirectClient( &clientAddress, connectionType ); + if (UseChooser( &clientAddress, connectionType )) { + d->useChooser = 1; + Debug( "use chooser for %s\n", d->name ); + } + } + d->clientAddr = clientAddress; + d->connectionType = connectionType; + d->remoteHost = NetworkAddressToHostname (pdpy->connectionType, + &pdpy->connectionAddress); + + XdmcpDisposeARRAY8( &clientPort ); + if (pdpy->fileAuthorization) { + d->authorizations = (Xauth **)Malloc( sizeof(Xauth *) ); + if (!d->authorizations) { + free( (char *)from_save ); + free( (char *)d ); + send_failed( from, fromlen, name, sessionID, + "out of memory", fd ); + goto abort; + } + d->authorizations[0] = pdpy->fileAuthorization; + d->authNum = 1; + pdpy->fileAuthorization = 0; + } + DisposeProtoDisplay( pdpy ); + Debug( "starting display %s,%s\n", d->name, d->class2 ); + if (LoadDisplayResources( d ) < 0) { + LogError( "Unable to read configuration for display %s; " + "stopping it.\n", d->name ); + StopDisplay( d ); + } else + StartDisplay( d ); + CloseGetter(); + } + } +abort: + XdmcpDisposeARRAY8( &displayClass ); + if (name) + free( (char *)name ); + if (class2) + free( (char *)class2 ); +} + +void +SendFailed( struct display *d, const char *reason ) +{ + Debug( "display start failed, sending \n" ); + send_failed( (struct sockaddr *)(d->from.data), d->from.length, d->name, + d->sessionID, reason, d->xdmcpFd ); +} + +static void +send_failed( struct sockaddr *from, int fromlen, + const char *name, CARD32 sessionID, const char *reason, int fd ) +{ + char buf[360]; + XdmcpHeader header; + ARRAY8 status; + + sprintf( buf, "Session %ld failed for display %.260s: %s", + (long)sessionID, name, reason ); + Debug( "send_failed(%\"s)\n", buf ); + status.length = strlen( buf ); + status.data = (CARD8Ptr) buf; + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16)FAILED; + header.length = 6 + status.length; + XdmcpWriteHeader( &buffer, &header ); + XdmcpWriteCARD32( &buffer, sessionID ); + XdmcpWriteARRAY8( &buffer, &status ); + XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); +} + +static void +send_refuse( struct sockaddr *from, int fromlen, CARD32 sessionID, int fd ) +{ + XdmcpHeader header; + + Debug( "send %ld\n", (long)sessionID ); + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16)REFUSE; + header.length = 4; + XdmcpWriteHeader( &buffer, &header ); + XdmcpWriteCARD32( &buffer, sessionID ); + XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); +} + +static void +send_alive( struct sockaddr *from, int fromlen, int length, int fd ) +{ + CARD32 sessionID; + CARD16 displayNumber; + struct display *d; + XdmcpHeader header; + CARD8 sendRunning; + CARD32 sendSessionID; + + Debug( "send \n" ); + if (XdmcpReadCARD16( &buffer, &displayNumber ) && + XdmcpReadCARD32( &buffer, &sessionID )) + { + if (length == 6) { + if (!(d = FindDisplayBySessionID( sessionID ))) + d = FindDisplayByAddress( (XdmcpNetaddr)from, fromlen, + displayNumber ); + sendRunning = 0; + sendSessionID = 0; + if (d && d->status == running) { + if (d->sessionID == sessionID) + sendRunning = 1; + sendSessionID = d->sessionID; + } + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16)ALIVE; + header.length = 5; + Debug( ": %d %ld\n", sendRunning, (long)sendSessionID ); + XdmcpWriteHeader( &buffer, &header ); + XdmcpWriteCARD8( &buffer, sendRunning ); + XdmcpWriteCARD32( &buffer, sendSessionID ); + XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); + } + } +} + +char * +NetworkAddressToHostname( CARD16 connectionType, ARRAY8Ptr connectionAddress ) +{ + switch (connectionType) { + case FamilyInternet: +#if defined(IPv6) && defined(AF_INET6) + case FamilyInternet6: +#endif + { + struct hostent *he; + char *name, *lname; + char *myDot; + int af_type; +#if defined(IPv6) && defined(AF_INET6) + char dotted[INET6_ADDRSTRLEN]; + + if (connectionType == FamilyInternet6) + af_type = AF_INET6; + else +#endif + af_type = AF_INET; + + he = gethostbyaddr( (char *)connectionAddress->data, + connectionAddress->length, af_type ); + if (he) { +#if defined(IPv6) && defined(AF_INET6) + struct addrinfo *ai, *nai; + if (!getaddrinfo( he->h_name, NULL, NULL, &ai )) { + for (nai = ai; nai; nai = nai->ai_next) { + if (af_type == nai->ai_family && + !memcmp( nai->ai_family == AF_INET ? + (char *)&((struct sockaddr_in *)nai->ai_addr)->sin_addr : + (char *)&((struct sockaddr_in6 *)nai->ai_addr)->sin6_addr, + connectionAddress->data, + connectionAddress->length )) + { + freeaddrinfo( ai ); + goto oki; + } + } + freeaddrinfo( ai ); +#else + if ((he = gethostbyname( he->h_name )) && + he->h_addrtype == AF_INET) + { + int i; + for (i = 0; he->h_addr_list[i]; i++) + if (!memcmp( he->h_addr_list[i], + connectionAddress->data, 4 )) + goto oki; +#endif + LogError( "DNS spoof attempt or misconfigured resolver.\n" ); + } + goto gotnone; + oki: + if (StrDup( &name, he->h_name ) && + !strchr( name, '.' ) && + (myDot = strchr( localHostname(), '.' ))) + { + if (ASPrintf( &lname, "%s%s", name, myDot )) { +#if defined(IPv6) && defined(AF_INET6) + if (!getaddrinfo( lname, NULL, NULL, &ai )) { + for (nai = ai; nai; nai = nai->ai_next) { + if (af_type == nai->ai_family && + !memcmp( nai->ai_family == AF_INET ? + (char *)&((struct sockaddr_in *)nai->ai_addr)->sin_addr : + (char *)&((struct sockaddr_in6 *)nai->ai_addr)->sin6_addr, + connectionAddress->data, + connectionAddress->length )) + { + freeaddrinfo( ai ); + free( name ); + return lname; + } + } + freeaddrinfo( ai ); + } +#else + if ((he = gethostbyname( lname )) && + he->h_addrtype == AF_INET) + { + int i; + for (i = 0; he->h_addr_list[i]; i++) + if (!memcmp( he->h_addr_list[i], + connectionAddress->data, 4 )) + { + free( name ); + return lname; + } + } +#endif + free( lname ); + } + } + } else { + gotnone: + /* can't get name, so use emergency fallback */ +#if defined(IPv6) && defined(AF_INET6) + inet_ntop( af_type, connectionAddress->data, + dotted, sizeof(dotted) ); + StrDup( &name, dotted ); +#else + ASPrintf( &name, "%[4|'.'hhu", connectionAddress->data ); +#endif + LogWarn( "Cannot convert Internet address %s to host name\n", + name ); + } + return name; + } +#ifdef DNET + case FamilyDECnet: + break; +#endif /* DNET */ + default: + break; + } + return 0; +} + +#endif /* XDMCP */ + diff --git a/tdm/config.def b/tdm/config.def new file mode 100644 index 000000000..a7ec59076 --- /dev/null +++ b/tdm/config.def @@ -0,0 +1,2662 @@ +# +# Copyright 2010 Timothy Pearson +# Copyright 2004-2005 Oswald Buddenhagen +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation. +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of a copyright holders shall +# not be used in advertising or otherwise to promote the sale, use or +# other dealings in this Software without prior written authorization +# from the copyright holders. +# + +# The contents of this section are copied into config.ci verbatim. + +#define RCVERMAJOR 2 +#define RCVERMINOR 3 + +#define TDMCONF KDE_CONFDIR "/tdm" +#define TDMDATA KDE_DATADIR "/tdm" + +#ifdef _AIX +# define HALT_CMD "/usr/sbin/shutdown -h now" +# define REBOOT_CMD "/usr/sbin/shutdown -r now" +#elif defined(BSD) +# define HALT_CMD "/sbin/shutdown -h now" +# define REBOOT_CMD "/sbin/shutdown -r now" +#elif defined(__SVR4) +# define HALT_CMD "/usr/sbin/halt" +# define REBOOT_CMD "/usr/sbin/reboot" +#else +# define HALT_CMD "/sbin/poweroff" +# define REBOOT_CMD "/sbin/reboot" +#endif + +#if defined(BSD) || defined(__linux__) +# define DEF_USER_PATH "/usr/local/bin:/opt/trinity/bin:/usr/bin:/bin:/opt/trinity/games:/usr/games" +# define DEF_SYSTEM_PATH "/usr/local/sbin:/usr/local/bin:/opt/trinity/sbin:/usr/sbin:/opt/trinity/bin:/usr/bin:/sbin:/bin" +#else +# define DEF_USER_PATH "/usr/local/bin:/opt/trinity/bin:/usr/bin:/bin:/opt/trinity/games:/usr/games:/usr/ucb" +# define DEF_SYSTEM_PATH "/usr/local/sbin:/usr/local/bin:/opt/trinity/sbin:/usr/sbin:/opt/trinity/bin:/usr/bin:/sbin:/bin:/etc:/usr/ucb" +#endif + +#if 0 /*def HASXDMAUTH*/ +# define DEF_AUTH_NAME "XDM-AUTHORIZATION-1,MIT-MAGIC-COOKIE-1" +#else +# define DEF_AUTH_NAME "MIT-MAGIC-COOKIE-1" +#endif + +#ifdef __linux__ +# define HAVE_VTS +#elif defined(__sun__) +# define DEF_SERVER_TTY "console" +#elif defined(_AIX) +# define DEF_SERVER_TTY "lft0" +#else +# define DEF_SERVER_TTY "" +#endif + +#ifdef _AIX +# define DEF_SERVER_CMD XBINDIR "/X -T -force" +#elif defined(__linux__) || defined(__GNU__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +/* we just assume that any free *nix installation has a recent xfree86/xorg */ +# define DEF_SERVER_CMD XBINDIR "/X -br" +#else +# define DEF_SERVER_CMD XBINDIR "/X" +#endif + + +# The contents of this section are copied mostly verbatim to the +# default/example configuration file. +# Everything indented with a space is considered a comment for the output; +# it is prefixed with a hash mark but otherwise copied verbatim (except +# for lines consisting of a single underscore, which generate empty comment +# lines). +# Section headers are "condensation seeds" for the Instance:s in the key +# definitions below. + + &tdm; master configuration file + _ + Please note: Settings in this file are sometimes ignored (overridden). + The default TDM startup script /etc/init.d/tdm looks in /etc/default/tdm.d + for theme-related settings which, if found, take precedence. The possibly + overridden settings are: UseBackground, BackgroundCfg, UseTheme, Theme. + See /usr/share/doc/tdm/README.Debian for details + _ + Definition: the greeter is the login dialog, i.e., the part of &tdm; + which the user sees. + _ + You can configure every X-display individually. + Every display has a display name, which consists of a host name + (which is empty for local displays specified in {Static|Reserve}Servers), + a colon, and a display number. Additionally, a display belongs to a + display class (which can be ignored in most cases; the control center + does not support this feature at all). + Sections with display-specific settings have the formal syntax + "[X-" host [":" number [ "_" class ]] "-" sub-section "]" + You can use the "*" wildcard for host, number, and class. You may omit + trailing components; they are assumed to be "*" then. + The host part may be a domain specification like ".inf.tu-dresden.de". + It may also be "+", which means non-empty, i.e. remote displays only. + From which section a setting is actually taken is determined by these + rules: + - an exact match takes precedence over a partial match (for the host part), + which in turn takes precedence over a wildcard ("+" taking precedence + over "*") + - precedence decreases from left to right for equally exact matches + Example: display name "myhost:0", class "dpy". + [X-myhost:0_dpy] precedes + [X-myhost:0_*] (same as [X-myhost:0]) precedes + [X-myhost:*_dpy] precedes + [X-myhost:*_*] (same as [X-myhost]) precedes + [X-+:0_dpy] precedes + [X-*:0_dpy] precedes + [X-*:0_*] (same as [X-*:0]) precedes + [X-*:*_*] (same as [X-*]) + These sections do NOT match this display: + [X-hishost], [X-myhost:0_dec], [X-*:1], [X-:*] + If a setting is not found in any matching section, the default is used. + _ + Every comment applies to the following section or key. Note that all + comments will be lost if you change this file with the kcontrol frontend. + The defaults refer to &tdm;'s built-in values, not anything set in this file. + _ + Special characters need to be backslash-escaped (leading and trailing + spaces (\\s), tab (\\t), linefeed (\\n), carriage return (\\r) and the + backslash itself (\\\\)). + In lists, fields are separated with commas without whitespace in between. + Some command strings are subject to simplified sh-style word splitting: + single quotes (') and double quotes (") have the usual meaning; the backslash + quotes everything (not only special characters). Note that the backslashes + need to be doubled because of the two levels of quoting. + +[General] + +[Xdmcp] + +[Shutdown] + + Rough estimations about how many seconds &tdm; will spend at most on + - opening a connection to the X-server (OpenTime) if the attempt + - times out: OpenTimeout + - is refused: OpenRepeat * OpenDelay + - starting a local X-server (ServerTime): + ServerAttempts * (ServerTimeout + OpenDelay) + - starting a display: + - local display: ServerTime + OpenTime + - foreign display: StartAttempts * OpenTime + - &XDMCP; display: OpenTime (repeated indefinitely by client) + + Core config for all displays +[X-*-Core] + + Greeter config for all displays +[X-*-Greeter] + + Core config for local displays +[X-:*-Core] + + Greeter config for local displays +[X-:*-Greeter] + + Core config for 1st local display +[X-:0-Core] + + Greeter config for 1st local display +[X-:0-Greeter] + + +# The contents of this section are copied into tdmrc-ref.docbook. +# The macro %REF% is replaced with the accumulated Description:s from the key +# definitions below. + + +The Files &tdm; Uses for Configuration + +This chapter documents the files that control &tdm;'s behavior. +Some of this can be also controlled from the &kcontrol; module, but +not all. + + +&tdmrc; - The &tdm; master configuration file + +The basic format of the file is INI-like. +Options are key/value pairs, placed in sections. +Everything in the file is case sensitive. +Syntactic errors and unrecognized key/section identifiers cause &tdm; to +issue non-fatal error messages. + +Lines beginning with # are comments; empty lines +are ignored as well. + +Sections are denoted by +[Name of Section]. + + +You can configure every X-display individually. +Every display has a display name, which consists of a host name +(which is empty for local displays specified in +or ), a colon, and a display number. +Additionally, a display belongs to a +display class (which can be ignored in most cases). + +Sections with display-specific settings have the formal syntax +[X- host [ : number [ _ class ] ] - sub-section ] + +All sections with the same sub-section +make up a section class. + +You can use the wildcard * (match any) for +host, number, +and class. You may omit trailing components; +they are assumed to be * then. The host part may be a +domain specification like .inf.tu-dresden.de +or the wildcard + (match non-empty). + +From which section a setting is actually taken is determined by +these rules: + + + +An exact match takes precedence over a partial match (for the +host part), which in turn takes precedence over a wildcard +(+ taking precendence over *). + + + +Precedence decreases from left to right for equally exact matches. + + + + + +Example: display name myhost.foo:0, class dpy + + + +[X-myhost.foo:0_dpy] precedes + + +[X-myhost.foo:0_*] (same as [X-myhost.foo:0]) precedes + + +[X-myhost.foo:*_dpy] precedes + + +[X-myhost.foo:*_*] (same as [X-myhost.foo]) precedes + + +[X-.foo:*_*] (same as [X-.foo]) precedes + + +[X-+:0_dpy] precedes + + +[X-*:0_dpy] precedes + + +[X-*:0_*] (same as [X-*:0]) precedes + + +[X-*:*_*] (same as [X-*]). + + +These sections do not match this display: +[X-hishost], [X-myhost.foo:0_dec], [X-*:1], [X-:*] + + + + + + + +Common sections are [X-*] (all displays), [X-:*] (all local displays) +and [X-:0] (the first local display). + +The format for all keys is + = value. +Keys are only valid in the section class they are defined for. +Some keys do not apply to particular displays, in which case they are ignored. + + +If a setting is not found in any matching section, the default +is used. + +Special characters need to be backslash-escaped (leading and trailing +spaces (\s), tab (\t), linefeed +(\n), carriage return (\r) and the +backslash itself (\\)). +In lists, fields are separated with commas without whitespace in between. + +Some command strings are subject to simplified sh-style word splitting: +single quotes (') and double quotes (") +have the usual meaning; the backslash quotes everything (not only special +characters). Note that the backslashes need to be doubled because of the +two levels of quoting. + +A pristine &tdmrc; is very thoroughly commented. +All comments will be lost if you change this file with the +kcontrol frontend. + +%REF% + + + + +Specifying permanent &X-Server;s + +Each entry in the list indicates a +display which should constantly be +managed and which is not using &XDMCP;. This method is typically used only for +local &X-Server;s that are started by &tdm;, but &tdm; can manage externally +started (foreign) &X-Server;s as well, may they run on the +local machine or rather remotely. + +The formal syntax of a specification is + +display name [_display class] + +for all &X-Server;s. Foreign displays differ in having +a host name in the display name, may it be localhost. + +The display name must be something that can +be passed in the option to an X program. This string +is used to generate the display-specific section names, so be careful to match +the names. +The display name of &XDMCP; displays is derived from the display's address by +reverse host name resolution. For configuration purposes, the +localhost prefix from locally running &XDMCP; displays is +not stripped to make them distinguishable from local +&X-Server;s started by &tdm;. + +The display class portion is also used in the +display-specific sections. This is useful if you have a large collection of +similar displays (such as a corral of X terminals) and would like to set +options for groups of them. +When using &XDMCP;, the display is required to specify the display class, +so the manual for your particular X terminal should document the display +class string for your device. If it does not, you can run &tdm; in debug +mode and grep the log for class. + +The displays specified in will not be +started when &tdm; starts up, but when it is explicitly requested via +the command socket (or FiFo). +If reserve displays are specified, the &kde; menu will have a +Start New Session item near the bottom; use that to +activate a reserve display with a new login session. The monitor will switch +to the new display, and you will have a minute to login. If there are no more +reserve displays available, the menu item will be disabled. + +When &tdm; starts a session, it sets up authorization data for the +&X-Server;. For local servers, &tdm; passes + filename +on the &X-Server;'s command line to point it at its authorization data. +For &XDMCP; displays, &tdm; passes the authorization data to the &X-Server; +via the Accept &XDMCP; message. + + + + +&XDMCP; access control + +The file specified by the option provides +information which &tdm; uses to control access from displays requesting service +via &XDMCP;. +The file contains four types of entries: entries which control the response +to Direct and Broadcast queries, entries which +control the response to Indirect queries, macro definitions for +Indirect entries, and entries which control on which network +interfaces &tdm; listens for &XDMCP; queries. +Blank lines are ignored, # is treated as a comment +delimiter causing the rest of that line to be ignored, and \ +causes an immediately following newline to be ignored, allowing indirect host +lists to span multiple lines. + + +The format of the Direct entries is simple, either a +host name or a pattern, which is compared against the host name of the display +device. +Patterns are distinguished from host names by the inclusion of one or more +meta characters; * matches any sequence of 0 or more +characters, and ? matches any single character. +If the entry is a host name, all comparisons are done using network addresses, +so any name which converts to the correct network address may be used. Note +that only the first network address returned for a host name is used. +For patterns, only canonical host names are used in the comparison, so ensure +that you do not attempt to match aliases. +Host names from &XDMCP; queries always contain the local domain name +even if the reverse lookup returns a short name, so you can use +patterns for the local domain. +Preceding the entry with a ! character causes hosts which +match that entry to be excluded. +To only respond to Direct queries for a host or pattern, +it can be followed by the optional NOBROADCAST keyword. +This can be used to prevent a &tdm; server from appearing on menus based on +Broadcast queries. + +An Indirect entry also contains a host name or pattern, +but follows it with a list of host names or macros to which the queries +should be forwarded. Indirect entries can be excluding as well, +in which case a (valid) dummy host name must be supplied to make the entry +distinguishable from a Direct entry. +If compiled with IPv6 support, multicast address groups may also be included +in the list of addresses the queries are forwarded to. + +If the indirect host list contains the keyword CHOOSER, +Indirect queries are not forwarded, but instead a host chooser +dialog is displayed by &tdm;. The chooser will send a Direct +query to each of the remaining host names in the list and offer a menu of +all the hosts that respond. The host list may contain the keyword +BROADCAST, to make the chooser send a +Broadcast query as well; note that on some operating systems, +UDP packets cannot be broadcast, so this feature will not work. + + +When checking access for a particular display host, each entry is scanned +in turn and the first matching entry determines the response. +Direct and Broadcast entries are ignored when +scanning for an Indirect entry and vice-versa. + +A macro definition contains a macro name and a list of host names and +other macros that the macro expands to. To distinguish macros from hostnames, +macro names start with a % character. + +The last entry type is the LISTEN directive. +The formal syntax is + + LISTEN [interface [multicast list]] + +If one or more LISTEN lines are specified, &tdm; listens +for &XDMCP; requests only on the specified interfaces. +interface may be a hostname or IP address +representing a network interface on this machine, or the wildcard +* to represent all available network interfaces. +If multicast group addresses are listed on a LISTEN line, +&tdm; joins the multicast groups on the given interface. For IPv6 multicasts, +the IANA has assigned ff0X:0:0:0:0:0:0:12b as the +permanently assigned range of multicast addresses for &XDMCP;. The +X in the prefix may be replaced by any valid scope +identifier, such as 1 for Node-Local, 2 for Link-Local, 5 for Site-Local, and +so on (see IETF RFC 2373 or its replacement for further details and scope +definitions). &tdm; defaults to listening on the Link-Local scope address +ff02:0:0:0:0:0:0:12b to most closely match the IPv4 subnet broadcast behavior. +If no LISTEN lines are given, &tdm; listens on all +interfaces and joins the default &XDMCP; IPv6 multicast group (when +compiled with IPv6 support). +To disable listening for &XDMCP; requests altogether, a +LISTEN line with no addresses may be specified, but using +the [Xdmcp] option is preferred. + + + + + +Supplementary programs + + +The following programs are run by &tdm; at various stages of a session. +They typically are shell scripts. + + + +The Setup, Startup and Reset programs are run as +root, so they should be careful +about security. +Their first argument is auto if the session results +from an automatic login; otherwise, no arguments are passed to them. + + + +Setup program + + +The Xsetup program is run after the &X-Server; is +started or reset, but before the greeter is offered. +This is the place to change the root background (if + is disabled) or bring up other windows that +should appear on the screen along with the greeter. + + + +In addition to any specified by , +the following environment variables are passed: + + + DISPLAY + the associated display name + + + PATH + the value of + + + SHELL + the value of + + + XAUTHORITY + may be set to an authority file + + + DM_CONTROL + the value of + + + + Note that since &tdm; grabs the keyboard, any other windows will not be +able to receive keyboard input. They will be able to interact with the mouse, +however; beware of potential security holes here. If +is set, Xsetup will not be able to connect to the display +at all. Resources for this program can be put into the file named by +. + + + + + +Startup program + +The Xstartup program is run as +root when the user logs in. +This is the place to put commands which add entries to +utmp (the sessreg program +may be useful here), mount users' home directories from file servers, +or abort the session if some requirements are not met (but note that on +modern systems, many of these tasks are already taken care of by +PAM modules). + +In addition to any specified by , +the following environment variables are passed: + + + DISPLAY + the associated display name + + + HOME + the initial working directory of the user + + + LOGNAME + the username + + + USER + the username + + + PATH + the value of + + + SHELL + the value of + + + XAUTHORITY + may be set to an authority file + + + DM_CONTROL + the value of + + + +&tdm; waits until this program exits before starting the user session. +If the exit value of this program is non-zero, &tdm; discontinues the session +and starts another authentication cycle. + + + + +Session program + +The Xsession program is the command which is run +as the user's session. It is run with the permissions of the authorized user. +One of the keywords failsafe, default +or custom, or a string to eval by a +Bourne-compatible shell is passed as the first argument. + +In addition to any specified by , +the following environment variables are passed: + + + DISPLAY + the associated display name + + + HOME + the initial working directory of the user + + + LOGNAME + the username + + + USER + the username + + + PATH + the value of + (or for + root user sessions) + + + + SHELL + the user's default shell + + + XAUTHORITY + may be set to a non-standard authority file + + + KRBTKFILE + may be set to a Kerberos4 credentials cache name + + + + KRB5CCNAME + may be set to a Kerberos5 credentials cache name + + + + DM_CONTROL + the value of + + + XDM_MANAGED + will contain a comma-separated list of parameters the + session might find interesting, like the location of the command + FiFo and its capabilities, and which conversation + plugin was used for the login + + + + DESKTOP_SESSION + the name of the session the user has chosen to run + + + + + + + +Reset program + +Symmetrical with Xstartup, the +Xreset program is run after the user session has +terminated. Run as root, it should +contain commands that undo the effects of commands in +Xstartup, removing entries from utmp +or unmounting directories from file servers. + +The environment variables that were passed to +Xstartup are also passed to Xreset. + + + + + + + + + + +# The rest of this file are section and key definitions for the options. +# The order of the keywords is fixed and everything is case sensitive. +# A keyword may expect supplementary data in the form of space-indented +# lines following it. Definitions are delimited by empty lines. +# +# Section definition: +# Section: +# Section name. Section classes start with a dash. +# If: +# C preprocessor conditional for supporting this section. +# If it evaluates to false, all keys in this section are disabled as well. +# Description: +# A docbook description of this section is expected in the next lines. +# The contents are automatically enclosed in . +# +# Option key definition: +# Key: +# Option name. +# If: +# C preprocessor conditional for supporting this option. +# Type: (int|bool|enum|group|string|path|list) +# The option's data type. +# If the type is enum, the element definitions follow in the next lines: +# [/]: +# Default: +# Default value. string, path and list are copied verbatim and therefore +# must be already quoted appropriately. The other types are auto-quoted. +# If the default value is prefixed with a "*", a c #define def_ is +# created. +# The default is automatically appended to the tdmrc comment and the +# documentation entry. +# CDefault: +# Append this instead of the real default to the two docs. The quoting +# rules are the same as for Default. +# DDefault: - +# If specified, the default value will not be appended to the documentation +# entry. The Description should mention the default then. Use this when +# the default is system-dependent. +# PostProc: +# A function to postprocess the read config value before using it. +# User: (dummy|(core|greeter|greeter-c|dep|config)[()][:font]) +# These entries specify which parts of tdm need the option in question: +# dummy: no user; entry is there only for syntactical correctness. +# dep: this option is an internal dependency for another option. +# config: this option configures the config reader itself. +# core: the tdm backend needs this option. +# greeter-c: the tdm frontend needs this option as a C data type. +# greeter: the tdm frontend needs this option as a C++/Qt data type. +# If a :font tag is appended, a string entry is converted to a QFont. +# If no variable name is specified, it will be derived from the Key by +# un-capitalizing it. +# Instance: (-|[#][/](!|)) +# These entries specify option instances for the default/example tdmrc. +# A "-" entry is a dummy for syntactical correctness. +# A prefixing hash mark will be copied to tdmrc. +# For options in a section class a display must be specified. +# For bool options "!" can be used as the value to specify the negation +# of the default. +# Update: [/] +# Call this function on each occurence of this option in gentdmconf. +# Options with higher numbers (default is 0) will be processed later. +# Merge: (xdm[:][()]|tdm:[

/][][]) +# Specify config options to merge from xdm and older tdm versions. +# Kdm options from the current version are automatically merged. +# When merging an xdm resource and no resource name is specified, it is +# derived from the Key by un-capitalizing it. +# When merging a tdm option, at least one of
and must +# be given; an unspecified entity defaults to the current Section/Key. +#
may be a dash-prefixed section class. +# A function to postprocess the read value can be specified. +# Comment: [&|-] +# A tdmrc comment for this option is expected in the next lines. +# If "-" is given to Comment, no comment is generated at all. +# If "&" is given, the comment is derived from the Description below by +# applying some simple docbook interpretation to it. Note that the +# Description must be preformatted in this case. Use +# sed -ne 's/^\(.\{79,\}\)$/\1/p' < tdmrc +# after running "make install" to see whether all lines still fit. +# If Type is enum, a list of the previously defined element/description +# pairs is appended; the descriptions undergo docbook interpretation. +# Finally, a sentence with the Default (or CDefault, if given) is appended. +# Description: [!|-] +# A docbook description of this option is expected in the next lines. +# The contents are automatically enclosed in . +# If "-" is given to Description, no comment is generated at all. +# If "!" is given, enums are not treated specially; otherwise, the macro +# %ENUM% is replaced with a list of the defined element/description pairs, +# or - if the macro is not present - the list is appended to the +# description. +# Finally, a sentence with the Default (or CDefault, if given) is appended, +# unless "DDefault: -" was specified. +# Each option entry generates an anchor named option-; +# it can be referenced in the main documentation. +# Do not forget to run "make ref" in tdebase/doc/tdm after changing +# Descriptions. + +Section: General +Description: + This section contains global options that do not fit into any specific section. + +Key: ConfigVersion +Type: string +Default: "" +CDefault: - +User: dummy +# will be overwritten +Instance: +Comment: + This option exists solely for the purpose of a clean automatic upgrade. + Do not even think about changing it! +Description: + This option exists solely for the purpose of clean automatic upgrades. + Do not change it, you may interfere with future + upgrades and this could result in &tdm; failing to run. + +Key: PAMService +If: defined(USE_PAM) +Type: string +Default: TDM_PAM_SERVICE +User: core +Instance: - +Comment: - +Description: - + + +Proc: absorb_xservers +# note: this can miss Xservers from tdm for kde 2.2 because of stupid default. +Source: tdm:General/Xservers +Source: xdm:servers + + +Key: StaticServers +Type: list +Default: ":0" +User: core +Instance: ":0" +Comment: + List of permanent displays. Displays with a hostname are foreign. A display + class may be specified separated by an underscore. +Description: + List of displays (&X-Server;s) permanently managed by &tdm;. Displays with a + hostname are foreign displays which are expected to be already running, + the others are local displays for which &tdm; starts an own &X-Server;; + see . Each display may belong to a display class; + append it to the display name separated by an underscore. + See for the details. + +Key: ReserveServers +Type: list +Default: "" +User: core +Instance: ":1,:2,:3" +Comment: & +Description: + List of on-demand displays. See for syntax. + +Key: ServerVTs +If: defined(HAVE_VTS) +Type: list +Default: "" +User: core +Instance: #"7,8,-9,-10" +Update: upd_servervts +Comment: + VTs to allocate to &X-Server;s. A negative number means that the VT will be + used only if it is free. If all VTs in this list are used up, the next free + one greater than the last one in this list will be allocated. +Description: + List of Virtual Terminals to allocate to &X-Server;s. For negative numbers the + absolute value is used, and the VT will be allocated only + if the kernel says it is free. If &tdm; exhausts this list, it will allocate + free VTs greater than the absolute value of the last entry + in this list. + Currently Linux only. + +Key: ConsoleTTYs +If: defined(HAVE_VTS) +Type: list +Default: "" +User: core +Instance: #"tty1,tty2,tty3,tty4,tty5,tty6" +Update: upd_consolettys +Comment: + TTYs (without /dev/) to monitor for activity while in console mode. +Description: + This option is for operating systems (OSs) with support + for virtual terminals (VTs), by both &tdm; and the + OSs itself. + Currently this applies only to Linux. + + When &tdm; switches to console mode, it starts monitoring all + TTY lines listed here (without the leading + /dev/). + If none of them is active for some time, &tdm; switches back to the X login. + +Key: PidFile +Type: string +Default: "" +User: core +Instance: "/var/run/tdm.pid" +Merge: xdm +Comment: + Where &tdm; should store its PID (do not store if empty). +Description: + The filename specified will be created to contain an ASCII representation + of the process ID of the main &tdm; process; the PID will not be stored + if the filename is empty. + +Key: LockPidFile +Type: bool +Default: true +User: core +Instance: #! +Merge: xdm +Comment: + Whether &tdm; should lock the PID file to prevent having multiple &tdm; + instances running at once. Do not change unless you are brave. +Description: + This option controls whether &tdm; uses file locking to keep multiple + display managers from running onto each other. + +Key: AuthDir +Type: path +# differs from XDM +Default: "/var/run/xauth" +User: core +Instance: #"/tmp" +Merge: xdm(P_authDir) +Comment: + Where to store authorization files. +Description: + This names a directory under which &tdm; stores &X-Server; authorization + files while initializing the session. &tdm; expects the system to clean up + this directory from stale files on reboot. + + The authorization file to be used for a particular display can be + specified with the option in [X-*-Core]. + +Key: AutoRescan +Type: bool +Default: true +User: core +Instance: #! +Merge: xdm +Comment: + Whether &tdm; should automatically re-read configuration files, if it + finds them having changed. +Description: + This boolean controls whether &tdm; automatically re-reads its + configuration files if it finds them to have changed. + +Key: ExportList +Type: list +Default: "" +User: core +Instance: #"LD_LIBRARY_PATH,ANOTHER_IMPORTANT_VAR" +Merge: xdm(P_List) +Comment: & +Description: + Additional environment variables &tdm; should pass on to all programs it runs. + LD_LIBRARY_PATH and XCURSOR_THEME are good candidates; + otherwise, it should not be necessary very often. + +Key: RandomFile +If: !defined(ARC4_RANDOM) && !defined(DEV_RANDOM) +Type: string +Default: "/dev/mem" +User: core +Instance: #"" +Merge: xdm +Comment: + A file &tdm; should read entropy from. +Description: + If the system has no native entropy source like /dev/urandom (see + ) and no entropy daemon like EGD (see + and ) is running, + &tdm; will fall back to its own pseudo-random number generator + that will, among other things, successively checksum parts of this file + (which, obviously, should change frequently). + + This option does not exist on Linux and various BSDs. + +Key: PrngdSocket +If: !defined(ARC4_RANDOM) && !defined(DEV_RANDOM) +Type: string +# differs from xdm! +Default: "" +User: core +Instance: #"/tmp/entropy" +Merge: xdm +Comment: + A UNIX domain socket &tdm; should read entropy from. +Description: + If the system has no native entropy source like /dev/urandom (see + ), read random data from a Pseudo-Random + Number Generator Daemon, + like EGD (http://egd.sourceforge.net) via this UNIX domain socket. + + This option does not exist on Linux and various BSDs. + +Key: PrngdPort +If: !defined(ARC4_RANDOM) && !defined(DEV_RANDOM) +Type: int +Default: 0 +User: core +Instance: #4840 +Merge: xdm +Comment: + A TCP socket on localhost &tdm; should read entropy from. +Description: + Same as , only use a TCP socket on localhost. + +Key: RandomDevice +If: !defined(ARC4_RANDOM) +Type: string +Default: "" +User: core +Instance: #"/dev/altrandom" +Merge: xdm +Comment: + A character device &tdm; should read entropy from. + Empty means use the system's preferred entropy device. +Description: + The path to a character device which &tdm; should read random data from. + Empty means to use the system's preferred entropy device if there is one. + + This option does not exist on OpenBSD, as it uses the arc4_random + function instead. + +Key: FifoDir +Type: path +Default: *"/var/run/xdmctl" +User: core +Instance: #"/tmp" +Update: upd_fifodir +Comment: + Where the command FiFos should be created; make it empty to disable + them. +Description: + The directory in which the command FiFos should + be created; make it empty to disable them. +# See for the details. + +Key: FifoGroup +Type: group +Default: 0 +User: core +Instance: #xdmctl +Comment: & +Description: + The group to which the global command FiFo should belong; + can be either a name or a numerical ID. + +Key: DataDir +Type: path +Default: *"/var/lib/tdm" +User: greeter +Instance: #"" +Update: upd_datadir +Comment: + The directory in which &tdm; should store persistent working data. +Description: + The directory in which &tdm; should store persistent working data; such data + is, for example, the previous user that logged in on a particular display. + +Key: DmrcDir +Type: path +Default: "" +User: core +Instance: #"/nfs-shared/var/dmrcs" +Comment: & +Description: + The directory in which &tdm; should store users' .dmrc files. This is only + needed if the home directories are not readable before actually logging in + (like with AFS). + + +Section: Xdmcp +If: defined(XDMCP) +Description: + This section contains options that control &tdm;'s handling of + &XDMCP; requests. +# See to find out what &XDMCP; is. + +Key: Enable +Type: bool +Default: true +User: dep(xdmcpEnable) +Instance: false +Comment: & +Description: + Whether &tdm; should listen to incoming &XDMCP; requests. + +Key: Port +Type: int +Default: 177 +PostProc: PrequestPort +User: core(request_port) +Instance: # +Merge: xdm:requestPort(P_requestPort) +Comment: + The UDP port on which &tdm; should listen for &XDMCP; requests. Do not change. +Description: + This indicates the UDP port number which &tdm; uses to listen for incoming + &XDMCP; requests. Unless you need to debug the system, leave this with its + default value. + +Key: KeyFile +Type: string +Default: "" +User: core +Instance: #TDMCONF "/tdmkeys" +Update: cp_keyfile +Merge: xdm +Comment: + File with the private keys of X-terminals. Required for XDM authentication. +Description: + XDM-AUTHENTICATION-1 style &XDMCP; authentication requires a private + key to be shared between &tdm; and the terminal. This option specifies + the file containing those values. Each entry in the file consists of a + display name and the shared key. + +Key: Xaccess +Type: string +# differs from xdm +Default: *TDMCONF "/Xaccess" +User: config(Xaccess) +Instance: #"" +Update: mk_xaccess +Merge: xdm:accessFile +Comment: + &XDMCP; access control file in the usual XDM-Xaccess format. +Description: + To prevent unauthorized &XDMCP; service and to allow forwarding of &XDMCP; + IndirectQuery requests, this file contains a database of hostnames which + are either allowed direct access to this machine, or have a list of hosts + to which queries should be forwarded to. The format of this file is + described in . + +Key: ChoiceTimeout +Type: int +Default: 15 +User: core +Instance: #10 +Merge: xdm +Comment: + Number of seconds to wait for display to respond after the user has + selected a host from the chooser. +Description: + Number of seconds to wait for the display to respond after the user has + selected a host from the chooser. If the display sends an &XDMCP; + IndirectQuery within this time, the request is forwarded to the chosen + host; otherwise, it is assumed to be from a new session and the chooser + is offered again. + +Key: RemoveDomainname +Type: bool +Default: true +User: core +Instance: #! +Merge: xdm +Comment: + Strip domain name from remote display names if it is equal to the local + domain. +Description: + When computing the display name for &XDMCP; clients, the name resolver will + typically create a fully qualified host name for the terminal. As this is + sometimes confusing, &tdm; will remove the domain name portion of the host + name if it is the same as the domain name of the local host when this option + is enabled. + +Key: SourceAddress +Type: bool +Default: false +User: core +Instance: #! +Merge: xdm +Comment: + Use the numeric IP address of the incoming connection on multihomed hosts + instead of the host name. +Description: + Use the numeric IP address of the incoming connection on multihomed hosts + instead of the host name. This is to avoid trying to connect on the wrong + interface which might be down at this time. + +Key: Willing +Type: string +Default: "" +User: core +# will be overwritten +Instance: # +Update: mk_willing +Merge: xdm +Merge: tdm:Xwilling +Comment: + The program which is invoked to dynamically generate replies to &XDMCP; + DirectQuery or BroadcastQuery requests. + If empty, no program is invoked and "Willing to manage" is sent. +Description: + This specifies a program which is run (as + root) when an &XDMCP; + DirectQuery or BroadcastQuery is received and this host is configured + to offer &XDMCP; display management. The output of this program may be + displayed in a chooser window. If no program is specified, the string + Willing to manage is sent. + + +Section: Shutdown +Description: + This section contains global options concerning system shutdown. + +Key: HaltCmd +Type: string +Default: HALT_CMD +DDefault: - +User: core(cmdHalt) +Instance: #"" +Comment: + The command (subject to word splitting) to run to halt the system. +Description: + The command (subject to word splitting) to run to halt/poweroff the system. + + The default is something reasonable for the system on which &tdm; was built, like + /sbin/shutdown  now. + +Key: RebootCmd +Type: string +Default: REBOOT_CMD +DDefault: - +User: core(cmdReboot) +Instance: #"" +Comment: + The command (subject to word splitting) to run to reboot the system. +Description: + The command (subject to word splitting) to run to reboot the system. + + The default is something reasonable for the system &tdm; on which was built, like + /sbin/shutdown  now. + +Key: AllowFifo +Type: bool +Default: false +User: core(fifoAllowShutdown) +Instance: #! +Comment: & +Description: + Whether it is allowed to shut down the system via the global command FiFo. + +Key: AllowFifoNow +Type: bool +Default: true +User: core(fifoAllowNuke) +Instance: #! +Comment: + Whether it is allowed to abort active sessions when shutting down the + system via the global command FiFo. +Description: + Whether it is allowed to abort active sessions when shutting down the + system via the global command FiFo. + + This will have no effect unless is enabled. + +Key: BootManager +Type: enum + None/BO_NONE: no boot manager + Grub/BO_GRUB: Grub boot manager + Lilo/BO_LILO: Lilo boot manager (Linux on i386 & x86-64 only) +Default: None +User: core +User: greeter +Instance: #Grub +Merge: tdm:UseLilo(P_UseLilo) +Comment: & +Description: + The boot manager &tdm; should use for offering boot options in the + shutdown dialog. + + +Section: -Core +Description: + This section class contains options concerning the configuration + of the &tdm; backend (core). + +Key: OpenDelay +Type: int +Default: 15 +User: core +Instance: #*/ +Merge: xdm(P_openDelay) +Comment: + How long to wait before retrying to connect a display. +Description: + See . + +Key: OpenTimeout +Type: int +Default: 120 +User: core +Instance: #*/ +Merge: xdm +Comment: + How long to wait before timing out a display connection attempt. +Description: + See . + +Key: OpenRepeat +Type: int +Default: 5 +User: core +Instance: #*/ +Merge: xdm +Comment: + How many connection attempts to make during a start attempt. Note that + a timeout aborts the entire start attempt. +Description: + These options control the behavior of &tdm; when attempting to open a + connection to an &X-Server;. is the length + of the pause (in seconds) between successive attempts, + is the number of attempts to make and + is the amount of time to spend on a + connection attempt. After attempts have been + made, or if seconds elapse in any particular + connection attempt, the start attempt is considered failed. + +Key: StartAttempts +Type: int +Default: 4 +User: core +Instance: #*/ +Merge: xdm +Comment: + Try at most that many times to start a display. If this fails, the display + is disabled. +Description: + How many times &tdm; should attempt to start a foreign + display listed in before giving up + and disabling it. + Local displays are attempted only once, and &XDMCP; displays are retried + indefinitely by the client (unless the option + was given to the &X-Server;). + +Key: ServerAttempts +Type: int +Default: 1 +User: core +Instance: #:*/ +Merge: xdm +Comment: + How often to try to run the &X-Server;. Running includes executing it and + waiting for it to come up. +Description: + How many times &tdm; should attempt to start up a local &X-Server;. + Starting up includes executing it and waiting for it to come up. + +Key: ServerTimeout +Type: int +Default: 15 +User: core +Instance: #:*/ +Comment: + How long to wait for a local &X-Server; to come up. +Description: + How many seconds &tdm; should wait for a local &X-Server; to come up. + +Key: ServerCmd +Type: string +Default: DEF_SERVER_CMD +DDefault: - +User: core +Instance: :*/DEF_SERVER_CMD +Comment: + The command line to start the &X-Server;, without display number and VT spec. + This string is subject to word splitting. +Description: + The command line to start the &X-Server;, without display number and VT spec. + This string is subject to word splitting. + + The default is something reasonable for the system on which &tdm; was built, + like /usr/bin/X. + +Key: ServerArgsLocal +Type: string +Default: "" +User: core +Instance: :*/"-nolisten tcp" +Comment: & +Description: + Additional arguments for the &X-Server;s for local sessions. + This string is subject to word splitting. + +Key: ServerArgsRemote +Type: string +Default: "" +User: core +Instance: #:*/"" +Comment: & +Description: + Additional arguments for the &X-Server;s for remote sessions. + This string is subject to word splitting. + +Key: ServerVT +If: defined(HAVE_VTS) +Type: int +Default: 0 +User: core(reqSrvVT) +Instance: #:0/7 +Comment: + The VT the &X-Server; should run on; auto-assign if zero, don't assign if -1. + Better leave it zero and use ServerVTs. +Description: + The VT the &X-Server; should run on. + should be used instead of this option. + Leave it zero to let &tdm; assign a VT automatically. + Set it to -1 to avoid assigning a VT + alltogether - this is required for setups with multiple physical consoles. + Currently Linux only. + +Key: ServerTTY +If: !defined(HAVE_VTS) +Type: string +Default: "" +User: core(console) +Instance: :0/DEF_SERVER_TTY +Comment: + The TTY line (without /dev/) the &X-Server; covers physically. +Description: + This option is for OSs without support for + VTs, either by &tdm; or the OS itself. + Currently this applies to all OSs but Linux. + + When &tdm; switches to console mode, it starts monitoring this + TTY line (specified without the leading + /dev/) for activity. If the line is not used for some time, + &tdm; switches back to the X login. + +Key: PingInterval +Type: int +Default: 5 +User: core +User: greeter +Instance: #*/ +Merge: xdm +Comment: + Ping remote display every that many minutes. +Description: + See . + +Key: PingTimeout +Type: int +Default: 5 +User: core +User: greeter +Instance: #*/ +Merge: xdm +Comment: + Wait for a Pong that many minutes. +Description: + To discover when remote displays disappear, &tdm; + regularly pings them. + specifies the time (in minutes) between the + pings and specifies the maximum amount of + time (in minutes) to wait for the terminal to respond to the request. If + the terminal does not respond, the session is declared dead and terminated. + + If you frequently use X terminals which can become isolated from + the managing host, you may wish to increase the timeout. The only worry + is that sessions will continue to exist after the terminal has been + accidentally disabled. + +Key: TerminateServer +Type: bool +Default: false +User: core +Instance: #:*/! +Merge: xdm +Comment: + Restart instead of resetting the local &X-Server; after session exit. + Use it if the server leaks memory etc. +Description: + Whether &tdm; should restart the local &X-Server; after session exit instead + of resetting it. Use this if the &X-Server; leaks memory or crashes the system + on reset attempts. + +Key: ResetSignal +Type: int +Default: 1 +CDefault: 1 (SIGHUP) +User: core +Instance: #:*/ +Merge: xdm +Comment: + The signal needed to reset the local &X-Server;. +Description: + The signal number to use to reset the local &X-Server;. + +Key: TermSignal +Type: int +Default: 15 +CDefault: 15 (SIGTERM) +User: core +Instance: #:*/ +Merge: xdm +Comment: + The signal needed to terminate the local &X-Server;. +Description: + The signal number to use to terminate the local &X-Server;. + +Key: Authorize +Type: bool +Default: true +User: core +Instance: #:*/! +Merge: xdm +Comment: + Create X-authorizations for local displays. +Description: + Controls whether &tdm; generates and uses authorization for + local &X-Server; connections. + For &XDMCP; displays the authorization requested by the display is used; + foreign non-&XDMCP; displays do not support authorization at all. + +Key: AuthNames +Type: list +Default: DEF_AUTH_NAME +User: core +Instance: #:*/"" +Merge: xdm:authName +Comment: + Which X-authorization mechanisms should be used. +Description: + If is true, use the authorization mechanisms + listed herein. The MIT-MAGIC-COOKIE-1 authorization is always available; + XDM-AUTHORIZATION-1, SUN-DES-1 and MIT-KERBEROS-5 might be available as well, + depending on the build configuration. + +Key: ResetForAuth +Type: bool +Default: false +User: core +Instance: #:*/! +Merge: xdm +Comment: + Need to reset the &X-Server; to make it read initial Xauth file. +Description: + Some old &X-Server;s re-read the authorization file + at &X-Server; reset time, instead of when checking the initial connection. + As &tdm; generates the authorization information just before connecting to + the display, an old &X-Server; would not get up-to-date authorization + information. This option causes &tdm; to send SIGHUP to the &X-Server; + after setting up the file, causing an additional &X-Server; reset to occur, + during which time the new authorization information will be read. + +Key: AuthFile +Type: string +Default: "" +User: core(clientAuthFile) +Instance: #*/"" +Merge: xdm +Comment: + The name of this &X-Server;'s Xauth file. + If empty, a random name in the AuthDir directory will be used. +Description: + This file is used to communicate the authorization data from &tdm; to + the &X-Server;, using the &X-Server; command line + option. It should be kept in a directory which is not world-writable + as it could easily be removed, disabling the authorization mechanism in + the &X-Server;. If not specified, a random name is generated from + and the name of the display. + +Key: Resources +# XXX strictly speaking this is supposed to be a string list, i think. +Type: string +Default: "" +User: core +Instance: #*/"" +Update: cp_resources +Merge: xdm +Comment: + Specify a file with X-resources for the greeter, chooser and background. + The KDE frontend does not use this file, so you do not need it unless you + use another background generator than krootimage. +Description: + This option specifies the name of the file to be loaded by + xrdb as the resource database onto the root window + of screen 0 of the display. KDE programs generally do not use + X-resources, so this option is only needed if the + program needs some X-resources. + +Key: Xrdb +Type: string +Default: XBINDIR "/xrdb" +User: core +Instance: #*/"" +Merge: xdm +Comment: + The xrdb program to use to read the above specified recources. + Subject to word splitting. +Description: + The xrdb program to use to read the X-resources file + specified in . + The command is subject to word splitting. + +Key: Setup +Type: string +Default: "" +User: core +# will be overwritten +Instance: #*/"" +Update: mk_setup +Merge: xdm +Comment: + A program to run before the greeter is shown. Can be used to start an + xconsole or an alternative background generator. Subject to word splitting. +Description: + This string is subject to word splitting. + It specifies a program which is run (as + root) before offering the + greeter window. This may be used to change the appearance of the screen + around the greeter window or to put up other windows (e.g., you may want + to run xconsole here). + The conventional name for a file used here is Xsetup. + See . + +Key: Startup +Type: string +Default: "" +User: core +# will be overwritten +Instance: #*/"" +Update: mk_startup +Merge: xdm +Comment: + A program to run before a user session starts. Subject to word splitting. +Description: + This string is subject to word splitting. + It specifies a program which is run (as + root) after the user + authentication process succeeds. + The conventional name for a file used here is Xstartup. + See . + +Key: Reset +Type: string +Default: "" +User: core +# will be overwritten +Instance: #*/"" +Update: mk_reset +Merge: xdm +Comment: + A program to run after a user session exits. Subject to word splitting. +Description: + This string is subject to word splitting. + It specifies a program which is run (as + root) after the session + terminates. + The conventional name for a file used here is Xreset. + See . + +Key: Session +Type: string +Default: XBINDIR "/xterm -ls -T" +#Merge: xdm - incompatible! +User: core +# will be overwritten +Instance: #*/"" +Update: mk_session +Comment: + The program which is run as the user which logs in. It is supposed to + interpret the session argument (see SessionsDirs) and start an appropriate + session according to it. Subject to word splitting. +Description: + This string is subject to word splitting. + It specifies the session program to be executed (as the user owning + the session). + The conventional name for a file used here is Xsession. + See . + +Key: FailsafeClient +Type: string +Default: XBINDIR "/xterm" +User: core +Instance: #*/"" +Merge: xdm +Comment: + The program to run if Session fails. +Description: + If the program fails to execute, &tdm; will + fall back to this program. This program is executed with no arguments, + but executes using the same environment variables as the session would + have had (see ). + +Key: UserPath +Type: string +Default: DEF_USER_PATH +DDefault: - +User: core +Instance: #*/"" +Merge: xdm +Comment: + The PATH for the Session program. +Description: + The PATH environment variable for + non-root s. + + The default depends on the system &tdm; was built on. + +Key: SystemPath +Type: string +Default: DEF_SYSTEM_PATH +DDefault: - +User: core +Instance: #*/"" +Merge: xdm +Comment: + The PATH for Setup, Startup and Reset, etc. +Description: + The PATH environment variable for all programs but + non-root + s. Note that it is good practice not to include + . (the current directory) into this entry. + + The default depends on the system &tdm; was built on. + +Key: SystemShell +Type: string +Default: "/bin/sh" +User: core +Instance: #*/"/bin/bash" +Merge: xdm +Comment: + The default system shell. +Description: + The SHELL environment variable for all programs but the + . + +Key: UserAuthDir +Type: path +Default: "/tmp" +User: core +Instance: #*/"" +Merge: xdm +Comment: + Where to put the user's &X-Server; authorization file if ~/.Xauthority + cannot be created. +Description: + When &tdm; is unable to write to the usual user authorization file + ($HOME/.Xauthority), it creates a unique file name in this + directory and points the environment variable XAUTHORITY + at the created file. + +Key: AutoReLogin +Type: bool +Default: false +User: core +Instance: #*/! +Merge: xdm +Comment: + Whether to automatically restart sessions after &X-Server; crashes. + Note that enabling this makes circumventing screen lockers other than + KDE's built-in one possible! +Description: + If enabled, &tdm; will automatically restart a session after an &X-Server; + crash (or if it is killed by Alt-Ctrl-BackSpace). Note that enabling this + feature opens a security hole: a secured display lock can be circumvented + (unless &kde;'s built-in screen locker is used). + +Key: AllowRootLogin +Type: bool +Default: true +User: core +User: greeter(showRoot) +Instance: */false +Merge: xdm +Comment: + Allow root logins? +Description: + If disabled, do not allow root + (and any other user with UID = 0) to log in directly. + +Key: AllowNullPasswd +Type: bool +Default: true +User: core +# sensible? +Instance: */false +Instance: :*/true +Merge: xdm +Comment: + Allow to log in, when user has set an empty password? +Description: + If disabled, only users that have passwords assigned can log in. + +Key: AllowShutdown +Type: enum + None/SHUT_NONE: no Shutdown... menu entry is shown at all + Root/SHUT_ROOT: the root password must be entered to shut down + All/SHUT_ALL: everybody can shut down the machine +Default: All +User: core +User: greeter +Instance: */Root +Instance: :*/All +Merge: tdm:-Greeter/ +Comment: & +Description: + Who is allowed to shut down the system. This applies both to the + greeter and to the command FiFo. + +Key: AllowSdForceNow +Type: enum + None: no forced shutdown is allowed at all + Root: the root password must be entered to shut down forcibly + All: everybody can shut down the machine forcibly +Default: All +User: core(allowNuke) +User: greeter(allowNuke) +Instance: #*/Root +Comment: & +Description: + Who is allowed to abort active sessions when shutting down. + +Key: DefaultSdMode +Type: enum + Schedule: shut down after all active sessions exit (possibly at once) + TryNow: shut down, if no active sessions are open; otherwise, do nothing + ForceNow: shut down unconditionally +Default: Schedule +User: core(defSdMode) +User: greeter(defSdMode) +Instance: #*/ForceNow +Comment: & +Description: + The default choice for the shutdown condition/timing. + +Key: ScheduledSd +Type: enum + Never/SHUT_NEVER: not at all + Optional/SHUT_OPTION: as a button in the simple shutdown dialogs + Always/SHUT_ALWAYS: instead of the simple shutdown dialogs +Default: Never +User: greeter +Instance: #*/Optional +Comment: & +Description: + How to offer shutdown scheduling options: + +Key: NoPassEnable +Type: bool +Default: false +User: dep +Instance: #:*/true +Comment: & +Description: + Enable password-less logins on this display. Use with extreme care! + +Key: NoPassUsers +Type: list +Default: "" +PostProc: PnoPassUsers +User: core +Instance: #:*/"fred,ethel" +Merge: xdm(P_noPassUsers) +Comment: + The users that do not need to provide a password to log in. NEVER list root! + "*" means all non-root users. @ means all users in that group. +Description: + The users that do not need to provide a password to log in. + Items which are prefixed with @ represent all users in the + user group named by that item. + * means all users but + root + (and any other user with UID = 0). + Never list root. + +Key: AutoLoginEnable +Type: bool +Default: false +User: dep +Instance: #:0/true +Comment: & +Description: + Enable automatic login. Use with extreme care! + +Key: AutoLoginAgain +Type: bool +Default: false +User: core(autoAgain) +User: greeter +Instance: #:0/true +Comment: & +Description: + If true, auto-login after logout. If false, auto-login is performed only + when a display session starts up. + +Key: AutoLoginDelay +Type: int +Default: 0 +User: core(autoDelay) +User: greeter +Instance: #:0/10 +Comment: + The delay in seconds before automatic login kicks in. +Description: + The delay in seconds before automatic login kicks in. This is also known as + Timed Login. + +Key: AutoLoginUser +Type: string +Default: "" +PostProc: PautoLoginX +User: core(autoUser) +User: greeter +Instance: #:0/"fred" +Merge: xdm:autoUser(P_autoUser) +Comment: & +Description: + The user to log in automatically. Never specify root! + +Key: AutoLoginPass +Type: string +Default: "" +PostProc: PautoLoginX +User: core(autoPass) +Instance: #:0/"secret!" +Merge: xdm:autoPass(P_autoPass) +Comment: & +Description: + The password for the user to log in automatically. This is not required + unless the user is logged into a NIS or Kerberos domain. If you use this + option, you should chmod  tdmrc for obvious reasons. + +Key: AutoLoginLocked +Type: bool +Default: false +User: core(autoLock) +Instance: #:0/! +Comment: & +Description: + Immediately lock the automatically started session. This works only with + KDE sessions. + +Key: SessionsDirs +Type: list +Default: "/usr/share/xsessions,/var/lib/menu-xdg/xsessions,/usr/share/apps/tdm/sessions" +User: core +User: greeter-c +Instance: #*/"/usr/share/xsessions,/var/lib/menu-xdg/xsessions,/usr/share/apps/tdm/sessions" +Comment: + The directories containing session type definitions in .desktop format. +Description: + A list of directories containing session type definitions. +# See for details. + +Key: ClientLogFile +Type: string +Default: ".xsession-errors" +User: core +Instance: */".xsession-errors-%s" +Instance: :0/".xsession-errors" +Comment: + The file (relative to $HOME) to redirect the session output to. This is + a printf format string; one %s will be replaced with the display name. +Description: + The file (relative to the user's home directory) to redirect the session + output to. One occurrence of %s in this string will be + substituted with the display name. Use %% to obtain a + literal %. + +Key: UseSessReg +Type: bool +Default: false +User: core +Instance: #*/! +Comment: + Whether &tdm;'s built-in utmp/wtmp/lastlog registration should be used. +Description: + Specify whether &tdm;'s built-in utmp/wtmp/lastlog registration should + be used. If it is not, the tool sessreg should be used + in the and scripts, or, + alternatively, the pam_lastlog module should be used on + PAM-enabled systems. + + +Section: -Greeter +Description: + This section class contains options concerning the configuration + of the &tdm; frontend (greeter). + +Key: GUIStyle +Type: string +Default: "" +User: greeter +Instance: #*/"Windows" +Update: upd_guistyle +Comment: + Widget style of the greeter. "" means the built-in default which currently + is "Plastik". +Description: + Specify the widget style for the greeter. Empty means to use the + built-in default which currently is Plastik. + +Key: Compositor +Type: string +Default: "" +User: greeter +Instance: #*/"" +Comment: + Compositor binary name, if compositing is desired. "" means no compositing support. +Description: + Specify the Xorg compositing manager. Currently only kompmgr is supported. + +Key: WindowManager +Type: string +Default: "twin" +User: greeter +Instance: #*/"" +Comment: + Window manager binary name, if window decorations are desired. "" means no window manager support. +Description: + Specify the Xorg window manager. Currently only twin is supported. + +Key: UseSAK +Type: bool +Default: true +User: greeter +Instance: #*/! +Comment: + SAK +Description: + If true then the SAK anti-spoofing dialog will be utilized + +Key: UseAdminSession +Type: bool +Default: false +User: greeter +Instance: #*/! +Comment: + Admin session +Description: + If given there will be a special button that requires root password + and starts the given session + +Key: ColorScheme +Type: string +Default: "" +User: greeter +Instance: #*/"Pumpkin" +Comment: + Widget color scheme of the greeter. "" means the built-in default which + currently is yellowish grey with some light blue and yellow elements. +Description: + Specify the widget color scheme for the greeter. Empty means to use + the built-in default which currently is yellowish grey with some light + blue and yellow elements. + +Key: LogoArea +Type: enum + None/LOGO_NONE: nothing + Logo/LOGO_LOGO: the image specified by + Clock/LOGO_CLOCK: a neat analog clock +Default: Clock +User: greeter +Instance: */Logo +Comment: + What should be shown in the greeter's logo are: +Description: + What should be shown in the greeter righthand of the input lines (if + is disabled) or above them (if + is enabled): + +Key: LogoPixmap +Type: string +Default: "" +User: greeter(logo) +Instance: */TDMDATA "/pics/kdelogo.png" +Comment: + The image to show when LogoArea=Logo. +Description: + The image to show in the greeter if is + Logo. + +Key: GreeterPos +Type: string +Default: "50,50" +User: greeter-c +Instance: #*/"30,40" +Comment: + The relative coordinates (X,Y in percent) of the center of the greeter. +Description: + The relative coordinates (percentages of the screen size; X,Y) at which + the center of the greeter is put. &tdm; aligns the greeter to the edges + of the screen it would cross otherwise. + +Key: GreeterScreen +Type: int +Default: 0 +User: greeter +Instance: #*/-1 +Comment: & +Description: + The screen the greeter should be displayed on in multi-headed and Xinerama + setups. The numbering starts with 0. For Xinerama, it corresponds to the + listing order in the active ServerLayout section of XF86Config; -1 means + to use the upper-left screen, -2 means to use the upper-right screen. + +Key: GreetString +Type: string +Default: "Welcome to Trinity at %n" +User: greeter +Instance: #*/"Welcome to Trinity at %n" +Comment: + The headline in the greeter. The following character pairs are replaced: + - %d -> current display + - %h -> host name, possibly with domain name + - %n -> node name, most probably the host name without domain name + - %s -> the operating system + - %r -> the operating system's version + - %m -> the machine (hardware) type + - %% -> a single % +Description: + The headline in the greeter. An empty greeting means none at all. + + The following character pairs are replaced by their value: + + + %d + name of the current display + + + %h + local host name, possibly with the + domain name + + + %n + local node name, most probably the host name without the + domain name + + + %s + operating system + + + %r + operating system version + + + %m + machine (hardware) type + + + %% + a single % + + + +# This needs to come _in front_ of the font settings to be effective! +Key: AntiAliasing +Type: bool +Default: true +User: greeter +Instance: */ +Comment: & +Description: + Whether the fonts used in the greeter should be antialiased. + +Key: GreetFont +Type: string +Default: "Sans Serif,22,5,0,50,0" +CDefault: "Serif,20,bold" +User: greeter:font +Instance: #*/"Sans Serif,22,5,0,50,0" +Comment: & +Description: + The font for the greeter headline. + +Key: StdFont +Type: string +Default: "Sans Serif,10,5,0,50,0" +CDefault: "Sans Serif,10" +User: greeter(normalFont):font +Instance: #*/"Sans Serif,10,5,0,50,0" +Comment: & +Description: + The normal font used in the greeter. + +Key: FailFont +Type: string +Default: "Sans Serif,10,5,0,75,0" +CDefault: "Sans Serif,10,bold" +User: greeter:font +Instance: #*/"Sans Serif,10,5,0,75,0" +Comment: & +Description: + The font used for the Login Failed message. + +Key: NumLock +Type: enum + Off: turn off + On: turn on + Keep: do not change the state +Default: Keep +User: greeter(numLockStatus) +Instance: #*/Off +Comment: & +Description: + What to do with the Num Lock modifier for the time the greeter is running: + +Key: Language +Type: string +Default: "en_US" +User: greeter-c +Instance: #*/"de_DE" +Update: upd_language +Comment: & +Description: + Language and locale to use in the greeter, encoded like $LC_LANG. + +Key: UserCompletion +Type: bool +Default: false +User: greeter +Instance: #*/! +Comment: & +Description: + Enable autocompletion in the username line edit. + +Key: UserList +Type: bool +Default: true +User: greeter +Instance: #*/! +Comment: + Enable user list (names along with images) in the greeter. +Description: + Show a user list with unix login names, real names, and images in the greeter. + +Key: ShowUsers +Type: enum + NotHidden/SHOW_ALL: all users except those listed in HiddenUsers + Selected/SHOW_SEL: only the users listed in SelectedUsers +Default: NotHidden +User: greeter +Instance: #*/Selected +Update: upd_showusers +Comment: + User selection for UserCompletion and UserList: +Description: ! + This option controls which users will be shown in the user view + () and/or offered for autocompletion + (). + If it is Selected, contains + the final list of users. + If it is NotHidden, the initial user list are all users + found on the system. Users contained in are + removed from the list, just like all users with a UID greater than specified + in and users with a non-zero UID less than + specified in . + Items in and + which are prefixed with @ represent all users in the + user group named by that item. + Finally, the user list will be sorted alphabetically, if + is enabled. + +Key: SelectedUsers +Type: list +Default: "" +User: greeter-c(users) +Instance: #*/"root,johndoe" +Merge: tdm:Users +Comment: + For ShowUsers=Selected. @ means all users in that group. +Description: + See . + +Key: HiddenUsers +Type: list +Default: "" +User: greeter-c(noUsers) +Instance: #*/"root" +# depends on {Min,Max}ShowUID +Update: upd_hiddenusers/1 +Merge: tdm:NoUsers +Comment: + For ShowUsers=NotHidden. @ means all users in that group. +Description: + See . + +Key: MinShowUID +Type: int +Default: 0 +User: greeter(lowUserId) +# will be overwritten +Instance: #*/ +Update: upd_minshowuid +Comment: + Special case of HiddenUsers: users with a non-zero UID less than this number + will not be shown as well. +Description: + See . + +Key: MaxShowUID +Type: int +Default: 65535 +User: greeter(highUserId) +# will be overwritten +Instance: #*/ +Update: upd_maxshowuid +Comment: + Complement to MinShowUID: users with a UID greater than this number will + not be shown as well. +Description: + See . + +Key: SortUsers +Type: bool +Default: true +User: greeter +Instance: #*/! +Comment: + If false, the users are listed in the order they appear in /etc/passwd. + If true, they are sorted alphabetically. +Description: + See . + +Key: FaceSource +Type: enum + AdminOnly/FACE_ADMIN_ONLY: from <>/$USER.face[.icon] + PreferAdmin/FACE_PREFER_ADMIN: prefer <>, fallback on $HOME + PreferUser/FACE_PREFER_USER: ... and the other way round + UserOnly/FACE_USER_ONLY: from the user's $HOME/.face[.icon] +Default: AdminOnly +User: greeter +Instance: #*/PreferUser +Comment: + Specify, where the users' pictures should be taken from. +Description: + If is enabled, this specifies where &tdm; gets the + images from: + + %ENUM% + + The images can be in any format Qt recognizes, but the filename + must match &tdm;'s expectations: .face.icon should be a + 48x48 icon, while .face should be a 300x300 image. + Currently the big image is used only as a fallback and is scaled down, + but in the future it might be displayed full-size in the logo area or a + tooltip. + +Key: FaceDir +Type: string +Default: *TDMDATA "/faces" +User: greeter +Instance: #*/"/usr/share/faces" +Update: upd_facedir +Comment: + The directory containing the user images if FaceSource is not UserOnly. +Description: + See . + +Key: PreselectUser +Type: enum + None/PRESEL_NONE: do not preselect any user + Previous/PRESEL_PREV: the user which successfully logged in last time + Default/PRESEL_DEFAULT: the user specified in the option +Default: None +User: greeter(preselUser) +Instance: #*/Previous +Instance: :*/Previous +Instance: #:0/Default +Comment: + Specify, if/which user should be preselected for log in. +Description: + Specify, if/which user should be preselected for log in: + + %ENUM% + + If is enabled and a user was preselected, + the cursor is placed in the password input field automatically. + + Enabling user preselection can be considered a security hole, + as it presents a valid login name to a potential attacker, so he + only needs to guess the password. On the other hand, + one could set to a fake login name. + + +Key: DefaultUser +Type: string +Default: "" +User: greeter +Instance: #:0/"johndoe" +Comment: + The user to preselect if PreselectUser=Default. +Description: + See . + +Key: FocusPasswd +Type: bool +Default: false +User: greeter +Instance: #*/! +Instance: :*/true +Comment: + If this is true, the password input line is focused automatically if + a user is preselected. +Description: + See . + +Key: EchoMode +Type: enum + OneStar: * is shown for every typed letter + ThreeStars: *** is shown for every typed letter + NoEcho: nothing is shown at all, the cursor does not move +# HACK! This must be in sync with KPasswordEdit::EchoModes (kpassdlg.h) +Default: OneStar +User: greeter +Instance: #*/NoEcho +Comment: & +Description: + The password input fields cloak the typed in text. Specify, how to do it: + +Key: UseBackground +Type: bool +Default: true +User: greeter +Instance: #*/! +Comment: + If true, krootimage will be automatically started by &tdm;; otherwise, the + Setup script should be used to setup the background. +Description: + If enabled, &tdm; will automatically start the krootimage + program to set up the background; otherwise, the + program is responsible for the background. + +Key: BackgroundCfg +Type: string +Default: *TDMCONF "/backgroundrc" +User: greeter-c +Instance: #*/"" +Update: handBgCfg +Comment: + The configuration file to be used by krootimage. +Description: + The configuration file to be used by krootimage. + It contains a section named [Desktop0] like + kdesktoprc does. Its options are not described + herein; guess their meanings or use the control center. + +Key: GrabServer +Type: bool +Default: false +User: greeter-c +Instance: #*/! +Comment: + Hold the &X-Server; grabbed the whole time the greeter is visible. This + may be more secure, but it will disable any background and other + X-clients started from the Setup script. +Description: + To improve security, the greeter grabs the &X-Server; and then the keyboard + when it starts up. This option specifies if the &X-Server; grab should be held + for the duration of the name/password reading. When disabled, the &X-Server; + is ungrabbed after the keyboard grab succeeds; otherwise, the &X-Server; is + grabbed until just before the session begins. + + Enabling this option disables and + . + + +Key: GrabTimeout +Type: int +Default: 3 +User: greeter +Instance: #*/ +Comment: + How many seconds to wait for grab to succeed. +Description: + This option specifies the maximum time &tdm; will wait for the grabs to + succeed. A grab may fail if some other X-client has the &X-Server; or the + keyboard grabbed, or possibly if the network latencies are very high. You + should be cautious when raising the timeout, as a user can be spoofed by + a look-alike window on the display. If a grab fails, &tdm; kills and + restarts the &X-Server; (if possible) and the session. + +Key: AuthComplain +Type: bool +Default: true +User: greeter +Instance: #*/! +Merge: xdm +Comment: + Warn, if display has no X-authorization (local auth cannot be created, + &XDMCP; display wants no auth, or display is foreign from StaticServers). +Description: + Warn, if a display has no X-authorization. This will be the case if + + + the authorization file for a local &X-Server; could not be created, + + + a remote display from &XDMCP; did not request any authorization or + + + the display is a foreign display specified in + . + + + +Key: LoginMode +If: defined(XDMCP) +Type: enum + LocalOnly/LOGIN_LOCAL_ONLY: only local login possible + DefaultLocal/LOGIN_DEFAULT_LOCAL: start up in local mode, but allow switching to remote mode + DefaultRemote/LOGIN_DEFAULT_REMOTE: ... and the other way round + RemoteOnly/LOGIN_REMOTE_ONLY: only choice of remote host possible +Default: LocalOnly +User: core +User: greeter +Instance: :*/DefaultLocal +# from make_it_cool branch and SuSE 8.1 +Merge: tdm:EnableChooser(P_EnableChooser) +Comment: & +Description: + Specify whether the greeter of local displays should start up in host chooser + (remote) or login (local) mode and whether it is allowed to switch to the + other mode. + +Key: ChooserHosts +If: defined(XDMCP) +Type: list +Default: "*" +User: core +Instance: #:*/"*,ugly,sky,dino,kiste.local,login.crap.com" +Comment: + A list of hosts to be automatically added to the remote login menu. The + special name "*" means broadcast. +Description: + A list of hosts to be automatically added to the remote login menu. + The special name * means broadcast. + Has no effect if is LocalOnly. + +Key: ForgingSeed +Type: int +Default: 0 +User: greeter +Instance: #*/ +Comment: + Random seed for forging saved session types, etc. of unknown users. + This value should be random but constant across the login domain. +Description: + Use this number as a random seed when forging saved session types, etc. of + unknown users. This is used to avoid telling an attacker about existing users + by reverse conclusion. This value should be random but constant across the + login domain. + +Key: ShowLog +If: defined(WITH_TDM_XCONSOLE) +Type: bool +Default: false +User: greeter +Instance: :0/true +Comment: + Enable &tdm;'s built-in xconsole. Note that this can be enabled for only + one display at a time. +Description: + Enable &tdm;'s built-in xconsole. + Note that this can be enabled for only one display at a time. + This option is available only if &tdm; was configured + with . + +Key: LogSource +If: defined(WITH_TDM_XCONSOLE) +Type: string +Default: "" +User: greeter-c +Instance: :0/"/dev/xconsole" +Comment: + The data source for &tdm;'s built-in xconsole. + If empty, a console log redirection is requested from /dev/console. +Description: + The data source for &tdm;'s built-in xconsole. + If empty, a console log redirection is requested from + /dev/console. + Has no effect if is disabled. + +Key: PluginsLogin +Type: list +Default: "classic" +User: greeter +Instance: #*/"sign" +Comment: + Specify conversation plugins for the login dialog. Each plugin can be + specified as a base name (which expands to $kde_modulesdir/kgreet_$base) + or as a full pathname. +Description: + Specify conversation plugins for the login dialog; the first in the list + is selected initially. + Each plugin can be specified as a base name (which expands to + $kde_modulesdir/kgreet_base) + or as a full pathname. + + Conversation plugins are modules for the greeter which obtain authentication + data from the user. Currently only the classic plugin is + shipped with &kde;; it presents the well-known username and password form. + +Key: PluginsShutdown +Type: list +Default: "classic" +User: greeter +Instance: #*/"modern" +Comment: & +Description: + Same as , but for the shutdown dialog. + +Key: PluginOptions +Type: list +Default: "" +User: greeter +Instance: #*/"SomeKey=randomvalue,Foo=bar" +Comment: + A list of options of the form Key=Value. The conversation plugins can query + these settings; it is up to them what possible keys are. +Description: + A list of options of the form + Key=Value. + The conversation plugins can query these settings; it is up to them what + possible keys are. + +Key: AllowConsole +Type: bool +Default: true +User: greeter(hasConsole) +Instance: #*/! +Comment: & +Description: + Show the Console Login action in the greeter (if / + is configured). + +Key: AllowClose +Type: bool +Default: true +User: greeter +Instance: :*/true +Comment: & +Description: + Show the Restart X Server/Close Connection action in the greeter. + +Key: Preloader +Type: string +Default: "" +User: greeter-c +Instance: */KDE_BINDIR "/preloadkde" +Comment: & +Description: + A program to run while the greeter is visible. It is supposed to preload + as much as possible of the session that is going to be started (most + probably). + +Key: UseTheme +Type: bool +Default: true +User: greeter +Instance: */true +Comment: & +Description: + Whether the greeter should be themed. + +Key: Theme +Type: string +Default: TDMDATA "/themes/o2_enterprise" +User: greeter +Instance: */TDMDATA "/themes/o2_enterprise" +Comment: & +Description: + The theme to use for the greeter. Can point to either a directory or an XML + file. diff --git a/tdm/configure.in.bot b/tdm/configure.in.bot new file mode 100644 index 000000000..a0d238b29 --- /dev/null +++ b/tdm/configure.in.bot @@ -0,0 +1,8 @@ +if $tdm_no_Xau; then + AC_MSG_WARN([Cannot build TDM! Make sure that libXau.a is installed!]) +fi +if $tdm_no_Xdmcp; then + AC_MSG_WARN([Cannot build TDM! Make sure that libXdmcp.a and Xdmcp.h +are installed or use --without-xdmcp to disable XDMCP support!]) +fi + diff --git a/tdm/configure.in.in b/tdm/configure.in.in new file mode 100644 index 000000000..5422e5a99 --- /dev/null +++ b/tdm/configure.in.in @@ -0,0 +1,361 @@ +KDE_FIND_PATH(xmkmf, XMKMF, [], [AC_MSG_ERROR([xmkmf/imake not found. Please make sure it's in PATH!])]) + +dnl ask imake about various X settings +AC_MSG_CHECKING([X paths]) +imkv=8 +test "$kde_cv_defines_imake_version" = $imkv || unset kde_cv_defines_imake +AC_CACHE_VAL(kde_cv_defines_imake, [ + rm -fr conftestdir + if mkdir conftestdir; then + cd conftestdir + cat > Imakefile <<'EOF'[ + +acimake: + @echo "XBINDIR=\"/usr/bin\" XLIBDIR=\"$(LIBDIR)\"" + +]EOF + if imake -I/usr/lib/X11/config -DTOPDIR=/etc/X11 -DCURDIR=. /etc/X11 >&5 2>&1 && test -f Makefile; then + kde_cv_defines_imake=`${MAKE-make} acimake 2> /dev/null | grep -v "^make"` + kde_cv_defines_imake_version=$imkv + else + AC_MSG_RESULT([failed]) + AC_MSG_ERROR([$XMKMF (imake) failed. +Make sure you have all necessary X development packages installed. +On some systems a missing /lib/cpp symlink is at fault.]) + fi + cd .. + rm -fr conftestdir + else + AC_MSG_RESULT([failed]) + AC_MSG_ERROR([cannot create temporary directory]) + fi +]) +AC_MSG_RESULT([done]) +eval "$kde_cv_defines_imake" +AC_DEFINE_UNQUOTED(XBINDIR, "$XBINDIR", [X binaries directory]) +AC_DEFINE_UNQUOTED(XLIBDIR, "$XLIBDIR", [X libraries directory]) + +if test -f /etc/ttys; then + AC_DEFINE(BSD_INIT, 1, [Define if the system uses a BSD-style init]) +fi + +AC_CHECK_FUNCS([getttyent]) +case $host_os in + linux*) ac_cv_func_getutxent=no;; + darwin*) ac_cv_func_getutxent=no;; + kfreebsd*-gnu) ac_cv_func_getutxent=no;; + *) AC_CHECK_FUNC([getutxent]);; +esac +if test $ac_cv_func_getutxent = yes; then + AC_DEFINE(HAVE_UTMPX, 1, [Define if the system uses extended utmp]) +else + AC_CHECK_FUNC([getutent], , + [AC_DEFINE(BSD_UTMP, 1, [Define if the system has no getutent])]) +fi + +AC_CHECK_MEMBERS([struct utmp.ut_user], , , [#include ]) +AC_CHECK_MEMBERS([struct passwd.pw_expire], , , [#include ]) +AC_CHECK_MEMBERS([struct sockaddr_in.sin_len], , , [ +#include +#include +]) + +ac_save_libs=$LIBS +LIBS="$LIBS $LIBUTIL" +AC_CHECK_FUNCS([setlogin setusercontext getusershell login_getclass auth_timeok]) +LIBS=$ac_save_libs + +dnl is getifaddrs always available without additional libs? +AC_CHECK_FUNCS([mkstemp setproctitle sysinfo strnlen getifaddrs]) + +AC_CHECK_FUNCS([arc4random], , + [ +dnl assume that /dev/random is non-blocking if /dev/urandom does not exist +for i in urandom random; do + if test -c /dev/$i; then + AC_DEFINE_UNQUOTED(DEV_RANDOM, "/dev/$i", [Define the system's entropy device]) + break + fi +done + ]) + +AC_CHECK_FUNC(vsyslog, [ + AC_DEFINE(USE_SYSLOG, 1, [Define if tdm should be built with syslog support])]) + +tdm_no_Xau=false +tdm_no_Xdmcp=false + +AC_CHECK_LIB(Xau, main, [:], + [ + tdm_no_Xau=true + DO_NOT_COMPILE="$DO_NOT_COMPILE tdm" + ], + $X_LDFLAGS -lX11 $LIBSOCKET) + +AC_ARG_WITH(xdmcp, + AC_HELP_STRING([--without-xdmcp],[build tdm without xdmcp support [default=with xdmcp]]), , + [with_xdmcp=yes]) +if test "x$with_xdmcp" = xyes; then + AC_CHECK_LIB(Xdmcp, main, [LIBXDMCP="-lXdmcp"], , $X_LDFLAGS -lX11 $LIBSOCKET) + if test -n "$LIBXDMCP"; then + cppflags_safe=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $X_INCLUDES" + AC_CHECK_HEADER(X11/Xdmcp.h, [HAVE_X11_XDMCP_H=1], , [#include ]) + CPPFLAGS=$cppflags_safe + fi + if test -z "$HAVE_X11_XDMCP_H"; then + tdm_no_Xdmcp=true + DO_NOT_COMPILE="$DO_NOT_COMPILE tdm" + fi + AC_DEFINE(XDMCP, 1, [Define if tdm should be built with XDMCP support]) + ac_save_libs=$LIBS + LIBS="$LIBS $LIBXDMCP" + AC_CHECK_FUNC(XdmcpWrap, [ + AC_DEFINE(HASXDMAUTH, 1, [Define if tdm should be built with XDMAUTH support]) + ]) + LIBS=$ac_save_libs +fi +AC_SUBST(LIBXDMCP) + +KRB4_INCS= +KRB4_LIBS= +KRB4_RPATH= + +AC_MSG_CHECKING(whether to use Kerberos v4) +AC_ARG_WITH(krb4, +AC_HELP_STRING([--with-krb4=PATH],[Compile in Kerberos v4 support]), +[ test "x$with_krb4" = xyes && with_krb4=/usr/kerberos ], +[ with_krb4=no ] +) +case "$with_krb4" in +no) + AC_MSG_RESULT(no) + ;; +*) + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(KRB4, 1, [define if you have Kerberos IV]) + KRB4_INCS="-I$with_krb4/include" + KRB4_LIBS="-L$with_krb4/lib -lkrb -ldes" + if test "$USE_RPATH" = "yes" ; then + KRB4_RPATH="-R $with_krb4/lib" + fi + AC_CHECK_LIB(resolv, dn_expand, KRB4_LIBS="$KRB4_LIBS -lresolv") + ;; +esac + +AC_MSG_CHECKING(whether to use AFS) +AC_ARG_WITH(afs, + AC_HELP_STRING([--with-afs],[Compile in AFS support (requires KTH krb4)]), , + [ with_afs=no ]) +if test "$with_afs" = no; then + AC_MSG_RESULT(no) +else + if test "$with_krb4" = no; then + AC_MSG_RESULT(no) + AC_MSG_WARN("AFS requires Kerberos v4 support.") + with_afs=no + else + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(AFS, 1, [define if you have KTH Kerberos IV and AFS]) + KRB4_LIBS="$KRB4_LIBS -lkafs" + if test -n "$os_aix"; then + KRB4_LIBS="$KRB4_LIBS -lld" + fi + fi +fi + +AC_SUBST(KRB4_INCS) +AC_SUBST(KRB4_LIBS) +AC_SUBST(KRB4_RPATH) + +AC_CHECK_LIB(s, main, [LIB_LIBS="-ls"]) dnl for AIX +AC_SUBST(LIB_LIBS) + +AC_CHECK_LIB(posix4, sched_yield, [LIBPOSIX4=-lposix4]) +AC_SUBST(LIBPOSIX4) + +KRB5_INCS= +KRB5_LIBS= +KRB5_RPATH= + +AC_MSG_CHECKING([whether to use Kerberos5 for Xauth cookies in tdm]) +AC_ARG_WITH(krb5auth, + AC_HELP_STRING([--with-krb5auth=PATH],[Use Kerberos5 for Xauth cookies in tdm]), , + [ with_krb5auth=no ]) +if test "x$with_krb5auth" = xno; then + AC_MSG_RESULT(no) +else + AC_MSG_RESULT(yes) + if test "x$with_krb5auth" != xyes; then + KRB5_INCS="-I$with_krb5auth/include" + KRB5_LIBS="-L$with_krb5auth/lib" + if test "$USE_RPATH" = "yes" ; then + KRB5_RPATH="-R $with_krb5auth/lib" + fi + fi + KRB5_LIBS="$KRB5_LIBS -lkrb5" dnl -lk5crypto -lcom_err -lresolv + keepcflags=$CFLAGS + CFLAGS="$KRB5_INCS $CFLAGS" + AC_CHECK_HEADER(krb5/krb5.h, + [ AC_DEFINE(K5AUTH, 1, [Define if tdm should use Kerberos 5 for Xauth cookies.]) ], + [ AC_MSG_ERROR([--with-krb5auth requires Kerberos5 header files. +Due to a problem with X includes you probably have to run "ln -s . krb5" +in the directory where the krb5.h include resides to make things actually work.])]) + CFLAGS="$keepcflags" +fi + +AC_SUBST(KRB5_INCS) +AC_SUBST(KRB5_LIBS) +AC_SUBST(KRB5_RPATH) + +AC_MSG_CHECKING([whether to use Sun's secure RPC for Xauth cookies in tdm]) +AC_ARG_WITH(rpcauth, + AC_HELP_STRING([--with-rpcauth],[Use Sun's secure RPC for Xauth cookies in tdm.]), , + [ with_rpcauth=no ]) +if test "x$with_rpcauth" = xno; then + AC_MSG_RESULT(no) +else + AC_MSG_RESULT(yes) + AC_CHECK_HEADER(rpc/rpc.h, + [ AC_DEFINE(SECURE_RPC, 1, [Define if tdm should use Sun's secure RPC for Xauth cookies.]) ], + [ AC_MSG_ERROR([--with-rpcauth requires Sun RPC header files.])]) +fi + +if test "x$use_pam" = xyes; then + AC_DEFINE(USE_PAM, 1, [Define if tdm should use PAM]) +elif test "x$use_shadow" = xyes; then + AC_DEFINE(USESHADOW, 1, [Define if tdm should use shadow passwords]) +fi +if test "x$with_krb4" != xno; then + AC_DEFINE(KERBEROS, 1, [Define if tdm should use Kerberos IV]) + if test "x$with_afs" = xno; then + AC_DEFINE(NO_AFS, 1, [Define if tdm should not use AFS]) + fi +fi + +AC_ARG_WITH(tdm-xconsole, + AC_HELP_STRING([--with-tdm-xconsole],[build tdm with built-in xconsole [default=no]]), , + [with_tdm_xconsole=no]) +if test "x$with_tdm_xconsole" = xyes; then + AC_DEFINE(WITH_TDM_XCONSOLE, 1, [Build tdm with built-in xconsole]) +fi + +########### Check for DBus + + AC_MSG_CHECKING(for DBus) + + dbus_inc=NOTFOUND + dbus_lib=NOTFOUND + dbus=NOTFOUND + + search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0" + AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir) + + search_incs_arch_deps="$kde_includes $kde_extra_includes /usr/lib$tdelibsuff/dbus-1.0/include /usr/local/lib$tdelibsuff/dbus-1.0/include" + AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps) + + if test -r $dbus_incdir/dbus/dbus.h && test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h ; then + DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps" + dbus_inc=FOUND + fi + + search_libs="$kde_libraries $kde_extra_libs /usr/lib$tdelibsuff /usr/local/lib$tdelibsuff" + AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir) + + if test -r $dbus_libdir/libdbus-1.so ; then + DBUS_LIBS="-L$dbus_libdir -ldbus-1" + dbus_lib=FOUND + fi + + if test $dbus_inc != FOUND || test $dbus_lib != FOUND ; then + KDE_PKG_CHECK_MODULES( DBUS, "dbus-1", [ DBUS_INCS=$DBUS_CFLAGS; dbus_inc=FOUND; dbus_lib=FOUND; ] , AC_MSG_RESULT( Nothing found on PKG_CONFIG_PATH ) ) + fi + + dbus_bus_var=`pkg-config --variable=system_bus_default_address dbus-1 2>/dev/null` + if test -z "$dbus_bus_var"; then + dbus_bus_var="unix:path=/var/run/dbus/system_bus_socket" + fi + AC_DEFINE_UNQUOTED(DBUS_SYSTEM_BUS, "$dbus_bus_var", [Define the unix domain path for dbus system bus]) + + if test $dbus_inc = FOUND && test $dbus_lib = FOUND ; then + AC_MSG_RESULT(headers $DBUS_INCS libraries $DBUS_LIBS) + dbus=FOUND + else + AC_MSG_RESULT(searched but not found) + fi + + AC_SUBST(DBUS_INCS) + AC_SUBST(DBUS_LIBS) + +########### Check for DBus + + AC_MSG_CHECKING(for DBus) + + dbus_inc=NOTFOUND + dbus_lib=NOTFOUND + dbus=NOTFOUND + + search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0" + AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir) + + search_incs_arch_deps="$kde_includes $kde_extra_includes /usr/lib$tdelibsuff/dbus-1.0/include /usr/local/lib$tdelibsuff/dbus-1.0/include" + AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps) + + if test -r $dbus_incdir/dbus/dbus.h && test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h ; then + DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps" + dbus_inc=FOUND + fi + + search_libs="$kde_libraries $kde_extra_libs /usr/lib$tdelibsuff /usr/local/lib$tdelibsuff" + AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir) + + if test -r $dbus_libdir/libdbus-1.so ; then + DBUS_LIBS="-L$dbus_libdir -ldbus-1" + dbus_lib=FOUND + fi + + if test $dbus_inc != FOUND || test $dbus_lib != FOUND ; then + KDE_PKG_CHECK_MODULES( DBUS, "dbus-1", [ DBUS_INCS=$DBUS_CFLAGS; dbus_inc=FOUND; dbus_lib=FOUND; ] , AC_MSG_RESULT( Nothing found on PKG_CONFIG_PATH ) ) + fi + + dbus_bus_var=`pkg-config --variable=system_bus_default_address dbus-1 2>/dev/null` + if test -z "$dbus_bus_var"; then + dbus_bus_var="unix:path=/var/run/dbus/system_bus_socket" + fi + AC_DEFINE_UNQUOTED(DBUS_SYSTEM_BUS, "$dbus_bus_var", [Define the unix domain path for dbus system bus]) + + if test $dbus_inc = FOUND && test $dbus_lib = FOUND ; then + AC_MSG_RESULT(headers $DBUS_INCS libraries $DBUS_LIBS) + dbus=FOUND + else + AC_MSG_RESULT(searched but not found) + fi + + AC_SUBST(DBUS_INCS) + AC_SUBST(DBUS_LIBS) + +dnl AC_OUTPUT(tdm/kfrontend/sessions/kde.desktop) + + +AC_ARG_WITH(libaudit, + [ --with-libaudit=[auto/yes/no] Add Linux audit support [default=auto]],, + with_libaudit=auto) + +# Check for Linux auditing API +# +# libaudit detection +if test x$with_libaudit = xno ; then + have_libaudit=no; +else + # See if we have audit daemon library + AC_CHECK_LIB(audit, audit_log_user_message, + have_libaudit=yes, have_libaudit=no) +fi + +AM_CONDITIONAL(HAVE_LIBAUDIT, test x$have_libaudit = xyes) + +if test x$have_libaudit = xyes ; then + EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -laudit" + AC_DEFINE(HAVE_LIBAUDIT,1,[linux audit support]) +fi + diff --git a/tdm/confproc.pl b/tdm/confproc.pl new file mode 100755 index 000000000..c187c88c0 --- /dev/null +++ b/tdm/confproc.pl @@ -0,0 +1,838 @@ +#! /usr/bin/perl -w +# +# Copyright 2004-2005 Oswald Buddenhagen +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation. +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of a copyright holders shall +# not be used in advertising or otherwise to promote the sale, use or +# other dealings in this Software without prior written authorization +# from the copyright holders. +# + +use strict; +use Cwd 'abs_path'; + +sub pegout($) +{ + print STDERR $_[0]."\n"; + exit 1; +} + +sub relpath($$) +{ + my @src = split(/\//, abs_path(shift)); + my @dst = split(/\//, abs_path(shift)); + pop @dst; + while (@src && @dst && $src[0] eq $dst[0]) { + shift @src; + shift @dst; + } + return "../"x@dst . join("/", @src); +} + +sub getl() +{ + while () { + next if (/^#/); + chop; +# print "read: ".$_."\n"; + return; + } + $_ = ""; +} + +sub dedb($) +{ + my $t = shift; + $t =~ s,,\",g; + $t =~ s,]+)?)>,,g; + $t =~ s,([^<]+),uc($1),ge; + $t =~ s, , ,g; + $t =~ s,<,<,g; + $t =~ s,>,>,g; + $t =~ s,&tdm;,TDM,g; + $t =~ s,&XDMCP;,XDMCP,g; + $t =~ s,&X-Server;,X-server,g; + return $t; +} + +sub mkvname($) +{ + my $v = shift; + if ($v !~ /^[A-Z]{2}/) { + $v = lcfirst $v; + } + return $v; +} + +sub emit_conds($) +{ + my $ret = ""; + for my $c (keys %{$_[0]}) { + my ($then, $else) = ("", ""); + for my $d (@{${$_[0]}{$c}}) { + my $bas = "# define ".$d->[0]; + if ($d->[1] =~ /\n/) { + $then .= $bas." \\\n".$d->[1]."\n"; + } else { + $then .= $bas." ".$d->[1]."\n"; + } + $else .= $bas."\n"; + } + $ret .= "#if ".$c."\n".$then."#else\n".$else."#endif\n\n"; + } + return $ret; +} + +sub add_cond($$$$) +{ + if ($_[0]) { + my $vn = uc($_[1]); + for my $i (@{$_[2]}) { + push @{${$_[3]}{$_[0]}}, [ $vn."_".$i->[1], $i->[0] ]; + $i->[0] = $vn."_".$i->[1]; + } + } +} + +my $do_doc = 0; +if ($ARGV[0] eq "--doc") { + $do_doc = 1; + shift @ARGV; +} + +@ARGV != 2 && pegout("usage: $0 [--doc] "); + +open (INFILE, $ARGV[0]) || pegout("$0: cannot open definition file ".$ARGV[0]); + +my %ex_conds = (); +my %ex_sects = (); # $name -> $index +my @ex_config = (); # ($name, $comment, $entries) + +my $raw_out = ""; + +my %ov_enum_conds = (); +my $ov_enums = ""; +my $ov_enum_defs = ""; + +my $ov_defaults = ""; + +my %arr_ov_vars = (); +my $ov_rd_sects = ""; +my $ov_rd_ents = ""; + +my $ov_gen_sects = ""; +my $ov_gen_ents = ""; +my $max_prio = 0; + +my %ov_sec_conds = (); +my %ov_ent_conds = (); +my $ov_sect_defs = ""; +my $ov_sect_refs = ""; + +my %ov_glob_conds = (); +my $ov_globs = ""; +my %ov_loc_conds = (); +my $ov_locs = ""; + +my %ov_glob_decl_conds = (); +my $ov_glob_decls = ""; +my %ov_glob_def_conds = (); +my %ov_glob_defs = (); +my %ov_loc_def_conds = (); +my %ov_loc_defs = (); + +my %ov_greet_conds = (); +my $ov_greet_init = ""; +my @ov_greet_decls = (); +my %ov_greet_defs = (); + +my %ov_xm_conds = (); +my @ov_xm = ("", ""); + +my %ov_km_conds = (); +my %ov_km = (); + +my %sect_names = (); +my $sect = ""; +my $sect_if; + +my $key_if; + +my %key_names; + +my $kid_seq = 0x1000; + +my $doc = ""; +my $doc_ref = ""; + +sub emit_section() +{ + my $ts = $sect; + $ts =~ s/-/_/; + my @oa = ( + ["static Ent ents".$ts."[] = { \\\n".$ov_rd_ents."};", "ENTS"], + ["static Ent ents".$ts."[] = { \\\n".$ov_gen_ents."};", "GENS"], + ["sec".$ts." = { \"".$sect."\", ents".$ts.", as(ents".$ts.") },", "SEC"], + ["&sec".$ts.",", "SECS"] + ); + $ov_rd_ents = ""; + $ov_gen_ents = ""; + add_cond($sect_if, $ts, \@oa, \%ov_sec_conds); + $ov_rd_sects .= " \\\n".$oa[0][0]." \\\n"; + $ov_gen_sects .= " \\\n".$oa[1][0]." \\\n"; + $ov_sect_defs .= " ".$oa[2][0]." \\\n"; + $ov_sect_refs .= "\t".$oa[3][0]." \\\n"; + $doc_ref .= "\n\n\n"; +} + +my %th = ( + "int" => [ "C_TYPE_INT", "", "int\t", "", "GetCfgInt", "" ], + "bool" => [ "C_TYPE_INT", " | C_BOOL", "int\t", "bool\t", "GetCfgInt", "GetCfgInt" ], + "enum" => [ "C_TYPE_INT", " | C_ENUM", "int\t", "", "GetCfgInt", "" ], + "group" => [ "C_TYPE_INT", " | C_GRP", "int\t", "", "GetCfgInt", "" ], + "string" => [ "C_TYPE_STR", "", "char\t*", "TQString\t", "GetCfgStr", "GetCfgQStr" ], + "path" => [ "C_TYPE_STR", " | C_PATH", "char\t*", "TQString\t", "GetCfgStr", "GetCfgQStr" ], + "list" => [ "C_TYPE_ARGV", "", "char\t**", "TQStringList\t", "GetCfgStrArr", "GetCfgQStrList" ] +); + +my @tl = ("TQFont\t", "TQStringList\t", "TQString\t", "char\t**", "char\t*", "int\t", "bool\t"); + +sub init_defs($) +{ + for my $t (@tl) { + $_[0]{$t} = ""; + } +} + +init_defs(\%ov_glob_defs); +init_defs(\%ov_loc_defs); +init_defs(\%ov_greet_defs); + +sub emit_defs($) +{ + my $ret = ""; + for my $t (@tl) { + $ret .= $_[0]{$t}; + } + return $ret; +} + +while () { + chop; + if (/^$/) { + while () { + last if (/^<\/code>\n$/); + $raw_out .= $_; + } + } elsif (/^$/) { + my $comm = ""; + while () { + last if (/^<\/tdmrc>\n$/); + chop; + if (/^\[(.*)\]$/) { + defined($ex_sects{$1}) && + pegout("redefinition of example section [$1]"); + push @ex_config, [$1, dedb($comm), "", ""]; + $ex_sects{$1} = $#ex_config; + $comm = ""; + } else { + if (!$_) { + $comm .= " \\\n\"\\n\""; + } elsif ($_ eq " _") { + $comm .= " \\\n\"#\\n\""; + } else { + s/"/\\"/g; + $comm .= " \\\n\"#".$_."\\n\""; + } + } + } + } elsif (/^$/) { + while () { + last if (/^<\/docu>\n$/); + $doc .= $_; + } + } elsif (/^$/) { + while () { + next if (/^($|#)/); + my ($proc, $kif); + if (/^If: (.+)$/) { + $kif = $1; + getl(); + } else { + $kif = ""; + } + if (/^Proc: (.+)$/) { + $proc = $1; + getl(); + } else { + pegout("expecting Proc keyword in legacy section"); + } + my $nsrc = 0; + my $mcnt = 0; + while (/^Source: (.+)$/) { + my $src = $1; + if ($src =~ /^xdm:(.*)$/) { + my $what = $1; + my $dsp = ($what =~ s/^\*\.//); + my @oa = ([ "{ \"".$what."\", (char *)-1, 0, ".$proc." },", "XMO" ]); + add_cond($kif, $what, \@oa, \%ov_xm_conds); + $ov_xm[$dsp] .= $oa[0][0]." \\\n"; + } elsif ($src =~ /^tdm:(.*)\/(.*)$/) { + my ($sec, $key) = ($1, $2); + my @oa = ([ "{ \"".$key."\", (char *)-1, 0, ".$proc." },", "KMO".($mcnt++) ]); + add_cond($kif, $key, \@oa, \%ov_km_conds); + $ov_km{$sec} .= $oa[0][0]." \\\n"; + } else { + pegout("invalid legacy option '$_'"); + } + $nsrc++; + getl(); + } + $nsrc || pegout("no sources for legacy processor ".$proc); + last if (/^<\/legacy>$/); + pegout("unidentified section body '".$_."' in legacy section") if ($_); + } + } else { + next if (/^($|#)/); + if (/^Key: (.+)$/) { + my $key = $1; + $sect || pegout("defining key ".$key." outside any section"); + defined($key_names{$key}) && + pegout("redefinition of key ".$key." in section [".$sect."]"); + $key_names{$key} = ""; + getl(); + if (/^If: (.+)$/) { + $key_if = $1; + getl(); + } else { + $key_if = ""; + } + my $kif = $sect_if ? + ($key_if ? "(".$sect_if.") && (".$key_if.")" : $sect_if) : $key_if; + my ($e_comm, $e_desc) = ("", ""); + my $type = ""; + if (/^Type: (.+)$/) { + $type = $1; + if ($type eq "enum") { + my $enum = "static const char *e".$key."[] = { "; + my $n_e_def = 0; + while (getl(), /^ ([A-Za-z]+)(\/([A-Z_]+))?: (.+)$/) { + my $e_nam = $1; + $enum .= "\"".$e_nam."\", "; + defined($3) && + ($ov_enum_defs .= "#define ".$3." ".($n_e_def++)."\n"); + my ($comm, $desc) = (dedb($4), $4); + $comm =~ s/\"/\\\"/g; + $e_comm .= " \\\n\"# \\\"".$e_nam."\\\" - ".$comm."\\n\""; + $e_desc .= + "\n". + "".$e_nam."\n". + "".$desc."\n". + "\n"; + } + $enum .= "0 };"; + my @oa = ( [ $enum, "ENUM" ] ); + add_cond($kif, $key, \@oa, \%ov_enum_conds); + $ov_enums .= $oa[0][0]." \\\n"; + $n_e_def && ($ov_enum_defs .= "\n"); + } elsif ($type =~ /^(int|bool|group|string|path|list)$/) { + getl(); + } else { + pegout("unknown Type ".$type." for key ".$key." in section [".$sect."]"); + } + } else { + pegout("expecting Type for key ".$key." in section [".$sect."]"); + } + my ($odflt, $dflt, $cdflt, $ddflt); + my $quot = ($type =~ /^(int|bool|enum|group)$/); + if (/^Default: (\*?)(.+)$/) { + my $defd = $1; + ($odflt, $dflt) = ($2, $2); + $quot && ($dflt = "\"".$dflt."\""); + $defd && ($ov_defaults .= "#define def_".$key." ".$dflt."\n"); + getl(); + } else { + pegout("expecting Default for key ".$key." in section [".$sect."]"); + } + if (/^CDefault: (.+)$/) { + if ($1 eq "-") { + $ddflt = + $cdflt = ""; + } else { + $ddflt = + $cdflt = $1; + $cdflt =~ s/"/\\"/g; + $cdflt = " \\\n\"# Default is ".$cdflt."\\n\""; + } + getl(); + } else { + $ddflt = $odflt; + if ($quot) { + $cdflt = " \\\n\"# Default is ".$odflt."\\n\""; + } else { + $cdflt = " \\\n\"# Default is \\\"\" ".$dflt." \"\\\"\\n\""; + } + } + if (/^DDefault: -$/) { + $ddflt = ""; + getl(); + } + my $pproc; + if (/^PostProc: (.+)$/) { + $pproc = $1; + getl(); + } else { + $pproc = ""; + } + my $nusers = 0; + my ($vname, $kid, $xkid, $ctype, $cpptype, $cget, $cppget); + while (/^User: (.+)$/) { + my $user = $1; + if ($user eq "dummy") { + $vname = "dummy"; + $kid = "C_INTERNAL | C_TYPE_STR"; + $xkid = ""; + } elsif ($user =~ s/^(core|greeter|greeter-c|dep|config)(\((.+)\))?(:font)?$/$1/) { + my ($hvn, $isfn) = (defined($3) ? $3 : mkvname($key), $4); + ($kid, $xkid, $ctype, $cpptype, $cget, $cppget) = @{$th{$type}}; + $kid = sprintf "%#x | %s", $kid_seq, $kid; + if ($user eq "dep") { + $vname = $hvn; + $xkid .= " | C_INTERNAL"; + } elsif ($user eq "config") { + $vname = $hvn; + $xkid .= " | C_INTERNAL | C_CONFIG"; + } else { + $vname = ""; + if ($user eq "core") { + if ($sect =~ /^-/) { + my @oa = ( + [ "{ ".$kid.", boffset(".$hvn.") },", "LOC" ], + [ $ctype.$hvn.";", "LDEF" ] + ); + add_cond($kif, $hvn, \@oa, \%ov_loc_conds); + $ov_locs .= " \\\n".$oa[0][0]; + $ov_loc_defs{$ctype} .= " \\\n\t".$oa[1][0]; + } else { + my @oa = ( + [ "{ ".$kid.", (char **) &".$hvn." },", "GLOB" ], + [ $ctype.$hvn.";", "GDEF" ], + [ "extern ".$ctype.$hvn.";", "GDECL" ] + ); + add_cond($kif, $hvn, \@oa, \%ov_glob_conds); + $ov_globs .= " \\\n".$oa[0][0]; + $ov_glob_defs{$ctype} .= " \\\n".$oa[1][0]; + $ov_glob_decls .= " \\\n".$oa[2][0]; + } + } else { # greeter(-c)? + my ($typ, $gtr, $isc); + if ($isfn) { + $typ = "TQFont\t"; + $gtr = "Str2Font( GetCfgQStr( ".$kid." ) )"; + $isc = 0; + } elsif ($user eq "greeter" && $cppget) { + $typ = $cpptype; + $gtr = $cppget."( ".$kid." )"; + $isc = 0; + } else { + $typ = $ctype; + $gtr = $cget."( ".$kid.(($type eq "list") ? ", 0" : "")." )"; + $isc = 1; + } + my @oa = ( + [ "_".$hvn." = ".$gtr.";", "GRINIT" ], + [ $typ."_".$hvn.";", "GRDEF" ], + [ "extern ".$typ."_".$hvn.";", "GRDECL" ] + ); + add_cond($kif, $hvn, \@oa, \%ov_greet_conds); + $ov_greet_init .= " \\\n ".$oa[0][0]; + $ov_greet_defs{$typ} .= " \\\n".$oa[1][0]; + $ov_greet_decls[$isc] .= " \\\n".$oa[2][0]; + } + } + } else { + pegout("unrecognized User '".$user."' for key ".$key." in section [".$sect."]"); + } + $nusers++; + getl(); + } + $nusers || pegout("expecting User for key ".$key." in section [".$sect."]"); + my $ninsts = 0; + while (/^Instance: ?(.*)$/) { + my $inst = $1; + if ($inst ne "-") { + my $on = 1 - ($inst =~ s/^#//); + my $sec; + if ($sect =~ /^-/) { + ($inst =~ s/^([^\/]+)\///) || pegout("instance for key ".$key." in section [".$sect."] does not specify display"); + $sec = "X-".$1.$sect; + } else { + $sec = $sect; + } + if ($type eq "bool" && $inst eq "!") { + $inst = ($dflt eq "\"true\"") ? "\"false\"" : "\"true\""; + } elsif (!$inst) { + $inst = $dflt; + } else { + $quot && ($inst = "\"".$inst."\""); + } + defined($ex_sects{$sec}) || + pegout("instantiating key ".$key." in section [".$sect."] in undeclared section"); + my @oa = ( [ "{ \"".$key."\",\t".$inst.", ".$on." },", "INST" ] ); + add_cond($key_if, $key, \@oa, \%ex_conds); + $ex_config[$ex_sects{$sec}][2] .= $oa[0][0]." \\\n"; + $ex_config[$ex_sects{$sec}][3] = $sect_if; + } + $ninsts++; + getl(); + } + $ninsts || + print STDERR "Warning: key ".$key." in section [".$sect."] not instanciated\n"; + my ($update, $prio) = ("0", ""); + if (/^Update: ([^\/]+)(\/(\d+))?$/) { + ($update, $prio) = ($1, $3); + getl(); + } + if ($prio) { + ($max_prio < $prio) && ($max_prio = $prio); + } else { + $prio = 0; + } + my $mcnt = 0; + while (/^Merge: (.+)$/) { + my $merge = $1; + if ($merge =~ /^xdm(:([^\(]+))?(\((.+)\))?$/) { + my ($what, $proc) = ($2, $4); + my @oa = ( + [ "{ \"".($what ? $what : lcfirst($key))."\", ". + "\"".(($sect =~ /^-/) ? "X-%s" : "").$sect."\", ". + ($what ? "\"".$key."\"" : "0").", ". + ($proc ? $proc : "0")." },", "XM" ] + ); + add_cond($kif, $key, \@oa, \%ov_xm_conds); + $ov_xm[$sect =~ /^-/] .= $oa[0][0]." \\\n"; + } elsif ($merge =~ /^tdm:([^\(]+)(\((.+)\))?$/) { + my ($where, $func) = ($1, $3); + my $sec = ""; + ($where =~ s/^([^\/]+)\///) && ($sec = $1); + my @oa = ( + [ "{ \"".($where ? $where : $key)."\", ". + ($sec ? "\"".$sect."\"" : "0").", ". + ($where ? "\"".$key."\"" : "0").", ". + ($func ? $func : "0")." },", "KM".($mcnt++) ] + ); + add_cond($kif, $key, \@oa, \%ov_km_conds); + $ov_km{$sec ? $sec : $sect} .= $oa[0][0]." \\\n"; + } else { + pegout("bogus Merge '".$merge."' for key ".$key." in section [".$sect."]"); + } + getl(); + } + # todo: handle $func here, too + my @oa = ( [ "{ \"".$key."\", 0, 0, 0 },", "KM" ] ); + add_cond($kif, $key, \@oa, \%ov_km_conds); + $ov_km{$sect} .= $oa[0][0]." \\\n"; + my $comm = ""; + if (/^Comment:(( [-&])?)$/) { + if ($1 eq " &") { + $comm = "&"; + getl(); + } elsif ($1 ne " -") { + while (getl(), /^ (.*)$/) { + $comm .= $1."\n"; + } + $comm || + print STDERR "Warning: key ".$key." in section [".$sect."] has empty Comment\n"; + } else { + getl(); + } + } else { + print STDERR "Warning: key ".$key." in section [".$sect."] has no Comment\n"; + } + if (/^Description:(( [-!])?)$/) { + if ($1 ne " -") { + $doc_ref .= + "\n". + "\n". + "\n"; + ($1 eq " !") && + ($e_desc = ""); + my $desc = ""; + while (getl(), /^ (_|(.*))$/) { + $desc .= $2."\n"; + } + $desc || + print STDERR "Warning: key ".$key." in section [".$sect."] has empty Description\n"; + ($comm eq "&") && + ($comm = $desc); + $desc = "\n".$desc."\n"; + if ($e_desc) { + $e_desc = "\n".$e_desc."\n"; + ($desc =~ s/%ENUM%/$e_desc/) || + ($desc .= $e_desc); + } + $doc_ref .= $desc; + if ($ddflt) { + if ($ddflt eq '""') { + $doc_ref .= "Empty by default.\n"; + } else { + $ddflt =~ s/\"//g; + $ddflt =~ s,TDMCONF ,\${kde_confdir}/tdm,; + $ddflt =~ s,TDMDATA ,\${kde_datadir}/tdm,; + $ddflt =~ s,XBINDIR ,\${x_bindir},; + $doc_ref .= "The default is ".$ddflt.".\n"; + } + } + $doc_ref .= "\n\n\n"; + } else { + getl(); + } + } else { + print STDERR "Warning: key ".$key." in section [".$sect."] has no Description\n"; + } + pegout("unidentified section body '".$_."' in section [".$sect."]") if ($_); + if ($vname) { + ($vname ne "dummy") && + ($arr_ov_vars{$vname} = $kif); + $vname = "&V".$vname; + } elsif ($pproc) { + $vname = "(void *)".$pproc; + } elsif ($type eq "enum") { + $vname = "e".$key; + } else { + $vname = "0"; + } + $comm = dedb($comm); + $comm =~ s/"/\\"/g; + $comm =~ s/([^\n]*)\n/ \\\n\"# $1\\n\"/g; + @oa = ( + [ "{ \"".$key."\", ".$kid.$xkid.", ".$vname.", ".$dflt." },", "RENT" ], + [ "{ \"".$key."\", ".$prio.", ".$update.",".$comm.$e_comm.$cdflt." },", "GENT" ], + ); + add_cond($key_if, $key, \@oa, \%ov_ent_conds); + $ov_rd_ents .= $oa[0][0]." \\\n"; + $ov_gen_ents .= $oa[1][0]." \\\n"; + $kid_seq++; + } elsif (/^Section: (.+)$/) { + emit_section() if ($sect); + $sect = $1; + defined($sect_names{$sect}) && pegout("redefinition of section [".$sect."]"); + $sect_names{$sect} = ""; + %key_names = (); + getl(); + if (/^If: (.+)$/) { + $sect_if = $1; + getl(); + } else { + $sect_if = ""; + } + my ($sref, $stit, $sna); + if ($sect =~ /^-(.*)$/) { + $sref = lc($1); + $stit = "X-*-".$1; + $sna = "section class"; + } else { + $sref = lc($sect); + $stit = $sect; + $sna = "section"; + } + $doc_ref .= + "\n\n". + "The [".$stit."] ".$sna." of &tdmrc;\n\n"; + if (/^Description:(( -)?)$/) { + if ($1 ne " -") { + my $desc = 0; + $doc_ref .= "\n"; + while (getl(), /^ (_|(.*))$/) { + $doc_ref .= $2."\n"; + $desc = 1; + } + $doc_ref .= "\n"; + $desc || + print STDERR "Warning: section [".$sect."] has empty Description\n"; + } else { + getl(); + } + } else { + print STDERR "Warning: section [".$sect."] has no Description\n"; + } + $doc_ref .= "\n\n\n"; + pegout("unidentified section body '".$_."' in section [".$sect."]") if ($_); + } else { + pegout("invalid section leadin: '".$_."'"); + } + } +} +emit_section(); +close INFILE; + +my $srcf = relpath($ARGV[0], $ARGV[1]); +my $exen = relpath($0, $ARGV[1]); + +open (OUTFILE, ">".$ARGV[1]) || pegout("$0: cannot create output file ".$ARGV[1]); + +if (!$do_doc) { + +print OUTFILE + "/* generated from $srcf by $exen - DO NOT EDIT! */\n\n". + "#ifndef CONFIG_DEFS\n". + "#define CONFIG_DEFS\n\n". + $raw_out."\n\n". + $ov_enum_defs."\n". + $ov_defaults."\n\n"; + +my $ov_vars = ""; +my %ov_var_conds = (); +for my $v (keys %arr_ov_vars) { + my @oa = ( ["V".$v.",", "VAR"] ); + add_cond($arr_ov_vars{$v}, $v, \@oa, \%ov_var_conds); + $ov_vars .= " ".$oa[0][0]." \\\n"; +} +print OUTFILE + emit_conds(\%ov_var_conds). + "#define CONF_READ_VARS \\\n \\\n". + "static Value \\\n". + $ov_vars. + " Vdummy;\n\n\n"; + +print OUTFILE + emit_conds(\%ov_ent_conds). + emit_conds(\%ov_sec_conds). + "#define CONF_SECTS \\\n \\\n". + "static Sect \\\n". + $ov_sect_defs. + " *allSects[]\t= { \\\n". + $ov_sect_refs. + " };\n\n\n"; + +print OUTFILE + emit_conds(\%ov_enum_conds). + "#define CONF_READ_ENTRIES \\\n \\\n". + $ov_enums. + $ov_rd_sects." \\\n". + "CONF_SECTS\n\n\n"; + +print OUTFILE + "#define CONF_MAX_PRIO ".$max_prio."\n\n". + "#define CONF_GEN_ENTRIES \\\n". + $ov_gen_sects." \\\n". + "CONF_SECTS\n\n\n"; + +print OUTFILE + emit_conds(\%ov_glob_conds). + "#define CONF_CORE_GLOBALS \\\n". + $ov_globs."\n\n\n". + "#define CONF_CORE_GLOBAL_DECLS \\\n". + $ov_glob_decls."\n\n\n". + "#define CONF_CORE_GLOBAL_DEFS \\\n". + emit_defs(\%ov_glob_defs)."\n\n\n"; + +print OUTFILE + emit_conds(\%ov_loc_conds). + "#define CONF_CORE_LOCALS \\\n". + $ov_locs."\n\n\n". + "#define CONF_CORE_LOCAL_DEFS \\\n". + emit_defs(\%ov_loc_defs)."\n\n\n\n"; + +print OUTFILE + emit_conds(\%ov_greet_conds). + "#define CONF_GREET_INIT \\\n". + $ov_greet_init."\n\n\n". + "#define CONF_GREET_C_DECLS \\\n". + $ov_greet_decls[1]."\n\n\n". + "#define CONF_GREET_CPP_DECLS \\\n". + $ov_greet_decls[0]."\n\n\n". + "#define CONF_GREET_DEFS \\\n". + emit_defs(\%ov_greet_defs)."\n\n\n"; + +my ($ov1, $ov2) = ("", ""); +my %ex_sec_conds = (); +for my $i (@ex_config) { + my $vn; + if ($i->[0] =~ /^X-(.+)-(.+)$/) { + if ($1 eq "*") { + $vn = "dEntsAny".$2; + } elsif ($1 eq ":*") { + $vn = "dEntsLocal".$2; + } else { + my ($t1, $t2) = ($1, $2); + $t1 =~ s/[-:]/_/g; + $vn = "dEnts".$t1.$t2; + } + } else { + $vn = "dEnts".$i->[0]; + } + my @oa = ( + [ "static DEnt ".$vn."[] = { \\\n".$i->[2]."};", "DSEC" ], + [ "{ \"".$i->[0]."\",\t".$vn.",\tas(".$vn."),".$i->[1]." },", "DSECS" ] + ); + add_cond($i->[3], $vn, \@oa, \%ex_sec_conds); + $ov1 .= $oa[0][0]." \\\n \\\n"; + $ov2 .= $oa[1][0]." \\\n"; +} +print OUTFILE + emit_conds(\%ex_conds). + emit_conds(\%ex_sec_conds). + "#define CONF_GEN_EXAMPLE \\\n \\\n". + $ov1. + "static DSect dAllSects[] = { \\\n". + $ov2. + "};\n\n\n"; + +print OUTFILE + emit_conds(\%ov_xm_conds). + "#define CONF_GEN_XMERGE \\\n \\\n". + "XResEnt globents[] = { \\\n". + $ov_xm[0]. + "}, dpyents[] = { \\\n". + $ov_xm[1]. + "};\n\n\n"; + +my $ov_km_sects = ""; +my $ov_km_sect_refs = ""; +for my $s (keys %ov_km) { + my $ts = $s; + $ts =~ s/-/_/; + $ov_km_sects .= + "KUpdEnt upd".$ts."[] = { \\\n". + $ov_km{$s}. + "}; \\\n \\\n"; + $ov_km_sect_refs .= "{ \"".$s."\", upd".$ts.", as(upd".$ts.") }, \\\n"; +} +print OUTFILE + emit_conds(\%ov_km_conds). + "#define CONF_GEN_KMERGE \\\n \\\n". + $ov_km_sects. + "KUpdSec kupsects[] = { \\\n". + $ov_km_sect_refs. + "};\n"; +print OUTFILE + "\n#endif /* CONFIG_DEFS */\n"; + +} else { + +$doc =~ s/%REF%/$doc_ref/; +print OUTFILE + "\n\n". + $doc; + +} + +close OUTFILE; diff --git a/tdm/kfrontend/CMakeLists.txt b/tdm/kfrontend/CMakeLists.txt new file mode 100644 index 000000000..4a069a3ae --- /dev/null +++ b/tdm/kfrontend/CMakeLists.txt @@ -0,0 +1,101 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +add_subdirectory( themer ) +add_subdirectory( themes ) +add_subdirectory( pics ) +add_subdirectory( sessions ) + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/tdm/backend + ${CMAKE_SOURCE_DIR}/tdmlib + ${CMAKE_SOURCE_DIR}/kcontrol/background + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +if( NOT DEFINED GENTDMCONF_FLAGS ) + set( GENTDMCONF_FLAGS "--no-old" ) +endif( ) + +install( CODE "execute_process( COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gentdmconf --in \$ENV{DESTDIR}${CONFIG_INSTALL_DIR}/tdm --no-in-notice --face-src ${CMAKE_CURRENT_SOURCE_DIR}/pics ${GENTDMCONF_FLAGS} )" ) + + +##### config.ci (generated) ##################### + +add_custom_command( OUTPUT config.ci + COMMAND perl -w ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def config.ci + DEPENDS ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def ) + + +##### tdm_config (executable) ################### + +set_property( SOURCE tdm_config.c APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/config.ci ) + +tde_add_executable( tdm_config + SOURCES tdm_config.c + LINK + DESTINATION ${BIN_INSTALL_DIR} +) + + +##### tdm_greet (executable) #################### +if( WITH_XRANDR ) + set( TDMGREET_OPTIONAL_LINK "krandr-shared" ) +endif ( ) + +tde_add_executable( tdm_greet AUTOMOC + SOURCES + tdm_greet.c tdmconfig.cpp tdmclock.cpp kconsole.cpp + kfdialog.cpp kgdialog.cpp kchooser.cpp kgverify.cpp + tdmshutdown.cpp tdmadmindialog.cpp kgreeter.cpp + kgapp.cpp sakdlg.cc + LINK tdmthemer-static tdeui-shared Xtst ${TDMGREET_OPTIONAL_LINK} + DESTINATION ${BIN_INSTALL_DIR} +) + + +##### krootimage (executable) ################### + +tde_add_executable( krootimage AUTOMOC + SOURCES krootimage.cpp + LINK bgnd-static kio-shared + DESTINATION ${BIN_INSTALL_DIR} +) + + +##### gentdmconf (executable) ################### + +set_property( SOURCE gentdmconf.c APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/config.ci ) + +tde_add_executable( gentdmconf AUTOMOC + SOURCES gentdmconf.c + LINK X11 + DESTINATION ${BIN_INSTALL_DIR} +) + + +##### tdmctl (executable) ####################### + +tde_add_executable( tdmctl + SOURCES tdmctl.c + LINK + DESTINATION ${BIN_INSTALL_DIR} +) diff --git a/tdm/kfrontend/Makefile.am b/tdm/kfrontend/Makefile.am new file mode 100644 index 000000000..7c58dc67f --- /dev/null +++ b/tdm/kfrontend/Makefile.am @@ -0,0 +1,67 @@ +# use 'make GENTDMCONF_FLAGS=... install' to override +GENTDMCONF_FLAGS = --no-old + +SUBDIRS = themer themes pics sessions + +AM_CPPFLAGS = -I$(srcdir)/../backend -I.. -I$(top_srcdir)/kcontrol/background \ + -I$(top_srcdir)/tdmlib $(all_includes) + +bin_PROGRAMS = tdm_config tdm_greet krootimage gentdmconf tdmctl + +tdm_config_SOURCES = tdm_config.c +tdm_config_LDADD = $(LIBRESOLV) $(LIBSOCKET) $(LIBPOSIX4) + +tdm_greet_SOURCES = \ + tdm_greet.c \ + tdmconfig.cpp \ + tdmclock.cpp \ + kconsole.cpp \ + kfdialog.cpp \ + kgdialog.cpp \ + kchooser.cpp \ + kgverify.cpp \ + tdmshutdown.cpp \ + tdmadmindialog.cpp \ + kgreeter.cpp \ + kgapp.cpp +tdm_greet_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -lktexteditor +tdm_greet_LDADD = themer/libtdmthemer.a $(LIB_TDEUI) $(XTESTLIB) $(LIBPOSIX4) + +krootimage_SOURCES = krootimage.cpp +krootimage_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -lktexteditor +krootimage_LDADD = $(top_builddir)/kcontrol/background/libbgnd.la $(LIB_KIO) + +METASOURCES = AUTO + +gentdmconf_SOURCES = gentdmconf.c +gentdmconf_LDFLAGS = $(X_LDFLAGS) $(X_RPATH) +gentdmconf_LDADD = $(LIB_X11) + +tdmctl_SOURCES = tdmctl.c +tdmctl_LDADD = $(LIBSOCKET) + +install-data-local: gentdmconf + ./gentdmconf --in $(DESTDIR)$(kde_confdir)/tdm --no-in-notice --face-src $(srcdir)/pics $(GENTDMCONF_FLAGS) + +messages: + $(XGETTEXT) `find . -name "*.cpp"` -o $(podir)/tdmgreet.pot + +noinst_HEADERS = \ + tdm_greet.h \ + tdmconfig.h \ + tdmclock.h \ + kconsole.h \ + kfdialog.h \ + kgdialog.h \ + kchooser.h \ + kgverify.h \ + tdmshutdown.h \ + kgreeter.h \ + kgapp.h \ + \ + krootimage.h + +tdm_greet_COMPILE_FIRST = ../config.ci +tdm_config_COMPILE_FIRST = ../config.ci +gentdmconf_COMPILE_FIRST = ../config.ci + diff --git a/tdm/kfrontend/gentdmconf.c b/tdm/kfrontend/gentdmconf.c new file mode 100644 index 000000000..f55ffbbbc --- /dev/null +++ b/tdm/kfrontend/gentdmconf.c @@ -0,0 +1,2849 @@ +/* + +Create a suitable configuration for tdm taking old xdm/tdm +installations into account + +Copyright (C) 2001-2005 Oswald Buddenhagen + + +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 +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef BSD +# include +#endif + +#include "config.ci" + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +# define ATTR_UNUSED __attribute__((unused)) +#else +# define ATTR_UNUSED +#endif + +#if defined(__sun) && !defined(__sun__) +# define __sun__ +#endif + +#define as(ar) ((int)(sizeof(ar)/sizeof(ar[0]))) + +#define __stringify(x) #x +#define stringify(x) __stringify(x) + +#define RCVERSTR stringify(RCVERMAJOR) "." stringify(RCVERMINOR) + +static int old_scripts, no_old_scripts, old_confs, no_old, + no_backup, no_in_notice, use_destdir, mixed_scripts; +static const char *newdir = TDMCONF, *facesrc = TDMDATA "/pics/users", + *oldxdm, *oldkde; + +static int oldver; + + +typedef struct StrList { + struct StrList *next; + const char *str; +} StrList; + + +static void * +mmalloc( size_t sz ) +{ + void *ptr; + + if (!(ptr = malloc( sz ))) { + fprintf( stderr, "Out of memory\n" ); + exit( 1 ); + } + return ptr; +} + +static void * +mcalloc( size_t sz ) +{ + void *ptr; + + if (!(ptr = calloc( 1, sz ))) { + fprintf( stderr, "Out of memory\n" ); + exit( 1 ); + } + return ptr; +} + +static void * +mrealloc( void *optr, size_t sz ) +{ + void *ptr; + + if (!(ptr = realloc( optr, sz ))) { + fprintf( stderr, "Out of memory\n" ); + exit( 1 ); + } + return ptr; +} + +static char * +mstrdup( const char *optr ) +{ + char *ptr; + + if (!optr) + return 0; + if (!(ptr = strdup( optr ))) { + fprintf( stderr, "Out of memory\n" ); + exit( 1 ); + } + return ptr; +} + + +#define NO_LOGGER +#define STATIC static +#include + +typedef struct { + char *buf; + int clen, blen, tlen; +} OCABuf; + +static void +OutCh_OCA( void *bp, char c ) +{ + OCABuf *ocabp = (OCABuf *)bp; + + ocabp->tlen++; + if (ocabp->clen >= ocabp->blen) { + ocabp->blen = ocabp->blen * 3 / 2 + 100; + ocabp->buf = mrealloc( ocabp->buf, ocabp->blen ); + } + ocabp->buf[ocabp->clen++] = c; +} + +static int +VASPrintf( char **strp, const char *fmt, va_list args ) +{ + OCABuf ocab = { 0, 0, 0, -1 }; + + DoPr( OutCh_OCA, &ocab, fmt, args ); + OutCh_OCA( &ocab, 0 ); + *strp = realloc( ocab.buf, ocab.clen ); + if (!*strp) + *strp = ocab.buf; + return ocab.tlen; +} + +static int +ASPrintf( char **strp, const char *fmt, ... ) +{ + va_list args; + int len; + + va_start( args, fmt ); + len = VASPrintf( strp, fmt, args ); + va_end( args ); + return len; +} + +static void +StrCat( char **strp, const char *fmt, ... ) +{ + char *str, *tstr; + va_list args; + int el; + + va_start( args, fmt ); + el = VASPrintf( &str, fmt, args ); + va_end( args ); + if (*strp) { + int ol = strlen( *strp ); + tstr = mmalloc( el + ol + 1 ); + memcpy( tstr, *strp, ol ); + memcpy( tstr + ol, str, el + 1 ); + free( *strp ); + free( str ); + *strp = tstr; + } else + *strp = str; +} + + +#define WANT_CLOSE 1 + +typedef struct File { + char *buf, *eof, *cur; +#if defined(HAVE_MMAP) && defined(WANT_CLOSE) + int ismapped; +#endif +} File; + +static int +readFile( File *file, const char *fn ) +{ + off_t flen; + int fd; + + if ((fd = open( fn, O_RDONLY )) < 0) + return 0; + + flen = lseek( fd, 0, SEEK_END ); +#ifdef HAVE_MMAP +# ifdef WANT_CLOSE + file->ismapped = 0; +# endif + file->buf = mmap( 0, flen + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0 ); +# ifdef WANT_CLOSE + if (file->buf) + file->ismapped = 1; + else +# else + if (!file->buf) +# endif +#endif + { + file->buf = mmalloc( flen + 1 ); + lseek( fd, 0, SEEK_SET ); + if (read( fd, file->buf, flen ) != flen) { + free( file->buf ); + close( fd ); + fprintf( stderr, "Cannot read file\n" ); + return 0; /* maybe better abort? */ + } + } + file->eof = file->buf + flen; + close( fd ); + return 1; +} + +#ifdef WANT_CLOSE +static void +freeBuf( File *file ) +{ +# ifdef HAVE_MMAP + if (file->ismapped) + munmap( file->buf, file->eof - file->buf ); + else +# endif + free( file->buf ); +} +#endif + +static int +isTrue( const char *val ) +{ + return !strcmp( val, "true" ) || + !strcmp( val, "yes" ) || + !strcmp( val, "on" ) || + atoi( val ); +} + +static int +mkdirp( const char *name, int mode, const char *what, int existok ) +{ + char *mfname = mstrdup( name ); + int i; + struct stat st; + + for (i = 1; mfname[i]; i++) + if (mfname[i] == '/') { + mfname[i] = 0; + if (stat( mfname, &st )) { + if (mkdir( mfname, 0755 )) { + fprintf( stderr, "Cannot create parent %s of %s directory %s: %s\n", + mfname, what, name, strerror( errno ) ); + free( mfname ); + return 0; + } + chmod( mfname, 0755 ); + } + mfname[i] = '/'; + } + free( mfname ); + if (stat( name, &st )) { + if (mkdir( name, mode )) { + fprintf( stderr, "Cannot create %s directory %s: %s\n", + what, name, strerror( errno ) ); + return 0; + } + chmod( name, mode ); + return 1; + } + return existok; +} + + +static void +displace( const char *fn ) +{ + if (!no_backup) { + char bn[PATH_MAX + 4]; + sprintf( bn, "%s.bak", fn ); /* won't overflow if only existing paths are passed */ + rename( fn, bn ); + } else + unlink( fn ); +} + + +static char * +locate( const char *exe ) +{ + int len; + char *path, *name, *thenam, nambuf[PATH_MAX+1]; + char *pathe; + + if (!(path = getenv( "PATH" ))) + return 0; + len = strlen( exe ); + name = nambuf + PATH_MAX - len; + memcpy( name, exe, len + 1 ); + *--name = '/'; + do { + if (!(pathe = strchr( path, ':' ))) + pathe = path + strlen( path ); + len = pathe - path; + if (len && !(len == 1 && *path == '.')) { + thenam = name - len; + if (thenam >= nambuf) { + memcpy( thenam, path, len ); + if (!access( thenam, X_OK )) + return mstrdup( thenam ); + } + } + path = pathe; + } while (*path++ != '\0'); + return 0; +} + + +/* + * target data to be written to tdmrc + */ + +typedef struct Entry { + struct Entry *next; + struct Ent *spec; + const char *value; + int active:1; + int written:1; +} Entry; + +typedef struct Section { + struct Section *next; + struct Sect *spec; + const char *name; + const char *comment; + Entry *ents; +} Section; + +static Section *config; /* the tdmrc data to be written */ + +/* + * Specification of the (currently possible) tdmrc entries + */ + +typedef struct Ent { + const char *key; + int prio; + void (*func)( Entry *ce, Section *cs ); + const char *comment; +} Ent; + +typedef struct Sect { + const char *name; + Ent *ents; + int nents; +} Sect; + +static Sect *findSect( const char *name ); +static Ent *findEnt( Sect *sect, const char *key ); + +/* + * Functions to manipulate the current tdmrc data + */ + +static const char * +getfqval( const char *sect, const char *key, const char *defval ) +{ + Section *cs; + Entry *ce; + + for (cs = config; cs; cs = cs->next) + if (!strcmp( cs->name, sect )) { + for (ce = cs->ents; ce; ce = ce->next) + if (!strcmp( ce->spec->key, key )) { + if (ce->active && ce->written) + return ce->value; + break; + } + break; + } + return defval; +} + +static void +putfqval( const char *sect, const char *key, const char *value ) +{ + Section *cs, **csp; + Entry *ce, **cep; + + if (!value) + return; + + for (csp = &config; (cs = *csp); csp = &(cs->next)) + if (!strcmp( sect, cs->name )) + goto havesec; + cs = mcalloc( sizeof(*cs) ); + ASPrintf( (char **)&cs->name, "%s", sect ); + cs->spec = findSect( sect ); + *csp = cs; + havesec: + + for (cep = &(cs->ents); (ce = *cep); cep = &(ce->next)) + if (!strcmp( key, ce->spec->key )) + goto haveent; + ce = mcalloc( sizeof(*ce) ); + ce->spec = findEnt( cs->spec, key ); + *cep = ce; + haveent: + ASPrintf( (char **)&ce->value, "%s", value ); + ce->written = ce->active = 1; +} + +static const char *csect; + +#define setsect(se) csect = se + +static void +putval( const char *key, const char *value ) +{ + putfqval( csect, key, value ); +} + + +static void +wrconf( FILE *f ) +{ + Section *cs; + Entry *ce; + StrList *sl = 0, *sp; + const char *cmt; + + putfqval( "General", "ConfigVersion", RCVERSTR ); + for (cs = config; cs; cs = cs->next) { + fprintf( f, "%s[%s]\n", + cs->comment ? cs->comment : "\n", cs->name ); + for (ce = cs->ents; ce; ce = ce->next) { + if (ce->spec->comment) { + cmt = ce->spec->comment; + for (sp = sl; sp; sp = sp->next) + if (sp->str == cmt) { + cmt = "# See above\n"; + goto havit; + } + if (!(sp = malloc( sizeof(*sp) ))) + fprintf( stderr, "Warning: Out of memory\n" ); + else { + sp->str = cmt; + sp->next = sl; sl = sp; + } + } else + cmt = ""; + havit: + fprintf( f, "%s%s%s=%s\n", + cmt, ce->active ? "" : "#", ce->spec->key, ce->value ); + } + } +} + + +/* + * defaults + */ +#ifdef XDMCP +static const char def_xaccess[] = +"# Xaccess - Access control file for XDMCP connections\n" +"#\n" +"# To control Direct and Broadcast access:\n" +"#\n" +"# pattern\n" +"#\n" +"# To control Indirect queries:\n" +"#\n" +"# pattern list of hostnames and/or macros ...\n" +"#\n" +"# To use the chooser:\n" +"#\n" +"# pattern CHOOSER BROADCAST\n" +"#\n" +"# or\n" +"#\n" +"# pattern CHOOSER list of hostnames and/or macros ...\n" +"#\n" +"# To define macros:\n" +"#\n" +"# %name list of hosts ...\n" +"#\n" +"# The first form tells xdm which displays to respond to itself.\n" +"# The second form tells xdm to forward indirect queries from hosts matching\n" +"# the specified pattern to the indicated list of hosts.\n" +"# The third form tells xdm to handle indirect queries using the chooser;\n" +"# the chooser is directed to send its own queries out via the broadcast\n" +"# address and display the results on the terminal.\n" +"# The fourth form is similar to the third, except instead of using the\n" +"# broadcast address, it sends DirectQuerys to each of the hosts in the list\n" +"#\n" +"# In all cases, xdm uses the first entry which matches the terminal;\n" +"# for IndirectQuery messages only entries with right hand sides can\n" +"# match, for Direct and Broadcast Query messages, only entries without\n" +"# right hand sides can match.\n" +"#\n" +"\n" +"#* #any host can get a login window\n" +"\n" +"#\n" +"# To hardwire a specific terminal to a specific host, you can\n" +"# leave the terminal sending indirect queries to this host, and\n" +"# use an entry of the form:\n" +"#\n" +"\n" +"#terminal-a host-a\n" +"\n" +"\n" +"#\n" +"# The nicest way to run the chooser is to just ask it to broadcast\n" +"# requests to the network - that way new hosts show up automatically.\n" +"# Sometimes, however, the chooser can't figure out how to broadcast,\n" +"# so this may not work in all environments.\n" +"#\n" +"\n" +"#* CHOOSER BROADCAST #any indirect host can get a chooser\n" +"\n" +"#\n" +"# If you'd prefer to configure the set of hosts each terminal sees,\n" +"# then just uncomment these lines (and comment the CHOOSER line above)\n" +"# and edit the %hostlist line as appropriate\n" +"#\n" +"\n" +"#%hostlist host-a host-b\n" +"\n" +"#* CHOOSER %hostlist #\n"; +#endif + +#ifdef XDMCP +static const char def_willing[] = +"#! /bin/sh\n" +"# The output of this script is displayed in the chooser window\n" +"# (instead of \"Willing to manage\").\n" +"\n" +"load=`uptime|sed -e 's/^.*load[^0-9]*//'`\n" +"nrusers=`who|cut -c 1-8|sort -u|wc -l|sed 's/^[ \t]*//'`\n" +"s=\"\"; [ \"$nrusers\" != 1 ] && s=s\n" +"\n" +"echo \"${nrusers} user${s}, load: ${load}\"\n"; +#endif + +static const char def_setup[] = +"#! /bin/sh\n" +"# Xsetup - run as root before the login dialog appears\n" +"\n" +"#xconsole -geometry 480x130-0-0 -notify -verbose -fn fixed -exitOnFail -file /dev/xconsole &\n"; + +static const char def_startup[] = +"#! /bin/sh\n" +"# Xstartup - run as root before session starts\n" +"\n" +"\n" +"\n" +"if [ -e /etc/nologin ]; then\n" +" # always display the nologin message, if possible\n" +" if [ -s /etc/nologin ] && which xmessage > /dev/null 2>&1; then\n" +" xmessage -file /etc/nologin -geometry 640x480\n" +" fi\n" +" if [ \"$(id -u)\" != \"0\" ] && \\\n" +" ! grep -qs '^ignore-nologin' /etc/trinity/tdm/tdm.options; then\n" +" exit 1\n" +" fi\n" +"fi\n" +"\n" +"if grep -qs '^use-sessreg' /etc/trinity/tdm/tdm.options && \\\n" +" which sessreg > /dev/null 2>&1; then\n" +" exec sessreg -a -l \"$DISPLAY\" -u /var/run/utmp \\\n" +" -h \"`echo $DISPLAY | cut -d: -f1`\" \"$USER\"\n" +" # NOTREACHED\n" +"fi\n"; + +static const char def_reset[] = +"#! /bin/sh\n" +"# Xreset - run as root after session exits\n" +"\n" +"# Reassign ownership of the console to root, this should disallow\n" +"# assignment of console output to any random users's xterm. See Xstartup.\n" +"#\n" +"#chown root /dev/console\n" +"#chmod 622 /dev/console\n" +"\n" +#ifdef _AIX +"#devname=`echo $DISPLAY | cut -c1-8`\n" +"#exec sessreg -d -l xdm/$devname -h \"`echo $DISPLAY | cut -d: -f1`\"" +#else +"if grep -qs '^use-sessreg' /etc/trinity/tdm/tdm.options && \\\n" +" which sessreg > /dev/null 2>&1; then\n" +" exec sessreg -d -l \"$DISPLAY\" -u /var/run/utmp \\\n" +" -h \"`echo $DISPLAY | cut -d: -f1`\" \"$USER\"\n" +" # NOTREACHED\n" +"fi\n"; +#endif /* _AIX */ + +static const char def_session1[] = +"#! /bin/sh\n" +"# Xsession - run as user\n" +"\n" +"session=$1\n" +"\n" +"# Note that the respective logout scripts are not sourced.\n" +"case $SHELL in\n" +" */bash)\n" +" [ -z \"$BASH\" ] && exec $SHELL $0 \"$@\"\n" +" set +o posix\n" +" [ -f /etc/profile ] && . /etc/profile\n" +" if [ -f $HOME/.bash_profile ]; then\n" +" . $HOME/.bash_profile\n" +" elif [ -f $HOME/.bash_login ]; then\n" +" . $HOME/.bash_login\n" +" elif [ -f $HOME/.profile ]; then\n" +" . $HOME/.profile\n" +" fi\n" +" ;;\n" +" */zsh)\n" +" [ -z \"$ZSH_NAME\" ] && exec $SHELL $0 \"$@\"\n" +" emulate -R zsh\n" +" [ -d /etc/zsh ] && zdir=/etc/zsh || zdir=/etc\n" +" zhome=${ZDOTDIR:-$HOME}\n" +" # zshenv is always sourced automatically.\n" +" [ -f $zdir/zprofile ] && . $zdir/zprofile\n" +" [ -f $zhome/.zprofile ] && . $zhome/.zprofile\n" +" [ -f $zdir/zlogin ] && . $zdir/zlogin\n" +" [ -f $zhome/.zlogin ] && . $zhome/.zlogin\n" +" setopt shwordsplit noextendedglob\n" +" ;;\n" +" */csh|*/tcsh)\n" +" # [t]cshrc is always sourced automatically.\n" +" # Note that sourcing csh.login after .cshrc is non-standard.\n" +" xsess_tmp="; +static const char def_session2[] = +"\n" +" $SHELL -c \"if (-f /etc/csh.login) source /etc/csh.login; if (-f ~/.login) source ~/.login; /bin/sh -c export -p >! $xsess_tmp\"\n" +" . $xsess_tmp\n" +" rm -f $xsess_tmp\n" +" ;;\n" +" *) # Plain sh, ksh, and anything we don't know.\n" +" [ -f /etc/profile ] && . /etc/profile\n" +" [ -f $HOME/.profile ] && . $HOME/.profile\n" +" ;;\n" +"esac\n" +"# invoke global X session script\n" +". /etc/X11/Xsession\n"; + +static const char def_background[] = +"[Desktop0]\n" +"BackgroundMode=Flat\n" +"BlendBalance=100\n" +"BlendMode=NoBlending\n" +"ChangeInterval=60\n" +"Color1=0,0,200\n" +"Color2=192,192,192\n" +"CurrentWallpaper=0\n" +"LastChange=0\n" +"MinOptimizationDepth=1\n" +"MultiWallpaperMode=NoMulti\n" +"Pattern=fish\n" +"Program=\n" +"ReverseBlending=false\n" +"UseSHM=false\n" +"Wallpaper=isadora.png\n" +"WallpaperList=\n" +"WallpaperMode=Scaled\n"; + +static char * +prepName( const char *fn ) +{ + const char *tname; + char *nname; + + tname = strrchr( fn, '/' ); + ASPrintf( &nname, "%s/%s", newdir, tname ? tname + 1 : fn ); + displace( nname ); + return nname; +} + +static FILE * +Create( const char *fn, int mode ) +{ + char *nname; + FILE *f; + + nname = prepName( fn ); + if (!(f = fopen( nname, "w" ))) { + fprintf( stderr, "Cannot create %s\n", nname ); + exit( 1 ); + } + chmod( nname, mode ); + free( nname ); + return f; +} + +static void +WriteOut( const char *fn, int mode, time_t stamp, const char *buf, size_t len ) +{ + char *nname; + int fd; + struct utimbuf utim; + + nname = prepName( fn ); + if ((fd = creat( nname, mode )) < 0) { + fprintf( stderr, "Cannot create %s\n", nname ); + exit( 1 ); + } + write( fd, buf, len ); + close( fd ); + if (stamp) { + utim.actime = utim.modtime = stamp; + utime( nname, &utim ); + } + free( nname ); +} + + +/* returns static array! */ +static const char * +resect( const char *sec, const char *name ) +{ + static char sname[64]; + char *p; + + if ((p = strrchr( sec, '-' ))) { + sprintf( sname, "%.*s-%s", p - sec, sec, name ); + return sname; + } else + return name; +} + +static int +inNewDir( const char *name ) +{ + return !memcmp( name, TDMCONF "/", sizeof(TDMCONF) ); +} + +static int +inList( StrList *sp, const char *s ) +{ + for (; sp; sp = sp->next) + if (!strcmp( sp->str, s )) + return 1; + return 0; +} + +static void +addStr( StrList **sp, const char *s ) +{ + for (; *sp; sp = &(*sp)->next) + if (!strcmp( (*sp)->str, s )) + return; + *sp = mcalloc( sizeof(**sp) ); + ASPrintf( (char **)&(*sp)->str, "%s", s ); +} + +StrList *aflist, *uflist, *eflist, *cflist, *lflist; + +/* file is part of new config */ +static void +addedFile( const char *fn ) +{ + addStr( &aflist, fn ); +} + +/* file from old config was parsed */ +static void +usedFile( const char *fn ) +{ + addStr( &uflist, fn ); +} + +/* file from old config was copied with slight modifications */ +static void +editedFile( const char *fn ) +{ + addStr( &eflist, fn ); +} + +/* file from old config was copied verbatim */ +static void +copiedFile( const char *fn ) +{ + addStr( &cflist, fn ); +} + +/* file from old config is still being used */ +static void +linkedFile( const char *fn ) +{ + addStr( &lflist, fn ); +} + +/* + * XXX this stuff is highly borked. it does not handle collisions at all. + */ +static int +copyfile( Entry *ce, const char *tname, int mode, int (*proc)( File * ) ) +{ + const char *tptr; + char *nname; + File file; + int rt; + + if (!*ce->value) + return 1; + + tptr = strrchr( tname, '/' ); + ASPrintf( &nname, TDMCONF "/%s", tptr ? tptr + 1 : tname ); + if (inList( cflist, ce->value ) || + inList( eflist, ce->value ) || + inList( lflist, ce->value )) + { + rt = 1; + goto doret; + } + if (!readFile( &file, ce->value )) { + fprintf( stderr, "Warning: cannot copy file %s\n", ce->value ); + rt = 0; + } else { + if (!proc || !proc( &file )) { + if (!use_destdir && !strcmp( ce->value, nname )) + linkedFile( nname ); + else { + struct stat st; + stat( ce->value, &st ); + WriteOut( nname, mode, st.st_mtime, file.buf, file.eof - file.buf ); + copiedFile( ce->value ); + } + } else { + WriteOut( nname, mode, 0, file.buf, file.eof - file.buf ); + editedFile( ce->value ); + } + if (strcmp( ce->value, nname ) && inNewDir( ce->value ) && !use_destdir) + displace( ce->value ); + addedFile( nname ); + rt = 1; + } + doret: + ce->value = nname; + return rt; +} + +static void +dlinkfile( const char *name ) +{ + File file; + + if (!readFile( &file, name )) { + fprintf( stderr, "Warning: cannot read file %s\n", name ); + return; + } + if (inNewDir( name ) && use_destdir) { + struct stat st; + stat( name, &st ); + WriteOut( name, st.st_mode, st.st_mtime, file.buf, file.eof - file.buf ); + copiedFile( name ); + } else + linkedFile( name ); + addedFile( name ); +} + +static void +linkfile( Entry *ce ) +{ + if (ce->written && *ce->value) + dlinkfile( ce->value ); +} + +static void +writefile( const char *tname, int mode, const char *cont ) +{ + WriteOut( tname, mode, 0, cont, strlen( cont ) ); + addedFile( tname ); +} + + +char *background; + +static void +handBgCfg( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) /* can be only the X-*-Greeter one */ + writefile( def_BackgroundCfg, 0644, + background ? background : def_background ); +#if 0 /* risk of kcontrol clobbering the original file */ + else if (old_confs) + linkfile( ce ); +#endif + else { + if (!copyfile( ce, ce->value, 0644, 0 )) { + if (!strcmp( cs->name, "X-*-Greeter" )) + writefile( def_BackgroundCfg, 0644, def_background ); + ce->active = 0; + } + } +} + + +#ifdef HAVE_VTS +static char * +mem_mem( char *mem, int lmem, const char *smem, int lsmem ) +{ + for (; lmem >= lsmem; mem++, lmem--) + if (!memcmp( mem, smem, lsmem )) + return mem + lsmem; + return 0; +} + +static int maxTTY, TTYmask; + +static void +getInitTab( void ) +{ + File it; + char *p, *eol, *ep; + int tty; + + if (maxTTY) + return; + if (!maxTTY) { + maxTTY = 6; + TTYmask = 0x3f; + } +} +#endif + + +/* TODO: handle solaris' local_uid specs */ + +static char * +ReadWord( File *file, int EOFatEOL ) +{ + char *wordp, *wordBuffer; + int quoted; + char c; + + rest: + wordp = wordBuffer = file->cur; + mloop: + quoted = 0; + qloop: + if (file->cur == file->eof) { + doeow: + if (wordp == wordBuffer) + return 0; + retw: + *wordp = '\0'; + return wordBuffer; + } + c = *file->cur++; + switch (c) { + case '#': + if (quoted) + break; + do { + if (file->cur == file->eof) + goto doeow; + c = *file->cur++; + } while (c != '\n'); + case '\0': + case '\n': + if (EOFatEOL && !quoted) { + file->cur--; + goto doeow; + } + if (wordp != wordBuffer) { + file->cur--; + goto retw; + } + goto rest; + case ' ': + case '\t': + if (wordp != wordBuffer) + goto retw; + goto rest; + case '\\': + if (!quoted) { + quoted = 1; + goto qloop; + } + break; + } + *wordp++ = c; + goto mloop; +} + +/* backslashes are double-escaped - for KConfig and for parseArgs */ +static const char * +joinArgs( StrList *argv ) +{ + StrList *av; + const char *s, *rs; + char *str; + int slen; + + if (!argv) + return ""; + for (slen = 0, av = argv; slen++, av; av = av->next) { + int nq = 0; + for (s = av->str; *s; s++, slen++) + if (isspace( *s ) || *s == '\'') + nq = 2; + else if (*s == '"') + slen += 2; + else if (*s == '\\') + slen += 3; + slen += nq; + } + rs = str = mmalloc( slen ); + for (av = argv; av; av = av->next) { + int nq = 0; + for (s = av->str; *s; s++) + if (isspace( *s ) || *s == '\'') + nq = 2; + if (av != argv) + *str++ = ' '; + if (nq) + *str++ = '"'; + for (s = av->str; *s; s++) { + if (*s == '\\') + *str++ = '\\'; + if (*s == '"' || *s == '\\') { + *str++ = '\\'; + *str++ = '\\'; + } + *str++ = *s; + } + if (nq) + *str++ = '"'; + } + *str = 0; + return rs; +} + +# define dLocation 1 +# define dLocal 0 +# define dForeign 1 + +static struct displayMatch { + const char *name; + int len, type; +} displayTypes[] = { + { "local", 5, dLocal }, + { "foreign", 7, dForeign }, +}; + +static int +parseDisplayType( const char *string, const char **atPos ) +{ + struct displayMatch *d; + + *atPos = 0; + for (d = displayTypes; d < displayTypes + as(displayTypes); d++) { + if (!memcmp( d->name, string, d->len ) && + (!string[d->len] || string[d->len] == '@')) + { + if (string[d->len] == '@' && string[d->len + 1]) + *atPos = string + d->len + 1; + return d->type; + } + } + return -1; +} + +typedef struct serverEntry { + struct serverEntry *next; + const char *name, *class2, *console, *argvs, *arglvs; + StrList *argv, *arglv; + int type, reserve, vt; +} ServerEntry; + +static void +absorb_xservers( const char *sect ATTR_UNUSED, char **value ) +{ + ServerEntry *se, *se1, *serverList, **serverPtr; + const char *word, *word2; + char *sdpys, *rdpys; + StrList **argp, **arglp, *ap, *ap2; + File file; + int nldpys = 0, nrdpys = 0, dpymask = 0; + int cpcmd, cpcmdl; +#ifdef HAVE_VTS + int dn, cpvt, mtty; +#endif + + if (**value == '/') { + if (!readFile( &file, *value )) + return; + usedFile( *value ); + } else { + file.buf = *value; + file.eof = *value + strlen( *value ); + } + file.cur = file.buf; + + serverPtr = &serverList; +#ifdef HAVE_VTS + bustd: +#endif + while ((word = ReadWord( &file, 0 ))) { + se = mcalloc( sizeof(*se) ); + se->name = word; + if (!(word = ReadWord( &file, 1 ))) + continue; + se->type = parseDisplayType( word, &se->console ); + if (se->type < 0) { + se->class2 = word; + if (!(word = ReadWord( &file, 1 ))) + continue; + se->type = parseDisplayType( word, &se->console ); + if (se->type < 0) { + while (ReadWord( &file, 1 )); + continue; + } + } + word = ReadWord( &file, 1 ); + if (word && !strcmp( word, "reserve" )) { + se->reserve = 1; + word = ReadWord( &file, 1 ); + } + if (((se->type & dLocation) == dLocal) != (word != 0)) + continue; + argp = &se->argv; + arglp = &se->arglv; + while (word) { +#ifdef HAVE_VTS + if (word[0] == 'v' && word[1] == 't') + se->vt = atoi( word + 2 ); + else if (!strcmp( word, "-crt" )) { /* SCO style */ + if (!(word = ReadWord( &file, 1 )) || + memcmp( word, "/dev/tty", 8 )) + goto bustd; + se->vt = atoi( word + 8 ); + } else +#endif + if (strcmp( word, se->name )) { + ap = mmalloc( sizeof(*ap) ); + ap->str = word; + if (!strcmp( word, "-nolisten" )) { + if (!(word2 = ReadWord( &file, 1 ))) + break; + ap2 = mmalloc( sizeof(*ap2) ); + ap2->str = word2; + ap->next = ap2; + if (!strcmp( word2, "unix" )) { + *argp = ap; + argp = &ap2->next; + } else { + *arglp = ap; + arglp = &ap2->next; + } + } else { + *argp = ap; + argp = &ap->next; + } + } + word = ReadWord( &file, 1 ); + } + *argp = *arglp = 0; + if ((se->type & dLocation) == dLocal) { + nldpys++; + dpymask |= 1 << atoi( se->name + 1 ); + if (se->reserve) + nrdpys++; + } + *serverPtr = se; + serverPtr = &se->next; + } + *serverPtr = 0; + +#ifdef HAVE_VTS + /* don't copy only if all local displays are ordered and have a vt */ + cpvt = 0; + getInitTab(); + for (se = serverList, mtty = maxTTY; se; se = se->next) + if ((se->type & dLocation) == dLocal) { + mtty++; + if (se->vt != mtty) { + cpvt = 1; + break; + } + } +#endif + + for (se = serverList; se; se = se->next) { + se->argvs = joinArgs( se->argv ); + se->arglvs = joinArgs( se->arglv ); + } + + se1 = 0, cpcmd = cpcmdl = 0; + for (se = serverList; se; se = se->next) + if ((se->type & dLocation) == dLocal) { + if (!se1) + se1 = se; + else { + if (strcmp( se1->argvs, se->argvs )) + cpcmd = 1; + if (strcmp( se1->arglvs, se->arglvs )) + cpcmdl = 1; + } + } + if (se1) { + putfqval( "X-:*-Core", "ServerCmd", se1->argvs ); + putfqval( "X-:*-Core", "ServerArgsLocal", se1->arglvs ); + for (se = serverList; se; se = se->next) + if ((se->type & dLocation) == dLocal) { + char sec[32]; + sprintf( sec, "X-%s-Core", se->name ); + if (cpcmd) + putfqval( sec, "ServerCmd", se->argvs ); + if (cpcmdl) + putfqval( sec, "ServerArgsLocal", se->arglvs ); +#ifdef HAVE_VTS + if (cpvt && se->vt) { + char vt[8]; + sprintf( vt, "%d", se->vt ); + putfqval( sec, "ServerVT", vt ); + } +#else + if (se->console) + putfqval( sec, "ServerTTY", se->console ); +#endif + } + } + + sdpys = rdpys = 0; + for (se = serverList; se; se = se->next) + StrCat( se->reserve ? &rdpys : &sdpys, + se->class2 ? ",%s_%s" : ",%s", se->name, se->class2 ); + +#ifdef HAVE_VTS + /* add reserve dpys */ + if (nldpys < 4 && nldpys && !nrdpys) + for (; nldpys < 4; nldpys++) { + for (dn = 0; dpymask & (1 << dn); dn++); + dpymask |= (1 << dn); + StrCat( &rdpys, ",:%d", dn ); + } +#endif + + putfqval( "General", "StaticServers", sdpys ? sdpys + 1 : "" ); + putfqval( "General", "ReserveServers", rdpys ? rdpys + 1 : "" ); + + if (**value == '/' && inNewDir( *value ) && !use_destdir) + displace( *value ); +} + +#ifdef HAVE_VTS +static void +upd_servervts( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) { /* there is only the Global one */ +#ifdef __linux__ /* XXX actually, sysvinit */ + getInitTab(); + ASPrintf( (char **)&ce->value, "-%d", maxTTY + 1 ); + ce->active = ce->written = 1; +#endif + } +} + +static void +upd_consolettys( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) { /* there is only the Global one */ +#ifdef __linux__ /* XXX actually, sysvinit */ + char *buf; + int i; + + getInitTab(); + for (i = 0, buf = 0; i < 16; i++) + if (TTYmask & (1 << i)) + StrCat( &buf, ",tty%d", i + 1 ); + if (buf) { + ce->value = buf + 1; + ce->active = ce->written = 1; + } +#endif + } +} +#endif + +#ifdef XDMCP +static void +cp_keyfile( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) /* there is only the Global one */ + return; + if (old_confs) + linkfile( ce ); + else + if (!copyfile( ce, "tdmkeys", 0600, 0 )) + ce->active = 0; +} + +static void +mk_xaccess( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) /* there is only the Global one */ + writefile( def_Xaccess, 0644, def_xaccess ); + else if (old_confs) + linkfile( ce ); + else + copyfile( ce, "Xaccess", 0644, 0 ); /* don't handle error, it will disable Xdmcp automatically */ +} + +static void +mk_willing( Entry *ce, Section *cs ATTR_UNUSED ) +{ + char *fname; + + if (!ce->active) /* there is only the Global one */ + goto dflt; + else { + if (!(fname = strchr( ce->value, '/' ))) + return; /* obviously in-line (or empty) */ + if (old_scripts || inNewDir( fname )) + dlinkfile( fname ); + else { + dflt: + ce->value = TDMCONF "/Xwilling"; + ce->active = ce->written = 1; + writefile( ce->value, 0755, def_willing ); + } + } +} +#endif + +/* +static int +edit_resources( File *file ) +{ + // XXX remove any login*, chooser*, ... resources + return 0; +} +*/ + +static void +cp_resources( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) /* the X-*-Greeter one */ + return; + if (old_confs) + linkfile( ce ); + else + if (!copyfile( ce, ce->value, 0644, 0/*edit_resources*/ )) + ce->active = 0; +} + +static int +delstr( File *fil, const char *pat ) +{ + char *p, *pp, *bpp; + const char *pap, *paap; + + *fil->eof = 0; + for (p = fil->buf; *p; p++) { + for (pp = p, pap = pat; ; ) { + if (!*pap) { + *p = '\n'; + memcpy( p + 1, pp, fil->eof - pp + 1 ); + fil->eof -= pp - p - 1; + return 1; + } else if (!memcmp( pap, "*/", 2 )) { + paap = pap += 2; + while (!isspace( *pap )) + pap++; + if (*pp != '/') + break; + for (;;) + for (bpp = ++pp; *pp != '/'; pp++) + if (!*pp || isspace( *pp )) + goto wbrk; + wbrk: + if ((pp - bpp != pap - paap) || memcmp( bpp, paap, pap - paap )) + break; + } else if (*pap == '\t') { + pap++; + while (*pp == ' ' || *pp == '\t') + pp++; + } else if (*pap == '[') { + pap++; + for (;;) { + if (!*pap) { + fprintf( stderr, "Internal error: unterminated char set\n" ); + exit( 1 ); + } + if (*pap == *pp) { + while (*++pap != ']') + if (!*pap) { + fprintf( stderr, "Internal error: unterminated char set\n" ); + exit( 1 ); + } + pap++; + pp++; + break; + } + if (*++pap == ']') + goto no; + } + } else { + if (*pap == '\n') + while (*pp == ' ' || *pp == '\t') + pp++; + if (*pap != *pp) + break; + pap++; + pp++; + } + } + no: ; + } + return 0; +} + +/* XXX + the UseBackground voodoo will horribly fail, if multiple sections link + to the same Xsetup file +*/ + +static int mod_usebg; + +static int +edit_setup( File *file ) +{ + int chg = + delstr( file, "\n" + "(\n" + " PIDFILE=/var/run/tdmdesktop-$DISPLAY.pid\n" + " */tdmdesktop\t&\n" + " echo $! >$PIDFILE\n" + " wait $!\n" + " rm $PIDFILE\n" + ")\t&\n" ) | + delstr( file, "\n" + "*/tdmdesktop\t&\n" ) | + delstr( file, "\n" + "tdmdesktop\t&\n" ) | + delstr( file, "\n" + "tdmdesktop\n" ); + putval( "UseBackground", chg ? "true" : "false" ); + return chg; +} + +static void +mk_setup( Entry *ce, Section *cs ) +{ + setsect( resect( cs->name, "Greeter" ) ); + if (old_scripts || mixed_scripts) { + if (mod_usebg && *ce->value) + putval( "UseBackground", "false" ); + linkfile( ce ); + } else { + if (ce->active && inNewDir( ce->value )) { + if (mod_usebg) + copyfile( ce, ce->value, 0755, edit_setup ); + else + linkfile( ce ); + } else { + ce->value = TDMCONF "/Xsetup"; + ce->active = ce->written = 1; + writefile( ce->value, 0755, def_setup ); + } + } +} + +static int +edit_startup( File *file ) +{ + int chg1 = 0, chg2 = 0; + + if (mod_usebg && + (delstr( file, "\n" + "PIDFILE=/var/run/tdmdesktop-$DISPLAY.pid\n" + "if [[] -f $PIDFILE ] ; then\n" + " kill `cat $PIDFILE`\n" + "fi\n" ) || + delstr( file, "\n" + "PIDFILE=/var/run/tdmdesktop-$DISPLAY.pid\n" + "test -f $PIDFILE && kill `cat $PIDFILE`\n" ))) + chg1 = 1; + if (oldver < 0x0203) { + chg2 = +#ifdef _AIX + delstr( file, "\n" +"# We create a pseudodevice for finger. (host:0 becomes [kx]dm/host_0)\n" ); +"# Without it, finger errors out with \"Can't stat /dev/host:0\".\n" +"#\n" +"if [[] -f /usr/lib/X11/xdm/sessreg ]; then\n" +" devname=`echo $DISPLAY | /usr/bin/sed -e 's/[[]:\\.]/_/g' | /usr/bin/cut -c1-8`\n" +" hostname=`echo $DISPLAY | /usr/bin/cut -d':' -f1`\n" +"\n" +" if [[] -z \"$devname\" ]; then\n" +" devname=\"unknown\"\n" +" fi\n" +" if [[] ! -d /dev/[kx]dm ]; then\n" +" /usr/bin/mkdir /dev/[kx]dm\n" +" /usr/bin/chmod 755 /dev/[kx]dm\n" +" fi\n" +" /usr/bin/touch /dev/[kx]dm/$devname\n" +" /usr/bin/chmod 644 /dev/[kx]dm/$devname\n" +"\n" +" if [[] -z \"$hostname\" ]; then\n" +" exec /usr/lib/X11/xdm/sessreg -a -l [kx]dm/$devname $USER\n" +" else\n" +" exec /usr/lib/X11/xdm/sessreg -a -l [kx]dm/$devname -h $hostname $USER\n" +" fi\n" +"fi\n") | +#else +# ifdef BSD + delstr( file, "\n" +"exec sessreg -a -l $DISPLAY -x */Xservers -u " _PATH_UTMP " $USER\n" ) | +# endif +#endif /* _AIX */ + delstr( file, "\n" +"exec sessreg -a -l $DISPLAY" +#ifdef BSD +" -x */Xservers" +#endif +" $USER\n" ) | + delstr( file, "\n" +"exec sessreg -a -l $DISPLAY -u /var/run/utmp -x */Xservers $USER\n" ); + putval( "UseSessReg", chg2 ? "true" : "false"); + } + return chg1 | chg2; +} + +static void +mk_startup( Entry *ce, Section *cs ) +{ + setsect( cs->name ); + if (old_scripts || mixed_scripts) + linkfile( ce ); + else { + if (ce->active && inNewDir( ce->value )) { + if (mod_usebg || oldver < 0x0203) + copyfile( ce, ce->value, 0755, edit_startup ); + else + linkfile( ce ); + } else { + ce->value = TDMCONF "/Xstartup"; + ce->active = ce->written = 1; + writefile( ce->value, 0755, def_startup ); + } + } +} + +static int +edit_reset( File *file ) +{ + return +#ifdef _AIX + delstr( file, "\n" +"if [[] -f /usr/lib/X11/xdm/sessreg ]; then\n" +" devname=`echo $DISPLAY | /usr/bin/sed -e 's/[[]:\\.]/_/g' | /usr/bin/cut -c1-8`\n" +" exec /usr/lib/X11/xdm/sessreg -d -l [kx]dm/$devname $USER\n" +"fi\n" ) | +#else +# ifdef BSD + delstr( file, "\n" +"exec sessreg -d -l $DISPLAY -x */Xservers -u " _PATH_UTMP " $USER\n" ) | +# endif +#endif /* _AIX */ + delstr( file, "\n" +"exec sessreg -d -l $DISPLAY" +# ifdef BSD +" -x */Xservers" +# endif +" $USER\n" ) | + delstr( file, "\n" +"exec sessreg -d -l $DISPLAY -u /var/run/utmp -x */Xservers $USER\n" ); +} + +static void +mk_reset( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (old_scripts || mixed_scripts) + linkfile( ce ); + else { + if (ce->active && inNewDir( ce->value )) { + if (oldver < 0x0203) + copyfile( ce, ce->value, 0755, edit_reset ); + else + linkfile( ce ); + } else { + ce->value = TDMCONF "/Xreset"; + ce->active = ce->written = 1; + writefile( ce->value, 0755, def_reset ); + } + } +} + +static void +mk_session( Entry *ce, Section *cs ATTR_UNUSED ) +{ + char *def_session; + const char *tmpf; + + if ((old_scripts || (ce->active && inNewDir( ce->value ))) && + oldver >= 0x202) + linkfile( ce ); + else { + tmpf = locate( "mktemp" ) ? + "`mktemp /tmp/xsess-env-XXXXXX`" : + locate( "tempfile" ) ? + "`tempfile`" : + "$HOME/.xsession-env-$DISPLAY"; + ASPrintf( &def_session, "%s%s%s", def_session1, tmpf, def_session2 ); + ce->value = TDMCONF "/Xsession"; + ce->active = ce->written = 1; + writefile( ce->value, 0755, def_session ); + } +} + +static void +upd_language( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!strcmp( ce->value, "C" )) + ce->value = (char *)"en_US"; +} + +static void +upd_guistyle( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!strcmp( ce->value, "Motif+" )) + ce->value = (char *)"MotifPlus"; + else if (!strcmp( ce->value, "KDE" )) + ce->value = (char *)"Default"; +} + +static void +upd_showusers( Entry *ce, Section *cs ) +{ + if (!strcmp( ce->value, "All" )) + ce->value = (char *)"NotHidden"; + else if (!strcmp( ce->value, "None" )) { + if (ce->active) + putfqval( cs->name, "UserList", "false" ); + ce->value = (char *)"Selected"; + ce->active = 0; + ce->written = 1; + } +} + +static const char *defminuid, *defmaxuid; + +static void +upd_minshowuid( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) { + ce->value = defminuid; + ce->active = ce->written = 1; + } +} + +static void +upd_maxshowuid( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) { + ce->value = defmaxuid; + ce->active = ce->written = 1; + } +} + +static void +upd_hiddenusers( Entry *ce, Section *cs ATTR_UNUSED ) +{ + char *nv; + const char *msu, *pt, *et; + struct passwd *pw; + unsigned minuid, maxuid; + char nbuf[128]; + + if (!ce->active) + return; + + msu = getfqval( cs->name, "MinShowUID", "0" ); + sscanf( msu, "%u", &minuid ); + msu = getfqval( cs->name, "MaxShowUID", "65535" ); + sscanf( msu, "%u", &maxuid ); + + nv = 0; + pt = ce->value; + for (;;) { + et = strpbrk( pt, ";," ); + if (et) { + memcpy( nbuf, pt, et - pt ); + nbuf[et - pt] = 0; + } else + strcpy( nbuf, pt ); + if ((pw = getpwnam( nbuf ))) { + if (!pw->pw_uid || + (pw->pw_uid >= minuid && pw->pw_uid <= maxuid)) + { + if (nv) + StrCat( &nv, ",%s", nbuf ); + else + nv = mstrdup( nbuf ); + } + } + if (!et) + break; + pt = et + 1; + } + ce->value = nv ? nv : ""; +} + +static void +upd_forgingseed( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) { + ASPrintf( (char **)&ce->value, "%d", time( 0 ) ); + ce->active = ce->written = 1; + } +} + +static void +upd_fifodir( Entry *ce, Section *cs ATTR_UNUSED ) +{ + const char *dir; + struct stat st; + + if (use_destdir) + return; + dir = ce->active ? ce->value : def_FifoDir; + stat( dir, &st ); + chmod( dir, st.st_mode | 0755 ); +} + +static void +upd_datadir( Entry *ce, Section *cs ATTR_UNUSED ) +{ + char *oldsts, *newsts; + const char *dir; + + if (use_destdir) + return; + dir = ce->active ? ce->value : def_DataDir; + if (mkdirp( dir, 0755, "data", 0 ) && oldkde) { + ASPrintf( &oldsts, "%s/tdm/tdmsts", oldkde ); + ASPrintf( &newsts, "%s/tdmsts", dir ); + rename( oldsts, newsts ); + } +} + +static void +CopyFile( const char *from, const char *to ) +{ + File file; + int fd; + + if (readFile( &file, from )) { + if ((fd = creat( to, 0644 )) >= 0) { + write( fd, file.buf, file.eof - file.buf ); + close( fd ); + } + freeBuf( &file ); + } +} + +static void +upd_facedir( Entry *ce, Section *cs ATTR_UNUSED ) +{ + char *oldpic, *newpic, *defpic, *rootpic; + const char *dir; + struct passwd *pw; + + if (use_destdir) + return; + dir = ce->active ? ce->value : def_FaceDir; + if (mkdirp( dir, 0755, "user face", 0 )) { + ASPrintf( &defpic, "%s/.default.face.icon", dir ); + ASPrintf( &rootpic, "%s/root.face.icon", dir ); + if (oldkde) { + setpwent(); + while ((pw = getpwent())) + if (strcmp( pw->pw_name, "root" )) { + ASPrintf( &oldpic, "%s/../apps/tdm/pics/users/%s.png", + oldkde, pw->pw_name ); + ASPrintf( &newpic, "%s/%s.face.icon", dir, pw->pw_name ); + rename( oldpic, newpic ); + free( newpic ); + free( oldpic ); + } + endpwent(); + ASPrintf( &oldpic, "%s/../apps/tdm/pics/users/default.png", oldkde ); + if (!rename( oldpic, defpic )) + defpic = 0; + ASPrintf( &oldpic, "%s/../apps/tdm/pics/users/root.png", oldkde ); + if (!rename( oldpic, rootpic )) + rootpic = 0; + } + if (defpic) { + ASPrintf( &oldpic, "%s/default1.png", facesrc ); + CopyFile( oldpic, defpic ); + } + if (rootpic) { + ASPrintf( &oldpic, "%s/root1.png", facesrc ); + CopyFile( oldpic, rootpic ); + } + } +} + +CONF_GEN_ENTRIES + +static Sect * +findSect( const char *name ) +{ + const char *p; + int i; + + p = strrchr( name, '-' ); + if (!p) + p = name; + for (i = 0; i < as(allSects); i++) + if (!strcmp( allSects[i]->name, p )) + return allSects[i]; + fprintf( stderr, "Internal error: unknown section %s\n", name ); + exit( 1 ); +} + +static Ent * +findEnt( Sect *sect, const char *key ) +{ + int i; + + for (i = 0; i < sect->nents; i++) + if (!strcmp( sect->ents[i].key, key )) + return sect->ents + i; + fprintf( stderr, "Internal error: unknown key %s in section %s\n", + key, sect->name ); + exit( 1 ); +} + + +/* + * defaults + */ + +typedef struct DEnt { + const char *key; + const char *value; + int active; +} DEnt; + +typedef struct DSect { + const char *name; + DEnt *ents; + int nents; + const char *comment; +} DSect; + +CONF_GEN_EXAMPLE + +static void +mkdefconf( void ) +{ + Section *cs, **csp; + Entry *ce, **cep; + int sc, ec; + + for (csp = &config, sc = 0; sc < as(dAllSects); csp = &(cs->next), sc++) { + cs = mcalloc( sizeof(*cs) ); + *csp = cs; + cs->spec = findSect( dAllSects[sc].name ); + cs->name = dAllSects[sc].name; + cs->comment = dAllSects[sc].comment; + for (cep = &(cs->ents), ec = 0; ec < dAllSects[sc].nents; + cep = &(ce->next), ec++) + { + ce = mcalloc( sizeof(*ce) ); + *cep = ce; + ce->spec = findEnt( cs->spec, dAllSects[sc].ents[ec].key ); + ce->value = dAllSects[sc].ents[ec].value; + ce->active = dAllSects[sc].ents[ec].active; + } + } +} + + +/* + * read rc file structure + */ + +typedef struct REntry { + struct REntry *next; + const char *key; + char *value; +} REntry; + +typedef struct RSection { + struct RSection *next; + const char *name; + REntry *ents; +} RSection; + +static RSection * +ReadConf( const char *fname ) +{ + char *nstr; + char *s, *e, *st, *en, *ek, *sl; + RSection *rootsec = 0, *cursec; + REntry *curent; + int nlen; + int line, sectmoan; + File file; + + if (!readFile( &file, fname )) + return 0; + usedFile( fname ); + + for (s = file.buf, line = 0, cursec = 0, sectmoan = 1; s < file.eof; s++) { + line++; + + while ((s < file.eof) && isspace( *s ) && (*s != '\n')) + s++; + + if ((s < file.eof) && ((*s == '\n') || (*s == '#'))) { + sktoeol: + while ((s < file.eof) && (*s != '\n')) + s++; + continue; + } + sl = s; + + if (*s == '[') { + while ((s < file.eof) && (*s != '\n')) + s++; + e = s - 1; + while ((e > sl) && isspace( *e )) + e--; + if (*e != ']') { + fprintf( stderr, "Invalid section header at %s:%d\n", + fname, line ); + continue; + } + sectmoan = 0; + nstr = sl + 1; + nlen = e - nstr; + for (cursec = rootsec; cursec; cursec = cursec->next) + if (!memcmp( nstr, cursec->name, nlen ) && + !cursec->name[nlen]) + { +#if 0 /* not our business ... */ + fprintf( stderr, "Warning: Multiple occurrences of section " + "[%.*s] in %s. Consider merging them.\n", + nlen, nstr, fname ); +#endif + goto secfnd; + } + cursec = mmalloc( sizeof(*cursec) ); + ASPrintf( (char **)&cursec->name, "%.*s", nlen, nstr ); + cursec->ents = 0; + cursec->next = rootsec; + rootsec = cursec; + secfnd: + continue; + } + + if (!cursec) { + if (sectmoan) { + sectmoan = 0; + fprintf( stderr, "Entry outside any section at %s:%d", + fname, line ); + } + goto sktoeol; + } + + for (; (s < file.eof) && (*s != '\n'); s++) + if (*s == '=') + goto haveeq; + fprintf( stderr, "Invalid entry (missing '=') at %s:%d\n", fname, line ); + continue; + + haveeq: + for (ek = s - 1;; ek--) { + if (ek < sl) { + fprintf( stderr, "Invalid entry (empty key) at %s:%d\n", + fname, line ); + goto sktoeol; + } + if (!isspace( *ek )) + break; + } + + s++; + while ((s < file.eof) && isspace( *s ) && (*s != '\n')) + s++; + st = s; + while ((s < file.eof) && (*s != '\n')) + s++; + for (en = s - 1; en >= st && isspace( *en ); en--); + + nstr = sl; + nlen = ek - sl + 1; + for (curent = cursec->ents; curent; curent = curent->next) + if (!memcmp( nstr, curent->key, nlen ) && + !curent->key[nlen]) { + fprintf( stderr, "Multiple occurrences of key '%s' in section " + "[%s] of %s.\n", curent->key, cursec->name, fname ); + goto keyfnd; + } + curent = mmalloc( sizeof(*curent) ); + ASPrintf( (char **)&curent->key, "%.*s", nlen, nstr ); + ASPrintf( (char **)&curent->value, "%.*s", en - st + 1, st ); + curent->next = cursec->ents; + cursec->ents = curent; + keyfnd: + continue; + } + return rootsec; +} + + +static int +mergeKdmRcOld( const char *path ) +{ + char *p; + struct stat st; + + ASPrintf( &p, "%s/tdmrc", path ); + if (stat( p, &st )) { + free( p ); + return 0; + } + printf( "Information: ignoring old tdmrc %s from kde < 2.2\n", p ); + free( p ); + return 1; +} + +typedef struct { + const char *sect, *key, *def; + int (*cond)( void ); +} FDefs; + +static void +applydefs( FDefs *chgdef, int ndefs, const char *path ) +{ + char *p; + int i; + + for (i = 0; i < ndefs; i++) + if (!getfqval( chgdef[i].sect, chgdef[i].key, 0 ) && + (!chgdef[i].cond || chgdef[i].cond())) + { + ASPrintf( &p, chgdef[i].def, path ); + putfqval( chgdef[i].sect, chgdef[i].key, p ); + free( p ); + } +} + +#ifdef XDMCP +static FDefs tdmdefs_all[] = { +{ "Xdmcp", "Xaccess", "%s/tdm/Xaccess", 0 }, +{ "Xdmcp", "Willing", "", 0 }, +}; +#endif + +static FDefs tdmdefs_eq_22[] = { +{ "General", "PidFile", "/var/run/xdm.pid", 0 }, +{ "X-*-Core", "Setup", "%s/tdm/Xsetup", 0 }, +{ "X-*-Core", "Startup", "%s/tdm/Xstartup", 0 }, +{ "X-*-Core", "Reset", "%s/tdm/Xreset", 0 }, +{ "X-*-Core", "Session", "%s/tdm/Xsession", 0 }, +}; + +#ifdef XDMCP +static int +if_xdmcp (void) +{ + return isTrue( getfqval( "Xdmcp", "Enable", "true" ) ); +} + +static FDefs tdmdefs_le_30[] = { +{ "Xdmcp", "KeyFile", "%s/tdm/tdmkeys", if_xdmcp }, +}; +#endif + +/* HACK: misused by is22conf() below */ +static FDefs tdmdefs_ge_30[] = { +{ "X-*-Core", "Setup", "", 0 }, +{ "X-*-Core", "Startup", "", 0 }, +{ "X-*-Core", "Reset", "", 0 }, +{ "X-*-Core", "Session", XBINDIR "/xterm -ls -T", 0 }, +}; + +static int +if_usebg (void) +{ + return isTrue( getfqval( "X-*-Greeter", "UseBackground", "true" ) ); +} + +static FDefs tdmdefs_ge_31[] = { +{ "X-*-Greeter","BackgroundCfg","%s/tdm/backgroundrc", if_usebg }, +}; + +static int +is22conf( const char *path ) +{ + char *p; + const char *val; + int i, sl; + + sl = ASPrintf( &p, "%s/tdm/", path ); + /* safe bet, i guess ... */ + for (i = 0; i < 4; i++) { + val = getfqval( "X-*-Core", tdmdefs_ge_30[i].key, 0 ); + if (val && !memcmp( val, p, sl )) { + free( p ); + return 0; + } + } + free( p ); + return 1; +} + +typedef struct KUpdEnt { + const char *okey, *nsec, *nkey; + void (*func)( const char *sect, char **value ); +} KUpdEnt; + +typedef struct KUpdSec { + const char *osec; + KUpdEnt *ents; + int nents; +} KUpdSec; + +#ifdef XDMCP +static void +P_EnableChooser( const char *sect ATTR_UNUSED, char **value ) +{ + *value = (char *)(isTrue( *value ) ? "DefaultLocal" : "LocalOnly"); +} +#endif + +static void +P_UseLilo( const char *sect ATTR_UNUSED, char **value ) +{ + *value = (char *)(isTrue( *value ) ? "Lilo" : "None"); +} + +CONF_GEN_KMERGE + +static int +mergeKdmRcNewer( const char *path ) +{ + char *p; + const char *cp, *sec, *key; + RSection *rootsect, *cs; + REntry *ce; + int i, j; + static char sname[64]; + + ASPrintf( &p, "%s/tdm/tdmrc", path ); + if (!(rootsect = ReadConf( p ))) { + free( p ); + return 0; + } + printf( "Information: reading current tdmrc %s (from kde >= 2.2.x)\n", p ); + free( p ); + + for (cs = rootsect; cs; cs = cs->next) { + if (!strcmp( cs->name, "Desktop0" )) { + background = mstrdup( "[Desktop0]\n" ); + for (ce = cs->ents; ce; ce = ce->next) + StrCat( &background, "%s=%s\n", ce->key, ce->value ); + } else { + cp = strrchr( cs->name, '-' ); + if (!cp) + cp = cs->name; + else if (cs->name[0] != 'X' || cs->name[1] != '-') + goto dropsec; + for (i = 0; i < as(kupsects); i++) + if (!strcmp( cp, kupsects[i].osec )) { + for (ce = cs->ents; ce; ce = ce->next) { + for (j = 0; j < kupsects[i].nents; j++) + if (!strcmp( ce->key, kupsects[i].ents[j].okey )) { + if (kupsects[i].ents[j].nsec == (char *)-1) { + kupsects[i].ents[j].func( 0, &ce->value ); + goto gotkey; + } + if (!kupsects[i].ents[j].nsec) + sec = cs->name; + else { + sec = sname; + sprintf( sname, "%.*s-%s", cp - cs->name, cs->name, + kupsects[i].ents[j].nsec ); + } + if (!kupsects[i].ents[j].nkey) + key = ce->key; + else + key = kupsects[i].ents[j].nkey; + if (kupsects[i].ents[j].func) + kupsects[i].ents[j].func( sec, &ce->value ); + putfqval( sec, key, ce->value ); + goto gotkey; + } + printf( "Information: dropping key %s from section [%s]\n", + ce->key, cs->name ); + gotkey: ; + } + goto gotsec; + } + dropsec: + printf( "Information: dropping section [%s]\n", cs->name ); + gotsec: ; + } + } + +#ifdef XDMCP + applydefs( tdmdefs_all, as(tdmdefs_all), path ); +#endif + if (!*(cp = getfqval( "General", "ConfigVersion", "" ))) { /* < 3.1 */ + mod_usebg = 1; + if (is22conf( path )) { + /* work around 2.2.x defaults borkedness */ + applydefs( tdmdefs_eq_22, as(tdmdefs_eq_22), path ); + printf( "Information: current tdmrc is from kde 2.2\n" ); + } else { + applydefs( tdmdefs_ge_30, as(tdmdefs_ge_30), path ); + printf( "Information: current tdmrc is from kde 3.0\n" ); + } +#ifdef XDMCP + /* work around minor <= 3.0.x defaults borkedness */ + applydefs( tdmdefs_le_30, as(tdmdefs_le_30), path ); +#endif + } else { + int ma, mi; + sscanf( cp, "%d.%d", &ma, &mi ); + oldver = (ma << 8) | mi; + printf( "Information: current tdmrc is from kde >= 3.1 (config version %d.%d)\n", ma, mi ); + applydefs( tdmdefs_ge_30, as(tdmdefs_ge_30), path ); + applydefs( tdmdefs_ge_31, as(tdmdefs_ge_31), path ); + } + + return 1; +} + + +typedef struct XResEnt { + const char *xname; + const char *ksec, *kname; + void (*func)( const char *sect, char **value ); +} XResEnt; + +static void +handleXdmVal( const char *dpy, const char *key, char *value, + const XResEnt *ents, int nents ) +{ + const char *kname; + int i; + char knameb[80], sname[80]; + + for (i = 0; i < nents; i++) + if (!strcmp( key, ents[i].xname ) || + (key[0] == toupper( ents[i].xname[0] ) && + !strcmp( key + 1, ents[i].xname + 1 ))) + { + if (ents[i].ksec == (char *)-1) { + ents[i].func (0, &value); + break; + } + sprintf( sname, ents[i].ksec, dpy ); + if (ents[i].kname) + kname = ents[i].kname; + else { + kname = knameb; + sprintf( knameb, "%c%s", + toupper( ents[i].xname[0] ), ents[i].xname + 1 ); + } + if (ents[i].func) + ents[i].func( sname, &value ); + putfqval( sname, kname, value ); + break; + } +} + +static void +P_List( const char *sect ATTR_UNUSED, char **value ) +{ + int is, d, s; + char *st; + + for (st = *value, is = d = s = 0; st[s]; s++) + if (st[s] == ' ' || st[s] == '\t') { + if (!is) + st[d++] = ','; + is = 1; + } else { + st[d++] = st[s]; + is = 0; + } + st[d] = 0; +} + +static void +P_authDir( const char *sect ATTR_UNUSED, char **value ) +{ + int l; + + l = strlen( *value ); + if (l < 4) { + *value = 0; + return; + } + if ((*value)[l-1] == '/') + (*value)[--l] = 0; + if (!strncmp( *value, "/tmp/", 5 ) || + !strncmp( *value, "/var/tmp/", 9 )) + { + printf( "Warning: Resetting inappropriate value %s for AuthDir to default\n", + *value ); + *value = 0; + return; + } + if ((l >= 4 && !strcmp( *value + l - 4, "/tmp" )) || + (l >= 6 && !strcmp( *value + l - 6, "/xauth" )) || + (l >= 8 && !strcmp( *value + l - 8, "/authdir" )) || + (l >= 10 && !strcmp( *value + l - 10, "/authfiles" ))) + return; + ASPrintf( value, "%s/authdir", *value ); +} + +static void +P_openDelay( const char *sect, char **value ) +{ + putfqval( sect, "ServerTimeout", *value ); +} + +static void +P_noPassUsers( const char *sect, char **value ATTR_UNUSED ) +{ + putfqval( sect, "NoPassEnable", "true" ); +} + +static void +P_autoUser( const char *sect, char **value ATTR_UNUSED ) +{ + putfqval( sect, "AutoLoginEnable", "true" ); +} + +#ifdef XDMCP +static void +P_requestPort( const char *sect, char **value ) +{ + if (!strcmp( *value, "0" )) { + *value = 0; + putfqval( sect, "Enable", "false" ); + } else + putfqval( sect, "Enable", "true" ); +} +#endif + +static int tdmrcmode = 0644; + +static void +P_autoPass( const char *sect ATTR_UNUSED, char **value ATTR_UNUSED ) +{ + tdmrcmode = 0600; +} + +CONF_GEN_XMERGE + +static XrmQuark XrmQString, empty = NULLQUARK; + +static Bool +DumpEntry( XrmDatabase *db ATTR_UNUSED, + XrmBindingList bindings, + XrmQuarkList quarks, + XrmRepresentation *type, + XrmValuePtr value, + XPointer data ATTR_UNUSED ) +{ + const char *dpy, *key; + int el, hasu; + char dpybuf[80]; + + if (*type != XrmQString) + return False; + if (*bindings == XrmBindLoosely || + strcmp( XrmQuarkToString (*quarks), "DisplayManager" )) + return False; + bindings++, quarks++; + if (!*quarks) + return False; + if (*bindings != XrmBindLoosely && !quarks[1]) { /* DM.foo */ + key = XrmQuarkToString (*quarks); + handleXdmVal( 0, key, value->addr, globents, as(globents) ); + return False; + } else if (*bindings == XrmBindLoosely && !quarks[1]) { /* DM*bar */ + dpy = "*"; + key = XrmQuarkToString (*quarks); + } else if (*bindings != XrmBindLoosely && quarks[1] && + *bindings != XrmBindLoosely && !quarks[2]) + { /* DM.foo.bar */ + dpy = dpybuf + 4; + strcpy( dpybuf + 4, XrmQuarkToString (*quarks) ); + for (hasu = 0, el = 4; dpybuf[el]; el++) + if (dpybuf[el] == '_') + hasu = 1; + if (!hasu/* && isupper (dpy[0])*/) { + dpy = dpybuf; + memcpy( dpybuf, "*:*_", 4 ); + } else { + for (; --el >= 0; ) + if (dpybuf[el] == '_') { + dpybuf[el] = ':'; + for (; --el >= 4; ) + if (dpybuf[el] == '_') + dpybuf[el] = '.'; + break; + } + } + key = XrmQuarkToString (quarks[1]); + } else + return False; + handleXdmVal( dpy, key, value->addr, dpyents, as(dpyents) ); + return False; +} + +static FDefs xdmdefs[] = { +#ifdef XDMCP +{ "Xdmcp", "Xaccess", "%s/Xaccess", 0 }, +{ "Xdmcp", "Willing", "", 0 }, +#endif +{ "X-*-Core", "Setup", "", 0 }, +{ "X-*-Core", "Startup", "", 0 }, +{ "X-*-Core", "Reset", "", 0 }, +{ "X-*-Core", "Session", "", 0 }, +}; + +static int +mergeXdmCfg( const char *path ) +{ + char *p; + XrmDatabase db; + + ASPrintf( &p, "%s/xdm-config", path ); + if ((db = XrmGetFileDatabase( p ))) { + printf( "Information: reading current xdm config file %s\n", p ); + usedFile( p ); + free( p ); + XrmEnumerateDatabase( db, &empty, &empty, XrmEnumAllLevels, + DumpEntry, (XPointer)0 ); + applydefs( xdmdefs, as(xdmdefs), path ); + mod_usebg = 1; + return 1; + } + free( p ); + return 0; +} + +static void +fwrapprintf( FILE *f, const char *msg, ... ) +{ + char *txt, *ftxt, *line; + va_list ap; + int col, lword, fspace; + + va_start( ap, msg ); + VASPrintf( &txt, msg, ap ); + va_end( ap ); + ftxt = 0; + for (line = txt, col = 0, lword = fspace = -1; line[col]; ) { + if (line[col] == '\n') { + StrCat( &ftxt, "%.*s", ++col, line ); + line += col; + col = 0; + lword = fspace = -1; + continue; + } else if (line[col] == ' ') { + if (lword >= 0) { + fspace = col; + lword = -1; + } + } else { + if (lword < 0) + lword = col; + if (col >= 78 && fspace >= 0) { + StrCat( &ftxt, "%.*s\n", fspace, line ); + line += lword; + col -= lword; + lword = 0; + fspace = -1; + } + } + col++; + } + free( txt ); + fputs( ftxt, f ); + free( ftxt ); +} + + +static const char *oldkdes[] = { + KDE_CONFDIR, + "/opt/trinity/share/config", + "/usr/local/trinity/share/config", + + "/opt/kde/share/config", + "/usr/local/kde/share/config", + "/usr/local/share/config", + "/usr/share/config", + + "/opt/kde2/share/config", + "/usr/local/kde2/share/config", +}; + +static const char *oldxdms[] = { + "/etc/X11/xdm", + XLIBDIR "/xdm", +}; + +int main( int argc, char **argv ) +{ + const char **where; + char *newtdmrc; + FILE *f; + StrList *fp; + Section *cs; + Entry *ce, **cep; + int i, ap, newer, locals, foreigns; + int no_old_xdm = 0, no_old_kde = 0; + struct stat st; + char *nname; + + for (ap = 1; ap < argc; ap++) { + if (!strcmp( argv[ap], "--help" )) { + printf( +"gentdmconf - generate configuration files for tdm\n" +"\n" +"If an older xdm/tdm configuration is found, its config files are \"absorbed\";\n" +"if it lives in the new target directory, its scripts are reused (and possibly\n" +"modified) as well, otherwise the scripts are ignored and default scripts are\n" +"installed.\n" +"\n" +"options:\n" +" --in /path/to/new/tdm-config-dir\n" +" In which directory to put the new configuration. You can use this\n" +" to support a $(DESTDIR), but not to change the final location of\n" +" the installation - the paths inside the files are not affected.\n" +" Default is " TDMCONF ".\n" +" --old-xdm /path/to/old/xdm-dir\n" +" Where to look for the config files of an xdm/older tdm.\n" +" Default is to scan /etc/X11/tdm, $XLIBDIR/tdm, /etc/X11/xdm,\n" +" $XLIBDIR/xdm; there in turn look for tdm-config and xdm-config.\n" +" Note that you possibly need to use --no-old-kde to make this take effect.\n" +" --old-kde /path/to/old/kde-config-dir\n" +" Where to look for the tdmrc of an older tdm.\n" +" Default is to scan " KDE_CONFDIR " and\n" +" {/usr,/usr/local,{/opt,/usr/local}/{trinity,kde,kde2,kde1}}/share/config.\n" +" --no-old\n" +" Don't look at older xdm/tdm configurations, just create default config.\n" +" --no-old-xdm\n" +" Don't look at older xdm configurations.\n" +" --no-old-kde\n" +" Don't look at older tdm configurations.\n" +" --old-scripts\n" +" Directly use all scripts from the older xdm/tdm configuration.\n" +" --no-old-scripts\n" +" Don't use scripts from the older xdm/tdm configuration even if it lives\n" +" in the new target directory.\n" +" --old-confs\n" +" Directly use all ancillary config files from the older xdm/tdm\n" +" configuration. This is usually a bad idea.\n" +" --no-backup\n" +" Overwrite/delete old config files instead of backing them up.\n" +" --no-in-notice\n" +" Don't put the notice about --in being used into the generated README.\n" +); + exit( 0 ); + } + if (!strcmp( argv[ap], "--no-old" )) { + no_old = 1; + continue; + } + if (!strcmp( argv[ap], "--old-scripts" )) { + old_scripts = 1; + continue; + } + if (!strcmp( argv[ap], "--no-old-scripts" )) { + no_old_scripts = 1; + continue; + } + if (!strcmp( argv[ap], "--old-confs" )) { + old_confs = 1; + continue; + } + if (!strcmp( argv[ap], "--no-old-xdm" )) { + no_old_xdm = 1; + continue; + } + if (!strcmp( argv[ap], "--no-old-kde" )) { + no_old_kde = 1; + continue; + } + if (!strcmp( argv[ap], "--no-backup" )) { + no_backup = 1; + continue; + } + if (!strcmp( argv[ap], "--no-in-notice" )) { + no_in_notice = 1; + continue; + } + where = 0; + if (!strcmp( argv[ap], "--in" )) + where = &newdir; + else if (!strcmp( argv[ap], "--old-xdm" )) + where = &oldxdm; + else if (!strcmp( argv[ap], "--old-kde" )) + where = &oldkde; + else if (!strcmp( argv[ap], "--face-src" )) + where = &facesrc; + else { + fprintf( stderr, "Unknown command line option '%s', try --help\n", argv[ap] ); + exit( 1 ); + } + if (ap + 1 == argc || argv[ap + 1][0] == '-') { + fprintf( stderr, "Missing argument to option '%s', try --help\n", argv[ap] ); + exit( 1 ); + } + *where = argv[++ap]; + } + if (memcmp( newdir, TDMCONF, sizeof(TDMCONF) )) + use_destdir = 1; + + if (!mkdirp( newdir, 0755, "target", 1 )) + exit( 1 ); + + mkdefconf(); + newer = 0; + if (no_old) { + DIR *dir; + if ((dir = opendir( newdir ))) { + struct dirent *ent; + char bn[PATH_MAX]; + while ((ent = readdir( dir ))) { + int l; + if (!strcmp( ent->d_name, "." ) || !strcmp( ent->d_name, ".." )) + continue; + l = sprintf( bn, "%s/%s", newdir, ent->d_name ); /* cannot overflow (kernel would not allow the creation of a longer path) */ + if (!stat( bn, &st ) && !S_ISREG( st.st_mode )) + continue; + if (no_backup || !memcmp( bn + l - 4, ".bak", 5 )) + unlink( bn ); + else + displace( bn ); + } + closedir( dir ); + } + } else { + if (oldkde) { + if (!(newer = mergeKdmRcNewer( oldkde )) && !mergeKdmRcOld( oldkde )) + fprintf( stderr, + "Cannot read old tdmrc at specified location\n" ); + } else if (!no_old_kde) { + for (i = 0; i < as(oldkdes); i++) { + if ((newer = mergeKdmRcNewer( oldkdes[i] )) || + mergeKdmRcOld( oldkdes[i] )) { + oldkde = oldkdes[i]; + break; + } + } + } + if (!newer && !no_old_xdm) { + XrmInitialize(); + XrmQString = XrmPermStringToQuark( "String" ); + if (oldxdm) { + if (!mergeXdmCfg( oldxdm )) + fprintf( stderr, + "Cannot read old tdm-config/xdm-config at specified location\n" ); + } else + for (i = 0; i < as(oldxdms); i++) + if (mergeXdmCfg( oldxdms[i] )) { + oldxdm = oldxdms[i]; + break; + } + } else + oldxdm = 0; + } + if (no_old_scripts) + goto no_old_s; + if (!old_scripts) { + locals = foreigns = 0; + for (cs = config; cs; cs = cs->next) + if (!strcmp( cs->spec->name, "-Core" )) { + for (ce = cs->ents; ce; ce = ce->next) + if (ce->active && + (!strcmp( ce->spec->key, "Setup" ) || + !strcmp( ce->spec->key, "Startup" ) || + !strcmp( ce->spec->key, "Reset" ))) + { + if (inNewDir( ce->value )) + locals = 1; + else + foreigns = 1; + } + } + if (foreigns) { + if (locals) { + fprintf( stderr, + "Warning: both local and foreign scripts referenced. " + "Won't touch any.\n" ); + mixed_scripts = 1; + } else { + no_old_s: + for (cs = config; cs; cs = cs->next) { + if (!strcmp( cs->spec->name, "Xdmcp" )) { + for (ce = cs->ents; ce; ce = ce->next) + if (!strcmp( ce->spec->key, "Willing" )) + ce->active = ce->written = 0; + } else if (!strcmp( cs->spec->name, "-Core" )) { + for (cep = &cs->ents; (ce = *cep); ) { + if (ce->active && + (!strcmp( ce->spec->key, "Setup" ) || + !strcmp( ce->spec->key, "Startup" ) || + !strcmp( ce->spec->key, "Reset" ) || + !strcmp( ce->spec->key, "Session" ))) + { + if (!memcmp( cs->name, "X-*-", 4 )) + ce->active = ce->written = 0; + else { + *cep = ce->next; + free( ce ); + continue; + } + } + cep = &ce->next; + } + } + } + } + } + } +#ifdef __linux__ + if (!stat( "/etc/debian_version", &st )) { /* debian */ + defminuid = "1000"; + defmaxuid = "29999"; + } else if (!stat( "/usr/portage", &st )) { /* gentoo */ + defminuid = "1000"; + defmaxuid = "65000"; + } else if (!stat( "/etc/mandrake-release", &st )) { /* mandrake - check before redhat! */ + defminuid = "500"; + defmaxuid = "65000"; + } else if (!stat( "/etc/redhat-release", &st )) { /* redhat */ + defminuid = "100"; + defmaxuid = "65000"; + } else /* if (!stat( "/etc/SuSE-release", &st )) */ { /* suse */ + defminuid = "500"; + defmaxuid = "65000"; + } +#else + defminuid = "1000"; + defmaxuid = "65000"; +#endif + for (i = 0; i < CONF_MAX_PRIO; i++) + for (cs = config; cs; cs = cs->next) + for (ce = cs->ents; ce; ce = ce->next) + if (ce->spec->func && i == ce->spec->prio) + ce->spec->func( ce, cs ); + ASPrintf( &newtdmrc, "%s/tdmrc", newdir ); + f = Create( newtdmrc, tdmrcmode ); + wrconf( f ); + fclose( f ); + + ASPrintf( &nname, "%s/README", newdir ); + f = Create( nname, 0644 ); + fprintf( f, +"This automatically generated configuration consists of the following files:\n" ); + fprintf( f, "- " TDMCONF "/tdmrc\n" ); + for (fp = aflist; fp; fp = fp->next) + fprintf( f, "- %s\n", fp->str ); + if (use_destdir && !no_in_notice) + fwrapprintf( f, +"All files destined for " TDMCONF " were actually saved in %s; " +"this config won't be workable until moved in place.\n", newdir ); + if (uflist || eflist || cflist || lflist) { + fprintf( f, +"\n" +"This config was derived from existing files. As the used algorithms are\n" +"pretty dumb, it may be broken.\n" ); + if (uflist) { + fprintf( f, +"Information from these files was extracted:\n" ); + for (fp = uflist; fp; fp = fp->next) + fprintf( f, "- %s\n", fp->str ); + } + if (lflist) { + fprintf( f, +"These files were directly incorporated:\n" ); + for (fp = lflist; fp; fp = fp->next) + fprintf( f, "- %s\n", fp->str ); + } + if (cflist) { + fprintf( f, +"These files were copied verbatim:\n" ); + for (fp = cflist; fp; fp = fp->next) + fprintf( f, "- %s\n", fp->str ); + } + if (eflist) { + fprintf( f, +"These files were copied with modifications:\n" ); + for (fp = eflist; fp; fp = fp->next) + fprintf( f, "- %s\n", fp->str ); + } + if (!no_backup && !use_destdir) + fprintf( f, +"Old files that would have been overwritten were renamed to .bak.\n" ); + } + fprintf( f, +"\nTry 'gentdmconf --help' if you want to generate another configuration.\n" +"\nYou may delete this README.\n" ); + fclose( f ); + + return 0; +} diff --git a/tdm/kfrontend/kchooser.cpp b/tdm/kfrontend/kchooser.cpp new file mode 100644 index 000000000..00b08cd35 --- /dev/null +++ b/tdm/kfrontend/kchooser.cpp @@ -0,0 +1,227 @@ +/* + +chooser widget for TDM + +Copyright (C) 2002-2003 Oswald Buddenhagen +based on the chooser (C) 1999 by Harald Hoyer + +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 + +#ifdef XDMCP + +#include "kchooser.h" +#include "kconsole.h" +#include "tdmconfig.h" +#include "tdm_greet.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include // for free() + +class ChooserListViewItem : public TQListViewItem { + public: + ChooserListViewItem( TQListView* parent, int _id, const TQString& nam, const TQString& sts ) + : TQListViewItem( parent, nam, sts ) { id = _id; }; + + int id; +}; + + +ChooserDlg::ChooserDlg() + : inherited() +{ + completeMenu( LOGIN_REMOTE_ONLY, ex_greet, i18n("&Local Login"), ALT+Key_L ); + + TQBoxLayout *vbox = new TQVBoxLayout( this, 10, 10 ); + + TQLabel *title = new TQLabel( i18n("XDMCP Host Menu"), this ); + title->setAlignment( AlignCenter ); + vbox->addWidget( title ); + + host_view = new TQListView( this, "hosts" ); + host_view->addColumn( i18n("Hostname") ); + host_view->setColumnWidth( 0, fontMetrics().width( "login.crap.net" ) ); + host_view->addColumn( i18n("Status") ); + host_view->setMinimumWidth( fontMetrics().width( "login.crap.com Display not authorized to connect this server" ) ); + host_view->setResizeMode( TQListView::LastColumn ); + host_view->setAllColumnsShowFocus( true ); + vbox->addWidget( host_view ); + + iline = new TQLineEdit( this ); + iline->setEnabled( TRUE ); + TQLabel *itxt = new TQLabel( iline, i18n("Hos&t:"), this ); + TQPushButton *addButton = new TQPushButton( i18n("A&dd"), this ); + connect( addButton, TQT_SIGNAL(clicked()), TQT_SLOT(addHostname()) ); + TQBoxLayout *hibox = new TQHBoxLayout( vbox, 10 ); + hibox->addWidget( itxt ); + hibox->addWidget( iline ); + hibox->addWidget( addButton ); + + // Buttons + TQPushButton *acceptButton = new TQPushButton( i18n("&Accept"), this ); + acceptButton->setDefault( true ); + TQPushButton *pingButton = new TQPushButton( i18n("&Refresh"), this ); + + TQBoxLayout *hbox = new TQHBoxLayout( vbox, 20 ); + hbox->addWidget( acceptButton ); + hbox->addWidget( pingButton ); + hbox->addStretch( 1 ); + + if (optMenu) { + TQPushButton *menuButton = new TQPushButton( i18n("&Menu"), this ); + menuButton->setPopup( optMenu ); + hbox->addWidget( menuButton ); + hbox->addStretch( 1 ); + } + +// TQPushButton *helpButton = new TQPushButton( i18n("&Help"), this ); +// hbox->addWidget( helpButton ); + +#ifdef WITH_TDM_XCONSOLE + if (consoleView) + vbox->addWidget( consoleView ); +#endif + + sn = new TQSocketNotifier( rfd, TQSocketNotifier::Read, TQT_TQOBJECT(this) ); + connect( sn, TQT_SIGNAL(activated( int )), TQT_SLOT(slotReadPipe()) ); + + connect( pingButton, TQT_SIGNAL(clicked()), TQT_SLOT(pingHosts()) ); + connect( acceptButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); +// connect( helpButton, TQT_SIGNAL(clicked()), TQT_SLOT(slotHelp()) ); + connect( host_view, TQT_SIGNAL(doubleClicked(TQListViewItem *)), TQT_SLOT(accept()) ); + + adjustGeometry(); +} + +/* +void ChooserDlg::slotHelp() +{ + KMessageBox::information(0, + i18n("Choose a host, you want to work on,\n" + "in the list or add one.\n\n" + "After this box, you must press cancel\n" + "in the Host Menu to enter a host. :(")); + iline->setFocus(); +} +*/ + +void ChooserDlg::addHostname() +{ + if (!iline->text().isEmpty()) { + GSendInt( G_Ch_RegisterHost ); + GSendStr( iline->text().latin1() ); + iline->clear(); + } +} + +void ChooserDlg::pingHosts() +{ + GSendInt( G_Ch_Refresh ); +} + +void ChooserDlg::accept() +{ + if (focusWidget() == iline) { + if (!iline->text().isEmpty()) { + GSendInt( G_Ch_DirectChoice ); + GSendStr( iline->text().latin1() ); + iline->clear(); + } + return; + } else /*if (focusWidget() == host_view)*/ { + TQListViewItem *item = host_view->currentItem(); + if (item) { + GSendInt( G_Ready ); + GSendInt( ((ChooserListViewItem *)item)->id ); + ::exit( EX_NORMAL ); + } + } +} + +void ChooserDlg::reject() +{ +} + +TQString ChooserDlg::recvStr() +{ + char *arr = GRecvStr(); + if (arr) { + TQString str = TQString::fromLatin1( arr ); + free( arr ); + return str; + } else + return i18n(""); +} + +TQListViewItem *ChooserDlg::findItem( int id ) +{ + TQListViewItem *itm; + for (TQListViewItemIterator it( host_view ); (itm = it.current()); ++it) + if (((ChooserListViewItem *)itm)->id == id) + return itm; + return 0; +} + +void ChooserDlg::slotReadPipe() +{ + int id; + TQString nam, sts; + + int cmd = GRecvInt(); + switch (cmd) { + case G_Ch_AddHost: + case G_Ch_ChangeHost: + id = GRecvInt(); + nam = recvStr(); + sts = recvStr(); + GRecvInt(); /* swallow willing for now */ + if (cmd == G_Ch_AddHost) + host_view->insertItem( + new ChooserListViewItem( host_view, id, nam, sts ) ); + else { + TQListViewItem *itm = findItem( id ); + itm->setText( 0, nam ); + itm->setText( 1, sts ); + } + break; + case G_Ch_RemoveHost: + delete findItem( GRecvInt() ); + break; + case G_Ch_BadHost: + KFMsgBox::box( this, TQMessageBox::Warning, i18n("Unknown host %1").arg( recvStr() ) ); + break; + case G_Ch_Exit: + done( ex_exit ); + break; + default: /* XXX huuh ...? */ + break; + } +} + +#include "kchooser.moc" + +#endif diff --git a/tdm/kfrontend/kchooser.h b/tdm/kfrontend/kchooser.h new file mode 100644 index 000000000..fcf14b1e1 --- /dev/null +++ b/tdm/kfrontend/kchooser.h @@ -0,0 +1,59 @@ +/* + +chooser widget for TDM + +Copyright (C) 2002-2003 Oswald Buddenhagen +based on the chooser (C) 1999 by Harald Hoyer + +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. + +*/ + +#ifndef KCHOOSER_H +#define KCHOOSER_H + +#include "kgdialog.h" + +class TQSocketNotifier; +class TQPopupMenu; +class TQLineEdit; +class TQListView; +class TQListViewItem; + +class ChooserDlg : public KGDialog { + Q_OBJECT + typedef KGDialog inherited; + + public: + ChooserDlg(); + + public slots: + void slotReadPipe(); + void addHostname(); +// void slotHelp(); + void pingHosts(); + void accept(); + void reject(); + + private: + TQString recvStr(); + TQListViewItem *findItem( int id ); + + TQListView *host_view; + TQLineEdit *iline; + TQSocketNotifier *sn; +}; + +#endif /* KCHOOSER_H */ diff --git a/tdm/kfrontend/kconsole.cpp b/tdm/kfrontend/kconsole.cpp new file mode 100644 index 000000000..834507bdb --- /dev/null +++ b/tdm/kfrontend/kconsole.cpp @@ -0,0 +1,183 @@ +/* + +xconsole widget for TDM + +Copyright (C) 2002-2003 Oswald Buddenhagen + + +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 + +#ifdef WITH_TDM_XCONSOLE + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_TERMIOS_H +/* for HP-UX (some versions) the extern C is needed, and for other + platforms it doesn't hurt */ +extern "C" { +#include +} +#endif +#if !defined(__osf__) +#ifdef HAVE_TERMIO_H +/* needed at least on AIX */ +#include +#endif +#endif + +#if defined (_HPUX_SOURCE) +#define _TERMIOS_INCLUDED +#include +#endif + + +#include "kconsole.h" +#include "tdmconfig.h" +#include "tdm_greet.h" + +#include +#include + +#include + +KConsole::KConsole( TQWidget *_parent ) + : inherited( _parent ) + , pty( 0 ) + , notifier( 0 ) + , fd( -1 ) +{ + setReadOnly( true ); + setWordWrap( NoWrap ); + setTextFormat( PlainText ); + + if (!OpenConsole()) + append( i18n("Cannot open console") ); +} + +KConsole::~KConsole() +{ + CloseConsole(); +} + +int +KConsole::OpenConsole() +{ +#ifdef TIOCCONS + static const char on = 1; +#endif + + if (*_logSource) { + if ((fd = open( _logSource, O_RDONLY | O_NONBLOCK )) >= 0) + goto gotcon; + LogError( "Cannot open log source %s, " + "falling back to /dev/console.\n", _logSource ); + } + + pty = new KPty; + if (!pty->open()) { + delete pty; + pty = 0; + return 0; + } + +#ifdef TIOCCONS + if (ioctl( pty->slaveFd(), TIOCCONS, &on ) < 0) { + perror( "ioctl TIOCCONS" ); + delete pty; + pty = 0; + return 0; + } +#else + int consfd; + if ((consfd = open( "/dev/console", O_RDONLY )) < 0) { + perror( "opening /dev/console" ); + delete pty; + pty = 0; + return 0; + } + if (ioctl( consfd, SRIOCSREDIR, slave_fd ) < 0) { + perror( "ioctl SRIOCSREDIR" ); + ::close( consfd ); + delete pty; + pty = 0; + return 0; + } + ::close( consfd ); +#endif + fd = pty->masterFd(); + + gotcon: + notifier = new TQSocketNotifier( fd, TQSocketNotifier::Read, this ); + connect( notifier, TQT_SIGNAL(activated( int )), TQT_SLOT(slotData()) ); + return 1; +} + +void +KConsole::CloseConsole() +{ + delete notifier; + notifier = 0; + if (pty) { + delete pty; + pty = 0; + } else + ::close( fd ); + fd = -1; +} + +void +KConsole::slotData() +{ + int n; + char buffer[1024]; + + if ((n = read( fd, buffer, sizeof(buffer) )) <= 0) { + CloseConsole(); + if (!n) + if (!OpenConsole()) + append( i18n("\n*** Cannot open console log source ***") ); + } else { + bool as = !verticalScrollBar()->isVisible() || + (verticalScrollBar()->value() == + verticalScrollBar()->maxValue()); + TQString str( TQString::fromLocal8Bit( buffer, n ).remove( '\r' ) ); + int pos, opos; + for (opos = 0; (pos = str.find( '\n', opos )) >= 0; opos = pos + 1) { + if (paragraphs() == 100) + removeParagraph( 0 ); + if (!leftover.isEmpty()) { + append( leftover + str.mid( opos, pos - opos ) ); + leftover = TQString::null; + } else + append( str.mid( opos, pos - opos ) ); + } + leftover += str.mid( opos ); + if (as) + scrollToBottom(); + } +} + +#include "kconsole.moc" + +#endif diff --git a/tdm/kfrontend/kconsole.h b/tdm/kfrontend/kconsole.h new file mode 100644 index 000000000..2b3e2aac3 --- /dev/null +++ b/tdm/kfrontend/kconsole.h @@ -0,0 +1,53 @@ +/* + +xconsole widget for TDM + +Copyright (C) 2002-2003 Oswald Buddenhagen + + +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. + +*/ + +#ifndef KCONSOLE_H +#define KCONSOLE_H + +#include + +class TQSocketNotifier; +class KPty; + +class KConsole : public TQTextEdit { + Q_OBJECT + typedef TQTextEdit inherited; + + public: + KConsole( TQWidget *_parent = 0 ); + ~KConsole(); + + private slots: + void slotData(); + + private: + int OpenConsole(); + void CloseConsole(); + + KPty *pty; + TQSocketNotifier *notifier; + TQString leftover; + int fd; +}; + +#endif // KCONSOLE_H diff --git a/tdm/kfrontend/kfdialog.cpp b/tdm/kfrontend/kfdialog.cpp new file mode 100644 index 000000000..98b5773c2 --- /dev/null +++ b/tdm/kfrontend/kfdialog.cpp @@ -0,0 +1,182 @@ +/* + +Dialog class that handles input focus in absence of a wm + +Copyright (C) 1997, 1998 Steffen Hansen +Copyright (C) 2000-2003 Oswald Buddenhagen + + +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 "kfdialog.h" +#include "tdmconfig.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +extern bool has_twin; +extern bool is_themed; + +FDialog::FDialog( TQWidget *parent, bool framed ) + : inherited( parent, 0, true, (framed&&has_twin)?0:WX11BypassWM ), winFrame(NULL), m_wmTitle(has_twin) +{ + if (framed) { + // Signal that we do not want any window controls to be shown at all + Atom kde_wm_system_modal_notification; + kde_wm_system_modal_notification = XInternAtom(qt_xdisplay(), "_KDE_WM_MODAL_SYS_NOTIFICATION", False); + XChangeProperty(qt_xdisplay(), winId(), kde_wm_system_modal_notification, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L); + } + + if (framed) { + winFrame = new TQFrame( this, 0, TQt::WNoAutoErase ); + if (m_wmTitle) + winFrame->setFrameStyle( TQFrame::NoFrame ); + else + winFrame->setFrameStyle( TQFrame::WinPanel | TQFrame::Raised ); + winFrame->setLineWidth( 2 ); + } else + winFrame = 0; + + setCaption(TDM_LOGIN_SCREEN_BASE_TITLE); + + if (framed) { + if (m_wmTitle) setFixedSize(sizeHint()); + } +} + +void +FDialog::resizeEvent( TQResizeEvent *e ) +{ + inherited::resizeEvent( e ); + if (winFrame) { + winFrame->resize( size() ); + winFrame->erase(); + if (m_wmTitle) setFixedSize(sizeHint()); + } +} + +void +FDialog::adjustGeometry() +{ + TQDesktopWidget *dsk = tqApp->desktop(); + + if (_greeterScreen < 0) + _greeterScreen = _greeterScreen == -2 ? + dsk->screenNumber( TQPoint( dsk->width() - 1, 0 ) ) : + dsk->screenNumber( TQPoint( 0, 0 ) ); + + TQRect scr = dsk->screenGeometry( _greeterScreen ); + if (!winFrame) + setFixedSize( scr.size() ); + else { + setMaximumSize( scr.size() * .9 ); + adjustSize(); + } + + if (parentWidget()) + return; + + TQRect grt( rect() ); + if (winFrame) { + unsigned x = 50, y = 50; + sscanf( _greeterPos, "%u,%u", &x, &y ); + grt.moveCenter( TQPoint( scr.x() + scr.width() * x / 100, + scr.y() + scr.height() * y / 100 ) ); + int di; + if ((di = scr.right() - grt.right()) < 0) + grt.moveBy( di, 0 ); + if ((di = scr.left() - grt.left()) > 0) + grt.moveBy( di, 0 ); + if ((di = scr.bottom() - grt.bottom()) < 0) + grt.moveBy( 0, di ); + if ((di = scr.top() - grt.top()) > 0) + grt.moveBy( 0, di ); + setGeometry( grt ); + } + + if (dsk->screenNumber( TQCursor::pos() ) != _greeterScreen) + TQCursor::setPos( grt.center() ); +} + +struct WinList { + struct WinList *next; + TQWidget *win; +}; + +int +FDialog::exec() +{ + static WinList *wins; + WinList *win; + + win = new WinList; + win->win = this; + win->next = wins; + wins = win; + show(); + setActiveWindow(); + inherited::exec(); + hide(); + wins = win->next; + delete win; + if (wins) + wins->win->setActiveWindow(); + return result(); +} + +void +FDialog::box( TQWidget *parent, TQMessageBox::Icon type, const TQString &text ) +{ + KFMsgBox dlg( parent, type, text.stripWhiteSpace() ); + dlg.exec(); +} + +KFMsgBox::KFMsgBox( TQWidget *parent, TQMessageBox::Icon type, const TQString &text ) + : inherited( parent, !is_themed ) +{ + if (type == TQMessageBox::NoIcon) setCaption(TDM_LOGIN_SCREEN_BASE_TITLE); + if (type == TQMessageBox::Question) setCaption(TDM_LOGIN_SCREEN_BASE_TITLE + " - " + i18n("Question")); + if (type == TQMessageBox::Information) setCaption(TDM_LOGIN_SCREEN_BASE_TITLE + " - " + i18n("Information")); + if (type == TQMessageBox::Warning) setCaption(TDM_LOGIN_SCREEN_BASE_TITLE + " - " + i18n("Warning")); + if (type == TQMessageBox::Critical) setCaption(TDM_LOGIN_SCREEN_BASE_TITLE + " - " + i18n("Error")); + + TQLabel *label1 = new TQLabel( this ); + label1->setPixmap( TQMessageBox::standardIcon( type ) ); + TQLabel *label2 = new TQLabel( text, this ); + TQRect d = KGlobalSettings::desktopGeometry(this); + if ( label2->fontMetrics().size( 0, text).width() > d.width() * 3 / 5) + label2->setAlignment(TQt::WordBreak | TQt::AlignAuto ); + KPushButton *button = new KPushButton( KStdGuiItem::ok(), this ); + button->setDefault( true ); + button->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) ); + connect( button, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); + + TQGridLayout *grid = new TQGridLayout( this, 2, 2, 10 ); + grid->addWidget( label1, 0, 0, Qt::AlignCenter ); + grid->addWidget( label2, 0, 1, Qt::AlignCenter ); + grid->addMultiCellWidget( button, 1,1, 0,1, Qt::AlignCenter ); +} diff --git a/tdm/kfrontend/kfdialog.h b/tdm/kfrontend/kfdialog.h new file mode 100644 index 000000000..851d9a2db --- /dev/null +++ b/tdm/kfrontend/kfdialog.h @@ -0,0 +1,65 @@ +/* + +Dialog class that handles input focus in absence of a wm + +Copyright (C) 1997, 1998 Steffen Hansen +Copyright (C) 2000-2003 Oswald Buddenhagen + + +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. + +*/ + +#define TDM_LOGIN_SCREEN_BASE_TITLE i18n("Login to TDE") + +#ifndef FDIALOG_H +#define FDIALOG_H + +#include +#include + +class TQFrame; + +class FDialog : public TQDialog { + typedef TQDialog inherited; + + public: + FDialog( TQWidget *parent = 0, bool framed = true ); + virtual int exec(); + + static void box( TQWidget *parent, TQMessageBox::Icon type, + const TQString &text ); +#define errorbox TQMessageBox::Critical +#define sorrybox TQMessageBox::Warning +#define infobox TQMessageBox::Information + void MsgBox( TQMessageBox::Icon typ, const TQString &msg ) { box( this, typ, msg ); } + + protected: + virtual void resizeEvent( TQResizeEvent *e ); + void adjustGeometry(); + + private: + TQFrame *winFrame; + bool m_wmTitle; +}; + +class KFMsgBox : public FDialog { + typedef FDialog inherited; + + public: + KFMsgBox( TQWidget *parent, TQMessageBox::Icon type, const TQString &text ); +}; + +#endif /* FDIALOG_H */ diff --git a/tdm/kfrontend/kgapp.cpp b/tdm/kfrontend/kgapp.cpp new file mode 100644 index 000000000..5ad52dda6 --- /dev/null +++ b/tdm/kfrontend/kgapp.cpp @@ -0,0 +1,469 @@ +/* + +Greeter module for xdm + +Copyright (C) 1997, 1998 Steffen Hansen +Copyright (C) 2000-2003 Oswald Buddenhagen + + +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 + +#include "tdm_greet.h" +#include "tdmshutdown.h" +#include "tdmconfig.h" +#include "kgapp.h" +#include "kgreeter.h" +#ifdef XDMCP +# include "kchooser.h" +#endif +#include "sakdlg.h" + +#include +#include +#include +#include +#include +#include +#include +#ifdef WITH_XRANDR +#include +#endif + +#include +#include +#include +#include + +#include // free(), exit() +#include // alarm() + +#include +#include +#include +#include + +#ifdef HAVE_XCOMPOSITE +#include +#include +#endif + +#include + +bool argb_visual_available = false; +bool has_twin = false; +bool is_themed = false; +bool trinity_desktop_lock_use_sak = TRUE; + +static int +ignoreXError( Display *dpy ATTR_UNUSED, XErrorEvent *event ATTR_UNUSED ) +{ + return 0; +} + +extern "C" { + +static void +sigAlarm( int ) +{ + exit( EX_RESERVER_DPY ); +} + +} + +GreeterApp::GreeterApp() +{ + pingInterval = _isLocal ? 0 : _pingInterval; + if (pingInterval) { + struct sigaction sa; + sigemptyset( &sa.sa_mask ); + sa.sa_flags = 0; + sa.sa_handler = sigAlarm; + sigaction( SIGALRM, &sa, 0 ); + alarm( pingInterval * 70 ); // sic! give the "proper" pinger enough time + startTimer( pingInterval * 60000 ); + } +} + +GreeterApp::GreeterApp(Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap) : KApplication(dpy, visual, colormap) +{ + pingInterval = _isLocal ? 0 : _pingInterval; + if (pingInterval) { + struct sigaction sa; + sigemptyset( &sa.sa_mask ); + sa.sa_flags = 0; + sa.sa_handler = sigAlarm; + sigaction( SIGALRM, &sa, 0 ); + alarm( pingInterval * 70 ); // sic! give the "proper" pinger enough time + startTimer( pingInterval * 60000 ); + } +} + +void +GreeterApp::timerEvent( TQTimerEvent * ) +{ + alarm( 0 ); + if (!PingServer( qt_xdisplay() )) + ::exit( EX_RESERVER_DPY ); + alarm( pingInterval * 70 ); // sic! give the "proper" pinger enough time +} + +bool +GreeterApp::x11EventFilter( XEvent * ev ) +{ + KeySym sym; + + switch (ev->type) { + case FocusIn: + case FocusOut: + // Hack to tell dialogs to take focus when the keyboard is grabbed + ev->xfocus.mode = NotifyNormal; + break; + case KeyPress: + sym = XLookupKeysym( &ev->xkey, 0 ); + if (sym != XK_Return && !IsModifierKey( sym )) + emit activity(); + break; + case ButtonPress: + emit activity(); + /* fall through */ + case ButtonRelease: + // Hack to let the RMB work as LMB + if (ev->xbutton.button == 3) + ev->xbutton.button = 1; + /* fall through */ + case MotionNotify: + if (ev->xbutton.state & Button3Mask) + ev->xbutton.state = (ev->xbutton.state & ~Button3Mask) | Button1Mask; + break; + } + return false; +} + +extern bool kde_have_kipc; + +extern "C" { + +static int +xIOErr( Display * ) +{ + exit( EX_RESERVER_DPY ); +} + +//KSimpleConfig *iccconfig; + +void +checkSAK(GreeterApp* app) +{ + app->restoreOverrideCursor(); + SAKDlg sak(0); + sak.exec(); + app->setOverrideCursor( Qt::WaitCursor ); +} + +void +kg_main( const char *argv0 ) +{ + static char *argv[] = { (char *)"tdmgreet", 0 }; + KCmdLineArgs::init( 1, argv, *argv, 0, 0, 0, true ); + + kdDebug() << timestamp() << "start" << endl; + kde_have_kipc = false; + KApplication::disableAutoDcopRegistration(); + KCrash::setSafer( true ); + + KProcess *tsak = 0; + KProcess *proc = 0; + KProcess *comp = 0; + KProcess *twin = 0; + + trinity_desktop_lock_use_sak = _useSAK; + if (trinity_desktop_lock_use_sak) { + tsak = new KProcess; + *tsak << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + "tsak"; + tsak->start(KProcess::Block); + } + if (tsak) { + tsak->closeStdin(); + tsak->detach(); + delete tsak; + } + +#ifdef HAVE_XCOMPOSITE + // Begin ARGB initialization + XSetErrorHandler( ignoreXError ); + argb_visual_available = false; + char *display = 0; + + Display *dpyi = XOpenDisplay( display ); + if ( !dpyi ) { + kdError() << "cannot connect to X server " << display << endl; + exit( 1 ); + } + + int screen = DefaultScreen( dpyi ); + Colormap colormap = 0; + Visual *visual = 0; + int event_base, error_base; + + if ( XRenderQueryExtension( dpyi, &event_base, &error_base ) ) { + int nvi; + XVisualInfo templ; + templ.screen = screen; + templ.depth = 32; + templ.c_class = TrueColor; + XVisualInfo *xvi = XGetVisualInfo( dpyi, VisualScreenMask | VisualDepthMask + | VisualClassMask, &templ, &nvi ); + + for ( int i = 0; i < nvi; i++ ) { + XRenderPictFormat *format = XRenderFindVisualFormat( dpyi, xvi[i].visual ); + if ( format->type == PictTypeDirect && format->direct.alphaMask ) { + visual = xvi[i].visual; + colormap = XCreateColormap( dpyi, RootWindow( dpyi, screen ), visual, AllocNone ); + kdDebug() << "found visual with alpha support" << endl; + argb_visual_available = true; + break; + } + } + } + XSetErrorHandler( (XErrorHandler)0 ); + + GreeterApp *app; + if ( (argb_visual_available == true) && (!_compositor.isEmpty()) ) { + app = new GreeterApp(dpyi, Qt::HANDLE( visual ), Qt::HANDLE( colormap )); + } + else { + app = new GreeterApp(); + } + // End ARGB initialization +#else + GreeterApp *app = new GreeterApp(); +#endif + + XSetIOErrorHandler( xIOErr ); + TQString login_user; + + Display *dpy = qt_xdisplay(); + + if (!_GUIStyle.isEmpty()) + app->setStyle( _GUIStyle ); + + // Load up systemwide display settings +#ifdef WITH_XRANDR + KRandrSimpleAPI *randrsimple = new KRandrSimpleAPI(); + TQPoint primaryScreenPosition = randrsimple->applySystemwideDisplayConfiguration("", KDE_CONFDIR); + delete randrsimple; +#endif + + // Load up the systemwide ICC profile + TQString iccConfigFile = TQString(KDE_CONFDIR); + iccConfigFile += "/kicc/kiccconfigrc"; + KSimpleConfig iccconfig(iccConfigFile, true); + if (iccconfig.readBoolEntry("EnableICC", false) == true) { + TQString iccCommand = TQString("/usr/bin/xcalib "); + iccCommand += iccconfig.readEntry("ICCFile"); + iccCommand += TQString(" &"); + system(iccCommand.ascii()); + } + + _colorScheme = locate( "data", "kdisplay/color-schemes/" + _colorScheme + ".kcsrc" ); + if (!_colorScheme.isEmpty()) { + KSimpleConfig config( _colorScheme, true ); + config.setGroup( "Color Scheme" ); + app->setPalette( app->createApplicationPalette( &config, 7 ) ); + } + + app->setFont( _normalFont ); + + setup_modifiers( dpy, _numLockStatus ); + SecureDisplay( dpy ); + if (!_grabServer) { + if (_useBackground) { + proc = new KProcess; + *proc << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + "krootimage"; + *proc << _backgroundCfg; + proc->start(); + } + GSendInt( G_SetupDpy ); + GRecvInt(); + } + + if (!_compositor.isEmpty()) { + comp = new KProcess; + *comp << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + _compositor.ascii(); + comp->start(KProcess::NotifyOnExit, KProcess::Stdin); + } + + if (!_windowManager.isEmpty()) { + twin = new KProcess; + *twin << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + _windowManager.ascii(); + twin->start(); + has_twin = true; + } + + GSendInt( G_Ready ); + + kdDebug() << timestamp() << " main1" << endl; + setCursor( dpy, app->desktop()->winId(), XC_left_ptr ); + + for (;;) { + int rslt, cmd = GRecvInt(); + + if (cmd == G_ConfShutdown) { + int how = GRecvInt(), uid = GRecvInt(); + char *os = GRecvStr(); + TDMSlimShutdown::externShutdown( how, os, uid ); + if (os) + free( os ); + GSendInt( G_Ready ); + _autoLoginDelay = 0; + continue; + } + + if (cmd == G_ErrorGreet) { + if (KGVerify::handleFailVerify( TQT_TQWIDGET(tqApp->desktop()->screen( _greeterScreen )) )) + break; + _autoLoginDelay = 0; + cmd = G_Greet; + } + + KProcess *proc2 = 0; + app->setOverrideCursor( Qt::WaitCursor ); + FDialog *dialog = NULL; +#ifdef XDMCP + if (cmd == G_Choose) { + dialog = new ChooserDlg; + GSendInt( G_Ready ); /* tell chooser to go into async mode */ + GRecvInt(); /* ack */ + } else +#endif + { + if ((cmd != G_GreetTimed && !_autoLoginAgain) || + _autoLoginUser.isEmpty()) + _autoLoginDelay = 0; + if (_useTheme && !_theme.isEmpty()) { + // Qt4 has a nasty habit of generating BadWindow errors in normal operation, so we simply ignore them + // This also prevents the user from being dropped to a console login if Xorg glitches or is buggy + XSetErrorHandler( ignoreXError ); + KThemedGreeter *tgrt; + bool has_twin_bkp = has_twin; + is_themed = true; + has_twin = false; // [FIXME] The themed greeter is built on the assumption that there is no window manager available (i.e. it keeps stealing focus) and needs to be repaired. + dialog = tgrt = new KThemedGreeter; + kdDebug() << timestamp() << " themed" << endl; + if (!tgrt->isOK()) { + is_themed = false; + has_twin = has_twin_bkp; + delete tgrt; + checkSAK(app); + dialog = new KStdGreeter; +#ifdef WITH_XRANDR + dialog->move(dialog->x() + primaryScreenPosition.x(), dialog->y() + primaryScreenPosition.y()); +#endif + } + else { +#ifdef WITH_XRANDR + dialog->move(primaryScreenPosition.x(), primaryScreenPosition.y()); +#endif + } + XSetErrorHandler( (XErrorHandler)0 ); + } else { + checkSAK(app); + dialog = new KStdGreeter; +#ifdef WITH_XRANDR + dialog->move(dialog->x() + primaryScreenPosition.x(), dialog->y() + primaryScreenPosition.y()); +#endif + } + TQPoint oldCursorPos = TQCursor::pos(); +#ifdef WITH_XRANDR + TQCursor::setPos(oldCursorPos.x() + primaryScreenPosition.x(), oldCursorPos.y() + primaryScreenPosition.y()); +#endif + if (*_preloader) { + proc2 = new KProcess; + *proc2 << _preloader; + proc2->start(); + } + } + app->restoreOverrideCursor(); + Debug( "entering event loop\n" ); + // Qt4 has a nasty habit of generating BadWindow errors in normal operation, so we simply ignore them + // This also prevents the user from being dropped to a console login if Xorg glitches or is buggy + XSetErrorHandler( ignoreXError ); + rslt = dialog->exec(); + XSetErrorHandler( (XErrorHandler)0 ); + Debug( "left event loop\n" ); + + login_user = static_cast(dialog)->curUser; + + if (rslt != ex_greet) { + delete dialog; + } + delete proc2; +#ifdef XDMCP + switch (rslt) { + case ex_greet: + GSendInt( G_DGreet ); + continue; + case ex_choose: + GSendInt( G_DChoose ); + continue; + default: + break; + } +#endif + break; + } + + KGVerify::done(); + + if (comp) { + if (_compositor == "kompmgr") { + // Change process UID + // Get user UID + passwd* userinfo = getpwnam(login_user.ascii()); + if (userinfo) { + TQString newuid = TQString("%1").arg(userinfo->pw_uid); + // kompmgr allows us to change its uid in this manner: + // 1.) Send SIGUSER1 + // 2.) Send the new UID to it on the command line + comp->kill(SIGUSR1); + comp->writeStdin(newuid.ascii(), newuid.length()); + usleep(50000); // Give the above function some time to execute. Note that on REALLY slow systems this could fail, leaving kompmgr running as root. TODO: Look into ways to make this more robust. + } + } + comp->closeStdin(); + comp->detach(); + delete comp; + } + if (twin) { + twin->closeStdin(); + twin->detach(); + delete twin; + } + delete proc; + UnsecureDisplay( dpy ); + restore_modifiers(); + + XSetInputFocus( qt_xdisplay(), PointerRoot, PointerRoot, CurrentTime ); + + delete app; +} + +} // extern "C" + +#include "kgapp.moc" diff --git a/tdm/kfrontend/kgapp.h b/tdm/kfrontend/kgapp.h new file mode 100644 index 000000000..2c4374f47 --- /dev/null +++ b/tdm/kfrontend/kgapp.h @@ -0,0 +1,50 @@ +/* + +Greeter module for xdm + +Copyright (C) 1997, 1998 Steffen Hansen +Copyright (C) 2000-2003 Oswald Buddenhagen + + +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. + +*/ + + +#ifndef KGAPP_H +#define KGAPP_H + +#include + +class GreeterApp : public KApplication { + Q_OBJECT + typedef KApplication inherited; + + public: + GreeterApp(); + GreeterApp(Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap); + virtual bool x11EventFilter( XEvent * ); + + protected: + virtual void timerEvent( TQTimerEvent * ); + + signals: + void activity(); + + private: + int pingInterval; +}; + +#endif /* KGAPP_H */ diff --git a/tdm/kfrontend/kgdialog.cpp b/tdm/kfrontend/kgdialog.cpp new file mode 100644 index 000000000..667eca8e1 --- /dev/null +++ b/tdm/kfrontend/kgdialog.cpp @@ -0,0 +1,240 @@ +/* + +Base class for various tdm greeter dialogs + +Copyright (C) 1997, 1998 Steffen Hansen +Copyright (C) 2000-2004 Oswald Buddenhagen + + +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 "kgdialog.h" +#include "kgverify.h" +#include "kconsole.h" +#include "tdmshutdown.h" +#include "tdm_greet.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include + +KGDialog::KGDialog( bool themed ) : inherited( 0, !themed ) +{ +#ifdef WITH_TDM_XCONSOLE + consoleView = _showLog ? new KConsole( this ) : 0; +#endif + + optMenu = 0; + verify = 0; +} + +void +#ifdef XDMCP +KGDialog::completeMenu( int _switchIf, int _switchCode, const TQString &_switchMsg, int _switchAccel ) +#else +KGDialog::completeMenu() +#endif +{ +#ifdef HAVE_VTS + if (_isLocal) { + dpyMenu = new TQPopupMenu( this ); + int id = inserten( i18n("Sw&itch User"), ALT+Key_I, dpyMenu ); + connect( dpyMenu, TQT_SIGNAL(activated( int )), + TQT_SLOT(slotDisplaySelected( int )) ); + connect( dpyMenu, TQT_SIGNAL(aboutToShow()), + TQT_SLOT(slotPopulateDisplays()) ); + TQAccel *accel = new TQAccel( this ); + accel->insertItem( ALT+CTRL+Key_Insert, id ); + connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotActivateMenu( int )) ); + } +#endif + + if (_allowClose) + inserten( _isLocal ? i18n("R&estart X Server") : i18n("Clos&e Connection"), + ALT+Key_E, TQT_SLOT(slotExit()) ); + +#ifdef XDMCP + if (_isLocal && _loginMode != _switchIf) { + switchCode = _switchCode; + inserten( _switchMsg, _switchAccel, TQT_SLOT(slotSwitch()) ); + } +#endif + + if (_hasConsole) + inserten( i18n("Co&nsole Login"), ALT+Key_N, TQT_SLOT(slotConsole()) ); + + if (_allowShutdown != SHUT_NONE) { + ensureMenu(); + optMenu->insertItem(SmallIconSet( "exit" ), i18n("&Shutdown..."), this, TQT_SLOT(slotShutdown(int)), ALT+Key_S ); + TQAccel *accel = new TQAccel( this ); + accel->insertItem( ALT+CTRL+Key_Delete ); + connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotShutdown( int )) ); + accel = new TQAccel( this ); + accel->insertItem( SHIFT+ALT+CTRL+Key_PageUp, SHUT_REBOOT ); + connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotShutdown( int )) ); + accel = new TQAccel( this ); + accel->insertItem( SHIFT+ALT+CTRL+Key_PageDown, SHUT_HALT ); + connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotShutdown( int )) ); + } +} + +void +KGDialog::ensureMenu() +{ + if (!optMenu) { + optMenu = new TQPopupMenu( this ); + optMenu->setCheckable( false ); + needSep = false; + } else if (needSep) { + optMenu->insertSeparator(); + needSep = false; + } +} + +void +KGDialog::inserten( const TQString& txt, int accel, const char *member ) +{ + ensureMenu(); + optMenu->insertItem( txt, this, member, accel ); +} + +int +KGDialog::inserten( const TQString& txt, int accel, TQPopupMenu *cmnu ) +{ + ensureMenu(); + int id = optMenu->insertItem( txt, cmnu ); + optMenu->setAccel( accel, id ); + optMenu->connectItem( id, this, TQT_SLOT(slotActivateMenu( int )) ); + optMenu->setItemParameter( id, id ); + return id; +} + +void +KGDialog::slotActivateMenu( int id ) +{ + TQPopupMenu *cmnu = optMenu->findItem( id )->popup(); + TQSize sh( cmnu->sizeHint() / 2 ); + cmnu->exec( geometry().center() - TQPoint( sh.width(), sh.height() ) ); +} + +void +KGDialog::slotExit() +{ + if (verify) + verify->abort(); + ::exit( EX_RESERVER_DPY ); +} + +void +KGDialog::slotSwitch() +{ +#ifdef XDMCP + // workaround for Qt bug + TQTimer::singleShot( 0, this, TQT_SLOT(slotReallySwitch()) ); +#endif +} + +void +KGDialog::slotReallySwitch() +{ +#ifdef XDMCP + done( switchCode ); +#endif +} + +void +KGDialog::slotConsole() +{ +#ifdef HAVE_VTS + dpySpec *sess = fetchSessions( 0 ); + if (sess) { + if (verify) + verify->suspend(); + int ret = TDMConfShutdown( -1, sess, SHUT_CONSOLE, 0 ).exec(); + if (verify) + verify->resume(); + disposeSessions( sess ); + if (!ret) + return; + } +#else + if (verify) + verify->abort(); +#endif + GSet( 1 ); + GSendInt( G_Console ); + GSet( 0 ); +} + +void +KGDialog::slotShutdown( int id ) +{ + if (verify) + verify->suspend(); + if (id < 0) { + if (_scheduledSd == SHUT_ALWAYS) + TDMShutdown::scheduleShutdown( this ); + else + TDMSlimShutdown( this ).exec(); + } else + TDMSlimShutdown::externShutdown( id, 0, -1 ); + if (verify) + verify->resume(); +} + +void +KGDialog::slotDisplaySelected( int vt ) +{ +#ifdef HAVE_VTS + GSet( 1 ); + GSendInt( G_Activate ); + GSendInt( vt ); + GSet( 0 ); +#else + (void)vt; +#endif +} + +void +KGDialog::slotPopulateDisplays() +{ +#ifdef HAVE_VTS + dpyMenu->clear(); + dpySpec *sessions = fetchSessions( lstPassive | lstTTY ); + TQString user, loc; + for (dpySpec *sess = sessions; sess; sess = sess->next) { + decodeSess( sess, user, loc ); + int id = dpyMenu->insertItem( + i18n("session (location)", "%1 (%2)").arg( user ).arg( loc ), + sess->vt ? sess->vt : -1 ); + if (!sess->vt) + dpyMenu->setItemEnabled( id, false ); + if (sess->flags & isSelf) + dpyMenu->setItemChecked( id, true ); + } + disposeSessions( sessions ); +#endif +} + +#include "kgdialog.moc" diff --git a/tdm/kfrontend/kgdialog.h b/tdm/kfrontend/kgdialog.h new file mode 100644 index 000000000..a902b6ff0 --- /dev/null +++ b/tdm/kfrontend/kgdialog.h @@ -0,0 +1,87 @@ +/* + +Base class for various tdm greeter dialogs + +Copyright (C) 1997, 1998 Steffen Hansen +Copyright (C) 2000-2004 Oswald Buddenhagen + + +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. + +*/ + + +#ifndef KGDIALOG_H +#define KGDIALOG_H + +#include // for WITH_TDM_XCONSOLE + +#include "tdmconfig.h" +#include "kfdialog.h" + +class TQPopupMenu; +class TQGridLayout; +class KConsole; +class KGVerify; + +#define ex_exit 1 +#define ex_greet 2 +#define ex_choose 3 + +class KGDialog : public FDialog { + Q_OBJECT + typedef FDialog inherited; + + public: + KGDialog( bool themed = false ); + + public slots: + void slotActivateMenu( int id ); + void slotExit(); + void slotSwitch(); + void slotReallySwitch(); + void slotConsole(); + void slotShutdown( int id ); + + protected: +#ifdef XDMCP + void completeMenu( int _switchIf, int _switchCode, const TQString &_switchMsg, int _switchAccel ); +#else + void completeMenu(); +#endif + void inserten( const TQString& txt, int accel, const char *member ); + int inserten( const TQString& txt, int accel, TQPopupMenu *cmnu ); + + bool needSep; + TQPopupMenu *optMenu; + KGVerify *verify; +#ifdef WITH_TDM_XCONSOLE + KConsole *consoleView; +#endif + + private slots: + void slotDisplaySelected( int vt ); + void slotPopulateDisplays(); + + private: + void ensureMenu(); + +#ifdef HAVE_VTS + TQPopupMenu *dpyMenu; +#endif + int switchCode; +}; + +#endif /* KGDIALOG_H */ diff --git a/tdm/kfrontend/kgreeter.cpp b/tdm/kfrontend/kgreeter.cpp new file mode 100644 index 000000000..ee1bf3e72 --- /dev/null +++ b/tdm/kfrontend/kgreeter.cpp @@ -0,0 +1,1280 @@ +/* + +Greeter widget for tdm + +Copyright (C) 1997, 1998, 2000 Steffen Hansen +Copyright (C) 2000-2004 Oswald Buddenhagen + + +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 "kgreeter.h" +#include "kconsole.h" +#include "tdmconfig.h" +#include "tdmclock.h" +#include "tdm_greet.h" +#include "tdmadmindialog.h" +#include "themer/tdmthemer.h" +#include "themer/tdmitem.h" +#include "themer/tdmlabel.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#undef Unsorted // x headers suck - make tqdir.h work with --enable-final +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define FIFO_DIR "/tmp/ksocket-global/tdm" +#define FIFO_FILE "/tmp/ksocket-global/tdm/tdmctl-%1" +#define FIFO_SAK_FILE "/tmp/ksocket-global/tdm/tdmctl-sak-%1" + +class UserListView : public KListView { + public: + UserListView( bool _them, TQWidget *parent = 0, const char *name = 0 ) + : KListView( parent, name ) + , themed(_them), cachedSizeHint( -1, 0 ) + { + setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Ignored ); + header()->hide(); + addColumn( TQString::null ); + setColumnAlignment( 0, AlignVCenter ); + setResizeMode( TQListView::LastColumn ); + // FIXME: This must be configurable, so disable + // painting of list background for now. +// if (themed) { +// setBackgroundMode( Qt::NoBackground ); +// viewport()->setBackgroundMode( Qt::NoBackground ); +// setFrameStyle( TQFrame::NoFrame ); +// } + } + + bool themed; + mutable TQSize cachedSizeHint; + + int sumHeight() const + { + int sum = 0; + for (TQListViewItem *itm = firstChild(); itm; itm = itm->nextSibling()) { + sum += itm->height(); + } + return sum; + } +public: + virtual TQSize sizeHint() const + { + if (themed) + return KListView::sizeHint(); + + if (!cachedSizeHint.isValid()) { + constPolish(); + uint maxw = 0; + for (TQListViewItem *itm = firstChild(); itm; itm = itm->nextSibling()) { + uint thisw = itm->width( fontMetrics(), this, 0 ); + if (thisw > maxw) + maxw = thisw; + } + cachedSizeHint.setWidth( + style().pixelMetric( TQStyle::PM_ScrollBarExtent ) + + frameWidth() * 2 + maxw ); + } + return cachedSizeHint; + } + virtual void paintEmptyArea ( TQPainter * p, const TQRect & rect ) + { + if (!themed) + return KListView::paintEmptyArea(p, rect ); + + // FIXME: This must be configurable, so disable + // painting of list background for now. + return KListView::paintEmptyArea(p, rect ); + + const TQPixmap *pm = TQT_TQPIXMAP_CONST(paletteBackgroundPixmap()); + if (!pm || pm->isNull()) + return; + + kdDebug() << "paintEmpty " << rect << endl; + TQRect devRect = p->xForm( rect ); + kdDebug() << "paintEmpty2 " << devRect << endl; + p->drawPixmap(0, 0, *pm, devRect.left(), devRect.top() ); + } + + TQPixmap background; +}; + +int KGreeter::curPlugin = -1; +PluginList KGreeter::pluginList; + +KGreeter::KGreeter( bool framed ) + : inherited( framed ) + , dName( dname ) + , userView( 0 ) + , userList( 0 ) + , nNormals( 0 ) + , nSpecials( 0 ) + , curPrev( -1 ) + , curSel( -1 ) + , prevValid( true ) + , needLoad( false ) + , themed( framed ) + , mPipe_fd( -1 ) + , closingDown( false ) +{ + stsFile = new KSimpleConfig( _stsFile ); + stsFile->setGroup( "PrevUser" ); + + if (_userList) { + readFacesList(); + userView = new UserListView( framed, this ); + connect( userView, TQT_SIGNAL(clicked( TQListViewItem * )), + TQT_SLOT(slotUserClicked( TQListViewItem * )) ); + connect( userView, TQT_SIGNAL(doubleClicked( TQListViewItem * )), + TQT_SLOT(accept()) ); + } + if (_userCompletion) + userList = new TQStringList; + + sessMenu = new TQPopupMenu( this ); + connect( sessMenu, TQT_SIGNAL(activated( int )), + TQT_SLOT(slotSessionSelected( int )) ); + insertSessions(); + + if (curPlugin < 0) { + curPlugin = 0; + pluginList = KGVerify::init( _pluginsLogin ); + } + + TQTimer::singleShot( 0, this, TQT_SLOT(handleInputPipe()) ); +} + +KGreeter::~KGreeter() +{ + if (mPipe_fd != -1) { + closingDown = true; + ::close(mPipe_fd); + ::unlink(mPipeFilename.ascii()); + } + hide(); + delete userList; + delete verify; + delete stsFile; +} + +void KGreeter::done(int r) { + closingDown = true; + inherited::done(r); +} + +void KGreeter::handleInputPipe(void) { + if (closingDown) { + ::unlink(mPipeFilename.ascii()); + return; + } + + if (isShown() == false) { + TQTimer::singleShot( 100, this, TQT_SLOT(handleInputPipe()) ); + return; + } + + char readbuf[2048]; + int displayNumber; + TQString currentDisplay; + currentDisplay = TQString(getenv("DISPLAY")); + currentDisplay = currentDisplay.replace(":", ""); + displayNumber = currentDisplay.toInt(); + mPipeFilename = TQString(FIFO_FILE).arg(displayNumber); + ::unlink((TQString(FIFO_SAK_FILE).arg(displayNumber)).ascii()); + + /* Create the FIFOs if they do not exist */ + umask(0); + struct stat buffer; + int status; + status = stat(FIFO_DIR, &buffer); + if (status == 0) { + int file_mode = ((buffer.st_mode & S_IRWXU) >> 6) * 100; + file_mode = file_mode + ((buffer.st_mode & S_IRWXG) >> 3) * 10; + file_mode = file_mode + ((buffer.st_mode & S_IRWXO) >> 0) * 1; + if ((file_mode != 600) || (buffer.st_uid != 0) || (buffer.st_gid != 0)) { + ::unlink(mPipeFilename.ascii()); + printf("[WARNING] Possible security breach! Please check permissions on " FIFO_DIR " (must be 600 and owned by root/root, got %d %d/%d). Not listening for login credentials on remote control socket.\n", file_mode, buffer.st_uid, buffer.st_gid); fflush(stdout); + return; + } + } + mkdir(FIFO_DIR,0600); + mknod(mPipeFilename.ascii(), S_IFIFO|0600, 0); + chmod(mPipeFilename.ascii(), 0600); + + mPipe_fd = ::open(mPipeFilename.ascii(), O_RDONLY | O_NONBLOCK); + int numread; + TQString inputcommand = ""; + while ((!inputcommand.contains('\n')) && (!closingDown)) { + numread = ::read(mPipe_fd, readbuf, 2048); + readbuf[numread] = 0; + readbuf[2047] = 0; + inputcommand += readbuf; + if (!tqApp->hasPendingEvents()) { + usleep(500); + } + tqApp->processEvents(); + } + if (closingDown) { + ::unlink(mPipeFilename.ascii()); + return; + } + inputcommand = inputcommand.replace('\n', ""); + TQStringList commandList = TQStringList::split('\t', inputcommand, false); + if ((*(commandList.at(0))) == "LOGIN") { + if (verify) { + verify->setUser( (*(commandList.at(1))) ); + verify->setPassword( (*(commandList.at(2))) ); + accept(); + } + } + if (!closingDown) { + TQTimer::singleShot( 0, this, TQT_SLOT(handleInputPipe()) ); + ::close(mPipe_fd); + ::unlink(mPipeFilename.ascii()); + } + else { + ::unlink(mPipeFilename.ascii()); + } +} + +void KGreeter::readFacesList() +{ + FILE *f = fopen( TQFile::encodeName( _faceDir + "/.randomlist" ), "rt" ); + if ( !f ) + return; + TQTextIStream is( f ); + while ( !is.eof() ) + { + TQString line = is.readLine().simplifyWhiteSpace(); + if ( line.isEmpty() ) + continue; + TQString icon; + int index = line.find( ' ' ); + if ( index > 0 ) { + icon = line.left( index ); + line = line.mid( index ); + } else { + icon = line; + line = TQString::null; + } + randomFaces.push_back( icon ); + TQStringList list = TQStringList::split( ' ', line ); + for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) + randomFacesMap[*it] = icon; + } +} + +class UserListViewItem : public KListViewItem { + public: + UserListViewItem( UserListView *parent, const TQString &text, + const TQPixmap &pixmap, const TQString &username ) + : KListViewItem( parent ) + , login( username ) + { + setPixmap( 0, pixmap ); + setMultiLinesEnabled( true ); + setText( 0, text ); + parent->cachedSizeHint.setWidth( -1 ); + } + + virtual void paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment) + { + if (((UserListView*)listView())->themed) + TQListViewItem::paintCell(p, cg, column, width, alignment); + else + KListViewItem::paintCell(p, cg, column, width, alignment); + } + + TQString login; +}; + +#define FILE_LIMIT_ICON 20 +#define FILE_LIMIT_IMAGE 200 + +void +KGreeter::insertUser( const TQImage &default_pix, + const TQString &username, struct passwd *ps ) +{ + if (setegid( ps->pw_gid )) + return; + if (seteuid( ps->pw_uid )) { + setegid(0); + return; + } + + if (userList) + userList->append( username ); + if (!userView) + return; + + int dp = 0, nd = 0; + if (_faceSource == FACE_USER_ONLY || + _faceSource == FACE_PREFER_USER) + dp = 1; + if (_faceSource != FACE_USER_ONLY && + _faceSource != FACE_ADMIN_ONLY) + nd = 1; + TQImage p; + do { + dp ^= 1; + TQCString fn = !dp ? + TQCString( ps->pw_dir ) + '/' : + TQCString(TQFile::encodeName( _faceDir + '/' + username )); + fn += ".face.icon"; + int fd, ico; + if ((fd = open( fn.data(), O_RDONLY | O_NONBLOCK )) < 0) { + fn.truncate( fn.length() - 5 ); + if ((fd = open( fn.data(), O_RDONLY | O_NONBLOCK )) < 0) + continue; + ico = 0; + } else + ico = 1; + TQFile f; + f.open( IO_ReadOnly, fd ); + int fs = f.size(); + if (fs > (ico ? FILE_LIMIT_ICON : FILE_LIMIT_IMAGE) * 1000) { + LogWarn( "%s exceeds file size limit (%dkB)\n", + fn.data(), ico ? FILE_LIMIT_ICON : FILE_LIMIT_IMAGE ); + continue; + } + TQByteArray fc( fs ); + int rfs = f.readBlock( fc.data(), fs ); + ::close( fd ); + fc.resize( rfs > 0 ? rfs : 0 ); + TQBuffer buf( fc ); + buf.open( IO_ReadOnly ); + TQImageIO ir; + ir.setIODevice( TQT_TQIODEVICE(&buf) ); + if (!ir.read()) { + LogInfo( "%s is no valid image\n", fn.data() ); + continue; + } + p = ir.image(); + TQSize ns( 48, 48 ); + if (p.size() != ns) + p = p.convertDepth( 32 ).smoothScale( ns, TQ_ScaleMin ); + break; + } while (--nd >= 0); + + if ( p.isNull() && randomFaces.count() ) { + TQString randomFace = randomFacesMap[username]; + if ( randomFace.isNull() ) { + TQStringList::size_type index = 0; + for ( size_t i = 0; i < username.length(); ++i ) + index += ( 0x7f - username.at( i ).latin1() ) % 37; + randomFace = randomFaces[ index % randomFaces.count() ]; + } + p.load( _faceDir + "/../pics/users/" + randomFace + ".png" ); + } + + if ( p.isNull() ) + p = default_pix; + + TQString realname = KStringHandler::from8Bit( ps->pw_gecos ); + realname.truncate( realname.find( ',' ) ); + if (realname.isEmpty() || realname == username) + new UserListViewItem( userView, username, TQPixmap( p ), username ); + else { + realname.append( "\n" ).append( username ); + new UserListViewItem( userView, realname, TQPixmap( p ), username ); + } + + seteuid( 0 ); + setegid( 0 ); +} + +class KCStringList : public TQValueList { + public: + bool contains( const char *str ) const + { + for (ConstIterator it = begin(); it != end(); ++it) + if (*it == str) + return true; + return false; + } +}; + +class UserList { + public: + UserList( char **in ); + bool hasUser( const char *str ) const { return users.contains( str ); } + bool hasGroup( gid_t gid ) const + { return groups.find( gid ) != groups.end(); } + bool hasGroups() const { return !groups.isEmpty(); } + KCStringList users; + + private: + TQValueList groups; +}; + +UserList::UserList( char **in ) +{ + struct group *grp; + + for (; *in; in++) + if (**in == '@') { + if ((grp = getgrnam( *in + 1 ))) { + for (; *grp->gr_mem; grp->gr_mem++) + users.append( *grp->gr_mem ); + groups.append( grp->gr_gid ); + } + } else + users.append( *in ); +} + +void +KGreeter::insertUsers(int limit_users) +{ + struct passwd *ps; + + if (!(ps = getpwnam( "nobody" ))) + return; + + TQImage default_pix; + if (userView) { + if (!default_pix.load( _faceDir + "/.default.face.icon" )) + if (!default_pix.load( _faceDir + "/.default.face" )) + LogError( "Can't open default user face\n" ); + TQSize ns( 48, 48 ); + if (default_pix.size() != ns) + default_pix = + default_pix.convertDepth( 32 ).smoothScale( ns, TQ_ScaleMin ); + } + if (_showUsers == SHOW_ALL) { + UserList noUsers( _noUsers ); + TQDict dupes( 1000 ); // Potential crash risk with buffer overrun? + TQStringList toinsert; + int count = 0; + for (setpwent(); (ps = getpwent()) != 0;) { + if (*ps->pw_dir && *ps->pw_shell && + ((ps->pw_uid >= (unsigned)_lowUserId) || + ((!ps->pw_uid) && _showRoot)) && + (ps->pw_uid <= (unsigned)_highUserId) && + (!noUsers.hasUser( ps->pw_name )) && + (!noUsers.hasGroup( ps->pw_gid ))) + { + TQString username( TQFile::decodeName( ps->pw_name ) ); + if (!dupes.find( username )) { + dupes.insert( username, (int *)-1 ); + toinsert.append( username ); + + if ( limit_users >= 0 && ++count > limit_users ) + break; + } + } + } + // FIXME: OpenSUSE added this code + // For some reason it does not allow LDAP users to be listed (!), + // therefore it was deactivated. It should be repaired and reactivated. +// if ( limit_users >= 0 && ++count > limit_users ) { +// utmpname( _PATH_WTMP ); +// setutxent(); +// toinsert = TQStringList(); +// dupes.clear(); +// +// for ( count = 0; count < limit_users; ) { +// struct utmpx * ent = getutxent(); +// if ( !ent ) +// break; +// struct passwd *ps = getpwnam( ent->ut_user ); +// if (ps && *ps->pw_dir && *ps->pw_shell && +// (ps->pw_uid >= (unsigned)_lowUserId || +// !ps->pw_uid && _showRoot) && +// ps->pw_uid <= (unsigned)_highUserId && +// !noUsers.hasUser( ps->pw_name ) && +// !noUsers.hasGroup( ps->pw_gid )) +// { +// TQString username( TQFile::decodeName( ent->ut_user ) ); +// if (!dupes.find( username )) { +// dupes.insert( username, (int *)-1 ); +// toinsert.append( username ); +// count++; +// } +// } +// +// +// } +// endutxent(); +// } + + for ( TQStringList::ConstIterator it = toinsert.begin(); + it != toinsert.end(); ++it ) + { + // pretty stupid to do another lookup round, but the number is limited + // and caching struct passwd is pretty ugly + struct passwd *ps = getpwnam( TQFile::encodeName( *it ) ); + if ( ps ) + insertUser( default_pix, *it, ps ); + } + } else { + UserList users( _users ); + if (users.hasGroups()) { + TQDict dupes( 1000 ); + for (setpwent(); (ps = getpwent()) != 0;) { + if (*ps->pw_dir && *ps->pw_shell && + (ps->pw_uid >= (unsigned)_lowUserId || + ((!ps->pw_uid) && _showRoot)) && + ps->pw_uid <= (unsigned)_highUserId && + (users.hasUser( ps->pw_name ) || + users.hasGroup( ps->pw_gid ))) + { + TQString username( TQFile::decodeName( ps->pw_name ) ); + if (!dupes.find( username )) { + dupes.insert( username, (int *)-1 ); + insertUser( default_pix, username, ps ); + } + } + } + } else { + KCStringList::ConstIterator it = users.users.begin(); + for (; it != users.users.end(); ++it) + if ((ps = getpwnam( (*it).data() )) && + (ps->pw_uid || _showRoot)) + insertUser( default_pix, TQFile::decodeName( *it ), ps ); + } + } + endpwent(); + if (_sortUsers) { + if (userView) + userView->sort(); + if (userList) + userList->sort(); + } +} + +void +KGreeter::putSession( const TQString &type, const TQString &name, bool hid, const char *exe ) +{ + int prio = exe ? (!strcmp( exe, "default" ) ? 0 : + !strcmp( exe, "failsafe" ) ? 3 : 2) : 2; + for (uint i = 0; i < sessionTypes.size(); i++) + if (sessionTypes[i].type == type) { + sessionTypes[i].prio = prio; + return; + } + sessionTypes.append( SessType( name, type, hid, prio ) ); +} + +void +KGreeter::insertSessions() +{ + for (char **dit = _sessionsDirs; *dit; ++dit) { + TQStringList ents = TQDir( *dit ).entryList(); + for (TQStringList::ConstIterator it = ents.begin(); it != ents.end(); ++it) + if ((*it).endsWith( ".desktop" ) && !(*it).endsWith("admin.desktop")) { + KSimpleConfig dsk( TQString( *dit ).append( '/' ).append( *it ) ); + dsk.setGroup( "Desktop Entry" ); + putSession( (*it).left( (*it).length() - 8 ), + dsk.readEntry( "Name" ), + (dsk.readBoolEntry( "Hidden", false ) || + (dsk.hasKey( "TryExec" ) && + KStandardDirs::findExe( dsk.readEntry( "TryExec" ) ).isEmpty())), + dsk.readEntry( "Exec" ).latin1() ); + } + } + putSession( "default", i18n("Default"), false, "default" ); + putSession( "failsafe", i18n("Failsafe"), false, "failsafe" ); + qBubbleSort( sessionTypes ); + for (uint i = 0; i < sessionTypes.size() && !sessionTypes[i].hid; i++) { + sessMenu->insertItem( sessionTypes[i].name, i ); + switch (sessionTypes[i].prio) { + case 0: case 1: nSpecials++; break; + case 2: nNormals++; break; + } + } +} + +void +KGreeter::slotUserEntered() +{ + if (userView) { + TQListViewItem *item; + for (item = userView->firstChild(); item; item = item->nextSibling()) + if (((UserListViewItem *)item)->login == curUser) { + userView->setSelected( item, true ); + userView->ensureItemVisible( item ); + goto oke; + } + userView->clearSelection(); + } + oke: + if (isVisible()) + slotLoadPrevWM(); + else + TQTimer::singleShot( 0, this, TQT_SLOT(slotLoadPrevWM()) ); +} + +void +KGreeter::slotUserClicked( TQListViewItem *item ) +{ + if (item) { + curUser = ((UserListViewItem *)item)->login; + verify->setUser( curUser ); + slotLoadPrevWM(); + } +} + +void +KGreeter::slotSessionSelected( int id ) +{ + if (id != curSel) { + sessMenu->setItemChecked( curSel, false ); + sessMenu->setItemChecked( id, true ); + curSel = id; + verify->gplugActivity(); + } +} + +void +KGreeter::reject() +{ + verify->reject(); +} + +void +KGreeter::accept() +{ + if (userView && userView->hasFocus()) + slotUserClicked( userView->currentItem() ); + else + verify->accept(); +} + +void // private +KGreeter::setPrevWM( int wm ) +{ + if (curPrev != wm) { + if (curPrev != -1) + sessMenu->changeItem( curPrev, sessionTypes[curPrev].name ); + if (wm != -1) + sessMenu->changeItem( wm, sessionTypes[wm].name + i18n(" (previous)") ); + curPrev = wm; + } +} + +void +KGreeter::slotLoadPrevWM() +{ + int len, i, b; + unsigned long crc, by; + TQCString name; + char *sess; + + if (verify->coreLock) { + needLoad = true; + return; + } + needLoad = false; + + prevValid = true; + name = curUser.local8Bit(); + GSendInt( G_ReadDmrc ); + GSendStr( name.data() ); + GRecvInt(); // ignore status code ... + if ((len = name.length())) { + GSendInt( G_GetDmrc ); + GSendStr( "Session" ); + sess = GRecvStr(); + if (!sess) { /* no such user */ + if (!userView && !userList) { // don't fake if user list shown + prevValid = false; + /* simple crc32 */ + for (crc = _forgingSeed, i = 0; i < len; i++) { + by = (crc & 255) ^ name[i]; + for (b = 0; b < 8; b++) + by = (by >> 1) ^ (-(by & 1) & 0xedb88320); + crc = (crc >> 8) ^ by; + } + /* forge a session with this hash - default & custom more probable */ + /* XXX - this should do a statistical analysis of the real users */ +#if 1 + setPrevWM( crc % (nSpecials * 2 + nNormals) % (nSpecials + nNormals) ); +#else + i = crc % (nSpecials * 2 + nNormals); + if (i < nNormals) + setPrevWM( i + nSpecials ); + else + setPrevWM( (i - nNormals) / 2 ); +#endif + return; + } + } else { + if (!strcmp(sess, "admin")) { + // need to get the original + GSendInt( G_GetDmrc); + GSendStr( "OrigSession"); + sess = GRecvStr(); + if (!sess) { + free(sess); + sess = strdup("default"); + } + } + + for (uint i = 0; i < sessionTypes.count() && !sessionTypes[i].hid; i++) + if (sessionTypes[i].type == sess) { + free( sess ); + setPrevWM( i ); + return; + } + if (curSel == -1) + MsgBox( sorrybox, i18n("Your saved session type '%1' is not valid any more.\n" + "Please select a new one, otherwise 'default' will be used.").arg( sess ) ); + free( sess ); + prevValid = false; + } + } + setPrevWM( -1 ); +} + +void // protected +KGreeter::pluginSetup() +{ + int field = 0; + TQString ent, pn( verify->pluginName() ), dn( dName + '_' + pn ); + + if (_preselUser != PRESEL_PREV) + stsFile->deleteEntry( verify->entitiesLocal() ? dName : dn, false ); + if (_preselUser != PRESEL_NONE && verify->entityPresettable()) { + if (verify->entitiesLocal()) + ent = _preselUser == PRESEL_PREV ? + stsFile->readEntry( dName ) : _defaultUser; + else + ent = _preselUser == PRESEL_PREV ? + stsFile->readEntry( dn ) : + verify->getConf( 0, (pn + ".DefaultEntity").latin1(), TQVariant() ).toString(); + field = verify->entitiesFielded() ? + verify->getConf( 0, (pn + ".FocusField").latin1(), TQVariant( 0 ) ).toInt() : + _focusPasswd; + } + verify->presetEntity( ent, field ); + if (userList) + verify->loadUsers( *userList ); +} + +void +KGreeter::verifyPluginChanged( int id ) +{ + curPlugin = id; + pluginSetup(); +} + +void +KGreeter::verifyClear() +{ + curUser = TQString::null; + slotUserEntered(); + slotSessionSelected( -1 ); +} + +void +KGreeter::verifyOk() +{ + if (_preselUser == PRESEL_PREV && verify->entityPresettable()) + stsFile->writeEntry( verify->entitiesLocal() ? + dName : + dName + '_' + verify->pluginName(), + verify->getEntity() ); + if (curSel != -1) { + GSendInt( G_PutDmrc ); + GSendStr( "Session" ); + GSendStr( sessionTypes[curSel].type.utf8() ); + } else if (!prevValid) { + GSendInt( G_PutDmrc ); + GSendStr( "Session" ); + GSendStr( "default" ); + } + GSendInt( G_Ready ); + closingDown = true; + done( ex_exit ); +} + +void +KGreeter::verifyFailed() +{ + if (needLoad) + slotLoadPrevWM(); +} + +void +KGreeter::verifySetUser( const TQString &user ) +{ + curUser = user; + slotUserEntered(); +} + +KStdGreeter::KStdGreeter() + : KGreeter() + , clock( 0 ) + , pixLabel( 0 ) +{ + TQBoxLayout *main_box; +#ifdef WITH_TDM_XCONSOLE + if (consoleView) { + TQBoxLayout *ex_box = new TQVBoxLayout( this, 10, 10 ); + main_box = new TQHBoxLayout( ex_box, 10 ); + ex_box->addWidget( consoleView ); + } else +#endif + main_box = new TQHBoxLayout( this, 10, 10 ); + + if (userView) + main_box->addWidget( userView ); + + TQBoxLayout *inner_box = new TQVBoxLayout( main_box, 10 ); + + if (!_authorized && _authComplain) { + TQLabel *complainLabel = new TQLabel( + i18n("Warning: this is an unsecured session"), this ); + TQToolTip::add( complainLabel, + i18n("This display requires no X authorization.\n" + "This means that anybody can connect to it,\n" + "open windows on it or intercept your input.") ); + complainLabel->setAlignment( AlignCenter ); + complainLabel->setFont( _failFont ); + complainLabel->setPaletteForegroundColor( Qt::red ); + inner_box->addWidget( complainLabel ); + } + if (!_greetString.isEmpty()) { + TQLabel *welcomeLabel = new TQLabel( _greetString, this ); + welcomeLabel->setAlignment( AlignCenter ); + welcomeLabel->setFont( _greetFont ); + inner_box->addWidget( welcomeLabel ); + } + + switch (_logoArea) { + case LOGO_CLOCK: + clock = new KdmClock( this, "clock" ); + break; + case LOGO_LOGO: + { + TQMovie movie( _logo ); + kapp->eventLoop()->processEvents( TQEventLoop::ExcludeUserInput | TQEventLoop::ExcludeSocketNotifiers, 100 ); + TQPixmap pixmap; + if (!movie.framePixmap().isNull() || pixmap.load( _logo )) { + pixLabel = new TQLabel( this ); + if (!movie.framePixmap().isNull()) { + pixLabel->setMovie( movie ); + if (!movie.framePixmap().hasAlpha()) + pixLabel->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); + } else { + pixLabel->setPixmap( pixmap ); + if (!pixmap.hasAlpha()) + pixLabel->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); + } + pixLabel->setIndent( 0 ); + } + } + break; + } + + if (userView) { + if (clock) + inner_box->addWidget( clock, 0, AlignCenter ); + else if (pixLabel) + inner_box->addWidget( pixLabel, 0, AlignCenter ); + } else { + if (clock) + main_box->addWidget( clock, 0, AlignCenter ); + else if (pixLabel) + main_box->addWidget( pixLabel, 0, AlignCenter ); + } + + goButton = new TQPushButton( i18n("L&ogin"), this ); + goButton->setDefault( true ); + connect( goButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); + menuButton = new TQPushButton( i18n("&Menu"), this ); + //helpButton + + TQWidget *prec; + if (userView) + prec = userView; +#ifdef WITH_TDM_XCONSOLE + else if (consoleView) + prec = consoleView; +#endif + else + prec = menuButton; + KGStdVerify *sverify = + new KGStdVerify( this, this, prec, TQString::null, + pluginList, KGreeterPlugin::Authenticate, + KGreeterPlugin::Login ); + inner_box->addLayout( sverify->getLayout() ); + TQPopupMenu *plugMenu = sverify->getPlugMenu(); + sverify->selectPlugin( curPlugin ); + verify = sverify; + + inner_box->addWidget( new KSeparator( KSeparator::HLine, this ) ); + + TQBoxLayout *hbox2 = new TQHBoxLayout( inner_box, 10 ); + hbox2->addWidget( goButton ); + hbox2->addStretch( 1 ); + hbox2->addWidget( menuButton ); + hbox2->addStretch( 1 ); + + if (sessMenu->count() > 1) { + inserten( i18n("Session &Type"), 0, sessMenu ); + needSep = true; + } + + if (plugMenu) { + inserten( i18n("&Authentication Method"), 0, plugMenu ); + needSep = true; + } + +#ifdef XDMCP + completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), 0 ); +#else + completeMenu(); +#endif + + if (userView || userList) + insertUsers(); + + if (optMenu) + menuButton->setPopup( optMenu ); + else + menuButton->hide(); + + pluginSetup(); + + verify->start(); +} + +void +KStdGreeter::pluginSetup() +{ + inherited::pluginSetup(); + if (userView) { + if (verify->entitiesLocal() && verify->entityPresettable()) + userView->show(); + else + userView->hide(); + } + adjustGeometry(); + update(); +} + +void +KStdGreeter::verifyFailed() +{ + goButton->setEnabled( false ); + menuButton->setEnabled( false ); + if (userView) + userView->setEnabled( false ); + inherited::verifyFailed(); +} + +void +KStdGreeter::verifyRetry() +{ + goButton->setEnabled( true ); + menuButton->setEnabled( true ); + if (userView) + userView->setEnabled( true ); +} + + +KThemedGreeter::KThemedGreeter() + : KGreeter( true ) + , themer( 0 ) +// , clock( 0 ) +{ + // We do all painting ourselves + setBackgroundMode( NoBackground ); + // Allow tracking the mouse position + setMouseTracking( true ); + + adjustGeometry(); + + themer = new KdmThemer( _theme, "console", this ); + if (!themer->isOK()) { + delete themer; + themer = 0; + return; + } + + connect( themer, TQT_SIGNAL(activated( const TQString & )), + TQT_SLOT(slotThemeActivated( const TQString & )) ); + + console_rect = themer->findNode( "xconsole" ); // tdm ext + userlist_rect = themer->findNode( "userlist" ); + caps_warning = themer->findNode( "caps-lock-warning" ); + xauth_warning = themer->findNode( "xauth-warning" ); // tdm ext + pam_error = themer->findNode( "pam-error" ); + timed_label = themer->findNode( "timed-label" ); + if (pam_error && pam_error->isA( "KdmLabel" )) + static_cast(pam_error)->setText( i18n("Login Failed.") ); + + KdmItem *itm; + if ((itm = themer->findNode( "pam-message" ))) // done via msgboxes + itm->hide( true ); + if ((itm = themer->findNode( "language_button" ))) // not implemented yet + itm->hide( true ); + +#ifdef WITH_TDM_XCONSOLE + if (console_rect) { + if (consoleView) + console_rect->setWidget( consoleView ); + else + console_rect->hide( true ); + } +#endif + + if (xauth_warning && (_authorized || !_authComplain)) + xauth_warning->hide( true ); + + if (userView || userList) + insertUsers( 7 ); // TODO: find out how many are a good value + +// if (!_greetString.isEmpty()) { +// } +// clock = new KdmClock( this, "clock" ); + + TQWidget *prec; + if (userView) + prec = userView; +#ifdef WITH_TDM_XCONSOLE + else if (consoleView) + prec = consoleView; +#endif + else + prec = 0; + KGThemedVerify *tverify = + new KGThemedVerify( this, themer, this, prec, TQString::null, + pluginList, KGreeterPlugin::Authenticate, + KGreeterPlugin::Login ); + TQPopupMenu *plugMenu = tverify->getPlugMenu(); + tverify->selectPlugin( curPlugin ); + verify = tverify; + + session_button = 0; + if ((itm = themer->findNode( "session_button" ))) { + if (sessMenu->count() <= 1) + itm->hide( true ); + else + session_button = itm; + } else { + if (sessMenu->count() > 1) { + inserten( i18n("Session &Type"), ALT+Key_T, sessMenu ); + needSep = true; + } + } + + admin_button = themer->findNode( "admin_button"); + if ( admin_button ) { + if ( !_useAdminSession ) + admin_button->hide( true ); + } + + if (plugMenu) { + inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu ); + needSep = true; + } + +#ifdef XDMCP + completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), ALT+Key_R ); +#else + completeMenu(); +#endif + + system_button = themer->findNode( "system_button" ); + TQAccel *accel = new TQAccel( this ); + accel->insertItem( ALT+Key_M, 0 ); + connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotActionMenu()) ); + + pluginSetup(); + + verify->start(); +} + +bool +KThemedGreeter::event( TQEvent *e ) +{ + if (themer) + themer->widgetEvent( e ); + return inherited::event( e ); +} + +void +KThemedGreeter::pluginSetup() +{ + inherited::pluginSetup(); + + if (userView && verify->entitiesLocal() && verify->entityPresettable() && userlist_rect) { +// userView->setMaximumHeight( userView->sumHeight() ); + userlist_rect->setWidget( userView ); + } else { + if (userView) + userView->hide(); + if (userlist_rect) + userlist_rect->hide( true ); + } + + update(); +} + +void +KThemedGreeter::verifyFailed() +{ +// goButton->setEnabled( false ); + inherited::verifyFailed(); + if (userView) + userView->setEnabled(false); +} + +void +KThemedGreeter::verifyRetry() +{ +// goButton->setEnabled( true ); + if (userView) + userView->setEnabled(true); + +} + +TQString KThemedGreeter::timedUser = TQString::null; +int KThemedGreeter::timedDelay = -1; + +void +KThemedGreeter::updateStatus( bool fail, bool caps, int timedleft ) +{ + if (pam_error) { + if (fail) + pam_error->show( true ); + else + pam_error->hide( true ); + } + if (caps_warning) { + if (caps) + caps_warning->show( true ); + else + caps_warning->hide( true ); + } + if (timed_label) { + if (timedleft) { + if (timedleft != timedDelay) { + timedDelay = timedleft; + timedUser = curUser; + timed_label->show( true ); + timed_label->update(); + } + } else { + timedDelay = -1; + timed_label->hide( true ); + } + } +} + +void +KThemedGreeter::slotThemeActivated( const TQString &id ) +{ + if (id == "login_button") + accept(); + else if (id == "session_button") + slotSessMenu(); + else if (id == "system_button") + slotActionMenu(); + else if (id == "admin_button") + slotAskAdminPassword(); +} + +void +KThemedGreeter::slotSessMenu() +{ + sessMenu->popup( mapToGlobal( session_button->rect().center() ) ); +} + +void +KThemedGreeter::slotActionMenu() +{ + if (system_button) + optMenu->popup( mapToGlobal( system_button->rect().center() ) ); + else + optMenu->popup( mapToGlobal( rect().center() ) ); +} + +void +KThemedGreeter::keyPressEvent( TQKeyEvent *e ) +{ + inherited::keyPressEvent( e ); + if (!(e->state() & KeyButtonMask) && + (e->key() == Key_Return || e->key() == Key_Enter)) + accept(); +} + +void +KThemedGreeter::slotAskAdminPassword() +{ + TDMAdmin k(curUser, this); + if (k.exec()) { + GSendInt(G_Ready); + hide(); + closingDown = true; + done(ex_exit); + } +} + +#include "kgreeter.moc" diff --git a/tdm/kfrontend/kgreeter.h b/tdm/kfrontend/kgreeter.h new file mode 100644 index 000000000..0de48a21d --- /dev/null +++ b/tdm/kfrontend/kgreeter.h @@ -0,0 +1,180 @@ +/* + +Greeter widget for tdm + +Copyright (C) 1997, 1998 Steffen Hansen +Copyright (C) 2000-2004 Oswald Buddenhagen + + +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. + +*/ + + +#ifndef KGREETER_H +#define KGREETER_H + +#include "kgverify.h" +#include "kgdialog.h" + +class KdmClock; +class UserListView; +class KdmThemer; +class KdmItem; + +class KListView; +class KSimpleConfig; + +class TQLabel; +class TQPushButton; +class TQPopupMenu; +class TQListViewItem; + +struct SessType { + TQString name, type; + bool hid; + int prio; + + SessType() {} + SessType( const TQString &n, const TQString &t, bool h, int p ) : + name( n ), type( t ), hid( h ), prio( p ) {} + bool operator<( const SessType &st ) { + return hid != st.hid ? hid < st.hid : + prio != st.prio ? prio < st.prio : + name < st.name; + } +}; + +class KGreeter : public KGDialog, public KGVerifyHandler { + Q_OBJECT + typedef KGDialog inherited; + + public: + KGreeter( bool themed = false ); + ~KGreeter(); + + public slots: + void accept(); + void reject(); + void done(int r); + void slotUserClicked( TQListViewItem * ); + void slotSessionSelected( int ); + void slotUserEntered(); + void handleInputPipe(); + + public: + TQString curUser, dName; + + protected: + void readFacesList(); + void installUserList(); + void insertUser( const TQImage &, const TQString &, struct passwd * ); + void insertUsers( int limit = -1); + void putSession( const TQString &, const TQString &, bool, const char * ); + void insertSessions(); + virtual void pluginSetup(); + void setPrevWM( int ); + + KSimpleConfig *stsFile; + UserListView *userView; + TQStringList *userList; + TQPopupMenu *sessMenu; + TQValueVector sessionTypes; + TQStringList randomFaces; + TQMap randomFacesMap; + int nNormals, nSpecials; + int curPrev, curSel; + bool prevValid; + bool needLoad; + bool themed; + + static int curPlugin; + static PluginList pluginList; + + private slots: + void slotLoadPrevWM(); + + private: + int mPipe_fd; + TQString mPipeFilename; + + protected: + bool closingDown; + + public: // from KGVerifyHandler + virtual void verifyPluginChanged( int id ); + virtual void verifyClear(); + virtual void verifyOk(); + virtual void verifyFailed(); +// virtual void verifyRetry(); + virtual void verifySetUser( const TQString &user ); +}; + +class KStdGreeter : public KGreeter { + Q_OBJECT + typedef KGreeter inherited; + + public: + KStdGreeter(); + + protected: + virtual void pluginSetup(); + + private: + KdmClock *clock; + TQLabel *pixLabel; + TQPushButton *goButton; + TQPushButton *menuButton; + + public: // from KGVerifyHandler + virtual void verifyFailed(); + virtual void verifyRetry(); +}; + +class KThemedGreeter : public KGreeter { + Q_OBJECT + typedef KGreeter inherited; + + public: + KThemedGreeter(); + bool isOK() { return themer != 0; } + static TQString timedUser; + static int timedDelay; + + public slots: + void slotThemeActivated( const TQString &id ); + void slotSessMenu(); + void slotActionMenu(); + void slotAskAdminPassword(); + + protected: + virtual void updateStatus( bool fail, bool caps, int timedleft ); + virtual void pluginSetup(); + virtual void keyPressEvent( TQKeyEvent * ); + virtual bool event( TQEvent *e ); + + private: +// KdmClock *clock; + KdmThemer *themer; + KdmItem *caps_warning, *xauth_warning, *pam_error, *timed_label, + *console_rect, *userlist_rect, + *session_button, *system_button, *admin_button; + + public: // from KGVerifyHandler + virtual void verifyFailed(); + virtual void verifyRetry(); +}; + +#endif /* KGREETER_H */ diff --git a/tdm/kfrontend/kgverify.cpp b/tdm/kfrontend/kgverify.cpp new file mode 100644 index 000000000..ec0bfae6c --- /dev/null +++ b/tdm/kfrontend/kgverify.cpp @@ -0,0 +1,1218 @@ +/* + +Shell for tdm conversation plugins + +Copyright (C) 1997, 1998, 2000 Steffen Hansen +Copyright (C) 2000-2004 Oswald Buddenhagen + + +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 + +#include "kgverify.h" +#include "tdmconfig.h" +#include "tdm_greet.h" + +#include "themer/tdmthemer.h" +#include "themer/tdmitem.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include // for updateLockStatus() +#include // ... and make eventFilter() work again + +#define FULL_GREET_TO 40 // normal inactivity timeout +#define TIMED_GREET_TO 20 // inactivity timeout when persisting timed login +#define MIN_TIMED_TO 5 // minimal timed login delay +#define DEAD_TIMED_TO 2 // dead time after re-activating timed login +#define SECONDS 1000 // reduce to 100 to speed up testing + +void KGVerifyHandler::verifyClear() +{ +} + +void KGVerifyHandler::updateStatus( bool, bool, int ) +{ +} + +KGVerify::KGVerify( KGVerifyHandler *_handler, KdmThemer *_themer, + TQWidget *_parent, TQWidget *_predecessor, + const TQString &_fixedUser, + const PluginList &_pluginList, + KGreeterPlugin::Function _func, + KGreeterPlugin::Context _ctx ) + : inherited() + , coreLock( 0 ) + , fixedEntity( _fixedUser ) + , pluginList( _pluginList ) + , handler( _handler ) + , themer( _themer ) + , parent( _parent ) + , predecessor( _predecessor ) + , plugMenu( 0 ) + , curPlugin( -1 ) + , timedLeft( 0 ) + , func( _func ) + , ctx( _ctx ) + , enabled( true ) + , running( false ) + , suspended( false ) + , failed( false ) + , isClear( true ) +{ + connect( &timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeout()) ); + connect( kapp, TQT_SIGNAL(activity()), TQT_SLOT(slotActivity()) ); + + _parent->installEventFilter( this ); +} + +KGVerify::~KGVerify() +{ + Debug( "delete %s\n", pName.data() ); + delete greet; +} + +TQPopupMenu * +KGVerify::getPlugMenu() +{ + // assert( !cont ); + if (!plugMenu) { + uint np = pluginList.count(); + if (np > 1) { + plugMenu = new TQPopupMenu( parent ); + connect( plugMenu, TQT_SIGNAL(activated( int )), + TQT_SLOT(slotPluginSelected( int )) ); + for (uint i = 0; i < np; i++) + plugMenu->insertItem( i18n(greetPlugins[pluginList[i]].info->name), pluginList[i] ); + } + } + return plugMenu; +} + +bool // public +KGVerify::entitiesLocal() const +{ + return greetPlugins[pluginList[curPlugin]].info->flags & kgreeterplugin_info::Local; +} + +bool // public +KGVerify::entitiesFielded() const +{ + return greetPlugins[pluginList[curPlugin]].info->flags & kgreeterplugin_info::Fielded; +} + +bool // public +KGVerify::entityPresettable() const +{ + return greetPlugins[pluginList[curPlugin]].info->flags & kgreeterplugin_info::Presettable; +} + +bool // public +KGVerify::isClassic() const +{ + return !strcmp( greetPlugins[pluginList[curPlugin]].info->method, "classic" ); +} + +TQString // public +KGVerify::pluginName() const +{ + TQString name( greetPlugins[pluginList[curPlugin]].library->fileName() ); + uint st = name.findRev( '/' ) + 1; + uint en = name.find( '.', st ); + if (en - st > 7 && TQConstString( name.unicode() + st, 7 ).string() == "kgreet_") + st += 7; + return name.mid( st, en - st ); +} + +static void +showWidgets( TQLayoutItem *li ) +{ + TQWidget *w; + TQLayout *l; + + if ((w = li->widget())) + w->show(); + else if ((l = li->layout())) { + TQLayoutIterator it = l->iterator(); + for (TQLayoutItem *itm = it.current(); itm; itm = ++it) + showWidgets( itm ); + } +} + +void // public +KGVerify::selectPlugin( int id ) +{ + if (pluginList.isEmpty()) { + MsgBox( errorbox, i18n("No greeter widget plugin loaded. Check the configuration.") ); + ::exit( EX_UNMANAGE_DPY ); + } + curPlugin = id; + if (plugMenu) + plugMenu->setItemChecked( id, true ); + pName = ("greet_" + pluginName()).latin1(); + Debug( "new %s\n", pName.data() ); + greet = greetPlugins[pluginList[id]].info->create( this, themer, parent, predecessor, fixedEntity, func, ctx ); + timeable = _autoLoginDelay && entityPresettable() && isClassic(); +} + +void // public +KGVerify::loadUsers( const TQStringList &users ) +{ + Debug( "%s->loadUsers(...)\n", pName.data() ); + greet->loadUsers( users ); +} + +void // public +KGVerify::presetEntity( const TQString &entity, int field ) +{ + presEnt = entity; + presFld = field; +} + +bool // private +KGVerify::applyPreset() +{ + if (!presEnt.isEmpty()) { + Debug( "%s->presetEntity(%\"s, %d)\n", pName.data(), + presEnt.latin1(), presFld ); + greet->presetEntity( presEnt, presFld ); + if (entitiesLocal()) { + curUser = presEnt; + handler->verifySetUser( presEnt ); + } + return true; + } + return false; +} + +bool // private +KGVerify::scheduleAutoLogin( bool initial ) +{ + if (timeable) { + Debug( "%s->presetEntity(%\"s, -1)\n", pName.data(), + _autoLoginUser.latin1(), -1 ); + greet->presetEntity( _autoLoginUser, -1 ); + curUser = _autoLoginUser; + handler->verifySetUser( _autoLoginUser ); + timer.start( 1000 ); + if (initial) { + timedLeft = _autoLoginDelay; + deadTicks = 0; + } else { + timedLeft = QMAX( _autoLoginDelay - TIMED_GREET_TO, MIN_TIMED_TO ); + deadTicks = DEAD_TIMED_TO; + } + updateStatus(); + running = false; + isClear = true; + return true; + } + return false; +} + +void // private +KGVerify::performAutoLogin() +{ +// timer.stop(); + GSendInt( G_AutoLogin ); + handleVerify(); +} + +TQString // public +KGVerify::getEntity() const +{ + Debug( "%s->getEntity()\n", pName.data() ); + TQString ent = greet->getEntity(); + Debug( " entity: %s\n", ent.latin1() ); + return ent; +} + +void +KGVerify::setUser( const TQString &user ) +{ + // assert( fixedEntity.isEmpty() ); + curUser = user; + Debug( "%s->setUser(%\"s)\n", pName.data(), user.latin1() ); + greet->setUser( user ); + gplugActivity(); +} + +void +KGVerify::setPassword( const TQString &pass ) +{ + greet->setPassword( pass ); + gplugActivity(); +} + +void +KGVerify::start() +{ + authTok = (func == KGreeterPlugin::ChAuthTok); + cont = false; + if (func == KGreeterPlugin::Authenticate && ctx == KGreeterPlugin::Login) { + if (scheduleAutoLogin( true )) { + if (!_autoLoginAgain) + _autoLoginDelay = 0, timeable = false; + return; + } else + applyPreset(); + } + running = true; + Debug( "%s->start()\n", pName.data() ); + greet->start(); + if (!(func == KGreeterPlugin::Authenticate || + ctx == KGreeterPlugin::ChangeTok || + ctx == KGreeterPlugin::ExChangeTok)) + { + cont = true; + handleVerify(); + } +} + +void +KGVerify::abort() +{ + Debug( "%s->abort()\n", pName.data() ); + greet->abort(); + running = false; +} + +void +KGVerify::suspend() +{ + // assert( !cont ); + if (running) { + Debug( "%s->abort()\n", pName.data() ); + greet->abort(); + } + suspended = true; + updateStatus(); + timer.suspend(); +} + +void +KGVerify::resume() +{ + timer.resume(); + suspended = false; + updateLockStatus(); + if (running) { + Debug( "%s->start()\n", pName.data() ); + greet->start(); + } else if (delayed) { + delayed = false; + running = true; + Debug( "%s->start()\n", pName.data() ); + greet->start(); + } +} + +void // not a slot - called manually by greeter +KGVerify::accept() +{ + Debug( "%s->next()\n", pName.data() ); + greet->next(); +} + +void // private +KGVerify::doReject( bool initial ) +{ + // assert( !cont ); + if (running) { + Debug( "%s->abort()\n", pName.data() ); + greet->abort(); + } + handler->verifyClear(); + Debug( "%s->clear()\n", pName.data() ); + greet->clear(); + curUser = TQString::null; + if (!scheduleAutoLogin( initial )) { + isClear = !(isClear && applyPreset()); + if (running) { + Debug( "%s->start()\n", pName.data() ); + greet->start(); + } + if (!failed) + timer.stop(); + } +} + +void // not a slot - called manually by greeter +KGVerify::reject() +{ + doReject( true ); +} + +void +KGVerify::setEnabled( bool on ) +{ + Debug( "%s->setEnabled(%s)\n", pName.data(), on ? "true" : "false" ); + greet->setEnabled( on ); + enabled = on; + updateStatus(); +} + +void // private +KGVerify::slotTimeout() +{ + if (failed) { + failed = false; + updateStatus(); + Debug( "%s->revive()\n", pName.data() ); + greet->revive(); + handler->verifyRetry(); + if (suspended) + delayed = true; + else { + running = true; + Debug( "%s->start()\n", pName.data() ); + greet->start(); + slotActivity(); + gplugActivity(); + if (cont) + handleVerify(); + } + } else if (timedLeft) { + deadTicks--; + if (!--timedLeft) + performAutoLogin(); + else + timer.start( 1000 ); + updateStatus(); + } else { + // assert( ctx == Login ); + isClear = true; + doReject( false ); + } +} + +void +KGVerify::slotActivity() +{ + if (timedLeft) { + Debug( "%s->revive()\n", pName.data() ); + greet->revive(); + Debug( "%s->start()\n", pName.data() ); + greet->start(); + running = true; + timedLeft = 0; + updateStatus(); + timer.start( TIMED_GREET_TO * SECONDS ); + } else if (timeable) + timer.start( TIMED_GREET_TO * SECONDS ); +} + + +void // private static +KGVerify::VMsgBox( TQWidget *parent, const TQString &user, + TQMessageBox::Icon type, const TQString &mesg ) +{ + FDialog::box( parent, type, user.isEmpty() ? + mesg : i18n("Authenticating %1...\n\n").arg( user ) + mesg ); +} + +static const char *msgs[]= { + I18N_NOOP( "You are required to change your password immediately (password aged)." ), + I18N_NOOP( "You are required to change your password immediately (root enforced)." ), + I18N_NOOP( "You are not allowed to login at the moment." ), + I18N_NOOP( "Home folder not available." ), + I18N_NOOP( "Logins are not allowed at the moment.\nTry again later." ), + I18N_NOOP( "Your login shell is not listed in /etc/shells." ), + I18N_NOOP( "Root logins are not allowed." ), + I18N_NOOP( "Your account has expired; please contact your system administrator." ) +}; + +void // private static +KGVerify::VErrBox( TQWidget *parent, const TQString &user, const char *msg ) +{ + TQMessageBox::Icon icon; + TQString mesg; + + if (!msg) { + mesg = i18n("A critical error occurred.\n" + "Please look at TDM's logfile(s) for more information\n" + "or contact your system administrator."); + icon = errorbox; + } else { + mesg = TQString::fromLocal8Bit( msg ); + TQString mesg1 = mesg + '.'; + for (uint i = 0; i < as(msgs); i++) + if (mesg1 == msgs[i]) { + mesg = i18n(msgs[i]); + break; + } + icon = sorrybox; + } + VMsgBox( parent, user, icon, mesg ); +} + +void // private static +KGVerify::VInfoBox( TQWidget *parent, const TQString &user, const char *msg ) +{ + TQString mesg = TQString::fromLocal8Bit( msg ); + TQRegExp rx( "^Warning: your account will expire in (\\d+) day" ); + if (rx.search( mesg ) >= 0) { + int expire = rx.cap( 1 ).toInt(); + mesg = expire ? + i18n("Your account expires tomorrow.", + "Your account expires in %n days.", expire) : + i18n("Your account expires today."); + } else { + rx.setPattern( "^Warning: your password will expire in (\\d+) day" ); + if (rx.search( mesg ) >= 0) { + int expire = rx.cap( 1 ).toInt(); + mesg = expire ? + i18n("Your password expires tomorrow.", + "Your password expires in %n days.", expire) : + i18n("Your password expires today."); + } + } + VMsgBox( parent, user, infobox, mesg ); +} + +bool // public static +KGVerify::handleFailVerify( TQWidget *parent ) +{ + Debug( "handleFailVerify ...\n" ); + char *msg = GRecvStr(); + TQString user = TQString::fromLocal8Bit( msg ); + free( msg ); + + for (;;) { + int ret = GRecvInt(); + + // non-terminal status + switch (ret) { + /* case V_PUT_USER: cannot happen - we are in "classic" mode */ + /* case V_PRE_OK: cannot happen - not in ChTok dialog */ + /* case V_CHTOK: cannot happen - called by non-interactive verify */ + case V_CHTOK_AUTH: + Debug( " V_CHTOK_AUTH\n" ); + { + TQStringList pgs( _pluginsLogin ); + pgs += _pluginsShutdown; + TQStringList::ConstIterator it; + for (it = pgs.begin(); it != pgs.end(); ++it) + if (*it == "classic" || *it == "modern") { + pgs = *it; + goto gotit; + } else if (*it == "generic") { + pgs = "modern"; + goto gotit; + } + pgs = "classic"; + gotit: + KGChTok chtok( parent, user, init( pgs ), 0, + KGreeterPlugin::AuthChAuthTok, + KGreeterPlugin::Login ); + return chtok.exec(); + } + case V_MSG_ERR: + Debug( " V_MSG_ERR\n" ); + msg = GRecvStr(); + Debug( " message %\"s\n", msg ); + VErrBox( parent, user, msg ); + if (msg) + free( msg ); + continue; + case V_MSG_INFO: + Debug( " V_MSG_INFO\n" ); + msg = GRecvStr(); + Debug( " message %\"s\n", msg ); + VInfoBox( parent, user, msg ); + free( msg ); + continue; + } + + // terminal status + switch (ret) { + case V_OK: + Debug( " V_OK\n" ); + return true; + case V_AUTH: + Debug( " V_AUTH\n" ); + VMsgBox( parent, user, sorrybox, i18n("Authentication failed") ); + return false; + case V_FAIL: + Debug( " V_FAIL\n" ); + return false; + default: + LogPanic( "Unknown V_xxx code %d from core\n", ret ); + } + } +} + +void // private +KGVerify::handleVerify() +{ + TQString user; + + Debug( "handleVerify ...\n" ); + for (;;) { + char *msg; + int ret, echo, ndelay; + KGreeterPlugin::Function nfunc; + + ret = GRecvInt(); + + // requests + coreLock = 1; + switch (ret) { + case V_GET_TEXT: + Debug( " V_GET_TEXT\n" ); + msg = GRecvStr(); + Debug( " prompt %\"s\n", msg ); + echo = GRecvInt(); + Debug( " echo = %d\n", echo ); + ndelay = GRecvInt(); + Debug( " ndelay = %d\n%s->textPrompt(...)\n", ndelay, pName.data() ); + greet->textPrompt( msg, echo, ndelay ); + if (msg) + free( msg ); + return; + case V_GET_BINARY: + Debug( " V_GET_BINARY\n" ); + msg = GRecvArr( &ret ); + Debug( " %d bytes prompt\n", ret ); + ndelay = GRecvInt(); + Debug( " ndelay = %d\n%s->binaryPrompt(...)\n", ndelay, pName.data() ); + greet->binaryPrompt( msg, ndelay ); + if (msg) + free( msg ); + return; + } + + // non-terminal status + coreLock = 2; + switch (ret) { + case V_PUT_USER: + Debug( " V_PUT_USER\n" ); + msg = GRecvStr(); + curUser = user = TQString::fromLocal8Bit( msg ); + // greet needs this to be able to return something useful from + // getEntity(). but the backend is still unable to tell a domain ... + Debug( " %s->setUser(%\"s)\n", pName.data(), user.latin1() ); + greet->setUser( curUser ); + handler->verifySetUser( curUser ); + if (msg) + free( msg ); + continue; + case V_PRE_OK: // this is only for func == AuthChAuthTok + Debug( " V_PRE_OK\n" ); + // With the "classic" method, the wrong user simply cannot be + // authenticated, even with the generic plugin. Other methods + // could do so, but this applies only to ctx == ChangeTok, which + // is not implemented yet. + authTok = true; + cont = true; + Debug( "%s->succeeded()\n", pName.data() ); + greet->succeeded(); + continue; + case V_CHTOK_AUTH: + Debug( " V_CHTOK_AUTH\n" ); + nfunc = KGreeterPlugin::AuthChAuthTok; + user = curUser; + goto dchtok; + case V_CHTOK: + Debug( " V_CHTOK\n" ); + nfunc = KGreeterPlugin::ChAuthTok; + user = TQString::null; + dchtok: + { + timer.stop(); + Debug( "%s->succeeded()\n", pName.data() ); + greet->succeeded(); + KGChTok chtok( parent, user, pluginList, curPlugin, nfunc, KGreeterPlugin::Login ); + if (!chtok.exec()) + goto retry; + handler->verifyOk(); + return; + } + case V_MSG_ERR: + Debug( " V_MSG_ERR\n" ); + msg = GRecvStr(); + Debug( " %s->textMessage(%\"s, true)\n", pName.data(), msg ); + if (!greet->textMessage( msg, true )) { + Debug( " message passed\n" ); + VErrBox( parent, user, msg ); + } else + Debug( " message swallowed\n" ); + if (msg) + free( msg ); + continue; + case V_MSG_INFO: + Debug( " V_MSG_INFO\n" ); + msg = GRecvStr(); + Debug( " %s->textMessage(%\"s, false)\n", pName.data(), msg ); + if (!greet->textMessage( msg, false )) { + Debug( " message passed\n" ); + VInfoBox( parent, user, msg ); + } else + Debug( " message swallowed\n" ); + free( msg ); + continue; + } + + // terminal status + coreLock = 0; + running = false; + timer.stop(); + + if (ret == V_OK) { + Debug( " V_OK\n" ); + if (!fixedEntity.isEmpty()) { + Debug( " %s->getEntity()\n", pName.data() ); + TQString ent = greet->getEntity(); + Debug( " entity %\"s\n", ent.latin1() ); + if (ent != fixedEntity) { + Debug( "%s->failed()\n", pName.data() ); + greet->failed(); + MsgBox( sorrybox, + i18n("Authenticated user (%1) does not match requested user (%2).\n") + .arg( ent ).arg( fixedEntity ) ); + goto retry; + } + } + Debug( "%s->succeeded()\n", pName.data() ); + greet->succeeded(); + handler->verifyOk(); + return; + } + + Debug( "%s->failed()\n", pName.data() ); + greet->failed(); + + if (ret == V_AUTH) { + Debug( " V_AUTH\n" ); + failed = true; + updateStatus(); + handler->verifyFailed(); + timer.start( 1500 + kapp->random()/(RAND_MAX/1000) ); + return; + } + if (ret != V_FAIL) + LogPanic( "Unknown V_xxx code %d from core\n", ret ); + Debug( " V_FAIL\n" ); + retry: + Debug( "%s->revive()\n", pName.data() ); + greet->revive(); + running = true; + Debug( "%s->start()\n", pName.data() ); + greet->start(); + if (!cont) + return; + user = TQString::null; + } +} + +void +KGVerify::gplugReturnText( const char *text, int tag ) +{ + Debug( "%s: gplugReturnText(%\"s, %d)\n", pName.data(), + tag & V_IS_SECRET ? "" : text, tag ); + GSendStr( text ); + if (text) { + GSendInt( tag ); + handleVerify(); + } else + coreLock = 0; +} + +void +KGVerify::gplugReturnBinary( const char *data ) +{ + if (data) { + unsigned const char *up = (unsigned const char *)data; + int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24); + Debug( "%s: gplugReturnBinary(%d bytes)\n", pName.data(), len ); + GSendArr( len, data ); + handleVerify(); + } else { + Debug( "%s: gplugReturnBinary(NULL)\n", pName.data() ); + GSendArr( 0, 0 ); + coreLock = 0; + } +} + +void +KGVerify::gplugSetUser( const TQString &user ) +{ + Debug( "%s: gplugSetUser(%\"s)\n", pName.data(), user.latin1() ); + curUser = user; + handler->verifySetUser( user ); +} + +void +KGVerify::gplugStart() +{ + // XXX handle func != Authenticate + Debug( "%s: gplugStart()\n", pName.data() ); + GSendInt( ctx == KGreeterPlugin::Shutdown ? G_VerifyRootOK : G_Verify ); + GSendStr( greetPlugins[pluginList[curPlugin]].info->method ); + handleVerify(); +} + +void +KGVerify::gplugActivity() +{ + Debug( "%s: gplugActivity()\n", pName.data() ); + if (func == KGreeterPlugin::Authenticate && + ctx == KGreeterPlugin::Login) + { + isClear = false; + if (!timeable) + timer.start( FULL_GREET_TO * SECONDS ); + } +} + +void +KGVerify::gplugMsgBox( TQMessageBox::Icon type, const TQString &text ) +{ + Debug( "%s: gplugMsgBox(%d, %\"s)\n", pName.data(), type, text.latin1() ); + MsgBox( type, text ); +} + +bool +KGVerify::eventFilter( TQObject *o, TQEvent *e ) +{ + switch (e->type()) { + case TQEvent::KeyPress: + if (timedLeft) { + TQKeyEvent *ke = (TQKeyEvent *)e; + if (ke->key() == Key_Return || ke->key() == Key_Enter) { + if (deadTicks <= 0) { + timedLeft = 0; + performAutoLogin(); + } + return true; + } + } + /* fall through */ + case TQEvent::KeyRelease: + updateLockStatus(); + /* fall through */ + default: + break; + } + return inherited::eventFilter( o, e ); +} + +void +KGVerify::updateLockStatus() +{ + unsigned int lmask; + Window dummy1, dummy2; + int dummy3, dummy4, dummy5, dummy6; + XQueryPointer( qt_xdisplay(), DefaultRootWindow( qt_xdisplay() ), + &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, + &lmask ); + capsLocked = lmask & LockMask; + updateStatus(); +} + +void +KGVerify::MsgBox( TQMessageBox::Icon typ, const TQString &msg ) +{ + timer.suspend(); + FDialog::box( parent, typ, msg ); + timer.resume(); +} + + +TQVariant // public static +KGVerify::getConf( void *, const char *key, const TQVariant &dflt ) +{ + if (!qstrcmp( key, "EchoMode" )) + return TQVariant( _echoMode ); + else { + TQString fkey = TQString::fromLatin1( key ) + '='; + for (TQStringList::ConstIterator it = _pluginOptions.begin(); + it != _pluginOptions.end(); ++it) + if ((*it).startsWith( fkey )) + return (*it).mid( fkey.length() ); + return dflt; + } +} + +TQValueVector KGVerify::greetPlugins; + +PluginList +KGVerify::init( const TQStringList &plugins ) +{ + PluginList pluginList; + + for (TQStringList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it) { + GreeterPluginHandle plugin; + TQString path = KLibLoader::self()->findLibrary( + ((*it)[0] == '/' ? *it : "kgreet_" + *it ).latin1() ); + if (path.isEmpty()) { + LogError( "GreeterPlugin %s does not exist\n", (*it).latin1() ); + continue; + } + uint i, np = greetPlugins.count(); + for (i = 0; i < np; i++) + if (greetPlugins[i].library->fileName() == path) + goto next; + if (!(plugin.library = KLibLoader::self()->library( path.latin1() ))) { + LogError( "Cannot load GreeterPlugin %s (%s)\n", (*it).latin1(), path.latin1() ); + continue; + } + if (!plugin.library->hasSymbol( "kgreeterplugin_info" )) { + LogError( "GreeterPlugin %s (%s) is no valid greet widget plugin\n", + (*it).latin1(), path.latin1() ); + plugin.library->unload(); + continue; + } + plugin.info = (kgreeterplugin_info*)plugin.library->symbol( "kgreeterplugin_info" ); + if (!plugin.info->init( TQString::null, getConf, 0 )) { + LogError( "GreeterPlugin %s (%s) refuses to serve\n", + (*it).latin1(), path.latin1() ); + plugin.library->unload(); + continue; + } + Debug( "GreeterPlugin %s (%s) loaded\n", (*it).latin1(), plugin.info->name ); + greetPlugins.append( plugin ); + next: + pluginList.append( i ); + } + return pluginList; +} + +void +KGVerify::done() +{ + for (uint i = 0; i < greetPlugins.count(); i++) { + if (greetPlugins[i].info->done) + greetPlugins[i].info->done(); + greetPlugins[i].library->unload(); + } +} + + +KGStdVerify::KGStdVerify( KGVerifyHandler *_handler, TQWidget *_parent, + TQWidget *_predecessor, const TQString &_fixedUser, + const PluginList &_pluginList, + KGreeterPlugin::Function _func, + KGreeterPlugin::Context _ctx ) + : inherited( _handler, 0, _parent, _predecessor, _fixedUser, + _pluginList, _func, _ctx ) + , failedLabelState( 0 ) +{ + grid = new TQGridLayout; + grid->setAlignment( AlignCenter ); + + failedLabel = new TQLabel( parent ); + failedLabel->setFont( _failFont ); + grid->addWidget( failedLabel, 1, 0, Qt::AlignCenter ); + + updateLockStatus(); +} + +KGStdVerify::~KGStdVerify() +{ + grid->removeItem( greet->getLayoutItem() ); +} + +void // public +KGStdVerify::selectPlugin( int id ) +{ + inherited::selectPlugin( id ); + grid->addItem( greet->getLayoutItem(), 0, 0 ); + showWidgets( greet->getLayoutItem() ); +} + +void // private slot +KGStdVerify::slotPluginSelected( int id ) +{ + if (failed) + return; + if (id != curPlugin) { + plugMenu->setItemChecked( curPlugin, false ); + parent->setUpdatesEnabled( false ); + grid->removeItem( greet->getLayoutItem() ); + Debug( "delete %s\n", pName.data() ); + delete greet; + selectPlugin( id ); + handler->verifyPluginChanged( id ); + if (running) + start(); + parent->setUpdatesEnabled( true ); + } +} + +void +KGStdVerify::updateStatus() +{ + int nfls; + + if (!enabled) + nfls = 1; + else if (failed) + nfls = 2; + else if (timedLeft) + nfls = -timedLeft; + else if (!suspended && capsLocked) + nfls = 3; + else + nfls = 1; + + if (failedLabelState != nfls) { + failedLabelState = nfls; + if (nfls < 0) { + failedLabel->setPaletteForegroundColor( Qt::black ); + failedLabel->setText( i18n( "Automatic login in 1 second...", + "Automatic login in %n seconds...", + timedLeft ) ); + } else { + switch (nfls) { + default: + failedLabel->clear(); + break; + case 3: + failedLabel->setPaletteForegroundColor( Qt::red ); + failedLabel->setText( i18n("Warning: Caps Lock on") ); + break; + case 2: + failedLabel->setPaletteForegroundColor( Qt::black ); + failedLabel->setText( authTok ? + i18n("Change failed") : + fixedEntity.isEmpty() ? + i18n("Login failed") : + i18n("Authentication failed") ); + break; + } + } + } +} + +KGThemedVerify::KGThemedVerify( KGVerifyHandler *_handler, + KdmThemer *_themer, + TQWidget *_parent, TQWidget *_predecessor, + const TQString &_fixedUser, + const PluginList &_pluginList, + KGreeterPlugin::Function _func, + KGreeterPlugin::Context _ctx ) + : inherited( _handler, _themer, _parent, _predecessor, _fixedUser, + _pluginList, _func, _ctx ) +{ + updateLockStatus(); +} + +KGThemedVerify::~KGThemedVerify() +{ +} + +void // public +KGThemedVerify::selectPlugin( int id ) +{ + inherited::selectPlugin( id ); + TQLayoutItem *l; + KdmItem *n; + if (themer && (l = greet->getLayoutItem())) { + if (!(n = themer->findNode( "talker" ))) + MsgBox( errorbox, + i18n("Theme not usable with authentication method '%1'.") + .arg( i18n(greetPlugins[pluginList[id]].info->name) ) ); + else { + n->setLayoutItem( l ); + showWidgets( l ); + } + } + if (themer) + themer->updateGeometry( true ); +} + +void // private slot +KGThemedVerify::slotPluginSelected( int id ) +{ + if (failed) + return; + if (id != curPlugin) { + plugMenu->setItemChecked( curPlugin, false ); + Debug( "delete %s\n", pName.data() ); + delete greet; + selectPlugin( id ); + handler->verifyPluginChanged( id ); + if (running) + start(); + } +} + +void +KGThemedVerify::updateStatus() +{ + handler->updateStatus( enabled && failed, + enabled && !suspended && capsLocked, + timedLeft ); +} + + +KGChTok::KGChTok( TQWidget *_parent, const TQString &user, + const PluginList &pluginList, int curPlugin, + KGreeterPlugin::Function func, + KGreeterPlugin::Context ctx ) + : inherited( _parent ) + , verify( 0 ) +{ + TQSizePolicy fp( TQSizePolicy::Fixed, TQSizePolicy::Fixed ); + okButton = new KPushButton( KStdGuiItem::ok(), this ); + okButton->setSizePolicy( fp ); + okButton->setDefault( true ); + cancelButton = new KPushButton( KStdGuiItem::cancel(), this ); + cancelButton->setSizePolicy( fp ); + + verify = new KGStdVerify( this, this, cancelButton, user, pluginList, func, ctx ); + verify->selectPlugin( curPlugin ); + + TQVBoxLayout *box = new TQVBoxLayout( this, 10 ); + + box->addWidget( new TQLabel( i18n("Changing authentication token"), this ), 0, AlignHCenter ); + + box->addLayout( verify->getLayout() ); + + box->addWidget( new KSeparator( KSeparator::HLine, this ) ); + + TQHBoxLayout *hlay = new TQHBoxLayout( box ); + hlay->addStretch( 1 ); + hlay->addWidget( okButton ); + hlay->addStretch( 1 ); + hlay->addWidget( cancelButton ); + hlay->addStretch( 1 ); + + connect( okButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); + connect( cancelButton, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) ); + + TQTimer::singleShot( 0, verify, TQT_SLOT(start()) ); +} + +KGChTok::~KGChTok() +{ + hide(); + delete verify; +} + +void +KGChTok::accept() +{ + verify->accept(); +} + +void +KGChTok::verifyPluginChanged( int ) +{ + // cannot happen +} + +void +KGChTok::verifyOk() +{ + inherited::accept(); +} + +void +KGChTok::verifyFailed() +{ + okButton->setEnabled( false ); + cancelButton->setEnabled( false ); +} + +void +KGChTok::verifyRetry() +{ + okButton->setEnabled( true ); + cancelButton->setEnabled( true ); +} + +void +KGChTok::verifySetUser( const TQString & ) +{ + // cannot happen +} + + +////// helper class, nuke when qtimer supports suspend()/resume() + +QXTimer::QXTimer() + : inherited( 0 ) + , left( -1 ) +{ + connect( &timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeout()) ); +} + +void +QXTimer::start( int msec ) +{ + left = msec; + timer.start( left, true ); + gettimeofday( &stv, 0 ); +} + +void +QXTimer::stop() +{ + timer.stop(); + left = -1; +} + +void +QXTimer::suspend() +{ + if (timer.isActive()) { + timer.stop(); + struct timeval tv; + gettimeofday( &tv, 0 ); + left -= (tv.tv_sec - stv.tv_sec) * 1000 + (tv.tv_usec - stv.tv_usec) / 1000; + if (left < 0) + left = 0; + } +} + +void +QXTimer::resume() +{ + if (left >= 0 && !timer.isActive()) { + timer.start( left, true ); + gettimeofday( &stv, 0 ); + } +} + +void +QXTimer::slotTimeout() +{ + left = 0; + emit timeout(); +} + + +#include "kgverify.moc" diff --git a/tdm/kfrontend/kgverify.h b/tdm/kfrontend/kgverify.h new file mode 100644 index 000000000..44fab973a --- /dev/null +++ b/tdm/kfrontend/kgverify.h @@ -0,0 +1,249 @@ +/* + +Shell for tdm conversation plugins + +Copyright (C) 1997, 1998 Steffen Hansen +Copyright (C) 2000-2004 Oswald Buddenhagen + + +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. + +*/ + + +#ifndef KGVERIFY_H +#define KGVERIFY_H + +#include "kgreeterplugin.h" +#include "kfdialog.h" + +#include +#include +#include + +#include +#include + +// helper class, nuke when qt supports suspend()/resume() +class QXTimer : public TQObject { + Q_OBJECT + typedef TQObject inherited; + + public: + QXTimer(); + void start( int msec ); + void stop(); + void suspend(); + void resume(); + + signals: + void timeout(); + + private slots: + void slotTimeout(); + + private: + TQTimer timer; + struct timeval stv; + long left; +}; + +class KGVerifyHandler { + public: + virtual void verifyPluginChanged( int id ) = 0; + virtual void verifyClear(); + virtual void verifyOk() = 0; + virtual void verifyFailed() = 0; + virtual void verifyRetry() = 0; + virtual void verifySetUser( const TQString &user ) = 0; + virtual void updateStatus( bool fail, bool caps, int left ); // for themed only +}; + +class TQWidget; +class TQLabel; +class TQPopupMenu; +class TQTimer; +class KPushButton; +class KLibrary; + +struct GreeterPluginHandle { + KLibrary *library; + kgreeterplugin_info *info; +}; + +typedef TQValueVector PluginList; + +class KGVerify : public TQObject, public KGreeterPluginHandler { + Q_OBJECT + typedef TQObject inherited; + + public: + KGVerify( KGVerifyHandler *handler, KdmThemer *themer, + TQWidget *parent, TQWidget *predecessor, + const TQString &fixedEntity, const PluginList &pluginList, + KGreeterPlugin::Function func, KGreeterPlugin::Context ctx ); + virtual ~KGVerify(); + TQPopupMenu *getPlugMenu(); + void loadUsers( const TQStringList &users ); + void presetEntity( const TQString &entity, int field ); + TQString getEntity() const; + void setUser( const TQString &user ); + void setPassword( const TQString &pass ); + /* virtual */ void selectPlugin( int id ); + bool entitiesLocal() const; + bool entitiesFielded() const; + bool entityPresettable() const; + bool isClassic() const; + TQString pluginName() const; + void setEnabled( bool on ); + void abort(); + void suspend(); + void resume(); + void accept(); + void reject(); + + int coreLock; + + static bool handleFailVerify( TQWidget *parent ); + static PluginList init( const TQStringList &plugins ); + static void done(); + + public slots: + void start(); + + protected: + bool eventFilter( TQObject *, TQEvent * ); + void MsgBox( TQMessageBox::Icon typ, const TQString &msg ); + void setTimer(); + void updateLockStatus(); + virtual void updateStatus() = 0; + void handleVerify(); + + QXTimer timer; + TQString fixedEntity, presEnt, curUser; + PluginList pluginList; + KGVerifyHandler *handler; + KdmThemer *themer; + TQWidget *parent, *predecessor; + KGreeterPlugin *greet; + TQPopupMenu *plugMenu; + int curPlugin, presFld, timedLeft, deadTicks; + TQCString pName; + KGreeterPlugin::Function func; + KGreeterPlugin::Context ctx; + bool capsLocked; + bool enabled, running, suspended, failed, delayed, cont; + bool authTok, isClear, timeable; + + static void VMsgBox( TQWidget *parent, const TQString &user, TQMessageBox::Icon type, const TQString &mesg ); + static void VErrBox( TQWidget *parent, const TQString &user, const char *msg ); + static void VInfoBox( TQWidget *parent, const TQString &user, const char *msg ); + + static TQValueVector greetPlugins; + + private: + bool applyPreset(); + void performAutoLogin(); + bool scheduleAutoLogin( bool initial ); + void doReject( bool initial ); + + private slots: + //virtual void slotPluginSelected( int id ) = 0; + void slotTimeout(); + void slotActivity(); + + public: // from KGreetPluginHandler + virtual void gplugReturnText( const char *text, int tag ); + virtual void gplugReturnBinary( const char *data ); + virtual void gplugSetUser( const TQString &user ); + virtual void gplugStart(); + virtual void gplugActivity(); + virtual void gplugMsgBox( TQMessageBox::Icon type, const TQString &text ); + + static TQVariant getConf( void *ctx, const char *key, const TQVariant &dflt ); +}; + +class KGStdVerify : public KGVerify { + Q_OBJECT + typedef KGVerify inherited; + + public: + KGStdVerify( KGVerifyHandler *handler, TQWidget *parent, + TQWidget *predecessor, const TQString &fixedEntity, + const PluginList &pluginList, + KGreeterPlugin::Function func, KGreeterPlugin::Context ctx ); + virtual ~KGStdVerify(); + TQLayout *getLayout() const { return TQT_TQLAYOUT(grid); } + void selectPlugin( int id ); + + protected: + void updateStatus(); + + private: + TQGridLayout *grid; + TQLabel *failedLabel; + int failedLabelState; + + private slots: + void slotPluginSelected( int id ); +}; + +class KGThemedVerify : public KGVerify { + Q_OBJECT + typedef KGVerify inherited; + + public: + KGThemedVerify( KGVerifyHandler *handler, KdmThemer *themer, + TQWidget *parent, TQWidget *predecessor, + const TQString &fixedEntity, + const PluginList &pluginList, + KGreeterPlugin::Function func, + KGreeterPlugin::Context ctx ); + virtual ~KGThemedVerify(); + void selectPlugin( int id ); + + protected: + void updateStatus(); + + private slots: + void slotPluginSelected( int id ); +}; + +class KGChTok : public FDialog, public KGVerifyHandler { + Q_OBJECT + typedef FDialog inherited; + + public: + KGChTok( TQWidget *parent, const TQString &user, + const PluginList &pluginList, int curPlugin, + KGreeterPlugin::Function func, KGreeterPlugin::Context ctx ); + ~KGChTok(); + + public slots: + void accept(); + + private: + KPushButton *okButton, *cancelButton; + KGStdVerify *verify; + + public: // from KGVerifyHandler + virtual void verifyPluginChanged( int id ); + virtual void verifyOk(); + virtual void verifyFailed(); + virtual void verifyRetry(); + virtual void verifySetUser( const TQString &user ); +}; + +#endif /* KGVERIFY_H */ diff --git a/tdm/kfrontend/krootimage.cpp b/tdm/kfrontend/krootimage.cpp new file mode 100644 index 000000000..b51367485 --- /dev/null +++ b/tdm/kfrontend/krootimage.cpp @@ -0,0 +1,140 @@ +/* + +Copyright (C) 1999 Matthias Hoelzer-Kluepfel +Copyright (C) 2002,2004 Oswald Buddenhagen + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public +License version 2 as published by the Free Software Foundation. + +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; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. + +*/ + +#include + +#include +#include +#include + +#include + +#include "krootimage.h" + +#include +#include + +#include + +static const char description[] = + I18N_NOOP( "Fancy desktop background for tdm" ); + +static const char version[] = "v2.0"; + +static KCmdLineOptions options[] = { + { "+config", I18N_NOOP( "Name of the configuration file" ), 0 }, + KCmdLineLastOption +}; + +static Atom prop_root; +static bool properties_inited = false; + +MyApplication::MyApplication( const char *conf ) + : KApplication(), + renderer( 0, new KSimpleConfig( TQFile::decodeName( conf ) ) ) +{ + connect( &timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeout()) ); + connect( &renderer, TQT_SIGNAL(imageDone( int )), this, TQT_SLOT(renderDone()) ); + renderer.enableTiling( true ); // optimize + renderer.changeWallpaper(); // cannot do it when we're killed, so do it now + timer.start( 60000 ); + renderer.start(); + + if( !properties_inited ) { + prop_root = XInternAtom(qt_xdisplay(), "_XROOTPMAP_ID", False); + properties_inited = true; + } +} + + +void +MyApplication::renderDone() +{ + // Get the newly drawn pixmap... + TQPixmap pm = renderer.pixmap(); + + // ...set it to the desktop widget... + TQT_TQWIDGET(desktop())->setBackgroundPixmap( pm ); + TQT_TQWIDGET(desktop())->repaint( true ); + + // ...and export it via Esetroot-style so that composition managers can use it! + Pixmap bgPm = pm.handle(); // fetch the actual X handle to it + XChangeProperty(qt_xdisplay(), qt_xrootwin(), prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &bgPm, 1); + + renderer.saveCacheFile(); + renderer.cleanup(); + for (unsigned i=0; ibackgroundMode() == KBackgroundSettings::Program || + (r->multiWallpaperMode() != KBackgroundSettings::NoMulti && + r->multiWallpaperMode() != KBackgroundSettings::NoMultiRandom)) { + return; + } + } + +} + +void +MyApplication::slotTimeout() +{ + bool change = false; + + if (renderer.needProgramUpdate()) { + renderer.programUpdate(); + change = true; + } + + if (renderer.needWallpaperChange()) { + renderer.changeWallpaper(); + change = true; + } + + if (change) + renderer.start(); +} + +int +main( int argc, char *argv[] ) +{ + KApplication::disableAutoDcopRegistration(); + + KLocale::setMainCatalogue( "kdesktop" ); + KCmdLineArgs::init( argc, argv, "krootimage", I18N_NOOP( "KRootImage" ), description, version ); + KCmdLineArgs::addCmdLineOptions( options ); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if (!args->count()) + args->usage(); + MyApplication app( args->arg( 0 ) ); + args->clear(); + + app.exec(); + + app.flushX(); + + // Keep color resources after termination + XSetCloseDownMode( qt_xdisplay(), RetainTemporary ); + + return 0; +} + +#include "krootimage.moc" diff --git a/tdm/kfrontend/krootimage.h b/tdm/kfrontend/krootimage.h new file mode 100644 index 000000000..e46190116 --- /dev/null +++ b/tdm/kfrontend/krootimage.h @@ -0,0 +1,48 @@ +/* + +Copyright (C) 1999 Matthias Hoelzer-Kluepfel +Copyright (C) 2002,2004 Oswald Buddenhagen + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public +License version 2 as published by the Free Software Foundation. + +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; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. + +*/ + +#ifndef __TDMDESKTOP_H__ +#define __TDMDESKTOP_H__ + + +#include +#include + +#include + + +class MyApplication : public KApplication +{ + Q_OBJECT + + public: + MyApplication( const char * ); + + private slots: + void renderDone(); + void slotTimeout(); + + private: + KVirtualBGRenderer renderer; + TQTimer timer; +}; + +#endif diff --git a/tdm/kfrontend/pics/CMakeLists.txt b/tdm/kfrontend/pics/CMakeLists.txt new file mode 100644 index 000000000..e1b61b4f8 --- /dev/null +++ b/tdm/kfrontend/pics/CMakeLists.txt @@ -0,0 +1,18 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +install( FILES + kdelogo.png kdelogo-crystal.png shutdown.jpg + DESTINATION ${DATA_INSTALL_DIR}/tdm/pics ) + +install( FILES + default1.png default2.png default3.png root1.png + DESTINATION ${DATA_INSTALL_DIR}/tdm/pics/users ) diff --git a/tdm/kfrontend/pics/Makefile.am b/tdm/kfrontend/pics/Makefile.am new file mode 100644 index 000000000..9ba04536e --- /dev/null +++ b/tdm/kfrontend/pics/Makefile.am @@ -0,0 +1,9 @@ + +picsdir = $(kde_datadir)/tdm/pics +pics_DATA = kdelogo.png kdelogo-crystal.png shutdown.jpg + +usersdir = $(picsdir)/users +users_DATA = default1.png default2.png default3.png root1.png + + +EXTRA_DIST = $(pics_DATA) $(users_DATA) diff --git a/tdm/kfrontend/pics/default1.png b/tdm/kfrontend/pics/default1.png new file mode 100644 index 000000000..ef3aef3f9 Binary files /dev/null and b/tdm/kfrontend/pics/default1.png differ diff --git a/tdm/kfrontend/pics/default2.png b/tdm/kfrontend/pics/default2.png new file mode 100644 index 000000000..194acfe2c Binary files /dev/null and b/tdm/kfrontend/pics/default2.png differ diff --git a/tdm/kfrontend/pics/default3.png b/tdm/kfrontend/pics/default3.png new file mode 100644 index 000000000..a8663b15e Binary files /dev/null and b/tdm/kfrontend/pics/default3.png differ diff --git a/tdm/kfrontend/pics/kdelogo-crystal.png b/tdm/kfrontend/pics/kdelogo-crystal.png new file mode 100644 index 000000000..592a7e321 Binary files /dev/null and b/tdm/kfrontend/pics/kdelogo-crystal.png differ diff --git a/tdm/kfrontend/pics/kdelogo.png b/tdm/kfrontend/pics/kdelogo.png new file mode 100644 index 000000000..c89a7f660 Binary files /dev/null and b/tdm/kfrontend/pics/kdelogo.png differ diff --git a/tdm/kfrontend/pics/root1.png b/tdm/kfrontend/pics/root1.png new file mode 100644 index 000000000..fced75c11 Binary files /dev/null and b/tdm/kfrontend/pics/root1.png differ diff --git a/tdm/kfrontend/pics/shutdown.jpg b/tdm/kfrontend/pics/shutdown.jpg new file mode 100644 index 000000000..f1353c54b Binary files /dev/null and b/tdm/kfrontend/pics/shutdown.jpg differ diff --git a/tdm/kfrontend/sakdlg.cc b/tdm/kfrontend/sakdlg.cc new file mode 100644 index 000000000..396fa1627 --- /dev/null +++ b/tdm/kfrontend/sakdlg.cc @@ -0,0 +1,247 @@ +//=========================================================================== +// +// This file is part of the KDE project +// +// Copyright (c) 2010-2011 Timothy Pearson + +#include + +#include "sakdlg.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kfdialog.h" + +#ifndef AF_LOCAL +# define AF_LOCAL AF_UNIX +#endif + +#define FIFO_DIR "/tmp/ksocket-global/tdm" +#define FIFO_FILE "/tmp/ksocket-global/tdm/tdmctl-%1" +#define FIFO_SAK_FILE "/tmp/ksocket-global/tdm/tdmctl-sak-%1" + +bool trinity_desktop_lock_use_system_modal_dialogs = TRUE; +extern bool trinity_desktop_lock_use_sak; + +//=========================================================================== +// +// Simple dialog for displaying an unlock status or recurring error message +// +SAKDlg::SAKDlg(TQWidget *parent) + : TQDialog(parent, "information dialog", true, (trinity_desktop_lock_use_system_modal_dialogs?((WFlags)WStyle_StaysOnTop):((WFlags)WX11BypassWM))), + mUnlockingFailed(false), mPipe_fd(-1), closingDown(false) +{ + if (trinity_desktop_lock_use_system_modal_dialogs) { + // Signal that we do not want any window controls to be shown at all + Atom kde_wm_system_modal_notification; + kde_wm_system_modal_notification = XInternAtom(qt_xdisplay(), "_KDE_WM_MODAL_SYS_NOTIFICATION", False); + XChangeProperty(qt_xdisplay(), winId(), kde_wm_system_modal_notification, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L); + } + setCaption(TDM_LOGIN_SCREEN_BASE_TITLE); + + frame = new TQFrame( this ); + if (trinity_desktop_lock_use_system_modal_dialogs) + frame->setFrameStyle( TQFrame::NoFrame ); + else + frame->setFrameStyle( TQFrame::Panel | TQFrame::Raised ); + frame->setLineWidth( 2 ); + + KSMModalDialogHeader* theader = new KSMModalDialogHeader( frame ); + + KUser user; + + mStatusLabel = new TQLabel( " ", frame ); + mStatusLabel->setAlignment( TQLabel::AlignVCenter ); + + TQVBoxLayout *unlockDialogLayout = new TQVBoxLayout( this ); + unlockDialogLayout->addWidget( frame ); + + TQHBoxLayout *layStatus = new TQHBoxLayout( 0, 0, KDialog::spacingHint()); + layStatus->addWidget( mStatusLabel ); + + frameLayout = new TQGridLayout( frame, 1, 1, KDialog::marginHint(), KDialog::spacingHint() ); + frameLayout->addMultiCellWidget( theader, 0, 0, 0, 1, AlignTop | AlignLeft ); + frameLayout->addMultiCellLayout( layStatus, 1, 1, 0, 1, AlignLeft | AlignVCenter); + + mStatusLabel->setText("" + i18n("Press Ctrl+Alt+Del to begin.") + "

" + i18n("This process helps keep your password secure.") + "
" + i18n("It prevents unauthorized users from emulating the login screen.")); + + installEventFilter(this); + + mSAKProcess = new KProcess; + *mSAKProcess << "tdmtsak" << "dm"; + connect(mSAKProcess, TQT_SIGNAL(processExited(KProcess*)), this, TQT_SLOT(slotSAKProcessExited())); + mSAKProcess->start(); + + TQTimer::singleShot( 0, this, TQT_SLOT(handleInputPipe()) ); +} + +void SAKDlg::slotSAKProcessExited() +{ + int retcode = mSAKProcess->exitStatus(); + if (retcode != 0) trinity_desktop_lock_use_sak = false; + closingDown = true; + hide(); +} + +void SAKDlg::handleInputPipe(void) { + if (closingDown) { + ::unlink(mPipeFilename.ascii()); + return; + } + + if (isShown() == false) { + TQTimer::singleShot( 100, this, TQT_SLOT(handleInputPipe()) ); + return; + } + + char readbuf[2048]; + int displayNumber; + TQString currentDisplay; + currentDisplay = TQString(getenv("DISPLAY")); + currentDisplay = currentDisplay.replace(":", ""); + displayNumber = currentDisplay.toInt(); + mPipeFilename = TQString(FIFO_SAK_FILE).arg(displayNumber); + ::unlink((TQString(FIFO_FILE).arg(displayNumber)).ascii()); + + /* Create the FIFOs if they do not exist */ + umask(0); + struct stat buffer; + int status; + status = stat(FIFO_DIR, &buffer); + if (status == 0) { + int file_mode = ((buffer.st_mode & S_IRWXU) >> 6) * 100; + file_mode = file_mode + ((buffer.st_mode & S_IRWXG) >> 3) * 10; + file_mode = file_mode + ((buffer.st_mode & S_IRWXO) >> 0) * 1; + if ((file_mode != 600) || (buffer.st_uid != 0) || (buffer.st_gid != 0)) { + ::unlink(mPipeFilename.ascii()); + printf("[WARNING] Possible security breach! Please check permissions on " FIFO_DIR " (must be 600 and owned by root/root, got %d %d/%d). Not listening for login credentials on remote control socket.\n", file_mode, buffer.st_uid, buffer.st_gid); fflush(stdout); + return; + } + } + mkdir(FIFO_DIR,0600); + mknod(mPipeFilename.ascii(), S_IFIFO|0600, 0); + chmod(mPipeFilename.ascii(), 0600); + + mPipe_fd = ::open(mPipeFilename.ascii(), O_RDONLY | O_NONBLOCK); + int numread; + TQString inputcommand = ""; + while ((!inputcommand.contains('\n')) && (!closingDown)) { + numread = ::read(mPipe_fd, readbuf, 2048); + readbuf[numread] = 0; + readbuf[2047] = 0; + inputcommand += readbuf; + tqApp->processEvents(); + } + if (closingDown) { + ::unlink(mPipeFilename.ascii()); + return; + } + inputcommand = inputcommand.replace('\n', ""); + TQStringList commandList = TQStringList::split('\t', inputcommand, false); + if ((*(commandList.at(0))) == "CLOSE") { + mSAKProcess->kill(); + } + if (!closingDown) { + TQTimer::singleShot( 0, this, TQT_SLOT(handleInputPipe()) ); + ::close(mPipe_fd); + ::unlink(mPipeFilename.ascii()); + } + else { + ::unlink(mPipeFilename.ascii()); + } +} + +SAKDlg::~SAKDlg() +{ + if ((mSAKProcess) && (mSAKProcess->isRunning())) { + mSAKProcess->kill(SIGTERM); + delete mSAKProcess; + } + if (mPipe_fd != -1) { + closingDown = true; + ::close(mPipe_fd); + ::unlink(mPipeFilename.ascii()); + } + hide(); +} + +void SAKDlg::closeDialogForced() +{ + TQDialog::reject(); +} + +void SAKDlg::reject() +{ + +} + +void SAKDlg::updateLabel(TQString &txt) +{ + mStatusLabel->setPaletteForegroundColor(Qt::black); + mStatusLabel->setText("" + txt + ""); +} + +void SAKDlg::show() +{ + TQDialog::show(); + TQApplication::flushX(); +} + +#include "sakdlg.moc" diff --git a/tdm/kfrontend/sakdlg.h b/tdm/kfrontend/sakdlg.h new file mode 100644 index 000000000..a930707b1 --- /dev/null +++ b/tdm/kfrontend/sakdlg.h @@ -0,0 +1,64 @@ +//=========================================================================== +// +// This file is part of the KDE project +// +// Copyright (c) 2010 Timothy Pearson +// + +#ifndef __SAKDLG_H__ +#define __SAKDLG_H__ + +#include +#include + +#include + +class TQFrame; +class TQGridLayout; +class TQLabel; +class KPushButton; +class TQListView; + +//=========================================================================== +// +// Simple dialog for displaying an info message. +// It does not handle password validation. +// +class SAKDlg : public TQDialog +{ + Q_OBJECT + +public: + SAKDlg(TQWidget *parent); + ~SAKDlg(); + virtual void show(); + + void updateLabel( TQString &txt ); + void closeDialogForced(); + +private slots: + void slotSAKProcessExited(); + void handleInputPipe(); + +protected slots: + virtual void reject(); + +private: + TQFrame *frame; + TQGridLayout *frameLayout; + TQLabel *mStatusLabel; + int mCapsLocked; + bool mUnlockingFailed; + TQStringList layoutsList; + TQStringList::iterator currLayout; + int sPid, sFd; + KProcess* mSAKProcess; + int mPipe_fd; + TQString mPipeFilename; + +protected: + bool closingDown; +}; + +#endif + diff --git a/tdm/kfrontend/sessions/9wm.desktop b/tdm/kfrontend/sessions/9wm.desktop new file mode 100644 index 000000000..d17276782 --- /dev/null +++ b/tdm/kfrontend/sessions/9wm.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=XSession +Exec=9wm +TryExec=9wm +Name=9WM +Name[cy]= 9WM +Name[eo]=9FA +Name[hi]=9डबल्यू-एम +Name[ta]=9 WM +Name[te]=9 డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง gWM +Comment=An emulation of the Plan 9 window manager 8-1/2 +Comment[af]='n Nabootsing van die 'Plan 9' venster bestuurder +Comment[be]=Эмуляцыя кіраўніка вокнаў 8-1/2 для Plan 9 +Comment[bn]=প্ল্যান ৯ উইণ্ডো ম্যানেজার ৮-১/২ -এর এমুলেশন +Comment[bs]=Simulacija Plan 9 window managera 8-1/2 +Comment[ca]=Una emulació del gestor de finestres Plan 9 +Comment[cs]=Emulace Plane 9 správce oken 8-1/2 +Comment[csb]=Emùlacëjô menedżera òknów Plan 9 - 8-1/2 +Comment[cy]=Efelychiad o 8-1/2, y trefnydd ffenestri Plan 9 +Comment[da]=En emulering af Plan 9 vindueshåndteringen 8-1/2 +Comment[de]=Emulation des Plan 9-Fenstermanagers 8-1/2 +Comment[el]=Μια προσομοίωση του Plan 9 διαχειριστή παραθύρων 8-1/2 +Comment[eo]=KDE-fenestroadministrilo de plano 9 +Comment[es]=Una emulación del gestor de ventanas Plan 9 8-1/2 +Comment[et]=Plan 9 aknahalduri 8-1/2 emuleerimine +Comment[eu]=Plan 9 8-1/2 leiho kudeatzailearen emulazioa +Comment[fa]=تقلیدی از نقشۀ مدیر پنجره ۹. ۸-۱/ ۲ +Comment[fi]=Emulaatio Plan9-ikkunaohjelmasta 8-1/2 +Comment[fr]=Une émulation du gestionnaire de fenêtres Plan 9 8-1/2 +Comment[fy]=In emulator foar de Plan9 finstersbehearder 8-1/2 +Comment[gl]=Unha emulación do xestor de fiestras de Plan9 +Comment[he]=מדמה של מנהל חלונות Plan 9 8-1/2 +Comment[hi]=प्लान 9 विंडो प्रबंधक 8-1/2 का एक एमुलेशन +Comment[hr]=Emulacija Plan 9 upravitelja prozora 8-1/2 +Comment[hu]=A Plan 9 operációs rendszer 8-1/2 nevű ablakkezelőjének emulálása +Comment[is]=Eftirlíking af Plan 9 gluggastjóranum 8-1/2 +Comment[it]=Un emulatore del window manager 8-1/2 Plan 9 +Comment[ja]=Plan9 ウィンドウマネージャのエミュレーション 8-1/2 +Comment[ka]=Plan 9 ფანჯრის მმართველის ემულატორი +Comment[kk]=Plan 9 терезе менеджерінің эмуляторы +Comment[km]=ការ​ត្រាប់​តាម​កម្មវិធី​គ្រប់គ្រង​បង្អួច Plan 9 8-1/2 +Comment[ko]=Plan 9 창 관리자 8-1/2 에뮬레이션 +Comment[lt]=Plan 9 langų tvarkyklės emuliatorius 8-1/2 +Comment[lv]=Plan 9 logu menedžera emulators 8-1/2 +Comment[mk]=Емулација на менаџерот на прозорци Plan 9 8-1/2 +Comment[ms]=Pelagakan Plan 9 pengurus tetingkap 8-1/2 +Comment[mt]=Emulazzjoni tal-window manager "Plan 9" 8½ +Comment[nb]=En emulering av vindusbehandleren 8 ½ fra Plan 9 +Comment[nds]=Emuleert den Plan-9-Finsterpleger 8-1/2 +Comment[ne]=योजना 9 सञ्झ्याल प्रबन्धक 8-1/2 को इमुलेसन +Comment[nl]=Een emulator voor de Plan9 windowmanager 8-1/2 +Comment[nn]=Emulering av vindaugssjefen 8 ½ frå Plan 9 +Comment[pa]=ਪਲੇਨ 9 ਝਰੋਖਾ ਮੈਨੇਜਰ 8-1/2 ਦਾ ਸਮਰੂਪ +Comment[pl]=Emulacja menedżera okien Plan 9 - 8-1/2 +Comment[pt]=Uma emulação do gestor de janelas do Plan 9 8-1/2 +Comment[pt_BR]=Uma emulação do gerenciador de janelas do Plan 9 +Comment[ro]=Un emulator al managerului de ferestre 8-1/2 din Plan 9 +Comment[ru]=Эмуляция оконного менеджера Plan 9 +Comment[rw]=Ikurura rya mugenga dirishya 8-1/2 Plan 9 +Comment[se]=Lásegieđahalli mii áddestaddá Plan 9 lásegieđahalli 8-1/2. +Comment[sk]=Emulácia správcu okien 8-1/2 systému Plan 9 +Comment[sl]=Emulacija okenskega upravitelja Plan 9 8-1/2 +Comment[sr]=Емулација Plan 9 менаџера прозора 8-1/2 +Comment[sr@Latn]=Emulacija Plan 9 menadžera prozora 8-1/2 +Comment[sv]=Emulering av Plan-9-fönsterhanteraren 8-1/2 +Comment[ta]= திட்டம் 9 சாளர மேலாளர் 8-1/2 இன் முன்மாதிரி +Comment[tg]=Эмулятори нақшаи 9-и мудири тирезаи 8-1/2 +Comment[th]=การจำลองตัวจัดการหน้าต่าง Plan 9 8-1/2 +Comment[tr]=Plan 9 pencere yöneticisi 8-1/2 için bir emülasyon +Comment[tt]=Plan 9 atlı täräzä idäräçenä axşap eşläw +Comment[uk]=Емуляція менеджера вікон Plan 9 "8-1/2" +Comment[vi]=Một bộ mô phỏng bộ quản lý cửa sổ Plan 9 8-1/2 +Comment[wa]=Ene emulåcion do manaedjeu di purneas di Plan 9 +Comment[zh_CN]=Plan 9 窗口管理器 8-1/2 的模拟 +Comment[zh_TW]=模仿 Plan 9 的視窗管理程式 8-1/2 diff --git a/tdm/kfrontend/sessions/CMakeLists.txt b/tdm/kfrontend/sessions/CMakeLists.txt new file mode 100644 index 000000000..780963bd4 --- /dev/null +++ b/tdm/kfrontend/sessions/CMakeLists.txt @@ -0,0 +1,29 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +configure_file( tde.desktop.cmake tde.desktop @ONLY ) + +install( FILES + admin.desktop ${CMAKE_CURRENT_BINARY_DIR}/tde.desktop + gnome.desktop 9wm.desktop aewm++.desktop aewm.desktop + afterstep.desktop amaterus.desktop amiwm.desktop + asclassic.desktop blackbox.desktop cde.desktop + ctwm.desktop cwwm.desktop enlightenment.desktop + evilwm.desktop fluxbox.desktop flwm.desktop fvwm.desktop + fvwm95.desktop golem.desktop icewm.desktop ion.desktop + larswm.desktop lwm.desktop matchbox.desktop metacity.desktop + mwm.desktop olvwm.desktop olwm.desktop openbox.desktop + oroborus.desktop phluid.desktop pwm.desktop qvwm.desktop + ratpoison.desktop sapphire.desktop sawfish.desktop + twm.desktop ude.desktop vtwm.desktop w9wm.desktop + waimea.desktop wm2.desktop wmaker.desktop xfce.desktop + xfce4.desktop + DESTINATION ${DATA_INSTALL_DIR}/tdm/sessions ) diff --git a/tdm/kfrontend/sessions/Makefile.am b/tdm/kfrontend/sessions/Makefile.am new file mode 100644 index 000000000..a29872441 --- /dev/null +++ b/tdm/kfrontend/sessions/Makefile.am @@ -0,0 +1,49 @@ +sessionsdir = $(kde_datadir)/tdm/sessions +sessions_DATA = \ + admin.desktop tde.desktop gnome.desktop \ + 9wm.desktop \ + aewm++.desktop \ + aewm.desktop \ + afterstep.desktop \ + amaterus.desktop \ + amiwm.desktop \ + asclassic.desktop \ + blackbox.desktop \ + cde.desktop \ + ctwm.desktop \ + cwwm.desktop \ + enlightenment.desktop \ + evilwm.desktop \ + fluxbox.desktop \ + flwm.desktop \ + fvwm.desktop \ + fvwm95.desktop \ + golem.desktop \ + icewm.desktop \ + ion.desktop \ + larswm.desktop \ + lwm.desktop \ + matchbox.desktop \ + metacity.desktop \ + mwm.desktop \ + olvwm.desktop \ + olwm.desktop \ + openbox.desktop \ + oroborus.desktop \ + phluid.desktop \ + pwm.desktop \ + qvwm.desktop \ + ratpoison.desktop \ + sapphire.desktop \ + sawfish.desktop \ + twm.desktop \ + ude.desktop \ + vtwm.desktop \ + w9wm.desktop \ + waimea.desktop \ + wm2.desktop \ + wmaker.desktop \ + xfce.desktop \ + xfce4.desktop + +EXTRA_DIST = $(sessions_DATA) diff --git a/tdm/kfrontend/sessions/admin.desktop b/tdm/kfrontend/sessions/admin.desktop new file mode 100644 index 000000000..73e6ae3bf --- /dev/null +++ b/tdm/kfrontend/sessions/admin.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=XSession +Exec=YaSTadminSession +TryExec=YaSTadminSession +Name=admin +Comment=Yast Admin Session diff --git a/tdm/kfrontend/sessions/aewm++.desktop b/tdm/kfrontend/sessions/aewm++.desktop new file mode 100644 index 000000000..3eb4ee8e8 --- /dev/null +++ b/tdm/kfrontend/sessions/aewm++.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Type=XSession +Exec=aewm++_xsession +TryExec=aewm++_xsession +Name=AEWM++ +Name[eo]=MFA++ +Name[hi]=एईडबल्यूएम++ +Name[te]=ఎ ఈ డబ్ల్యు ఎం ++ +Comment=A minimal window manager based on AEWM, enhanced by virtual desktops and partial GNOME support +Comment[af]='n Minimale venster bestuurder wat op AEWM gebaseer is. Dit is verbeter met virtuale werkskerms en gedeeltelike GNOME ondersteuning +Comment[ar]=مدير نوافذ مصغّر مبني على AEWM، محسّن بأسطح مكتب وهمية ودعم جينوم جزئي +Comment[be]=Мінімалістычны кіраўнік вокнаў, заснаваны на AEWM, з віртуальнымі працоўнымі сталамі і частковай падтрымкай GNOME +Comment[bn]=AEWM ভিত্তিক একটি পরিমিত উইণ্ডো ম্যানেজার, ভার্চুয়াল ডেস্কটপ এবং আংশিক গনোম সমর্থন দ্বারা বর্ধিত +Comment[bs]=Minimalni window manager baziran na AEWM, proširen virtuelnim desktopima i djelomičnom GNOME podrškom +Comment[ca]=Un gestor de finestres minimalista basat en AEWM, orientat a escriptoris virtuals i funcionament parcial per a GNOME +Comment[cs]=Minimalizovaný správce oken založený na AEWM rozšířený o virtuální plochy a částečnou podporu GNOME +Comment[csb]=Prosti menedżer òknów na spòdlém AEWM, zbògacony o wirtualné pùltë ë dzélowé wspiarce dlô GNOME +Comment[cy]= Trefnydd ffenestri lleiafol wed'i seilio ar AEWM, wedi'i wella gan penbyrddau rhith a cynhaliaeth Gnome rhannol. +Comment[da]=En minimal vindueshåndtering baseret på AEWM, udvidet med virtuelle desktoppe og delvis GNOME-støtte +Comment[de]=Minimalistischer Fenstermanager. Beruht auf AEWM, verbessert durch virtuelle Arbeitsflächen und teilweise GNOME-Unterstützung +Comment[el]=Ένας μικρός διαχειριστής παραθύρων βασισμένος στον AEWM, εμπλουτισμένος με εικονικές επιφάνειες εργασίας και μερική υποστήριξη GNOME +Comment[eo]=Minimuma fenestroadministrilo el MFA, plibonigita per virtualaj labortabloj kaj parta helpo por Gnomikuo +Comment[es]=Un gestor de ventanas minimalista basado en AEWM, mejorado con soporte para escritorios virtailes y, parcialmente, GNOME +Comment[et]=Vähenõudlik aknahaldur, mille aluseks on AEWM ja mida on täiendatud virtuaalsete töölaudade ning osalise GNOME toetusega +Comment[eu]=AEWMn oinarritutako leiho kudeatzaile minimoa, mahaigain birtualen euskarriaz eta, zati batez, GNOMEz hobetua +Comment[fa]= مدیر پنجرۀ کمینه بر اساس AEWM، گسترش‌یافته توسط رومیزیهای مجازی و پشتیبانی جزئی GNOME +Comment[fi]=Minimaalinen AEWM:ään pohjautuva ikkunaohjelma, jota on parannettuna virtuaalityöpöydillä ja osittaisella GNOME-tuella +Comment[fr]=Un gestionnaire de fenêtres minimal fondé sur AEWM avec, en plus, la gestion des bureaux virtuels ainsi qu'un support partiel de GNOME +Comment[fy]=In minimalistyske finstersmanager basearre op AEWM, útbreide mei firtuele buroblêden en gedieltelike GNOME-stipe +Comment[gl]=Un xestor de fiestras mínimo baseado en AEWM, mellorado cos escritórios virtuais e con soporte parcial para GNOME +Comment[he]=מנהל חלונות מינימלי המבוסס על AEWM, המשופר על ידי שולחנות עבודה וירטואליים ותמיכה חלקית ב GNOME +Comment[hi]= एईडबल्यूएम आधारित अल्प विंडो प्रबंधक, आभासी डेस्कटॉप तथा आंशिक ग्नोम समर्थन से बेहतर बनाया गया +Comment[hr]=Minimalistički upravitelj prozora zasnovan na AEWM, unaprijeđen virtualnim radnim površinama i djelomičnom podrškom za GNOME +Comment[hu]=Egy nagyon egyszerű ablakkezelő az AEWM alapján, virtuális munkaasztalokkal és részleges GNOME-támogatással kiegészítve +Comment[is]=Einfaldur gluggastjóri byggður á AEWM en með stuðningi fyrir sýndarskjáborð og takmörkuðum GNOME stuðningi +Comment[it]= Un window manager minimale basato su AEWM, migliorato con desktop virtuali e supporto parziale per GNOME +Comment[ja]=仮想デスクトップと部分的な GNOME サポートを強化した AEWM ベースの小さなウィンドウマネージャ +Comment[ka]=მინიმალური ფანჯრის მენეჯერი AEWM -ის ბაზაზე, имеющий частичную поддержку GNOME. +Comment[kk]=Виртуалды үстелдері және шамалы GNOME қолдауы бар AEWM-негіздеген шағын терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​តូច ដែល​ផ្អែក​លើ AEWM ដែល​ធ្វើ​ឲ្យ​ប្រសើរ​ដោយ​ផ្ទៃតុ​និមិត្ត និង​ការ​គាំទ្រ GNOME +Comment[ko]=부분적 그놈 지원과 가상 데스크톱 지원을 사용하는 AEWM 기반 창 관리자 +Comment[lt]=Minimalistinė langų tvarkyklė paremta AEWM, išplėsta virtualių darbastalių ir daliniu GNOME palaikymu +Comment[lv]=Minimālistisks logu menedžeris bāzēts uz AEWM, papildināts ar virtuālajām darbvirsmām un daļēju GNOME atbalstu +Comment[mk]=Минимален менаџер на прозорци базиран на AEWM, подобрен со виртуелни површини и парцијална GNOME поддршка +Comment[ms]=Pengurus tetingkap minima berdasarkan AEWM, dipertingkatkan dengan desktop visual dan sokongan GNOME separa +Comment[mt]=Window manager żgħir ibbażat fuq AEWM, filmkien ma' desktops virtwali u sapport parzjali għal GNOME. +Comment[nb]=En minimal vindusbehandler basert på AEWM, forbedret med virtuelle skrivebord og delvis støtte for GNOME +Comment[nds]=En minimaal Finsterpleger, opbuut op AEWM, verwiedert üm virtuelle Schriefdischen un deelwies Ünnerstütten för GNOME +Comment[ne]=अवास्तविक डेस्कटप र आंशिक GNOME समर्थनद्वारा बृद्धि गरिएको AEWM मा आधारित न्यूनतम सञ्झ्याल प्रबन्धक +Comment[nl]=Een minimalistische windowmanager gebaseerd op AEWM, uitgebreid met virtuele bureaubladen en gedeeltelijke GNOME-ondersteuning +Comment[nn]=Ein minimal vindaugssjef basert på AEWM, forbetra med virtuelle skrivebord og delvis støtte for GNOME +Comment[pa]= AEWM ਤੇ ਅਧਾਰਿਤ ਛੋਟਾ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਫਰਜ਼ੀ ਵੇਹੜਿਆਂ ਨਾਲ ਲੈੱਸ ਤੇ ਥੋੜਾ GNOME ਸਹਾਇਕ +Comment[pl]=Prosty menedżer okien na bazie AEWM, wzbogacony o wirtualne pulpity i częściowe wsparcie dla GNOME +Comment[pt]=Um gestor de janelas simples baseado no AEWM, melhorado com os ecrãs virtuais e com um suporte parcial do GNOME +Comment[pt_BR]=Um gerenciador de janelas pequeno, baseado no AEWM, melhorado pelas áreas de trabalho virtuais e com suporte parcial ao GNOME +Comment[ro]=Un manager de ferestre minimal bazat pe AEWM, îmbunătățit cu ecrane virtuale și suport parțial pentru GNOME +Comment[ru]=Минимальный оконный менеджер на основе AEWM, имеющий частичную поддержку GNOME. +Comment[rw]=Mugenga dirishya nto ishingiye kuri AEWM, rivuguruwe n'ibiro bitagaragara n'iyifashisha GNOME rituzuye +Comment[se]=Geahpes lásegieđahalli vuođđoduvvon AEWM:as, mas leat virtuella čállinbeavddit ja doarju GNOME muhton muddui. +Comment[sk]=Minimálny správca okien založený na AEWM, rozšírrený o virtuálne plochy a čiastočnú podporu GNOME +Comment[sl]=Skromen okenski upavitelj na osnovi AEWM, izboljšan z navideznimi namizji in delno podporo GNOME +Comment[sr]=Минимални менаџер прозора заснован на AEWM-у, побољшан виртуелним радним површинама и делимичном подршком за Гном +Comment[sr@Latn]=Minimalni menadžer prozora zasnovan na AEWM-u, poboljšan virtuelnim radnim površinama i delimičnom podrškom za Gnom +Comment[sv]=Minimal fönsterhanterare baserad på AEWM, utökad med virtuella skrivbord och delvis stöd för Gnome +Comment[ta]=AEWM அடிப்படையிலான சிறிய சாளர மேலாண்மை, மெய்நிகர் மேல்மேசை மற்றும் பகுதி GNOME ஆதரவால் மேப்படுத்தப்பட்டுள்ளது +Comment[tg]=Мудири равзанаҳои хурд дар асоси AEWM дорои нопурраи интерфейси GNOME +Comment[th]=ตัวจัดการหน้าต่างขนาดเล็ก โดยใช้พื้นฐานของ AEWM แล้วเพิ่มความสามารถด้วย พื้นที่ทำงานเสมือน และสนับสนุน GNOME บางส่วน +Comment[tr]=AEWM tabanlı bir pencere yöneticisi +Comment[tt]=AEWM asılında yasalğan, xıyalí öställär belän beraz GNOME totqan ciñel täräzä-idäräçe +Comment[uk]=Мінімальний менеджер вікон, заснований на AEWM, покращений підтримкою віртуальних стільниць та частковою підтримкою GNOME +Comment[vi]=Bộ quản lý cửa sổ tối thiểu dựa trên AEWM, cải tiến với màn hình nền ảo và được hỗ trợ một phần bởi GNOME +Comment[wa]=On manaedjeu di purneas minimå båzé so AEWM, avou sopoirt po les forveyous scribannes eyet ene miete di sopoirt po Gnome +Comment[zh_CN]=基于 AEWM 的小型窗口管理器,增强了虚拟桌面和部分 GNOME 支持 +Comment[zh_TW]=基於 AEWM 的小型視窗管理程式,增強了虛擬桌面及部分的 GNOME 支援 diff --git a/tdm/kfrontend/sessions/aewm.desktop b/tdm/kfrontend/sessions/aewm.desktop new file mode 100644 index 000000000..362fd921f --- /dev/null +++ b/tdm/kfrontend/sessions/aewm.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=XSession +Exec=aewm +TryExec=aewm +Name=AEWM +Name[eo]=MFA +Name[hi]=एईडबल्यूएम +Name[te]=ఎ ఈ డబ్ల్యు ఎం +Comment=A minimalist window manager +Comment[af]='n Minimale venster bestuurder +Comment[ar]=مسيير نوافذ ذو الميزات الأقل +Comment[be]=Мінімалістычны кіраўнік вокнаў +Comment[bn]=একটি পরিমিত উইণ্ডো ম্যানেজার +Comment[bs]=Minimalistički window manager +Comment[ca]=Un gestor de finestres minimalista +Comment[cs]=Minimalistický správce oken +Comment[csb]=Prosti menedżer òknów +Comment[cy]=Trefnydd ffenestri lleiafol +Comment[da]=En minimalistisk vindueshåndtering +Comment[de]=Minimalistischer Fenstermanager +Comment[el]=Ένας μινιμαλιστικός διαχειριστής παραθύρων +Comment[eo]=Minimumema fenestroadministrilo +Comment[es]=Un gestor de ventanas minimalista +Comment[et]=Vähenõudlik aknahaldur +Comment[eu]=Leiho kudeatzaile minimalista +Comment[fa]=یک مدیر پنجرۀ کمینه +Comment[fi]=Minimalistinen ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres minimaliste +Comment[fy]=In minimalistyske finstersmanager +Comment[gl]=Un xestor de fiestras minimalista +Comment[he]=מנהל חלונות מינימליסטי +Comment[hi]=एक अल्पतम विंडो प्रबंधक +Comment[hr]=Minimalistički upravitelj prozora +Comment[hu]=Egy nagyon egyszerű ablakkezelő +Comment[is]=Einfaldur gluggastjóri +Comment[it]=Un window manager minimalista +Comment[ja]=小さなウィンドウマネージャ +Comment[ka]=მინიმალისტური ფანჯრების მნეჯერი +Comment[kk]=Шағын терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​លក្ខណៈ​ពិសេស​តិច +Comment[ko]=최소 지향 창 관리자 +Comment[lt]=Minimalistinė langų tvarkyklė +Comment[lv]=Minimālistisks logu menedžeris +Comment[mk]=Минималистички менаџер на прозорци +Comment[mn]=Хамгийн жижиг цонхны удирдагч +Comment[mt]=Window manager żgħir +Comment[nb]=En minimalistisk vindusbehandler +Comment[nds]=En minimalistisch Finsterpleger +Comment[ne]=एक मिनिमलिस्ट सञ्झ्याल प्रबन्धक +Comment[nl]=Een minimalistische windowmanager +Comment[nn]=Ein minimalistisk vindaugssjef +Comment[pa]=ਇੱਕ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Prosty menedżer okien +Comment[pt]=Um gestor de janelas minimalista +Comment[pt_BR]=Um gerenciador de janelas minimalista +Comment[ro]=Un manager de ferestre minimal +Comment[ru]=Минимальный оконный менеджер +Comment[rw]=Mugenga dirishya igira-bito +Comment[se]=Minimalisttalaš lásegieđahalli +Comment[sk]=Minimálny správca okien +Comment[sl]=Minimalističen okenski upravitelj +Comment[sr]=Минималистички менаџер прозора +Comment[sr@Latn]=Minimalistički menadžer prozora +Comment[sv]=Minimalistisk fönsterhanterare +Comment[ta]=ஒரு சிறிதுப்படுத்தப்பட்ட சாளர மேலாளர் +Comment[tg]=Мудири тирезаи minimalist +Comment[th]=ระบบจัดการหน้าต่างขนาดเล็ก +Comment[tr]=Küçük bir pencere yöneticisi +Comment[tt]=Bik ciñel täräzä-idäräçe +Comment[uk]=Аскетичний менеджер вікон +Comment[uz]=Juda oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=Жуда оддий ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ đơn giản +Comment[wa]=On manaedjeu di purneas minimå +Comment[zh_CN]=最小的窗口管理器 +Comment[zh_TW]=一個最小型的視窗管理程式 diff --git a/tdm/kfrontend/sessions/afterstep.desktop b/tdm/kfrontend/sessions/afterstep.desktop new file mode 100644 index 000000000..c3f8d7329 --- /dev/null +++ b/tdm/kfrontend/sessions/afterstep.desktop @@ -0,0 +1,83 @@ +[Desktop Entry] +Type=XSession +Exec=afterstep +TryExec=afterstep +Name=AfterStep +Name[bn]=আফটার-স্টেপ +Name[eo]=Postpaŝo +Name[hi]=आफ्टर-स्टेप +Name[ne]=चरण पछाडि +Name[pa]=ਪਗਬਾਅਦ +Name[rw]=NyumaIntambwe +Name[sv]=Afterstep +Name[ta]=ஆஃப்டர்ஸ்டெப் +Name[te]=ఆఫ్టర్ స్టెప్ +Comment=A window manager with the NeXTStep look and feel, based on FVWM +Comment[af]='n Venster bestuurder wat NeXTStep naboots, gebaseer of FVWM +Comment[ar]=مدير نوافذ ذو مظهر شبيه بـNeXTStep، مبني على FVWM +Comment[be]=Кіраўнік вокнаў з вонкавым выглядам NeXTStep, заснаваны на FVWM +Comment[bn]=FVWM-এর ওপর ভিত্তি করে তৈরি একটি উইণ্ডো ম্যানেজার, যা দেখতে শুনতে অনেকটানেক্সট-স্টেপ (NeXTStep)-এর মত +Comment[bs]=Window manager sa NeXTStep izgledom i osjećajem, baziran na FVWM +Comment[ca]=Un gestor de finestres amb l'aspecte i comportament de NeXTStep, basat en FVWM +Comment[cs]=Správce oken podobný NeXTStepu založený na FVWM +Comment[csb]=Menedżer òknów jidący w szlach NeXTStep, ùsôdzony na spòdlém FVWM +Comment[cy]= Trefnydd ffenestri efo golwg a theimlad CamNesaf (NeXTStep), wedi'i seilio ar FVWM +Comment[da]=En vindueshåndtering med NeXTStep udseende, baseret på FVWM +Comment[de]=Fenstermanager mit der Optik von NeXTStep, basiert auf FVWM +Comment[el]=Ένας διαχειριστής παραθύρων με την όψη και αίσθηση του NeXTStep, βασισμένος στον FVWM +Comment[eo]=Fenestroadministrilo, kiu aperas kiel Venontpaŝo, farita de FVWM +Comment[es]=Un gestor de ventanas con el aspecto de NeXTStep, basado en FVWM +Comment[et]=Aknahaldur NeXTStep välimuse ja vaimuga, aluseks FVWM +Comment[eu]=FVWMn oinarritutako, eta NeXTStep-en itxura eta portaera duen leiho kudeatzailea +Comment[fa]=یک مدیر پنجره توسط ظاهر و احساس NeXTStep، براساس FVWM +Comment[fi]=NeXTStep-tyylinen ja -tuntuinen FVWM:ään pohjautuva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres similaire à NeXTStep et fondé sur FVWM +Comment[fy]=In finstersmanager mei it úterlik en gedrach fan NeXTStep; basearre op FVWM +Comment[gl]=Un xestor de fiestras de aspeito NeXTStep, baseado en FVWM +Comment[he]=מנהל חלונות עם מראה ומרגש כמו של NeXTStep המבוסס על, FVWM +Comment[hi]=एफ़वीडबल्यूएम आधारित नेक्स्टस्टेप की तरह दिखने और महसूस होने वाला विंडो प्रबंधक +Comment[hr]=Upravitelj prozora s NeXTStep izgledom i načinom rada, zasnovan na FVWM-u +Comment[hu]=Egy FVWM-alapú ablakkezelő, megjelenése a NeXTStepére hasonlít +Comment[is]=Gluggastjóri sem líkist þeim sem er í NeXTStep, byggður á FVWM +Comment[it]=Un window manager con lo stile NeXTStep, basato su FVWM +Comment[ja]=NeXTStep のルック&フィールをもった FVWM ベースのウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი FVWM -ის ბაზაზე, რომელიც NeXTStep-ს ჰგავს +Comment[kk]=FVWM-негіздеген, көрінісі NeXTStep-те сияқты, терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​មាន​រូបរាង និង​មុខងារ NeXTStep ដែល​ផ្អែក​លើ FVWM +Comment[ko]=FVWM 기반 NeXTStep 모양 창 관리자 +Comment[lt]=Langų tvarkyklė su NeXTStep išvaizda ir jausena, paremta FVWM +Comment[lv]=Logu menedžeris ar NeXTStep izskatu un izturēšanos, bāzēts uz FVWM +Comment[mk]=Менаџер на прозорци со изгледот и чувството на NeXTStep, базиран на FVWM +Comment[mn]=NeXTStep look болон feel, based бүхий FVWM-д суурилсан цонх удирдагч +Comment[ms]=Pengurus tetingkap dengan rupa dan rasa NeXTStep berdasarkan FVWM +Comment[mt]=Window manager ibbażat fuq FVWM, jixbaħ lil NeXTStep +Comment[nb]=En vindusbehandler som ligner på NeXTStep, basert på FVWM +Comment[nds]=En Finsterpleger mit dat Utsehn vun NeXTStep, opbuut op FVWM +Comment[ne]=FVWMA आधारित एउटा सञ्झ्याल प्रबन्धक NeXTStep मा हेर्छ र थाहा पाउँछ +Comment[nl]=Een windowmanager met het uiterlijk en gedrag van NeXTStep; gebaseerd op FVWM +Comment[nn]=Ein vindaugssjef som liknar på NeXTStep, basert på FVWM +Comment[pa]=NeXTStep ਦੀ ਦਿੱਖ ਤੇ ਦਰਿਸ਼ ਵਾਲਾ FVWM ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien naśladujący NeXTStep, stworzony na podstawie FVWM +Comment[pt]=Um gestor de janelas com a aparência e comportamento do NeXTStep. Baseado no FVWM. +Comment[pt_BR]=Um gerenciador de janelas com a aparência do NeXTSep, baseado no FVWM +Comment[ro]=Un manager de ferestre cu aspect NeXTStep, bazat pe FVWM +Comment[ru]=Оконный менеджер на основе FVWM, повторяющий внешний вид NeXTStep +Comment[rw]=Mugenga dirishya ifite imboneko n'ukumva NtambweIkurikira, ishingiye kuri FVWM +Comment[se]=Lásegieđahalli mii sulastahttá NeXTStep, vuođđoduvvon FVWM:as +Comment[sk]=Správca okien podobný NeXTStep založený na FVWM +Comment[sl]=Okenski upravitelj z občutkom in izgledom NeXTStep-a, na osnovi FVWM +Comment[sr]=Менаџер прозора са NeXTStep-овим изгледом и осећајем, заснован на FVWM-у +Comment[sr@Latn]=Menadžer prozora sa NeXTStep-ovim izgledom i osećajem, zasnovan na FVWM-u +Comment[sv]=Fönsterhanterare med Nextstep-utseende och -känsla, baserad på FVWM +Comment[ta]=FVWM அடிப்படையிலான NeXTStep உடனான சாளர மேலாளர். +Comment[tg]=Мудири равзанаҳо дар асоси FVWM дорои намуди NeXTStep +Comment[th]=ระบบจัดการหน้าต่างที่มีรูปแบบและสัมผัสของระบบปฏิบัติการ NeXTStep โดยใช้พื้นฐานของ FVWM +Comment[tr]=NeXTStep görünümlü bir pencere yöneticisi +Comment[tt]=FVWM asılında qorılğan, NeXTStep küreneşe belän täräzä-idäräçe +Comment[uk]=Менеджер вікон з виглядом та поведінкою NeXTStep, заснований на FVWM +Comment[uz]=FVWM asosida yaratilgan NeXTStep'ga oʻxshash oyna boshqaruvchi +Comment[uz@cyrillic]=FVWM асосида яратилган NeXTStep'га ўхшаш ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ với giao diện NeXTStep, dựa trên FVWM +Comment[wa]=On manaedjeu di purneas avou l' rivnance di NeXTStep, båzé so FVWM +Comment[zh_CN]=一个带有 NeXTStep 观感的窗口管理器,基于 FVWM +Comment[zh_TW]=一個基於 FVWM 並擁有 NeXTStep 外觀及感覺的視窗管理程式 diff --git a/tdm/kfrontend/sessions/amaterus.desktop b/tdm/kfrontend/sessions/amaterus.desktop new file mode 100644 index 000000000..3c52ee180 --- /dev/null +++ b/tdm/kfrontend/sessions/amaterus.desktop @@ -0,0 +1,75 @@ +[Desktop Entry] +Type=XSession +Exec=amaterus +TryExec=amaterus +Name=AMATERUS +Name[hi]=एमेच्योर्स +Name[te]=అమాటెరస్ +Comment=A GTK+ based window manager with a window grouping feature +Comment[af]='n GTK+ gebaseerde venster bestuurder met 'n venster groepering funksie +Comment[ar]=مدير نوافذ مبني على GTK+ له ميزة تجميع النوافذ +Comment[be]=Кіраўнік вокнаў, заснаваны на GTK+, са здольнасцю групавання вокнаў +Comment[bn]=GTK+ ভিত্তিল উইণ্ডো ম্যানেজার, যাতে উইণ্ডো গ্রুপিং করা যায় +Comment[bs]=Window manager baziran na GTK+ sa mogućnošću grupisanja prozora +Comment[ca]=Un gestor de finestres de GTK+ amb una característica per a l'agrupament de finestres +Comment[cs]=Správce oken založený na GTK+ s funkcí seskupování okne +Comment[csb]=Menedżer òknów brëkùjący GTK+, z optacëją grëpòwaniô òknów +Comment[cy]=Trefnydd ffenestri wedi'i seilio ar GTK+, efo nodwedd casglu ffenestri +Comment[da]=En GTK+ baseret vindueshåndtering med en vinduesgrupperingsegenskab +Comment[de]=Auf GTK+ basierender Fenstermanager mit Gruppierungsfunktion für die Fenster +Comment[el]=Ένας διαχειριστής παραθύρων βασισμένος στο GTK+ με ένα χαρακτηριστικό ομαδοποίησης παραθύρων +Comment[eo]=Fenestroadministrilo kun ebleco kunigi fenestrojn, kiu uzas GTK+ +Comment[es]=Un gestor de ventanas basado en GTK+ con la posibilidad de agrupar ventanas +Comment[et]=GTK+-le tuginev aknahaldur akende grupeerimise võimalusega +Comment[eu]=GTK+-n oinarritutako leiho kudeatzailea, leihoak taldeka biltzeko gaitasuna duena +Comment[fa]=یک GTK+ بر مبنای مدیر پنجره توسط ویژگی گروهی کردن پنجره‌ها +Comment[fi]=GTK+-pohjainen ikkunaohjelma ikkunoiden ryhmittely -ominaisuudella +Comment[fr]=Un gestionnaire de fenêtres écrit en GTK+, avec une fonctionnalité de groupement des fenêtres +Comment[fy]=In op GTK+ basearre finstersmanager mei finsterkeppelfûnksje +Comment[gl]=Un xestor de fiestras baseado en GTK+ con agrupamento de fiestras +Comment[he]=מנהל חלונות מבוסס GTK+ עם אפשרות לקבץ חלונות +Comment[hi]=जीटीके+ आधारित विंडो प्रबंधक, विंडो समूह विशेषता सहित +Comment[hr]=Upravitelj prozora zasnovan na GTK+ s mogućnošću grupiranja prozora +Comment[hu]=Egy GTK+-alapú ablakkezelő ablakcsoportosítási lehetőséggel +Comment[is]=Gluggastjóri sem hópar saman glugga og er byggður á GTK+ +Comment[it]=Un window manager basato su GTK+ con la possibilità di raggruppare le finestre +Comment[ja]=ウィンドウのグループ化が可能な GTK+ ベースのウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი GTK+ ს ბაზაზე ფანჯრების დაჯგუფების ფუნქციით +Comment[kk]=GTK+ негіздеген, терезелерді топтастыру қасиеті бар, терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ផ្អែក​លើ GTK+ ដែល​មាន​លក្ខណៈ​ពិសេស​ដាក់​បង្អួច​ជា​ក្រុម +Comment[ko]=창 그룹 기능을 사용하는 GTK+ 기반 창 관리자 +Comment[lt]=GTK+ paremta langų tvarkyklė su langų grupavimo galimybe +Comment[lv]=GTK+ bāzēts logu menedžeris ar logu grupēšanas iespēju +Comment[mk]=GTK+ базиран менаџер на прозорци со можност за групирање на прозорци +Comment[mn]=A GTK+ суурилсан цонх бүлэглэгчтэй цонх удирдагч +Comment[mt]=Window manager ibbażat fuq GTK+ b'faċilitajiet ta' gruppi ta' windows +Comment[nb]=En vindusbehandler basert på GTK+ med vindusgruppering +Comment[nds]=En Finsterpleger opbuut op GTK+, kann Finstern in Koppeln tosamenfaten +Comment[ne]=सञ्झ्याल समूह विशेषतासँग GTK+ मा आधारित सञ्झ्याल प्रबन्धक +Comment[nl]=Een op GTK+ gebaseerde windowmanager met venstergroeperingfunctionaliteit +Comment[nn]=Ein GTK+-basert vindaugssjef med vindaugsgruppering +Comment[pa]=ਇੱਕ GTK+ ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਜੋ ਕਿ ਝਰੋਖਿਆਂ ਨੂੰ ਇੱਕ ਥਾਂ ਸੰਭਾਲਣ ਦੀ ਸਹੂਲਤ ਨਾਲ ਲੈੱਸ ਹੈ। +Comment[pl]=Menedżer okien korzystający z GTK+, z opcją grupowania okien +Comment[pt]=Um gestor de janelas baseado em GTK+ com uma funcionalidade de agrupamento de janelas +Comment[pt_BR]=Um gerenciador de janelas baseado em GTK+, com o recurso de agrupamento de janelas +Comment[ro]=Un manager de ferestre bazat pe GTK+ și cu posibilitatea de grupare a ferestrelor +Comment[ru]=Оконный менеджер на основе GTK+ c функцией группировки окон +Comment[rw]=GTK + bishingiye mugenga dirishya ifite idirishya rihuza ibiranga +Comment[se]=GTK+-vuođđoduvvon lásegieđahalli mii sáhttá sierra lásiid bidjat seamma joavkui +Comment[sk]=Správca okien založený na GTK+ s funkciou zoskupovania okien +Comment[sl]=Okenski upravitelj na osnovi GTK+ z možnostjo združevanja oken +Comment[sr]=Менаџер прозора заснован на GTK+-у са особином груписања прозора +Comment[sr@Latn]=Menadžer prozora zasnovan na GTK+-u sa osobinom grupisanja prozora +Comment[sv]=GTK+-baserad fönsterhanterare med en funktion för fönstergruppering +Comment[ta]=சாளர குழுப்பிரித்தல் தன்மையுடனான சாளர மேலாளர் அடிப்படையிலான GTK+. +Comment[tg]=Мудири равзанаҳо дар асоси GTK+ дорои фаъолияти гурӯҳ кардан равзанаҳо +Comment[th]=ตัวจัดการหน้าต่างที่ใช้พื้นฐานจาก GTK+ พร้อมด้วยความสามารถในการจัดกลุ่มหน้าต่าง +Comment[tr]=GTK+ tabanlı bir pencere yöneticisi +Comment[tt]=GTK+ asılında qorılğan, täräzälärne törkemli ala torğan täräzä-idäräçe +Comment[uk]=Менеджер вікон заснований на GTK+ з підтримкою групування вікон +Comment[uz]=A GTK+ asosida yaratilgan, oynalarni guruhlash imkoniyatiga ega oyna boshqaruvchi +Comment[uz@cyrillic]=A GTK+ асосида яратилган, ойналарни гуруҳлаш имкониятига эга ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ với khả năng tạo nhóm cửa sổ dựa trên GTK+ +Comment[wa]=On manaedjeu di purneas båzé so GTK+, avou ene fonccionålité di rgroupaedje des purneas +Comment[zh_CN]=一个基于 GTK+ 的窗口管理器,带有窗口成组特性 +Comment[zh_TW]=一個基於 GTK+ 的視窗管理程式並擁有視窗群組功能 diff --git a/tdm/kfrontend/sessions/amiwm.desktop b/tdm/kfrontend/sessions/amiwm.desktop new file mode 100644 index 000000000..ced73c346 --- /dev/null +++ b/tdm/kfrontend/sessions/amiwm.desktop @@ -0,0 +1,78 @@ +[Desktop Entry] +Type=XSession +Exec=amiwm +TryExec=amiwm +Name=AmiWM +Name[eo]=AmiFA +Name[hi]=एमी-डबल्यूएम +Name[sv]=Ami WM +Name[te]=ఎమి డబ్ల్యు ఎం +Comment=The Amiga look-alike window manager +Comment[af]='n Amiga gebaseerde venster bestuurder +Comment[ar]=مدبِر نوافذ مشابه لِــ Amiga +Comment[be]=Кіраўнік вокнаў, падобны на Amiga +Comment[bn]=অ্যামিগার মত দেখতে উইণ্ডো ম্যানেজার +Comment[bs]=Window manager nalik na Amigu +Comment[ca]=Un gestor de finestres que dona l'aspecte d'un Amiga +Comment[cs]=Správce oken podobný Amize +Comment[csb]=Menedżer òknów szlachùjący za Amiga +Comment[cy]=Trefnydd ffenestri sy'n edrych yn debyg i'r Amiga +Comment[da]=Amiga-lignende vindueshåndtering +Comment[de]=Fenstermanager im Stil des Amiga +Comment[el]=Ο διαχειριστής παραθύρων με όψη αλά Amiga +Comment[eo]=Fenestroadministrilo kiel tiu de Amiga +Comment[es]=Un gestor de ventanas con el aspecto de Amiga +Comment[et]=Amiga välimusega aknahaldur +Comment[eu]=Amigaren itxura duen leiho kudeatzailea +Comment[fa]=Amiga شبیه مدیر پنجره +Comment[fi]=Amigan tyylinen ikkunaohjelma +Comment[fr]=Le gestionnaire de fenêtres ressemblant à Amiga +Comment[fy]=In Amiga-likens finstersmanager +Comment[gl]=Un xestor de fiestras coma o de Amiga +Comment[he]=מנהל החלונות הדומה ל־Amiga +Comment[hi]=अमीगा की तरह दिखने वाला विंडो प्रबंधक +Comment[hr]=Upravitelj prozora koji podsjeća na Amigu +Comment[hu]=Egy Amiga-szerű ablakkezelő +Comment[is]=Gluggastjóri sem líkist Amiga tölvunum +Comment[it]=Un window manager in stile Amiga +Comment[ja]=Amiga に似たウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი Amiga-ს სტილში +Comment[kk]=Amiga секілді терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រប់​បង្អួច​ស្រដៀង Amiga +Comment[ko]=Amiga를 닮은 창 관리자 +Comment[lt]=Langų tvarkyklė, panaši į Amiga +Comment[lv]=Amiga izskata logu menedžeris +Comment[mk]=Менаџер на прозорци со изглед на Amiga +Comment[mn]=Amiga look-alike Цонхны удирдагч +Comment[ms]=Pengurus tetingkap serupa Amiga +Comment[mt]=Window manager jixbaħ lill-Amiga +Comment[nb]=Vindusbehandler som ligner på Amiga +Comment[nds]=De Finsterpleger mit dat Utsehn vun den Amiga +Comment[ne]=अमिगा सञ्झ्याल प्रबन्धक जस्तो छ +Comment[nl]=Een Amiga-achtige windowmanager +Comment[nn]=Vindaugssjef som liknar på Amiga +Comment[pa]=ਅਮੀਗਾ ਵਰਗਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien naśladujący Amigę +Comment[pt]=O gestor de janelas com o visual do Amiga +Comment[pt_BR]=Um gerenciador de janelas com a aparência do Amiga +Comment[ro]=Manager de ferestre cu aspect Amiga +Comment[ru]=Оконный менеджер в стиле Amiga +Comment[rw]=Amiga ijya gusa na mugenga dirishya +Comment[se]=Amiga-lágan lásegieđahalli +Comment[sk]=Správca okien podobný systému Amiga +Comment[sl]=Okenski upravitelj, podoben Amiginemu +Comment[sr]=Менаџер прозора који подсећа на Амигу +Comment[sr@Latn]=Menadžer prozora koji podseća na Amigu +Comment[sv]=Fönsterhanteraren som ser ut som Amiga +Comment[ta]=சாளர மேலாளரை ஒத்த அமிகா +Comment[tg]=Монанди мудири тирезаи Amiga look +Comment[th]=ระบบจัดการหน้าต่างที่ดูเหมือน Amiga +Comment[tr]=Amiga görünümlü bir pencere yöneticisi +Comment[tt]=Amiga küreneşendä täräzä idäräçe +Comment[uk]=Менеджер вікон на штиб Amiga +Comment[uz]=Amiga'ga oʻxshash oyna boshqaruvchi +Comment[uz@cyrillic]=Amiga'га ўхшаш ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ nhìn giống Amiga +Comment[wa]=On manaedjeu di purneas rishonnant l' ci di l' Amiga +Comment[zh_CN]=Amiga 外观的窗口管理器 +Comment[zh_TW]=一個看起來像 Amiga 視窗管理程式 diff --git a/tdm/kfrontend/sessions/asclassic.desktop b/tdm/kfrontend/sessions/asclassic.desktop new file mode 100644 index 000000000..e84a0977e --- /dev/null +++ b/tdm/kfrontend/sessions/asclassic.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=XSession +Exec=asclassic +TryExec=asclassic +Name=ASClassic +Name[af]= ASClassic +Name[cy]=ASClasurol +Name[eo]=KlasikaPP +Name[hi]=एएस-क्लॉसिक +Name[ne]=AS शास्त्रीय +Name[sv]=AS klassisk +Name[ta]=ASதரமான +Name[te]=ఏఎస్ క్లాసిక్ +Comment=AfterStep Classic, a window manager based on AfterStep v1.1 +Comment[af]=AfterStep Classic, 'n venster bestuurder wat op AfterStep v1.1 gebaseer is. +Comment[ar]=AfterStep كلاسيك، وهو مدير نوافذ مبني على AfterStep الإصدارة 1.1 +Comment[be]=Класічны AfterStep, кіраўнік вокнаў, заснаваны на AfterStep 1.1 +Comment[bn]=আফটার-স্টেপ ক্লাসিক: আফটার-স্টেপ ১.১ ভিত্তিক একটি উইণ্ডো ম্যানেজার +Comment[bs]=AfterStep Classic, window manager baziran na AfterStep v1.1 +Comment[ca]=El clàssic AfterStep, un gestor de finestres basat en AfterStep v1.1 +Comment[cs]=AfterStep Classic, správce oken založený na AfterStepu v1.1 +Comment[csb]=AfterStep Classic, menedżer òknów ùsôdzony na spòdlém AfterStep v1.1 +Comment[cy]=ÔlGam Clasurol, trefnydd ffenestri wedi'i seilio ar AfterStep v1.1 +Comment[da]=AfterStep Classic, en vindueshåndtering baseret på AfterStep v1.1 +Comment[de]=AfterStep Classic, ein Fenstermanager, der auf AfterStep v1.1 basiert +Comment[el]=AfterStep κλασικός, ένας διαχειριστής παραθύρων βασισμένος στον AfterStep v1.1 +Comment[eo]=Klasika Postpaŝo, fenestroadministrilo kiel Postpaŝo v1.1 +Comment[es]=AfterStep Classic, un gestor de ventanas basado en AfterStep v1.1 +Comment[et]=AfterStep Classic - aknahaldur, mille aluseks on AfterStep v1.1 +Comment[eu]=AfterStep Classic, AfterStep v1.1-en oinarrituta dagoen leiho kudeatzailea +Comment[fa]=AfterStep کلاسیک، مدیر پنجره بر اساس AfterStep نسخه ۱.۱ +Comment[fi]=AfterStep Classic, After Step v1.1:een pohjautuva ikkunaohjelma +Comment[fr]=AfterStep Classic, un gestionnaire de fenêtres fondé sur AfterStep v1.1 +Comment[fy]=AfterStep Classic, In finstersmanager basearre op AfterStep 1.1 +Comment[gl]=AfterStep Clásico, un xestor de fiestras baseado en AfterSetp v1.1 +Comment[he]=AfterStep Classic, מנהל חלונות המבוסס על AfterStep v1.1 +Comment[hi]=आफ्टरस्टेप क्लासिक, एक विंडो प्रबंधक जो आफ्टरस्टेप व.1 पर आधारित है +Comment[hr]=Klasični AfterStep, upravitelj prozora zasnovan na AfterStepu verzija 1.1 +Comment[hu]=AfterStep Classic ablakkezelő, az AfterStep v1.1 alapján +Comment[is]=Klassískur AfterStep gluggastjóri byggður á AfterStep v1.1 +Comment[it]=AfterStep Classico, un window manager basato su AfterStep v1.1 +Comment[ja]=AfterStep クラシック, AfterStep v1.1 ベースのウィンドウマネージャ +Comment[ka]=AfterStep Classic, ფანჯრის მენეჯერი AfterStep v1.1 -ის ბაზაზე +Comment[kk]=AfterStep v1.1 негіздеген AfterStep Classic терезе менеджері +Comment[km]=AfterStep បុរាណ,កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​ផ្អែក​លើ AfterStep v1.1 +Comment[ko]=AfterStrp 1.1 기반 창 관리자 +Comment[lt]=AfterStep Classic, langų tvarkyklė, paremta AfterStep v1.1 +Comment[lv]=Klasiskais Afterstep, logu menedžeris bāzēts uz AfterStem v1.1 +Comment[mk]=AfterStep Classic, менаџер на прозорци базиран на AfterStep v1.1 +Comment[mn]=AfterStep Classic, AfterStep v1.1 дээр суурилсан цонх удирдагч +Comment[mt]=AfterStep klassiku, window manager ibbażat fuq AfterStep v1.1 +Comment[nb]=AfterStep Classic, en vindusbehandler basert på AfterStep v1.1 +Comment[nds]=De AfterStepClassic-Finsterpleger is opbuut op AfterStep v1.1 +Comment[ne]=AfterStep शास्त्रीय, AfterStep v१.१ मा आधारित सञ्झ्याल प्रबन्धक +Comment[nl]=AfterStep Classic, een windowmanager gebaseerd op AfterStep 1.1 +Comment[nn]=AfterStep Classic, ein vindaugssjef som byggjer på AfterStep 1.1 +Comment[pa]=AfterStep ਟਕਸਾਲੀ, AfterStep v1.1 ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=AfterStep Classic, menedżer okien stworzony na podstawie AfterStep v1.1 +Comment[pt]=AfterStep Classic, um gestor de janelas baseado no AfterStep v1.1 +Comment[pt_BR]=AfterSep clássico, um gerenciador de janelas baseado no AfterStep v1.1 +Comment[ro]=AfterStep Classic, un manager de ferestre bazat pe AfterStep v1.1 +Comment[ru]=AfterStep Classic, оконный менеджер на основе AfterStep v1.1 +Comment[rw]=AfterStep Classic, mugenga dirishya ishingiye kuri AfterStep v1.1 +Comment[se]=AfterStep Classic, lásegieđahalli ráhkaduvvon AfterStep 1.1 vuođul +Comment[sk]=AfterStep Classic, správca okien založený na AfterStep v1.1 +Comment[sl]=AfterStep Classic, okenski upravitelj na osnovi AfterStep različice 1.1 +Comment[sr]=Класични AfterStep, менаџер прозора заснован на AfterStep-у верзије 1.1 +Comment[sr@Latn]=Klasični AfterStep, menadžer prozora zasnovan na AfterStep-u verzije 1.1 +Comment[sv]=Afterstep klassisk, en fönsterhanterare baserad på Afterstep version 1.1 +Comment[ta]=ஆஃப்டர்ஸ்டெப் க்ளாசிக், ஆஃப்டர்ஸ்டெப் க்ளாசிக் v1.1 அடிப்படையிலான சாளர மேலாளர் +Comment[tg]=Мудири равзанаҳои AfterStep Classic дар асоси AfterStep v1.1 +Comment[th]=AfterStep Classic คือระบบจัดการหน้าต่างที่ใช้ฐานของอาฟเตอร์สเตปเวอร์ชั่น 1.1 +Comment[tr]=AfterStep Classic pencere yöneticisi +Comment[tt]=AfterStep Classic, AfterStep v1.1 asılında täräzä-idäräçe +Comment[uk]=AfterStep Classic, менеджер вікон, заснований на AfterStep v1.1 +Comment[uz]=AfterStep Classic - AfterStep v1.1 asosida yaratilgan oyna boshqaruvchi +Comment[uz@cyrillic]=AfterStep Classic - AfterStep v1.1 асосида яратилган ойна бошқарувчи +Comment[vi]=AfterStep Classic, một trình quản lý cửa sổ dựa trên AfterStep v1.1 +Comment[wa]=AfterStep Classic, on manaedjeu di purneas båzé so AfterStep v1.1 +Comment[zh_CN]=AfterStep 经典,一个基于 AfterStep v1.1 的窗口管理器 +Comment[zh_TW]=AfterStep 經典, 一個基於 AfterStep v1.1 的視窗管理程式 diff --git a/tdm/kfrontend/sessions/blackbox.desktop b/tdm/kfrontend/sessions/blackbox.desktop new file mode 100644 index 000000000..457ec7614 --- /dev/null +++ b/tdm/kfrontend/sessions/blackbox.desktop @@ -0,0 +1,88 @@ +[Desktop Entry] +Type=XSession +Exec=blackbox +TryExec=blackbox +Name=Blackbox +Name[bn]=ব্ল্যাকবক্স +Name[cy]= Du-flwch (Blackbox) +Name[eo]=Negrujo +Name[hi]=ब्लेकबॉक्स +Name[ja]=BlackBox +Name[mn]=Хар хайрцаг +Name[ne]=कालो बाकस +Name[pa]=ਕਾਲਾਬਕਸਾ +Name[rw]=AgasandukuUmukara +Name[ta]=கறுப்புப் பெட்டி +Name[te]=నల్లడబ్బా +Name[tg]=Қуттии сиёҳ +Comment=A fast & light window manager +Comment[af]='n Vinnige, lig gewig venster bestuurder +Comment[ar]=مدير نوافذ خفيف وسريع +Comment[be]=Хуткі і лёгкі кіраўнік вокнаў +Comment[bg]=Бърз и лек мениджър на прозорци +Comment[bn]=একটি হালকা এবং দ্রুত উইণ্ডো ম্যানেজার +Comment[bs]=Brz i lagan window manager +Comment[ca]=Un gestor de finestres ràpid i clar +Comment[cs]=Rychlý a malý správce oken +Comment[csb]=Chùtczi menedżer òknów o môłëch żądaniach +Comment[cy]=Trefnydd ffenestri cyflym ac ysgafn +Comment[da]=En hurtig & let vindueshåndtering +Comment[de]=Kleiner, schneller Fenstermanager +Comment[el]=Ένας γρήγορος και ελαφρύς διαχειριστής παραθύρων +Comment[eo]=Rapida kaj malpeza fenestroadministrilo +Comment[es]=Un gestor de ventanas rápido y ligero +Comment[et]=Kiire ja vähenõudlik aknahaldur +Comment[eu]=Leiho kudeatzaile bizkor eta arina +Comment[fa]=یک مدیر پنجرۀ سبک و سریع +Comment[fi]=Kevyt ja nopea ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres rapide et léger +Comment[fy]=In flugge lichtgewicht finstersmanager +Comment[ga]=Bainisteoir fuinneoga gasta éadrom +Comment[gl]=Un xestor de fiestras lixeiro e rápido +Comment[he]=מנהל חלונות מהיר וקל +Comment[hi]=तेज और सरल विंडो प्रबंधक +Comment[hr]=Brzi i lagani upravitelj prozora +Comment[hu]=Egy gyors, egyszerű ablakkezelő +Comment[is]=Léttur og hraðvirkur gluggastjóri +Comment[it]=Un window manager veloce e leggero +Comment[ja]=軽快なウィンドウマネージャ +Comment[ka]=სწრაფი და მსუბუქი ფანჯრის მენეჯერი +Comment[kk]=Жедел және жеңіл терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​លឿន ហើយ​ភ្លឺ +Comment[ko]=빠르고 가벼운 창 관리자 +Comment[lt]=Greita ir nedaug resursų naudojanti langų tvarkyklė +Comment[lv]=Ātrs un viegls logu menedžeris +Comment[mk]=Брз и лесен менаџер на прозорци +Comment[mn]=Хурдан & хөнгөн цонхны удирдагч +Comment[ms]=Pengurus tetingkap yang pantas & ringan +Comment[mt]=Window manager ħafif u żgħir +Comment[nb]=En rask og lett vindusbehandler +Comment[nds]=En gaue un lütte Finsterpleger +Comment[ne]=छिटो र हल्का सञ्झ्याल प्रबन्धक +Comment[nl]=Een snelle lichtgewicht windowmanager +Comment[nn]=Ein rask og lett vindaugssjef +Comment[pa]=ਇੱਕ ਤੇਜ਼ ਅਤੇ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Szybki menedżer okien o małych wymaganiach +Comment[pt]=Um gestor de janelas rápido e leve +Comment[pt_BR]=Um gerenciador de janelas rápido e leve +Comment[ro]=Un manager de ferestre mic și rapid +Comment[ru]=Быстрый и лёгкий оконный менеджер +Comment[rw]=Mugenga dirishya yihuta & yoroshye +Comment[se]=Jođánis ja geahpes lásegieđahalli +Comment[sk]=Rýchly a nenáročný správca okien +Comment[sl]=Hiter in lahek okenski uporavljalnik +Comment[sr]=Брзи и лагани менаџер прозора +Comment[sr@Latn]=Brzi i lagani menadžer prozora +Comment[sv]=Snabb och lättviktig fönsterhanterare +Comment[ta]=விரைவான மற்றும் இலகுவான KDE சாளர மேலாளர் +Comment[tg]=Суст ва мудири тирезаи равшан +Comment[th]=ระบบจัดการหน้าต่างที่เร็วและเบา +Comment[tr]=Hızlı ve hafif bir pencere yöneticisi +Comment[tt]=Citez ciñel täräzä-idäräçe +Comment[uk]=Легкий та швидкий менеджер вікон +Comment[uz]=Tez va oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=Тез ва оддий ойна бошқарувчи +Comment[vi]=Một trình quản lý cửa sổ nhẹ và nhanh +Comment[wa]=On ledjir et roed manaedjeu di purneas +Comment[zh_CN]=又快又轻巧的窗口管理器 +Comment[zh_TW]=一個快速及輕量化的視窗管理程式 diff --git a/tdm/kfrontend/sessions/cde.desktop b/tdm/kfrontend/sessions/cde.desktop new file mode 100644 index 000000000..1f2dee088 --- /dev/null +++ b/tdm/kfrontend/sessions/cde.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Type=XSession +Exec=/usr/dt/bin/Xsession +TryExec=/usr/dt/bin/Xsession +Name=CDE +Name[hi]=सीडीई +Name[mn]=КДE +Name[te]=సిడిఈ +Name[tg]=Муҳити графикии муштарак (CDE) +Name[th]=แบบ CDE +Comment=The Common Desktop Environment, a proprietary industry standard desktop environment +Comment[af]=Die 'Common Desktop Environment', 'n beskermde, industrie standaard werkskerm omgewing +Comment[ar]=محيط سطح المكتب الشائع، محيط سطح المكتب الصناعي المعايير +Comment[be]=Common Desktop Environment, прапрыетарнае стандартнае працоўнае асяроддзе +Comment[bn]=কমন ডেস্কটপ এনভায়রনমেন্ট (Common Desktop Environment), একটি মালিকানাধীন ইনডাস্ট্রি স্ট্যান্ডার্ড +Comment[bs]=Common Desktop Environment, vlasnička desktop okolina, industrijski standard +Comment[ca]=The Common Desktop Environment, l'entorn d'escriptori estàndard de la indústria propietària +Comment[csb]=Common Desktop Environment, sztandardowé industrëjné òkrãże pùltu +Comment[cy]=Yr Amgylchedd Penbwrdd Cyffredin (Common Desktop Environment), amgylchedd penbwrdd perchnogol sy'n safonol yn y diwydiant +Comment[da]=Common Desktop Environment, et privatejet industristandard desktopmiljø +Comment[de]=Das Common Desktop Environment, eine proprietäre Arbeitsumgebung und ein Industriestandard +Comment[el]=To Κοινό Περιβάλλον Επιφάνειας εργασίας, ένα βιομηχανικό πρότυπο επιφάνειας εργασίας +Comment[eo]=La Komuna Labortablo Ĉirkaŭaĵo +Comment[es]=El Common Desktop Environment, un estándar en los entornos de escritorio propietarios +Comment[et]=Üldine töölaua keskond (Common Desktop Environment) on kaubanduslik standardne töölaua keskkond +Comment[eu]=Common Desktopo Environment, mahaigain jabedun inguruneetako estandarra +Comment[fa]=محیط رومیزی مشترک، محیط رومیزی استاندارد صنعت اختصاصی +Comment[fi]=Common Desktop Environment, patentoitu työpöytäympäristöjen teollisuusstandardi +Comment[fr]=Le Common Desktop Environment, un environnement de bureau propriétaire standard dans l'industrie +Comment[fy]=The Common Desktop Environment, In kommersjele yndustrieel standerdisearre buroblêd omwrâld +Comment[gl]=O Common Desktop Environment, un entorno de escritório proprietario estándar para industria +Comment[he]=The Common Desktop Environment, סביבת עבודה מסחרית וקניינית סטנדרטית +Comment[hi]=सामूहिक डेस्कटॉप माहौल, एक स्वामित्व युक्त औद्योगिक मानक डेस्कटॉप माहौल +Comment[hr]=Opće okruženje radne površine, standardizirano industrijskim vlasništvima +Comment[hu]=The Common Desktop Environment, egy kereskedelmi, kváziszabványnak számító grafikus környezet +Comment[is]=Common Desktop Environment er lokað skjáborðsumhverfi sem var staðlað umhverfi til skamms tíma +Comment[it]=Il Common Desktop Environment, un desktop environment proprietario standard. +Comment[ja]=Common Desktop Environment,プロプライエタリな業界標準のデスクトップ環境 +Comment[ka]=Common Desktop Environment, UNIX -ის სამუშაო სფეროს სამრეწვლო სტანდარტი +Comment[kk]=Common Desktop Environment - UNIX жұмыс ортаның өнеркәсіп стандарты +Comment[km]=The Common Desktop Environment, បរិស្ថាន​ផ្ទៃតុ​ខ្នាត​គំរូ​ដែល​មាន​កម្មសិទ្ធិ +Comment[lt]=Common Desktop Environment, nuosavybinių sistemų standartinė darbastalio tvarkyklė +Comment[mk]=Common Desktop Environment, сопственичка индустриски стандардна работна околина +Comment[mn]=Нийтлэг дэлгэцийн системийн орчин, үйлдвэрийн стандарт дэлгэцийн системийн орчин +Comment[ms]=Persekitaran Desktop Biasa, persekitaran desktop standard industri proprietari +Comment[mt]=Common Desktop Environment, ambjent grafiku propjetarju u standard tal-industrija +Comment[nb]=Common desktop Environment, et godseid skrivebordsmiljø som er standard i programvareindustrien +Comment[nds]=De Common Desktop Environment, de Schriefdisch-Ümgeven vun en proprieteren Industrie-Standard +Comment[ne]=साझा डेस्कटप वातावरण, श: शुल्क उद्योग मानक डेस्कटप वातावरण +Comment[nl]=The Common Desktop Environment, een commerciële industrieel gestandariseerde desktop environment +Comment[nn]=Common Desktop Environment, eit godseigd skrivebordsmiljø som er standard i programvareindustrien +Comment[pa]=ਇੱਕ ਆਮ ਵੇਹੜਾ ਵਾਤਾਵਰਣ, ਇੱਕ ਵਪਾਰਿਕ ਮਿਆਰ ਦਾ ਵੇਹੜਾ ਵਾਤਾਵਰਣ +Comment[pl]=Common Desktop Environment, standardowe przemysłowe środowisko pulpitu +Comment[pt]=O Common Desktop Environment, um ambiente de trabalho gráfico padrão e proprietário +Comment[pt_BR]=O Ambiente de Trabalho Comum (CDE), um ambiente de trabalho proprietário padrão da indústria +Comment[ro]=Common Desktop Environment, un mediu grafic proprietar și devenit standard industrial +Comment[ru]=Common Desktop Environment, промышленный стандарт рабочей среды UNIX +Comment[rw]=Ibikikije Ibiro Rusange, ibikikije ibiro bisanzwe bwite by'isosiyete +Comment[se]=Common Desktop Environment, čállinbeavdebiras mii lea standárda prográmmagálvoindustriijas +Comment[sk]=The Common Desktop Environment, proprietárne štandardné pracovné prostredie +Comment[sl]=Common Desktop Environment, lastniško standardno industrijsko namizno okolje +Comment[sr]=„Common Desktop Environment“, власничко индустријски стандардно радно окружење +Comment[sr@Latn]=„Common Desktop Environment“, vlasničko industrijski standardno radno okruženje +Comment[sv]=Common Desktop Environment, en privatägd industristandard skrivbordsmiljö +Comment[ta]=பொதுவான மேல்மேசை, தன்உரிமை உடைய நிறுவனத்தின் நிலையான மேல்மேசை சூழல் +Comment[tg]=Common Desktop Environment дар асоси UNIX +Comment[th]=Common Desktop Environment คือ สภาพแวดล้อมของพื้นที่ทำงานที่ได้มาตรฐานอุตสาหกรรม ที่ไม่ใช่ซอฟต์แวร์เสรี +Comment[tr]=Common Desktop Environment (CDE) +Comment[tt]=Common Desktop Environment, UNIX öçen citeşterü standardı +Comment[uk]=The Common Desktop Environment, закритий промисловий стандарт графічного середовища +Comment[vi]=Môi trường Màn hình nền Chung, một môi trường màn hình nền giữ bản quyền, tuân thủ chuẩn công nghiệp +Comment[wa]=Li Comon Evironmint d' Sicribanne (Common Desktop Environment), on evironmint d' sicribanne nén libe po l' industreye +Comment[zh_CN]=通用窗口环境(CDE),私有工业标准的桌面环境 +Comment[zh_TW]=The Common Desktop Environment, 一個有專利的工業標準 diff --git a/tdm/kfrontend/sessions/ctwm.desktop b/tdm/kfrontend/sessions/ctwm.desktop new file mode 100644 index 000000000..e7ee84471 --- /dev/null +++ b/tdm/kfrontend/sessions/ctwm.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=XSession +Exec=ctwm +TryExec=ctwm +Name=CTWM +Name[eo]=TFAC +Name[hi]=सीटीडबल्यूएम +Name[te]=సి టి డబ్ల్యు ఎం +Comment=Claude's Tab Window Manager, TWM enhanced by virtual screens, etc. +Comment[af]=Claude se Tab venster bestuurder. Dis TWM wat met virtuele skerms verbeter is +Comment[ar]=مدير نوافذ Claude's Tab، وهي TWM محسّن بشاشات وهمية، إلخ. +Comment[be]=Кіраўнік вокнаў з укладкамі ад Claude, TWM з падтрымкай віртуальных экранаў і інш. +Comment[bg]=Claude"s Tab Window Manager, TWM enhanced by virtual screens, etc. +Comment[bn]=ক্লড-এর ট্যাব উইণ্ডো ম্যানেজার +Comment[bs]=Claude's Tab Window Manager, TWM proširen virtuelnim ekranima itd. +Comment[ca]=Gestor de finestres amb pestanyes d'en Claude, millores TWM per a pantalles virtuals, etc. +Comment[csb]=Menedżer òknów Claude, TWM zbògacony ò wirtualné pùltë, ëtp. +Comment[cy]=Trefnydd Ffenestri Tab Claude, TWM wedi ei wella gan sgriniau rhith, ayyb. +Comment[da]=Claude's Tab vindueshåndtering, TWM udvidet med virtuelle skærme osv. +Comment[de]=Claudes Fenstermanager mit Karteikartenfenstern, eine verbesserte Fassung von TWM mit virtuellen Ansichten usw. +Comment[el]=Ο διαχειριστής παραθύρων Tab του Claude, ο TWM εμπλουτισμένος με εικονικές οθόνες, κτλ. +Comment[eo]=Taba Fenestroadministrilo de Claude, TWM, bonigita per virtualaj ekranoj ktp +Comment[es]=Claude's Tab Window Manager, TWM mejorado con pantallas virtuales, etc. +Comment[et]=Claude kaartidega aknahaldur, aluseks TWM, mida on täiendatud virtuaaltöölaudadega jne. +Comment[eu]=Claude's Tab leiho kudeatzailea, pantaila birtual eta abarrez hobetutako TWMa +Comment[fa]=مدیر پنجرۀ تب Claude، TWM، گسترش‌یافته توسط پرده‌های مجازی و غیره. +Comment[fi]=Clauden välilehtiikkunaohjelma. TWM, johon lisätty muun muassa virtuaalityöpöydät. +Comment[fr]=Claude's Tab Window Manager, TWM avec en plus les bureaux virtuels, etc. +Comment[fy]=Claude's Tab _indow Manager, TWM útbreide mei firtuele skermen etc. +Comment[gl]=Xestor de Fiestras de Claude, TWM mellorado con pantallas virtuais, etc. +Comment[he]=Claude's Tab Window Manager, TWM המשופרת על ידי מסכים וירטואליים וכו' +Comment[hi]=क्लाउडे का टैब युक्त विंडो प्रबंधक, टीडबल्यूएम को आभासी स्क्रीन इत्यादि से बेहतर बनाया गया. +Comment[hr]=Claudov Tab upravitelj prozora, TWM poboljšan virtualnim zaslonima, itd. +Comment[hu]=Claude lapozós ablakkezelője, lényegében a TWM, kiegészítve virtuális képernyőkkel, egyebekkel +Comment[is]=Tab gluggastjórinn eftir Claude sem hefur verið endurbættur með sýndarskjáum og fl. +Comment[it]=Window manager con linguette di Claude, TWM migliorato con schermi virtuali, ecc. +Comment[ja]=TWM に仮想デスクトップなどを強化した Claude のウィンドウマネージャ +Comment[ka]=Claude's Tab Window Manager - TWM-ის გაუმჯობესებული ვერსია +Comment[kk]=Claude's Tab Window Manager, TWM-ның жетілдірген нұсқасы. +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ជា​ផ្ទាំង​របស់ Claude, TWM ដែល​ធ្វើ​ឲ្យ​ប្រសើរ​ដោយ​អេក្រង់​និមិត្ត​ជាដើម +Comment[lt]=Claude kortelių langų tvarkyklė, TWM praplėsta virtualių ekranų palaikymu ir t.t. +Comment[mk]=Claude's Tab Window Manager, TWM подобрен менаџер со виртуелни екрани итн. +Comment[mn]=Клаудиагийн  ТАВ цонхны удирдагч, TWM виртуал дэлгэцээр өргөтгөгдсөн, гэх мэт. +Comment[mt]=Claude's Tab Window Manager, TWM flimkien ma' virtual screens, eċċ. +Comment[nb]=Claude's Tab Window Manager, TWM forbedret med virtuelle skrivebord,osv. +Comment[nds]=Claude's Tab Finsterpleger, TWM verbetert üm virtuelle Schriefdischen usw. +Comment[ne]=क्लाउडको ट्याब सञ्झ्याल प्रबन्धक, अवास्तविक पर्दाद्वारा बृद्धि गरिएको TWM, आदि +Comment[nl]=Claude's Tab Window Manager, TWM uitgebreid met virtuele schermen etc. +Comment[nn]=Claude's Tab Window Manager, TWM med virtuelle skrivebord og andre forbetringar +Comment[pa]=ਕਲਾਉਡੀ ਦਾ ਟੈਬ ਝਰੋਖਾ ਮੈਨੈਜਰ, TWM ਫਰਜ਼ੀ ਪਰਦਿਆਂ ਆਦਿ ਨਾਲ ਲੈੱਸ ਹੈ। +Comment[pl]=Menedżer okien Claude, TWM wzbogacony o wirtualne pulpity, itp. +Comment[pt]=O Tab Window Manager do Claude, um TWM melhorado com ecrãs virtuais, etc. +Comment[pt_BR]=O gerenciador de janelas em abas do Claude, o TWM melhorado pelas telas virtuais, etc. +Comment[ro]=Managerul de ferestre al lui Claude, o versiune îmbunătățită de TWM cu ecrane virtuale etc. +Comment[ru]=Claude's Tab Window Manager - улучшенная версия TWM +Comment[rw]=Mugenga Dirishya y'Agafishi ya Claude, TWM ivuguruwe na mugaragaza zitagaragara, n'ibindi +Comment[se]=Claudea Tab Window Manager, TWM mas lea virtuella čállinbeavddit ja eará buorideamit. +Comment[sk]=Claude's Tab Window Manager, TWM rozšírený o virtuálne plochy, atď. +Comment[sl]=Claude's Tab Window Manager, TWM izboljšan z navideznimi zasloni ipd. +Comment[sr]=„Claude's Tab Window Manager“, TWM побољшан виртуелним екранима и сл. +Comment[sr@Latn]=„Claude's Tab Window Manager“, TWM poboljšan virtuelnim ekranima i sl. +Comment[sv]=Claudes fönsterhanterare med flikar, TWM förbättrad med virtuella skärmar, etc. +Comment[ta]= க்ளூடின் தத்தல் சாளர மேளாளர், TWM ஆல் மேம்படுத்தப்பட்ட மெய்நிகர் திரைகள்.. +Comment[tg]=Claude's Tab Window Manager - Версияи навтарини TWM +Comment[th]=ตัวจัดการแท็บหน้าต่างของ Claude คือ TWM ที่เพิ่มความสามารถด้วยหน้าจอเสมือน และอื่นๆ +Comment[tr]=Claude's Sekme Pencere Yöneticisi, sanal ekranlar ile TWM genişletilmiş, vb. +Comment[tt]=Claude's Tab Window Manager, TWM'nıñ qulaylanğan töre +Comment[uk]=Claude's Tab Window Manager, TWM з підтримкою віртуальних екранів, тощо. +Comment[vi]=Trình quản lý cửa sổ kiểu Thẻ của Claude, TWM cải tiến với màn hình ảo v.v. +Comment[wa]=Li Manaedjeu di Purneas a Linwetes di Claude (Claude's Tab Window Manager). TWM permete des forveyowès waitroûles, evnd. +Comment[zh_CN]=Claude 的标签式窗口管理器,加强了虚拟屏幕等功能的 TWM。 +Comment[zh_TW]=Claude's Tab 視窗管理程式, 基於 TWM 並加強虛擬螢幕等功能 diff --git a/tdm/kfrontend/sessions/cwwm.desktop b/tdm/kfrontend/sessions/cwwm.desktop new file mode 100644 index 000000000..51b60abd3 --- /dev/null +++ b/tdm/kfrontend/sessions/cwwm.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Type=XSession +Exec=cwwm +TryExec=cwwm +Name=CWWM +Name[eo]=CWFA +Name[hi]=सीडबल्यूडबल्यूएम +Name[te]=సి డబ్ల్యు డబ్ల్యు ఎం +Comment=The ChezWam Window Manager, a minimalist window manager based on EvilWM +Comment[af]=Die ChezWam venster bestuurder. Dis 'n minimalistiese venster bestuurder wat op EvilWM gebaseer is. +Comment[ar]=مدير نوافذ ChezWam، وهو مدير نوافذ مصغّر مبني على EvilWM +Comment[be]=Кіраўнік вокнаў ChezWam, мінімалістычны, заснаваны на EvilWM +Comment[bn]=ChezWam উইণ্ডো ম্যানেজার, EvilWM ভিত্তিক একটি উইণ্ডো ম্যানেজার +Comment[bs]=ChezWam Window Manager, minimalistički window manager baziran na EvilWM +Comment[ca]=El gestor de finestres ChezWam, un gestor de finestres minimalista basat en EvilWM +Comment[cs]=ChezWam, minimalistický správce oken založený na EvilWM +Comment[csb]=Menedżer òknów ChezWam, prosti menedżer òknów ùsôdzony na spòdlém EvilWM +Comment[cy]=Y Trefnydd Ffenestri ChezWam, trefnydd ffenestri lleiafol wedi'i seilio ar EvilWM +Comment[da]=ChezWam vindueshåndteringen, en minimalistisk vindueshåndtering baseret på EvilWM +Comment[de]=Deer ChezWam-Fenstermanager, eine minimalistische Lösung, die auf EvilWM basiert +Comment[el]=Ο ChezWam διαχειριστής παραθύρων, ένας μινιμαλιστικός διαχειριστής παραθύρων βασισμένος στον EvilWM +Comment[eo]=La ChezWam Fenestroadministrilo, devenigita de MalbonaFA +Comment[es]=El gestor de ventanas ChezWam, un gestor minimalista basado en EvilWM +Comment[et]=ChezWami aknahaldur on vähenõudlik aknahaldur, mille aluseks on EvilWM +Comment[eu]=ChezWarn leiho kudeatzailea, EvilWM-en oinarritutako leiho kudeatzaile minimalista +Comment[fa]=مدیر پنجره ChezWam، مدیر پنجرۀ کمینه بر اساس EvilWM +Comment[fi]=ChezWam, minimalistinen EvilWM:ään pohjautuva ikkunaohjelma. +Comment[fr]=Le ChezWam Window Manager, un gestionnaire de fenêtres minimaliste fondé sur EvilWM +Comment[fy]=The ChezWam Window Manager, in minimalistyske finstersmanager baseare op EvilWM +Comment[gl]=O Xestor de Fiestras ChezWarm, un xestor minimalista baseado en EvilWM +Comment[he]=The ChezWam Window Manager, מנהל חלונות מינימליסטי המבוסס על EvilWM +Comment[hi]=चेकवाम विंडो प्रबंधक, एक अल्पतम विंडो प्रबंधक EvilWM पर आधारित +Comment[hr]=ChezWam, minimalistički upravitelj prozora zasnovan na EvilWM +Comment[hu]=ChezWam ablakkezelő, egy nagyon egyszerű ablakkezelő az EvilWM alapján +Comment[is]=ChezWam gluggastjórinn er lágmarks gluggastjóri sem er byggður á EvilWM +Comment[it]=Il ChezWam Window Manager, un window manager minimalista basato su EvilWM +Comment[ja]=ChezWam ウィンドウマネージャ, EvilWM ベースの小さなウィンドウマネージャ +Comment[ka]=ChezWam Window Manager - მინიმალისტური ფანჯრის მენეჯერი EvilWM -ის ბაზაზე +Comment[kk]=ChezWam Window Manager, EvilWM-негіздеген шағын терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច ChezWam ដែល​ជា​កម្មវិធី​គ្រប់គ្រង​បង្អួច​មិន​សូវ​សម្បូរ​បែប​ហើយ​ផ្អែក​លើ EvilWM +Comment[lt]=ChezWam langų tvarkyklė, minimalistinė langų tvarkyklė, paremta EvilWM +Comment[mk]=ChezWam Window Manager, минималистички менаџер на прозорци базиран на EvilWM +Comment[mn]=ChezWam Цонхны удирдагч, EvilWM дээр суурилсан хамгийн жижиг цонхны удирдагч +Comment[mt]=ChezWam Window Manager - window manager minimu ibbażat fuq EvilWM +Comment[nb]=The ChezWam Window Manager, en minimalistisk vindusbehandler basert på EvilWM +Comment[nds]=De ChezWam Finsterpleger is minimalistisch un buut op EvilWM op +Comment[ne]=चेजवाम सञ्झ्याल प्रबन्धक, EvilWM आधारित मिनिमलिस्ट सञ्झ्याल प्रबन्धक +Comment[nl]=The ChezWam Window Manager, een minimalistische windowmanager gebaseerd op EvilWM +Comment[nn]=ChezWam Window Manager, ein minimalistisk vindaugssjef som byggjer på EvilWM +Comment[pa]=ChezWam ਝਰੋਖਾ ਮੈਨੇਜਰ, ਇੱਕ EvilWM ਤੇ ਆਧਾਰਿਤ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ ਹੈ +Comment[pl]=Menedżer okien ChezWam, prosty menedżer okien stworzony na podstawie EvilWM +Comment[pt]=O ChezWam Window Manager, um gestor de janelas minimalista baseado no EvilWM +Comment[pt_BR]=O gerenciador de janelas de ChezWam, um gerenciador de janelas minimalista baseado no EvilWM +Comment[ro]=Managerul de ferestre ChezWam, o versiune minimalistică bazată pe EvilWM +Comment[ru]=ChezWam Window Manager - минимальный оконный менеджер на основе EvilWM +Comment[rw]=Mugenga Dirishya ChezWam, mugenga dirishya igira-nto ishingiye kuri EvilWM +Comment[se]=ChezWam Window Manager, ein minimalisttalaš lásegieđahalli, ráhkaduvvon EvilWM vuođul +Comment[sk]=The ChezWam Window Manager, minimálny správca okien založený na EvilWM +Comment[sl]=ChezWam Window Manager, skromen okenski upravitelj na osnovi EvilWM +Comment[sr]=„ChezWam Window Manager“, минималистички менаџер прозора заснован на EvilWM-у +Comment[sr@Latn]=„ChezWam Window Manager“, minimalistički menadžer prozora zasnovan na EvilWM-u +Comment[sv]=Fönsterhanteraren Chezwam, en minimalistisk fönsterhanterare baserad på Ond WM +Comment[ta]=செஸ்வாம் சாளர மேளாளர்,EvilWM ஐ அடிப்படையிலான குறைந்தபட்ச சாளர மேளாளர் +Comment[tg]=ChezWam Window Manager - Мудири равзанаҳои хурд дар асоси EvilWM +Comment[th]=ตัวจัดการหน้าต่าง ChezWarm คือ ระบบจัดการ หน้าต่างขนาดเล็ก สร้างจากพื้นฐานของ EvilWM +Comment[tr]=ChezWam Pencere Yöneticisi +Comment[tt]=ChezWam Window Manager, EvilWM asılında ciñel täräzä-idäräçe +Comment[uk]=Мінімалістичний менеджер вікон ChezWam, заснований на EvilWM +Comment[uz]=EvilWM asosida yaratilgan juda oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=EvilWM асосида яратилган жуда оддий ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ ChezWam, một trình quản lý cửa sổ đơn giản dựa trên EvilWM +Comment[wa]=Li Manaedjeu di Purneas di ChezWam (ChezWam Window Manager). On manaedjeu di purneas tot simpe, båzé so EvilWM +Comment[zh_CN]=ChezWam 窗口管理器,基于 EvilWM 的最小化窗口管理器 +Comment[zh_TW]=The ChezWam 視窗管理程式,基於 EvilWM 的小型化視窗管理程式 diff --git a/tdm/kfrontend/sessions/enlightenment.desktop b/tdm/kfrontend/sessions/enlightenment.desktop new file mode 100644 index 000000000..66dcdd574 --- /dev/null +++ b/tdm/kfrontend/sessions/enlightenment.desktop @@ -0,0 +1,86 @@ +[Desktop Entry] +Type=XSession +Exec=enlightenment_start +TryExec=enlightenment +Name=Enlightenment +Name[bn]=এনলাইটেনমেন্ট +Name[cy]=Goleuni (Enlightenment) +Name[eo]=Lumaĵo +Name[fa]=روشن‌فکری +Name[hi]=एनलाइटनमेंट +Name[km]=ភ្លឺ +Name[mn]=Гэгээрэл +Name[ne]=बुद्धत्व +Name[pa]=ਗਿਆਨ +Name[rw]=Imurika +Name[ta]=விளக்கிக்கூறுதல் +Name[te]=జ్ఞానొదయం +Comment=An extremely themable very feature-rich window manager +Comment[af]='n Uitbreibare, tema geaktiveerde venster bestuurder +Comment[ar]=مدير نوافذ غني بالمزايا وقابل لاستخدام السّمات بشكل كبير. +Comment[be]=Абсалютна змяняльны, багаты на здольнасці кіраўнік вокнаў +Comment[bn]=প্রচুর বৈশিষ্ট্য সম্বলিত একটি উইণ্ডো ম্যানেজার, যা বহুভাবে নিজের পছন্দমত বদলে নেওয়া যায় +Comment[bs]=Izuzetno prilagodljiv window manager bogat opcijama +Comment[ca]=Un gestor de finestres extremadament temible molt ric en característiques +Comment[cs]=Na funkce bohatý správce oken s širokou škálou témat +Comment[csb]=Bògati w fùnkcëje menedżer òknów ò wiôldżich mòżnotach zjinaczi wëzdrzatkù +Comment[cy]=Trefnydd ffenestri sy'n llawn o nodweddion, efo llawer o themau. +Comment[da]=En ekstremt tema-fleksibel egenskabsrig vindueshåndtering +Comment[de]=Sehr design- und funktionsreicher Fenstermanager +Comment[el]=Ένας εξαιρετικά παραμετροποιήσιμος και πλούσιος σε χαρακτηριστικά διαχειριστής παραθύρων +Comment[eo]=Fenestroadministrilo kun tre multaj eblecoj +Comment[es]=Un gestor de ventanas lleno de características y extremadamente personalizable +Comment[et]=Äärmiselt paljude teemade ja väga laialdaste võimalustega aknahaldur +Comment[eu]=Gaitasun ugari dituen, eta zeharo pertsonalizagarria den leiho kudeatzailea +Comment[fa]=مدیر پنجره با ویژگی زیاد و شدیداً موضوعی +Comment[fi]=Erittäin muokattavissa oleva ominaisuusrikas ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres avec beaucoup de thèmes et de fonctionnalités +Comment[fy]=In tige rike en ynstelbere finstersmanager +Comment[gl]=Un xestor de fiestras moi configurábel en apariencia e rico en características +Comment[he]=מנהל חלונות פונקציונלי המכיל אפשרויות רבות להגדרת ערכות נושא +Comment[hi]=एक विंडो प्रबंधक जो अत्यंत प्रसंग युक्त तथा विशेषता से भरपूर है +Comment[hr]=Izuzetno prilagodljiv upravitelj prozora, bogat mogućnostima +Comment[hu]=Egy nagyon sokoldalúan témázható, sok lehetőséget biztosító ablakkezelő +Comment[is]=Afskaplega öflugur gluggastjóri með góðum þemastuðningi +Comment[it]=Un window manager estremamente temabile con molte funzionalità +Comment[ja]=詳細な部分までもテーマ化が可能な非常に多機能のウィンドウマネージャ +Comment[ka]=მრავალფუნქციური ფანჯრის მენეჯერი თემების მხარდაჭერით +Comment[kk]=Қасиеттер жағынан бай, көп тақырыпты терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​មាន​លក្ខណៈ​ពិសេស​សម្បូរ​បែប ដែល​អាច​ប្ដូរ​រូបរាង​បាន​តាម​ចិត្ត +Comment[ko]=다양한 곳을 꾸밀 수 있는 기능이 풍부한 창 관리자 +Comment[lt]=Daug temų ir savybių turinti langų tvarkyklė +Comment[lv]=Tēmām un iespējām bagāts logu menedžeris +Comment[mk]=Менаџер на прозорци богат со можности и екстремно подложен на стилизирање со теми +Comment[mn]=Маш ирээдүйтэй цонхны удирдагч +Comment[ms]=Pengurus tetingkap kaya ciri yang amat boleh tema +Comment[mt]=Window manager rikk u b'ħafna effetti viżwali. +Comment[nb]=En svært omfattende vindusbehandler som kan tilpasses med temaer +Comment[nds]=En Finsterpleger mit bannig vele Funkschonen un Mustern +Comment[ne]=अत्याधिक विषयवस्तु योग्य धेरै आकृति सञ्झ्याल प्रबन्धक +Comment[nl]=Een zeer rijke en configureerbare windowmanager +Comment[nn]=Ein svært omfattande vindaugssjef som kan tilpassast med tema +Comment[pa]=ਇੱਕ ਸਰੂਪ ਦੇ ਪੂਰੇ ਫੀਚਰਾਂ ਨਾਲ ਭਰਪੂਰ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Bogaty w funkcje menedżer okien o dużych możliwościach zmiany wyglądu +Comment[pt]=Um gestor de janelas muito rico em funcionalidades e extremamente personalizado na sua aparência +Comment[pt_BR]=Um gerenciador de janelas rico em recursos e extremamente configurável através de temas +Comment[ro]=Un manager de ferestre extrem de versatil și cu multe facilități +Comment[ru]=Многофункциональный, поддерживающий темы оконный менеджер +Comment[rw]=Mugenga Dirishya biranga-bikize cyane ngirwa-nsanganyamatsiko mu buryo burenze +Comment[se]=Lášegieđahalli mas leat erenoamáš ollu doaimmat ja maid sáhttá heivehit fáttáin +Comment[sk]=Správca okien s veľkým množstvom funkcií a extrémnou podporou tém +Comment[sl]=Okenski upravitelj, zelo prilagodljiv in poln možnosti +Comment[sr]=Изузетно прилагодљив менаџер прозора са пуно могућности +Comment[sr@Latn]=Izuzetno prilagodljiv menadžer prozora sa puno mogućnosti +Comment[sv]=En ytterst anpassningsbar mycket funktionsrik fönsterhanterare +Comment[ta]=நிறைய தன்மைகள் அடங்கிய சாளர மேளாளர் +Comment[tg]=Мудири равзанаҳо дорои мавзӯъҳои гуногун ва дигар бисёр функсияҳо +Comment[th]=ระบบจัดการหน้าต่างที่เต็มไปด้วยความสามารถ และใช้ชุดตกแต่งมากมาย +Comment[tr]=İleri derecede temalanabilir, özellik zengini bir masaüstü yöneticisi +Comment[tt]=Küpçaralı tışlanulı täräzä-idäräçe +Comment[uk]=Менеджер вікон з потужною підтримкою тем та різноманітних функцій +Comment[uz]=Mavzu va imkoniyatlarga juda boy oyna boshqaruvchi +Comment[uz@cyrillic]=Мавзу ва имкониятларга жуда бой ойна бошқарувчи +Comment[vi]=Một trình quản lý cửa sổ cực kỳ dễ thay đổi sắc thái với nhiều tích năng +Comment[wa]=On manaedjeu di purneas foirt bén po-z eployî des tinmes et foirt ritche en usteyes +Comment[zh_CN]=强主题化的多功能窗口管理器 +Comment[zh_TW]=一個功能相當豐富的視窗管理程式 diff --git a/tdm/kfrontend/sessions/evilwm.desktop b/tdm/kfrontend/sessions/evilwm.desktop new file mode 100644 index 000000000..3c8c4f657 --- /dev/null +++ b/tdm/kfrontend/sessions/evilwm.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Type=XSession +Exec=evilwm +TryExec=evilwm +Name=EvilWM +Name[eo]=MalbonaFA +Name[hi]=एविलडबल्यूएम +Name[sv]=Ond WM +Name[te]=ఈవిల్ డబ్ల్యు ఎం +Comment=A minimalist window manager based on AEWM +Comment[af]='n Minimalistiese venster bestuurder wat op AEWM gebaseer is +Comment[ar]=مدير نوافذ مصغّر مبني على AEWM +Comment[be]=Кіраўнік вокнаў для мінімаліста, заснаваны на AEWM +Comment[bn]=AEWM ভিত্তিক একটি পরিমিত উইণ্ডো ম্যানেজার +Comment[bs]=Minimalistički window manager baziran na AEWM +Comment[ca]=Un gestor de finestres minimalista basat en AEWM +Comment[cs]=Minimalistický správce oken založený na AEWM +Comment[csb]=Prosti menedżer òknów ùsôdzony na spòdlém AEWM +Comment[cy]=Trefnydd ffenestri lleiafol wedi'i seilio ar AEM +Comment[da]=En minimalistisk vindueshåndtering baseret på AEWM +Comment[de]=Minimalistischer Fenstermanager, der auf AEWM basiert +Comment[el]=Ένας μινιμαλιστικός διαχειριστής παραθύρων βασισμένος στον AEWM +Comment[eo]=Minimumema fenestroadministrilo +Comment[es]=Un administrado de ventanas minimalista basado en AEWM +Comment[et]=Vähenõudlik aknahaldur, mille aluseks on AEWM +Comment[eu]=AEWMn oinarritutako leiho kudeatzaile minimalista +Comment[fa]=یک مدیر پنجرۀ کمینه براساس AEWM +Comment[fi]=Minimalistinen, AEWM:ään pohjautuva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres fondé sur AEWM +Comment[fy]=In minimalistyske finstersmanager basearre op AEWM +Comment[gl]=Un xestor de fiestras minimalista baseado en AEWM +Comment[he]=מנהל חלונות מינימליסטי המבוסס על AEWM +Comment[hi]= एक अल्पतम विंडो प्रबंधक एईडबल्यूएम पर आधारित +Comment[hr]=Minimalistički upravitelj prozora zasnovan na AEWM-u +Comment[hu]=Egy nagyon egyszerű ablakkezelő az AEWM alapján +Comment[is]=Lágmarks gluggastjóri sem er byggður á AEWM +Comment[it]=Un window manager minimalista basato su AEWM +Comment[ja]=AEWM ベースの小さなウィンドウマネージャ +Comment[ka]=მინიმალისტური ფანჯრის მენეჯერი AEWM-ის ბაზაზე +Comment[kk]=AEWM-негіздеген шағын терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​លក្ខណៈ​ពិសេស​តិច ដែល​ផ្អែក​លើ AEWM +Comment[ko]=AEWM 기반 창 관리자 +Comment[lt]=Minimalistinė langų tvarkyklė, paremta AEWM +Comment[lv]=Minimālistisks logu menedžeris bāzēts uz AEWM +Comment[mk]=Минималистички менаџер на прозорци базиран на AEWM +Comment[mn]=AEWM дээр суурилсан цонхны удирдагч +Comment[mt]=Window manager minimu ibbażat fuq AEWM +Comment[nb]=En minimalistisk vindusbehandler basert på AEWM +Comment[nds]=En minimalistischen Finsterpleger, de op AEWM opbuut +Comment[ne]=AEWM आधारित मिनिमलिस्ट सञ्झ्याल प्रबन्धक +Comment[nl]=Een minimalistische windowmanager gebaseerd op AEWM +Comment[nn]=Ein minimalistisk vindaugssjef som byggjer på AEWM +Comment[pa]=AEWM ਤੇ ਆਧਾਰਿਤ ਨਿਊਨਤਮ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Prosty menedżer okien stworzony na podstawie AEWM +Comment[pt]=Um gestor de janelas minimalista baseado no AEWM +Comment[pt_BR]=Um gerenciador de janelas minimalista baseado no AEWM +Comment[ro]=Un manager de ferestre minimalistic bazat pe AEWM +Comment[ru]=Минимальный оконный менеджер, основанный на AEWM +Comment[rw]=Mugenga dirishya igira-nto ishingiye kuri AEWM +Comment[se]=Minimalisttalaš lásegieđahalli, ráhkaduvvon AEWM vuođul +Comment[sk]=Minimálny správca okien založený na AEWM +Comment[sl]=Minimalističen okenski upravitelj na osnovi AEWM +Comment[sr]=Минималистички менаџер прозора заснован на AEWM-у +Comment[sr@Latn]=Minimalistički menadžer prozora zasnovan na AEWM-u +Comment[sv]=Minimalistisk fönsterhanterare baserad på AEWM +Comment[ta]=AEWM அடிப்படையிலான குறைதபட்ச சாளர மேளாளர் +Comment[tg]=Мудири равзанаҳои хурд дар асоси AEWM +Comment[th]=ระบบจัดการหน้าต่างขนาดเล็ก สร้างจากพื้นฐานของ AEWM +Comment[tr]=AEWM tabanlı küçük bir pencere yöneticisi +Comment[tt]=AEWM asılında ciñel täräcä-idäräçe +Comment[uk]=Мінімалістичний менеджер вікон, заснований на AEWM +Comment[uz]=AEWM asosida yaratilgan juda oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=AEWM асосида яратилган жуда оддий ойна бошқарувчи +Comment[vi]=Một trình quản lý cửa sổ đơn giản dựa trên AEWM +Comment[wa]=On manaedjeu di purneas minimå båzé so AEWM +Comment[zh_CN]=基于 AEWM 的最小化窗口管理器 +Comment[zh_TW]=一個基於 AEWM 的小型化視窗管理程式 diff --git a/tdm/kfrontend/sessions/fluxbox.desktop b/tdm/kfrontend/sessions/fluxbox.desktop new file mode 100644 index 000000000..df6a0813c --- /dev/null +++ b/tdm/kfrontend/sessions/fluxbox.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=XSession +Exec=startfluxbox +TryExec=startfluxbox +Name=Fluxbox +Name[bn]=ফ্লাক্সবক্স +Name[cy]=Llif-flwch (Fluxbox) +Name[eo]=Fluujo +Name[hi]=फ्ल्क्स-बाक्स +Name[ne]=फ्लक्सबक्स +Name[pa]=ਫਕਸਬਕਸ +Name[rw]=AgasandukuUmujyoumwe +Name[ta]=ப்ளக்ஸ் பெட்டி +Name[te]=ఫ్లక్స్ బాక్స్ +Name[tg]=Қуттии Flux +Comment=A highly configurable and low resource window manager based on Blackbox +Comment[af]='n Baie konfigureerbare en lae hulpbron intensiewe venster bestuurder, wat op Blackbox gebaseer is. +Comment[ar]=مدير نوافذ قابل للإعداد بشكل كبير ويستخدم القليل من موارد الجهاز وهو مبني Blackbox +Comment[be]=Кіраўнік вокнаў, заснаваны на Blackbox, з вялікімі здольнасцямі змяняцца і з нізкай патрабавальнасцю да рэсурсаў +Comment[bn]=ব্ল্যাকবক্স ভিত্তিক একটি উইণ্ডো ম্যানেজার, যা নানাভাবে কনফিগার করা যায়, কিন্তু খুবই কম রিসোর্স ব্যবহার করে +Comment[bs]=Visoko prilagodljiv window manager sa malim zauzećem resursa baziran na Blackbox-u +Comment[ca]=Un gestor de finestres altament configurable i que necessita pocs recursos basat en Blackbox +Comment[cs]=Vysoce přizpůsobitelný a nízkoúrovňový správce oken založený na Blackboxu +Comment[csb]=Menedżer òknów òpiarti na Blackbox ò wiôldżich mòżnotach kònfigùracëji ë nisczich żądaniach +Comment[cy]=Trefnydd ffenestri hawdd ei ffurfweddu ac ysgafn ei ddefnydd adnoddau, wedi'i seilio ar Ddu-flwch (Blackbox) +Comment[da]=En meget indstillelig vindueshåndtering med lavt ressourceforbrug baseret på Blackbox +Comment[de]=Sehr flexibler, aber ressourcenschonender Fenstermanager, der auf Blackbox basiert +Comment[el]=Ένας ιδιαίτερα παραμετροποιήσιμος και με μικρή κατανάλωση πόρων διαχειριστής παραθύρων βασισμένος στον Blackbox +Comment[eo]=Fenestroadministrilo devenigita de Negrujo +Comment[es]=Un gestor de ventanas basado en Blackbox muy configurable y con poco consumo de recursos +Comment[et]=Väga hästi kohandatav ja vähenõudlik aknahaldur, mille aluseks on Blackbox +Comment[eu]=Blackbox-en oinarritutako leiho kudeatzaile zeharo konfiguragarria, eta errekurtso gutxi kontsumitzen dituena +Comment[fa]=یک مدیر پنجره با قابلیت پیکربندی بالا و منبع پایین براساس Blackbox +Comment[fi]=Blackboxiin pohjautuva erittäin muokattava ja vähäisen resurssitarpeen omaava ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres très configurable et utilisant peu de ressources, fondé sur Blackbox +Comment[fy]=In tige ynstelbere lichtgewicht finstersmanager basearre op Blackbox +Comment[gl]=Un xestor de fiestras moi configurábel e lixeiro baseado en Blackbox +Comment[he]=מנהל חלונות בעל הגדרות רבות הצורך משאבים מעטים ומבוסס עלBlackbox +Comment[hi]=ब्लेक-बाक्स आधारित, अत्यंत कॉन्फ़िगरेबल तथा कम साधन चाहने वाला विंडो प्रबंधक +Comment[hr]=Visoko konfigurabilan upravitelj prozora, male potrošnje resursa, zasnovan na Blackbox-u +Comment[hu]=Egy Blackbox-alapú ablakkezelő, alacsony erőforrásigénnyel, sokféle beállítási lehetőséggel +Comment[is]=Öflugur gluggastjóri sem notar lítið af auðlindum vélarinnar sem er byggður á Blackbox +Comment[it]= Un window manager molto configurabile e che utilizza poche risorse basato su Blackbox +Comment[ja]=Blackbox ベースの高度な設定が可能でリソースにやさしいウィンドウマネージャ +Comment[ka]=კონფიგურირებადი ფანჯრის მენეჯერი Blackbox -ის ბაზაზე +Comment[kk]=Blackbox-негіздеген, баптаулары көп, үнемді терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​អាច​កំណត់​រចនាសម្ព័ន្ធ​បាន​ខ្ពស់ និង​ប្រើ​ធនធាន​តិច ដែល​ផ្អែក​លើ Blackbox +Comment[ko]=Blackbox 기반의 다양하게 설정 가능하고 자원을 적게 사용하는 창 관리자 +Comment[lt]=Daug konfigūravimo parinkčių turinti ir mažai resursų naudojanti langų tvarkyklė, paremta Blackbox +Comment[lv]=Plaši konfigurējams un resursus taupošs logu menedžeris bāzēts uz Blackbox +Comment[mk]=Високо конфигурабилен менаџер на прозорци со мали побарувања на ресурси базиран на Blackbox +Comment[mn]=Хар хайрцаг дээр суурилсан маш бага нөөц хэрэглэдэг тохируулах чадвар өндөр цонхны удирдагч +Comment[mt]=Window manager ħafif u konfigurabbli ibbażat fuq BlackBox +Comment[nb]=En lite ressurskrevende og svært fleksibel vindusbehandler basert på Blackbox +Comment[nds]=En Finsterpleger, de wenig Ressourcen bruukt, man bannig vele Instellen hett. Opbuut op Blackbox +Comment[ne]=कालो बाकसमा आधारित उच्च कन्फिगरयोग्य र न्यून संसाधन सञ्झ्याल प्रबन्धक +Comment[nl]=Een zeer configureerbare lichtgewicht windowmanager gebaseerd op Blackbox. +Comment[nn]=Ein lite ressurskrevjande og svært fleksibel vindaugssjef basert på Blackbox +Comment[pa]=ਇੱਕ ਬਿਲਕੁੱਲ ਹਲਕਾ ਤੇ ਜਿਆਦਾ ਸੋਧਯੋਗ ਫਾਇਲ਼ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien oparty na Blackbox o dużych możliwościach konfiguracji i niskich wymaganiach +Comment[pt]=Um gestor de janelas bastante configurável e que usa poucos recursos, baseado no Blackbox +Comment[pt_BR]=Um gerenciador de janelas altamente configurável e com baixo uso de recursos, baseado no Blackbox +Comment[ro]=Un manager de ferestre foarte configurabil și mic, bazat pe Blackbox +Comment[ru]=Настраиваемый оконный менеджер, основанный на Blackbox +Comment[rw]=Mugenga dirishya mbonezwa mu buryo buhanitse kandi bikorana bike ishingiye ku Gasandukumukara +Comment[se]=Lásegieđahalli vuođđoduvvon Blackbox:as, hui heivehahtti ja geavaha unnán resurssaid +Comment[sk]=Veľmi konfigurovateľný a nenáročný správca okien založený na Blackbox +Comment[sl]=Visoko nastavljiv in učinkovit okenski upravitelj na osnovi Blackboxa +Comment[sr]=Врло подесив и незахтеван менаџер прозора заснован на Blackbox-у +Comment[sr@Latn]=Vrlo podesiv i nezahtevan menadžer prozora zasnovan na Blackbox-u +Comment[sv]=Mycket anpassningsbar fönsterhanterare med litet resursbehov baserad på Blackbox +Comment[ta]=கறுப்புபெட்டி சார்ந்த அமைக்கக்கூடிய குறைந்த வள சாளர மேளாளர் +Comment[tg]=Мудири равзанаҳои танзимшаванда дар асоси Blackbox +Comment[th]=ระบบจัดการหน้าต่างที่สามารถปรับแต่งได้อย่างละ เอียด และใช้ทรัพยากรน้อย สร้างบนพื้นฐานของ Blackbox +Comment[tr]=Blackbox temelli, kolayca özelleştirilebilir düşük kaynaklı bir pencere yöneticisi +Comment[tt]=Blackbox asılında qorılğan, yaqşı caylana torğan täräcä-idäräçe +Comment[uk]=Дуже гнучкий та невибагливий для ресурсів менеджер вікон, заснований на Blackbox +Comment[vi]=Một trình quản lý cửa sổ rất dễ cấu hình và đòi hỏi ít tài nguyên dựa trên Blackbox +Comment[wa]=On ledjir et foirt apontiåve manaedjeu di purneas båzé so Blackbox +Comment[zh_CN]=基于 BlackBox 可深入配置且占用资源较少的窗口管理器 +Comment[zh_TW]=一個基於 Blackbox 且高可組態及低資源的視窗管理程式 diff --git a/tdm/kfrontend/sessions/flwm.desktop b/tdm/kfrontend/sessions/flwm.desktop new file mode 100644 index 000000000..d6dc24010 --- /dev/null +++ b/tdm/kfrontend/sessions/flwm.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Type=XSession +Exec=flwm +TryExec=flwm +Name=FLWM +Name[eo]=RMFA +Name[hi]=एफएलडबल्यूएम +Name[te]=ఎఫ్ ఎల్ డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง FLWM +Comment=The Fast Light Window Manager, based primarily on WM2 +Comment[af]=Die Vinnige, ligte venster bestuurder, wat op WM2 gebaseer is +Comment[ar]=مدير النوافذ السريع الخفيف، مبني بشكل أساسي على WM2 +Comment[be]=The Fast Light Window Manager, заснаваны на WM2 +Comment[bn]=ফাস্ট লাইট উইণ্ডো ম্যানেজার, WM2 ভিত্তি করে তৈরি +Comment[bs]=Fast Light Window Manager, baziran uglavnom na WM2 +Comment[ca]=El gestor de finestres Fast Light, primerament basat en WM2 +Comment[cs]=Fast Light Window Manager založený původně na WM2 +Comment[csb]=Fast Light Window Manager, menedżer òknów ùsôdzony przédno na WM2 +Comment[cy]=Y Trefnydd Ffenestri Chwim ac Ysgafn, wedi'i seilio ar WM2 am y rhan fwyaf +Comment[da]=Fast Light vindueshåndtering, baseret først og fremmest på WM2 +Comment[de]=Der Fast Light Window Manager, der vor allem auf WM2 basiert +Comment[el]=Ο Fast Light διαχειριστής παραθύρων, βασισμένος κυρίως στον WM2 +Comment[eo]=Rapida malpeza fenestroadministrilo +Comment[es]=El Fast Light Window Manager, basado principalmente en WM2 +Comment[et]=Kiire ja vähenõudlik aknahaldur, aluseks peamiselt WM2 +Comment[eu]=Batez ere WM2-en oinarritutako leiho kudeatzaile arin eta bizkorra +Comment[fa]=مدیر پنجرۀ سریع و سبک، در اصل بر اساس WM2 +Comment[fi]=Fast Light Window Manager. Pohjautuu suurimmaksi osin WM2:een +Comment[fr]=The Fast Light Window Manager, fondé au départ sur WM2 +Comment[fy]=De Fast Light Window Manager, primêr basearre op WM2 +Comment[gl]=O Fast Light Window Manager, un xestor de fiestras lixeiro baseado en WM2 +Comment[he]=The Fast Light Window Manager, מבוסס בעיקר על WM2 +Comment[hi]=मुख्यतः डबल्यूएम2 पर आधारित तेज और हल्का विंडो प्रबंधक +Comment[hr]=Brzi i lagani upravitelj prozora (FLWM), zasnovan na WM2 +Comment[hu]=Fast Light Window Manager ablakkezelő, elsősorban a WM2 alapján +Comment[is]=Léttur og hraðvirkur gluggastjóri sem er aðallega byggður á WM2 +Comment[it]=Il Fast Light Window Manager, basato principalmente su WM2 +Comment[ja]="高速で軽い"WM2 ベースのウィンドウマネージャ +Comment[ka]=სწრაფი და მსუბუქი ფანჯრების მენეჯერი WM2 -ის ბაზაზე +Comment[kk]=WM2-негіздеген жеңіл және жедел терезе менеджері +Comment[km]=Fast Light Window Manager ផ្អែក​ចម្បង​លើ WM2 +Comment[ko]=WM2에 기반을 둔 빠르고 가벼운 창 관리자 +Comment[lt]=Greita ir lengva langų tvarkyklė, paremta daugiausiai WM2 +Comment[lv]=Fast Light logu menedžeris, bāzēts galvenokārt uz WM2 +Comment[mk]=Fast Light Window Manager, менаџер примарно базиран на WM2 +Comment[mn]=Ерөнхийдөө WM2 дээр суурилсан хурдан хөнгөн цонхны удирдагч +Comment[mt]=Fast Light Window Manager, ibbażat fuq WM2 +Comment[nb]=En rask, lett vindusbehandler (Fast Light Window Manager), mest basert på WM2 +Comment[nds]=De "Fast Light"-Finsterpleger, to'n gröttsten Deel opbuut op WM2 +Comment[ne]=साधारणतया WM2 मा आधारित छिटो हल्का सञ्झ्याल प्रबन्धक +Comment[nl]=De Fast Light Window Manager, primair gebaseerd op WM2. +Comment[nn]=Ein rask, lett vindaugssjef (Fast Light Window Manager), mest basert på WM2 +Comment[pa]=ਇੱਕ ਹਲਕਾ ਤੇਜ਼ ਫਾਇਲ਼ ਮੈਨੇਜਰ, ਜੋ ਕਿ WM2 ਤੇ ਆਧਾਰਿਤ ਹੈ +Comment[pl]=Fast Light Window Manager, menedżer okien stworzony głownie na podstawie WM2 +Comment[pt]=O Fast Light Window Manager, baseado em primeiro lugar no WM2 +Comment[pt_BR]=Acrônimo para Fast Light Window Manager (gerenciador rápido e leve), baseado primeiramente no WM2 +Comment[ro]=Fast Light Window Manager, bazat în principal pe WM2 +Comment[ru]=Быстрый и лёгкий оконный менеджер, основанный на WM2 +Comment[rw]=Mugenga Dirishya Yihuta Yoroshye, ishingiye mbere na mbere kuri WM2 +Comment[se]=Jođánis, geahpes lásegieđahalli, ráhkaduvvon WM2 vuođul +Comment[sk]=The Fast Light Window Manager založený na WM2 +Comment[sl]=Fast Light Window Manager, v glavnem na osnovi WM2 +Comment[sr]=Брзи лаки менаџер прозора (FLWM), заснован на WM2 +Comment[sr@Latn]=Brzi laki menadžer prozora (FLWM), zasnovan na WM2 +Comment[sv]=Fönsterhanteraren Fast Light Window Manager, i huvudsak baserad på WM2 +Comment[ta]=WM2 அடிப்படையிலான வேக ஒளி வேக சாளர மேளாளர் +Comment[tg]=мудири равзанаҳои тез ва осон дар асоси WM2 +Comment[th]=ระบบจัดการหน้าต่างที่เร็วและเบา สร้างบนพื้นฐานของ WM2 +Comment[tr]=Fast Light Pencere Yöneticisi +Comment[tt]=WM2 asılında qorılğan, citez ciñel täräcä-idäräçe +Comment[uk]=Швидкий легкий менеджер вікон, заснований здебільшого на WM2 +Comment[uz]=Asosan WM2 asosida yaratilgan tez va oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=Асосан WM2 асосида яратилган тез ва оддий ойна бошқарувчи +Comment[vi]=Trình Quản lý Cửa sổ Nhanh và Nhẹ, dựa chủ yếu vào WM2 +Comment[wa]=Li Roed et Ledjir Manaedjeu di Purneas (ast Light Window Manager) båzé so WM2 +Comment[zh_CN]=又快又轻巧的窗口管理器,主要基于 WM2 +Comment[zh_TW]=一個主要基於 WM2 且快速及輕量化的視窗管理程式 diff --git a/tdm/kfrontend/sessions/fvwm.desktop b/tdm/kfrontend/sessions/fvwm.desktop new file mode 100644 index 000000000..20ae57d4c --- /dev/null +++ b/tdm/kfrontend/sessions/fvwm.desktop @@ -0,0 +1,71 @@ +[Desktop Entry] +Type=XSession +Exec=fvwm +TryExec=fvwm +Name=FVWM +Name[hi]=एफ़वीडबल्यूएम +Name[te]=ఎఫ్ వి డబ్ల్యు ఎం +Comment=A powerful ICCCM-compliant multiple virtual desktop window manager +Comment[af]='n Kragtige, ICCCM-aanpasbare veelvuldige virtuele werkskermvenster bestuurder. +Comment[ar]=مدير نوافذ قوي ومتوافق مع ICCCM ذي أسطح مكتب وهمية متعددة +Comment[be]=Магутны ICCCM-сумяшчальны кіраўнік вокнаў з падтрымкай віртуальных працоўных сталоў +Comment[bn]= একটি শক্তিশালী ICCCM-compliant উইণ্ডো ম্যানেজার, যাতে একাধিক ভার্চুয়াল ডেস্কটপ সম্ভব +Comment[bs]=Moćan ICCCM-sukladan window manager sa podrškom za više virtuelnih desktopa +Comment[ca]=Un poderós gestor de finestres per a múltiples escriptoris virtuals que compleix amb ICCCM +Comment[csb]=Stolemny menedżer òknów zgòdny z ICCCM òbsłëgòwujący wirtualné pùltë +Comment[cy]=Trefnydd ffenestri pwerus efo penbyrddau rhith lluosol, sy'n cydymffurfio â ICCCM +Comment[da]=En kraftig ICCCM-kompliant vindueshåndtering med flere virtuelle desktoppe +Comment[de]=Ein leistungsfähiger ICCCM-kompatibler Fenstermanager mit virtuellen Arbeitsflächen +Comment[el]=Ένας πολύ δυνατός, συμβατός με το ICCCM, διαχειριστής παραθύρων με πολλαπλές εικονικές επιφάνειες εργασίας +Comment[eo]=Fenestroadministrilo +Comment[es]=Un potente gestor de ventanas, compatible con ICCCM y que soporta varios escritorios virtuales +Comment[et]=Võimas ICCCM nõuetele vastav mitme virtuaalse töölauaga aknahaldur +Comment[eu]=ICCCM konpatiblea den, eta mahaigain birtual ugari dituen leiho kudeatzaile bortitza +Comment[fa]=یک مدیر پنجرۀ رومیزی مجازی چندگانه ICCCM-compliant نیرومند +Comment[fi]=Tehokas ICCCM-mukautuva virtuaalityöpöytiä tukeva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres puissant compatible ICCCM avec gestion de bureaux virtuels multiples +Comment[fy]=In krêftige ICCCM-compliant finstersmanager mei meardere buroblêden +Comment[gl]=Un xestor de fiestras potente acorde coa ICCCM con múltiplos escritórios virtuais +Comment[he]=מנהל חלונות עצמתי עם תאימות ל־ICCCM בעל שולחנות עבודה וירטואליים רבים +Comment[hi]=शक्तिशाली आईसीसीसीएम-कम्पलाएंट अनेक आभासी डेस्कटॉप विंडो प्रबंधक +Comment[hr]=Comment=Moćni, ICCCM kompatibilan, upravitelj prozora s više virtualnih radnih površina +Comment[hu]=Egy sokoldalú, ICCCM-kompatibilis ablakkezelő, virtuális munkaasztal-kezeléssel +Comment[is]=Öflugur ICCCM samhæfður gluggastjóri með sýndarskjáborðum +Comment[it]=Un window manager molto potente e ICCCM-compatibile che supporta i desktop virtuali +Comment[ja]=複数の仮想デスクトップをサポートした ICCCM 準拠のパワフルなウィンドウマネージャ +Comment[ka]=ძლიერი ICCCM-თავსებადი ვირტულური სამუშაო დაფების მხარდამჭერი ფანჯრის მენეჯერი +Comment[kk]=Қуатты ICCCM-үйлесімді, көп виртуалды үстел қолдайтын терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ផ្ទៃតុ​និមិត្ត​ច្រើន​ដ៏​មាន​អានុភាព ដែល​អនុវត្ត​តាម ICCCM +Comment[ko]=다중 가상 데스크톱을 사용하는 ICCCM 호환 창 관리자 +Comment[lt]=galinga, su ICCCM suderinama daugelio virtualių darbastalių langų tvarkyklė +Comment[lv]=Spēcīgs ICCCM-savietojams logu menedžeris ar vairāku darbvirsmu atbalstu +Comment[mk]=Моќен менаџер на прозорци со повеќе виртуелни површини во согласност со ICCCM +Comment[mt]=Window manager b'saħħtu, konformi ma' ICCCM, b'desktops virtwali. +Comment[nb]=En slagkraftig vindusbehandler med flere virtuelle skrivebord, som støtter ICCCM +Comment[nds]=En kraftvulle, ICCCM-kompatible Finsterpleger mit vele virtuelle Schriefdischen +Comment[ne]=शक्तिशाली ICCCM-मान्ने बहुविध अवास्तविक डेस्कटप सञ्झ्याल प्रबन्धक +Comment[nl]=Een krachtige ICCCM-compliant windowmanager met meerdere bureaubladen +Comment[nn]=Ein slagkraftig vindaugssjef med fleire virtuelle skrivebord, som støttar ICCCM +Comment[pa]=ਇੱਕ ਸ਼ਕਤੀਸ਼ਾਲੀ ICCCM-ਅਨੁਕੂਲ ਬਹੁ-ਫਰਜ਼ੀ ਵੇਹੜਿਆਂ ਵਾਲਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Potężny menedżer okien zgodny z ICCCM obsługujący wirtualne pulpity +Comment[pt]=Um gestor de janelas poderoso em conformidade com o ICCCM e que suporta vários ecrãs virtuais +Comment[pt_BR]=Um poderoso gerenciador de janelas compatível com o ICCM, com suporte a múltiplas áreas de trabalho virtuais +Comment[ro]=Un manager de ferestre puternic compliant ICCCM ce suportă ecrane virtuale +Comment[ru]=Мощный ICCCM-совместимый оконный менеджер, поддерживающий виртуальные рабочие столы +Comment[rw]=igikoranisha-ICCCM nyembaraga mugenga dirishya y'ibiro bitandukanye bitagaragara +Comment[se]=Fápmolaš ICCCM-heivvolaš lásegieđahalli mas lea virtuealla čállinbeavddit +Comment[sk]=Výkonný správca okien kompatibilný s ICCCM s podporou virtuálnych plôch +Comment[sl]=Močan okenski upravitelj z večimi navideznimi namizji in popolnoma v skladu z ICCCM +Comment[sr]=Моћни, ICCCM-сагласни, менаџер прозора са више виртуелних радних површина +Comment[sr@Latn]=Moćni, ICCCM-saglasni, menadžer prozora sa više virtuelnih radnih površina +Comment[sv]=Kraftfull fönsterhanterare med flera virtuella skrivbord som följer ICCCM +Comment[ta]=ICCCM-தரத்தில் பலதரப்பட்ட மெய்நிகர் மேல் மேசை சாளர மேளாளர் +Comment[tg]=Мудири равзанаҳои бузург дар асоси ICCCM дорои мудири равзанаҳо бо мизикориҳои виртуалӣ +Comment[th]=ระบบจัดการหน้าต่างที่มีหลายพื้นที่ทำงานเสมือน สอดรับกับ ICCCM ประสิทธิภาพสูง +Comment[tr]=Güçlü ICCCM-uyumlu çoklu sanal masaüstü yöneticisi +Comment[tt]=ICCCM-ütkän, küp öställär totqan köçle täräzä-idäräçe +Comment[uk]=Потужний, сумісний з ICCCM менеджер вікон, з підтримкою віртуальних стільниць +Comment[vi]=Trình quản lý cửa sổ tương thích với ICCCM nhiều chức năng, quản lý nhiều màn hình nền ảo +Comment[wa]=On manaedjeu di purneas avou multi-forveyowès sicribannes ki rote avou ICCM +Comment[zh_CN]=强大的多虚拟桌面窗口管理器,与 ICCCM 兼容 +Comment[zh_TW]=一個強大的 ICCCM 相容的多重虛擬桌面視窗管理程式 diff --git a/tdm/kfrontend/sessions/fvwm2.desktop b/tdm/kfrontend/sessions/fvwm2.desktop new file mode 100644 index 000000000..1a25a91e4 --- /dev/null +++ b/tdm/kfrontend/sessions/fvwm2.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +Type=XSession +Exec=fvwm2 +TryExec=fvwm2 +Name=FVWM2 +Name[te]=ఎఫ్ వి డబ్ల్యు ఎం 2 +Comment=A powerful ICCCM-compliant multiple virtual desktop window manager +Comment[af]='n Kragtige, ICCCM-aanpasbare veelvuldige virtuele werkskermvenster bestuurder. +Comment[ar]=مدير نوافذ قوي ومتوافق مع ICCCM ذي أسطح مكتب وهمية متعددة +Comment[be]=Магутны ICCCM-сумяшчальны кіраўнік вокнаў з падтрымкай віртуальных працоўных сталоў +Comment[bn]= একটি শক্তিশালী ICCCM-compliant উইণ্ডো ম্যানেজার, যাতে একাধিক ভার্চুয়াল ডেস্কটপ সম্ভব +Comment[bs]=Moćan ICCCM-sukladan window manager sa podrškom za više virtuelnih desktopa +Comment[ca]=Un poderós gestor de finestres per a múltiples escriptoris virtuals que compleix amb ICCCM +Comment[csb]=Stolemny menedżer òknów zgòdny z ICCCM òbsłëgòwujący wirtualné pùltë +Comment[cy]=Trefnydd ffenestri pwerus efo penbyrddau rhith lluosol, sy'n cydymffurfio â ICCCM +Comment[da]=En kraftig ICCCM-kompliant vindueshåndtering med flere virtuelle desktoppe +Comment[de]=Ein leistungsfähiger ICCCM-kompatibler Fenstermanager mit virtuellen Arbeitsflächen +Comment[el]=Ένας πολύ δυνατός, συμβατός με το ICCCM, διαχειριστής παραθύρων με πολλαπλές εικονικές επιφάνειες εργασίας +Comment[eo]=Fenestroadministrilo +Comment[es]=Un potente gestor de ventanas, compatible con ICCCM y que soporta varios escritorios virtuales +Comment[et]=Võimas ICCCM nõuetele vastav mitme virtuaalse töölauaga aknahaldur +Comment[eu]=ICCCM konpatiblea den, eta mahaigain birtual ugari dituen leiho kudeatzaile bortitza +Comment[fa]=یک مدیر پنجرۀ رومیزی مجازی چندگانه ICCCM-compliant نیرومند +Comment[fi]=Tehokas ICCCM-mukautuva virtuaalityöpöytiä tukeva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres puissant compatible ICCCM avec gestion de bureaux virtuels multiples +Comment[fy]=In krêftige ICCCM-compliant finstersmanager mei meardere buroblêden +Comment[gl]=Un xestor de fiestras potente acorde coa ICCCM con múltiplos escritórios virtuais +Comment[he]=מנהל חלונות עצמתי עם תאימות ל־ICCCM בעל שולחנות עבודה וירטואליים רבים +Comment[hi]=शक्तिशाली आईसीसीसीएम-कम्पलाएंट अनेक आभासी डेस्कटॉप विंडो प्रबंधक +Comment[hr]=Comment=Moćni, ICCCM kompatibilan, upravitelj prozora s više virtualnih radnih površina +Comment[hu]=Egy sokoldalú, ICCCM-kompatibilis ablakkezelő, virtuális munkaasztal-kezeléssel +Comment[is]=Öflugur ICCCM samhæfður gluggastjóri með sýndarskjáborðum +Comment[it]=Un window manager molto potente e ICCCM-compatibile che supporta i desktop virtuali +Comment[ja]=複数の仮想デスクトップをサポートした ICCCM 準拠のパワフルなウィンドウマネージャ +Comment[ka]=ძლიერი ICCCM-თავსებადი ვირტულური სამუშაო დაფების მხარდამჭერი ფანჯრის მენეჯერი +Comment[kk]=Қуатты ICCCM-үйлесімді, көп виртуалды үстел қолдайтын терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ផ្ទៃតុ​និមិត្ត​ច្រើន​ដ៏​មាន​អានុភាព ដែល​អនុវត្ត​តាម ICCCM +Comment[ko]=다중 가상 데스크톱을 사용하는 ICCCM 호환 창 관리자 +Comment[lt]=galinga, su ICCCM suderinama daugelio virtualių darbastalių langų tvarkyklė +Comment[lv]=Spēcīgs ICCCM-savietojams logu menedžeris ar vairāku darbvirsmu atbalstu +Comment[mk]=Моќен менаџер на прозорци со повеќе виртуелни површини во согласност со ICCCM +Comment[mt]=Window manager b'saħħtu, konformi ma' ICCCM, b'desktops virtwali. +Comment[nb]=En slagkraftig vindusbehandler med flere virtuelle skrivebord, som støtter ICCCM +Comment[nds]=En kraftvulle, ICCCM-kompatible Finsterpleger mit vele virtuelle Schriefdischen +Comment[ne]=शक्तिशाली ICCCM-मान्ने बहुविध अवास्तविक डेस्कटप सञ्झ्याल प्रबन्धक +Comment[nl]=Een krachtige ICCCM-compliant windowmanager met meerdere bureaubladen +Comment[nn]=Ein slagkraftig vindaugssjef med fleire virtuelle skrivebord, som støttar ICCCM +Comment[pa]=ਇੱਕ ਸ਼ਕਤੀਸ਼ਾਲੀ ICCCM-ਅਨੁਕੂਲ ਬਹੁ-ਫਰਜ਼ੀ ਵੇਹੜਿਆਂ ਵਾਲਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Potężny menedżer okien zgodny z ICCCM obsługujący wirtualne pulpity +Comment[pt]=Um gestor de janelas poderoso em conformidade com o ICCCM e que suporta vários ecrãs virtuais +Comment[pt_BR]=Um poderoso gerenciador de janelas compatível com o ICCM, com suporte a múltiplas áreas de trabalho virtuais +Comment[ro]=Un manager de ferestre puternic compliant ICCCM ce suportă ecrane virtuale +Comment[ru]=Мощный ICCCM-совместимый оконный менеджер, поддерживающий виртуальные рабочие столы +Comment[rw]=igikoranisha-ICCCM nyembaraga mugenga dirishya y'ibiro bitandukanye bitagaragara +Comment[se]=Fápmolaš ICCCM-heivvolaš lásegieđahalli mas lea virtuealla čállinbeavddit +Comment[sk]=Výkonný správca okien kompatibilný s ICCCM s podporou virtuálnych plôch +Comment[sl]=Močan okenski upravitelj z večimi navideznimi namizji in popolnoma v skladu z ICCCM +Comment[sr]=Моћни, ICCCM-сагласни, менаџер прозора са више виртуелних радних површина +Comment[sr@Latn]=Moćni, ICCCM-saglasni, menadžer prozora sa više virtuelnih radnih površina +Comment[sv]=Kraftfull fönsterhanterare med flera virtuella skrivbord som följer ICCCM +Comment[ta]=ICCCM-தரத்தில் பலதரப்பட்ட மெய்நிகர் மேல் மேசை சாளர மேளாளர் +Comment[tg]=Мудири равзанаҳои бузург дар асоси ICCCM дорои мудири равзанаҳо бо мизикориҳои виртуалӣ +Comment[th]=ระบบจัดการหน้าต่างที่มีหลายพื้นที่ทำงานเสมือน สอดรับกับ ICCCM ประสิทธิภาพสูง +Comment[tr]=Güçlü ICCCM-uyumlu çoklu sanal masaüstü yöneticisi +Comment[tt]=ICCCM-ütkän, küp öställär totqan köçle täräzä-idäräçe +Comment[uk]=Потужний, сумісний з ICCCM менеджер вікон, з підтримкою віртуальних стільниць +Comment[vi]=Trình quản lý cửa sổ tương thích với ICCCM nhiều chức năng, quản lý nhiều màn hình nền ảo +Comment[wa]=On manaedjeu di purneas avou multi-forveyowès sicribannes ki rote avou ICCM +Comment[zh_CN]=强大的多虚拟桌面窗口管理器,与 ICCCM 兼容 +Comment[zh_TW]=一個強大的 ICCCM 相容的多重虛擬桌面視窗管理程式 diff --git a/tdm/kfrontend/sessions/fvwm95.desktop b/tdm/kfrontend/sessions/fvwm95.desktop new file mode 100644 index 000000000..2bbd1c403 --- /dev/null +++ b/tdm/kfrontend/sessions/fvwm95.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=XSession +Exec=fvwm95 +TryExec=fvwm95 +Name=FVWM95 +Name[hi]=एफ़वीडबल्यूएम95 +Name[te]=ఎఫ్ వి డబ్ల్యు ఎం 95 +Comment=A Windows 95 look-alike derivative of FVWM +Comment[af]='n FVWM venster bestuurder wat soos Windows 95 lyk +Comment[ar]=شبيه بـWin95 ومشتق من FVWM +Comment[be]=Вытворная ад FVWM, падобная на Windows 95 +Comment[bn]=FVWM-ভিত্তিক Windows 95-এর মত দেখতে একটি উইণ্ডো ম্যানেজার +Comment[bs]=Derivacija FVWM nalik na Windows 95 +Comment[ca]=Un semblant a Win95 derivat de FVWM +Comment[cs]=Správce oken se vzhledem Windows 95 odvozený od FVWM +Comment[csb]=Pòchòdzący z FVWM menedżer òknów ò wëzdrzatkù szlachùjącym za Windows 95 +Comment[cy]=Deilliant o FVWM sy'n edrych yn debyg i Windows95 +Comment[da]=En Windows 95-lignende vindueshåndtering afledt af FVWM +Comment[de]=Ein Abkömmling von FVWM im Stil von Windows 95 +Comment[el]=Ένας παρόμοιος με τα Windows 95 διαχειριστής παραθύρων προερχόμενος από τον FVWM +Comment[eo]=Fenestroadministrilo kiel tiu de Vindozo 95 +Comment[es]=Un derivado de FVWM de aspecto similar a Win95 +Comment[et]=FVWM derivaat, mis näeb välja nagu Windows 95 +Comment[eu]=Windows 95en itxura duen FVWMren ondorengo bat +Comment[fa]=ویندوز ۹۵ شبیه مشتق FVWM +Comment[fi]=Windows 95:lta näyttävä FVWM-johdannainen +Comment[fr]=Un gestionnaire de fenêtres ressemblant à Windows 95 dérivant de FVWM +Comment[fy]=In op Windows 95 lykjende fariant fan FVWM +Comment[gl]=Un xestor de fiestras coma o de Windows 95 derivado de FVWM +Comment[he]=נגזרת של FVWM הנראה כמו חלונות 95 +Comment[hi]=विंडोज़ 95 जैसा दिखने वाला एफ़वीडबल्यूएम का प्रतिरूप +Comment[hr]=Derivat FVWM-a nalik na Windows 95 +Comment[hu]=Win95-szerű FVWM-változat +Comment[is]=Útgáfa af FVWM sem líkist Windows 95 +Comment[it]=Una variante di FVWM che assomiglia a Windows 95 +Comment[ja]=Windows95 に似た外見の FVWM 派生ウィンドウマネージャ +Comment[ka]=FVWM კლონი Windows 95-ის სტილში +Comment[kk]=Windows 95 секілді FVWM-негіздеген терезе менеджері +Comment[km]=ស្រដៀង Windows 95 ដែល​ក្លាយ​មក​ពី FVWM +Comment[ko]=FVWM의 윈도 95를 닮은 변종 +Comment[lt]=Windows 95 išvaizdą primenanti FVWM atmaina +Comment[lv]=Windows 95 līdzīgs FVWM atvasinājums +Comment[mk]=Деривација на FVWM менаџерот со изглед на Windows 95 +Comment[mn]=FVWM -ээс уламжилсан Виндовс 95 шиг харагдалттай +Comment[ms]=Terbitan FVWM yang menyerupai Windows 95 +Comment[mt]=Derivattiv ta' FVWM jixbaħ lil Windows 95 +Comment[nb]=En variant av FVWM som ser ut som Windows 95 +Comment[nds]=Süht ut as A Windows 95 un is vun FVWM afleddt +Comment[ne]=विण्डोज ९५ FVWM को डेरिभेटिभ जस्तो छ +Comment[nl]=Een op Windows 95 lijkende variant van FVWM +Comment[nn]=Ein variant av FVWM som ser ut som Windows 95 +Comment[pa]=ਵਿੰਡੋ 95 ਵਰਗਾ FVWM ਦਾ ਇੱਕ ਰੂਪ +Comment[pl]=Wywodzący się z FVWM menedżer okien o wyglądzie podobnym do Windows 95 +Comment[pt]=Uma derivação do FVWM parecida com o Windows 95 +Comment[pt_BR]=Um derivado do FVWM com a aparência do Windows 95 +Comment[ro]=O versiune de FVWM cu aspect de Windows 95 +Comment[ru]=Клон FVWM в стиле Windows 95 +Comment[rw]=Windows 95 isa nk'ikomoka kuri FVWM +Comment[se]=FVWM-vuođđoduvvon lásegieđahalli mii lea Windows 95-lágan +Comment[sk]=Správca okien podobný Windows 95 založený na FVWM +Comment[sl]=Izpeljanka FVWM v izgledu Windows 95 +Comment[sr]=Дериват FVWM-а налик на Windows 95 +Comment[sr@Latn]=Derivat FVWM-a nalik na Windows 95 +Comment[sv]=Fönsterhanterare som liknar Windows 95 med ursprung i FVWM +Comment[ta]=FVWM லிருந்து தோன்றிய விண்டோஸ் 95 ஐப் போன்ற +Comment[tg]=Windows 95 look-монанди маҳсулии FVWM +Comment[th]=FVWM ที่ถูกทำให้ดูเหมือนวินโดวส์ 95 +Comment[tr]=Windows 95'e benzeyen bir pencere yönetimi +Comment[tt]=Windows 95 küreneşendä FVWM qabatlama +Comment[uk]=Похідний від FVWM з виглядом Windows 95 +Comment[uz]=Win95'ga oʻxshagan FVWM'ning turi +Comment[uz@cyrillic]=Win95'га ўхшаган FVWM'нинг тури +Comment[vi]=Trình quản lý cửa sổ giống Windows 95, hậu duệ của FVWM +Comment[wa]=On manaedjeu di purneas rishonnant a Windows 95 et k' est båzé so FVWM +Comment[zh_CN]=一个与 Windows 95 外观类似的 FVWM 变种 +Comment[zh_TW]=一個由 FVWM 演化出來且外觀像 Win95 的視窗管理程式 diff --git a/tdm/kfrontend/sessions/gnome.desktop b/tdm/kfrontend/sessions/gnome.desktop new file mode 100644 index 000000000..ed89391ec --- /dev/null +++ b/tdm/kfrontend/sessions/gnome.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=XSession +Exec=gnome-session +TryExec=gnome-session +Name=GNOME +Name[bn]=গনোম +Name[eo]=Gnomikuo +Name[hi]=ग्नोम +Name[ko]=세임 그놈 +Name[mn]=ГНОМЕ +Name[ne]=जिनोम +Name[sv]=Gnome +Name[ta]=க்னோம் +Name[te]=గ్నొమ్ +Comment=The GNU Network Object Model Environment. A complete, free and easy-to-use desktop environment +Comment[af]=Die GNU 'Network Object Model Environment'. 'n Volledige, gratis en maklik om te gebruik werkskerm omgewing. +Comment[ar]=بيئة نموذج الكائن الشبكي من GNU، بيئة سطح مكتبي حرّة وسهلة الاستخدام +Comment[be]=The GNU Network Object Model Environment. Поўнае, свабоднае і простае ў выкарыстанні працоўнае асяроддзе +Comment[bn]=দি গনিউ নেটওয়ার্ক অবজেক্টমডেল এনভায়রনমেন্ট। একটি পূর্ণ, মুক্ত এবং সহজেই ব্যবহারযোগ্য ডেস্কটপ এনভায়রনমেন্ট +Comment[bs]=GNU Network Object Model Environment. Kompletna, slobodna i jednostavna za upotrebu desktop okolina +Comment[ca]=El GNU Network Object Model Environment. Un complet, lliure i fàcil d'usar entorn d'escriptori +Comment[cs]=GNOME, GNU Network Object Model Environment. Kompletní, svobodné a uživatelsky přívětivé garfické prostředí. +Comment[csb]=GNU Network Object Model Environment (GNOME). Fùlwôrtné, wòlné ë prosté w brëkòwaniô òkrãżé pùltu +Comment[cy]=Yr Amgylchedd Model Gwrthrych Rhwydwaith GNU (GNU Network Object Model Environment). Amgylchedd penbwrdd cyflawn, rhydd, a hawdd ei ddefnyddio. +Comment[da]=GNU Network Object Model Environment. Et fuldstænding, frit og nemt at bruge desktopmiljø +Comment[de]=Das GNU Network Object Model Environment. Eine vollständige, freie und leicht bedienbare Arbeitsumgebung +Comment[el]=Το GNU Network Object Model Environment. Ένα πλήρης, ελεύθερο και εύκολο στη χρήση περιβάλλον επιφάνειας εργασίας +Comment[eo]=Plena labortabla ĉirkaŭaĵo +Comment[es]=El GNU Network Object Model Environment, un entorno de escritorio completo, libre y fácil de usar +Comment[et]=GNU Network Object Model Environment on täielik, vaba ja väga hõlpsasti kasutatav töölaua keskkond +Comment[eu]=GNU Network Object Model Environment. mahaigain-ingurune oso, libre eta erabilterraza +Comment[fa]=محیط مدل شئ شبکه گنو. محیط رومیزی کامل، آزاد و آسان برای استفاده. +Comment[fi]=GNU Network Object Model Environment. Valmis, vapaa ja helppokäyttöinen työpöytäympäristö +Comment[fr]=The GNU Network Object Model Environment. Un environnement de bureau complet, gratuit et facile à utiliser +Comment[fy]=De GNU Network Object Model Environment, In komplete, frije en ienfâldige te brûken buroblêd omwrâld +Comment[gl]=O GNU Network Object Model Environment. Un entorno de escritório completo, libre e de uso doado +Comment[he]=The GNU Network Object Model Environment. סביבת עבודה מלאה, חופשית וקלה לשימוש +Comment[hi]=जीएनयू नेटवर्क ऑब्जेक्ट मॉडल एनवायरनमेंट. एक संपूर्ण, उपयोग में आसान डेस्कटॉप वातावरण +Comment[hr]=GNOME - GNU Network Object Model Environment - Cjelokupno, besplatno i jednostavno okruženje radne površine +Comment[hu]=GNU Network Object Model Environment (GNOME), egy teljes, ingyenes, könnyen kezelhető grafikus környezet +Comment[is]=GNU Network Object Model Environment er fullkomið og fjrálst skjáborðsumhverfi sem er auðvelt að nota +Comment[it]=Il GNU Network Object Model Environment. Un ambiente desktop completo, libero e facile da usare +Comment[ja]=GNU オブジェクトモデル環境, 完全にフリーで使いやすいデスクトップ環境 +Comment[ka]=GNU Network Object Model Environment - სრული, თავისუფალი და ადვილად გამოყენებადი სამუშაო გარემო +Comment[kk]=GNU Network Object Model Environment. Толық, еркін таратылатын, ыңғайлы графикалық орта +Comment[km]=GNU Network Object Model Environment ។ បរិស្ថាន​ផ្ទៃតុ​ពេញលេញ, ឥត​គិត​ថ្លៃ និង​ងាយស្រួល​ប្រើ +Comment[ko]=GNU Network Object Model Environment(그놈). 완전한 자유 소프트웨어 데스크톱 환경입니다. +Comment[lt]=GNU tinklo objektų modeliavimo aplinka. Savarankiška, laisva ir lengvai naudojama darbastalio aplinka +Comment[lv]=GNU Network Object Model Environment. Pilnvērtīga bezmaksas viegli lietojama darba vide. +Comment[mk]=GNU Network Object Model Environment. Работна околина која е комплетна, слободна и едноставна за користење +Comment[mn]=GNU Network Object Model Environment. Бүрэн, үнэгүй хэрэглэхэд хялбар дэлгэцийн системийн орчин +Comment[mt]=GNU Network Object Model Environment. Ambjent grafiku komplet, ħieles u faċli tużah. +Comment[nb]=GNU Network Object Model Environment. Et skrivebordsmiljø som er komplett, fritt og lett å bruke. +Comment[nds]=De "GNU Network Object Model Environment". En komplette Schriefdisch-Ümgeven, ümsunst un eenfach to bruken +Comment[ne]=GNU सञ्जाल बस्तु नमूना वातावरण । पूर्ण, स्वतन्त्र र प्रयोग गर्न सजिलो डेस्कटप वातावरण +Comment[nl]=De GNU Network Object Model Environment, een complete, vrije en eenvoudig te gebruiken desktop environment. +Comment[nn]=GNU Network Object Model Environment. Eit skrivebordsmiljø som er komplett, fritt og lett å bruka. +Comment[pa]=GNU Network Object Model Environment, ਇੱਕ ਸੰਪੂਰਨ, ਮੁਫਤ ਅਤ ਵਰਤਣ ਵਿੱਚ ਅਤਿ ਆਸਾਨ ਵੇਹੜਾ ਵਾਤਾਵਰਣ +Comment[pl]=GNU Network Object Model Environment (GNOME). Pełne, wolne i łatwe w użyciu środowisko pulpitu +Comment[pt]=O GNU Network Object Model Environment. Um ambiente de trabalho completo, livre e fácil de usar +Comment[pt_BR]=Acrônimo para GNU Network Object Model Environment ou Ambiente de Modelo de Objetos de Rede GNU; um ambiente de trabalho completo, livre e fácil de usar +Comment[ro]=GNU Network Object Model Environment. Un mediu grafic complet, gratuit și ușor de utilizat +Comment[ru]=GNU Network Object Model Environment - полная, свободная и лёгкая в использовании графическая среда +Comment[rw]=Ibikikije Moderi Igikoresho Urusobemiyoboro GNU. Ibikikije by'ibiro byuzuye, by'ubuntu kandi byoroshye-gukoresha. +Comment[se]=GNU Netword Object Model Environment: Čállinbeavdebiras mii lea aibbas fridja ja álki geavahit. +Comment[sk]=The GNU Network Object Model Environment. Úplné, voľne šíriteľné a ľahko použiteľné pracovné prostredie +Comment[sl]=GNU Network Object Model Environment. Popolno, prosto in preposto namizno okolje +Comment[sr]=„GNU Network Object Model Environment“(Gnome, Гном). Потпуно, бесплатно и лако за коришћење радно окружење +Comment[sr@Latn]=„GNU Network Object Model Environment“(Gnome, Gnom). Potpuno, besplatno i lako za korišćenje radno okruženje +Comment[sv]=GNU Network Object Model Environment. En fullständig, fri och lättanvänd skrivbordsmiljö +Comment[ta]=GNU மாதிரி வலை பொருள் சூழல்.முழுமையான , இலவச சுலபமாக பயன்படுத்தக்கூடிய மேல்மேசை சூழல் +Comment[th]=GNU Network Object Model Environment สภาพแวดล้อมสำหรับเดสก์ทอปที่ครบถ้วน, ฟรี และใช้งานง่าย +Comment[tr]=GNU Network Object Model Environment (GNOME) +Comment[tt]=The GNU Network Object Model Environment. Qullanu öçen ciñel, buşlay, tulıçaralı östäl möxite +Comment[uk]=The GNU Network Object Model Environment. Повнофункціональне, вільне та зручне графічне середовище +Comment[uz]=GNOME (GNU Network Object Model Environment) - mukammal, erkin va foydalanish uchun juda qulay ish stoli muhiti +Comment[uz@cyrillic]=GNOME (GNU Network Object Model Environment) - мукаммал, эркин ва фойдаланиш учун жуда қулай иш столи муҳити +Comment[vi]=Môi trường Mạng Mô hình Đối tượng của GNU. Một môi trường màn hình nền đầy đủ, tự do và dễ sử dụng +Comment[wa]=L' evironmint di modele di cayets d' rantoele GNU (GNU Network Object Model Environment). On complet evironmint d' sicribanne, libe et åjhey a -z eployî. +Comment[zh_CN]=GNU 网络对象模型环境。完整、自由、易用的桌面环境 +Comment[zh_TW]=GNU 網路物件模型環境。一個完整,免費且容易使用的桌面環境 diff --git a/tdm/kfrontend/sessions/golem.desktop b/tdm/kfrontend/sessions/golem.desktop new file mode 100644 index 000000000..3ba7f2b41 --- /dev/null +++ b/tdm/kfrontend/sessions/golem.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=XSession +Exec=golem +TryExec=golem +Name=Golem +Name[bn]=গোলেম +Name[eo]=Golemo +Name[hi]=गोलेम +Name[ne]=गोलेम +Name[pa]=ਗੋਲੀਮ +Name[te]=గొలెం +Comment=A lightweight window manager +Comment[af]='n Lig gewig venster bestuurder +Comment[ar]=مدير نوافر خفيف العبء +Comment[be]=Лёгкі кіраўнік вокнаў +Comment[bn]=একটি হাল্কা উইণ্ডো ম্যানেজার +Comment[bs]=Lagani window manager +Comment[ca]=Un lleuger gestor de finestres KDE +Comment[cs]=Malý správce oken +Comment[csb]=Menedżer òknół ò môłëch żądaniach +Comment[cy]=Trefnydd ffenestri ysgafn +Comment[da]=En letvægtsvindueshåndtering +Comment[de]=Eine schlanker Fenstermanager +Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων +Comment[eo]=Malpeza fenestroadministrilo +Comment[es]=Un gestor de ventanas ligero +Comment[et]=Imeväike aknahaldur +Comment[eu]=Leiho kudeatzaile arina +Comment[fa]=یک مدیر پنجرۀ سبک +Comment[fi]=Kevyt ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres très léger +Comment[fy]=In lichtgewicht finstersmanager +Comment[gl]=Un xestor de fiestras lixeiro +Comment[he]=מנהל החלונות קל משקל +Comment[hi]=एक हल्का विंडो प्रबंधक +Comment[hr]=Lagani upravitelj prozora +Comment[hu]=Egy nagyon egyszerű ablakkezelő +Comment[is]=Léttur gluggastjóri +Comment[it]=Un window manager leggero +Comment[ja]=軽量なウィンドウマネージャ +Comment[ka]=მსუბუქი ფანჯრი მენეჯერი +Comment[kk]=Жеңіл терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​សមត្ថភាព​ខ្សោយ +Comment[ko]=가벼운 창 관리자 +Comment[lt]=Nedaug resursų eikvojanti langų tvarkyklė +Comment[lv]=Viegls logu menedžeris +Comment[mk]=Лесен менаџер на прозорци +Comment[mn]=Хөнгөн цонхны удирдагч +Comment[ms]=Pengurus tetingkap ringan +Comment[mt]=Window manager ħafif +Comment[nb]=En lettvekts vindusbehandler +Comment[nds]=En ranke Finsterpleger +Comment[ne]=हल्का वजन सञ्झ्याल प्रबन्धक +Comment[nl]=Een lichtgewicht windowmanager +Comment[nn]=Ein lett vindaugssjef +Comment[pa]=ਇੱਕ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien o małych wymaganiach +Comment[pt]=Um gestor de janelas leve +Comment[pt_BR]=Um gerenciador de janelas leve +Comment[ro]=Un manager de ferestre foarte mic +Comment[ru]=Лёгкий оконный менеджер +Comment[rw]=Mugenga dirishya yoroshye +Comment[se]=Geahpes lásegieđahalli +Comment[sk]=Nenáročný správca okien +Comment[sl]=Lahek okenski upravitelj +Comment[sr]=Лагани менаџер прозора +Comment[sr@Latn]=Lagani menadžer prozora +Comment[sv]=Lättviktig fönsterhanterare +Comment[ta]=குறைவான எடை உடைய சாளர மேலாளர் +Comment[te]=తెలికైన విండొ అభికర్త +Comment[tg]=Мудири тирезаи сабук +Comment[th]=ระบบจัดการหน้าต่างขนาดเบา +Comment[tr]=Hızlı çalışan bir pencere yöneticisi +Comment[tt]=Ciñel täräzä-idäräçe +Comment[uk]=Швидкий менеджер вікон +Comment[uz]=Oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=Оддий ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ nhẹ ký +Comment[wa]=On ledjir manaedjeu di purneas +Comment[zh_CN]=轻量级窗口管理器 +Comment[zh_TW]=一個輕量化的視窗管理程式 diff --git a/tdm/kfrontend/sessions/icewm.desktop b/tdm/kfrontend/sessions/icewm.desktop new file mode 100644 index 000000000..8b70361fa --- /dev/null +++ b/tdm/kfrontend/sessions/icewm.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=XSession +Exec=icewm-session +TryExec=icewm-session +Name=IceWM +Name[eo]=GlaciFA +Name[hi]=आइस-डबल्यूएम +Name[lo]=ຕົວຈັດການຫນ້າຕ່າງ IceWM +Name[sv]=Ice WM +Name[te]=ఐస్ డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง IceWM +Comment=A Windows 95-OS/2-Motif-like window manager +Comment[af]='n Windows 95-OS/2-Motif tipe venster bestuurder +Comment[ar]=مدير نوافذ مشابه لـ Win95-OS/2-Motif +Comment[be]=Кіраўнік вокнаў, падобны на Windows 95-OS/2-Motif +Comment[bn]=Windows 95-OS/2-Motif-এর অনুরূপ একটি উইণ্ডো ম্যানেজার +Comment[bs]=Window manager nalik na Windows 95-OS/2-Motif +Comment[ca]=Un gestor de finestres com els de Windows 95-OS/2-Motif +Comment[cs]=Správce oken podobný Windows 95-OS/2-Motif +Comment[csb]=Menedżer òknół szlachùjący za Windows 95-OS/2-Motif +Comment[cy]=Trefnydd ffenestri sy'n debyg i Windows95-OS/2-Motif +Comment[da]=En Windows 95-OS/2-Motif-lignende vindueshåndtering +Comment[de]=Fenstermanager im Stil von Windows 95, OS/2 und Motif +Comment[el]=Ένας διαχειριστής παραθύρων παρόμοιος με τα Windows 95-OS/2-Motif +Comment[eo]=Fenestroadministrilo kiel Vindozo 95, OS/2 kaj Motifo +Comment[es]=Un gestor de ventanas similar a Win95-OS/2-Motif +Comment[et]=Aknahaldur, mis näeb välja nagu Windows 95-OS/2-Motif +Comment[eu]=Windows 95 OS/2 Motif-en itxura duen leiho kudeatzailea +Comment[fa]=یک مدیر پنجره شبیه Windows 95-OS/2-Motif +Comment[fi]=Windows 95:n ja OS/2-Motifin tyylinen ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres ressemblant à Windows 95-OS/2-Motif +Comment[fy]=In Win95-OS/2-Motif-likens finstersmanager +Comment[gl]=Un xestor de fiestras coma o de Windows 95-OS/2-Motif +Comment[he]=מנהל חלונות מבוסס Motif הדומה במראהו לחלונות 95/OS-2 +Comment[hi]=विंडोज़ 95-ओएस/2-मोटिफ जैसा विंडो प्रबंधक +Comment[hr]=Upravitelj prozora nalik na Windows 95/OS/2/Motif +Comment[hu]=Win95-OS/2-Motif-szerű ablakkezelő +Comment[is]=Gluggastjóri sem líkist 95-OS/2-Motif +Comment[it]=Un window manager in stile Windows 95-OS/2-Motif +Comment[ja]=Windows95, OS/2, Motif に似たウィンドウマネージャ +Comment[ka]=ფანჯრების მენეჯერი Windows95-OS/2-Motif სტილში +Comment[kk]=Windows 95-OS/2-Motif-секілді терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​ដូច Windows 95-OS/2-Motif +Comment[ko]=윈도 95, OS/2, Motif를 닮은 창 관리자 +Comment[lt]=A Windows 95-OS/2-Motif-primenanti langų tvarkyklė +Comment[lv]=Windows 95 - OS/2 - Motif līdzīgs logu menedžeris +Comment[mk]=Менаџер на прозорци со изглед на Windows 95, OS/2 и Motif +Comment[mn]=Виндовс 95-OS/2-Motif-шиг цонхны удирдагч +Comment[ms]=Pengurus tetingkap seperti Motif Windows 95-OS/2 +Comment[mt]=Window manager jixbaħ lill-Windows 95-OS/2-Motif +Comment[nb]=En vindusbehandler som likner Windows 95-OS/2-Motif +Comment[nds]=Finsterpleger, de utsüht as Windows 95-OS/2-Motif +Comment[ne]=विण्डोज ९५-OS/2-मोटिफ जस्तो सञ्झ्याल प्रबन्धक +Comment[nl]=Een Win95-OS/2-Motif-achtige windowmanager +Comment[nn]=Ein vindaugssjef som liknar Windows 95-OS/2-Motif +Comment[pa]=ਇੱਕ ਵਿੰਡੋ 95-OS/2-Motif-ਵਰਗਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien podobny do Windows 95-OS/2-Motif +Comment[pt]=Um gestor de janelas parecido com o Windows 95, o OS/2 e o Motif +Comment[pt_BR]=Um gerenciador de janelas parecido com Windows 95-OS/2-Motif +Comment[ro]=Un manager de ferestre cu aspect de Windows 95, OS/2 sau Motif +Comment[ru]=Оконный менеджер в стиле Windows95-OS/2-Motif +Comment[rw]=Windows 95-OS/2-umutako-nka mugenga dirishya +Comment[se]=Windows 95-OS/2-Motif-lágan lásegieđahalli +Comment[sk]=Správca okien podobný Windows 95-OS/2-Motif +Comment[sl]=Okenski upravitelj, podoben Windows 95, OS/2 in Motifu +Comment[sr]=Менаџер прозора налик на Windows 95/OS/2/Motif +Comment[sr@Latn]=Menadžer prozora nalik na Windows 95/OS/2/Motif +Comment[sv]=Fönsterhanterare som liknar Windows 95-OS/2-Motif +Comment[ta]=சாளரங்கள் 95-OS/2-மாடிஃப்-லைக் சாளர மேலாளர் +Comment[te]=విండొస్ 95-ఒఎస్/2 -మొటిఫ్ లాంటి విండొ అభికర్త +Comment[tg]=Windows 95-OS/2-Motif-монанди мудири тиреза +Comment[th]=ระบบจัดการหน้าต่างของที่ดูคล้าย วินโดวส์ 95-โอเอสทู-โมทิฟ +Comment[tr]=Windows 95-OS/2-Motif benzeri bir pencere yöneticisi +Comment[tt]=Windows 95-OS/2-Motif küreneşendä täräzä-idäräçe +Comment[uk]=Менеджер вікон на кшталт Windows 95-OS/2-Motif +Comment[uz]=Win95-OS/2-Motif'ga oʻxshash oyna boshqaruvchi +Comment[uz@cyrillic]=Win95-OS/2-Motif'га ўхшаш ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ với mô típ kiểu Windows 95 +Comment[wa]=On manaedjeu di purneas rishonnant Windows95-OS/2-Motif +Comment[zh_CN]=类似 Windows-OS/2-Motif 的窗口管理器 +Comment[zh_TW]=一個像 Win95-OS/2-Motif 的視窗管理程式 diff --git a/tdm/kfrontend/sessions/ion.desktop b/tdm/kfrontend/sessions/ion.desktop new file mode 100644 index 000000000..c4ae9ca04 --- /dev/null +++ b/tdm/kfrontend/sessions/ion.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Type=XSession +Exec=ion +TryExec=ion +Name=Ion +Name[bn]=আয়ন (Ion) +Name[eo]=Iono +Name[hi]=आयन +Name[ja]=ION +Name[ko]=카메룬 +Name[pa]=ਲੋਨ +Name[te]=ఐయాన్ +Name[th]=ไอออน +Comment=A keyboard-friendly window manager with tiled windows, based on PWM +Comment[af]='n Sleutelbord vriendelike venster bestuurder, met geteëlde vensters. Dis op PWM gebaseer. +Comment[ar]=مدير نوافذ سهل استخدام لوحة المفاتيح ذي نوافذ معنونة، مبني على PWM +Comment[be]=Кіраўнік вокнаў для працы з клавіятурай, заснаваны на PWM +Comment[bn]=PWM ভিত্তিক উইণ্ডো ম্যানেজার, যা কীবোর্ড দিয়ে নিয়ন্ত্রণ করা সহজ +Comment[bs]=Window manager za tastaturu sa popločanim prozorima, baziran na PWM +Comment[ca]=Un gestor de finestres amigable amb el teclat i amb finestres alicatades, basat en PWM +Comment[csb]=Menedżer òknów z dobrą òbsłëgą klawiaturë ë kachelkòwaniém òknów, ùsôdzony na spòdlém PWM +Comment[cy]=Trefnydd ffenestri sy'n hawdd ei ddefnyddio o'r alweddell, efo ffenestri wedi'u teilio, wedi'i seilio ar PVM +Comment[da]=En tastaturvenlig vindueshåndtering med fliselagte vinduer, baseret på PWM +Comment[de]=Tastaturfreundlicher Fenstermanager mit gekachelten Fenstern, basiert auf PWM +Comment[el]=Ένας φιλικός με το πληκτρολόγιο διαχειριστής παραθύρων με υποστήριξη παραθύρων σε παράθεση, βασισμένος στον PWM +Comment[eo]=Fenestroadministrilo por la uzo klaviara +Comment[es]=Un gestor de ventanas utilizable desde el teclado con mosaico de ventanas, basado en PWM +Comment[et]=Klaviatuurisõprade aknahaldur paanitud akendega, aluseks PWM +Comment[eu]=PWMn oinarritutako leiho-mosaikoa duen leiho kudeatzailea, teklatutik erabil daitekeena +Comment[fa]=یک مدیر پنجرۀ صفحه کلید پسند با پنجره‌های کاشی‌شده، براساس PWM +Comment[fi]=Näppäimistöystävällinen ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres utilisable au clavier avec des fenêtres en mosaïque, fondé sur PWM +Comment[fy]=In toetseboerdfreonlike finstersmanager mei tegele finsters. basearre op PWM +Comment[gl]=Un xestor de fiestras de manexo co teclado e fiestras en mosaico baseado en PWM +Comment[he]=מנהל חלונות ידידותי למקלדת עם חלונות פרושים המבוסס על PWM +Comment[hi]=पीडबल्यूएम आधारित चटाई विंडो युक्त विंडो प्रबंधक जो कुंजीपट फ्रेडली है +Comment[hr]=Comment=Upravitelj prozora s popločenim prozorima, namijenjen tipkovnici i zasnovan na PWM-u +Comment[hu]=Egy billentyűzetről könnyen kezelhető ablakkezelő, mozaikszerű ablakelrendezéssel, a PWM alapján +Comment[is]=Gluggastjóri sem er gott að vinna í með lyklaborðinu einu, byggður á PWM +Comment[it]=Un window manager "amico della tastiera" con finestre affiancate, basato su PWM +Comment[ja]=PWM ベースのキーボード操作に適したタイル表示式のウィンドウマネージャ +Comment[ka]=კლავიატურით მართვადი ფანჯრების მენეჯერი, PWM-ის ბაზაზე +Comment[kk]=PWM-негіздеген, пернетақтадан басқарылатын, терезелері кезектескен, терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​ងាយ​ប្រើ​ជាមួយ​ក្ដារចុច ហើយ​អាច​រៀប​បង្អួច​ជា​ក្បឿង និង​ផ្អែក​លើ PWM +Comment[lt]=Patogi dirbti su klaviatūra langų tvarkyklė su išklotais langais, paremta PWM +Comment[lv]=Tastatūrai draudzīgs logu menedžeris ar tiled logiem, bāzēts uz PWM +Comment[mk]=Менаџер на прозорци со поплочени прозорци базиран на PWM погоден за работа со тастатура +Comment[mn]=PWM дээр суурилсан гараар ажиллахад тохиромжтой цонх удирдагч +Comment[ms]=Pengurus tetingkap mesra papan kekunci dengan tetingkap berjubin, berdasarkan PWM +Comment[mt]=Window manager ibbażat fuq PWM, b'sapport għal tastieri u windows imqassma fuiq madum +Comment[nb]=En tastaturvennlig vindusbehandler med flislagte vinduer, basert på PWM +Comment[nds]=En tastatuurfründliche Finsterpleger mit kachelte Finstern, opbuut op PWM +Comment[ne]=शीर्षक सञ्झ्यालसँग सोझो सञ्झ्याल प्रबन्धक कुञ्जीपाटी +Comment[nl]=Een toetsenbordvriendelijke windowmanager met getegelde vensters. Gebaseerd op PWM +Comment[nn]=Ein tastaturvennleg vindaugssjef med flislagde vindauge, basert på PWM +Comment[pa]=ਇੱਕ ਕੀ-ਬੋਰਡ ਸਹਾਇਕ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਜੋ ਕਿ PWM ਤੇ ਆਧਾਰਿਤ ਹੈ +Comment[pl]=Menedżer okien z dobrą obsługą klawiatury i kafelkowaniem okiem, stworzony na podstawie PWM +Comment[pt]=Um gestor de janelas amigável para o teclado, com janelas lado-a-lado, baseado no PWM +Comment[pt_BR]=Um gerenciador de janelas amigável com o teclado, com janelas ladrilhadas, baseado no PWM +Comment[ro]=Un manager de ferestre ușor de utilizat din tastatură, cu ferestre ce pot fi așezate în mozaic, bazat pe PWM +Comment[ru]=Управляемый с клавиатуры оконный менежер, основанный на PWM +Comment[rw]=mugenga dirishya ya mwandikisho-yoroshyeikoresha ifite amadirishya agerekeranye, ishingiye kuri PWM +Comment[se]=Boallobeavdeustitlaš lašegieđahalli, mas leat bálddalas láset, ráhkaduvvon PWM vuođul +Comment[sk]=Správca okien s podporou kláves, usporiadania okien do dlaždíc, založený na PWM +Comment[sl]=Tipkovnici prijazen okenski upravitelj z razdeljenimi okni, na osnovi PWM +Comment[sr]=Пријатељски према тастатури менаџер прозора са наслаганим прозорима, заснован на PWM-у +Comment[sr@Latn]=Prijateljski prema tastaturi menadžer prozora sa naslaganim prozorima, zasnovan na PWM-u +Comment[sv]=Tangentbordsvänlig fönsterhanterare med fönster sida vid sida, baserad på PWM +Comment[ta]=PWM அடிப்படையிலான விசைப்பலகையால் கையாளமுடிந்த சாளர மேளாளர் +Comment[th]=ระบบจัดการหน้าต่างที่เป็นมิตรกับการใช้แป้นพิมพ์ พร้อมกับหน้าต่างที่ถูกปูเรียง สร้างจาก PWM +Comment[tr]=PWM tabanlı, klavye dostu uzatılmış pencereleriyle bir pencere yönetici +Comment[tt]=Täräzä bülü belän töylek-söygän täräzä-idäräçe, PWM asılında +Comment[uk]=Менеджер вікон налаштований для легкого використання з клавіатурою, засновано на PWM +Comment[vi]=Trình quản lý cửa sổ thiết kết thân thiện với việc dùng bàn phím, có các cửa sổ xếp ngói, dựa trên PWM +Comment[wa]=On manaedjeu di purneas k' inme li taprece avou des purneas å pus grand, båzé so PWM +Comment[zh_CN]=一个基于 PWM 的窗口管理器,适合键盘操作,可平铺窗口 +Comment[zh_TW]=一個基於 PWM 且方便鍵盤使用和支援棋盤化視窗的視窗管理程式 diff --git a/tdm/kfrontend/sessions/larswm.desktop b/tdm/kfrontend/sessions/larswm.desktop new file mode 100644 index 000000000..072b382c5 --- /dev/null +++ b/tdm/kfrontend/sessions/larswm.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=XSession +Exec=larswm +TryExec=larswm +Name=LarsWM +Name[eo]=Lazero +Name[hi]=लार्स-डबल्यूएम +Name[ko]=라이코스 +Name[sv]=Lars WM +Name[te]=లార్స్ డబ్ల్యు ఎం +Comment=The Lars Window Manager, based on 9WM, supports tiled windows +Comment[af]=Die Lars venster bestuurder, wat op 9WM gebaseer is. Dit ondersteun geteëlde vensters. +Comment[ar]=مدير نوافذ لارس، مبني على 9WM، يدعم النوافذ المعنونة +Comment[be]=Кіраўнік вокнаў Lars Window Manager, заснаваны на 9WM +Comment[bn]=লার্স উইণ্ডো ম্যানেজার, 9WM-এর ওপর ভিত্তি করে তৈরি +Comment[bs]=Lars Window Manager, baziran 9WM, podržava popločane prozore +Comment[ca]=El gestor de finestres Lars, basat en 9WM, permet finestres alicatades +Comment[csb]=Menedżer òknów Larsa, ùsôdzony na spòdlém 9WM, wspiérô kachelkòwanié òknów +Comment[cy]=Y Trefnydd Ffenestri Lars, wedi'i seilio ar 9WM, sy'n cynnal ffenestri wedi'u teilio +Comment[da]=Lars vindueshåndteringen, baseret på 9WM, understøtter fliselagte vinduer +Comment[de]=Lars-Fenstermanager, basiert auf 9WM und unterstützt gekachelte Fenstern +Comment[el]=Ο διαχειριστής παραθύρων Lars, βασισμένος στον 9WM, υποστηρίζει παράθυρα σε παράθεση +Comment[eo]=La Laza Fenestroadministrilo, devenigita de 9FA +Comment[es]=El Lars Window Manager, basado en 9WM, soporta mosaico de ventanas +Comment[et]=Larsi aknahaldur, mille aluseks on 9WM, toetab paanitud aknaid +Comment[eu]=Lars leiho kudeatzailea, 9WM-n oinarritua, leiho-mosaikorako euskarria duena +Comment[fa]=مدیر پنجرۀ Lars، بر اساس 9WM، پنجره‌های کاشی‌شده را پشتیبانی می‌کند. +Comment[fi]=Lars-ikkunaohjelma. Pohjautuu 9WM:ään ja tukee järjestettyjä ikkunoita +Comment[fr]=The Lars Window Manager, fondé sur 9WM, avec une gestion des fenêtres en mosaïque +Comment[fy]=De Lars Window Manager, basearre op 9WM. Biedt stipe foar tegele finsters +Comment[gl]=O Xestor de Fiestras Lars, baseado en 9WM, atura fiestras en mosaico +Comment[he]=The Lars Window Manager, מבוסס על 9WM, תומך בחלונות פרושים +Comment[hi]=9डबल्यूएम आधारित लार्स विंडो प्रबंधक, चटाई विडो समर्थित करता है +Comment[hr]=Lars upravitelj prozora, zasnovan na 9WMu, podržava popločene prozore +Comment[hu]=Lars ablakkezelője, a 9WM alapján, mozaikszerű ablakelrendezési lehetőséggel +Comment[is]=Lars gluggastjórinn, byggður á 9WM og styður flísaða glugga +Comment[it]=Il Window Manager di Lars, basato su 9WM, supporta le finestre affiancate +Comment[ja]=Lars ウィンドウマネージャ, 9WMベース, タイル表示をサポートするウィンドウマネージャ +Comment[kk]=9WM-негіздеген терезе менеджері +Comment[km]=Lars Window Manager ផ្អែក​លើ 9WM គាំទ្រ​បង្អួច​ជា​ក្បឿង +Comment[lt]=Lars langų tvarkyklė, paremta 9WM, turi galimybę iškloti langus +Comment[mk]=Lars Window Manager, менаџер базиран на 9WM, поддржува поплочени прозорци +Comment[mn]=The Lars Window Manager, 9WM дээр суурилсан, олон цонхтой +Comment[ms]=Pengurus Tetingkap Lars, berdasarkan 9WM, menyokong tetingkap berjubin +Comment[mt]=Lars Window Manager - ibbażat fuq 9WM u jiflaħ windows imqassma f'madum +Comment[nb]=Lars vindusbehandler, basert på 9WM, støtter flislagte vinduer +Comment[nds]=De Lars-Finsterpleger, opbuut op 9WM, ünnerstütt kachelte Finstern +Comment[ne]=9WM मा आधारित लार्स सञ्झ्याल प्रबन्धक, टायल गरिएका सञ्झ्यालहरू समर्थन गर्छ +Comment[nl]=De Lars Window Manager, gebaseerd op 9WM. Biedt ondersteuning voor getegelde vensters +Comment[nn]=Vindaugssjefen Lars, basert på 9WM, støttar flislagde vindauge +Comment[pa]=ਲਾਰਸ ਫਾਇਲ਼ ਮੈਨੇਜਰ 9WM ਤੇ ਆਧਾਰਿਤ, ਝਰੋਖਿਆਂ ਦੇ ਸਮੇਟਣ ਲਈ ਸਹਾਈ +Comment[pl]=Menedżer okien Larsa, stworzony na podstawie 9WM, obsługuje kafelkowanie okien +Comment[pt]=O Lars Window Manager, baseado no 9WM, e que suporta janelas lado-a-lado +Comment[pt_BR]=O gerenciador de janelas Lars, baseado no 9WM, com suporte a janelas ladrilhadas +Comment[ro]=Managerul de ferestre al lui Lars, bazat pe 9WM. Suportă ferestre aranjate în mozaic +Comment[ru]=Оконный менеджер на основе 9wm +Comment[rw]=Mugenga Dirishya Lars, ishingiye kuri 9WM, yemera amadirishya agerekeranye +Comment[se]=Lásegieđahalli Lars, ráhkaduvvon 9WM vuođul, doarju bálddalas lásiid. +Comment[sk]=The Lars Window Manager založený na 9WM s podporou okien usporiadaných do dlaždíc +Comment[sl]=Larsov okenski upravitelj, na osnovi 9WM, podpira porazdeljena okna +Comment[sr]=„Lars Window Manager“, заснован на 9WM-у, подржава наслагане прозоре +Comment[sr@Latn]=„Lars Window Manager“, zasnovan na 9WM-u, podržava naslagane prozore +Comment[sv]=Lars fönsterhanterare, baserad på 9WM, med stöd för fönster sida vid sida +Comment[ta]=9WM அடிபடையிலான லார்ஸ் சாளர மேலாளர் சீரமைக்கப்பட்ட சாளரங்களை ஆதரிக்கிறது +Comment[th]=ระบบจัดการหน้าต่าง Lars สร้างจาก 9WM สนับสนุนการปูเรียงหน้าต่าง +Comment[tr]=Lars Pencere Yöneticisi +Comment[tt]=Lars Window Manager, 9WM asılında, bülengän täräzä tota +Comment[uk]=The Lars Window Manager, засновано на 9WM, підтримує розташування вікон плиткою +Comment[vi]= Trình Quản lý Cửa sổ Lars, dựa vào 9WM, hỗ trợ cửa sổ xếp ngói +Comment[wa]=Li manaedjeu d' purnea d' Lasrs (Lars Window Manager), båzé so 9WM, sopoite les purneas å pus grand +Comment[zh_CN]=Lars 窗口管理器,基于 9WM,支持平铺窗口 +Comment[zh_TW]=The Lars 視窗管理程式,基於 9WM,支援棋盤化視窗 diff --git a/tdm/kfrontend/sessions/lwm.desktop b/tdm/kfrontend/sessions/lwm.desktop new file mode 100644 index 000000000..2f3e0ff00 --- /dev/null +++ b/tdm/kfrontend/sessions/lwm.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=XSession +Exec=lwm +TryExec=lwm +Name=LWM +Name[eo]=MFA +Name[hi]=एलडबल्यूएम +Name[te]=ఎల్ డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง LWM +Comment=The Lightweight Window Manager. A non-configurable, bare window manager +Comment[af]=Die lig gewig venster bestuurder. +Comment[ar]=مدير النوافذ خفيف العبء، مدير نوافذ مجرّد غير قابل للإعداد +Comment[be]=The Lightweight Window Manager. Пусты кіраўнік вокнаў без падтрымкі настаўленняў +Comment[bn]=দি লাইটওয়েট উইণ্ডো ম্যানেজার +Comment[bs]=Lightweight Window Manager. Ne-podesivi, potpuno osnovni window manager +Comment[ca]=El gestor de finestres Lightweight. Un gestor de finestres no configurable i pelat +Comment[cs]=The Lightweight Window Manager. Prostý a nekonfigurovatelný správce oken +Comment[csb]=Lightweight Window Manager (Letczi menedżer òknół). Bro prosti menedżer òknów bez mòżnoté kònfigùracëji +Comment[cy]=Y Trefnydd Ffenestri Ysgafn. Trefnydd ffenestri noeth, na ellir ffurfweddu +Comment[da]=Lightweight Window Manager, en ikke-indstillelig, minimal vindueshåndtering +Comment[de]=Lightweight Window Manager -- reiner Fenstermanager ohne Einstellmöglichkeiten +Comment[el]=Ο ελαφρύς διαχειριστής παραθύρων. Ένας μη παραμετροποιήσιμος, πολύ απλός διαχειριστής παραθύρων +Comment[eo]=Malpeza Fenestroadministrilo +Comment[es]=El Lightweight Window Manager, un sencillísimo y no configurable gestor de ventanas +Comment[et]=Imeväike aknahaldur on seadistamatu, sõna otseses mõttes ainult akende haldur +Comment[eu]=Libhtweight leiho kudeatzailea. Konfiguraziorik onartzen ez duen leiho-kudeatzaile zeharo sinplea +Comment[fa]=مدیر پنجرۀ سبک، مدیر پنجرۀ غیرقابل پیکربندی و ساده +Comment[fi]=Kevyt ikkunaohjelma. Paljas, ei muokattavissa oleva ikkunaohjelma +Comment[fr]=The Lightweight Window Manager. Un gestionnaire de fenêtres non configurable et nu +Comment[fy]=De Lightweight Window Manager, in net-ynstelbere, keale finstersmanager +Comment[gl]=O Xestor de Fiestras Lixeiro. +Comment[he]=The Lightweight Window Manager. מנהל חלונות מצומצם בלי אפשרויות להגדרה. +Comment[hi]=हल्का विंडो प्रबंधक. खाली विंडो प्रबंधक जो कॉन्फ़िगर नहीं हो सकता +Comment[hr]=LWM - Lightweight Window Manager (Lagani upravitelj prozora) - Temeljni upravitelj prozora bez mogućnosti konfiguriranja +Comment[hu]=Lightweight Window Manager, egy könnyen konfigurálható, alapszintű ablakkezelő +Comment[is]=Hinn létti gluggastjóri. Ekki stillanlegur og hrár +Comment[it]=Il Window Manager Leggero. Un window manager essenziale e non configurabile +Comment[ja]=設定項目のない、単純なウィンドウマネージャ +Comment[ka]=მსუბუქი არაკონფიგურირებადი ფანჯრების მენეჯერი +Comment[kk]=Lightweight Window Manager. Баптауы жоқ, жай терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​សមត្ថភាព​ខ្សោយ ។ កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​គ្មាន​អ្វី​បិទបាំង ហើយ​មិន​អាច​កំណត់​រចនាសម្ព័ន្ធ​បាន +Comment[lt]=„Lengva“ langų tvarkyklė. Nekonfigūruojama, „plika“ langų tvarkyklė +Comment[lv]=Vieglais logu menedžeris. Nekonfigurējams, vienkāršs logu menedžeris +Comment[mk]=Lightweight Window Manager. Неконфигурабилен, скоро празен менаџер на прозорци +Comment[mn]=The Lightweight Window Manager. Тохируулгах боломжгүй,цонхны удирдлага +Comment[ms]=Pengurus tetingkap Ringan. Tidak boleh konfigur, pengurus tetingkap terdedah +Comment[mt]=Lightweight Window Manager. Window Manager sempliċi u mhux konfigurabbli +Comment[nb]=Lettvekts vindusbehandler- Lightweight Window Manager. En enkel vindusbehandler uten innstillinger. +Comment[nds]=De "Lightweight"-Finsterpleger. En reen Finsterpleger ahn Instellen +Comment[ne]=हल्का वजन सञ्झ्याल प्रबन्धक । कन्फिगर गर्न नसकिने, बेयर सञ्झ्याल प्रबन्धक +Comment[nl]=De Lightweight Window Manager, een niet-instelbare, kale windowmanager +Comment[nn]=Lightweight Window Manager. Ein enkel vindaugssjef utan innstillingar. +Comment[pa]=ਇੱਕ ਹਲਕਾ, ਨਾ-ਸੰਰਚਿਤਯੋਗ ਪੱਟੀ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Lightweight Window Manager (Lekki menedżer okien). Surowy menedżer okien bez możliwości konfiguracji +Comment[pt]=O Lightweight Window Manager. Um gestor de janelas não-configurável e básico +Comment[pt_BR]=Um gerenciador de janelas leve, sendo básico e não muito configurável +Comment[ro]=Lightweight Window Manager. Un manager de ferestre neconfigurabil și minimal +Comment[ru]=Облегчённый, не настраиваемый простой оконный менеджер +Comment[rw]=Mugenga Dirishya Yoroshye. Mugenga dirishya idafite ikintu, itabonezwa. +Comment[se]=Lightweight Window Manager. Oktageardánis lásegieđahalli mii ii lea heivehahtti. +Comment[sk]=The Lightweight Window Manager. Nenastaviteľný, jednoduchý správca okien +Comment[sl]=Lahek okenski upravitelj. Ni nastavljiv, osnovni okenski upravitelj +Comment[sr]=„Lightweight Window Manager“. Неподесив, голи менаџер прозора +Comment[sr@Latn]=„Lightweight Window Manager“. Nepodesiv, goli menadžer prozora +Comment[sv]=Den lättviktiga fönsterhanteraren. En enkel fönsterhanterare utan anpassningsmöjligheter +Comment[ta]=குறைந்த எடையுள்ள சாளர மேலாளர். வடிவமைக்க முடியாத +Comment[th]=Lightweight Window Manager ระบบจัดการหน้าต่างเปล่าๆ ที่ไม่สามารถปรับแต่งได้เลย +Comment[tr]=Lightweight Pencere Yöneticisi. Yapılandırılamayan, kaba pencere yönetici +Comment[tt]=Lightweight Window Manager. Caylanmí torğan, ciñel täräzä-idäräçe +Comment[uk]=Невеличкий менеджер вікон без можливості налаштування +Comment[vi]=Trình Quản lý Cửa sổ Nhẹ ký. Rất khó cấu hình +Comment[wa]=Li Ledjir Manaedjeu di Purneas (Lightweight Window Manager). On manaedjeu di purneas tot simpe, nén apontiåve +Comment[zh_CN]=轻量级窗口管理器。不可配置的裸窗口管理器 +Comment[zh_TW]=一個輕量化的視窗管理程式。不可組態、只有基礎視窗管理的視窗管理程式 +# this can't be used as a session in itself +Hidden=true diff --git a/tdm/kfrontend/sessions/matchbox.desktop b/tdm/kfrontend/sessions/matchbox.desktop new file mode 100644 index 000000000..3bec343b0 --- /dev/null +++ b/tdm/kfrontend/sessions/matchbox.desktop @@ -0,0 +1,82 @@ +[Desktop Entry] +Type=XSession +Exec=matchbox-window-manager +TryExec=matchbox-window-manager +Name=Matchbox +Name[bn]=ম্যাচবক্স +Name[eo]=Alumetujo +Name[hi]=मैचबॉक्स +Name[ne]=मिल्ने बाकस +Name[pa]=ਮੈਚ-ਬਾਕਸ +Name[rw]=Agasandukugahura +Name[ta]=பொருத்தப்பெட்டி +Name[te]=అగ్గి పెట్టె +Name[tg]=Қуттии гӯгирд +Name[wa]=Boesse di brocales (Matchbox) +Comment=A window manager for handheld devices +Comment[af]='n Venster bestuurder vir draagbare toestelle +Comment[ar]=مدير نوافذ للأجهزة اليدوية +Comment[be]=Кіраўнік вокнаў для кішанёвых кампутараў +Comment[bn]=হ্যাণ্ডহেল্ড যন্ত্রাদির উপযোগী একটি উইণ্ডো ম্যানেজার +Comment[bs]=Window manager za ručne uređaje +Comment[ca]=Un gestor de finestres per a dispositius de ma +Comment[cs]=Správce oken pro PDA +Comment[csb]=Menedżer òknów dlô palmtopów +Comment[cy]=Trefnydd ffenestri ar gyfer llawiaduron +Comment[da]=En vindueshåndtering for håndholdte enheder +Comment[de]=Fenstermanager für portable Geräte +Comment[el]=Ένας διακομιστής παραθύρων για συσκευές παλάμης +Comment[eo]=Fenestroadministrilo por manaj aparatoj +Comment[es]=Un gestor de ventanas para dispositivos de mano +Comment[et]=Aknahaldur pihuarvutitele +Comment[eu]=Eskuan erabiltzeko gailuentzako leiho kudeatzailea +Comment[fa]=یک مدیر پنجره برای دستگاههای دستی +Comment[fi]=ikkunaohjelma PDA-laitteisiin +Comment[fr]=Un gestionnaire de fenêtres pour les périphériques contrôlés à la main +Comment[fy]=In finstersmanager foar hânkompjûters +Comment[gl]=Un xestor de fiestras para dispositivos manuais +Comment[he]=מנהל חלונות למכשירים נישאים +Comment[hi]=हाथ में रखने वाले औज़ारों के लिए विंडो प्रबंधक +Comment[hr]=Upravitelj prozora za ručna računala +Comment[hu]=Ez az ablakkezelő elsősorban kéziszámítógépekhez ajánlott +Comment[is]=Gluggastjóri fyrir lófatölvur +Comment[it]=Un window manager per palmari +Comment[ja]=ハンドヘルドデバイス向けのウィンドウマネージャ +Comment[ka]=ფანჯრების მენეჯერი მობილური მოწყობილობებისთვის +Comment[kk]=Қол құрылғыларға арналған терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច សម្រាប់​ឧបករណ៍​យួរដៃ +Comment[ko]=핸드헬드 장치를 위한 창 관리자 +Comment[lt]=Langų tvarkyklė įvairiems įrenginiams +Comment[lv]=Logu menedžeris priekš portatīvajām iekārtām +Comment[mk]=Менаџер на прозорци за преносни уреди +Comment[mn]=Гар төхөөрөмжид зориулсан цонхны удирдлага +Comment[ms]=Pengurus tetingkap untuk peranti telapak +Comment[mt]=Window manager għal apparat "handheld" +Comment[nb]=En vindusbehandler for håndholdte enheter +Comment[nds]=Finsterpleger för Handreekner +Comment[ne]=ह्यान्डहेल्ड यन्त्रहरूका लागि सञ्झ्याल प्रबन्धक +Comment[nl]=Een windowmanager voor handcomputers +Comment[nn]=Ein vindaugssjef for handhaldne einingar +Comment[pa]=ਹੱਥਲੇ ਜੰਤਰਾਂ ਲਈ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien dla palmtopów +Comment[pt]=Um gestor de janelas para dispositivos móveis +Comment[pt_BR]=Um gerenciador de janelas para dispositivos handheld +Comment[ro]=Un manager de ferestre pentru PDA-uri +Comment[ru]=Оконный менеджер для мобильных устройств +Comment[rw]=Mugenga dirishya y'amapareye atwarwa-ntoki +Comment[se]=Lásegieđahalli giehtaovttadagaid várás +Comment[sk]=Správca okien pre prenosné zariadenia +Comment[sl]=Okenski upravitelj za dlančne naprave +Comment[sr]=Менаџер прозора за мале преносне уређаје +Comment[sr@Latn]=Menadžer prozora za male prenosne uređaje +Comment[sv]=Fönsterhanterare för handburna enheter +Comment[ta]=கையில் உள்ள சாதனங்களுக்கான சாளர மேலாளர் +Comment[tg]=Як мудири тиреза барои дастгоҳҳои дастӣ +Comment[th]=ระบบจัดการหน้าต่างของอุปกรณ์มือถือ +Comment[tr]=El bilgisayarları için bir pencere yöneticisi +Comment[tt]=Qul cıhazı öçen täräzä-idäräçe +Comment[uk]=Менеджер вікон для портативних пристроїв +Comment[vi]=Trình quản lý cửa sổ dành cho thiết bị cầm tay +Comment[wa]=On manaedjeu di purneas po les éndjins ebarkés +Comment[zh_CN]=手持设备的窗口管理器 +Comment[zh_TW]=一個掌上型設備所使用的視窗管理程式 diff --git a/tdm/kfrontend/sessions/metacity.desktop b/tdm/kfrontend/sessions/metacity.desktop new file mode 100644 index 000000000..d2a5a5537 --- /dev/null +++ b/tdm/kfrontend/sessions/metacity.desktop @@ -0,0 +1,83 @@ +[Desktop Entry] +Type=XSession +Exec=metacity +TryExec=metacity +Name=Metacity +Name[bn]=মেটাসিটি +Name[eo]=Metaurbo +Name[hi]=मेटासिटी +Name[mn]=Метасити +Name[ne]=मेटासिटी +Name[rw]=Metacity(Mugenga-dirishya) +Name[ta]=மெடாசிட்டி +Name[te]=మెటాసిటి +Comment=A lightweight GTK2 based window manager +Comment[af]=Die lig gewig GTK2 gebaseerde venster bestuurder +Comment[ar]=مدير نوافذ خفيف العبء مبني على GTK2 +Comment[be]=Лёгкі кіраўнік вокнаў, заснаваны на GTK2 +Comment[bn]=একটি হাল্কা GTK2 ভিত্তিক উইণ্ডো ম্যানেজার +Comment[bs]=Lagani window manager baziran na GTK2 +Comment[ca]=Un gestor de finestres lleuger basat en GTK2 +Comment[cs]=Malý správce oken založený na GTK2 +Comment[csb]=Menedżer òknół ò môłëch żądniach, òpiarti na GTK2 +Comment[cy]=Trefnydd ffenestri ysgafn, wedi'i seilio ar GTK2 +Comment[da]=En letvægts GTK2 baseret vindueshåndtering +Comment[de]=Schlanker Fenstermanager, der auf GTK2 basiert +Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων βασισμένος στο GTK2 +Comment[eo]=Malpeza fenestroadministrilo +Comment[es]=Un gestor de ventanas ligero basado en GTK2 +Comment[et]=Imeväike aknahaldur, mille aluseks on GTK2 +Comment[eu]=GTK2n oinarritutako leiho kudeatzaile arin bat +Comment[fa]=GTK2 سبک بر اساس مدیر پنجره +Comment[fi]=Kevyt, GTK2-pohjainen ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres fondé sur GTK2 et léger +Comment[fy]=In lichtgewicht op GTK2 basearre finstersmanager +Comment[gl]=Un xestor de fiestras lixeiro baseado en GTK2 +Comment[he]=מנהל חלונות קל מבוסס GTK2 +Comment[hi]=जीटीके2 आधारित हल्का विंडो प्रबंधक +Comment[hr]=Lagani upravitelj prozora zasnovan na GTK2 +Comment[hu]=Egy egyszerű, GTK2-alapú ablakkezelő +Comment[is]=Léttur gluggastjóri byggður á GTK2 +Comment[it]=Un window manager leggero basato su GTK2 +Comment[ja]=GTK2 ベースの軽量なウィンドウマネージャ +Comment[ka]=GTK2-ს ბაზაზე მსუბუქი ფანჯრის მენეჯერი +Comment[kk]=GTK2-негіздеген, жеңіл терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​សមត្ថភាព​ខ្សោយ ដែល​ផ្អែក​លើ GTK2 +Comment[ko]=가벼운 GTK2 기반 창 관리자 +Comment[lt]=Nedaug resursų reikalaujanti langų tvarkyklė, paremta GTK2 +Comment[lv]=Viegls GTK 2 bāzēts logu menedžeris +Comment[mk]=Лесен менаџер на прозорци базиран на GTK2 +Comment[mn]=Хөнгөн GTK2 суурьт цонхны удирдагч +Comment[ms]=Pengurus tetingkap berasaskan GTK2 ringan +Comment[mt]=Window manager ħafif ibbażat fuq GTK2 +Comment[nb]=En lettvekts vindusbehandler basert på GTK2 +Comment[nds]=En ranke Finsterpleger, opbuut op GTK2 +Comment[ne]=सञ्झ्याल प्रबन्धकमा आधारित हल्का वजन GTK2 +Comment[nl]=Een lichtgewicht op GTK2 gebaseerde windowmanager +Comment[nn]=En lett vindaugssjef basert på GTK2 +Comment[pa]=ਇੱਕ ਹਲਕਾ GTK2 ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien o małych wymaganiach, oparty na GTK2 +Comment[pt]=Um gestor de janelas leve, baseado em GTK2 +Comment[pt_BR]=Um gerenciador de Janelas leve baseado em GTK2 +Comment[ro]=Un manager de ferestre mic bazat pe GTK2 +Comment[ru]=Лёгкий оконный менеджер на основе GTK2 +Comment[rw]=Mugenga dirishya ishingiye kuri GTK2 yoroshye +Comment[se]=Geahpes GTK2-vuođđoduvvon lásegieđahalli +Comment[sk]=Nenáročný správca okien založený na GTK2 +Comment[sl]=Lahek okenski upravitelj na osnovi GTK2 +Comment[sr]=Лагани менаџер прозора заснован на GTK2 +Comment[sr@Latn]=Lagani menadžer prozora zasnovan na GTK2 +Comment[sv]=Lättviktig GTK2-baserad fönsterhanterare +Comment[ta]=சாளர மேலாளர் அடிப்படையிலான ஒரு குறைந்த எடை GTK2 +Comment[te]=తెలికైన జిటికె2 ఆధారిత విండొ అభికర్త +Comment[tg]=Сабуки GTK2 ба асоси мудири тиреза +Comment[th]=ระบบจัดการหน้าต่างขนาดเบาที่ใช้ GTK2 +Comment[tr]=Gtk2 tabanlı hafif bir pencere yöneticisi +Comment[tt]=GTK2 asılında ciñel täräzä-idäräçe +Comment[uk]=Простий менеджер вікон для GTK2 +Comment[uz]=GTK2 asosida yaratilgan oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=GTK2 асосида яратилган оддий ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ nhỏ gọn dựa trên GTK2 +Comment[wa]=On ledjir manaedjeu di purneas båzé so GTK2 +Comment[zh_CN]=轻量级 GTK2 窗口管理器 +Comment[zh_TW]=一個基於 GTK2 的輕量化視窗管理程式 diff --git a/tdm/kfrontend/sessions/mwm.desktop b/tdm/kfrontend/sessions/mwm.desktop new file mode 100644 index 000000000..b1d6e2acd --- /dev/null +++ b/tdm/kfrontend/sessions/mwm.desktop @@ -0,0 +1,78 @@ +[Desktop Entry] +Type=XSession +Exec=mwm +TryExec=mwm +Name=MWM +Name[eo]=MFA +Name[hi]=एमडबल्यूएम +Name[te]=ఎం డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง MWM +Comment=The Motif Window Manager +Comment[af]=Die Motif venster bestuurder +Comment[ar]=مسيير النوافذ Motif +Comment[be]=Кіраўнік вокнаў Motif +Comment[bn]=দি মোটিফ উইণ্ডো ম্যানেজার +Comment[bs]=Motif Window Manager +Comment[ca]=El gestor de finestres Motif +Comment[cs]=Motif Window Manager +Comment[csb]=Menedżer òknów Motif +Comment[cy]=Y Trefnydd Ffenestri Motif +Comment[da]=Motif vindueshåndtering +Comment[de]=Motif-Fenstermanager +Comment[el]=Ο διαχειριστής παραθύρων Motif +Comment[eo]=Motifa fenestroadministrilo +Comment[es]=El gestor de ventanas de Motif +Comment[et]=Motifi aknahaldur +Comment[eu]=Motif leiho kudeatzailea +Comment[fa]=مدیر پنجره موتیف +Comment[fi]=Motif-ikkunaohjelma +Comment[fr]=Le gestionnaire de fenêtres Motif +Comment[fy]=De Motif Window Manager +Comment[ga]=Bainisteoir fuinneoga Motif +Comment[gl]=O Xestor de Fiestras Motif +Comment[he]=מנהל החלונות Motif +Comment[hi]=मोटिफ विंडो प्रबंधक +Comment[hr]=Motif upravitelj prozora +Comment[hu]=Motif ablakkezelő +Comment[is]=Motif gluggastjórinn +Comment[it]=Il window manager di Motif +Comment[ja]=Motif 風のウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი Motif +Comment[kk]=Motif терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច Motif +Comment[ko]=Motif 창 관리자 +Comment[lt]=Motif langų tvarkyklė +Comment[lv]=Motif logu menedžeris +Comment[mk]=Менаџерот на прозорци Motif +Comment[mn]=Motif Цонхны удирдагч +Comment[ms]=Pengurus Tertingkap Motif +Comment[mt]=Window manager tal-Motif +Comment[nb]=Motif vindusbehandler +Comment[nds]=De Motif-Finsterpleger +Comment[ne]=मोटिफ सञ्झ्याल प्रबन्धक +Comment[nl]=De Motif Window Manager +Comment[nn]=Motif-vindaugssjefen +Comment[pa]=Motif ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien Motif +Comment[pt]=O gestor de janelas do Motif +Comment[pt_BR]=O gerenciador de janelas Motif +Comment[ro]=Managerul de ferestre Motif +Comment[ru]=Оконный менеджер Motif +Comment[rw]=Mugenga Dirishya Umutako +Comment[se]=Motif lásegieđahalli +Comment[sk]=Správca okien Motif +Comment[sl]=Okenski upravitelj Motif +Comment[sv]=Motifs fönsterhanterare +Comment[ta]=மோடிஃப் சாளர மேலாளர் +Comment[te]=మొటిఫ్ విండొ అభికర్త +Comment[tg]=Мавзӯъи мудири тиреза +Comment[th]=ระบบจัดการหน้าต่างของโมทิฟ +Comment[tr]=Motif Pencere Yöneticisi +Comment[tt]=Motif Täräzä İdäräçe +Comment[uk]=Менеджер вікон Motif +Comment[uz]=Motif oyna boshqaruvchi +Comment[uz@cyrillic]=Motif ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ Motif +Comment[wa]=Li manaedjeu di purneas di Motif +Comment[zh_CN]=Motif 窗口管理器 +Comment[zh_TW]=Motif 視窗管理程式 diff --git a/tdm/kfrontend/sessions/olvwm.desktop b/tdm/kfrontend/sessions/olvwm.desktop new file mode 100644 index 000000000..23dee1169 --- /dev/null +++ b/tdm/kfrontend/sessions/olvwm.desktop @@ -0,0 +1,71 @@ +[Desktop Entry] +Type=XSession +Exec=olvwm-x-window-manager +TryExec=olvwm-x-window-manager +Name=OLVWM +Name[br]=OVLWM +Name[eo]=OLVFA +Name[hi]=ओएलवीडबल्यूएम +Name[te]=ఒ ఎల్ వి డబ్యు ఎం +Comment=The OpenLook Virtual Window Manager. OLWM enhanced for handling of virtual desktops +Comment[af]=Die OpenLook virtuele venster bestuurder. OLWM wat uitgebrei is vir virtuele werkskerms +Comment[ar]=مدير النوافذ الوهمي OpenLook، محسّن للتعامل مع أسطح المكتب الوهمية +Comment[be]=The OpenLook Virtual Window Manager. OLWM дапрацаваны для падтрымкі віртуальных працоўных сталоў +Comment[bn]=দি ওপেনলুক ভার্চুয়াল উইণ্ডো ম্যানেজার। OLWM-এর বর্ধিত সংস্করণ যাতে ভার্চুয়াল ডেস্কটপ সমর্থিত +Comment[bs]=OpenLook Virtual Window Manager. OLWM proširen podrškom za virtualne desktope +Comment[ca]=El OpenLook Virtual Window Manager. OLWM millorat per a escriptoris virtuals de ma +Comment[csb]=OpenLook Virtual Window Manager. OLWM zbògacony ò wspiarce wirtualnëch pùltów +Comment[cy]=Y Trefnydd Ffenestri Rhith GolwgAgored (OpenLook). OLWM wedi'i wella i gynnal penbyrddau rhith +Comment[da]=OpenLook Virtual Window Manager. OLWM udvidet med håndtering af virtuelle desktoppe +Comment[de]=OpenLook virtueller Fenstermanager, OLWM mit verbesserter Verwaltung von virtuellen Arbeitsflächen +Comment[el]=Ο OpenLook εικονικός διαχειριστής παραθύρων. Ο OLWM εμπλουτισμένος με διαχείριση εικονικών επιφανειών εργασίας +Comment[eo]=Fenestroadministrilo por virtualaj labortabloj +Comment[es]=El OpenLook Virtual Window Manager, un versión mejorada de OLWM con soporte para escritorios virtuales +Comment[et]=OpenLook virtuaalne aknahaldur on OLWM, mida on täiendatud virtuaalsete töölaudade võimalusega +Comment[eu]=OpenLook leiho kudeatzaile birtuala. mahaigain birtualak kudeatzeko OLWM hobetua +Comment[fa]=مدیر پنجرۀ مجازی OpenLook. OLWM گسترش‌یافته برای گرداندن رومیزیهای مجازی +Comment[fi]=OpenLook virtuaalinen ikkunanhallinta. OLWM:n paranneltu versio,joka käsittelee virtuaalityöpöytiä paremmin +Comment[fr]=The OpenLook Virtual Window Manager. OLWM avec en plus la gestion des bureaux virtuels +Comment[fy]=De OpenLook Virtual Window Manager. OLWM útbreide mei firtuele buroblêden +Comment[gl]=O OpenLook Virtual Window Manager. OLWM mellorado para manexar escritórios virtuais +Comment[he]=The OpenLook Virtual Window Manager. OLWM משופר בשביל טיפול בשולחנות עבודה וירטואליים +Comment[hi]=ओपनलुक आभासी विंडो प्रबंधक. ओएलडबल्यूएम को आभासी डेस्कटॉप हैंडल करने के लिए बेहतर बनाया गया +Comment[hr]=OpenLook virtualni upravitelj prozora - OLWM unaprijeđen mogućnošću rukovanja s virtualnim radnim površinama +Comment[hu]=OpenLook Virtual Window Manager (OLWM), virtuális munkaasztalok kezelésére is képes +Comment[is]=OpenLook sýndargluggastjórinn. Endurbættur með OLWM til að styðja sýndarskjáborð +Comment[it]=L'OpenLook Virtual Window Manager. OLWM migliorato per gestire i desktop virtuali +Comment[ja]=OpenLook 仮想ウィンドウマネージャ, OLWM 強化仮想デスクトップ +Comment[ka]=გაუმჯობესებული ფანჯრის მენეჯერი OpenLook, რამდენიმე სამუშაო დაფის მხარდაჭერით +Comment[kk]=OpenLook Virtual Window Manager - виртуалды үстелдерді қолдайтын терезе менеджері +Comment[km]=OpenLook Virtual Window Manager ។ OLWM ដែល​បាន​ធ្វើ​ឲ្យ​ប្រសើរ សម្រាប់​ការ​ប្រើ​ផ្ទៃតុ​និមិត្ត ។ +Comment[lt]=OpenLook virtuali langų tvarkyklė. OLWM išplėsta su virtualių darbastalių palaikymu +Comment[mk]=OpenLook Virtual Window Manager. OLWM менаџерот со подобрено ракување на виртуелни површини +Comment[ms]=Pengurus Tetingkap Maya OpenLook. OLWM dipertingkat untuk mengendalikan desktop maya +Comment[mt]=OpenLook Virtual Window Manager - OLWM flimkien ma' desktops virtwali. +Comment[nb]=OpenLook Virtual Window Manager. OLWM utvidet med virtuelle skrivebord. +Comment[nds]=De "OpenLook Virtual Window Manager" is OLWM verwiedert üm virtuelle Schriefdischen +Comment[ne]=अवास्तविक डेस्कटपहरूको ह्यान्डलका लागि बृद्धि गरिएको OLWM खुला देखिने अवास्तविक सञ्झ्याल प्रबन्धक । +Comment[nl]=De OpenLook Virtual Window Manager. OLWM uitgebreid met virtuele bureaubladen +Comment[nn]=OpenLook Virtual Window Manager. OLWM utvida med virtuelle skrivebord. +Comment[pa]=OpenLook Virtual Window Manager. OLWM ਫਰਜ਼ੀ ਵੇਹੜਿਆਂ ਲਈ ਖਾਸ ਤੌਰ ਤੇ ਤਿਆਰ +Comment[pl]=OpenLook Virtual Window Manager. OLWM wzbogacony o obsługę wirtualnych pulpitów +Comment[pt]=O OpenLook Virtual Window Manager. Um OLWM melhorado para lidar com ecrãs virtuais +Comment[pt_BR]=Acrônimo para OpenLook Virtual Window Manager, o OLWM melhorado para a manipulação de áreas de trabalho virtuais +Comment[ro]=OpenLook Virtual Window Manager. Un OLWM îmbunătățit cu ecrane virtuale +Comment[ru]=Улучшенный оконный менеджер OpenLook, поддерживающий несколько рабочих столов +Comment[rw]=Mugenga Dirishya Itagaragara GufunguraKureba. OLWM ivuguruwe mu gufasha ibiro bitagaragara +Comment[se]=The OpenLook Virtual Window Manager. OLWM buoriduvvon nu ahte das leat virtuella čállinbeavddit +Comment[sk]=Virtuálny správca okien OpenLook. OLWM rozšírený o podporu virtuálnych plôch +Comment[sl]=Open Look Virtual Window Manager je izboljšan OLWM s podporo navideznim namizjem +Comment[sr]=„OpenLook Virtual Window Manager“. OLWM побољшан за управљање виртуелним радним површинама +Comment[sr@Latn]=„OpenLook Virtual Window Manager“. OLWM poboljšan za upravljanje virtuelnim radnim površinama +Comment[sv]=Open Look virtuell fönsterhanterare. OLWM utökad för att hantera virtuella skrivbord +Comment[ta]=ஓபன்லுக் மெய்நிகர் சாளர மேலாளர். மெய்நிகர் மேல்மேசைகளை கையாளுவதற்கு OLWM மேம்படுத்தப்பட்டது. +Comment[th]=ระบบจัดการหน้าต่างเสมือน OpenLook คือ OLWM ที่ถูกเพิ่มเติมความสามารถในการรับมือกับพื้นที่ทำงานเสมือน +Comment[tr]=OpenLook Sanal Pencere Yöneticisi. +Comment[tt]=OpenLook Virtual Window Manager. Xıyalí öställär öçen yaqşırtılğan OpenLook +Comment[uk]=OpenLook Virtual Window Manager. OLWM з підтримкою віртуальних стільниць +Comment[vi]=Trình Quản lý Cửa sổ Ảo "Cái nhìn Mở". Nó được cải tiến cho việc xử lý màn hình nền ảo +Comment[wa]=Li Manaedjeu di Forveyou Purnea OpenLook (OpenLook Virtual Window Manager). OLWM permete d' apougnî des forveyowès sicribannes +Comment[zh_CN]=OpenLook 虚拟窗口管理器。OLWM 特别增强了虚拟桌面的处理 +Comment[zh_TW]=Openlook 視窗管理程式。基於 OLWM 並強化管理虛擬桌面 diff --git a/tdm/kfrontend/sessions/olwm.desktop b/tdm/kfrontend/sessions/olwm.desktop new file mode 100644 index 000000000..32612eaa3 --- /dev/null +++ b/tdm/kfrontend/sessions/olwm.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=XSession +Exec=olwm-x-window-manager +TryExec=olwm-x-window-manager +Name=OLWM +Name[eo]=OLFA +Name[hi]=ओएलडबल्यूएम +Name[te]=ఒ ఎల్ డబ్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง OLWM +Comment=The traditional Open Look Window Manager +Comment[af]=Die tradisionele Open Look venster bestuurder +Comment[ar]=مسيير النوافذ Open Look التقليدي +Comment[be]=Традыцыйны кіраўнік вокнаў Open Look +Comment[bn]=দি ওপেনলুক উইণ্ডো ম্যানেজার +Comment[bs]=Tradicionalni Open Look Window Manager +Comment[ca]=El tradicional gestor de finestres Open Look +Comment[cs]=Tradiční Open Look Window Manager +Comment[csb]=Tradicëjny menedżer òknów Open Look +Comment[cy]=Y Trefnydd Ffenestri GolwgAgored (OpenLook) traddodiadol +Comment[da]=Den traditionelle Open Look vindueshåndtering +Comment[de]=Der traditionelle Open-Look-Fenstermanager +Comment[el]=Ο παραδοσιακός διαχειριστής παραθύρων Open Look +Comment[eo]=La klasika OL-fenestroadministrilo +Comment[es]=El tradicional Open Look Window Manager +Comment[et]=Tavapärane OpenLooki aknahaldur +Comment[eu]=Betiko Open Look leiho kudeatzailea +Comment[fa]=مدیر پنجره Open Look سنتی +Comment[fi]=Perinteinen Open Look -ikkunaohjelma +Comment[fr]=Le gestionnaire de fenêtres traditionnel Open Look +Comment[fy]=De tradisjoneel iepen like finstersManager +Comment[gl]=O tradicional Xestor de Fiestras de Open Look +Comment[he]=Open Look Window Manager המסורתי +Comment[hi]=परम्परागत ओपन लुक विंडो प्रबंधक +Comment[hr]=Tradicionalni 'Open Look' upravitelj prozora +Comment[hu]=A hagyományos Open Look ablakkezelő +Comment[is]=Hinn hefðbundni Open Look gluggastjóri +Comment[it]=L'Open Look Window Manager tradizionale +Comment[ja]=伝統的な OpenLook ウィンドウマネージャ +Comment[ka]=OpenLook სისტემის ტრადიციული ფანჯრის მენეჯერი +Comment[kk]=Дәстүрлі Open Look терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​រូបរាង​បើក​ចំហ​បុរាណ +Comment[lt]=Tradicinė Open Look langų tvarkyklė +Comment[lv]=Tradicionālais Open Look logu menedžeris +Comment[mk]=Традиционален Open Look Window Manager +Comment[mn]=Уламжилалт нээж харагч цонхны удирдагч +Comment[ms]=Pengurus Tetingkap OpenLook tradisional +Comment[mt]=Window manager tradizzjonali ta' OpenLook +Comment[nb]=Den tradisjonelle Open Look-vindusbehandleren +Comment[nds]=De traditschonelle OpenLook-Finsterpleger +Comment[ne]=खुला देखिने परम्परागत सञ्झ्याल प्रबन्धक +Comment[nl]=De traditionele Open Look Window Manager +Comment[nn]=Den tradisjonelle Open Look-vindaugssjefen +Comment[pa]=ਇੱਕ ਮੂਲ ਓਪਨ ਲੁੱਕ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Tradycyjny menedżer okien Open Look +Comment[pt]=O gestor de janelas Open Look tradicional +Comment[pt_BR]=O tradicional Open Look Window Manager +Comment[ro]=Managerul de ferestre tradițional Open Look Window Manager +Comment[ru]=Традиционный оконный менеджер системы OpenLook +Comment[rw]=Mugenga Dirishya Gufungura Kureba karande +Comment[se]=Árbevirolaš Open Look lásegieđahalli +Comment[sk]=Tradičný správca okien Open Look +Comment[sl]=Tradicionalni Open Look Window Manager +Comment[sr]=Традиционални „Open Look“ менаџер прозора +Comment[sr@Latn]=Tradicionalni „Open Look“ menadžer prozora +Comment[sv]=Den traditionella Open Look fönsterhanteraren +Comment[ta]=பழமையான சாளர மேலாளர் +Comment[te]=సాంప్రదాయ ఒపెన్ లుక్ విండొ అభికర్త +Comment[tg]=Расмшудаи Open Look-и мудири тиреза +Comment[th]=ระบบจัดการหน้าต่าง OpenLook แบบดั้งเดิม +Comment[tr]=OpenLook Pencere Yöneticisi +Comment[tt]=Open Look täräzä-idäräçeneñ töp söreme +Comment[uk]=Традиційний менеджер вікон Open Look +Comment[vi]=Trình Quản lý Cửa sổ "Cái nhìn Mở" truyền thống +Comment[wa]=Li mwaisse Manaedjeu di Purnea OpenLook (OpenLook Virtual Window Manager) +Comment[zh_CN]=传统的 OpenLook 窗口管理器 +Comment[zh_TW]=傳統的 Open Look 視窗管理程式 diff --git a/tdm/kfrontend/sessions/openbox.desktop b/tdm/kfrontend/sessions/openbox.desktop new file mode 100644 index 000000000..d0f4a06d7 --- /dev/null +++ b/tdm/kfrontend/sessions/openbox.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +Type=XSession +Exec=openbox-session +TryExec=openbox +Name=Openbox +Name[bn]=ওপেনবক্স +Name[cy]=Blwchagored (Openbox) +Name[eo]=Malfermujo +Name[hi]=ओपनबाक्स +Name[ne]=खुला बाकस +Name[pa]=ਓਪਨ ਬਕਸਾ +Name[rw]=GufunguraAgasanduku +Name[ta]=திறப்பு பெட்டி +Name[te]=ఒపెన్ బాక్స్ +Name[tg]=Кушодани қуттӣ +Comment=A lightweight window manager based on Blackbox +Comment[af]='n Lig gewig venster bestuurder wat op Blackbox gebaseer is +Comment[ar]=مدير نوافذ خفيف العبء مبني على Blackbox +Comment[be]=Лёгкі кіраўнік вокнаў, заснаваны на Blackbox +Comment[bn]=ব্ল্যাকবক্স ভিত্তিক হাল্কা উইণ্ডো ম্যানেজার +Comment[bs]=Lagani window manager baziran na Blackbox-u +Comment[ca]=Un lleuger gestor de finestres basat en Blackbox +Comment[cs]=Malý správce oken založený na Blackboxu +Comment[csb]=Menedżer òknów o môłëch żądaniach, òpairti na Blackbox +Comment[cy]=Trefnydd ffenestri ysgafn, wedi'i seilio ar Ddu-flwch +Comment[da]=En letvægts vindueshåndtering baseret på Blackbox +Comment[de]=Schlanker Fenstermanager, der auf Blackbox beruht +Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων βασισμένος στον Blackbox +Comment[eo]=Fenestroadministrilo devenigita de Negrujo +Comment[es]=Un gestor de ventanas ligero basado en BlackBox +Comment[et]=Imeväike aknahaldur, mille aluseks on Blackbox +Comment[eu]=Blackboxen oinarritutako leiho kudeatzaile arina +Comment[fa]=یک مدیر پنجرۀ سبک بر اساس Blackbox +Comment[fi]=Kevyt, Blackboxiin pohjautuva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres léger fondé sur Blackbox +Comment[fy]=In lichtgewicht finstersmanager, basearre op Blackbox +Comment[gl]=Un xestor de fiestras lixeiro baseado en Blackbox +Comment[he]=מנהל חלונות קל מבוסס על Blackbox +Comment[hi]=ब्लेकबाक्स आधारित हल्का विंडो प्रबंधक +Comment[hr]=Lagani upravitelj prozora zasnovan na Blackboxu +Comment[hu]=Egy nagyon egyszerű ablakkezelő a Blackbox alapján +Comment[is]=Léttur gluggastjóri byggður á Blackbox +Comment[it]=Un window manager leggero basato su BlackBox +Comment[ja]=Blackbox ベースの軽量なウィンドウマネージャ +Comment[ka]=Blackbox-ის ბაზაზე ფანჯრიოს მენეჯერი +Comment[kk]=Blackbox-негіздеген жеңіл терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​សមត្ថភាព​ខ្សោយ ដែល​ផ្អែក​លើ Blackbox +Comment[ko]=Blackbox 기반 가벼운 창 관리자 +Comment[lt]=Nedaug resursų reikalaujanti langų tvarkyklė, paremta Blackbox +Comment[lv]=Viegls logu menedžeris, bāzēts uz Blackbox +Comment[mk]=Лесен менаџер на прозорци базиран на Blackbox +Comment[ms]=Pengurus tetingkap ringan berdasarkan Kotak Hitam +Comment[mt]=Window manager ħafif ibbażat fuq BlackBox +Comment[nb]=En lettvekts vindusbehandler basert på Blackbox +Comment[nds]=En ranke Finsterpleger, opbuut op Blackbox +Comment[ne]=कालो बाकसमा आधारित हल्का वजन सञ्झ्याल प्रबन्धक +Comment[nl]=Een lichtgewicht windowmanager, gebaseerd op Blackbox +Comment[nn]=Ein lett vindaugssjef basert på Blackbox +Comment[pa]=ਬਲੈਕਬਕਸੇ ਤੇ ਆਧਾਰਿਤ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien o małych wymaganiach, oparty na Blackbox +Comment[pt]=Um gestor de janelas leve baseado no Blackbox +Comment[pt_BR]=Um gerenciador de janelas leve, baseado no Blackbox +Comment[ro]=Un manager de ferestre minimal bazat pe Blackbox +Comment[ru]=Лёгкий оконный менеджер, основанный на Blackbox +Comment[rw]=Mugenga dirishya yoroshye ishingiye ku Gasandukumukara +Comment[se]=Geahpes lásegieđahalli ráhkaduvvon Blackboxa vuođul +Comment[sk]=Nenáročný správca okien založený na Blackbox +Comment[sl]=Lahek okenski upravitelj na osnovi Blackboxa +Comment[sr]=Лагани менаџер прозора заснован на Blackbox-у +Comment[sr@Latn]=Lagani menadžer prozora zasnovan na Blackbox-u +Comment[sv]=Lättviktig fönsterhanterare baserad på Blackbox +Comment[ta]=கருப்புப் பெட்டியின் அடிப்படையிலான ஒரு குறைந்த எடை சாளர மேலாளர் +Comment[te]=బ్లాక్ బాక్స్ ఆధారిత తెలికైన విండొ అభికర్త +Comment[tg]=Мудири тирезаи сабук ба асоси қуттии сиёҳ +Comment[th]=ระบบจัดการหน้าต่างขนาดเบา สร้างมาจาก Blackbox +Comment[tr]=Blackbox temelli küçük bir pencere yöneticisi +Comment[tt]=Blackbox asılında ciñel täräzä-idäräçe +Comment[uk]=Легкий менеджер вікон, заснований на Blackbox +Comment[uz]=Blackbox asosida yaratilgan oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=Blackbox асосида яратилган оддий ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ nhỏ gọn dựa trên Blackbox +Comment[wa]=On ledjir manaedjeu di purneas båzé so Blackbox +Comment[zh_CN]=基于 BlackBox 的轻量级窗口管理器 +Comment[zh_TW]=一個基於 Blackbox 且輕量化的視窗管理程式 diff --git a/tdm/kfrontend/sessions/oroborus.desktop b/tdm/kfrontend/sessions/oroborus.desktop new file mode 100644 index 000000000..b7ea37c30 --- /dev/null +++ b/tdm/kfrontend/sessions/oroborus.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=XSession +Exec=oroborus +TryExec=oroborus +Name=Oroborus +Name[eo]=Koloroj +Name[hi]=ऑरोबोरस +Name[pa]=ਓਰੂਬੋਰੁਸ +Name[te]=ఒరొబొరస్ +Comment=A lightweight themeable window manager +Comment[af]='n Lig gewig, tema venster bestuurder +Comment[ar]=مدير نوافذ خفيف العبء قابل لاستخدام السمات +Comment[be]=Лёгкі кіраўнік вокнаў з падтрымкай тэмаў +Comment[bn]=হাল্কা থীমযুক্ত উইণ্ডো ম্যানেজার +Comment[bs]=Lagani window manager sa podrškom za teme +Comment[ca]=Un gestor de finestres lleuger i configurable amb temes +Comment[cs]=Malý správce oken s tématy +Comment[csb]=Menedżer òknów ò môłëch żądanich, z mòżnotą zmianë wëzdrzatkù +Comment[cy]=Trefnydd ffenestri ysgafn sy'n defnyddio themau +Comment[da]=En letvægts vindueshåndtering med temaer +Comment[de]=Schlanker Fenstermanager mit Designs +Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων με υποστήριξη θεμάτων +Comment[eo]=Fenestroadministrilo +Comment[es]=Un gestor de ventanas ligero con temas +Comment[et]=Imeväike teemadega aknahaldur +Comment[eu]=Temak onartzen dituen leiho kudeatzaile arina +Comment[fa]=یک مدیر پنجرۀ قابل چهره‌بندی سبک +Comment[fi]=Kevyt teemoitettava ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres avec gestion des thèmes +Comment[fy]=In lichtgewicht finstersmanager mei temabehear +Comment[gl]=Un xestor de fiestras lixeiro e con capacidade para temas +Comment[he]=מנהל חלונות קל ובר התאמה אישית של ערכות נושא +Comment[hi]=हल्का, प्रसंगयोग्य विंडो प्रबंधक +Comment[hr]=Lagani upravitelj prozora s temama +Comment[hu]=Kis erőforrásigényű ablakkezelő, témázási lehetőséggel +Comment[is]=Léttur þemanlegur gluggastjóri +Comment[it]=Un window manager leggero che supporta i temi +Comment[ja]=テーマ化可能な軽量のウィンドウマネージャ +Comment[ka]=მსუბუქი ფანჯრის მენეჯერი თემების მხარდაჭერით +Comment[kk]=Жеңіл, нақыштары бар терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​អាច​ប្ដូរ​ស្បែក​បាន តែ​មាន​សមត្ថភាព​ខ្សោយ +Comment[ko]=가벼운 테마를 설정할 수 있는 창 관리자 +Comment[lt]=Nedaug resursų reikalaujanti temas palaikanti langų tvarkyklė +Comment[lv]=Viegls logu menedžeris ar tēmu atbalstu +Comment[mk]=Лесен менаџер на прозорци со теми +Comment[ms]=Pengurus tetingkap boleh tema ringan +Comment[mt]=Window manager ħafif u temabbli +Comment[nb]=En lettvekts vindusbehandler med temaer +Comment[nds]=En ranke Finsterpleger, kann Mustern bruken +Comment[ne]=विषयवस्तु योग्य हल्का वजन सञ्झ्याल प्रबन्धक +Comment[nl]=Een lichtgewicht windowmanager met themabeheer +Comment[nn]=Ein lett vindaugssjef med tema +Comment[pa]=ਇੱਕ ਸਰੂਪਾਂ ਨਾਲ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien o małych wymaganiach, z możliwością zmiany wyglądu +Comment[pt]=Um gestor de janelas leve e com suporte para temas +Comment[pt_BR]=Um gerenciador de Janelas leve com vários temas +Comment[ro]=Un manager de ferestre mic și configurabil cu diverse tematici +Comment[ru]=Лёгкий оконный менеджер, поддерживающий темы +Comment[rw]=Mugenga dirishya ngirwa-nsanganyamatsiko yoroshye +Comment[se]=Geahpes lásegieđahalli mas leat fáttát +Comment[sk]=Nenáročný správca okien s podporou tém +Comment[sl]=Lahek okenski upravitelj s temami +Comment[sr]=Лагани менаџер прозора са темама +Comment[sr@Latn]=Lagani menadžer prozora sa temama +Comment[sv]=Lättviktig fönsterhanterare med teman +Comment[ta]=குறைந்தஎடை தலைப்புடைய சாளர மேலாளர் +Comment[th]=ระบบจัดการหน้าต่างขนาดเบาที่ใช้ชุดตกแต่งได้ +Comment[tr]=Küçük, hafif, temalı bir pencere yöneticisi +Comment[tt]=Tışlana torğan ciñel täräzä-idäräçe +Comment[uk]=Легкий менеджер вікон з підтримкою тем +Comment[vi]=Trình quản lý cửa sổ thay đổi được sắc thái +Comment[wa]=On ledjir manaedjeu di purneas avou des tinmes +Comment[zh_CN]=轻量级窗口管理器,可定义主题 +Comment[zh_TW]=一個輕量化且有佈景功能的視窗管理程式 +# not usable as a session +Hidden=true diff --git a/tdm/kfrontend/sessions/phluid.desktop b/tdm/kfrontend/sessions/phluid.desktop new file mode 100644 index 000000000..f1cca1d66 --- /dev/null +++ b/tdm/kfrontend/sessions/phluid.desktop @@ -0,0 +1,80 @@ +[Desktop Entry] +Type=XSession +Exec=phluid +TryExec=phluid +Name=Phluid +Name[eo]=Plena +Name[hi]=फ्लुइड +Name[pa]=ਫਲੁਇਡ +Name[te]=ఫ్లూయిడ్ +Comment=An Imlib2 based window manager +Comment[af]='n Imlib2 gebaseerde venster bestuurder +Comment[ar]=مدير نوافذ مبني على Imlib2 +Comment[be]=Кіраўнік вокнаў, заснаваны на Imlib2 +Comment[bn]=Imlib2 ভিত্তিক উইণ্ডো ম্যানেজার +Comment[bs]=Window manager baziran na Imlib2 +Comment[ca]=Un gestor de finestres basta en Imlib2 +Comment[cs]=Správce oken založený na Imlib2 +Comment[csb]=Menedżer òknów òpiarti na Imlib2 +Comment[cy]=Trefnydd ffenestri wedi'i seilio ar lmlib2 +Comment[da]=En Imlib2 baseret vindueshåndtering +Comment[de]=Imlib2-basierter Fenstermanager +Comment[el]=Ένας διαχειριστής παραθύρων βασισμένος στην imlib2 +Comment[eo]=Fenestroadministrilo +Comment[es]=Un gestor de ventanas basado en Imlib2 +Comment[et]=Aknahaldur, mille aluseks on Imlib2 +Comment[eu]=Imlib2-n oinarritutako leiho kudeatzailea +Comment[fa]=یک Imlib2 بر اساس مدیر پنجره +Comment[fi]=Imlib2-pohjainen ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres fondé sur Imlib2 +Comment[fy]=In op imlib2 basearre finstersmanager +Comment[ga]=Bainisteoir fuinneoga bunaithe ar Imlib2 +Comment[gl]=Un xestor de fiestras baseado en Imlib2 +Comment[he]=מנהל חלונות מבוסס Imlib2 +Comment[hi]=आईएमलिब2 आधारित विंडो प्रबंधक +Comment[hr]=Upravitelj prozora zasnovan na Imlib2 +Comment[hu]=Egy Imlib2-alapú ablakkezelő +Comment[is]=Gluggastjóri sem notar Imlib2 +Comment[it]=Un window manager basato su Imlib2 +Comment[ja]=Imlib2ベースのウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი imlib2 ის ბაზაზე +Comment[kk]=Imlib2-негіздеген терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ផ្អែក​លើ Imlib2 +Comment[ko]=Imlib2 기반 창 관리자 +Comment[lt]=Langų tvarkyklė, paremta Imlib2 +Comment[lv]=Imlib 2 bāzēts logu menedžeris +Comment[mk]=Менаџер на прозорци базиран на Imlib2 +Comment[mn]=Imlib2 дээр суурилсан цонхны удирдагч +Comment[ms]=Pengurus tetingkap berasaskan lmlib2 +Comment[mt]=Window manager ibbażat fuq Imlib2 +Comment[nb]=En vindusbehandler basert på Imlib2 +Comment[nds]=En Finsterpleger opbuut op Imlib2 +Comment[ne]=Imlib2 मा आधारित सञ्झ्याल प्रबन्धक +Comment[nl]=Een op imlib2 gebaseerde windowmanager +Comment[nn]=Ein vindaugssjef basert på Imlib2 +Comment[pa]=ਇੱਕ Imlib2 ਆਧਾਰਿਤ ਫਾਇਲ਼ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien oparty na Imlib2 +Comment[pt]=Um gestor de janelas baseado na Imlib2 +Comment[pt_BR]=Um gerenciador de janelas baseado na lmlib2 +Comment[ro]=Un manager de ferestre bazat pe Imlib2 +Comment[ru]=Оконный менеджер на основе imlib2 +Comment[rw]=Mugenga dirishya ishingiye kuri Imlib2 +Comment[se]=Imlib2-vuođđoduvvon lásegieđahalli +Comment[sk]=Správca okien založený na imlib2 +Comment[sl]=Okenski upravitelj na osnovi lmlib2 +Comment[sr]=Менаџер прозора заснован на Imlib2 +Comment[sr@Latn]=Menadžer prozora zasnovan na Imlib2 +Comment[sv]=Imlib2-baserad fönsterhanterare +Comment[ta]=சாளர மேலாளர் அடிப்படையிலான ஒரு Imlib2 +Comment[te]=ఐఎంలిబ్2 ఆధారిత విండొ అభికర్త +Comment[tg]=Imlib2 ба асосимудири тиреза +Comment[th]=ระบบจัดการหน้าต่างที่สร้างบน Imlib2 +Comment[tr]=Imlib2 tabanlı bir pencere yöneticisi +Comment[tt]=Imlib2 asılında täräzä-idäräçe +Comment[uk]=Менеджер вікон, заснований на Imlib2 +Comment[uz]=Imlib2 asosida yaratilgan oyna boshqaruvchi +Comment[uz@cyrillic]=Imlib2 асосида яратилган ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ dựa trên lmlib2 +Comment[wa]=On manaedjeu di purneas båzé so lmlib2 +Comment[zh_CN]=基于 Imlib2 的窗口管理器 +Comment[zh_TW]=一個基於 Imlib2 的視窗管理程式 diff --git a/tdm/kfrontend/sessions/pwm.desktop b/tdm/kfrontend/sessions/pwm.desktop new file mode 100644 index 000000000..5d967c0c0 --- /dev/null +++ b/tdm/kfrontend/sessions/pwm.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=XSession +Exec=pwm1 +TryExec=pwm1 +Name=PWM +Name[eo]=UnuFA +Name[hi]=पीडबल्यूएम +Name[te]=పి డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง PWM +Comment=A lightweight window manager able to attach multiple windows to one frame +Comment[af]='n Lig gewig venster bestuurder wat veelvuldige vensters aan een raam kan koppel +Comment[ar]=مدير نوافذ خفيف العبء قابل لربط عدة نوافذ إلى إطار واحد +Comment[be]=Лёгкі кіраўнік вокнаў, які можа далучаць некалькі вокнаў да аднаго фрэйма +Comment[bn]=একটি হাল্কা উইণ্ডো ম্যানেজার, যাতে একটি ফ্রেমে একাধিক উইণ্ডো সংযুক্ত করা সম্ভব +Comment[bs]=Lagani window manager koji može prikačiti više prozora na jedan okvir +Comment[ca]=Un lleuger gestor de finestres capaç d'aplegar múltiples finestres en un marc +Comment[csb]=Menedżer òknów ò môłëch żądaniach, rozmiejący doczepic wiele òknów do jedny ramë +Comment[cy]=Trefnydd ffenestri ysgafn sy'n gallu atodi mwy nag un ffenestr at un ffrâm +Comment[da]=En letvægts vindueshåndtering der kan knytte flere vinduer til én ramme +Comment[de]=Schlanker Fenstermanager, der mehrere Fenster an einen Rahmen andocken kann +Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων με δυνατότητα να προσαρτά πολλαπλά παράθυρα σε ένα πλαίσιο +Comment[eo]=Fenestroadministrilo, kiu faras unun fenestron el kelkaj +Comment[es]=Un gestor de ventanas ligero capaz de conectar varias ventanas a un mismo marco +Comment[et]=Imeväike aknahaldur, mis suudab mitu akent ühe raami külge haakida +Comment[eu]=Hainbat leiho marko bakarrean uztar ditzakeen leiho kudeatzaile arina +Comment[fa]=مدیر پنجرۀ سبک قادر به پیوست پنجره‌های چندگانه در یک قابک +Comment[fi]=Kevyt ikkunaohjelma, joka osaa liittää useita ikkunoita yhteen kehykseen +Comment[fr]=Un gestionnaire de fenêtres léger capable d'attacher plusieurs fenêtres à un même cadre +Comment[fy]=In lichtgewicht finstersmanager, hokker meardere finsters kin ferbine mei in kader +Comment[gl]=Un xestor de fiestras lixeiro capaz de adxuntar varias fiestras nun marco +Comment[he]=מנהל חלונות קל המסוגל לחבר חלונות רבים למסגרת אחת +Comment[hi]=एक हल्का विंडो प्रबंधक जिसके एक फ़रमा में अनेक विंडो जोड़े जा सकते हैं +Comment[hr]=Lagani upravitelj prozora koji jednom okviru može pridodati više prozora +Comment[hu]=Alacsony erőforrásigényű ablakkezelő, több ablakot képes egy kerethez rendelni +Comment[is]=Léttur gluggastjóri sem getur tengt marga glugga við einn ramma +Comment[it]=Un window manager leggero in grado di attaccare più finestre ad una cornice +Comment[ja]=複数のウィンドウ枠を設定可能な軽量なウィンドウマネージャ +Comment[ka]=მსუბუქი ფანჯრის მენეჯერი, რომელსაც შეუძლია ბევრი ფანჯრის ერთ ჩარჩოში ჩასმა +Comment[kk]=Жеңіл, бір коршауда бірнеше терезелерді біріктірелетін, терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​សមត្ថភាព​ខ្សោយ អាច​ភ្ជាប់​បង្អួច​ច្រើន​ទៅ​ស៊ុម​មួយ +Comment[lt]=Nedaug resursų reikalaujanti langų tvarkyklė, galinti prijungti daug langų prie vieno rėmo +Comment[lv]=Viegls logu menedžeris ar iespēju pievienot vairākus logus vienam kadram +Comment[mk]=Лесен менаџер на прозорци кој може да прикачи повеќе прозорци на една рамка +Comment[ms]=Pengurus tetingkap ringan yang boleh melekapkan berbilang tetingkap pada satu bingkai +Comment[mt]=Window manager ħafif li jista' jgħaqqad iżjed minn window waħda fl-istess gwarniċ +Comment[nb]=En lettvekts vindusbehandler som kan koble flere vinduer til én ramme +Comment[nds]=En ranke Finsterpleger, de mennige Finstern an een Rahmen andocken kann +Comment[ne]=एक हल्का वजन सञ्झ्याल प्रबन्धकले बहुभागिय सञ्झ्यालहरूलाई एक फ्रेममा सङ्लग्न गर्न सक्छ +Comment[nl]=Een lichtgewicht windowmanager, welke meerdere vensters kan verbinden met een frame +Comment[nn]=Ein lett vindaugssjef som kan kopla fleire vindauge til den same ramma +Comment[pa]=ਇੱਕ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਜੋ ਕਿ ਕਈ ਝਰੋਖਿਆਂ ਨੂੰ ਇੱਕ ਫਰੇਮ ਵਿੱਚ ਰੱਖ ਸਕਦਾ ਹੈ +Comment[pl]=Menedżer okien o małych wymaganiach, potrafiący doczepić wiele okien do jednego obramowania +Comment[pt]=Um gestor de janelas leve, com a possibilidade de anexar várias janelas a uma área +Comment[pt_BR]=Um gerenciador de janelas leve, capaz de anexar múltiplas janelas em um quadro +Comment[ro]=Un manager de ferestre minimal capabil să atașeze multe ferestre la un singur cadru +Comment[ru]=Лёгкий оконный менеджер, способный объединить несколько окон в одной рамке +Comment[rw]=Mugenga dirishya yoroshye ishobora gufatishya amadirishya menshi ku ikadiri imwe. +Comment[se]=Geahpes lásegieđahalli mii sáhttá ovttastahttit máŋga láse seamma rámmii. +Comment[sk]=Nenáročný správca okien schopný spojiť viac okien do jednoho rámca +Comment[sl]=Lahek okenski upravitelj, ki lahko pripne več oken na en okvir +Comment[sr]=Лагани менаџер прозора способан да прикачи више прозора за један оквир +Comment[sr@Latn]=Lagani menadžer prozora sposoban da prikači više prozora za jedan okvir +Comment[sv]=Lättviktig fönsterhanterare som kan ansluta flera fönster till en ram +Comment[ta]=குறைந்த கனமுள்ள பல சாளரங்களை இணைக்க முடிந்த ஒற்றை சாளர மேலாளர் +Comment[th]=ระบบจัดการหน้าต่างขนาดเบา มีความสามารถในการปะติดหลายๆหน้าต่างลงใน 1 กรอบ +Comment[tr]=Düşük ağırlıklı bir çok pencereyi bir çerçeveye toplayabilen bir pencere yöneticisi +Comment[tt]=Ber qısa eçendä berniçä täräzä totaştırala torğan täräzä-idäräçe +Comment[uk]=Простий менеджер вікон, що дозволяє долучати декілька вікон до однієї рамки +Comment[vi]=Trình quản lý cửa sổ nhỏ gọn, có thể gắn nhiều cửa sổ vào một khung +Comment[wa]=On ledjir manaedjeu di purneas ki pout ataetchî sacwants purneas so-z on cåde +Comment[zh_CN]=轻量级窗口管理器,可将多个窗口附加到一个框架中 +Comment[zh_TW]=一個輕量化且可以將多個視窗結合在一起的視窗管理程式 diff --git a/tdm/kfrontend/sessions/qvwm.desktop b/tdm/kfrontend/sessions/qvwm.desktop new file mode 100644 index 000000000..922e3e0bd --- /dev/null +++ b/tdm/kfrontend/sessions/qvwm.desktop @@ -0,0 +1,80 @@ +[Desktop Entry] +Type=XSession +Exec=qvwm +TryExec=qvwm +Name=QVWM +Name[eo]=QVFA +Name[hi]=क्यूवीडबल्यूएम +Name[te]=క్యు వి డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง QVWM +Comment=A Windows 95 like window manager +Comment[af]='n Venster bestuurder wat soos Windows 95 lyk +Comment[ar]=مدير نوافذ شبيه بويندوز 95 +Comment[be]=Кіраўнік вокнаў, падобны на Windows 95 +Comment[bn]=Windows 95-এর অনুরূপ একটি উইণ্ডো ম্যানেজার +Comment[bs]=Window manager nalik na Windows 95 +Comment[ca]=Un gestor de finestres com el Windows 95 +Comment[cs]=Správce oken se vzhledem Windows 95 +Comment[csb]=Menedżer òknów o wëzdrzatkù szlachùjącym za Windows 95 +Comment[cy]=Trefnydd Ffenestri sy'n debyg i Windows95 +Comment[da]=En Windows 95-lignende vindueshåndtering +Comment[de]=Fenstermanager im Stil von Windows 95 +Comment[el]=Ένας διαχειριστής παραθύρων παρόμοιος με τα Windows 95 +Comment[eo]=Fenestroadministrilo kiel Vindozo 95 +Comment[es]=Un gestor de ventanas similar a Windows 95 +Comment[et]=Aknahaldur, mis näeb välja nagu Windows 95 +Comment[eu]=Windows 95en itxura duen leiho kudeatzailea +Comment[fa]=یک مدیر پنجره شبیه ویندوز ۹۵ +Comment[fi]=Windows 95:n tyylinen ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres semblable à Windows 95 +Comment[fy]=In Win95-likens finstersmanager +Comment[ga]=Bainisteoir fuinneoga cosúil le Windows 95 +Comment[gl]=Un xestor de fiestras como o de Windows 95 +Comment[he]=מנהל חלונות הדומה לחלונות 95 +Comment[hi]=विंडोज़ 95 जैसा विंडो प्रबंधक +Comment[hr]=Upravitelj prozora nalik na Windows 95 +Comment[hu]=Egy Windows 95-szerű ablakkezelő +Comment[is]=Gluggastjóri sem líkist Windows 95 +Comment[it]=Un window manager in stile Windows 95 +Comment[ja]=Windows95 風のウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი Windows 95-ს სტილში +Comment[kk]=Windows 95 секілді терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ស្រដៀង Windows 95 +Comment[ko]=윈도 95를 닮은 창 관리자 +Comment[lt]=Langų tvarkyklė, primenanti Windows 95 +Comment[lv]=Windows 95 līdzīgs logu menedžeris +Comment[mk]=Менаџер на прозорци со изглед на Windows 95 +Comment[mn]=Виндовс 95 шиг цонхны удирдагч +Comment[ms]=Pengurus tetingkap seperti Windows 95 +Comment[mt]=Window manager jixbaħ lil Windows95 +Comment[nb]=En vindusbehandler som likner Windows 95 +Comment[nds]=En Finsterpleger liek to Windows 95 +Comment[ne]=विण्डोज ९५ जस्तो सञ्झ्याल प्रबन्धक +Comment[nl]=Een Win95-achtige windowmanager +Comment[nn]=Ein vindaugssjef som liknar Windows 95 +Comment[pa]=ਇੱਕ ਵਿੰਡੋ 95 ਵਰਗਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien o wyglądzie podobnym do Windows 95 +Comment[pt]=Um gestor de janelas com o visual do Windows 95 +Comment[pt_BR]=Um gerenciador de janelas parecido com o Windows 95 +Comment[ro]=Un manager de ferestre cu aspect de Windows 95 +Comment[ru]=Оконный менеджер в стиле Windows 95 +Comment[rw]=Windows 95 nka mugenga dirishya +Comment[se]=Windows95-lágan lásegieđahalli +Comment[sk]=Správca okien podobný Windows 95 +Comment[sl]=Okenski upravitelj, podoben Windows 95 +Comment[sr]=Менаџер прозора налик на Windows 95 +Comment[sr@Latn]=Menadžer prozora nalik na Windows 95 +Comment[sv]=Fönsterhanterare som liknar Windows 95 +Comment[ta]=சாளர மேலாளர் போன்ற விண்டோஸ் 95 +Comment[te]=విండొస్ 95 లాంటి విండొ అభికర్త +Comment[tg]=Windows 95 монанди мудири тиреза +Comment[th]=ระบบจัดการหน้าต่างที่ดูคล้ายวินโดวส์ 95 +Comment[tr]=Windows 95 benzeri bir pencere yöneticisi +Comment[tt]=Windows 95 kebek täräzä-idäräçe +Comment[uk]=Менеджер вікон на кшталт Windows95 +Comment[uz]=Win95'ga oʻxshagan oyna boshqaruvchi +Comment[uz@cyrillic]=Win95'га ўхшаган ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ giống Windows 95 +Comment[wa]=On manaedjeu di purneas rishonnant a Windows 95 +Comment[zh_CN]=类似 Windows 95 的窗口管理器 +Comment[zh_TW]=一個像 Win95 的視窗管理程式 diff --git a/tdm/kfrontend/sessions/ratpoison.desktop b/tdm/kfrontend/sessions/ratpoison.desktop new file mode 100644 index 000000000..1127db151 --- /dev/null +++ b/tdm/kfrontend/sessions/ratpoison.desktop @@ -0,0 +1,82 @@ +[Desktop Entry] +Type=XSession +Exec=ratpoison +TryExec=ratpoison +Name=Ratpoison +Name[bn]=র‌্যাট-পয়সন +Name[cy]=Gwenwynllygodmawr (Ratpoison) +Name[eo]=Raticido +Name[fa]=مرگ موش +Name[hi]=रैट-पॉइज़न +Name[ne]=र्याटपोइजन +Name[pa]=ਰਾਟਪੋਈਸਾਨ +Name[rw]=UburoziImbeba +Name[sv]=Råttgift +Name[ta]=ராட் பாய்சன் +Name[te]=ఎలుకలమందు +Name[vi]=Bả chuột +Name[wa]=Pwezon po les rats (Ratpoison) +Comment=A simple keyboard-only window manager modeled after Screen +Comment[af]='n Eenvoudige venster bestuurder wat net met die sleutel bord werk en op Screen gemoduleer is. +Comment[ar]=مدير نوافذ بسيط يستخدم لوحة المفاتيح فقط صنع مشابهاً لـScreen +Comment[be]=Просты кіраўнік вокнаў, працуе толькі з клавіятурай +Comment[bn]=একটি সরল কীবোর্ড-ভিত্তিক উইণ্ডো ম্যানেজার, Screen-এর আদর্শে তৈরি +Comment[bs]=Jednostavan windows manager samo za tastaturu, modeliran po uzoru na Screen +Comment[ca]=Un gestor de finestres simple de sols teclat modelat després de Screen +Comment[csb]=Prosti menedżer òknów òbsłùgiwôny blós z klawiaturë, szlachùje za programą screen +Comment[cy]=Trefnydd ffenestri syml sy'n defnyddio'r allweddell yn unig, wedi'i arddullio ar Sgrîn (Screen) +Comment[da]=En simpel kun-tastatur vindueshåndtering modeleret efter Screen +Comment[de]=Einfacher Fenstermanager, der nur über die Tastatur bedient wird und Screen nachgebildet ist +Comment[el]=Ένας απλός, μονό για πληκτρολόγιο, διαχειριστής παραθύρων σχεδιασμένος με βάση το Screen +Comment[en_GB]=A simple keyboard-only window manager modelled after Screen +Comment[eo]=Fenestroadministrilo por klaviaro +Comment[es]=Un gestor de ventanas sólo para teclado realizado a partir de Screen +Comment[et]=Lihtne ainult klaviatuuri abil kasutatav aknahaldur, mille eeskujuks on Screen +Comment[eu]=Screen-en oinarriturik egindako leiho kudeatzailea, teklatu hutsez erabiltzekoa +Comment[fa]=یک مدیر پنجره فقط صفحه کلید سادۀ مدل‌یافته پس از پرده +Comment[fi]=Yksinkertainen, vain näppäimistöltä käytettävä ikkunamanageri, screen-ohjelman tyyliin +Comment[fr]=Un gestionnaire de fenêtres simple uniquement dirigeable au clavier et fondé sur Screen +Comment[fy]=In ienfâldige finstersmanager dy allinnich mei it toetseboerd te betsjinnen is, ynspiraasje troch Screen +Comment[gl]=Un xestor de fiestras de manexo co teclado modelado despois de Screen +Comment[he]=מנהל חלונות פשוט למקלדת בלבד המעוצב בסגנון Screen +Comment[hi]=आफ्टर स्क्रीन आधारित साधारण विंडो प्रबंधक जो सिर्फ कुंजीपट के लिए है +Comment[hr]=Jednostavan, samo za tipkovnicu, upravitelj prozora napravljen prema Screenu +Comment[hu]=Egyszerű, csak billentyűzetről vezérelhető ablakkezelő (a Screen alapján) +Comment[is]=Einfaldur gluggastjóri sem notar eingöngu lyklaborðið hannaður eftir Screen forritinu +Comment[it]=Un window manager semplice solo-tastiera pensato come Screen +Comment[ja]=Screen をもとに作られた、キーボードインターフェースのみのウィンドウマネージャ +Comment[ka]=მარტივი კლაიატურით მართვადი ფანჯრის მმართველი +Comment[kk]=Screen үлгідегі, тек перенетақтадан басқарылатын, қарапайым терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​សាមញ្ញ​ប្រើ​តែ​ក្ដារចុច ដែល​យក​គំរូ​តាម​អេក្រង់ +Comment[lt]=Paprasta, tik klaviatūra valdoma langų tvarkyklė, panaši į Screen +Comment[lv]=Vienkāršs tikai tastatūras logu menedžeris, līdzīgs Screen +Comment[mk]=Едноставен менаџер на прозорци кој работи само со тастатура, моделиран според Screen +Comment[ms]=Pengurus tetingkap hanya papan kekunci ringkas dimodelkan seperti Skrin +Comment[mt]=Window manager għal tastieri biss immudellat fuq Screen +Comment[nb]=En enkel tastaturbasert vindusbehandler, etter forbilde av Screen +Comment[nds]=En eenfache Finsterpleger, de bloots mit de Tastatuur bruukt warrt. Screen weer dat Modell dorför +Comment[ne]=पर्दा पछाडि सञ्झ्याल प्रबन्धक मात्र नमूना बनाउने साधारण कुञ्जीपाटी +Comment[nl]=Een eenvoudige windowmanager die alleen met het toetsenbord te bedienen is, geïnspireerd door Screen +Comment[nn]=Ein enkel tastaturbasert vindaugssjef, med Screen som førebilete +Comment[pa]=ਪਰਦੇ ਮੈਡੀਊਲ ਬਾਅਦ ਸਿਰਫ ਕੀ-ਬੋਰਡ ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Prosty menedżer okien obsługiwany wyłącznie za pomocą klawiatury, stworzony na podobieństwo programu screen +Comment[pt]=Um gestor de janelas simples, só para o teclado e modelado sobre o Screen +Comment[pt_BR]=Um simples gerenciador de janelas baseado somente em teclado, modelado após a tela +Comment[ro]=Un manager de ferestre manipulat din tastatură, modelat după Screen +Comment[ru]=Простой клавиатурный оконный менеджер, моделирующий Screen +Comment[rw]=Mugenga dirishya ya mwandikisho-gusa yoroheje itunganyijwe nyuma ya Mugaragaza +Comment[se]=Oktageardánis, boallobeavdestivrejuvvon lásegieđahalli, mas lea Screen ovdagovvan +Comment[sk]=Jednoduchý správca okien ovládaný iba klávesami podľa programu Screen +Comment[sl]=Preprost okenski uporavljalnik na osnovi Screen, upravlja se samo s tipkovnico +Comment[sr]=Једноставан, само за тастатуру менаџер прозора, направљен према Screen-у +Comment[sr@Latn]=Jednostavan, samo za tastaturu menadžer prozora, napravljen prema Screen-u +Comment[sv]=Enkel fönsterhanterare bara för tangentbord modellerad efter Screen +Comment[ta]=சாளரமொன்றில் நிழல் ஏறுகிறது +Comment[th]=ตัวจัดการหน้าต่างแบบเรียบง่าย ใช้แป้นพิมพ์ควบคุมได้อย่างเดียว ถูกสร้างขึ้นมาตามหลัง Screen +Comment[tr]=Screen'den sonra modellenmiş salt klavye basit pencere yöneticisi +Comment[tt]=Töylekle genä ciñel täräzä-idäräçe +Comment[uk]=Простий менеджер вікон, розроблений на базі Screen, з підтримкою тільки клавіатури +Comment[vi]=Trình quản lý cửa sổ chỉ dùng bàn phím, dựa theo Screen +Comment[wa]=On simpe manaedjeu di purneas eployant fok li taprece, båzé so ls idêyes da «Screen» +Comment[zh_CN]=Screen 后又一只支持键盘的窗口管理器 +Comment[zh_TW]=一個簡易、只支援鍵盤的視窗管理程式 diff --git a/tdm/kfrontend/sessions/sapphire.desktop b/tdm/kfrontend/sessions/sapphire.desktop new file mode 100644 index 000000000..5cdd998d7 --- /dev/null +++ b/tdm/kfrontend/sessions/sapphire.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +Type=XSession +Exec=sapphire +TryExec=sapphire +Name=Sapphire +Name[bn]=স্যাফায়ার +Name[eo]=Safiro +Name[fa]=ياقوت كبود +Name[hi]=सेफायर +Name[ka]=საფირონი +Name[ne]=नीलमणि +Name[pa]=ਸਾਪਰਫੀਰੀ +Name[ru]=Сапфир +Name[ta]=சபையர் +Name[te]=ఇంద్రనీలం +Name[tg]=Ёқути кабуд +Comment=A minimal but configurable window manager +Comment[af]='n Minimalistiese venster bestuurder, wat nogsteeds opstel funksionaliteit bevat. +Comment[ar]=مدير نوافذ مصغّر ولكن قابل للإعداد +Comment[be]=Мінімалістычны кіраўнік вокнаў з магчымасцю настаўлення +Comment[bn]=পরিমিত কিন্তু থীমযুক্ত উইণ্ডো ম্যানেজার +Comment[bs]=Minimalan ali podesiv window manager +Comment[ca]=Un minimalista però configurable gestor de finestres +Comment[cs]=Minimalistický, ale přizpůsobitelný správce oken +Comment[csb]=Prosti menedżer òknów, równak z mòżnotą kònfigùracëji +Comment[cy]=Trefnydd ffenestri lleiafol a ffurfweddir +Comment[da]=En minimal men indstillelig vindueshåndtering +Comment[de]=Minimalistischer, aber anpassbarer Fenstermanager +Comment[el]=Ένας μικρός αλλά παραμετροποιήσιμος διαχειριστής παραθύρων +Comment[eo]=Fenestroadministrilo +Comment[es]=Un gestor de ventanas minimalista pero configurable +Comment[et]=Väga väike, kuid seadistatav aknahaldur +Comment[eu]=Leiho kudeatzaile minimal baina konfiguragarria +Comment[fa]=یک مدیر پنجرۀ کمینه، اما قابل پیکربندی +Comment[fi]=Minimaalinen, mutta muokattavissa oleva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres minimaliste mais configurable +Comment[fy]=In minimale mar ynstelbere finstersmanager +Comment[gl]=Un xestor de fiestras mínimo pero configurábel +Comment[he]=מנהל חלונות מינימלי אך ניתן להגדרה +Comment[hi]=एक अल्पतम परंतु कॉन्फ़िगर योग्य विंडो प्रबंधक +Comment[hr]=Minimalan, ali podesiv upravitelj prozora +Comment[hu]=Egyszerű, de jól konfigurálható ablakkezelő +Comment[is]=Einfaldur en stillanlegur gluggastjóri +Comment[it]=Un window manager minimale ma configurabile +Comment[ja]=各種設定が可能な小さなウィンドウマネージャ +Comment[ka]=მინიმალური მაგრამ კონფიგურირებადი ფანჯრის მენეჯერი +Comment[kk]=Шағын, баптауы бар, терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​តូច តែ​អាច​កំណត់​រចនាសម្ព័ន្ធ​បាន +Comment[ko]=설정 가능한 최소한의 창 관리자 +Comment[lt]=Minimalistinė tačiau konfigūruojama langų tvarkyklė +Comment[lv]=Minimālistisks, bet konfigurējams logu menedžeris +Comment[mk]=Минимален но конфигурабилен менаџер на прозорци +Comment[mn]=Маш жижиг тохируулах боломжгүй цонх удирдагч +Comment[ms]=Pengurus tetingkap minimum tetapi boleh konfigur +Comment[mt]=Window manager minimu imma konfigurabbli +Comment[nb]=En minimal vindusbehandler, men med innstillinger +Comment[nds]=En minimaal, man instellbor Finsterpleger +Comment[ne]=सानो तर कन्फिगर गर्न सकिने सञ्झ्याल प्रबन्धक +Comment[nl]=Een minimale maar instelbare windowmanager +Comment[nn]=Ein minimal vindaugssjef, men med innstillingar +Comment[pa]=ਇੱਕ ਨਿਊਨਤਮ, ਪਰ ਸੋਧਯੋਗ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Prosty menedżer okien, ale z możliwością konfiguracji +Comment[pt]=Um gestor de janelas configurável mas mínimo +Comment[pt_BR]=Um gerenciador de janelas mínimo, mas configurável +Comment[ro]=Un manager de ferestre minimal, dar configurabil +Comment[ru]=Минимальный, но настраиваемый оконный менеджер +Comment[rw]=Ntoya ariko mugenga dirishya ibonezwa +Comment[se]=Unna, muhto heivehahtti lásegieđahalli +Comment[sk]=Minimálny, ale nastaviteľný správca okien +Comment[sl]=Skromen, a nastavljiv okenski upravitelj +Comment[sr]=Минимални, али подесиви менаџер прозора +Comment[sr@Latn]=Minimalni, ali podesivi menadžer prozora +Comment[sv]=Minimal men anpassningsbar fönsterhanterare +Comment[ta]=சாளர மேலாளரின் மேம்பட்ட திறன்களை வடிவமைக்கலாம் +Comment[th]=ระบบจัดการหน้าต่างขนาดเล็ก แต่สามารถปรับแต่งได้ +Comment[tr]=Küçük, ancak kolayca özelleştirilebilir bir pencere yöneticisi +Comment[tt]=Ciñel bulsa da, köylänä torğan täräzä-idäräçe +Comment[uk]=Мінімальний менеджер вікон з можливістю налаштування +Comment[uz]=Oddiy, ammo moslab boʻladigan oyna boshqaruvchi +Comment[uz@cyrillic]=Оддий, аммо мослаб бўладиган ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ tối thiểu, nhưng có thể cấu hình được +Comment[wa]=On ptit, nén apontiåve, manaedjeu di purnea +Comment[zh_CN]=很小却可配置的窗口管理器 +Comment[zh_TW]=一個小但可組態的視窗管理程式 diff --git a/tdm/kfrontend/sessions/sawfish.desktop b/tdm/kfrontend/sessions/sawfish.desktop new file mode 100644 index 000000000..668620fff --- /dev/null +++ b/tdm/kfrontend/sessions/sawfish.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Type=XSession +Exec=sawfish +TryExec=sawfish +Name=Sawfish +Name[bn]=স-ফিশ +Name[eo]=Segfiŝo +Name[fa]=اره‌ماهی +Name[hi]=सा-फिश +Name[ne]=सफीस +Name[pa]=ਸ਼ਾਅਫਿਸ਼ +Name[te]=సాఫిష్ +Comment=An extensible window manager scriptable with an Emacs Lisp-like language +Comment[af]='n Uitbreibare venster bestuurder met 'n ingeboude skrip taal wat soos Emacs List lyk. +Comment[ar]=مدير نوافذ قابل للتوسعة يمكن بشفيره بلغة إيماكس ليسب +Comment[be]=Кіраўнік вокнаў з магчымасцю пашырэння сцэнарамі на мове, падобнай на Emacs Lisp +Comment[bs]=Proširiv window manager sa podškom za skriptiranje u jeziku sličnom Emacs Lisp-u +Comment[ca]=Un extensible gestor de finestres mitjançant scripts amb una aparença com el Lisp de Emacs +Comment[cs]=Rožšiřitelný správce oken skriptovatelný jazykem podobným jazyku Emacs Lisp +Comment[csb]=Menedżer òknów, jaczi je mòżno rozbùdowac dzãka skriptom w jãzëkù szlachùjącym za Emacs Lisp +Comment[cy]=Trefnydd ffenestri estynadwy a all ei sgriptio efo iaith sy'n debyg i Emacs Lisp +Comment[da]=En udvidelig vindueshåndtering der kan scriptes med et Emacs Lisp-lignende sprog +Comment[de]=Erweiterbarer Fenstermanager, der über Skripts ähnlich Emacs-Lisp gesteuert werden kann +Comment[el]=Ένας επεκτάσιμος διαχειριστής παραθύρων παραμετροποιήσιμος με μια γλώσσα παρόμοια με την Emacs Lisp +Comment[eo]=Fenestroadministrilo, kiu uzas Lispon por esti programata +Comment[es]=Un gestor de ventanas extensible con guiones escritos en un lenguaje similar a Lisp de Emacs +Comment[et]=Laiendatav aknahaldur, mis kasutab Emacs Lispi keele moodi skripte +Comment[eu]=Emacs Lisp bezalako hizkuntza batez idatziriko scripten bidez heda daitekeen leiho kudeatzailea +Comment[fa]=مدیر پنجرۀ توسعه‌پذیر دست‌نوشته‌ای با یک زبان شبیه Emacs Lisp +Comment[fi]=Laajennettavissa oleva ikkunaohjelma, johon voi luoda komentosarjoja Emacs lispin tyylisellä kielellä +Comment[fr]=Un gestionnaire de fenêtres extensible, à l'aide scripts dans un langage semblable au Lisp d'Emacs +Comment[fy]=In útbreidbere finstersmanager, skriptber fia in Emacs Lisp-likene taal +Comment[gl]=Un xestor de fiestras extensíbel e configurábel con scripts en linguaxe Emacs Lisp +Comment[he]=מנהל חלונות מקיף הניתן לתכנות עם שפה דמוית Emacs Lisp +Comment[hi]=ई-मेक्स लिस्प जैसे भाषा में स्क्रिप्ट किया जा सकने लायक विंडो प्रबंधक जिसे विस्तार दिया जा सकता है +Comment[hr]=Proširivi upravitelj prozora pisan u skripti nalik na jezik Emacs Lisp +Comment[hu]=Egy könnyen tovább bővíthető ablakkezelő, egy Emacs Lisp-szerű nyelvvel szkriptelhető +Comment[is]=Viðbætanlegur gluggastjóri sem er skriftanlegur á Emacs Lisp líku máli +Comment[it]=Un window manager estensibile per cui è possibile fare script in un linguaggio simile all'Emacs lisp +Comment[ja]=Emacs Lisp 言語スクリプトで機能拡張可能なウィンドウマネージャ +Comment[ka]=Lisp სკრიპტებით გაფათოვებადი Emacs ის მაგვარი ფანჯრის მენეჯერი +Comment[kk]=Emacs Lisp-секілді тілдегі скриптті қолданып, кеңейтілетін терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​អាច​ពង្រីក​បាន ហើយ​អាច​សរសេរ​ស្គ្រីប​ជាមួយ​ភាសា​ដែល​ដូច Emacs Lisp +Comment[lt]=Langų tvarkyklė, kurią galima išplėsti Emacs Lisp primenančia programavimo kalba +Comment[lv]=Paplašināms logu menedžeris ar Emacs Lisp līdzīgas valodas atbalstu +Comment[mk]=Екстензивен менаџер на прозорци кој може да се скриптира со јазик како Emacs Lisp +Comment[ms]=Pengurus tetingkap boleh kembang dan boleh diskrip dengan bahasa seperti Emacs Lisp +Comment[mt]=Window manager li jista' jiġi estiż, b'lingwa tixbaħ lil Emacs Lisp +Comment[nb]=En utvidbar vindusbehandler som kan skriptes med et språk som likner Emacs Lisp. +Comment[nds]=En verwiederbor Finsterpleger, de över en Skriptspraak liek to Emacs-Lisp stüert warrn kann +Comment[ne]=इमाक्स लिस्प जस्तो भाषसँग स्क्रिप्ट गर्न सकिने एउटा विस्तारयोग्य सञ्झ्याल प्रबन्धक +Comment[nl]=Een uitbreidbare windowmanager, scriptbaar via een Emacs Lisp-achtige taal +Comment[nn]=Ein utvidbar vindaugssjef som kan skriptast med eit språk som liknar Emacs Lisp +Comment[pa]= Emacs Lisp-ਵਰਗੀ ਭਾਸ਼ਾ ਸਕ੍ਰਿਪਟਯੋਗ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien, który można rozszerzać za pomocą skrytów w języku podobnym do Emacs Lisp +Comment[pt]=Um gestor de janelas extensível e programável com uma linguagem semelhante ao Emacs Lisp +Comment[pt_BR]=um gerenciador de janelas extensível, baseado em scripts, com uma linguagem parecida com o Lisp do Emacs +Comment[ro]=Un manager de ferestre extensibil scriptabil cu un limbaj similar cu Emacs Lisp +Comment[ru]=Расширяемый скриптами Lisp наподобие Emacs оконный менеджер +Comment[rw]=Mugenga dirishya yagurwa yandikwaho hakoreshejwe Emacs Kudedemanga-nka ururimi +Comment[sk]=Rozšíriteľný správca okien, ktorého je možné ovládať programovacím jazykom podobným Emacs Lispu +Comment[sl]=Razširljiv okenski upravitelj, ki se lahko upravlja s skripti v jeziku podobnem Emacs Lisp +Comment[sr]=Проширив менаџер прозора који се може скриптовати помоћу језика налик на Emacs-ов Lisp +Comment[sr@Latn]=Proširiv menadžer prozora koji se može skriptovati pomoću jezika nalik na Emacs-ov Lisp +Comment[sv]=Utökningsbar fönsterhanterare som kan styras med ett Emacs Lisp-liknande skriptspråk +Comment[ta]=Emacs Lisp-like மொழியுடனான விரிவாக்ககூடிய சாளர மேலாளர் எழுத்தாக்கம் +Comment[th]=ระบบจัดการหน้าต่างที่สามารถเพิ่มขยายได้ และควบคุมด้วยการเขียนสคริปต์โดยใช้ภาษาแบบ Emacs Lisp +Comment[tr]=Eklenti destekli Emacs Lisp benzeri bir kodlama dili kullanan kodlanabilir bir pencere yöneticisi +Comment[tt]=Emacs Lisp-kebek tel belän kiñäylelgän täräzä-idäräçe +Comment[uk]=Менеджер вікон, що можна розширювати мовою скриптів на кшталт Emacs Lisp +Comment[vi]=Trình quản lý cửa sổ có thể viết kịch bản được với ngôn ngữ giống Emacs Lisp +Comment[wa]=On manaedjeu d' purnea k' on pout radjouter des rawetes, apontiåve e scripes dins on lingaedje do stîle Emacs Lisp +Comment[zh_CN]=可用类似 Emacs Lisp 的语法进行编程的窗口管理器 +Comment[zh_TW]=一個可用類似 Emacs Lisp 語言延伸的視窗管理程式 diff --git a/tdm/kfrontend/sessions/tde.desktop.cmake b/tdm/kfrontend/sessions/tde.desktop.cmake new file mode 100644 index 000000000..c23a33205 --- /dev/null +++ b/tdm/kfrontend/sessions/tde.desktop.cmake @@ -0,0 +1,45 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=XSession +Exec=@TDE_BIN_DIR@/starttde +TryExec=@TDE_BIN_DIR@/starttde +Name=TDE +Name[hi]=केडीई +Name[mn]=КДЭ +Name[ta]=Kஏற்றக் காவலன் +Name[xh]=iTDE +Name[xx]=xxTDExx +Comment=The Trinity Desktop Environment. A powerful Open Source graphical desktop environment +Comment[bs]=Trinity Desktop Environment. Moćan grafički desktop otvorenog izvornog koda +Comment[ca]=L'entorn d'escriptori K. Un poderós entorn d'escriptori gràfic de Codi Font Obert +Comment[cy]=Yr Amgylchedd Penbwrdd K. Amgylchedd penbwrdd graffegol pwerus, sy'n gôd-agored. +Comment[da]=K Skrivebordsmiljøet. Et kraftigt, åbent, grafisk skrivebordsmiljø +Comment[de]=Das Trinity Desktop Environment. Eine mächtige, graphische Arbeitsumgebung und Open Source / Freie Software +Comment[el]=Το Trinity Desktop Environment. Ένα πανίσχυρο ελεύθερης προέλευσης γραφικό περιβάλλον επιφάνειας εργασίας +Comment[es]=El Entorno de Escritorio Trinity, un potente entorno de escritorio gráfico realizado de código abierto +Comment[et]=K töölaua keskkond on võimas vaba tarkvara graafiline töölaua keskkond +Comment[fi]=TDE-työpöytäympäristö (Trinity Desktop Environment) on tehokas avoimen lähdekoodin graafinen työpöytäympäristö +Comment[fr]=The Trinity Desktop Environment. Un environnement de bureau graphique, puissant et Open Source +Comment[he]=The Trinity Desktop Environment. סביבת עבודה גרפית, בעלת-עוצמה בקוד פתוח +Comment[hi]=के डेस्कटॉप वातावरण. एक शक्तिशाली, ओपन सोर्स चित्रमय डेस्कटॉप वातावरण +Comment[hu]=A TDE grafikus munkakörnyezet, egy szabad forráskódú grafikus ablakkezelő környezet +Comment[it]=L'ambiente desktop TDE. Un potente ambiente desktop grafico Open Source +Comment[mn]=The Trinity Desktop Environment. Хүчирхэг нээлттэй эх код бүхий график дэлгэцийн орчин +Comment[nb]=Trinity Desktop Environment. Et kraftig grafisk skrivebordsmiljø med åpen kildekode. +Comment[nl]=De Trinity Desktop Environment, een krachtige open source grafische desktop environment +Comment[nn]=Trinity Desktop Environment. Eit kraftig grafisk skrivebordsmiljø med open kjeldekode. +Comment[pl]=Środowisko TDE. Potężne środowisko graficzne Wolnego Oprogramowania. +Comment[pt]=O Trinity Desktop Environment. Um ambiente gráfico open source poderoso +Comment[pt_BR]=Acrônimo para Trinity Desktop Environment (ou Ambiente de Trabalho Trinity). Um poderoso ambiente de trabalho gráfico de código aberto +Comment[ro]=Trinity Desktop Environment. Un mediu grafic cu surse deschise, foarte puternic +Comment[sk]=The Trinity Desktop Environment. Výkonné, voľne šíriteľné grafické pracovné prostredie +Comment[sl]=Namizno okolje K. Zmogljivo grafično namizno okolje odprte kode +Comment[sr]=Trinity Desktop Environment (TDE). Моћно графичко радно окружење отвореног кода +Comment[sv]=Trinity-skrivbordsmiljön. En kraftfull grafisk skrivbordsmiljö med öppen källkod +Comment[ta]=Trinityமேல்மேசை சூழல். சக்திவாய்ந்த திறந்த ஆணைமூல சித்திர வகை மேல்மேசை சூழல் +Comment[tr]=TDE Masaüstü Yöneticisi. Güçlü bir grafiksel masaüstü ortamı +Comment[uk]=The Trinity Desktop Environment. Потужне графічне середовище з відкритими текстами +Comment[uz]=TDE (Trinity Desktop Environment) - кучли Open Source график иш столи муҳити +Comment[vi]=môi trường desktop Trinity, môi trường desktop đồ hoạ mã nguồn mở rất mạnh +Comment[xx]=xxThe Trinity Desktop Environment. A powerful Open Source graphical desktop environmentxx +Comment[zh_CN]=三位一体 桌面环境。强大的开放源代码图形桌面环境 diff --git a/tdm/kfrontend/sessions/tde.desktop.in b/tdm/kfrontend/sessions/tde.desktop.in new file mode 100644 index 000000000..b9472453f --- /dev/null +++ b/tdm/kfrontend/sessions/tde.desktop.in @@ -0,0 +1,45 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=XSession +Exec=@TDE_BINDIR@/starttde +TryExec=@TDE_BINDIR@/starttde +Name=Trinity +Name[hi]=केडीई +Name[mn]=КДЭ +Name[ta]=Kஏற்றக் காவலன் +Name[xh]=iTDE +Name[xx]=xxTDExx +Comment=The Trinity Desktop Environment. A powerful Open Source graphical desktop environment. +Comment[bs]=Trinity Desktop Environment. Moćan grafički desktop otvorenog izvornog koda +Comment[ca]=L'entorn d'escriptori Trinity. Un poderós entorn d'escriptori gràfic de Codi Font Obert +Comment[cy]=Yr Amgylchedd Penbwrdd Trinity. Amgylchedd penbwrdd graffegol pwerus, sy'n gôd-agored. +Comment[da]=K Skrivebordsmiljøet. Et kraftigt, åbent, grafisk skrivebordsmiljø +Comment[de]=Das Trinity Desktop Environment. Eine mächtige, graphische Arbeitsumgebung und Open Source / Freie Software +Comment[el]=Το Trinity Desktop Environment. Ένα πανίσχυρο ελεύθερης προέλευσης γραφικό περιβάλλον επιφάνειας εργασίας +Comment[es]=El Entorno de Escritorio Trinity, un potente entorno de escritorio gráfico realizado de código abierto +Comment[et]=K töölaua keskkond on võimas vaba tarkvara graafiline töölaua keskkond +Comment[fi]=TDE-työpöytäympäristö (Trinity Desktop Environment) on tehokas avoimen lähdekoodin graafinen työpöytäympäristö +Comment[fr]=The Trinity Desktop Environment. Un environnement de bureau graphique, puissant et Open Source +Comment[he]=The Trinity Desktop Environment. סביבת עבודה גרפית, בעלת-עוצמה בקוד פתוח +Comment[hi]=के डेस्कटॉप वातावरण. एक शक्तिशाली, ओपन सोर्स चित्रमय डेस्कटॉप वातावरण +Comment[hu]=A TDE grafikus munkakörnyezet, egy szabad forráskódú grafikus ablakkezelő környezet +Comment[it]=L'ambiente desktop TDE. Un potente ambiente desktop grafico Open Source +Comment[mn]=The Trinity Desktop Environment. Хүчирхэг нээлттэй эх код бүхий график дэлгэцийн орчин +Comment[nb]=Trinity Desktop Environment. Et kraftig grafisk skrivebordsmiljø med åpen kildekode. +Comment[nl]=De Trinity Desktop Environment, een krachtige open source grafische desktop environment +Comment[nn]=Trinity Desktop Environment. Eit kraftig grafisk skrivebordsmiljø med open kjeldekode. +Comment[pl]=Środowisko TDE. Potężne środowisko graficzne Wolnego Oprogramowania. +Comment[pt]=O Trinity Desktop Environment. Um ambiente gráfico open source poderoso +Comment[pt_BR]=Acrônimo para Trinity Desktop Environment (ou Ambiente de Trabalho Trinity). Um poderoso ambiente de trabalho gráfico de código aberto +Comment[ro]=Trinity Desktop Environment. Un mediu grafic cu surse deschise, foarte puternic +Comment[sk]=The Trinity Desktop Environment. Výkonné, voľne šíriteľné grafické pracovné prostredie +Comment[sl]=Namizno okolje K. Zmogljivo grafično namizno okolje odprte kode +Comment[sr]=Trinity Desktop Environment (TDE). Моћно графичко радно окружење отвореног кода +Comment[sv]=Trinity-skrivbordsmiljön. En kraftfull grafisk skrivbordsmiljö med öppen källkod +Comment[ta]= Trinityமேல்மேசை சூழல். சக்திவாய்ந்த திறந்த ஆணைமூல சித்திர வகை மேல்மேசை சூழல் +Comment[tr]=TDE Masaüstü Yöneticisi. Güçlü bir grafiksel masaüstü ortamı +Comment[uk]=The Trinity Desktop Environment. Потужне графічне середовище з відкритими текстами +Comment[uz]=TDE (Trinity Desktop Environment) - кучли Open Source график иш столи муҳити +Comment[vi]=môi trường desktop K, môi trường desktop đồ hoạ mã nguồn mở rất mạnh +Comment[xx]=xxThe Trinity Desktop Environment. A powerful Open Source graphical desktop environmentxx +Comment[zh_CN]=三位一体 桌面环境。强大的开放源代码图形桌面环境 diff --git a/tdm/kfrontend/sessions/twm.desktop b/tdm/kfrontend/sessions/twm.desktop new file mode 100644 index 000000000..894371ae9 --- /dev/null +++ b/tdm/kfrontend/sessions/twm.desktop @@ -0,0 +1,71 @@ +[Desktop Entry] +Type=XSession +Exec=twm +TryExec=twm +Name=TWM +Name[eo]=TFA +Name[hi]=टीडबल्यूएम +Name[te]=టి డబ్ల్యు ఎం +Comment=The Tab Window Manager +Comment[af]=Die Tab venster bestuurder +Comment[ar]=مدير النوافذ Tab +Comment[be]=Кіраўнік вокнаў з укладкамі Tab Window Manager +Comment[bn]=দি ট্যাব উইণ্ডো ম্যানেজার +Comment[bs]=Tab Window Manager +Comment[ca]=El gestor de finestres Tab +Comment[csb]=Tab Window Manager +Comment[cy]=Y Trefnydd Ffenestri Tab +Comment[da]=Tab-vindueshåndtering +Comment[de]=Der Tab-Fenstermanager +Comment[el]=Ο διαχειριστής παραθύρων Tab +Comment[eo]=Taba fenestroadministrilo +Comment[es]=El Tab Window Manager +Comment[et]=Kaartidega aknahaldur +Comment[eu]=Tab leiho kudeatzailea +Comment[fa]=مدیر پنجرۀ تب +Comment[fi]=Välilehtiä tukeva ikkunaohjelma +Comment[fy]=De Ljepper Finster Behearder +Comment[gl]=O Xestor de Fiestras Tab +Comment[hi]=टैब विंडो प्रबंधक +Comment[hr]=Tab upravitelj prozora +Comment[hu]=Tab Window Manager ablakkezelő +Comment[is]=Tab gluggastjórinn +Comment[it]=Il Tab Window Manager +Comment[ja]=Tab 化ウィンドウマネージャ +Comment[ka]=X11 სისტემის ტრადიციული ფანჯრის მენეჯერი +Comment[kk]=Tab терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ជា​ផ្ទាំង +Comment[ko]=탭 창 관리자 +Comment[lt]=Kortelių langų tvarkyklė +Comment[lv]=Tabu logu menedžeris +Comment[mk]=Tab Window Manager +Comment[mn]=Tab Цонхны удирдагч +Comment[ms]=Pengurus Tetingkap Tab +Comment[mt]=Tab Window Manager +Comment[nb]=Tab Vindusbehandler +Comment[nds]=De Tab-Finsterpleger +Comment[ne]=ट्याब सञ्झ्याल प्रबन्धक +Comment[nl]=De Tab Window Manager +Comment[nn]=Tab Window Manager +Comment[pa]=ਟੈਬ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Tab Window Manager +Comment[pt]=O Tab Window Manager +Comment[pt_BR]=O Gerenciador de Janelas de Abas +Comment[ro]=Tab Window Manager +Comment[ru]=Традиционный оконный менеджер системы X11 +Comment[rw]=Mugenga Dirishya Agafishi +Comment[se]=Tab-láse lásegieđahalli +Comment[sk]=Správca okien s kartami +Comment[sl]=Tab Window Manager, okenski upravitelj z zavihki +Comment[sv]=Flikfönsterhanteraren +Comment[ta]=டாப் சாளர மேலாளர் +Comment[te]=టాబ్ విండొ అభికర్త +Comment[tg]=Tab-и мудири тиреза +Comment[th]=Tab Window Manager +Comment[tr]=Tab Pencere Yöneticisi +Comment[tt]=X11 sistemendäge kebek tabaqlı täräzä-idäräçe +Comment[uk]=Tab Window Manager +Comment[vi]=Trình Quản lý Cửa sổ Thẻ +Comment[wa]=Li manaedjeu di purneas avou Linwetes (Tab Window Manager) +Comment[zh_CN]=标签式窗口管理器 +Comment[zh_TW]=Tab 視窗管理程式 diff --git a/tdm/kfrontend/sessions/ude.desktop b/tdm/kfrontend/sessions/ude.desktop new file mode 100644 index 000000000..108a493e4 --- /dev/null +++ b/tdm/kfrontend/sessions/ude.desktop @@ -0,0 +1,75 @@ +[Desktop Entry] +Type=XSession +Exec=uwm +TryExec=uwm +Name=UDE +Name[eo]=ULĈ +Name[hi]=यूडीई +Name[te]=యుడిఈ +Comment=The UNIX Desktop Environment +Comment[af]=Die 'Unix Desktop Environment' +Comment[ar]=بيئة سطح مكتب يونكس +Comment[be]=Працоўнае асяроддзе UNIX +Comment[bn]=দি ইউনিক্স ডেস্কটপ এনভায়রনমেন্ট +Comment[br]=An endro burev UNIX +Comment[bs]=UNIX Desktop Environment +Comment[ca]=L'entorn d'escriptori de Unix +Comment[csb]=Òkrãże pùltu Uniksa +Comment[cy]=Yr Amgylchedd Penbwrdd UNIX +Comment[da]=UNIX desktopmiljø +Comment[de]=Das UNIX Desktop Environment +Comment[el]=Το περιβάλλον επιφάνειας εργασίας του UNIX +Comment[eo]=La Uniksa Labortablo Ĉirkauaĵo +Comment[es]=El UNIX Desktop Environment +Comment[et]=UNIXi töölaua keskkond +Comment[eu]=UNIX mahaigain ingurunea +Comment[fa]=محیط رومیزی یونیکس +Comment[fi]=UNIX-työpöytäympäristö +Comment[fy]=De Unix Desktop Environment +Comment[ga]=Timpeallacht Deisce UNIX (UDE) +Comment[gl]=O Entorno de Escritório de UNIX +Comment[hi]=यूनिक्स डेस्कटॉप माहौल +Comment[hr]=UNIX radno okruženje +Comment[hu]=UNIX Desktop Environment ablakkezelő +Comment[is]=UNIX skjáborðsumhverfið +Comment[it]=Lo Unix Desktop Environment +Comment[ja]=UNIX デスクトップ環境 +Comment[ka]=UNIX-ის სამუშაო გარემო +Comment[kk]=UNIX Desktop Environment +Comment[km]=UNIX Desktop Environment +Comment[ko]=UNIX 데스크톱 환경 +Comment[lt]=UNIX darbastalio aplinka +Comment[lv]= UNIX Darba virsmas vide +Comment[mk]=UNIX Desktop Environment +Comment[mn]=ЮНИКС ажлын тавцангийн орчин +Comment[ms]=Persekitaran Desktop UNIX +Comment[mt]=UNIX Desktop Environment +Comment[nb]=UNIX Desktop Environment +Comment[nds]=De UNIX-Schriefdisch-Ümgeven +Comment[ne]=युनिक्स डेस्कटप वातावरण +Comment[nl]=De Unix Desktop Environment +Comment[nn]=UNIX Desktop Environment +Comment[pa]=UNIX Desktop Environment +Comment[pl]=Środowisko pulpitu Uniksa +Comment[pt]=O Unix Desktop Environment +Comment[pt_BR]=Ambiente de Trabalho do UNIX +Comment[ro]=Mediul grafic UNIX +Comment[ru]=UNIX Desktop Environment +Comment[rw]=Ibikikije Ibiro UNIX +Comment[se]=UNIX Desktop Environment +Comment[sl]=Namizno okolje UNIX +Comment[sr]=Unix радно окружење +Comment[sr@Latn]=Unix radno okruženje +Comment[sv]=Unix-skrivbordsmiljön +Comment[ta]=யுனிக்ஸ் மேல்மேசை சூழல் +Comment[te]=యూనిక్స్ రంగస్థల పర్యావరణం +Comment[tg]=Атрофи мизи кории UNIX +Comment[th]=สภาพแวดล้อมเดสก์ทอป UNIX +Comment[tr]=Unix Masaüstü Ortamı +Comment[tt]=UNIX Desktop Environment +Comment[uz]=Unix ish stoli muhiti (Unix Desktop Environment) +Comment[uz@cyrillic]=Unix иш столи муҳити (Unix Desktop Environment) +Comment[vi]=Môi trường Màn hình nền UNIX +Comment[wa]=L' evironmint di scribanne Unix UDE +Comment[zh_CN]=UNIX 桌面环境 +Comment[zh_TW]=Unix 桌面環境 diff --git a/tdm/kfrontend/sessions/vtwm.desktop b/tdm/kfrontend/sessions/vtwm.desktop new file mode 100644 index 000000000..50af40a63 --- /dev/null +++ b/tdm/kfrontend/sessions/vtwm.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=XSession +Exec=vtwm +TryExec=vtwm +Name=VTWM +Name[eo]=VTFA +Name[hi]=वीटीडबल्यूएम +Name[te]= వి టి డబ్ల్యు ఎం +Comment=The Virtual Tab Window Manager. TWM enhanced by virtual screens, etc. +Comment[af]=Die virtuele tab venster bestuurder. TWM wat met virtuele skerms uitgebreik is. +Comment[ar]=مدير نوافذ Tab الوهمي، مدير نوافذ TWM محسّن بأسطح المكتب الوهمية، إلخ. +Comment[be]=Віртуальны кіраўнік вокнаў з укладкамі Virtual Tab Window Manager. TWM, з дадатковай падтрымкай віртуальных экранаў і інш. +Comment[bn]=ভার্চুয়াল ট্যাব উইণ্ডো ম্যানেজার, ভার্চুয়াল স্ক্রীণ ইত্যাদি দ্বারা বর্ধিত +Comment[bs]=Virtual Tab Window Manager. TWM proširen virtuelnim ekranima itd. +Comment[ca]=El Virtual Tab Window Manager. TWM millorat per a pantalles virtuals, etc. +Comment[cs]=The Virtual Tab Window Manager. TWM vylepšené o virtuální obrazovky aj. +Comment[csb]=Virtual Tab Window Manager. TWM zbògacony ò wirtualné pùltë ëtp. +Comment[cy]=Y Trefnydd Ffenestri Tab Rhith. TWM wedi'i wella gan sgriniau rhith, ayyb. +Comment[da]=Virtual Tab Window Manager. TWM udvidet med virtuelle skærme osv. +Comment[de]=Der Virtual-Tab-Fenstermanager, eine Erweiterung von TWM mit virtuellen Arbeitsflächen usw. +Comment[el]=Ο εικονικός Tab διαχειριστής παραθύρων. Ο TWM εμπλουτισμένος με εικονικές οθόνες, κτλ. +Comment[eo]=La Virtuala Taba Fenestroadministrilo, TFA plibonigita per virtualaj ekranoj +Comment[es]=El Virtual Tab Window Manager, TWM mejorado con pantallas virtuales, etc. +Comment[et]=Virtuaalsete kaartidega aknahaldur ehk TWM, mida on täiendatud virtuaalsete ekraanidega jne. +Comment[eu]=Virtual Tab leiho kudeatzailea. Pantaila birtual eta abarrez hobetutako TWM-a +Comment[fa]=یک مدیر پنجرۀ تب مجازی.TWM گسترش‌یافته توسط پرده‌های مجازی و غیره. +Comment[fi]=Välilehtiä ja virtuaalityöpöytiä tukeva ikkunaohjelma, pohjautuu TWM:ään +Comment[fr]=The Virtual Tab Window Manager. TWM avec en plus la gestion des bureaux multiples +Comment[fy]=De firtuele Ljepper Window Manager. TWM útbreid mei firtuele buroblêden, ensfh. +Comment[gl]=O Virtual Tab Window Manager. TWM mellorado con pantallas virtuais, etc. +Comment[he]=The Virtual Tab Window Manager. TWM המשופר בשולחנות עבודה וירטואליים וכו' +Comment[hi]=आभासी टैब विंडो प्रबंधक. TWM को आभासी स्क्रीन इत्यादि से बेहतर बनाया गया +Comment[hr]=Comment=Virtual Tab Window Manager. TWM poboljšan virtualnim zaslonima itd. +Comment[hu]=Virtual Tab Window Manager, egy TWM-változat, támogatja a virtuális képernyőkezelést +Comment[is]=Tab gluggastjórinn endurbættur með sýndarskjám og fleiru. +Comment[it]=Il Virtual Tab Window Manager. TWM migliorato con schermi virtuali ecc. +Comment[ja]=仮想スクリーンなどの機能を拡張した TWM ベースの仮想タブウィンドウマネージャ +Comment[ka]=ვირტუალური ეკრანებით აღჭურვილი TWM-ის ვარიანტი +Comment[kk]=Virtual Tab Window Manager. TWM-негіздеген, виртуалды экрандары және т.б.с.с бар терезе менеджері. +Comment[km]=Virtual Tab Window Manager ។ TWM ដែល​បាន​ធ្វើ​ឲ្យ​ប្រសើរ​ដោយ​អេក្រង់​និមិត្ត ជាដើម ។ +Comment[lt]=Virtualių kortelių darbastalio aplinka. TWM išplėsta virtualiais darbastaliais ir pan. +Comment[lv]=Virtuālo tabu logu menedžeris. TWM papildināts ar virtuālajiem ekrāniem utml. +Comment[mk]=Virtual Tab Window Manager. TWM подобрен со виртуелни површини итн. +Comment[ms]=Pengurus Tetingkap Tab Maya. TWM dipertingkat dengan skrin maya, dsb. +Comment[mt]=Virtual Tab Window Manager. TWM flimkien ma' desktops virtwali eċċ +Comment[nb]=Virtual Tab vindusbehandler. TWM utvidet med virtuelle skjermer, osv. +Comment[nds]=De "Virtual Tab Window Manager". Dat is TWM verwiedert üm virtuelle Schirmen etc. +Comment[ne]=अवास्तविक ट्याब सञ्झ्याल प्रबन्धक । अवास्तविक पर्दाद्वारा बृद्धि गरिएको TWM, आदि +Comment[nl]=De Virtual Tab Window Manager. TWM uitgebreid met virtuele bureaubladen, etc. +Comment[nn]=Virtual Tab Window Manager. TWM utvida med virtuelle skjermar og anna. +Comment[pa]=Virtual Tab Window Manager. TWM ਫਰਜ਼ੀ ਪਰਦਿਆਂ ਨਾਲ ਲੈੱਸ +Comment[pl]=Virtual Tab Window Manager. TWM wzbogacony o wirtualne pulpity itp. +Comment[pt]=O Virtual Tab Window Manager. Um TWM melhorado com ecrãs virtuais, etc. +Comment[pt_BR]=O gerenciador de janelas de abas virtuais. TWM melhorado pelas telas virtuais. +Comment[ro]=Virtual Tab Window Manager. TWM îmbunătățit cu ecrane virtuale etc. +Comment[ru]=Вариант TWM, имеющий виртуальные экраны и т.д. +Comment[rw]=Mugenga Dirishya y'Agafishi Itaboneka.TWM ivuguruwe na mugaragaza zitagaragara, n'ibindi. +Comment[se]=The Virtual Tab Window Manager. TWM buoriduvvon virtuella čállinbevddiin, jna. +Comment[sk]=The Virtual Tab Window Manager. TWM rozšírený o virtuálne obrazovky atď. +Comment[sl]=Virtual Tab Window Manager. TWM, izboljšan z navideznimi zasloni ipd. +Comment[sr]=„The Virtual Tab Window Manager“. TWM побољшан виртуелним екранима и сл. +Comment[sr@Latn]=„The Virtual Tab Window Manager“. TWM poboljšan virtuelnim ekranima i sl. +Comment[sv]=Virtuell flikfönsterhanterare. TWM utökad med virtuella skärmar, etc. +Comment[ta]=மெய்நிகர் தத்தல் சாளர மேலாளர். TWM மெய்நிகர் திரைகளால் மேம்படுத்தப்பட்டது. +Comment[th]=The Virtual Tab Window Manager คือ TWM ที่เพิ่มความสามารถโดยหน้าจอเสมือน และอื่นๆ +Comment[tr]=Virtual Tab Masaüstü Yöneticisi. +Comment[tt]=Virtual Tab Window Manager. Öställär östälengän TWM kebek. +Comment[uk]=Virtual Tab Window Manager. TWM з підтримкою віртуальних екранів. +Comment[vi]=Trình Quản lý Cửa sổ Thẻ Ảo. TWM cải tiến với màn hình ảo, ... +Comment[wa]=Li Forveyou Manaedjeu di Purneas avou Linwetes (Virtual Tab Window Manager). TWM a sacwants forveyowès waitroûles, evnd. +Comment[zh_CN]=虚拟标签式窗口管理器。用虚拟屏幕等功能增强的 TWM。 +Comment[zh_TW]=虛擬 Tab 視窗管理程式。基於 TWM 並加強虛擬螢幕等等。 diff --git a/tdm/kfrontend/sessions/w9wm.desktop b/tdm/kfrontend/sessions/w9wm.desktop new file mode 100644 index 000000000..92633bcf7 --- /dev/null +++ b/tdm/kfrontend/sessions/w9wm.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Type=XSession +Exec=w9wm +TryExec=w9wm +Name=W9WM +Name[eo]=F9FA +Name[hi]=डबल्यू9डबल्यूएम +Name[ta]=IceWM +Name[te]=డబ్ల్యు 9 డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง W9WM +Comment=A window manager based on 9WM, enhanced by virtual screens and keyboard bindings +Comment[af]='n Venster bestuurder wat op 9WM gebaseer is, uitgebrei met virtuele skerms en sleutelbord bindinge +Comment[ar]=مدير نوافذ مبني على 9WM، محسّن الشاشات الوهمية والمفاتيح المرتبطة +Comment[be]=Кіраўнік вокнаў, заснаваны на 9WM, з дадатковай падтрымкай віртуальных экранаў і клавішных скаротаў +Comment[bn]=9WM ভিত্তিক উইণ্ডো ম্যানেজার, ভার্চুয়াল স্ক্রীণ এবং কীবোর্ড বাইন্ডিং দ্বারা বর্ধিত +Comment[bs]=Window manager baziran na 9WM, proširen virtuelnim ekranima i prečicama tastature +Comment[ca]=Un gestor de finestres basat en 9WM, millorat per a pantalles virtuals i amb dreceres de teclat +Comment[cs]=Správce oken založený na 9WM rozšířený o virtuální plochy a klávesové zkratky +Comment[csb]=Menedżer òknów òpiarty na 9WM, zbògacony ò wirtualné ekranë ë kònfigùracëjã klawiszowëch skrodzënów +Comment[cy]=Trefnydd ffenestri wedi'i seilio ar 9WM, wedi'i wella gan sgriniau rhith a rhwymiadau bysyll. +Comment[da]=En vindueshåndtering baseret på 9WM, udvidet med virtuelle skærme og tastaturbindinger +Comment[de]=Fenstermanager auf der Basis von 9WM, erweitert durch virtuelle Arbeitsflächen und Tastaturzuordnungen +Comment[el]=Ένας διαχειριστής παραθύρων βασισμένος στον 9WM, εμπλουτισμένος με εικονικές οθόνες και συνδυασμούς πλήκτρων +Comment[eo]=Fenestroadministrilo devenigita de 9FA, plibonigita per virtualaj ekranoj kaj klaviara uzo +Comment[es]=Un gestor de ventanas basado en 9WM, mejorado con ventanas virtuales y accesos rápidos de teclado +Comment[et]=Aknahaldur, mille aluseks on 9WM ja mida on täiendatud virtuaalsete ekraanide ja kiirklahvide võimalusega +Comment[eu]=9WM-n oinarritutako leiho kudeatzailea, pantaila birtual eta laster-teklez hobetua +Comment[fa]=یک مدیر پنجره بر اساس 9WM، گسترش‌یافته توسط ‌پرده‌های مجازی و مقیدسازیهای صفحه کلید +Comment[fi]=9WM:ään pohjautuva ikkunaohjelma, jossa tuki virtuaalityöpöydille ja näppäimistöyhdistelmille +Comment[fr]=Un gestionnaire de fenêtres fondé sur 9WM, avec en plus la gestion des bureaux virtuels et des raccourcis clavier +Comment[fy]=In finstersmanager basearrre op 9WM. útbreid mei firtuele buroblêden en fluchtoetsen +Comment[gl]=Un xestor de fiestras baseado en 9WM, mellorado polas pantallas virtuais e atallos de teclado +Comment[he]=מנהל חלונות המבוסס על 9WM, המשופר בשולחנות עבודה וירטואליים ומיפוי מקשים +Comment[hi]= 9डबल्यूएम आधारित विंडो प्रबंधक, आभासी स्क्रीन तथा की-बोर्ड बाइंडिंग से बेहतर बनाया गया +Comment[hr]=Upravitelj prozora zasnovan na 9WM, unaprijeđen virtualnim zaslonima i prečacima tipkovnice +Comment[hu]=Egy 9WM-alapú ablakkezelő, virtuális képernyőkezeléssel, konfigurálható billentyűparancsokkal +Comment[is]=Gluggastjóri byggður á 9WM en endurbættur með sýndarskjám og lyklaborðsvörpunum +Comment[it]=Un window manager basato su 9WM, migliorato con schermi virtuali e scorciatoie per la tastiera. +Comment[ja]=仮想スクリーンとキーボードショートカット機能を強化した 9WM ベースのウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი 9wm-ს ბაზაზე, ვირტუალური ეკრანებით და კლავიატურის შესაბამისობებით +Comment[kk]=9WM-негіздеген, виртуалды экрандары, пернетақта тіркесімдері бар терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ផ្អែក​លើ 9WM ដែល​ត្រូវ​បាន​ធ្វើ​ឲ្យ​ប្រសើរ​ដោយ​អេក្រង់​និមិត្ត និង​ការ​ចង​គ្រាប់ចុច +Comment[ko]=부분적 그놈 지원과 가상 데스크톱 지원을 사용하는 AEWM 기반 창 관리자 +Comment[lt]=Langų tvarkyklė, paremta 9WM, išplėsta virtualių ekranų ir klaviatūros greitųjų klavišų palaikymu +Comment[lv]=Logu menedžeris bāzēts uz 9WM, papildināts ar virtuālajiem ekrāniem un tastatūras saīsnēm +Comment[mk]=Менаџер на прозорци базиран на 9WM, подобрен со виртуелни површини и поврзувања за тастатурата +Comment[ms]=Pengurus tetingkap berdasarkan 9WM, dipertingkat dengan skrin maya dan ikatan papan kekunci +Comment[mt]=Window manager ibbażat fuq 9WM, flimkien ma desktops virtwali u hotkeys +Comment[nb]=En vindusbehandler basert på 9WM, forbedret med virtuelle skjermer og hurtigtaster +Comment[nds]=En Finsterpleger opbuut op 9WM, verwiedert üm virtuelle Schirmen un Tastkombinatschonen +Comment[ne]=कुञ्जीपाटी बाइन्डिङ र अवास्तविक पर्दाहरूद्वारा बृद्धि गरिएको 9WM मा आधारित सञ्झ्याल प्रबन्धक +Comment[nl]=Een windowmanager gebaseerd op 9WM. Uitgebreid met virtuele bureaubladen en sneltoetsen +Comment[nn]=Ein vindaugssjef basert på 9WM, forbetra med virtuelle skjermar og snøggtastar +Comment[pa]=9WM ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਫਰਜ਼ੀ ਪਰਦਿਆਂ ਤੇ ਕੀ-ਬੋਰਡ ਬਾਈਡਿੰਗ ਨਾਲ ਲੈੱਸ +Comment[pl]=Menedżer okien oparty na 9WM, wzbogacony o wirtualne ekrany i konfigurowanie skrótów klawiszowych +Comment[pt]=Um gestor de janelas baseado no 9WM, melhorado com ecrãs virtuais e atalhos de teclado +Comment[pt_BR]=Um gerenciador de janelas baseado no 9Wm, melhorado pelas telas virtuais e atalhos de teclado +Comment[ro]=Un manager de ferestre bazat pe 9WM, îmbunătățir cu ecrane virtuale și acceleratori de tastatură +Comment[ru]=Оконный менеджер на основе 9wm, имеющий виртуальные экраны и привязку клавиш +Comment[rw]=Mugenga Dirishya ishingiye kuri 9WM, ivuguruwe hakoreshejwe mugaragaza itaboneka n'amahuza mwandikisho +Comment[sk]=Správca okien založený na 9WM, rozšírený o virtuálne obrazovkya klávesové skratky +Comment[sl]=Okenski upravitelj na osnovi 9WM, izboljšan z navideznimi zasloni in tipkovnimi vezmi +Comment[sr]=Менаџер прозора заснован на 9WM-у, побољшан виртуелним екранима и повезивањем тастатуре +Comment[sr@Latn]=Menadžer prozora zasnovan na 9WM-u, poboljšan virtuelnim ekranima i povezivanjem tastature +Comment[sv]=Fönsterhanterare baserad på 9WM, utökad med virtuella skärmar och tangentbindingar +Comment[ta]=9WM அடிப்படையிலான மெய்நிகர் திரை மற்றும் விசைப்பலகை சேர்ப்புகளால் மேம்படுத்தப்பட்ட சாளர மேலாளார், +Comment[th]=ระบบจัดการหน้าต่างที่สร้างมาจาก 9WM และเพิ่มความสามารถด้วยหน้าจอเสมือนและแป้นพิมพ์ลัด +Comment[tr]=9WM tabanlı, sanal ekranları ve klavye kısayolları ile geliştirilmiş bir masaüstü yöneticisi +Comment[tt]=Xıyalí öställär belän töylekne totqan täräzä-idäräçe. 9WM asılında +Comment[uk]=Менеджер вікон, заснований на 9WM, додано віртуальні екрани та прив'язки клавіш +Comment[vi]=Trình quản lý cửa sổ dựa vào 9WM, cải tiến với màn hình ảo, tổ hợp phím +Comment[wa]=On manaedjeu di purneas båzé so 9WM, avou sopoirt po les forveyous scribannes eyet les rascourtis di taprece. +Comment[zh_CN]=基于 9WM 的窗口管理器,用虚拟屏幕和键盘绑定等功能增强了 +Comment[zh_TW]=一個基於 9WM 並加強虛擬螢幕及鍵盤組合鍵功能 diff --git a/tdm/kfrontend/sessions/waimea.desktop b/tdm/kfrontend/sessions/waimea.desktop new file mode 100644 index 000000000..8981b5af6 --- /dev/null +++ b/tdm/kfrontend/sessions/waimea.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Type=XSession +Exec=waimea +TryExec=waimea +Name=Waimea +Name[eo]=Vaimeo +Name[hi]=वाईमिया +Name[ne]=विमेआ +Name[pa]=ਵਾਈਮਿਆ +Name[te]=వైమెయా +Comment=A highly customizable window manager based on Blackbox +Comment[af]='n Hoë opstelbare venster bestuurder wat op Blackbox gebaseer is +Comment[ar]=مدير نوافذ قابل جداً للتخصيص مبني على Blackbox +Comment[be]=Кіраўнік вокнаў, заснаваны на Blackbox, з магчымасцю настаўлення +Comment[bn]=ব্ল্যাকবক্স ভিত্তিক উইণ্ডো ম্যানেজার +Comment[bs]=Visoko prilagodljiv window manager baziran na Blackbox +Comment[ca]=Un gestor de finestres altament configurable basat en Blackbox +Comment[cs]=Vysoce přizpůsobitelný správce oken založený na Blackboxu +Comment[csb]=Menedżer òknów òpiartëch na Blackbox z wiôldżima mòżnotama dopasowaniô +Comment[cy]=Trefnydd ffenestri sy'n hawdd ei ffurfweddu, wedi'i seilio ar Ddu-flwch +Comment[da]=En meget indstillelig vindueshåndtering baseret på Blackbox +Comment[de]=Vielfältig anpassbarer Fenstermanager, der auf Blackbox basiert +Comment[el]=Ένας ιδιαίτερα παραμετροποιήσιμος διαχειριστής παραθύρων βασισμένος στον Blackbox +Comment[en_GB]=A highly customisable window manager based on Blackbox +Comment[eo]=Tre agordebla fenestroadministrilo, devenigita de Negrujo +Comment[es]=Un gestor de ventanas muy personalizable basado en Blackbox +Comment[et]=Väga hästi kohandatav aknahaldur, aluseks Blackbox +Comment[eu]=Blackboxen oinarritutako leiho-kudeatzaile zeharo pertsonalizagarria +Comment[fa]=یک مدیر پنجره با قابلیت سفارشی‌سازی بالا بر اساس Blackbox +Comment[fi]=Blackboxiin perustuva paljon muokattavissa oleva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres très configurable fondé sur Blackbox +Comment[fy]=In tige ynstelbere finstersmanager, basearre op Blackbox +Comment[gl]=Un xestor de fiestras moi personalizábel baseado en Blackbox +Comment[he]=מנהל חלונות המאפשר התאמה אישית גבוהה והמבוסס על Blackbox +Comment[hi]=ब्लेक-बाक्स आधारित, अत्यंत कस्टमाइजेबल विंडो प्रबंधक +Comment[hr]=Vrlo prilagodljiv upravitelj prozora zasnovan na Blackboxu +Comment[hu]=Egy sokféle beállítási lehetőséggel rendelkező ablakkezelő a Blackbox alapján +Comment[is]=Afar stillanlegur gluggastjóri byggður á Blackbox +Comment[it]=Un window manager molto personalizzabile basato su BlackBox +Comment[ja]=Blackbox ベースの高度なカスタマイズが可能なウィンドウマネージャ +Comment[ka]=კონფიგურირებადი ფანჯრის მენეჯერი Blackbox-ს ბაზაზე +Comment[kk]=Blackbox-негіздеген, баптау жағынан бай, терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ដែល​អាច​ប្ដូរ​តាម​បំណង​កម្រិត​ខ្ពស់ ដោយ​ផ្អែក​លើ Blackbox +Comment[ko]=Blackbox 기반의 사용자 정의가 가능한 관리자 +Comment[lt]=Daug konfigūravimo parinkčių turinti langų tvarkyklė, paremta Blackbox +Comment[lv]=Plaši konfigurējams logu menedžeris bāzēts uz Blackbox +Comment[mk]=Менаџер на прозорци базиран на Blackbox со голем број опции +Comment[ms]=Pengurus tetingkap boleh suai berdasarkan Kotak Hitam +Comment[mt]=Window manager konfigurabbli ibbażat fuq BlackBox +Comment[nb]=En vindusbehandler med mange tilpasninger, basert på Blackbox +Comment[nds]=En Finsterpleger mit mennige Instellen, opbuut op Blackbox +Comment[ne]=कालो बाकसमा आधारित उच्च अनुकूल योग्य एक सञ्झ्याल प्रबन्धक +Comment[nl]=Een zeer instelbare windowmanager, gebaseerd op Blackbox +Comment[nn]=Ein vindaugssjef med mange tilpassingar, basert på Blackbox +Comment[pa]=ਬਲੈਕਬਕਸੇ 'ਤੇ ਆਧਾਰਿਤ ਅਤਿ ਸੋਧਯਯੋਗ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien oparty na Blackbox z dużymi możliwościami dostosowania +Comment[pt]=Um gestor de janelas altamente configurável, baseado no Blackbox +Comment[pt_BR]=Um gerenciador de janelas altamente personalizável, baseado no Blackbox +Comment[ro]=Un manager de ferestre foarte configurabil bazat pe Blackbox +Comment[ru]=Настраиваемый оконный менеджер, основанный на Blackbox +Comment[rw]=Mugenga dirishya ihabwa imiterere yifuzwa mu buryo hejuru ishingiye ku Gasandukumukara +Comment[sk]=Veľmi prispôsobiteľný správca okien založený na Blackbox +Comment[sl]=Visoko nastavljiv okenski upravitelj na osnovi Blackboxa +Comment[sr]=Врло прилагодљив менаџер прозора заснован на Blackbox-у +Comment[sr@Latn]=Vrlo prilagodljiv menadžer prozora zasnovan na Blackbox-u +Comment[sv]=Ytterst anpassningsbar fönsterhanterare baserad på Blackbox +Comment[ta]=தனதாக்க வல்ல கருப்புப்பெட்டி சார்ந்த சாளர மேலாளர் +Comment[th]=ระบบจัดการหน้าต่างที่ปรับแต่งได้อย่างละเอียด สร้างมาจาก Blackbox +Comment[tr]=Blackbox temelli, kolayca özelleştirilebilir bir pencere yöneticisi +Comment[tt]=Yaqşı köylänüçän täräzä-idäräçe. Blackbox asılında +Comment[uk]=Надгнучкий менеджер вікон, заснований на Blackbox +Comment[uz]=Blackbox asosida yaratilgan, moslab boʻladigan oyna boshqaruvchi +Comment[uz@cyrillic]=Blackbox асосида яратилган, мослаб бўладиган ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ rất dễ cá nhân hoá dựa trên Blackbox +Comment[wa]=On manaedjeu di purneas k' vos ploz pår mete da vosse båzé so Blackbox +Comment[zh_CN]=基于 BlackBox 可高度自定义的窗口管理器 +Comment[zh_TW]=一個基於 Blackbox 且高度可客製化的視窗管理程式 diff --git a/tdm/kfrontend/sessions/wm2.desktop b/tdm/kfrontend/sessions/wm2.desktop new file mode 100644 index 000000000..618c10bcc --- /dev/null +++ b/tdm/kfrontend/sessions/wm2.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Type=XSession +Exec=wm2 +TryExec=wm2 +Name=WM2 +Name[eo]=Fa2 +Name[hi]=डबल्यूएम2 +Name[te]=డబ్ల్యు ఎం 2 +Name[th]=ตัวจัดการหน้าต่าง WM2 +Comment=A small, non-configurable window manager +Comment[af]='n Klein, nie opstelbare venster bestuurder +Comment[ar]=مدير نوافذ صغير غير قابل للإعداد +Comment[be]=Маленькі кіраўнік вокнаў, без магчымасці настаўленняў +Comment[bn]=একটি ছোটো উইণ্ডো ম্যানেজার +Comment[bs]=Mali, ne-konfigurabilni window manager +Comment[ca]=Un petit i no configurable gestor de finestres +Comment[cs]=Malý nepřizpůsobitelný správce oken +Comment[csb]=Môłi menedżer òknów bez mòżnotë kònfigùracëji +Comment[cy]=Trefnydd ffenestri bach na ellir ffurfweddu +Comment[da]=En lille, ikke-indstillelig vindueshåndtering +Comment[de]=Kleiner, nicht einstellbarer Fenstermanager +Comment[el]=Ένας μικρός, μη παραμετροποιήσιμος διαχειριστής παραθύρων +Comment[eo]=Malgranda, ne agordebla fenestroadministrilo +Comment[es]=Un gestor de ventanas pequeño y no configurable +Comment[et]=Väike ja seadistamatu aknahaldur +Comment[eu]=Leiho-kudeatzaile txikia, konfiguratu ezin dena +Comment[fa]=یک مدیر پنجرۀ کوچک و غیرقابل پیکربندی +Comment[fi]=Pieni ikkunaohjelma, jossa ei ole asetuksia +Comment[fr]=Un gestionnaire de fenêtres petit et non configurable +Comment[fy]=In lytse, net-ynstelbere finstersmanager +Comment[gl]=Un xestor de fiestras pequeno non configurábel +Comment[he]=מנהל חלונות קטן ולא ניתן להגדרה +Comment[hi]=एक छोटा विंडो प्रबंधक जो कॉन्फ़िगर नहीं हो सकता +Comment[hr]=Malen, nepodesiv upravitelj prozora +Comment[hu]=Egy nagyon egyszerű ablakkezelő, beállítási lehetőségek nélkül +Comment[is]=Lítill, einfaldur gluggastjóri sem er ekki hægt að stilla +Comment[it]=Un window manager piccolo e non configurabile +Comment[ja]=小さくて設定項目のないウィンドウマネージャ +Comment[ka]=პატარა და არაკონფიგურირებადი ფანჯრის მენეჯერი +Comment[kk]=Шағын, баптауы жоқ, терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​តូច ហើយ​មិន​អាច​កំណត់​រចនាសម្ព័ន្ធ​បាន +Comment[ko]=설정할 수 없는 작은 창 관리자 +Comment[lt]=Maža, nekonfigūruojama langų tvarkyklė +Comment[lv]=Mazs, nekonfigurējams logu menedžeris +Comment[mk]=Мал и неконфигурабилен менаџер на прозорци +Comment[mn]=Жижиг тохируулах боломжгүй цонх удирдагч +Comment[ms]=Pengurus tetingkap yang kecil dan tidak boleh konfigur +Comment[mt]=Window manager żgħir u mhux konfigurabbli +Comment[nb]=En liten vindusbehandler uten tilpasninger +Comment[nds]=En lütte Finsterpleger ahn Instellen +Comment[ne]=सानो, कन्फिगर गर्न नसकिने सञ्झ्याल प्रबन्धक +Comment[nl]=Een kleine, niet-instelbare windowmanager +Comment[nn]=Ein liten vindaugssjef utan tilpassingar +Comment[pa]=ਇੱਕ ਹਲਕਾ ਨਾ-ਸੋਧਯੋਗ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Mały menedżer okien nie podlegający konfiguracji +Comment[pt]=Um gestor de janelas pequeno e não-configurável +Comment[pt_BR]=Um pequeno e não-configurável gerenciador de janelas +Comment[ro]=Un manager de ferestre mic, neconfigurabil +Comment[ru]=Маленький, не настраиваемый оконный менеджер +Comment[rw]=Mugenga Dirishya itabonezwa, ntoya +Comment[se]=Unna, ii heivehahtti lásegieđahalli +Comment[sk]=Malý, nenastaviteľný správca okien +Comment[sl]=Majhen, nenastavljiv okenski upravitelj +Comment[sr]=Мали, неподесиви менаџер прозора +Comment[sr@Latn]=Mali, nepodesivi menadžer prozora +Comment[sv]=Liten fönsterhanterare utan anpassningsmöjligheter +Comment[ta]=சிறிய, வடிவமைக்க முடியாத சாளர மேலாளர் +Comment[th]=ระบบจัดการหน้าที่ขนาดเล็ก ที่ไม่สามารถปรับแต่งอะไรได้ +Comment[tr]=Küçük ve yapılandırılamayan bir pencere yöneticisi +Comment[tt]=Caylanmí torğan keçkenä täräzä-idäräçe +Comment[uk]=Невеличкий менеджер вікон без можливості налаштування +Comment[uz]=Kichik, moslab boʻlmaydigan oyna boshqaruvchi +Comment[uz@cyrillic]=Кичик, мослаб бўлмайдиган ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ nhỏ, không cấu hình được +Comment[wa]=On ptit, nén apontiåve, manaedjeu di purneas +Comment[zh_CN]=小巧的不可配置的窗口管理器 +Comment[zh_TW]=一個小型且不可組態的視窗管理者 diff --git a/tdm/kfrontend/sessions/wmaker.desktop b/tdm/kfrontend/sessions/wmaker.desktop new file mode 100644 index 000000000..fada3d3b5 --- /dev/null +++ b/tdm/kfrontend/sessions/wmaker.desktop @@ -0,0 +1,82 @@ +[Desktop Entry] +Type=XSession +Exec=wmaker +TryExec=wmaker +Name=WindowMaker +Name[bn]=উইণ্ডো-মেকার +Name[cy]=GwneuthuryddFfenestri (WindowMaker) +Name[eo]=Fenestroadministrilo +Name[hi]=विंडोमेकर +Name[ne]=सञ्झ्याल निर्माता +Name[pa]=ਝਰੋਖਾ-ਨਿਰਮਾਤਾ +Name[rw]=MukoraDirishya +Name[sv]=Windowmaker +Name[ta]=விண்டோஸ்மேக்கர் +Name[te]=విండొమెకర్ +Name[tg]=Созандаи тиреза +Comment=A simple window manager that resembles the NeXTStep look very closely +Comment[af]='n Eenvoudige venster bestuurder wat soos NeXTStep lyk +Comment[ar]=مدير نوافذ بسيط يمثّل مظهر NeXTStep بشكل قريب جداً +Comment[be]=Просты кіраўнік вокнаў, які вельмі дакладна паўтарае вонкавы выгляд NeXTStep +Comment[bn]=একটি উইণ্ডো ম্যানেজার যা ভীষণরকম NeXTStep-এর মত দেখতে +Comment[bs]=Jednostavan window manager koji vrlo dosljedno imitira NeXTStep izgled +Comment[ca]=Un gestor de finestres simple que s'assembla molt a l'aspecte de NeXTStep +Comment[cs]=Jendoduchý správce oken, který se velmi podobá NeXTStep +Comment[csb]=Prosti menedżer òknów szlachùjący za NeXTStep +Comment[cy]=Trefnydd ffenestri syml sy'n debyg iawn i'r golwg CamNesaf +Comment[da]=En simpel vindueshåndtering der ligner NeXTStep's udseende meget +Comment[de]=Einfacher Fenstermanager mit starker Ähnlichkeit zu NeXTStep +Comment[el]=Ένας απλός διαχειριστής παραθύρων που προσομοιώνει πολύ καλά το στυλ του NeXTStep +Comment[eo]=Simpla fenestroadministrilo +Comment[es]=Un gestor de ventanas sencillo cuyo aspecto se parece mucho al de NeXTStep +Comment[et]=Lihtne aknahaldur, mis meenutab väga tugevasti NeXTStepi +Comment[eu]=Leiho kudeatzaile sinplea, NeXTStep-en antz handia duena +Comment[fa]=یک مدیر پنجرۀ ساده که خیلی شبیه گام بعدی است +Comment[fi]=Yksinkertainen ikkunaohjelma, joka muistuttaa erittäin paljon NeXTStepiltä +Comment[fr]=Un gestionnaire de fenêtres simple qui ressemble assez précisement à NeXTStep +Comment[fy]=In ienfâldige finstersmanager dy it úterlik fan NeXTStep saer tichtby benaderd +Comment[gl]=Un xestor de fiestras sinxelo que se achega moito á apariencia de NeXTStep +Comment[he]=מנהל חלונות פשוט הדומה מאוד במראה שלו ל־NeXTStep +Comment[hi]=नेक्स्टस्टेप की तरह दिखने वाला सादा विंडो प्रबंधक +Comment[hr]=Jednostavan upravitelj prozora koji odražava vrlo blisko izgled NeXTStepa +Comment[hu]=Egy egyszerű ablakkezelő, megjelenése nagyon hasonlít a NeXTStephez +Comment[is]=Einfaldur gluggastjóri sem líkir vel eftir NeXTStep umhverfinu +Comment[it]=Un semplice window manager che assomiglia molto a NeXTStep. +Comment[ja]=NextStep にとてもよく似たシンプルなウィンドウマネージャ +Comment[ka]=NeXTStep -ის მაგვარი მარტივი ფანჯრის მენეჯერი +Comment[kk]=Қарапайым, NeXTStep-ке үқсас терезе менеджері +Comment[km]=កម្មវិធី​គ្រប់គ្រង​បង្អួច​ធម្មតា​មួយ ដែល​ប្រហាក់ប្រហែល​នឹង​រូបរាង NeXTStep បំផុត +Comment[lt]=Paprasta langų tvarkyklė, išvaizda labai primenanti NeXTStep +Comment[lv]=Vienkāršs logu menedžeris, kas ir ļoti līdzīgs NeXTStep +Comment[mk]=Едноставен менаџер на прозорци кој е многу сличен на изгледот на NeXTStep +Comment[ms]=Pengurus tetingkap ringkas yang memasang NeXTStep dan menjadikannya tampak sangat hampir +Comment[mt]=Window manager li jixbaħ ħafna lil NextStep +Comment[nb]=En enkel vindusbehandler som ligner mye på NeXTStep +Comment[nds]=En eenfache Finsterpleger, de meist utsüht as NeXTStep +Comment[ne]=NeXTStep जस्तो देखिने साधारण सञ्झ्याल प्रबन्धक +Comment[nl]=Een eenvoudige windowmanager die het uiterlijk van NeXTStep zeer dicht benaderd +Comment[nn]=Ein enkel vindaugssjef som liknar mykje på NeXTStep +Comment[pa]=ਇੱਕ ਸਧਾਰਨ ਜੋ ਕਿ NeXTStep ਵਰਗਾ ਜਾਪਦਾ ਹੈ +Comment[pl]=Prosty menedżer okien przypominający bardzo wyglądem NeXTStep +Comment[pt]=Um gestor de janelas simples que faz lembrar bastante o visual do NeXTStep +Comment[pt_BR]=Um gerenciador de janelas simples, que lembra a aparência do NeXTStep +Comment[ro]=Un manager de ferestre simplu, care amintește foarte bine de aspectul NeXTStep +Comment[ru]=Простой оконный менеджер, воспроизводящий интерфейс NeXTStep +Comment[rw]=Mugenga Dirishya yoroheje ihuriza hamwe imboneko IntambweIkurikira byegeranye cyane +Comment[se]=Oktageardánis lásegieđahalli mii sulástahttá NeXTStep hui ollu +Comment[sk]=Jednoduchý správca okien, ktorý veľmi pripojíma NeXTStep +Comment[sl]=Preprost okenski upravitelj, ki zelo spominja na izgled NeXTStep +Comment[sr]=Једноставан менаџер прозора који одражава врло блиско изглед NeXTStep-а +Comment[sr@Latn]=Jednostavan menadžer prozora koji odražava vrlo blisko izgled NeXTStep-a +Comment[sv]=Enkel fönsterhanterare som mycket nära efterliknar Nextstep-utseendet +Comment[ta]=NeXTStep ஐ ஒத்த எளிய சாளர மேலாளார். +Comment[th]=ระบบจัดการหน้าต่างแบบเรียบง่าย ที่ดูคล้ายระบบ NeXTStep มากๆ +Comment[tr]=NeXTStep'e aşırı benzeyen basit bir masaüstü yöneticisi +Comment[tt]=NeXTStep küreneşendä ciñel täräzä-idäräçe +Comment[uk]=Простий менеджер вікон, що дуже нагадує NeXTStep +Comment[uz]=NeXTStep'ga juda oʻxshash oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=NeXTStep'га жуда ўхшаш оддий ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ giống với NeXTStep +Comment[wa]=On simpe manaedjeu di purneas avou l' foite rivnance di NeXTStep +Comment[zh_CN]=非常接近 NeXTStep 外观的简单窗口管理器 +Comment[zh_TW]=一個小型且與 NeXTStep 外觀很接近的視窗管理程式 diff --git a/tdm/kfrontend/sessions/xfce.desktop b/tdm/kfrontend/sessions/xfce.desktop new file mode 100644 index 000000000..6b199228b --- /dev/null +++ b/tdm/kfrontend/sessions/xfce.desktop @@ -0,0 +1,73 @@ +[Desktop Entry] +Type=XSession +Exec=xfwm +TryExec=xfwm +Name=XFce +Name[eo]=Facoj +Name[hi]=एक्सएफसीई +Name[sv]=Xfce +Name[te]=ఎక్స్ ఎఫ్ సి ఈ +Comment=The Cholesterol Free Desktop Environment. A desktop environment reminiscent of CDE +Comment[af]=Die Cholesterol Gratis Werkskerm Omgewing. 'n Werkskerm omgewing wat op CDE gebaseer is +Comment[ar]=بيئة سطح المكتب الخالي من الكوليسترول، بيئة سطح مكتب مليئة بذكريات CDE +Comment[be]=XFCE - Cholesterol Free Desktop Environment. Працоўнае асяроддзе, падобнае на CDE +Comment[bn]=দি কলেস্টরল ফ্রী ডেস্কটপ এনভায়রনমেন্ট। CDE-র কথা মনে করিয়ে দেয় এমন একটি ডেস্কটপ এনভায়রনমেন্ট +Comment[bs]=Cholesterol Free Desktop Environment. Desktop okolina nalik na CDE +Comment[ca]=El Cholesterol Free Desktop Environment. Un entorn d'escriptori amb reminiscències de CDE +Comment[cs]=Svobodné grafické prostředí neobsahující cholesterol. Prostředí připomínající CDE +Comment[csb]=Òkrãże pùltu szlachùjące za CDE +Comment[cy]=Yr Amgylchedd Penbwrdd Di-Golesterol. Amgylchedd penbwrdd sy'n atgoffaol o CDE +Comment[da]=Det kolesterolfrie desktopmiljø. Et desktopmiljø der minder om CDE +Comment[de]=Cholesterol Free Desktop Environment. Graphische Arbeitsumgebung, die an CDE erinnert +Comment[el]=Το Cholesterol Free Desktop Environment. Ένα περιβάλλον επιφάνειας εργασίας βασισμένο στο CDE +Comment[eo]=La libera labortablo ĉirkaŭajo +Comment[es]=El Cholesterol Free Desktop Environment, un entorno de escritorio que recuerda a CDE +Comment[et]=Kolesteroolivaba töölaua keskkond, mis meenutab mitmeti CDE-d +Comment[eu]=Kolesterolik gabeko mahaigain ingurunea. CDE gogorarazten duen mahaigaina +Comment[fa]=محیط رومیزی آزاد Cholesterol. یادآور محیط رومیزی CDE +Comment[fi]=Cholesterol Free -työpöytäympäristö. CDE:tä muistuttavatyöpöytäympäristö. +Comment[fr]=The Cholesterol Free Desktop Environment. Un environnement de bureau rappelant CDE +Comment[fy]=The Cholesterol Free Desktop Environment. In buroblêd omwrâld die tinken dat oan CDE +Comment[gl]=O Cholesterol Free Desktop Environment. Un entorno de escritório reminiscente de CDE +Comment[he]=The Cholesterol Free Desktop Environment. סביבת עבודה המזכירה את CDE +Comment[hi]=कॉलेस्ट्रॉल रहित डेस्कटॉप माहौल. एक डेस्कटॉप माहौल जो सीडीई जैसा है +Comment[hr]=Cholesterol Free Desktop Environment - Okruženje radne površine koje podsjeća na CDE +Comment[hu]=Cholesterol Free Desktop Environment, egy a CDE-re emlékeztető ablakkezelő +Comment[is]=Kólesterol-lausa skjáborðsumhverfið. Skjáborð sem líkist CDE +Comment[it]=Il Cholesterol Free Desktop Environment. Un desktop environment che ricorda CDE +Comment[ja]=Cholesterol Free Desktop Environment, CDE を思わせる、むだのないデスクトップ環境 +Comment[ka]=CDE-ს მაგვარი სამუშაო დაფა ქოლესტერინის გარეშე +Comment[kk]=Cholesterol Free Desktop Environment. CDE-ге үқсас графикалық орта +Comment[km]=Cholesterol Free Desktop Environment ។ បរិស្ថាន​ផ្ទៃតុ​ដែល​សម្អាង​លើ CDE +Comment[lt]=Darbatalio aplinka „Be cholesterolio“. CDE primenanti darbastalio aplinka +Comment[lv]=Darbvirsmas vide bez holesterīna. Darba virsmas vide, kas atgādina CDE +Comment[mk]=Cholesterol Free Desktop Environment. Работна околина која потсетува на CDE +Comment[ms]=Persekitaran Desktop Bebas Kolesterol. Mengenang kembali persekitaran desktop CDE +Comment[mt]=Cholesterol Free Desktop Environment. Ambjent grafiku li jixbaħ lis-CDE +Comment[nb]=Det kolesterolfrie skrivebordsmiljø. Et skrivebordsmiljø som minner om CDE +Comment[nds]=De "Cholesterol Free Desktop Environment". En Schriefdisch-Ümgeven, de wat liek is to CDE +Comment[ne]=कोलेस्ट्रोल रहित डेस्कटप परिवेश । CDE को स्मरणशील डेस्कटप परिवेश +Comment[nl]=The Cholesterol Free Desktop Environment. Een desktop environment die herinnert aan CDE +Comment[nn]=Cholesterol Free Desktop Environment. Eit skrivebordsmiljø som minner om CDE +Comment[pa]=ਚੋਲੀਸਟੀਰੋਲ ਮੁਫਤ ਵਾਤਾਵਰਣ, ਇੱਕ CDE ਵਰਗਾ ਵਾਤਾਵਰਣ +Comment[pl]=Środowisko pulpitu przypominające CDE +Comment[pt]=O Cholesterol Free Desktop Environment. Um ambiente de trabalho com vestígios do CDE +Comment[pt_BR]=Acrônimo para Cholesterol Free Desktop Environment (ou ambiente livre de colesterol), um ambiente de trabalho remanescente do CDE +Comment[ro]=Cholesterol Free Desktop Environment. Un mediu grafic cu reminescente din CDE +Comment[ru]="Не содержащая холестерина" рабочая среда, напоминающая CDE +Comment[rw]=Ibikikije Ibiro Ubuntu Kolesiterole. Ibikikije ibiro nkumburwa bya CDE +Comment[se]=The Cholesterol Free Desktop Environment. Čállinbeavdebiras mii muittuha CDE +Comment[sk]=The Cholesterol Free Desktop Environment. Pracovné prostredie pripomínajúce CDE +Comment[sl]=Cholesterol Free Desktop Environment. Namizno okolje, podobno okolju CDE +Comment[sr]=„The Cholesterol Free Desktop Environment“. Радно окружење које подсећа на CDE +Comment[sr@Latn]=„The Cholesterol Free Desktop Environment“. Radno okruženje koje podseća na CDE +Comment[sv]=Den kolesterolfria skrivbordsmiljön. En skrivbordsmiljö som påminner om CDE +Comment[ta]=கொலஸ்ட்ரால் இல்லாத மேல்மேசை சூழல். CDE பொருள்பொதிந்த மேல்மேசை சூழல் +Comment[th]=สภาพแวดล้อมสำหรับเดสก์ทอปไร้คอเลสเตอรอล เป็นสภาพแวดล้อมสำหรับเดสก์ทอปที่เหลือมาจาก CDE +Comment[tr]=Cholesterol Masaüstü Ortamı +Comment[tt]=Holesterol Bulmağan Östäl Möxite. CDE küreneşendä +Comment[uk]=The Cholesterol Free Desktop Environment. Графічне середовище, що нагадує CDE +Comment[vi]=Môi trường Màn hình nền Không có Cholesterol. Một môi trường màn hình nền gợi nhớ lại CDE +Comment[wa]=Li Libe Evironmint di Scribanne Colesterole (Cholesterol Free Desktop Environment). On evironmint d' sicribanne ki nos vént d' CDE +Comment[zh_CN]=胆固醇自由桌面环境。CDE 桌面环境的追随者 +Comment[zh_TW]=Cholesterol 免費桌面環境。一個另人懷念的 CDE 桌面環境 diff --git a/tdm/kfrontend/sessions/xfce4.desktop b/tdm/kfrontend/sessions/xfce4.desktop new file mode 100644 index 000000000..11b4097a6 --- /dev/null +++ b/tdm/kfrontend/sessions/xfce4.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=XSession +Exec=startxfce4 +TryExec=startxfce4 +Name=XFce 4 +Name[eo]=Facoj 4 +Name[hi]=एक्सएफसीई4 +Name[sv]=Xfce 4 +Name[te]=ఎక్స్ ఎఫ్ సి ఈ 4 +Comment=The Cholesterol Free Desktop Environment, version 4. A desktop environment reminiscent of CDE +Comment[af]=Die Cholesterol Gratis Werkskerm Omgewing, weergawe 4. 'n Werkskerm omgewing wat op CDE gebaseer is +Comment[be]=XFCE4 - Cholesterol Free Desktop Environment, version 4. Працоўнае асяроддзе, падобнае на CDE +Comment[bn]=দি কলেস্টরল ফ্রী ডেস্কটপ এনভায়রনমেন্ট, ৪র্থ সংস্করণ। CDE-র কথা মনে করিয়ে দেয় এমন একটি ডেস্কটপ এনভায়রনমেন্ট +Comment[bs]=Cholesterol Free Desktop Environment. Desktop okolina nalik na CDE +Comment[ca]=L'entorn d'escriptori sense colesterol, versió 4. Un entorn d'escriptori que recorda a CDE +Comment[cs]=Svobodné grafické prostředí neobsahující cholesterol verze 4. Prostředí připomínající CDE +Comment[csb]=Cholesterol Free Desktop Environment, wersëjô 4 - graficzné òkrãże szlachùjące za CDE +Comment[cy]=Yr Amgylchedd Penbwrdd Di-Golesterol, fersiwn 4. Amgylchedd penbwrdd sy'n atgoffaol o CDE +Comment[da]=Det kolesterolfrie desktopmiljø, version 4. Et desktopmiljø der minder om CDE +Comment[de]=Cholesterol Free Desktop Environment, Version 4. Benutzerumgebung in der Art von CDE +Comment[el]=Το Cholesterol Free Desktop Environment, έκδοση 4. Ένα περιβάλλον επιφάνειας εργασίας βασισμένο στο CDE +Comment[eo]=La libera labortablo ĉirkaŭajo 4 +Comment[es]=El Cholesterol Free Desktop Environment, versión 4. Un entorno de escritorio que recuerda a CDE +Comment[et]=Kolesteroolivaba töölaua keskkond (versioon 4), mis meenutab mitmeti CDE-d +Comment[eu]=Kolesterolik gabeko mahaigain ingurunea, 4 bertsioa. CDE gogorarazten duen mahaigaina +Comment[fa]=محیط رومیزی آزاد Cholesterol، نسخه ۴. یادآور محیط رومیزی CDE +Comment[fi]=Cholesterol Free -työpöytäympäristö. CDE:tä muistuttavatyöpöytäympäristö. +Comment[fr]=The Cholesterol Free Desktop Environment, version 4. Un environnement de bureau rappelant CDE +Comment[fy]=De Cholesterol Free Desktop Environment, ferzje 4. In buroblêd omwrâld die tinken dat oan CDE +Comment[gl]=O Cholesterol Free Desktop Environment, versión 4. Un entorno de escritório reminiscencia de CDE +Comment[he]=The Cholesterol Free Desktop Environment. גרסה 4, סביבת עבודה המזכירה את CDE +Comment[hi]=कोलेस्ट्रॉल मुक्त डेस्कटॉप वातावरण, संस्करण 4. सीडीई की याद दिलाता एक डेस्कटॉप वातावरण +Comment[hr]=Cholesterol Free Desktop Environment verzija 4 - Okruženje radne površine koje podsjeća na CDE +Comment[hu]=The Cholesterol Free Desktop Environment, 4-es verzió. Egy CDE-szerű ablakkezelő +Comment[is]=Kólesterol-lausa skjáborðsumhverfið, útgáfa 4. Skjáborð sem líkist CDE +Comment[it]=Il Cholesterol Free Desktop Environment, versione 4. Un desktop environment che ricorda CDE +Comment[ja]=Cholesterol Free Desktop Environment, version 4, CDE を思わせる、むだのないデスクトップ環境 +Comment[ka]=CDE-ს მაგვარი უქოლესტერინო სამუშაო დაფა xfce 4 +Comment[kk]=Cholesterol Free Desktop Environment, 4-нұсқа. CDE-ге ұқсас графикалық орта +Comment[km]=Cholesterol Free Desktop Environment កំណែ 4 ។ បរិស្ថាន​ផ្ទៃតុ​ដែល​សម្អាង​លើ CDE +Comment[lt]=Darbatalio aplinka „Be cholesterolio“ , 4 versija. CDE primenanti darbastalio aplinka +Comment[lv]=Darbvirsmas vide bez holesterīna, versija 4. Darbavirsmas vide, kas atgādina CDE +Comment[mk]=Cholesterol Free Desktop Environment, верзија 4. Работна околина која потсетува на CDE +Comment[ms]=Persekitaran Desktop Bebas Kolesterol, versi 4. Mengingatkan kembali persekitaran desktop CDE +Comment[mt]=Cholesterol Free Desktop Environment (v4). Ambjent grafiku li jixbaħ lis-CDE +Comment[nb]=Det kolesterolfrie skrivebordet, versjon 4. Et skrivebordsmiljø som minner om CDE +Comment[nds]=De "Cholesterol Free Desktop Environment", Verschoon 4. En Schriefdisch-Ümgeven, de wat liek is to CDE +Comment[ne]=कोलेस्ट्रोल रहित डेस्कटप परिवेश, संस्करण ४ । CDE को स्मरणशील डेस्कटप परिवेश +Comment[nl]=De Cholesterol Free Desktop Environment, versie 4. Een desktop environment die herinnert aan CDE +Comment[nn]=Cholesterol Free Desktop Environment. Eit skrivebordsmiljø som minner om CDE +Comment[pa]=ਚੋਲੀਸਟੀਰੋਲ ਮੁਫਤ ਵਾਤਾਵਰਣ, ਵਰਜਨ 4 ਇੱਕ CDE ਵਰਗਾ ਵਾਤਾਵਰਣ +Comment[pl]=Cholesterol Free Desktop Environment, wersja 4 - środowisko graficzne podobne do CDE. +Comment[pt]=O Cholesterol Free Desktop Environment, versão 4. Um ambiente de trabalho com vestígios do CDE +Comment[pt_BR]=Acrônimo para Cholesterol Free Desktop Environment (ou ambiente livre de colesterol), versão 4; um ambiente de trabalho remanescente do CDE +Comment[ro]=Cholesterol Free Desktop Environment, versiunea 4. Un mediu grafic cu reminescente din CDE +Comment[ru]="Не содержащая холестерина" рабочая среда xfce версии 4, напоминающая CDE +Comment[rw]=Ibikikije Ibiro Ubuntu Kolesiterole, verisiyo 4. Ibikikije ibiro nkumburwa bya CDE +Comment[se]=The Cholesterol Free Desktop Environment, version 4. Čállinbeavdebiras mii muittuha CDE +Comment[sk]=The Cholesterol Free Desktop Environment verzia 4. Pracovné prostredie pripomínajúce CDE +Comment[sl]=Cholesterol Free Desktop Environment, različica 4. Namizno okolje, podobno okolju CDE +Comment[sr]=„The Cholesterol Free Desktop Environment“ 4. издање. Радно окружење које подсећа на CDE +Comment[sr@Latn]=„The Cholesterol Free Desktop Environment“ 4. izdanje. Radno okruženje koje podseća na CDE +Comment[sv]=Den kolesterolfria skrivbordsmiljön, version 4. En skrivbordsmiljö som påminner om CDE +Comment[ta]=கொலஸ்ட்ரால் இல்லாத மேல்மேசை சூழல். பதிப்பு 4. CDE பொருள்பொதிந்த மேல்மேசை சூழல் +Comment[th]=สภาพแวดล้อมสำหรับเดสก์ทอปแบบไร้คอเลสเตอรอล เวอร์ชั่น 4 เป็นสภาพแวดล้อมสำหรับเดสก์ทอปที่เหลือมาจาก CDE +Comment[tr]=Cholesterol Ücretsiz Masaüstü Ortamı, sürüm 4. CDE'nin benzeri olan masaüstü ortamı +Comment[tt]=Holesterol Bulmağan Östäl Möxiteneñ 4. söreme. CDE küreneşendä +Comment[uk]=The Cholesterol Free Desktop Environment, версія 4. Графічне середовище, що нагадує CDE +Comment[vi]=Môi trường Màn hình nền Không có Cholesterol, phiên bản 4. Một môi trường màn hình nền gợi nhớ lại CDE +Comment[wa]=Li Libe Evironmint di Scribanne Colesterole (Cholesterol Free Desktop Environment), modêye 4. On evironmint d' sicribanne ki nos vént d' CDE +Comment[zh_CN]=胆固醇自由桌面环境,版本 4。CDE 桌面环境的追随者 +Comment[zh_TW]=Cholesterol 免費桌面環境,第 4 版。一個另人懷念的 CDE 桌面環境 diff --git a/tdm/kfrontend/tdm_config.c b/tdm/kfrontend/tdm_config.c new file mode 100644 index 000000000..48f316320 --- /dev/null +++ b/tdm/kfrontend/tdm_config.c @@ -0,0 +1,1477 @@ +/* + +Read options from tdmrc + +Copyright (C) 2001-2005 Oswald Buddenhagen + + +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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _POSIX_PRIORITY_SCHEDULING +# include +#endif + +#include +#ifdef FamilyInternet6 +# define IPv6 +#endif + +#include +#include + +/* + * Section/Entry definition structs + */ + +typedef struct Ent { + const char *name; + int id; + void *ptr; + const char *def; +} Ent; + +typedef struct Sect { + const char *name; + Ent *ents; + int numents; +} Sect; + +/* + * Parsed ini file structs + */ + +typedef struct Entry { + struct Entry *next; + const char *val; + Ent *ent; + int vallen; + int line; +} Entry; + +typedef struct Section { + struct Section *next; + Entry *entries; + Sect *sect; + const char *name, *dname, *dhost, *dnum, *dclass; + int nlen, dlen, dhostl, dnuml, dclassl; +} Section; + + +/* + * Split up display-name/-class for fast comparison + */ +typedef struct DSpec { + const char *dhost, *dnum, *dclass; + int dhostl, dnuml, dclassl; +} DSpec; + + +/* + * Config value storage structures + */ + +typedef struct Value { + const char *ptr; + int len; +} Value; + +typedef struct Val { + Value val; + int id; +} Val; + +typedef struct ValArr { + Val *ents; + int nents, esiz, nchars, nptrs; +} ValArr; + + +static void *Malloc( size_t size ); +static void *Realloc( void *ptr, size_t size ); + +#define PRINT_QUOTES +#define LOG_NAME "tdm_config" +#define LOG_DEBUG_MASK DEBUG_CONFIG +#define LOG_PANIC_EXIT 1 +#define STATIC static +#include + + +static void * +Malloc( size_t size ) +{ + void *ret; + + if (!(ret = malloc( size ))) + LogOutOfMem(); + return ret; +} + +static void * +Realloc( void *ptr, size_t size ) +{ + void *ret; + + if (!(ret = realloc( ptr, size )) && size) + LogOutOfMem(); + return ret; +} + + +static void +MkDSpec( DSpec *spec, const char *dname, const char *dclass ) +{ + spec->dhost = dname; + for (spec->dhostl = 0; dname[spec->dhostl] != ':'; spec->dhostl++); + spec->dnum = dname + spec->dhostl + 1; + spec->dnuml = strlen( spec->dnum ); + spec->dclass = dclass; + spec->dclassl = strlen( dclass ); +} + + +static int rfd, wfd; + +static int +Reader( void *buf, int count ) +{ + int ret, rlen; + + for (rlen = 0; rlen < count; ) { + dord: + ret = read( rfd, (void *)((char *)buf + rlen), count - rlen ); + if (ret < 0) { + if (errno == EINTR) + goto dord; + if (errno == EAGAIN) + break; + return -1; + } + if (!ret) + break; + rlen += ret; + } + return rlen; +} + +static void +GRead( void *buf, int count ) +{ + if (Reader( buf, count ) != count) + LogPanic( "Can't read from core\n" ); +} + +static void +GWrite( const void *buf, int count ) +{ + if (write( wfd, buf, count ) != count) + LogPanic( "Can't write to core\n" ); +#ifdef _POSIX_PRIORITY_SCHEDULING + if ((debugLevel & DEBUG_HLPCON)) + sched_yield(); +#endif +} + +static void +GSendInt( int val ) +{ + GWrite( &val, sizeof(val) ); +} + +static void +GSendStr( const char *buf ) +{ + if (buf) { + int len = strlen( buf ) + 1; + GWrite( &len, sizeof(len) ); + GWrite( buf, len ); + } else + GWrite( &buf, sizeof(int)); +} + +static void +GSendNStr( const char *buf, int len ) +{ + int tlen = len + 1; + GWrite( &tlen, sizeof(tlen) ); + GWrite( buf, len ); + GWrite( "", 1 ); +} + +#ifdef XDMCP +static void +GSendArr( int len, const char *data ) +{ + GWrite( &len, sizeof(len) ); + GWrite( data, len ); +} +#endif + +static int +GRecvCmd( int *val ) +{ + if (Reader( val, sizeof(*val) ) != sizeof(*val)) + return 0; + return 1; +} + +static int +GRecvInt() +{ + int val; + + GRead( &val, sizeof(val) ); + return val; +} + +static char * +GRecvStr() +{ + int len; + char *buf; + + len = GRecvInt(); + if (!len) + return 0; + if (!(buf = malloc( len ))) + LogPanic( "No memory for read buffer" ); + GRead( buf, len ); + return buf; +} + + +/* #define WANT_CLOSE 1 */ + +typedef struct File { + char *buf, *eof, *cur; +#if defined(HAVE_MMAP) && defined(WANT_CLOSE) + int ismapped; +#endif +} File; + +static int +readFile( File *file, const char *fn, const char *what ) +{ + int fd; + off_t flen; + + if ((fd = open( fn, O_RDONLY )) < 0) { + LogInfo( "Cannot open %s file %s\n", what, fn ); + return 0; + } + + flen = lseek( fd, 0, SEEK_END ); +#ifdef HAVE_MMAP +# ifdef WANT_CLOSE + file->ismapped = 0; +# endif + file->buf = mmap( 0, flen + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0 ); +# ifdef WANT_CLOSE + if (file->buf) + file->ismapped = 1; + else +# else + if (!file->buf) +# endif +#endif + { + if (!(file->buf = Malloc( flen + 1 ))) { + close( fd ); + return 0; + } + lseek( fd, 0, SEEK_SET ); + if (read( fd, file->buf, flen ) != flen) { + free( file->buf ); + LogError( "Cannot read %s file %s\n", what, fn ); + close( fd ); + return 0; + } + } + file->eof = (file->cur = file->buf) + flen; + close( fd ); + return 1; +} + +#ifdef WANT_CLOSE +static void +freeBuf( File *file ) +{ +# ifdef HAVE_MMAP + if (file->ismapped) + munmap( file->buf, file->eof - file->buf + 1 ); + else +# endif + free( file->buf ); +} +#endif + +CONF_READ_VARS + +#define C_MTYPE_MASK 0x30000000 +# define C_PATH 0x10000000 /* C_TYPE_STR is a path spec */ +# define C_BOOL 0x10000000 /* C_TYPE_INT is a boolean */ +# define C_ENUM 0x20000000 /* C_TYPE_INT is an enum (option) */ +# define C_GRP 0x30000000 /* C_TYPE_INT is a group spec */ +#define C_INTERNAL 0x40000000 /* don't expose to core */ +#define C_CONFIG 0x80000000 /* process only for finding deps */ + +#ifdef XDMCP +static int +PrequestPort( Value *retval ) +{ + if (!VxdmcpEnable.ptr) { + retval->ptr = (char *)0; + return 1; + } + return 0; +} +#endif + +static Value + emptyStr = { "", 1 }, + nullValue = { 0, 0 }, + emptyArgv = { (char *)&nullValue, 0 }; + +static int +PnoPassUsers( Value *retval ) +{ + if (!VnoPassEnable.ptr) { + *retval = emptyArgv; + return 1; + } + return 0; +} + +static int +PautoLoginX( Value *retval ) +{ + if (!VautoLoginEnable.ptr) { + *retval = emptyStr; + return 1; + } + return 0; +} + +CONF_READ_ENTRIES + +static const char *tdmrc = TDMCONF "/tdmrc"; +static const char *tdmrc_dist = TDMCONF "/tdmdistrc"; + +static Section *rootsec; + +static void +ReadConf() +{ + const char *nstr, *dstr, *cstr, *dhost, *dnum, *dclass; + char *s, *e, *st, *en, *ek, *sl, *pt; + Section *cursec; + Entry *curent; + Ent *ce; + int nlen, dlen, clen, dhostl, dnuml, dclassl; + int i, line, sectmoan, restl; + File file; + static int confread; + + if (confread) + return; + confread = 1; + + Debug( "reading config %s ...\n", tdmrc_dist ); + if (!readFile( &file, tdmrc_dist, "master configuration" )) { + Debug( "reading config %s ...\n", tdmrc ); + if (!readFile( &file, tdmrc, "master configuration" )) + return; + } + else { + tdmrc = tdmrc_dist; + } + + for (s = file.buf, line = 0, cursec = 0, sectmoan = 1; s < file.eof; s++) { + line++; + + while ((s < file.eof) && isspace( *s ) && (*s != '\n')) + s++; + + if ((s < file.eof) && ((*s == '\n') || (*s == '#'))) { + sktoeol: + while ((s < file.eof) && (*s != '\n')) + s++; + continue; + } + sl = s; + + if (*s == '[') { + sectmoan = 0; + while ((s < file.eof) && (*s != '\n')) + s++; + e = s - 1; + while ((e > sl) && isspace( *e )) + e--; + if (*e != ']') { + cursec = 0; + LogError( "Invalid section header at %s:%d\n", tdmrc, line ); + continue; + } + nstr = sl + 1; + nlen = e - nstr; + for (cursec = rootsec; cursec; cursec = cursec->next) + if (nlen == cursec->nlen && + !memcmp( nstr, cursec->name, nlen )) + { + LogInfo( "Multiple occurrences of section [%.*s] in %s. " + "Consider merging them.\n", nlen, nstr, tdmrc ); + goto secfnd; + } + if (nstr[0] == 'X' && nstr[1] == '-') { + cstr = nstr + nlen; + clen = 0; + while (++clen, *--cstr != '-'); + if (cstr == nstr + 1) + goto illsec; + dstr = nstr + 2; + dlen = nlen - clen - 2; + dhost = dstr; + dhostl = 0; + for (restl = dlen; restl; restl--) { + if (dhost[dhostl] == ':') { + dnum = dhost + dhostl + 1; + dnuml = 0; + for (restl--; restl; restl--) { + if (dnum[dnuml] == '_') { + dclass = dnum + dnuml + 1; + dclassl = restl; + goto gotall; + } + dnuml++; + } + goto gotnum; + } + dhostl++; + } + dnum = "*"; + dnuml = 1; + gotnum: + dclass = "*"; + dclassl = 1; + gotall: ; + } else { + if (nstr[0] == '-') + goto illsec; + dstr = 0; + dlen = 0; + dhost = 0; + dhostl = 0; + dnum = 0; + dnuml = 0; + dclass = 0; + dclassl = 0; + cstr = nstr; + clen = nlen; + } + for (i = 0; i < as(allSects); i++) + if ((int)strlen( allSects[i]->name ) == clen && + !memcmp( allSects[i]->name, cstr, clen )) + goto newsec; + illsec: + cursec = 0; + LogError( "Unrecognized section name [%.*s] at %s:%d\n", + nlen, nstr, tdmrc, line ); + continue; + newsec: + if (!(cursec = Malloc( sizeof(*cursec) ))) + return; + cursec->name = nstr; + cursec->nlen = nlen; + cursec->dname = dstr; + cursec->dlen = dlen; + cursec->dhost = dhost; + cursec->dhostl = dhostl; + cursec->dnum = dnum; + cursec->dnuml = dnuml; + cursec->dclass = dclass; + cursec->dclassl = dclassl; + cursec->sect = allSects[i]; + cursec->entries = 0; + cursec->next = rootsec; + rootsec = cursec; + /*Debug( "now in section [%.*s], dpy '%.*s', core '%.*s'\n", + nlen, nstr, dlen, dstr, clen, cstr );*/ + secfnd: + continue; + } + + if (!cursec) { + if (sectmoan) { + sectmoan = 0; + LogError( "Entry outside any section at %s:%d", tdmrc, line ); + } + goto sktoeol; + } + + for (; (s < file.eof) && (*s != '\n'); s++) + if (*s == '=') + goto haveeq; + LogError( "Invalid entry (missing '=') at %s:%d\n", tdmrc, line ); + continue; + + haveeq: + for (ek = s - 1; ; ek--) { + if (ek < sl) { + LogError( "Invalid entry (empty key) at %s:%d\n", tdmrc, line ); + goto sktoeol; + } + if (!isspace( *ek )) + break; + } + + s++; + while ((s < file.eof) && isspace( *s ) && (*s != '\n')) + s++; + for (pt = st = en = s; s < file.eof && *s != '\n'; s++) { + if (*s == '\\') { + s++; + if (s >= file.eof || *s == '\n') { + LogError( "Trailing backslash at %s:%d\n", tdmrc, line ); + break; + } + switch (*s) { + case 's': *pt++ = ' '; break; + case 't': *pt++ = '\t'; break; + case 'n': *pt++ = '\n'; break; + case 'r': *pt++ = '\r'; break; + case '\\': *pt++ = '\\'; break; + default: *pt++ = '\\'; *pt++ = *s; break; + } + en = pt; + } else { + *pt++ = *s; + if (*s != ' ' && *s != '\t') + en = pt; + } + } + + nstr = sl; + nlen = ek - sl + 1; + /*Debug( "read entry '%.*s'='%.*s'\n", nlen, nstr, en - st, st );*/ + for (i = 0; i < cursec->sect->numents; i++) { + ce = cursec->sect->ents + i; + if ((int)strlen( ce->name ) == nlen && + !memcmp( ce->name, nstr, nlen )) + goto keyok; + } + LogError( "Unrecognized key '%.*s' in section [%.*s] at %s:%d\n", + nlen, nstr, cursec->nlen, cursec->name, tdmrc, line ); + continue; + keyok: + for (curent = cursec->entries; curent; curent = curent->next) + if (ce == curent->ent) { + LogError( "Multiple occurrences of key '%s' in section [%.*s]" + " of %s\n", + ce->name, cursec->nlen, cursec->name, tdmrc ); + goto keyfnd; + } + if (!(curent = Malloc( sizeof(*curent) ))) + return; + curent->ent = ce; + curent->line = line; + curent->val = st; + curent->vallen = en - st; + curent->next = cursec->entries; + cursec->entries = curent; + keyfnd: + continue; + } +} + +static Entry * +FindGEnt( int id ) +{ + Section *cursec; + Entry *curent; + + for (cursec = rootsec; cursec; cursec = cursec->next) + if (!cursec->dname) + for (curent = cursec->entries; curent; curent = curent->next) + if (curent->ent->id == id) { + Debug( "line %d: %s = %'.*s\n", + curent->line, curent->ent->name, + curent->vallen, curent->val ); + return curent; + } + return 0; +} + +/* Display name match scoring: + * - class (any/exact) -> 0/1 + * - number (any/exact) -> 0/2 + * - host (any/nonempty/trail/exact) -> 0/4/8/12 + */ +static Entry * +FindDEnt( int id, DSpec *dspec ) +{ + Section *cursec, *bestsec; + Entry *curent, *bestent; + int score, bestscore; + + bestscore = -1, bestent = 0; + for (cursec = rootsec; cursec; cursec = cursec->next) + if (cursec->dname) { + score = 0; + if (cursec->dclassl != 1 || cursec->dclass[0] != '*') { + if (cursec->dclassl == dspec->dclassl && + !memcmp( cursec->dclass, dspec->dclass, dspec->dclassl )) + score = 1; + else + continue; + } + if (cursec->dnuml != 1 || cursec->dnum[0] != '*') { + if (cursec->dnuml == dspec->dnuml && + !memcmp( cursec->dnum, dspec->dnum, dspec->dnuml )) + score += 2; + else + continue; + } + if (cursec->dhostl != 1 || cursec->dhost[0] != '*') { + if (cursec->dhostl == 1 && cursec->dhost[0] == '+') { + if (dspec->dhostl) + score += 4; + else + continue; + } else if (cursec->dhost[0] == '.') { + if (cursec->dhostl < dspec->dhostl && + !memcmp( cursec->dhost, + dspec->dhost + dspec->dhostl - cursec->dhostl, + cursec->dhostl )) + score += 8; + else + continue; + } else { + if (cursec->dhostl == dspec->dhostl && + !memcmp( cursec->dhost, dspec->dhost, dspec->dhostl )) + score += 12; + else + continue; + } + } + if (score > bestscore) { + for (curent = cursec->entries; curent; curent = curent->next) + if (curent->ent->id == id) { + bestent = curent; + bestsec = cursec; + bestscore = score; + break; + } + } + } + if (bestent) + Debug( "line %d: %.*s:%.*s_%.*s/%s = %'.*s\n", bestent->line, + bestsec->dhostl, bestsec->dhost, + bestsec->dnuml, bestsec->dnum, + bestsec->dclassl, bestsec->dclass, + bestent->ent->name, bestent->vallen, bestent->val ); + return bestent; +} + +static const char * +CvtValue( Ent *et, Value *retval, int vallen, const char *val, char **eopts ) +{ + Value *ents; + int i, b, e, tlen, nents, esiz; + char buf[80]; + + switch (et->id & C_TYPE_MASK) { + case C_TYPE_INT: + for (i = 0; i < vallen && i < (int)sizeof(buf) - 1; i++) + buf[i] = tolower( val[i] ); + buf[i] = 0; + if ((et->id & C_MTYPE_MASK) == C_BOOL) { + if (!strcmp( buf, "true" ) || + !strcmp( buf, "on" ) || + !strcmp( buf, "yes" ) || + !strcmp( buf, "1" )) + retval->ptr = (char *)1; + else if (!strcmp( buf, "false" ) || + !strcmp( buf, "off" ) || + !strcmp( buf, "no" ) || + !strcmp( buf, "0" )) + retval->ptr = (char *)0; + else + return "boolean"; + return 0; + } else if ((et->id & C_MTYPE_MASK) == C_ENUM) { + for (i = 0; eopts[i]; i++) + if (!memcmp( eopts[i], val, vallen ) && !eopts[i][vallen]) { + retval->ptr = (char *)i; + return 0; + } + return "option"; + } else if ((et->id & C_MTYPE_MASK) == C_GRP) { + struct group *ge; + if ((ge = getgrnam( buf ))) { + retval->ptr = (char *)ge->gr_gid; + return 0; + } + } + retval->ptr = 0; + if (sscanf( buf, "%li", &retval->ptr ) != 1) + return "integer"; + return 0; + case C_TYPE_STR: + retval->ptr = val; + retval->len = vallen + 1; + if ((et->id & C_MTYPE_MASK) == C_PATH) + if (vallen && val[vallen-1] == '/') + retval->len--; + return 0; + case C_TYPE_ARGV: + if (!(ents = Malloc( sizeof(Value) * (esiz = 10) ))) + return 0; + for (nents = 0, tlen = 0, i = 0; ; i++) { + for (; i < vallen && isspace( val[i] ); i++); + for (b = i; i < vallen && val[i] != ','; i++); + if (b == i) + break; + for (e = i; e > b && isspace( val[e - 1] ); e--); + if (esiz < nents + 2) { + Value *entsn = Realloc( ents, + sizeof(Value) * (esiz = esiz * 2 + 1) ); + if (!nents) + break; + ents = entsn; + } + ents[nents].ptr = val + b; + ents[nents].len = e - b; + nents++; + tlen += e - b + 1; + } + ents[nents].ptr = 0; + retval->ptr = (char *)ents; + retval->len = tlen; + return 0; + default: + LogError( "Internal error: unknown value type in id %#x\n", et->id ); + return 0; + } +} + +static void +GetValue( Ent *et, DSpec *dspec, Value *retval, char **eopts ) +{ + Entry *ent; + const char *errs; + +/* Debug( "Getting value %#x\n", et->id );*/ + if (dspec) + ent = FindDEnt( et->id, dspec ); + else + ent = FindGEnt( et->id ); + if (ent) { + if (!(errs = CvtValue( et, retval, ent->vallen, ent->val, eopts ))) + return; + LogError( "Invalid %s value '%.*s' at %s:%d\n", + errs, ent->vallen, ent->val, tdmrc, ent->line ); + } + Debug( "default: %s = %'s\n", et->name, et->def ); + if ((errs = CvtValue( et, retval, strlen( et->def ), et->def, eopts ))) + LogError( "Internal error: invalid default %s value '%s' for key %s\n", + errs, et->def, et->name ); +} + +static int +AddValue( ValArr *va, int id, Value *val ) +{ + int nu; + +/* Debug( "Addig value %#x\n", id );*/ + if (va->nents == va->esiz) { + va->ents = Realloc( va->ents, sizeof(Val) * (va->esiz += 50) ); + if (!va->ents) + return 0; + } + va->ents[va->nents].id = id; + va->ents[va->nents].val = *val; + va->nents++; + switch (id & C_TYPE_MASK) { + case C_TYPE_INT: + break; + case C_TYPE_STR: + va->nchars += val->len; + break; + case C_TYPE_ARGV: + va->nchars += val->len; + for (nu = 0; ((Value *)val->ptr)[nu++].ptr; ); + va->nptrs += nu; + break; + } + return 1; +} + +static void +CopyValues( ValArr *va, Sect *sec, DSpec *dspec, int isconfig ) +{ + Value val; + int i; + + Debug( "getting values for section class [%s]\n", sec->name ); + for (i = 0; i < sec->numents; i++) { +/*Debug ("value %#x\n", sec->ents[i].id);*/ + if ((sec->ents[i].id & (int)C_CONFIG) != isconfig) + ; + else if (sec->ents[i].id & C_INTERNAL) { + GetValue( sec->ents + i, dspec, ((Value *)sec->ents[i].ptr), 0 ); + } else { + if (((sec->ents[i].id & C_MTYPE_MASK) == C_ENUM) || + !sec->ents[i].ptr || + !((int (*)( Value * ))sec->ents[i].ptr)(&val)) { + GetValue( sec->ents + i, dspec, &val, + (char **)sec->ents[i].ptr ); + } + if (!AddValue( va, sec->ents[i].id, &val )) + break; + } + } + return; +} + +static void +SendValues( ValArr *va ) +{ + Value *cst; + int i, nu; + + GSendInt( va->nents ); + GSendInt( va->nptrs ); + GSendInt( 0/*va->nints*/ ); + GSendInt( va->nchars ); + for (i = 0; i < va->nents; i++) { + GSendInt( va->ents[i].id & ~C_PRIVATE ); + switch (va->ents[i].id & C_TYPE_MASK) { + case C_TYPE_INT: + GSendInt( (int)va->ents[i].val.ptr ); + break; + case C_TYPE_STR: + GSendNStr( va->ents[i].val.ptr, va->ents[i].val.len - 1 ); + break; + case C_TYPE_ARGV: + cst = (Value *)va->ents[i].val.ptr; + for (nu = 0; cst[nu].ptr; nu++); + GSendInt( nu ); + for (; cst->ptr; cst++) + GSendNStr( cst->ptr, cst->len ); + break; + } + } +} + + +#ifdef XDMCP +static char * +ReadWord( File *file, int *len, int EOFatEOL ) +{ + char *wordp, *wordBuffer; + int quoted; + char c; + + rest: + wordp = wordBuffer = file->cur; + mloop: + quoted = 0; + qloop: + if (file->cur == file->eof) { + doeow: + if (wordp == wordBuffer) + return 0; + retw: + *wordp = '\0'; + *len = wordp - wordBuffer; + return wordBuffer; + } + c = *file->cur++; + switch (c) { + case '#': + if (quoted) + break; + do { + if (file->cur == file->eof) + goto doeow; + c = *file->cur++; + } while (c != '\n'); + case '\0': + case '\n': + if (EOFatEOL && !quoted) { + file->cur--; + goto doeow; + } + if (wordp != wordBuffer) { + file->cur--; + goto retw; + } + goto rest; + case ' ': + case '\t': + if (wordp != wordBuffer) + goto retw; + goto rest; + case '\\': + if (!quoted) { + quoted = 1; + goto qloop; + } + break; + } + *wordp++ = c; + goto mloop; +} + +#define ALIAS_CHARACTER '%' +#define EQUAL_CHARACTER '=' +#define NEGATE_CHARACTER '!' +#define CHOOSER_STRING "CHOOSER" +#define BROADCAST_STRING "BROADCAST" +#define NOBROADCAST_STRING "NOBROADCAST" +#define LISTEN_STRING "LISTEN" +#define WILDCARD_STRING "*" + +typedef struct hostEntry { + struct hostEntry *next; + int type; + union _hostOrAlias { + char *aliasPattern; + char *hostPattern; + struct _display { + int connectionType; + int hostAddrLen; + char *hostAddress; + } displayAddress; + } entry; +} HostEntry; + +typedef struct listenEntry { + struct listenEntry *next; + int iface; + int mcasts; + int nmcasts; +} ListenEntry; + +typedef struct aliasEntry { + struct aliasEntry *next; + char *name; + HostEntry **pHosts; + int hosts; + int nhosts; + int hasBad; +} AliasEntry; + +typedef struct aclEntry { + struct aclEntry *next; + HostEntry **pEntries; + int entries; + int nentries; + HostEntry **pHosts; + int hosts; + int nhosts; + int flags; +} AclEntry; + + +static int +HasGlobCharacters( char *s ) +{ + for (;;) + switch (*s++) { + case '?': + case '*': + return 1; + case '\0': + return 0; + } +} + +#define PARSE_ALL 0 +#define PARSE_NO_BCAST 1 +#define PARSE_NO_PAT 2 +#define PARSE_NO_ALIAS 4 + +static int +ParseHost( int *nHosts, HostEntry ***hostPtr, int *nChars, + char *hostOrAlias, int len, int parse ) +{ +#if defined(IPv6) && defined(AF_INET6) + struct addrinfo *ai; +#else + struct hostent *hostent; +#endif + void *addr; + int addr_type, addr_len; + + if (!(**hostPtr = (HostEntry *)Malloc( sizeof(HostEntry)))) + return 0; + if (!(parse & PARSE_NO_BCAST) && !strcmp( hostOrAlias, BROADCAST_STRING )) + { + (**hostPtr)->type = HOST_BROADCAST; + } + else if (!(parse & PARSE_NO_ALIAS) && *hostOrAlias == ALIAS_CHARACTER) + { + (**hostPtr)->type = HOST_ALIAS; + (**hostPtr)->entry.aliasPattern = hostOrAlias + 1; + *nChars += len; + } + else if (!(parse & PARSE_NO_PAT) && HasGlobCharacters( hostOrAlias )) + { + (**hostPtr)->type = HOST_PATTERN; + (**hostPtr)->entry.hostPattern = hostOrAlias; + *nChars += len + 1; + } + else + { + (**hostPtr)->type = HOST_ADDRESS; +#if defined(IPv6) && defined(AF_INET6) + if (getaddrinfo( hostOrAlias, NULL, NULL, &ai )) +#else + if (!(hostent = gethostbyname( hostOrAlias ))) +#endif + { + LogWarn( "XDMCP ACL: unresolved host %'s\n", hostOrAlias ); + free( (char *)(**hostPtr) ); + return 0; + } +#if defined(IPv6) && defined(AF_INET6) + addr_type = ai->ai_addr->sa_family; + if (ai->ai_family == AF_INET) { + addr = &((struct sockaddr_in *)ai->ai_addr)->sin_addr; + addr_len = sizeof(struct in_addr); + } else /*if (ai->ai_addr->sa_family == AF_INET6)*/ { + addr = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr; + addr_len = sizeof(struct in6_addr); + } +#else + addr_type = hostent->h_addrtype; + addr = hostent->h_addr; + addr_len = hostent->h_length; +#endif + if (!((**hostPtr)->entry.displayAddress.hostAddress = + Malloc( addr_len ))) + { +#if defined(IPv6) && defined(AF_INET6) + freeaddrinfo( ai ); +#endif + free( (char *)(**hostPtr) ); + return 0; + } + memcpy( (**hostPtr)->entry.displayAddress.hostAddress, addr, addr_len ); + *nChars += addr_len; + (**hostPtr)->entry.displayAddress.hostAddrLen = addr_len; + (**hostPtr)->entry.displayAddress.connectionType = addr_type; +#if defined(IPv6) && defined(AF_INET6) + freeaddrinfo( ai ); +#endif + } + *hostPtr = &(**hostPtr)->next; + (*nHosts)++; + return 1; +} + +/* Returns non-0 if string is matched by pattern. Does case folding. */ +static int +patternMatch( const char *string, const char *pattern ) +{ + int p, s; + + if (!string) + string = ""; + + for (;;) { + s = *string++; + switch (p = *pattern++) { + case '*': + if (!*pattern) + return 1; + for (string--; *string; string++) + if (patternMatch( string, pattern )) + return 1; + return 0; + case '?': + if (s == '\0') + return 0; + break; + case '\0': + return s == '\0'; + case '\\': + p = *pattern++; + /* fall through */ + default: + if (tolower( p ) != tolower( s )) + return 0; + } + } +} + +#define MAX_DEPTH 32 + +#define CHECK_NOT 1 +#define CHECK_NO_PAT 2 + +static int +checkHostlist( HostEntry **hosts, int nh, AliasEntry *aliases, int na, + int depth, int flags ) +{ + HostEntry *h; + AliasEntry *a; + int hn, an, am; + + for (h = *hosts, hn = 0; hn < nh; hn++, h = h->next) + if (h->type == HOST_ALIAS) { + if (depth == MAX_DEPTH) { + LogError( "XDMCP ACL: alias recursion involving %%%s\n", + h->entry.aliasPattern ); + return 1; + } + for (a = aliases, an = 0, am = 0; an < na; an++, a = a->next) + if (patternMatch( a->name, h->entry.aliasPattern )) { + am = 1; + if ((flags & CHECK_NOT) && a->hasBad) { + LogError( "XDMCP ACL: alias %%%s with unresolved hosts " + "in denying rule\n", a->name ); + return 1; + } + if (checkHostlist( a->pHosts, a->nhosts, aliases, na, + depth + 1, flags )) + return 1; + } + if (!am) { + if (flags & CHECK_NOT) { + LogError( "XDMCP ACL: unresolved alias pattern %%%s " + "in denying rule\n", h->entry.aliasPattern ); + return 1; + } else + LogWarn( "XDMCP ACL: unresolved alias pattern %%%s\n", + h->entry.aliasPattern ); + } + } else if (h->type == HOST_PATTERN && (flags & CHECK_NO_PAT)) + LogWarn( "XDMCP ACL: wildcarded pattern %'s in host-only context\n", + h->entry.hostPattern ); + return 0; +} + +static void +ReadAccessFile( const char *fname ) +{ + HostEntry *hostList, **hostPtr = &hostList; + AliasEntry *aliasList, **aliasPtr = &aliasList; + AclEntry *acList, **acPtr = &acList, *acl; + ListenEntry *listenList, **listenPtr = &listenList; + char *displayOrAlias, *hostOrAlias; + File file; + int nHosts, nAliases, nAcls, nListens, nChars, error, bad; + int i, len; + + nHosts = nAliases = nAcls = nListens = nChars = error = 0; + if (!readFile( &file, fname, "XDMCP access control" )) + goto sendacl; + while ((displayOrAlias = ReadWord( &file, &len, FALSE ))) { + if (*displayOrAlias == ALIAS_CHARACTER) + { + if (!(*aliasPtr = (AliasEntry *)Malloc( sizeof(AliasEntry)))) { + error = 1; + break; + } + (*aliasPtr)->name = displayOrAlias + 1; + nChars += len; + (*aliasPtr)->hosts = nHosts; + (*aliasPtr)->pHosts = hostPtr; + (*aliasPtr)->nhosts = 0; + (*aliasPtr)->hasBad = 0; + while ((hostOrAlias = ReadWord( &file, &len, TRUE ))) { + if (ParseHost( &nHosts, &hostPtr, &nChars, hostOrAlias, len, + PARSE_NO_BCAST )) + (*aliasPtr)->nhosts++; + else + (*aliasPtr)->hasBad = 1; + } + aliasPtr = &(*aliasPtr)->next; + nAliases++; + } + else if (!strcmp( displayOrAlias, LISTEN_STRING )) + { + if (!(*listenPtr = (ListenEntry *)Malloc( sizeof(ListenEntry)))) { + error = 1; + break; + } + (*listenPtr)->iface = nHosts; + if (!(hostOrAlias = ReadWord( &file, &len, TRUE )) || + !strcmp( hostOrAlias, WILDCARD_STRING ) || + !ParseHost( &nHosts, &hostPtr, &nChars, hostOrAlias, len, + PARSE_NO_BCAST|PARSE_NO_PAT|PARSE_NO_ALIAS )) + { + (*listenPtr)->iface = -1; + } + (*listenPtr)->mcasts = nHosts; + (*listenPtr)->nmcasts = 0; + while ((hostOrAlias = ReadWord( &file, &len, TRUE ))) { + if (ParseHost( &nHosts, &hostPtr, &nChars, hostOrAlias, len, + PARSE_NO_BCAST|PARSE_NO_PAT|PARSE_NO_ALIAS )) + (*listenPtr)->nmcasts++; + } + listenPtr = &(*listenPtr)->next; + nListens++; + } + else + { + if (!(*acPtr = (AclEntry *)Malloc( sizeof(AclEntry)))) { + error = 1; + break; + } + (*acPtr)->flags = 0; + if (*displayOrAlias == NEGATE_CHARACTER) { + (*acPtr)->flags |= a_notAllowed; + displayOrAlias++; + } else if (*displayOrAlias == EQUAL_CHARACTER) + displayOrAlias++; + (*acPtr)->entries = nHosts; + (*acPtr)->pEntries = hostPtr; + (*acPtr)->nentries = 1; + if (!ParseHost( &nHosts, &hostPtr, &nChars, displayOrAlias, len, + PARSE_NO_BCAST )) + { + bad = 1; + if ((*acPtr)->flags & a_notAllowed) { + LogError( "XDMCP ACL: unresolved host in denying rule\n" ); + error = 1; + } + } else + bad = 0; + (*acPtr)->hosts = nHosts; + (*acPtr)->pHosts = hostPtr; + (*acPtr)->nhosts = 0; + while ((hostOrAlias = ReadWord( &file, &len, TRUE ))) { + if (!strcmp( hostOrAlias, CHOOSER_STRING )) + (*acPtr)->flags |= a_useChooser; + else if (!strcmp( hostOrAlias, NOBROADCAST_STRING )) + (*acPtr)->flags |= a_notBroadcast; + else { + if (ParseHost( &nHosts, &hostPtr, &nChars, + hostOrAlias, len, PARSE_NO_PAT )) + (*acPtr)->nhosts++; + } + } + if (!bad) { + acPtr = &(*acPtr)->next; + nAcls++; + } + } + } + + if (!nListens) { + if (!(*listenPtr = (ListenEntry *)Malloc( sizeof(ListenEntry)))) + error = 1; + else { + (*listenPtr)->iface = -1; + (*listenPtr)->mcasts = nHosts; + (*listenPtr)->nmcasts = 0; +#if defined(IPv6) && defined(AF_INET6) && defined(XDM_DEFAULT_MCAST_ADDR6) + if (ParseHost( &nHosts, &hostPtr, &nChars, + XDM_DEFAULT_MCAST_ADDR6, + sizeof(XDM_DEFAULT_MCAST_ADDR6)-1, + PARSE_ALL )) + (*listenPtr)->nmcasts++; +#endif + nListens++; + } + } + + for (acl = acList, i = 0; i < nAcls; i++, acl = acl->next) + if (checkHostlist( acl->pEntries, acl->nentries, aliasList, nAliases, + 0, (acl->flags & a_notAllowed) ? CHECK_NOT : 0 ) || + checkHostlist( acl->pHosts, acl->nhosts, aliasList, nAliases, + 0, CHECK_NO_PAT )) + error = 1; + + if (error) { + nHosts = nAliases = nAcls = nListens = nChars = 0; + sendacl: + LogError( "No XDMCP requests will be granted\n" ); + } + GSendInt( nHosts ); + GSendInt( nListens ); + GSendInt( nAliases ); + GSendInt( nAcls ); + GSendInt( nChars ); + for (i = 0; i < nHosts; i++, hostList = hostList->next) { + GSendInt( hostList->type ); + switch (hostList->type) { + case HOST_ALIAS: + GSendStr( hostList->entry.aliasPattern ); + break; + case HOST_PATTERN: + GSendStr( hostList->entry.hostPattern ); + break; + case HOST_ADDRESS: + GSendArr( hostList->entry.displayAddress.hostAddrLen, + hostList->entry.displayAddress.hostAddress ); + GSendInt( hostList->entry.displayAddress.connectionType ); + break; + } + } + for (i = 0; i < nListens; i++, listenList = listenList->next) { + GSendInt( listenList->iface ); + GSendInt( listenList->mcasts ); + GSendInt( listenList->nmcasts ); + } + for (i = 0; i < nAliases; i++, aliasList = aliasList->next) { + GSendStr( aliasList->name ); + GSendInt( aliasList->hosts ); + GSendInt( aliasList->nhosts ); + } + for (i = 0; i < nAcls; i++, acList = acList->next) { + GSendInt( acList->entries ); + GSendInt( acList->nentries ); + GSendInt( acList->hosts ); + GSendInt( acList->nhosts ); + GSendInt( acList->flags ); + } +} +#endif + + +int main( int argc ATTR_UNUSED, char **argv ) +{ + DSpec dspec; + ValArr va; + char *ci, *disp, *dcls, *cfgfile; + int what; + + if (!(ci = getenv( "CONINFO" ))) { + fprintf( stderr, "This program is part of tdm and should not be run manually.\n" ); + return 1; + } + if (sscanf( ci, "%d %d", &rfd, &wfd ) != 2) + return 1; + + InitLog(); + + if ((debugLevel = GRecvInt()) & DEBUG_WCONFIG) + sleep( 100 ); + +/* Debug ("parsing command line\n");*/ + if (**++argv) + tdmrc_dist = tdmrc = *argv; +/* + while (*++argv) { + } +*/ + + for (;;) { +/* Debug ("Awaiting command ...\n");*/ + if (!GRecvCmd( &what )) + break; + switch (what) { + case GC_Files: +/* Debug ("GC_Files\n");*/ + ReadConf(); + CopyValues( 0, &secGeneral, 0, C_CONFIG ); +#ifdef XDMCP + CopyValues( 0, &secXdmcp, 0, C_CONFIG ); + GSendInt( 2 ); +#else + GSendInt( 1 ); +#endif + GSendStr( tdmrc ); + GSendInt( -1 ); +#ifdef XDMCP + GSendNStr( VXaccess.ptr, VXaccess.len - 1 ); + GSendInt( 0 ); +#endif + for (; (what = GRecvInt()) != -1; ) + switch (what) { + case GC_gGlobal: + case GC_gDisplay: + GSendInt( 0 ); + break; +#ifdef XDMCP + case GC_gXaccess: + GSendInt( 1 ); + break; +#endif + default: + GSendInt( -1 ); + break; + } + break; + case GC_GetConf: +/* Debug( "GC_GetConf\n" );*/ + memset( &va, 0, sizeof(va) ); + what = GRecvInt(); + cfgfile = GRecvStr(); + switch (what) { + case GC_gGlobal: +/* Debug( "GC_gGlobal\n" );*/ + Debug( "getting global config\n" ); + ReadConf(); + CopyValues( &va, &secGeneral, 0, 0 ); +#ifdef XDMCP + CopyValues( &va, &secXdmcp, 0, 0 ); +#endif + CopyValues( &va, &secShutdown, 0, 0 ); + SendValues( &va ); + break; + case GC_gDisplay: +/* Debug( "GC_gDisplay\n" );*/ + disp = GRecvStr(); +/* Debug( " Display %s\n", disp );*/ + dcls = GRecvStr(); +/* Debug( " Class %s\n", dcls );*/ + Debug( "getting config for display %s, class %s\n", disp, dcls ); + MkDSpec( &dspec, disp, dcls ? dcls : "" ); + ReadConf(); + CopyValues( &va, &sec_Core, &dspec, 0 ); + CopyValues( &va, &sec_Greeter, &dspec, 0 ); + free( disp ); + if (dcls) + free( dcls ); + SendValues( &va ); + break; +#ifdef XDMCP + case GC_gXaccess: + ReadAccessFile( cfgfile ); + break; +#endif + default: + Debug( "Unsupported config category %#x\n", what ); + } + free( cfgfile ); + break; + default: + Debug( "Unknown config command %#x\n", what ); + } + } + +/* Debug( "Config reader exiting ..." );*/ + return EX_NORMAL; +} diff --git a/tdm/kfrontend/tdm_greet.c b/tdm/kfrontend/tdm_greet.c new file mode 100644 index 000000000..f74c2410d --- /dev/null +++ b/tdm/kfrontend/tdm_greet.c @@ -0,0 +1,787 @@ +/* + +KDE Greeter module for xdm + +Copyright (C) 2001-2003 Oswald Buddenhagen + +This file contains code from the old xdm core, +Copyright 1988, 1998 Keith Packard, MIT X Consortium/The Open Group + +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 + +#include "tdm_greet.h" +#include "tdmconfig.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _POSIX_PRIORITY_SCHEDULING +# include +#endif + +# include +#if defined(HAVE_XTEST) || defined(HAVE_XKB) +# include +#endif + +#ifdef HAVE_XTEST +# include +#endif + +#ifdef HAVE_XKB +# include +#endif + +extern void LogOutOfMem( void ); + +static void * +Realloc( void *ptr, size_t size ) +{ + void *ret; + + if (!(ret = realloc( ptr, size )) && size) + LogOutOfMem(); + return ret; +} + +#define PRINT_QUOTES +#define PRINT_ARRAYS +#define LOG_NAME "tdm_greet" +#define LOG_DEBUG_MASK DEBUG_GREET +#define LOG_PANIC_EXIT 1 +#define STATIC +#include + +static void +GDebug( const char *fmt, ... ) +{ + va_list args; + + if (debugLevel & DEBUG_HLPCON) { + va_start( args, fmt ); + Logger( DM_DEBUG, fmt, args ); + va_end( args ); + } +} + + +char *dname; + +int rfd; +static int wfd, mrfd, mwfd, srfd, swfd; +static const char *who; + +void +GSet( int master ) +{ + if (master) + rfd = mrfd, wfd = mwfd, who = "core (master)"; + else + rfd = srfd, wfd = swfd, who = "core"; + +} + +static int +Reader( void *buf, int count ) +{ + int ret, rlen; + + for (rlen = 0; rlen < count; ) { + dord: + ret = read( rfd, (void *)((char *)buf + rlen), count - rlen ); + if (ret < 0) { + if (errno == EINTR) + goto dord; + if (errno == EAGAIN) + break; + return -1; + } + if (!ret) + break; + rlen += ret; + } + return rlen; +} + +static void +GRead( void *buf, int count ) +{ + if (Reader( buf, count ) != count) + LogPanic( "Can't read from %s\n", who ); +} + +static void +GWrite( const void *buf, int count ) +{ + if (write( wfd, buf, count ) != count) + LogPanic( "Can't write to %s\n", who ); +#ifdef _POSIX_PRIORITY_SCHEDULING + if ((debugLevel & DEBUG_HLPCON)) + sched_yield(); +#endif +} + +void +GSendInt( int val ) +{ + GDebug( "Sending int %d (%#x) to %s\n", val, val, who ); + GWrite( &val, sizeof(val) ); +} + +void +GSendStr( const char *buf ) +{ + int len = buf ? strlen( buf ) + 1 : 0; + GDebug( "Sending string %'s to %s\n", buf, who ); + GWrite( &len, sizeof(len) ); + GWrite( buf, len ); +} + +/* +static void +GSendNStr( const char *buf, int len ) +{ + int tlen = len + 1; + GDebug( "Sending string %'.*s to %s\n", len, buf, who ); + GWrite( &tlen, sizeof(tlen) ); + GWrite( buf, len ); + GWrite( "", 1 ); +} +*/ + +void +GSendArr( int len, const char *buf ) +{ + GDebug( "Sending array %02[:*hhx to %s\n", len, buf, who ); + GWrite( &len, sizeof(len) ); + GWrite( buf, len ); +} + +int +GRecvInt() +{ + int val; + + GDebug( "Receiving int from %s ...\n", who ); + GRead( &val, sizeof(val) ); + GDebug( " -> %d (%#x)\n", val, val ); + return val; +} + +static char * +iGRecvArr( int *rlen ) +{ + int len; + char *buf; + + GRead( &len, sizeof(len) ); + *rlen = len; + GDebug( " -> %d bytes\n", len ); + if (!len) + return (char *)0; + if (!(buf = malloc( len ))) + LogPanic( "No memory for read buffer\n" ); + GRead( buf, len ); + return buf; +} + +char * +GRecvStr() +{ + int len; + char *buf; + + GDebug( "Receiving string from %s ...\n", who ); + buf = iGRecvArr( &len ); + GDebug( " -> %'.*s\n", len, buf ); + return buf; +} + +char ** +GRecvStrArr( int *rnum ) +{ + int num; + char **argv, **cargv; + + GDebug( "Receiving string array from %s ...\n", who ); + GRead( &num, sizeof(num) ); + GDebug( " -> %d strings\n", num ); + if (rnum) + *rnum = num; + if (!num) + return (char **)0; + if (!(argv = malloc( num * sizeof(char *)))) + LogPanic( "No memory for read buffer\n" ); + for (cargv = argv; --num >= 0; cargv++) + *cargv = GRecvStr(); + return argv; +} + +char * +GRecvArr( int *num ) +{ + char *arr; + + GDebug( "Receiving array from %s ...\n", who ); + GRead( num, sizeof(*num) ); + GDebug( " -> %d bytes\n", *num ); + if (!*num) + return (char *)0; + if (!(arr = malloc( *num ))) + LogPanic( "No memory for read buffer\n" ); + GRead( arr, *num ); + GDebug( " -> %02[*hhx\n", *num, arr ); + return arr; +} + +static void +ReqCfg( int id ) +{ + GSendInt( G_GetCfg ); + GSendInt( id ); + switch (GRecvInt()) { + case GE_NoEnt: + LogPanic( "Config value %#x not available\n", id ); + case GE_BadType: + LogPanic( "Core does not know type of config value %#x\n", id ); + } +} + +int +GetCfgInt( int id ) +{ + ReqCfg( id ); + return GRecvInt(); +} + +char * +GetCfgStr( int id ) +{ + ReqCfg( id ); + return GRecvStr(); +} + +char ** +GetCfgStrArr( int id, int *len ) +{ + ReqCfg( id ); + return GRecvStrArr( len ); +} + +static void +disposeSession( dpySpec *sess ) +{ + free( sess->display ); + free( sess->from ); + if (sess->user) + free( sess->user ); + if (sess->session) + free( sess->session ); +} + +dpySpec * +fetchSessions( int flags ) +{ + dpySpec *sess, *sessions = 0, tsess; + + GSet( 1 ); + GSendInt( G_List ); + GSendInt( flags ); + next: + while ((tsess.display = GRecvStr())) { + tsess.from = GRecvStr(); +#ifdef HAVE_VTS + tsess.vt = GRecvInt(); +#endif + tsess.user = GRecvStr(); + tsess.session = GRecvStr(); + tsess.flags = GRecvInt(); + if ((tsess.flags & isTTY) && *tsess.from) + for (sess = sessions; sess; sess = sess->next) + if (sess->user && !strcmp( sess->user, tsess.user ) && + !strcmp( sess->from, tsess.from )) + { + sess->count++; + disposeSession( &tsess ); + goto next; + } + if (!(sess = malloc( sizeof(*sess) ))) + LogPanic( "Out of memory\n" ); + tsess.count = 1; + tsess.next = sessions; + *sess = tsess; + sessions = sess; + } + GSet( 0 ); + return sessions; +} + +void +disposeSessions( dpySpec *sess ) +{ + while (sess) { + dpySpec *nsess = sess->next; + disposeSession( sess ); + free( sess ); + sess = nsess; + } +} + +void +freeStrArr( char **arr ) +{ + char **tarr; + + if (arr) { + for (tarr = arr; *tarr; tarr++) + free( *tarr ); + free( arr ); + } +} + + +static int +ignoreErrors( Display *dpy ATTR_UNUSED, XErrorEvent *event ATTR_UNUSED ) +{ + Debug( "ignoring X error\n" ); + return 0; +} + +/* + * this is mostly bogus -- but quite useful. I wish the protocol + * had some way of enumerating and identifying clients, that way + * this code wouldn't have to be this kludgy. + */ + +static void +killWindows( Display *dpy, Window window ) +{ + Window root, parent, *children; + unsigned child, nchildren = 0; + + while (XQueryTree( dpy, window, &root, &parent, &children, &nchildren ) + && nchildren > 0) + { + for (child = 0; child < nchildren; child++) { + Debug( "XKillClient 0x%lx\n", (unsigned long)children[child] ); + XKillClient( dpy, children[child] ); + } + XFree( (char *)children ); + } +} + +static jmp_buf resetJmp; + +static void +abortReset( int n ATTR_UNUSED ) +{ + longjmp (resetJmp, 1); +} + +/* + * this display connection better not have any windows... + */ + +static void +pseudoReset( Display *dpy ) +{ + int screen; + + if (setjmp( resetJmp )) { + LogError( "pseudoReset timeout\n" ); + } else { + (void)signal( SIGALRM, abortReset ); + (void)alarm( 30 ); + XSetErrorHandler( ignoreErrors ); + for (screen = 0; screen < ScreenCount( dpy ); screen++) { + Debug( "pseudoReset screen %d\n", screen ); + killWindows( dpy, RootWindow( dpy, screen ) ); + } + Debug( "before XSync\n" ); + XSync( dpy, False ); + (void)alarm( 0 ); + } + signal( SIGALRM, SIG_DFL ); + XSetErrorHandler( (XErrorHandler)0 ); + Debug( "pseudoReset done\n" ); +} + + +static jmp_buf syncJump; + +static void +syncTimeout( int n ATTR_UNUSED ) +{ + longjmp( syncJump, 1 ); +} + +void +SecureDisplay( Display *dpy ) +{ + Debug( "SecureDisplay %s\n", dname ); + (void)signal( SIGALRM, syncTimeout ); + if (setjmp( syncJump )) { + LogError( "Display %s could not be secured\n", dname ); + exit( EX_RESERVER_DPY ); + } + (void)alarm( (unsigned)_grabTimeout ); + Debug( "Before XGrabServer %s\n", dname ); + XGrabServer( dpy ); + Debug( "XGrabServer succeeded %s\n", dname ); + if (XGrabKeyboard( dpy, DefaultRootWindow( dpy ), True, GrabModeAsync, + GrabModeAsync, CurrentTime ) != GrabSuccess) + { + (void)alarm( 0 ); + (void)signal( SIGALRM, SIG_DFL ); + LogError( "Keyboard on display %s could not be secured\n", dname ); + sleep( 10 ); + exit( EX_RESERVER_DPY ); + } + (void)alarm( 0 ); + (void)signal( SIGALRM, SIG_DFL ); + pseudoReset( dpy ); + if (!_grabServer) + { + XUngrabServer( dpy ); + XSync( dpy, 0 ); + } + Debug( "done secure %s\n", dname ); +#ifdef HAVE_XKBSETPERCLIENTCONTROLS + /* + * Activate the correct mapping for modifiers in XKB extension as + * grabbed keyboard has its own mapping by default + */ + { + int opcode, evbase, errbase, majret, minret; + unsigned int value = XkbPCF_GrabsUseXKBStateMask; + if (XkbQueryExtension( dpy, &opcode, &evbase, + &errbase, &majret, &minret )) + XkbSetPerClientControls( dpy, value, &value ); + } +#endif +} + +void +UnsecureDisplay( Display *dpy ) +{ + Debug( "Unsecure display %s\n", dname ); + if (_grabServer) { + XUngrabServer( dpy ); + XSync( dpy, 0 ); + } +} + +static jmp_buf pingTime; + +static int +PingLostIOErr( Display *dpy ATTR_UNUSED ) +{ + longjmp( pingTime, 1 ); +} + +static void +PingLostSig( int n ATTR_UNUSED ) +{ + longjmp( pingTime, 1 ); +} + +int +PingServer( Display *dpy ) +{ + int (*oldError)( Display * ); + void (*oldSig)( int ); + int oldAlarm; + + oldError = XSetIOErrorHandler( PingLostIOErr ); + oldAlarm = alarm( 0 ); + oldSig = signal( SIGALRM, PingLostSig ); + (void)alarm( _pingTimeout * 60 ); + if (!setjmp( pingTime )) { + Debug( "Ping server\n" ); + XSync( dpy, 0 ); + } else { + Debug( "Server dead\n" ); + (void)alarm( 0 ); + (void)signal( SIGALRM, SIG_DFL ); + XSetIOErrorHandler( oldError ); + return 0; + } + (void)alarm( 0 ); + (void)signal( SIGALRM, oldSig ); + (void)alarm( oldAlarm ); + Debug( "Server alive\n" ); + XSetIOErrorHandler( oldError ); + return 1; +} + +/* + * Modifier changing code based on tdebase/kxkb/kcmmisc.cpp + * + * XTest part: Copyright (C) 2000-2001 Lubos Lunak + * XKB part: Copyright (C) 2001-2002 Oswald Buddenhagen + * + */ + +#ifdef HAVE_XKB +static int +xkb_init( Display *dpy ) +{ + int xkb_opcode, xkb_event, xkb_error; + int xkb_lmaj = XkbMajorVersion; + int xkb_lmin = XkbMinorVersion; + return XkbLibraryVersion( &xkb_lmaj, &xkb_lmin ) && + XkbQueryExtension( dpy, &xkb_opcode, &xkb_event, + &xkb_error, &xkb_lmaj, &xkb_lmin ); +} + +static unsigned int +xkb_modifier_mask_work( XkbDescPtr xkb, const char *name ) +{ + int i; + + if (!xkb->names) + return 0; + for (i = 0; i < XkbNumVirtualMods; i++) { + char *modStr = XGetAtomName( xkb->dpy, xkb->names->vmods[i] ); + if (modStr != NULL && strcmp( name, modStr ) == 0) { + unsigned int mask; + XkbVirtualModsToReal( xkb, 1 << i, &mask ); + return mask; + } + } + return 0; +} + +static unsigned int +xkb_modifier_mask( Display *dpy, const char *name ) +{ + XkbDescPtr xkb; + + if ((xkb = XkbGetKeyboard( dpy, XkbAllComponentsMask, XkbUseCoreKbd ))) { + unsigned int mask = xkb_modifier_mask_work( xkb, name ); + XkbFreeKeyboard( xkb, 0, True ); + return mask; + } + return 0; +} + +static int +xkb_get_modifier_state( Display *dpy, const char *name ) +{ + unsigned int mask; + XkbStateRec state; + + if (!(mask = xkb_modifier_mask( dpy, name ))) + return 0; + XkbGetState( dpy, XkbUseCoreKbd, &state ); + return (mask & state.locked_mods) != 0; +} + +static int +xkb_set_modifier( Display *dpy, const char *name, int sts ) +{ + unsigned int mask; + + if (!(mask = xkb_modifier_mask( dpy, name ))) + return 0; + XkbLockModifiers( dpy, XkbUseCoreKbd, mask, sts ? mask : 0 ); + return 1; +} +#endif /* HAVE_XKB */ + +#ifdef HAVE_XTEST +static int +xtest_get_modifier_state( Display *dpy, int key ) +{ + XModifierKeymap *map; + KeyCode modifier_keycode; + unsigned int i, mask; + Window dummy1, dummy2; + int dummy3, dummy4, dummy5, dummy6; + + if ((modifier_keycode = XKeysymToKeycode( dpy, key )) == NoSymbol) + return 0; + map = XGetModifierMapping( dpy ); + for (i = 0; i < 8; ++i) + if (map->modifiermap[map->max_keypermod * i] == modifier_keycode) { + XFreeModifiermap( map ); + XQueryPointer( dpy, DefaultRootWindow( dpy ), + &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, + &mask ); + return (mask & (1 << i)) != 0; + } + XFreeModifiermap( map ); + return 0; +} + +static void +xtest_fake_keypress( Display *dpy, int key ) +{ + XTestFakeKeyEvent( dpy, XKeysymToKeycode( dpy, key ), True, CurrentTime ); + XTestFakeKeyEvent( dpy, XKeysymToKeycode( dpy, key ), False, CurrentTime ); +} +#endif /* HAVE_XTEST */ + +#ifdef HAVE_XKB +static int havexkb; +#endif +static int nummodified, oldnumstate, newnumstate; +static Display *dpy; + +void +setup_modifiers( Display *mdpy, int numlock ) +{ + if (numlock == 2) + return; + newnumstate = numlock; + nummodified = 1; + dpy = mdpy; +#ifdef HAVE_XKB + if (xkb_init( mdpy )) { + havexkb = 1; + oldnumstate = xkb_get_modifier_state( mdpy, "NumLock" ); + xkb_set_modifier( mdpy, "NumLock", numlock ); + return; + } +#endif +#ifdef HAVE_XTEST + oldnumstate = xtest_get_modifier_state( mdpy, XK_Num_Lock ); + if (oldnumstate != numlock) + xtest_fake_keypress( mdpy, XK_Num_Lock ); +#endif +} + +void +restore_modifiers( void ) +{ +#ifdef HAVE_XTEST + int numstat; +#endif + + if (!nummodified) + return; +#ifdef HAVE_XKB + if (havexkb) { + if (xkb_get_modifier_state( dpy, "NumLock" ) == newnumstate) + xkb_set_modifier( dpy, "NumLock", oldnumstate ); + return; + } +#endif +#ifdef HAVE_XTEST + numstat = xtest_get_modifier_state( dpy, XK_Num_Lock ); + if (numstat == newnumstate && newnumstate != oldnumstate) + xtest_fake_keypress( dpy, XK_Num_Lock ); +#endif +} + +void +setCursor( Display *mdpy, int window, int shape ) +{ + Cursor xcursor; + + if ((xcursor = XCreateFontCursor( mdpy, shape ))) { + XDefineCursor( mdpy, window, xcursor ); + XFreeCursor( mdpy, xcursor ); + XFlush( mdpy ); + } +} + +static void +sigterm( int n ATTR_UNUSED ) +{ + exit( EX_NORMAL ); +} + +static char *savhome; + +static void +cleanup( void ) +{ + char buf[128]; + + if (strcmp( savhome, getenv( "HOME" ) ) || memcmp( savhome, "/tmp/", 5 )) + LogError( "Internal error: memory corruption detected\n" ); /* no panic: recursion */ + else { + sprintf( buf, "rm -rf %s", savhome ); + system( buf ); + } +} + +extern void kg_main( const char *argv0 ); + +int +main( int argc ATTR_UNUSED, char **argv ) +{ + char *ci; + int i; + char qtrc[40]; + + if (!(ci = getenv( "CONINFO" ))) { + fprintf( stderr, "This program is part of tdm and should not be run manually.\n" ); + return 1; + } + if (sscanf( ci, "%d %d %d %d", &srfd, &swfd, &mrfd, &mwfd ) != 4) + return 1; + fcntl( srfd, F_SETFD, FD_CLOEXEC ); + fcntl( swfd, F_SETFD, FD_CLOEXEC ); + fcntl( mrfd, F_SETFD, FD_CLOEXEC ); + fcntl( mwfd, F_SETFD, FD_CLOEXEC ); + GSet( 0 ); + + InitLog(); + + if ((debugLevel = GRecvInt()) & DEBUG_WGREET) + sleep( 100 ); + + signal( SIGTERM, sigterm ); + + dname = getenv( "DISPLAY" ); + + init_config(); + + /* for TQSettings */ + srand( time( 0 ) ); + for (i = 0; i < 10000; i++) { + sprintf( qtrc, "/tmp/%010d", rand() ); + if (!mkdir( qtrc, 0700 )) + goto okay; + } + LogPanic( "Cannot create $HOME\n" ); + okay: + if (setenv( "HOME", qtrc, 1 )) + LogPanic( "Cannot set $HOME\n" ); + if (!(savhome = strdup( qtrc ))) + LogPanic( "Cannot save $HOME\n" ); + atexit( cleanup ); + + setenv( "LC_ALL", _language, 1 ); + + kg_main( argv[0] ); + + return EX_NORMAL; +} diff --git a/tdm/kfrontend/tdm_greet.h b/tdm/kfrontend/tdm_greet.h new file mode 100644 index 000000000..9f7e3bd6a --- /dev/null +++ b/tdm/kfrontend/tdm_greet.h @@ -0,0 +1,91 @@ +/* + +KDE Greeter module for xdm + +Copyright (C) 2001-2003 Oswald Buddenhagen + +This file contains code from the old xdm core, +Copyright 1988, 1998 Keith Packard, MIT X Consortium/The Open Group + +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. + +*/ + +#ifndef _TDM_GREET_H_ +#define _TDM_GREET_H_ + +#include /* for the ATTR_ defines */ +#include /* for the HAVE_VTS define */ + +#ifdef __cplusplus +extern "C" { +#endif + +void GSet( int master ); +void GSendInt( int val ); +void GSendStr( const char *buf ); +/*void GSendNStr( const char *buf, int len );*/ +void GSendArr( int len, const char *buf ); +int GRecvInt( void ); +char *GRecvStr( void ); +char **GRecvStrArr( int *len ); +char *GRecvArr( int *len ); + +int GetCfgInt( int id ); +char *GetCfgStr( int id ); +char **GetCfgStrArr( int id, int *len ); + +typedef struct dpySpec { + struct dpySpec *next; + char *display, *from, *user, *session; +#ifdef HAVE_VTS + int vt; +#endif + int flags; + int count; +} dpySpec; + +dpySpec *fetchSessions( int flags ); +void disposeSessions( dpySpec *sess ); + +void freeStrArr( char **arr ); + +void Debug( const char *fmt, ... ); +void LogInfo( const char *fmt, ... ); +void LogWarn( const char *fmt, ... ); +void LogError( const char *fmt, ... ); +void LogPanic( const char *fmt, ... ) ATTR_NORETURN; + +struct _XDisplay; + +void SecureDisplay( struct _XDisplay *dpy ); +void UnsecureDisplay( struct _XDisplay *dpy ); +int PingServer( struct _XDisplay *dpy ); + +void setup_modifiers( struct _XDisplay *mdpy, int numlock ); +void restore_modifiers( void ); + +void setCursor( struct _XDisplay *mdpy, int window, int shape ); + + +extern int rfd; /* for select() loops */ + +extern char *dname; /* d->name */ + +#ifdef __cplusplus +} +#endif + +#endif /* _TDM_GREET_H_ */ diff --git a/tdm/kfrontend/tdmadmindialog.cpp b/tdm/kfrontend/tdmadmindialog.cpp new file mode 100644 index 000000000..6486eb3dc --- /dev/null +++ b/tdm/kfrontend/tdmadmindialog.cpp @@ -0,0 +1,176 @@ + /* + + Admin dialog + + Copyright (C) 1997, 1998, 2000 Steffen Hansen + Copyright (C) 2000-2003 Oswald Buddenhagen + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +#include "tdmadmindialog.h" +#include "tdmconfig.h" +#include "kgdialog.h" +#include "tdm_greet.h" +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +int TDMAdmin::curPlugin = -1; +PluginList TDMAdmin::pluginList; + +TDMAdmin::TDMAdmin( const TQString &user, TQWidget *_parent ) + : inherited( _parent ) + , verify( 0 ), curUser(user) +{ + TQSizePolicy fp( TQSizePolicy::Fixed, TQSizePolicy::Fixed ); + + TQVBoxLayout *box = new TQVBoxLayout( this, 10 ); + + TQHBoxLayout *hlay = new TQHBoxLayout( box ); + + GSendInt( G_ReadDmrc ); + GSendStr( "root" ); + GRecvInt(); // ignore status code ... + + if (curPlugin < 0) { + curPlugin = 0; + pluginList = KGVerify::init( "classic" ); + } + verify = new KGStdVerify( this, this, + this, "root", + pluginList, KGreeterPlugin::Authenticate, + KGreeterPlugin::Shutdown ); + verify->selectPlugin( curPlugin ); + box->addLayout( verify->getLayout() ); + TQAccel *accel = new TQAccel( this ); + accel->insertItem( ALT+Key_A, 0 ); + connect( accel, TQT_SIGNAL(activated(int)), TQT_SLOT(slotActivatePlugMenu()) ); + + box->addWidget( new KSeparator( KSeparator::HLine, this ) ); + + okButton = new KPushButton( KStdGuiItem::ok(), this ); + okButton->setSizePolicy( fp ); + okButton->setDefault( true ); + cancelButton = new KPushButton( KStdGuiItem::cancel(), this ); + cancelButton->setSizePolicy( fp ); + + hlay = new TQHBoxLayout( box ); + hlay->addStretch( 1 ); + hlay->addWidget( okButton ); + hlay->addStretch( 1 ); + hlay->addWidget( cancelButton ); + hlay->addStretch( 1 ); + + connect( okButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); + connect( cancelButton, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) ); + + slotWhenChanged(); +} + +TDMAdmin::~TDMAdmin() +{ + hide(); + delete verify; +} + +void +TDMAdmin::slotActivatePlugMenu() +{ + TQPopupMenu *cmnu = verify->getPlugMenu(); + TQSize sh( cmnu->sizeHint() / 2 ); + cmnu->exec( geometry().center() - TQPoint( sh.width(), sh.height() ) ); +} + +void +TDMAdmin::accept() +{ + verify->accept(); +} + +void +TDMAdmin::slotWhenChanged() +{ + verify->abort(); + verify->setEnabled( 1 ); + verify->start(); +} + +void +TDMAdmin::bye_bye() +{ + GSendInt( G_GetDmrc ); + GSendStr( "Session" ); + char *sess = GRecvStr(); + if (sess && strcmp(sess, "admin")) { + GSendInt( G_PutDmrc ); + GSendStr( "OrigSession"); + GSendStr( sess); + free(sess); + } + + GSendInt( G_PutDmrc ); + GSendStr( "Session" ); + GSendStr( "admin" ); + inherited::accept(); +} + +void +TDMAdmin::verifyPluginChanged( int id ) +{ + curPlugin = id; + adjustSize(); +} + +void +TDMAdmin::verifyOk() +{ + bye_bye(); +} + +void +TDMAdmin::verifyFailed() +{ + okButton->setEnabled( false ); + cancelButton->setEnabled( false ); +} + +void +TDMAdmin::verifyRetry() +{ + okButton->setEnabled( true ); + cancelButton->setEnabled( true ); +} + +void +TDMAdmin::verifySetUser( const TQString & ) +{ +} + + +#include "tdmadmindialog.moc" diff --git a/tdm/kfrontend/tdmadmindialog.h b/tdm/kfrontend/tdmadmindialog.h new file mode 100644 index 000000000..e5a68fbb9 --- /dev/null +++ b/tdm/kfrontend/tdmadmindialog.h @@ -0,0 +1,70 @@ + /* + + Shutdown dialog + + Copyright (C) 1997, 1998 Steffen Hansen + Copyright (C) 2000-2003 Oswald Buddenhagen + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + + +#ifndef TDMADMIN_H +#define TDMADMIN_H + +#include "kgverify.h" + +#include + +class LiloInfo; +class TQLabel; +class KPushButton; +class TQButtonGroup; +class TQComboBox; + +class TDMAdmin : public FDialog, public KGVerifyHandler { + Q_OBJECT + typedef FDialog inherited; + +public: + TDMAdmin( const TQString &user, TQWidget *_parent = 0 ); + ~TDMAdmin(); + +public slots: + void accept(); + void slotWhenChanged(); + void slotActivatePlugMenu(); + +private: + void bye_bye(); + + KPushButton *okButton, *cancelButton; + KGStdVerify *verify; + TQString curUser; + + static int curPlugin; + static PluginList pluginList; + +public: // from KGVerifyHandler + virtual void verifyPluginChanged( int id ); + virtual void verifyOk(); + virtual void verifyFailed(); + virtual void verifyRetry(); + virtual void verifySetUser( const TQString &user ); +}; + +#endif diff --git a/tdm/kfrontend/tdmclock.cpp b/tdm/kfrontend/tdmclock.cpp new file mode 100644 index 000000000..2b2a99cea --- /dev/null +++ b/tdm/kfrontend/tdmclock.cpp @@ -0,0 +1,176 @@ +/* + +clock module for tdm + +Copyright (C) 2000 Espen Sand, espen@kde.org + Based on work by NN(yet to be determined) +flicker free code by Remi Guyomarch + +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 "tdmclock.h" + +//#include +//#include + +#include +#include +#include +#include + +KdmClock::KdmClock( TQWidget *parent, const char *name ) + : inherited( parent, name ) +{ + // start timer + TQTimer *timer = new TQTimer( this ); + connect( timer, TQT_SIGNAL(timeout()), TQT_SLOT(timeout()) ); + timer->start( 1000 ); + + // reading rc file + //KConfig *config = kapp->config(); + + //config->setGroup( "Option" ); + mDate = false;//config->readNumEntry( "date", FALSE ); + mSecond = true;//config->readNumEntry( "second", TRUE ); + mDigital = false;//config->readNumEntry( "digital", FALSE ); + mBorder = false;//config->readNumEntry( "border", FALSE ); + + //config->setGroup( "Font" ); + mFont.setFamily( TQString::fromLatin1("Utopia")/*config->readEntry( "Family", "Utopia")*/ ); + mFont.setPointSize( 51/*config->readNumEntry( "Point Size", 51)*/ ); + mFont.setWeight( 75/*config->readNumEntry( "Weight", 75)*/ ); + mFont.setItalic( TRUE/*config->readNumEntry( "Italic",TRUE )*/ ); + mFont.setBold( TRUE/*config->readNumEntry( "Bold",TRUE )*/ ); + + setFixedSize( 100, 100 ); + + if (mBorder) { + setLineWidth( 1 ); + setFrameStyle( Box|Plain ); + //setFrameStyle( WinPanel|Sunken ); + } + +/* + if (!mDigital) { + if (height() < width()) + resize( height(), height() ); + else + resize( width() ,width() ); + } +*/ + + //setBackgroundOrigin( WindowOrigin ); + mBackgroundBrush = backgroundBrush(); + setBackgroundMode( NoBackground ); + repaint(); +} + + +void KdmClock::showEvent( TQShowEvent * ) +{ + repaint(); +} + + +void KdmClock::timeout() +{ + repaint(); +} + +void KdmClock::paintEvent( TQPaintEvent * ) +{ + if (!isVisible()) + return; + + TQPainter p( this ); + drawFrame( &p ); + + TQPixmap pm( contentsRect().size() ); + TQPainter paint; + paint.begin( &pm ); + paint.fillRect( contentsRect(), mBackgroundBrush ); + + // get current time + TQTime time = TQTime::currentTime(); + +/* + if (mDigital) { + TQString buf; + if (mSecond) + buf.sprintf( "%02d:%02d:%02d", time.hour(), time.minute(), + time.second() ); + else + buf.sprintf( "%02d:%02d", time.hour(), time.minute() ); + mFont.setPointSize( QMIN( (int)(width()/buf.length()*1.5),height() ) ); + paint.setFont( mFont ); + paint.setPen( backgroundColor() ); + paint.drawText( contentsRect(),AlignHCenter|AlignVCenter, buf,-1,0,0 ); + } else { +*/ + TQPointArray pts; + TQPoint cp = contentsRect().center() - TQPoint( 2,2 ); + int d = QMIN( contentsRect().width()-15,contentsRect().height()-15 ); + paint.setPen( foregroundColor() ); + paint.setBrush( foregroundColor() ); + + TQWMatrix matrix; + matrix.translate( cp.x(), cp.y() ); + matrix.scale( d/1000.0F, d/1000.0F ); + + // Hour + float h_angle = 30*(time.hour()%12-3) + time.minute()/2; + matrix.rotate( h_angle ); + paint.setWorldMatrix( matrix ); + pts.setPoints( 4, -20,0, 0,-20, 300,0, 0,20 ); + paint.drawPolygon( pts ); + matrix.rotate( -h_angle ); + + // Minute + float m_angle = (time.minute()-15)*6; + matrix.rotate( m_angle ); + paint.setWorldMatrix( matrix ); + pts.setPoints( 4, -10,0, 0,-10, 400,0, 0,10 ); + paint.drawPolygon( pts ); + matrix.rotate( -m_angle ); + + // Second + float s_angle = (time.second()-15)*6; + matrix.rotate( s_angle ); + paint.setWorldMatrix( matrix ); + pts.setPoints( 4,0,0,0,0,400,0,0,0 ); + if (mSecond) + paint.drawPolygon( pts ); + matrix.rotate( -s_angle ); + + // quadrante + for (int i=0 ; i < 60 ; i++) { + paint.setWorldMatrix( matrix ); + if ((i % 5) == 0) + paint.drawLine( 450,0, 500,0 ); // draw hour lines + else + paint.drawPoint( 480,0 ); // draw second lines + matrix.rotate( 6 ); + } + +// } // if (mDigital) + paint.end(); + + // flicker free code by Remi Guyomarch + bitBlt( this, contentsRect().topLeft(), &pm ); +} + +#include "tdmclock.moc" diff --git a/tdm/kfrontend/tdmclock.h b/tdm/kfrontend/tdmclock.h new file mode 100644 index 000000000..89a48eb8e --- /dev/null +++ b/tdm/kfrontend/tdmclock.h @@ -0,0 +1,52 @@ +/* + +clock module for tdm + +Copyright (C) 2000 Espen Sand, espen@kde.org + Based on work by NN (yet to be determined) + +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. + +*/ + +#ifndef _TDM_CLOCK_H_ +#define _TDM_CLOCK_H_ + +#include + +class KdmClock : public TQFrame { + Q_OBJECT + typedef TQFrame inherited; + + public: + KdmClock( TQWidget *parent=0, const char *name=0 ); + + protected: + virtual void showEvent( TQShowEvent * ); + virtual void paintEvent( TQPaintEvent * ); + + private slots: + void timeout(); + + private: + TQBrush mBackgroundBrush; + TQFont mFont; + bool mSecond; + bool mDigital; + bool mDate; + bool mBorder; +}; + +#endif diff --git a/tdm/kfrontend/tdmconfig.cpp b/tdm/kfrontend/tdmconfig.cpp new file mode 100644 index 000000000..5b57a6375 --- /dev/null +++ b/tdm/kfrontend/tdmconfig.cpp @@ -0,0 +1,179 @@ +/* + +Config for tdm + +Copyright (C) 1997, 1998 Steffen Hansen +Copyright (C) 2000-2003 Oswald Buddenhagen + + +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 "tdmconfig.h" +#include "tdm_greet.h" + +#include +#include + +#include +#include +#include +#include + +struct timeval st = {0, 0}; + +CONF_GREET_DEFS + +TQString _stsFile; +bool _isLocal; +bool _authorized; + +static TQString +GetCfgQStr( int id ) +{ + char *tmp = GetCfgStr( id ); + TQString qs = TQString::fromUtf8( tmp ); + free( tmp ); + return qs; +} + +static TQStringList +GetCfgQStrList( int id ) +{ + int i, len; + char **tmp = GetCfgStrArr( id, &len ); + TQStringList qsl; + for (i = 0; i < len - 1; i++) { + qsl.append( TQString::fromUtf8( tmp[i] ) ); + free( tmp[i] ); + } + free( tmp ); + return qsl; +} + +// Based on kconfigbase.cpp +static TQFont +Str2Font( const TQString &aValue ) +{ + uint nFontBits; + TQFont aRetFont; + TQString chStr; + + TQStringList sl = TQStringList::split( TQString::fromLatin1(","), aValue ); + + if (sl.count() == 1) { + /* X11 font spec */ + aRetFont = TQFont( aValue ); + aRetFont.setRawMode( true ); + } else if (sl.count() == 10) { + /* qt3 font spec */ + aRetFont.fromString( aValue ); + } else if (sl.count() == 6) { + /* backward compatible kde2 font spec */ + aRetFont = TQFont( sl[0], sl[1].toInt(), sl[4].toUInt() ); + + aRetFont.setStyleHint( (TQFont::StyleHint)sl[2].toUInt() ); + + nFontBits = sl[5].toUInt(); + aRetFont.setItalic( (nFontBits & 0x01) != 0 ); + aRetFont.setUnderline( (nFontBits & 0x02) != 0 ); + aRetFont.setStrikeOut( (nFontBits & 0x04) != 0 ); + aRetFont.setFixedPitch( (nFontBits & 0x08) != 0 ); + aRetFont.setRawMode( (nFontBits & 0x20) != 0 ); + } + aRetFont.setStyleStrategy( (TQFont::StyleStrategy) + (TQFont::PreferMatch | + (_antiAliasing ? TQFont::PreferAntialias : TQFont::NoAntialias)) ); + + return aRetFont; +} + +extern "C" +void init_config( void ) +{ + CONF_GREET_INIT + + _isLocal = GetCfgInt( C_isLocal ); + _hasConsole = _hasConsole && _isLocal && GetCfgInt( C_hasConsole ); + _authorized = GetCfgInt( C_isAuthorized ); + + _stsFile = _dataDir + "/tdmsts"; + + // Greet String + char hostname[256], *ptr; + hostname[0] = '\0'; + if (!gethostname( hostname, sizeof(hostname) )) + hostname[sizeof(hostname)-1] = '\0'; + struct utsname tuname; + uname( &tuname ); + TQString gst = _greetString; + _greetString = TQString::null; + int i, j, l = gst.length(); + for (i = 0; i < l; i++) { + if (gst[i] == '%') { + switch (gst[++i].cell()) { + case '%': _greetString += gst[i]; continue; + case 'd': ptr = dname; break; + case 'h': ptr = hostname; break; + case 'n': ptr = tuname.nodename; + for (j = 0; ptr[j]; j++) + if (ptr[j] == '.') { + ptr[j] = 0; + break; + } + break; + case 's': ptr = tuname.sysname; break; + case 'r': ptr = tuname.release; break; + case 'm': ptr = tuname.machine; break; + default: _greetString += i18n("[fix tdmrc!]"); continue; + } + _greetString += TQString::fromLocal8Bit( ptr ); + } else + _greetString += gst[i]; + } +} + + +/* out-of-place utility function */ +void +decodeSess( dpySpec *sess, TQString &user, TQString &loc ) +{ + if (sess->flags & isTTY) { + user = + i18n( "%1: TTY login", "%1: %n TTY logins", sess->count ) + .arg( sess->user ); + loc = +#ifdef HAVE_VTS + sess->vt ? + TQString("vt%1").arg( sess->vt ) : +#endif + TQString::fromLatin1( *sess->from ? sess->from : sess->display ); + } else { + user = + !sess->user ? + i18n("Unused") : + *sess->user ? + i18n("user: session type", "%1: %2") + .arg( sess->user ).arg( sess->session ) : + i18n("... host", "X login on %1").arg( sess->session ); + loc = +#ifdef HAVE_VTS + sess->vt ? + TQString("%1, vt%2").arg( sess->display ).arg( sess->vt ) : +#endif + TQString::fromLatin1( sess->display ); + } +} diff --git a/tdm/kfrontend/tdmconfig.h b/tdm/kfrontend/tdmconfig.h new file mode 100644 index 000000000..275cafa1b --- /dev/null +++ b/tdm/kfrontend/tdmconfig.h @@ -0,0 +1,69 @@ +/* + +Configuration for tdm + +Copyright (C) 1997, 1998, 2000 Steffen Hansen +Copyright (C) 2000-2003 Oswald Buddenhagen + + +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. + +*/ + + +#ifndef TDMCONFIG_H +#define TDMCONFIG_H + +#include + +#include "config.ci" + +#ifdef __cplusplus + +#include +#include +#include +#include + +extern TQString _stsFile; +extern bool _isLocal; +extern bool _authorized; + +CONF_GREET_CPP_DECLS + +// this file happens to be included everywhere, so just put it here +struct dpySpec; +void decodeSess( dpySpec *sess, TQString &user, TQString &loc ); + +extern struct timeval st; + +inline TQString timestamp() { + struct timeval nst; + gettimeofday(&nst, 0); + if (!st.tv_sec) + gettimeofday(&st, 0); + + TQString ret; + ret.sprintf("[%07ld]", (nst.tv_sec - st.tv_sec) * 1000 + (nst.tv_usec - st.tv_usec) / 1000); + return ret; +} + +extern "C" +#endif +void init_config( void ); + +CONF_GREET_C_DECLS + +#endif /* TDMCONFIG_H */ diff --git a/tdm/kfrontend/tdmctl.c b/tdm/kfrontend/tdmctl.c new file mode 100644 index 000000000..d6abe959a --- /dev/null +++ b/tdm/kfrontend/tdmctl.c @@ -0,0 +1,234 @@ +/* + +TDM remote control application + +Copyright (C) 2004 Oswald Buddenhagen + +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 + +#include +#include +#include +#include +#include +#include +#include + +static int +openctl( int fd, int err, const char *ctl, const char *dpy ) +{ + struct sockaddr_un sa; + + sa.sun_family = AF_UNIX; + if (dpy) + snprintf( sa.sun_path, sizeof(sa.sun_path), + "%s/dmctl-%s/socket", ctl, dpy ); + else + snprintf( sa.sun_path, sizeof(sa.sun_path), + "%s/dmctl/socket", ctl ); + if (!connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) + return 1; + if (err) + fprintf( stderr, "Cannot connect socket '%s'.\n", sa.sun_path ); + return 0; +} + +static const char * +readcfg( const char *cfg ) +{ + FILE *fp; + const char *ctl; + char *ptr, *ptr2; + char buf[1024]; + + if (!(fp = fopen( cfg, "r" ))) { + fprintf( stderr, + "Cannot open tdm config file '%s'.\n", + cfg ); + return 0; + } + ctl = "/var/run/xdmctl"; + while (fgets( buf, sizeof(buf), fp )) + if (!strncmp( buf, "FifoDir", 7 )) { + ptr = buf + 7; + while (*ptr && isspace( *ptr )) + ptr++; + if (*ptr++ != '=') + continue; + while (*ptr && isspace( *ptr )) + ptr++; + for (ptr2 = buf + strlen( buf ); + ptr2 > ptr && isspace( *(ptr2 - 1) ); + ptr2--); + *ptr2 = 0; + ctl = strdup( ptr ); + break; + } + fclose( fp ); + return ctl; +} + +static int +exe( int fd, const char *in, int len ) +{ + char buf[4096]; + + if (write( fd, in, len ) != len) { + fprintf( stderr, "Cannot send command\n" ); + return 1; + } + do { + if ((len = read(fd, buf, sizeof(buf))) <= 0) { + fprintf(stderr, "Cannot receive reply\n"); + return 1; + } + fwrite(buf, 1, len, stdout); + } while (buf[len - 1] != '\n'); + return 0; +} + +static int +run( int fd, char **argv ) +{ + unsigned len, l; + char buf[1024]; + + if (!*argv) + return exe( fd, "caps\n", 5 ); + if (!strcmp( *argv, "-" )) { + for (;;) { + if (isatty( 0 )) { + fputs( "> ", stdout ); + fflush( stdout ); + } + if (!fgets( buf, sizeof(buf), stdin )) + return 0; + if (exe( fd, buf, strlen( buf ) )) + return 1; + } + } else { + len = strlen( *argv ); + if (len >= sizeof(buf)) + goto bad; + memcpy( buf, *argv, len ); + while (*++argv) { + l = strlen( *argv ); + if (len + l + 1 >= sizeof(buf)) + goto bad; + buf[len++] = '\t'; + memcpy( buf + len, *argv, l ); + len += l; + } + buf[len++] = '\n'; + return exe( fd, buf, len ); + bad: + fprintf( stderr, "Command too long\n" ); + return 1; + } +} + +int +main( int argc, char **argv ) +{ + char *dpy = getenv( "DISPLAY" ); + const char *ctl = getenv( "DM_CONTROL" ); + const char *cfg = KDE_CONFDIR "/tdm/tdmrc"; + char *ptr; + int fd; + + (void)argc; + while (*++argv) { + ptr = *argv; + if (*ptr != '-' || !*(ptr + 1)) + break; + ptr++; + if (*ptr == '-') + ptr++; + if (!strcmp( ptr, "h" ) || !strcmp( ptr, "help" )) { + puts( +"Usage: tdmctl [options] [command [command arguments]]\n" +"\n" +"Options are:\n" +" -h -help This help message.\n" +" -g -global Use global control socket even if $DISPLAY is set\n" +" -d -display Override $DISPLAY\n" +" -s -sockets Override $DM_CONTROL\n" +" -c -config Use alternative tdm config file\n" +"\n" +"The directory in which the sockets are located is determined this way:\n" +"- the -s option is examined\n" +"- the $DM_CONTROL variable is examined\n" +"- the tdm config file is searched for the FifoDir key\n" +"- /var/run/xdmctl and /var/run are tried\n" +"\n" +"If $DISPLAY is set (or -d was specified) and -g was not specified, the\n" +"display-specific control socket will be used, otherwise the global one.\n" +"\n" +"Tokens in the command and the reply are tab-separated.\n" +"Command arguments can be specified as separate command line parameters,\n" +"in which case they are simply concatenated with tabs in between.\n" +"\n" +"If the command is '-', tdmctl reads commands from stdin.\n" +"The default command is 'caps'.\n" + ); + return 0; + } else if (!strcmp( ptr, "g" ) || !strcmp( ptr, "global" )) + dpy = 0; + else if (!strcmp( ptr, "d" ) || !strcmp( ptr, "display" )) { + if (!argv[1]) + goto needarg; + dpy = *++argv; + } else if (!strcmp( ptr, "s" ) || !strcmp( ptr, "sockets" )) { + if (!argv[1]) + goto needarg; + ctl = *++argv; + } else if (!strcmp( ptr, "c" ) || !strcmp( ptr, "config" )) { + if (!argv[1]) { + needarg: + fprintf( stderr, "Option '%s' needs argument.\n", + ptr ); + return 1; + } + cfg = *++argv; + } else { + fprintf( stderr, "Unknown option '%s'.\n", ptr ); + return 1; + } + } + if ((!ctl || !*ctl) && *cfg) + ctl = readcfg( cfg ); + if ((fd = socket( PF_UNIX, SOCK_STREAM, 0 )) < 0) { + fprintf( stderr, "Cannot create UNIX socket\n" ); + return 1; + } + if (dpy && (ptr = strchr( dpy, ':' )) && (ptr = strchr( ptr, '.' ))) + *ptr = 0; + if (ctl && *ctl) { + if (!openctl( fd, 1, ctl, dpy )) + return 1; + } else { + if (!openctl( fd, 0, "/var/run/xdmctl", dpy ) && + !openctl( fd, 0, "/var/run", dpy )) + { + fprintf( stderr, "No command socket found.\n" ); + return 1; + } + } + return run( fd, argv ); +} diff --git a/tdm/kfrontend/tdmshutdown.cpp b/tdm/kfrontend/tdmshutdown.cpp new file mode 100644 index 000000000..e546f62b6 --- /dev/null +++ b/tdm/kfrontend/tdmshutdown.cpp @@ -0,0 +1,925 @@ +/* + +Shutdown dialog + +Copyright (C) 1997, 1998, 2000 Steffen Hansen +Copyright (C) 2000-2003,2005 Oswald Buddenhagen + + +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 "tdmshutdown.h" +#include "tdm_greet.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KDmh KDialog::marginHint() +#define KDsh KDialog::spacingHint() + +#include + +extern bool has_twin; + +int TDMShutdownBase::curPlugin = -1; +PluginList TDMShutdownBase::pluginList; + +TDMShutdownBase::TDMShutdownBase( int _uid, TQWidget *_parent ) + : inherited( _parent ) + , box( new TQVBoxLayout( this, KDmh, KDsh ) ) +#ifdef HAVE_VTS + , willShut( true ) +#endif + , mayNuke( false ) + , doesNuke( false ) + , mayOk( true ) + , maySched( false ) + , rootlab( 0 ) + , verify( 0 ) + , needRoot( -1 ) + , uid( _uid ) +{ +} + +TDMShutdownBase::~TDMShutdownBase() +{ + hide(); + delete verify; +} + +void +TDMShutdownBase::complete( TQWidget *prevWidget ) +{ + TQSizePolicy fp( TQSizePolicy::Fixed, TQSizePolicy::Fixed ); + + if (uid && + ((willShut && _allowShutdown == SHUT_ROOT) || + (mayNuke && _allowNuke == SHUT_ROOT))) + { + rootlab = new TQLabel( i18n("Root authorization required."), this ); + box->addWidget( rootlab ); + if (curPlugin < 0) { + curPlugin = 0; + pluginList = KGVerify::init( _pluginsShutdown ); + } + verify = new KGStdVerify( this, this, + prevWidget, "root", + pluginList, KGreeterPlugin::Authenticate, + KGreeterPlugin::Shutdown ); + verify->selectPlugin( curPlugin ); + box->addLayout( verify->getLayout() ); + TQAccel *accel = new TQAccel( this ); + accel->insertItem( ALT+Key_A, 0 ); + connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotActivatePlugMenu()) ); + } + + box->addWidget( new KSeparator( KSeparator::HLine, this ) ); + + TQBoxLayout *hlay = new TQHBoxLayout( box, KDsh ); + hlay->addStretch( 1 ); + if (mayOk) { + okButton = new KPushButton( KStdGuiItem::ok(), this ); + okButton->setSizePolicy( fp ); + okButton->setDefault( true ); + hlay->addWidget( okButton ); + hlay->addStretch( 1 ); + connect( okButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); + } + if (maySched) { + KPushButton *schedButton = + new KPushButton( KGuiItem( i18n("&Schedule...") ), this ); + schedButton->setSizePolicy( fp ); + hlay->addWidget( schedButton ); + hlay->addStretch( 1 ); + connect( schedButton, TQT_SIGNAL(clicked()), TQT_SLOT(slotSched()) ); + } + cancelButton = new KPushButton( KStdGuiItem::cancel(), this ); + cancelButton->setSizePolicy( fp ); + if (!mayOk) + cancelButton->setDefault( true ); + hlay->addWidget( cancelButton ); + hlay->addStretch( 1 ); + connect( cancelButton, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) ); + + updateNeedRoot(); +} + +void +TDMShutdownBase::slotActivatePlugMenu() +{ + if (needRoot) { + TQPopupMenu *cmnu = verify->getPlugMenu(); + if (!cmnu) + return; + TQSize sh( cmnu->sizeHint() / 2 ); + cmnu->exec( geometry().center() - TQPoint( sh.width(), sh.height() ) ); + } +} + +void +TDMShutdownBase::accept() +{ + if (needRoot == 1) + verify->accept(); + else + accepted(); +} + +void +TDMShutdownBase::slotSched() +{ + done( Schedule ); +} + +void +TDMShutdownBase::updateNeedRoot() +{ + int nNeedRoot = uid && + (((willShut && _allowShutdown == SHUT_ROOT) || + (_allowNuke == SHUT_ROOT && doesNuke))); + if (verify && nNeedRoot != needRoot) { + if (needRoot == 1) + verify->abort(); + needRoot = nNeedRoot; + rootlab->setEnabled( needRoot ); + verify->setEnabled( needRoot ); + if (needRoot) + verify->start(); + } +} + +void +TDMShutdownBase::accepted() +{ + inherited::done( needRoot ? (int)Authed : (int)Accepted ); +} + +void +TDMShutdownBase::verifyPluginChanged( int id ) +{ + curPlugin = id; + adjustSize(); +} + +void +TDMShutdownBase::verifyOk() +{ + accepted(); +} + +void +TDMShutdownBase::verifyFailed() +{ + okButton->setEnabled( false ); + cancelButton->setEnabled( false ); +} + +void +TDMShutdownBase::verifyRetry() +{ + okButton->setEnabled( true ); + cancelButton->setEnabled( true ); +} + +void +TDMShutdownBase::verifySetUser( const TQString & ) +{ +} + + +static void +doShutdown( int type, const char *os ) +{ + GSet( 1 ); + GSendInt( G_Shutdown ); + GSendInt( type ); + GSendInt( 0 ); + GSendInt( 0 ); + GSendInt( SHUT_FORCE ); + GSendInt( 0 ); /* irrelevant, will timeout immediately anyway */ + GSendStr( os ); + GSet( 0 ); +} + + + +TDMShutdown::TDMShutdown( int _uid, TQWidget *_parent ) + : inherited( _uid, _parent ) +{ + setCaption(i18n("Shutdown TDE")); + + TQSizePolicy fp( TQSizePolicy::Fixed, TQSizePolicy::Fixed ); + + TQHBoxLayout *hlay = new TQHBoxLayout( box, KDsh ); + + howGroup = new TQVButtonGroup( i18n("Shutdown Type"), this ); + hlay->addWidget( howGroup, 0, AlignTop ); + + TQRadioButton *rb; + rb = new TDMRadioButton( i18n("&Turn off computer"), howGroup ); + rb->setChecked( true ); + rb->setFocus(); + + restart_rb = new TDMRadioButton( i18n("&Restart computer"), howGroup ); + + connect( rb, TQT_SIGNAL(doubleClicked()), TQT_SLOT(accept()) ); + connect( restart_rb, TQT_SIGNAL(doubleClicked()), TQT_SLOT(accept()) ); + + GSet( 1 ); + GSendInt( G_ListBootOpts ); + if (GRecvInt() == BO_OK) { /* XXX show dialog on failure */ + char **tlist = GRecvStrArr( 0 ); + int defaultTarget = GRecvInt(); + oldTarget = GRecvInt(); + TQWidget *hlp = new TQWidget( howGroup ); + targets = new TQComboBox( hlp ); + for (int i = 0; tlist[i]; i++) + targets->insertItem( TQString(TQString::fromLocal8Bit( tlist[i] )) ); + freeStrArr( tlist ); + targets->setCurrentItem( oldTarget == -1 ? defaultTarget : oldTarget ); + TQHBoxLayout *hb = new TQHBoxLayout( hlp, 0, KDsh ); + int spc = kapp->style().pixelMetric( TQStyle::PM_ExclusiveIndicatorWidth ) + + howGroup->insideSpacing(); + hb->addSpacing( spc ); + hb->addWidget( targets ); + connect( targets, TQT_SIGNAL(activated( int )), TQT_SLOT(slotTargetChanged()) ); + } + GSet( 0 ); + + howGroup->setSizePolicy( fp ); + + schedGroup = new TQGroupBox( i18n("Scheduling"), this ); + hlay->addWidget( schedGroup, 0, AlignTop ); + + le_start = new TQLineEdit( schedGroup ); + TQLabel *lab1 = new TQLabel( le_start, i18n("&Start:"), schedGroup ); + + le_timeout = new TQLineEdit( schedGroup ); + TQLabel *lab2 = new TQLabel( le_timeout, i18n("T&imeout:"), schedGroup ); + + cb_force = new TQCheckBox( i18n("&Force after timeout"), schedGroup ); + if (_allowNuke != SHUT_NONE) { + connect( cb_force, TQT_SIGNAL(clicked()), TQT_SLOT(slotWhenChanged()) ); + mayNuke = true; + } else + cb_force->setEnabled( false ); + + TQGridLayout *grid = new TQGridLayout( schedGroup, 0, 0, KDmh, KDsh ); + grid->addRowSpacing( 0, schedGroup->fontMetrics().height() - 5 ); + grid->addWidget( lab1, 1, 0, Qt::AlignRight ); + grid->addWidget( le_start, 1, 1 ); + grid->addWidget( lab2, 2, 0, Qt::AlignRight ); + grid->addWidget( le_timeout, 2, 1 ); + grid->addMultiCellWidget( cb_force, 3,3, 0,1 ); + + schedGroup->setSizePolicy( fp ); + + le_start->setText( "0" ); + if (_defSdMode == SHUT_SCHEDULE) + le_timeout->setText( "-1" ); + else { + le_timeout->setText( "0" ); + if (_defSdMode == SHUT_FORCENOW && cb_force->isEnabled()) + cb_force->setChecked( true ); + } + + complete( schedGroup ); +} + +static int +get_date( const char *str ) +{ + KProcIO prc; + prc << "/bin/date" << "+%s" << "-d" << str; + prc.start( KProcess::Block, false ); + TQString dstr; + if (prc.readln( dstr, false, 0 ) < 0) + return -1; + return dstr.toInt(); +} + +void +TDMShutdown::accept() +{ + if (le_start->text() == "0" || le_start->text() == "now") + sch_st = time( 0 ); + else if (le_start->text()[0] == '+') + sch_st = time( 0 ) + le_start->text().toInt(); + else if ((sch_st = get_date( le_start->text().latin1() )) < 0) { + MsgBox( errorbox, i18n("Entered start date is invalid.") ); + le_start->setFocus(); + return; + } + if (le_timeout->text() == "-1" || le_timeout->text().startsWith( "inf" )) + sch_to = TO_INF; + else if (le_timeout->text()[0] == '+') + sch_to = sch_st + le_timeout->text().toInt(); + else if ((sch_to = get_date( le_timeout->text().latin1() )) < 0) { + MsgBox( errorbox, i18n("Entered timeout date is invalid.") ); + le_timeout->setFocus(); + return; + } + + inherited::accept(); +} + +void +TDMShutdown::slotTargetChanged() +{ + restart_rb->setChecked( true ); +} + +void +TDMShutdown::slotWhenChanged() +{ + doesNuke = cb_force->isChecked(); + updateNeedRoot(); +} + +void +TDMShutdown::accepted() +{ + GSet( 1 ); + GSendInt( G_Shutdown ); + GSendInt( restart_rb->isChecked() ? SHUT_REBOOT : SHUT_HALT ); + GSendInt( sch_st ); + GSendInt( sch_to ); + GSendInt( cb_force->isChecked() ? SHUT_FORCE : SHUT_CANCEL ); + GSendInt( _allowShutdown == SHUT_ROOT ? 0 : -2 ); + GSendStr( (restart_rb->isChecked() && + targets && targets->currentItem() != oldTarget) ? + targets->currentText().local8Bit().data() : 0 ); + GSet( 0 ); + inherited::accepted(); +} + +void +TDMShutdown::scheduleShutdown( TQWidget *_parent ) +{ + GSet( 1 ); + GSendInt( G_QueryShutdown ); + int how = GRecvInt(); + int start = GRecvInt(); + int timeout = GRecvInt(); + int force = GRecvInt(); + int uid = GRecvInt(); + char *os = GRecvStr(); + GSet( 0 ); + if (how) { + int ret = + TDMCancelShutdown( how, start, timeout, force, uid, os, + _parent ).exec(); + if (!ret) + return; + doShutdown( 0, 0 ); + uid = ret == Authed ? 0 : -1; + } else + uid = -1; + if (os) + free( os ); + TDMShutdown( uid, _parent ).exec(); +} + + +TDMRadioButton::TDMRadioButton( const TQString &label, TQWidget *parent ) + : inherited( label, parent ) +{ +} + +void +TDMRadioButton::mouseDoubleClickEvent( TQMouseEvent * ) +{ + emit doubleClicked(); +} + + +TDMDelayedPushButton::TDMDelayedPushButton( const KGuiItem &item, + TQWidget *parent, + const char *name ) + : inherited( item, parent, name ) + , pop( 0 ) +{ + connect( this, TQT_SIGNAL(pressed()), TQT_SLOT(slotPressed()) ); + connect( this, TQT_SIGNAL(released()), TQT_SLOT(slotReleased()) ); + connect( &popt, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeout()) ); +} + +void TDMDelayedPushButton::setPopup( TQPopupMenu *p ) +{ + pop = p; + setIsMenuButton( p != 0 ); +} + +void TDMDelayedPushButton::slotPressed() +{ + if (pop) + popt.start( TQApplication::startDragTime() ); +} + +void TDMDelayedPushButton::slotReleased() +{ + popt.stop(); +} + +void TDMDelayedPushButton::slotTimeout() +{ + popt.stop(); + pop->popup( mapToGlobal( rect().bottomLeft() ) ); + setDown( false ); +} + +TDMSlimShutdown::TDMSlimShutdown( TQWidget *_parent ) + : inherited( _parent ) + , targetList( 0 ) +{ + setCaption(i18n("Shutdown TDE")); + + bool doUbuntuLogout = KConfigGroup(KGlobal::config(), "Shutdown").readBoolEntry("doUbuntuLogout", false); + + TQFrame* lfrm = new TQFrame( this ); + TQHBoxLayout* hbuttonbox; + + if(doUbuntuLogout) + { + TQVBoxLayout* vbox = new TQVBoxLayout( this ); + if (has_twin) + lfrm->setFrameStyle( TQFrame::NoFrame ); + else + lfrm->setFrameStyle( TQFrame::StyledPanel | TQFrame::Raised ); + lfrm->setLineWidth( style().pixelMetric( TQStyle::PM_DefaultFrameWidth, lfrm ) ); + // we need to set the minimum size for the logout box, since it + // gets too small if there all options are not available + lfrm->setMinimumSize(300,120); + vbox->addWidget( lfrm ); + vbox = new TQVBoxLayout( lfrm, 2 * KDialog::marginHint(), + 2 * KDialog::spacingHint() ); + + // first line of buttons + hbuttonbox = new TQHBoxLayout( vbox, 8 * KDialog::spacingHint() ); + hbuttonbox->setAlignment( Qt::AlignHCenter ); + + // Reboot + FlatButton* btnReboot = new FlatButton( lfrm ); + btnReboot->setTextLabel( i18n("&Restart"), false ); + btnReboot->setPixmap( DesktopIcon( "reload") ); + int i = btnReboot->textLabel().find( TQRegExp("\\&"), 0 ); // i == 1 + btnReboot->setAccel( "ALT+" + btnReboot->textLabel().lower()[i+1] ) ; + hbuttonbox->addWidget ( btnReboot); + connect(btnReboot, TQT_SIGNAL(clicked()), TQT_SLOT(slotReboot())); + + // Copied completely from the standard restart/shutdown dialog + GSet( 1 ); + GSendInt( G_ListBootOpts ); + if (GRecvInt() == BO_OK) { + targetList = GRecvStrArr( 0 ); + /*int def =*/ GRecvInt(); + int cur = GRecvInt(); + TQPopupMenu *targets = new TQPopupMenu( this ); + btnReboot->setPopupDelay(300); // visually add dropdown + for (int i = 0; targetList[i]; i++) { + TQString t( TQString::fromLocal8Bit( targetList[i] ) ); + targets->insertItem( i == cur ? + i18n("current option in boot loader", + "%1 (current)").arg( t ) : + t, i ); + } + btnReboot->setPopup( targets ); + connect( targets, TQT_SIGNAL(activated(int)), TQT_SLOT(slotReboot(int)) ); + } + GSet( 0 ); + // Copied completely from the standard restart/shutdown dialog + + // Shutdown + FlatButton* btnHalt = new FlatButton( lfrm ); + btnHalt->setTextLabel( i18n("&Turn Off"), false ); + btnHalt->setPixmap( DesktopIcon( "exit") ); + i = btnHalt->textLabel().find( TQRegExp("\\&"), 0 ); // i == 1 + btnHalt->setAccel( "ALT+" + btnHalt->textLabel().lower()[i+1] ) ; + hbuttonbox->addWidget ( btnHalt ); + connect(btnHalt, TQT_SIGNAL(clicked()), TQT_SLOT(slotHalt())); + + // cancel buttonbox + TQHBoxLayout* hbuttonbox2 = new TQHBoxLayout( vbox, 8 * KDialog::spacingHint() ); + hbuttonbox2->setAlignment( Qt::AlignRight ); + + // Back to tdm + KSMPushButton* btnBack = new KSMPushButton( KStdGuiItem::cancel(), lfrm ); + hbuttonbox2->addWidget( btnBack ); + connect(btnBack, TQT_SIGNAL(clicked()), TQT_SLOT(reject())); + } + else + { + TQHBoxLayout *hbox = new TQHBoxLayout( this, KDmh, KDsh ); + if (has_twin) + lfrm->setFrameStyle( TQFrame::NoFrame ); + else + lfrm->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); + hbox->addWidget( lfrm, AlignCenter ); + // we need to set the minimum size for the logout box, since it + // gets too small if there all options are not available + TQLabel *icon = new TQLabel( lfrm ); + icon->setPixmap( TQPixmap( locate( "data", "tdm/pics/shutdown.jpg" ) ) ); + TQVBoxLayout *iconlay = new TQVBoxLayout( lfrm ); + iconlay->addWidget( icon ); + + TQVBoxLayout *buttonlay = new TQVBoxLayout( hbox, KDsh ); + + buttonlay->addStretch( 1 ); + + KPushButton *btnHalt = new + KPushButton( KGuiItem( i18n("&Turn Off Computer"), "exit" ), this ); + buttonlay->addWidget( btnHalt ); + connect( btnHalt, TQT_SIGNAL(clicked()), TQT_SLOT(slotHalt()) ); + + buttonlay->addSpacing( KDialog::spacingHint() ); + + TDMDelayedPushButton *btnReboot = new + TDMDelayedPushButton( KGuiItem( i18n("&Restart Computer"), "reload" ), this ); + buttonlay->addWidget( btnReboot ); + connect( btnReboot, TQT_SIGNAL(clicked()), TQT_SLOT(slotReboot()) ); + + GSet( 1 ); + GSendInt( G_ListBootOpts ); + if (GRecvInt() == BO_OK) { + targetList = GRecvStrArr( 0 ); + /*int def =*/ GRecvInt(); + int cur = GRecvInt(); + TQPopupMenu *targets = new TQPopupMenu( this ); + for (int i = 0; targetList[i]; i++) { + TQString t( TQString::fromLocal8Bit( targetList[i] ) ); + targets->insertItem( i == cur ? + i18n("current option in boot loader", + "%1 (current)").arg( t ) : + t, i ); + } + btnReboot->setPopup( targets ); + connect( targets, TQT_SIGNAL(activated(int)), TQT_SLOT(slotReboot(int)) ); + } + GSet( 0 ); + + buttonlay->addStretch( 1 ); + + if (_scheduledSd != SHUT_NEVER) { + KPushButton *btnSched = new + KPushButton( KGuiItem( i18n("&Schedule...") ), this ); + buttonlay->addWidget( btnSched ); + connect( btnSched, TQT_SIGNAL(clicked()), TQT_SLOT(slotSched()) ); + + buttonlay->addStretch( 1 ); + } + + buttonlay->addWidget( new KSeparator( this ) ); + + buttonlay->addSpacing( 0 ); + + KPushButton *btnBack = new KPushButton( KStdGuiItem::cancel(), this ); + buttonlay->addWidget( btnBack ); + connect( btnBack, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) ); + + buttonlay->addSpacing( KDialog::spacingHint() ); + } + +} + +TDMSlimShutdown::~TDMSlimShutdown() +{ + freeStrArr( targetList ); +} + +void +TDMSlimShutdown::slotSched() +{ + reject(); + TDMShutdown::scheduleShutdown(); +} + +void +TDMSlimShutdown::slotHalt() +{ + if (checkShutdown( SHUT_HALT, 0 )) + doShutdown( SHUT_HALT, 0 ); +} + +void +TDMSlimShutdown::slotReboot() +{ + if (checkShutdown( SHUT_REBOOT, 0 )) + doShutdown( SHUT_REBOOT, 0 ); +} + +void +TDMSlimShutdown::slotReboot( int opt ) +{ + if (checkShutdown( SHUT_REBOOT, targetList[opt] )) + doShutdown( SHUT_REBOOT, targetList[opt] ); +} + +bool +TDMSlimShutdown::checkShutdown( int type, const char *os ) +{ + reject(); + dpySpec *sess = fetchSessions( lstRemote | lstTTY ); + if (!sess && _allowShutdown != SHUT_ROOT) + return true; + int ret = TDMConfShutdown( -1, sess, type, os ).exec(); + disposeSessions( sess ); + if (ret == Schedule) { + TDMShutdown::scheduleShutdown(); + return false; + } + return ret; +} + +void +TDMSlimShutdown::externShutdown( int type, const char *os, int uid ) +{ + dpySpec *sess = fetchSessions( lstRemote | lstTTY ); + int ret = TDMConfShutdown( uid, sess, type, os ).exec(); + disposeSessions( sess ); + if (ret == Schedule) + TDMShutdown( uid ).exec(); + else if (ret) + doShutdown( type, os ); +} + + +KSMPushButton::KSMPushButton( const KGuiItem &item, + TQWidget *parent, + const char *name) + : KPushButton( item, parent, name), + m_pressed(false) +{ + setDefault( false ); + setAutoDefault ( false ); +} + +void KSMPushButton::keyPressEvent( TQKeyEvent* e ) +{ + switch ( e->key() ) + { + case Key_Enter: + case Key_Return: + case Key_Space: + m_pressed = TRUE; + setDown(true); + emit pressed(); + break; + case Key_Escape: + e->ignore(); + break; + default: + e->ignore(); + } + + TQPushButton::keyPressEvent(e); +} + + +void KSMPushButton::keyReleaseEvent( TQKeyEvent* e ) +{ + switch ( e->key() ) + { + case Key_Space: + case Key_Enter: + case Key_Return: + if ( m_pressed ) + { + setDown(false); + m_pressed = FALSE; + emit released(); + emit clicked(); + } + break; + case Key_Escape: + e->ignore(); + break; + default: + e->ignore(); + + } +} + +FlatButton::FlatButton( TQWidget *parent, const char *name ) + : TQToolButton( parent, name/*, TQt::WNoAutoErase*/ ), + m_pressed(false) +{ + init(); +} + + +FlatButton::~FlatButton() {} + +void FlatButton::init() +{ + setUsesTextLabel(true); + setUsesBigPixmap(true); + setAutoRaise(true); + setTextPosition( TQToolButton::Under ); + setFocusPolicy(TQ_StrongFocus); + } + + +void FlatButton::keyPressEvent( TQKeyEvent* e ) +{ + switch ( e->key() ) + { + case Key_Enter: + case Key_Return: + case Key_Space: + m_pressed = TRUE; + setDown(true); + emit pressed(); + break; + case Key_Escape: + e->ignore(); + break; + default: + e->ignore(); + } + + TQToolButton::keyPressEvent(e); +} + +void FlatButton::keyReleaseEvent( TQKeyEvent* e ) +{ + switch ( e->key() ) + { + case Key_Space: + case Key_Enter: + case Key_Return: + if ( m_pressed ) + { + setDown(false); + m_pressed = FALSE; + emit released(); + emit clicked(); + } + break; + case Key_Escape: + e->ignore(); + break; + default: + e->ignore(); + } + +} + + + +TDMConfShutdown::TDMConfShutdown( int _uid, dpySpec *sess, int type, const char *os, + TQWidget *_parent ) + : inherited( _uid, _parent ) +{ +#ifdef HAVE_VTS + if (type == SHUT_CONSOLE) + willShut = false; +#endif + box->addWidget( new TQLabel( TQString( "

" + "%1%2" + "

" ) + .arg( (type == SHUT_HALT) ? + i18n("Turn Off Computer") : +#ifdef HAVE_VTS + (type == SHUT_CONSOLE) ? + i18n("Switch to Console") : +#endif + i18n("Restart Computer") ) + .arg( os ? + i18n("
(Next boot: %1)") + .arg( TQString::fromLocal8Bit( os ) ) : + TQString() ), + this ) ); + + if (sess) { + if (willShut && _scheduledSd != SHUT_NEVER) + maySched = true; + mayNuke = doesNuke = true; + if (_allowNuke == SHUT_NONE) + mayOk = false; + TQLabel *lab = new TQLabel( mayOk ? + i18n("Abort active sessions:") : + i18n("No permission to abort active sessions:"), + this ); + box->addWidget( lab ); + TQListView *lv = new TQListView( this ); + lv->setSelectionMode( TQListView::NoSelection ); + lv->setAllColumnsShowFocus( true ); + lv->header()->setResizeEnabled( false ); + lv->addColumn( i18n("Session") ); + lv->addColumn( i18n("Location") ); + TQListViewItem *itm; + int ns = 0; + TQString user, loc; + do { + decodeSess( sess, user, loc ); + itm = new TQListViewItem( lv, user, loc ); + sess = sess->next, ns++; + } while (sess); + int fw = lv->frameWidth() * 2; + lv->setFixedHeight( fw + lv->header()->height() + + itm->height() * (ns < 3 ? 3 : ns > 10 ? 10 : ns) ); + box->addWidget( lv ); + complete( lv ); + } else + complete( 0 ); +} + + +TDMCancelShutdown::TDMCancelShutdown( int how, int start, int timeout, + int force, int uid, const char *os, + TQWidget *_parent ) + : inherited( -1, _parent ) +{ + if (force == SHUT_FORCE) { + if (_allowNuke == SHUT_NONE) + mayOk = false; + else if (_allowNuke == SHUT_ROOT) + mayNuke = doesNuke = true; + } + TQLabel *lab = new TQLabel( mayOk ? + i18n("Abort pending shutdown:") : + i18n("No permission to abort pending shutdown:"), + this ); + box->addWidget( lab ); + TQDateTime qdt; + TQString strt, end; + if (start < time( 0 )) + strt = i18n("now"); + else { + qdt.setTime_t( start ); + strt = qdt.toString( Qt::LocalDate ); + } + if (timeout == TO_INF) + end = i18n("infinite"); + else { + qdt.setTime_t( timeout ); + end = qdt.toString( Qt::LocalDate ); + } + TQString trg = + i18n("Owner: %1" + "\nType: %2%5" + "\nStart: %3" + "\nTimeout: %4") + .arg( uid == -2 ? + i18n("console user") : + uid == -1 ? + i18n("control socket") : + KUser( uid ).loginName() ) + .arg( how == SHUT_HALT ? + i18n("turn off computer") : + i18n("restart computer") ) + .arg( strt ).arg( end ) + .arg( os ? + i18n("\nNext boot: %1").arg( TQString::fromLocal8Bit( os ) ) : + TQString() ); + if (timeout != TO_INF) + trg += i18n("\nAfter timeout: %1") + .arg( force == SHUT_FORCE ? + i18n("abort all sessions") : + force == SHUT_FORCEMY ? + i18n("abort own sessions") : + i18n("cancel shutdown") ); + lab = new TQLabel( trg, this ); + box->addWidget( lab ); + complete( 0 ); +} + +#include "tdmshutdown.moc" diff --git a/tdm/kfrontend/tdmshutdown.h b/tdm/kfrontend/tdmshutdown.h new file mode 100644 index 000000000..6a2ee3a70 --- /dev/null +++ b/tdm/kfrontend/tdmshutdown.h @@ -0,0 +1,240 @@ +/* + +Shutdown dialog + +Copyright (C) 1997, 1998 Steffen Hansen +Copyright (C) 2000-2003,2005 Oswald Buddenhagen + + +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. + +*/ + + +#ifndef TDMSHUTDOWN_H +#define TDMSHUTDOWN_H + +#include "tdmconfig.h" // for HAVE_VTS +#include "kgverify.h" + +#include + +#include +#include +#include + +class TQLabel; +class KPushButton; +class TQButtonGroup; +class TQGroupBox; +class TQComboBox; +class TQCheckBox; +class TQLineEdit; + +enum { Authed = TQDialog::Accepted + 1, Schedule }; + +class TDMShutdownBase : public FDialog, public KGVerifyHandler { + Q_OBJECT + typedef FDialog inherited; + + public: + TDMShutdownBase( int _uid, TQWidget *_parent ); + virtual ~TDMShutdownBase(); + + protected slots: + virtual void accept(); + + protected: + virtual void accepted(); + + protected: + void updateNeedRoot(); + void complete( TQWidget *prevWidget ); + + TQVBoxLayout *box; +#ifdef HAVE_VTS + bool willShut; +#else + static const bool willShut = true; +#endif + bool mayNuke, doesNuke, mayOk, maySched; + + private slots: + void slotSched(); + void slotActivatePlugMenu(); + + private: + KPushButton *okButton, *cancelButton; + TQLabel *rootlab; + KGStdVerify *verify; + int needRoot, uid; + + static int curPlugin; + static PluginList pluginList; + + public: // from KGVerifyHandler + virtual void verifyPluginChanged( int id ); + virtual void verifyOk(); + virtual void verifyFailed(); + virtual void verifyRetry(); + virtual void verifySetUser( const TQString &user ); +}; + + +class TDMShutdown : public TDMShutdownBase { + Q_OBJECT + typedef TDMShutdownBase inherited; + + public: + TDMShutdown( int _uid, TQWidget *_parent = 0 ); + static void scheduleShutdown( TQWidget *_parent = 0 ); + + protected slots: + virtual void accept(); + + protected: + virtual void accepted(); + + private slots: + void slotTargetChanged(); + void slotWhenChanged(); + + private: + TQButtonGroup *howGroup; + TQGroupBox *schedGroup; + TQRadioButton *restart_rb; + TQLineEdit *le_start, *le_timeout; + TQCheckBox *cb_force; + TQComboBox *targets; + int oldTarget; + int sch_st, sch_to; + +}; + +class TDMRadioButton : public TQRadioButton { + Q_OBJECT + typedef TQRadioButton inherited; + + public: + TDMRadioButton( const TQString &label, TQWidget *parent ); + + private: + virtual void mouseDoubleClickEvent( TQMouseEvent * ); + + signals: + void doubleClicked(); + +}; + +class TDMDelayedPushButton : public KPushButton { + Q_OBJECT + typedef KPushButton inherited; + + public: + TDMDelayedPushButton( const KGuiItem &item, TQWidget *parent, const char *name = 0 ); + void setPopup( TQPopupMenu *pop ); + + private slots: + void slotTimeout(); + void slotPressed(); + void slotReleased(); + + private: + TQPopupMenu *pop; + TQTimer popt; +}; + +class TDMSlimShutdown : public FDialog { + Q_OBJECT + typedef FDialog inherited; + + public: + TDMSlimShutdown( TQWidget *_parent = 0 ); + ~TDMSlimShutdown(); + static void externShutdown( int type, const char *os, int uid ); + + private slots: + void slotHalt(); + void slotReboot(); + void slotReboot( int ); + void slotSched(); + + private: + bool checkShutdown( int type, const char *os ); + char **targetList; + +}; + +class TDMConfShutdown : public TDMShutdownBase { + Q_OBJECT + typedef TDMShutdownBase inherited; + + public: + TDMConfShutdown( int _uid, struct dpySpec *sess, int type, const char *os, + TQWidget *_parent = 0 ); +}; + +class TDMCancelShutdown : public TDMShutdownBase { + Q_OBJECT + typedef TDMShutdownBase inherited; + + public: + TDMCancelShutdown( int how, int start, int timeout, int force, int uid, + const char *os, TQWidget *_parent ); +}; + +class KSMPushButton : public KPushButton +{ + Q_OBJECT + +public: + + KSMPushButton( const KGuiItem &item, TQWidget *parent, const char *name = 0 ); + +protected: + virtual void keyPressEvent(TQKeyEvent*e); + virtual void keyReleaseEvent(TQKeyEvent*e); + +private: + + bool m_pressed; + +}; + +class FlatButton : public TQToolButton +{ + Q_OBJECT + + public: + + FlatButton( TQWidget *parent = 0, const char *name = 0 ); + ~FlatButton(); + + protected: + virtual void keyPressEvent(TQKeyEvent*e); + virtual void keyReleaseEvent(TQKeyEvent*e); + + private slots: + + private: + void init(); + + bool m_pressed; + TQString m_text; + TQPixmap m_pixmap; + +}; + +#endif /* TDMSHUTDOWN_H */ diff --git a/tdm/kfrontend/themer/CMakeLists.txt b/tdm/kfrontend/themer/CMakeLists.txt new file mode 100644 index 000000000..fc0b80fc3 --- /dev/null +++ b/tdm/kfrontend/themer/CMakeLists.txt @@ -0,0 +1,41 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/tdm/kfrontend + ${CMAKE_SOURCE_DIR}/tdmlib + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +# FIXME this must be optimized +##### config.ci (generated) ##################### + +add_custom_command( OUTPUT config.ci + COMMAND perl -w ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def config.ci + DEPENDS ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def ) +set_property( SOURCE tdmthemer.cpp APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/config.ci ) + + +##### tdmthemer (static) ######################## + +tde_add_library( tdmthemer STATIC_PIC AUTOMOC + SOURCES + tdmthemer.cpp tdmitem.cpp tdmpixmap.cpp + tdmrect.cpp tdmlabel.cpp tdmlayout.cpp +) diff --git a/tdm/kfrontend/themer/Makefile.am b/tdm/kfrontend/themer/Makefile.am new file mode 100644 index 000000000..f736795d6 --- /dev/null +++ b/tdm/kfrontend/themer/Makefile.am @@ -0,0 +1,16 @@ +AM_CPPFLAGS = -I$(srcdir)/../../backend -I$(srcdir)/.. -I../.. \ + -I$(top_srcdir)/tdmlib \ + $(all_includes) + +noinst_LIBRARIES = libtdmthemer.a +libtdmthemer_a_SOURCES = \ + tdmthemer.cpp \ + tdmitem.cpp \ + tdmpixmap.cpp \ + tdmrect.cpp \ + tdmlabel.cpp \ + tdmlayout.cpp + +METASOURCES = AUTO + +libtdmthemer_a_COMPILE_FIRST = ../../config.ci diff --git a/tdm/kfrontend/themer/tdmitem.cpp b/tdm/kfrontend/themer/tdmitem.cpp new file mode 100644 index 000000000..8cf126b66 --- /dev/null +++ b/tdm/kfrontend/themer/tdmitem.cpp @@ -0,0 +1,657 @@ +/* + * Copyright (C) 2003 by Unai Garro + * Copyright (C) 2004 by Enrico Ros + * Copyright (C) 2004 by Stephan Kulow + * Copyright (C) 2004 by Oswald Buddenhagen + * + * 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. + */ + +/* + * Generic Kdm Item + */ + +// #define DRAW_OUTLINE 1 // for debugging only + +#include "tdmitem.h" +#include "tdmlayout.h" +#include "tdmconfig.h" + +#include +#include + +#include +#include +#include +#include +#include + +extern bool argb_visual_available; + +KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name ) + : TQObject( parent, name ) + , boxManager( 0 ) + , fixedManager( 0 ) + , image( 0 ) + , myWidget( 0 ) + , myLayoutItem( 0 ) + , buttonParent( 0 ) +{ + init(node, name); +} + + +KdmItem::KdmItem( TQWidget *parent, const TQDomNode &node, const char *name ) + : TQObject( parent, name ) + , boxManager( 0 ) + , fixedManager( 0 ) + , image( 0 ) + , myWidget( 0 ) + , myLayoutItem( 0 ) + , buttonParent( 0 ) +{ + init(node, name); +} + +void +KdmItem::init( const TQDomNode &node, const char * ) +{ + // Set default layout for every item + currentManager = MNone; + pos.x = pos.y = 0; + pos.width = pos.height = 1; + pos.xType = pos.yType = pos.wType = pos.hType = DTnone; + pos.anchor = "nw"; + m_backgroundModifier = 255; + + isShown = InitialHidden; + + // Set defaults for derived item's properties + properties.incrementalPaint = false; + state = Snormal; + + // The "toplevel" node (the screen) is really just like a fixed node + if (!parent() || !parent()->inherits( "KdmItem" )) { + setFixedLayout(); + return; + } + // Read the mandatory Pos tag. Other tags such as normal, prelighted, + // etc.. are read under specific implementations. + TQDomNodeList childList = node.childNodes(); + for (uint nod = 0; nod < childList.count(); nod++) { + TQDomNode child = childList.item( nod ); + TQDomElement el = child.toElement(); + TQString tagName = el.tagName(), attr; + + if (tagName == "pos") { + parseAttribute( el.attribute( "x", TQString::null ), pos.x, pos.xType ); + parseAttribute( el.attribute( "y", TQString::null ), pos.y, pos.yType ); + parseAttribute( el.attribute( "width", TQString::null ), pos.width, pos.wType ); + parseAttribute( el.attribute( "height", TQString::null ), pos.height, pos.hType ); + pos.anchor = el.attribute( "anchor", "nw" ); + } + + if (tagName == "bgmodifier") { + m_backgroundModifier = TQString(el.attribute( "value", "255" )).toInt(); + } + } + + TQDomNode tnode = node; + id = tnode.toElement().attribute( "id", TQString::number( (ulong)this, 16 ) ); + + // Tell 'parent' to add 'me' to its children + KdmItem *parentItem = static_cast( parent() ); + parentItem->addChildItem( this ); +} + +KdmItem::~KdmItem() +{ + delete boxManager; + delete fixedManager; + delete image; +} + +void +KdmItem::update() +{ +} + +void +KdmItem::needUpdate() +{ + emit needUpdate( area.x(), area.y(), area.width(), area.height() ); +} + +void +KdmItem::show( bool force ) +{ + if (isShown != InitialHidden && !force) + return; + + TQValueList::Iterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) + (*it)->show(); + + isShown = Shown; + + if (myWidget) + myWidget->show(); + // XXX showing of layouts not implemented, prolly pointless anyway + + needUpdate(); +} + +void +KdmItem::hide( bool force ) +{ + if (isShown == ExplicitlyHidden) + return; + + if (isShown == InitialHidden && force) { + isShown = ExplicitlyHidden; + return; // no need for further action + } + + TQValueList::Iterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) + (*it)->hide(); + + isShown = force ? ExplicitlyHidden : InitialHidden; + + if (myWidget) + myWidget->hide(); + // XXX hiding of layouts not implemented, prolly pointless anyway + + needUpdate(); +} + +void +KdmItem::inheritFromButton( KdmItem *button ) +{ + if (button) + buttonParent = button; + + TQValueList::Iterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) + (*it)->inheritFromButton( button ); +} + +KdmItem * +KdmItem::findNode( const TQString &_id ) const +{ + if (id == _id) + return const_cast( this ); + + TQValueList::ConstIterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) { + KdmItem *t = (*it)->findNode( _id ); + if (t) + return t; + } + + return 0; +} + +void +KdmItem::setWidget( TQWidget *widget ) +{ +// delete myWidget; -- themer->widget() owns the widgets + + myWidget = widget; + if (isHidden()) + myWidget->hide(); + else + myWidget->show(); + + // Remove borders so that it blends nicely with the theme background + TQFrame* frame = ::tqqt_cast( widget ); + if (frame) + frame->setFrameStyle( TQFrame::NoFrame ); + + setGeometry(area, true); + + connect( myWidget, TQT_SIGNAL(destroyed()), TQT_SLOT(widgetGone()) ); +} + +void +KdmItem::widgetGone() +{ + myWidget = 0; +} + +void +KdmItem::setLayoutItem( TQLayoutItem *item ) +{ + myLayoutItem = item; + // XXX hiding not supported - it think it's pointless here + if (myLayoutItem->widget()) + connect( myLayoutItem->widget(), TQT_SIGNAL(destroyed()), + TQT_SLOT(layoutItemGone()) ); + else if (myLayoutItem->layout()) + connect( myLayoutItem->layout(), TQT_SIGNAL(destroyed()), + TQT_SLOT(layoutItemGone()) ); +} + +void +KdmItem::layoutItemGone() +{ + myLayoutItem = 0; +} + +/* This is called as a result of KdmLayout::update, and directly on the root */ +void +KdmItem::setGeometry( const TQRect &newGeometry, bool force ) +{ + kdDebug() << " KdmItem::setGeometry " << id << newGeometry << endl; + // check if already 'in place' + if (!force && area == newGeometry) + return; + + area = newGeometry; + + if (myWidget) { + TQRect widGeo = newGeometry; + if ( widGeo.height() > myWidget->maximumHeight() ) { + widGeo.moveTop( widGeo.top() + ( widGeo.height() - myWidget->maximumHeight() ) / 2 ); + widGeo.setHeight( myWidget->maximumHeight() ); + } + myWidget->setGeometry( widGeo ); + } + if (myLayoutItem) + myLayoutItem->setGeometry( newGeometry ); + + // recurr to all boxed children + if (boxManager && !boxManager->isEmpty()) + boxManager->update( newGeometry, force ); + + // recurr to all fixed children + if (fixedManager && !fixedManager->isEmpty()) + fixedManager->update( newGeometry, force ); + + // TODO send *selective* repaint signal +} + +void +KdmItem::paint( TQPainter *p, const TQRect &rect ) +{ + if (isHidden()) + return; + + if (myWidget || (myLayoutItem && myLayoutItem->widget())) { + // KListView because it's missing a Q_OBJECT' + // FIXME: This is a nice idea in theory, but in practice it is + // very confusing for the user not to see the empty list box + // delineated from the rest of the greeter. + // Maybe set a darker version of the background instead of an exact copy? + if ( myWidget && myWidget->isA( "KListView" ) ) { + if ((_compositor.isEmpty()) || (!argb_visual_available)) { + // Software blend only (no compositing support) + TQPixmap copy( myWidget->size() ); + kdDebug() << myWidget->geometry() << " " << area << " " << myWidget->size() << endl; + bitBlt( ©, TQPoint( 0, 0), p->device(), myWidget->geometry(), TQt::CopyROP ); + // Lighten it slightly + TQImage lightVersion; + lightVersion = copy.convertToImage(); + + register uchar * r = lightVersion.bits(); + register uchar * g = lightVersion.bits() + 1; + register uchar * b = lightVersion.bits() + 2; + uchar * end = lightVersion.bits() + lightVersion.numBytes(); + + while ( r != end ) { + if ((*r) < (255-m_backgroundModifier)) + *r = (uchar) (*r) + m_backgroundModifier; + else + *r = 255; + if ((*g) < (255-m_backgroundModifier)) + *g = (uchar) (*g) + m_backgroundModifier; + else + *g = 255; + if ((*b) < (255-m_backgroundModifier)) + *b = (uchar) (*b) + m_backgroundModifier; + else + *b = 255; + r += 4; + g += 4; + b += 4; + } + + copy = lightVersion; + // Set it + myWidget->setPaletteBackgroundPixmap( copy ); + } + else { + // We have compositing support! + TQRgb blend_color = tqRgba(m_backgroundModifier, m_backgroundModifier, m_backgroundModifier, 0); // RGBA overlay + float alpha = tqAlpha(blend_color) / 255.; + int pixel = tqAlpha(blend_color) << 24 | + int(tqRed(blend_color) * alpha) << 16 | + int(tqGreen(blend_color) * alpha) << 8 | + int(tqBlue(blend_color) * alpha); + + TQImage img( myWidget->size(), 32 ); + img = img.convertDepth(32); + img.setAlphaBuffer(true); + register uchar * rd = img.bits(); + for( int y = 0; y < img.height(); ++y ) + { + for( short int x = 0; x < img.width(); ++x ) + { + *reinterpret_cast(rd) = blend_color; + rd += 4; + } + } + myWidget->setPaletteBackgroundPixmap( img ); + } + } + return; + } + + if (area.intersects( rect )) { + TQRect contentsRect = area.intersect( rect ); + contentsRect.moveBy( QMIN( 0, -area.x() ), QMIN( 0, -area.y() ) ); + drawContents( p, contentsRect ); + } + +#ifdef DRAW_OUTLINE + // Draw bounding rect for this item + p->setPen( Qt::white ); + p->drawRect( area ); +#endif + + if (myLayoutItem) + return; + + // Dispatch paint events to children + TQValueList::Iterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) + (*it)->paint( p, rect ); + + +} + +KdmItem *KdmItem::currentActive = 0; + +void +KdmItem::mouseEvent( int x, int y, bool pressed, bool released ) +{ + if (isShown == ExplicitlyHidden) + return; + + if (buttonParent && buttonParent != this) { + buttonParent->mouseEvent( x, y, pressed, released ); + return; + } + + ItemState oldState = state; + if (area.contains( x, y )) { + if (released && oldState == Sactive) { + if (buttonParent) + emit activated( id ); + state = Sprelight; + currentActive = 0; + } else if (pressed || currentActive == this) { + state = Sactive; + currentActive = this; + } else if (!currentActive) + state = Sprelight; + else + state = Snormal; + } else { + if (released) + currentActive = 0; + if (currentActive == this) + state = Sprelight; + else + state = Snormal; + } + + if (!buttonParent) { + TQValueList::Iterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) + (*it)->mouseEvent( x, y, pressed, released ); + } + + if (oldState != state) + statusChanged(); +} + +void +KdmItem::statusChanged() +{ + if (buttonParent == this) { + TQValueList::Iterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) { + (*it)->state = state; + (*it)->statusChanged(); + } + } +} + +// BEGIN protected inheritable + +TQSize +KdmItem::sizeHint() +{ + if (myWidget) + return myWidget->size(); + if (myLayoutItem) + return myLayoutItem->sizeHint(); + int w = pos.wType == DTpixel ? kAbs( pos.width ) : -1, + h = pos.hType == DTpixel ? kAbs( pos.height ) : -1; + return TQSize( w, h ); +} + +TQRect +KdmItem::placementHint( const TQRect &parentRect ) +{ + TQSize hintedSize = sizeHint(); + TQSize boxHint; + + int x = parentRect.left(), + y = parentRect.top(), + w = parentRect.width(), + h = parentRect.height(); + + kdDebug() << timestamp() << " KdmItem::placementHint parentRect=" << parentRect << " hintedSize=" << hintedSize << endl; + + // check if width or height are set to "box" + if (pos.wType == DTbox || pos.hType == DTbox) { + if (myLayoutItem || myWidget) + boxHint = hintedSize; + else { + if (!boxManager) + return parentRect; + boxHint = boxManager->sizeHint(); + } + kdDebug() << timestamp() << " boxHint " << boxHint << endl; + } + + if (pos.xType == DTpixel) + x += pos.x; + else if (pos.xType == DTnpixel) + x = parentRect.right() - pos.x; + else if (pos.xType == DTpercent) + x += tqRound( parentRect.width() / 100.0 * pos.x ); + + if (pos.yType == DTpixel) + y += pos.y; + else if (pos.yType == DTnpixel) + y = parentRect.bottom() - pos.y; + else if (pos.yType == DTpercent) + y += tqRound( parentRect.height() / 100.0 * pos.y ); + + if (pos.wType == DTpixel) + w = pos.width; + else if (pos.wType == DTnpixel) + w -= pos.width; + else if (pos.wType == DTpercent) + w = tqRound( parentRect.width() / 100.0 * pos.width ); + else if (pos.wType == DTbox) + w = boxHint.width(); + else if (hintedSize.width() > 0) + w = hintedSize.width(); + else + w = 0; + + if (pos.hType == DTpixel) + h = pos.height; + else if (pos.hType == DTnpixel) + h -= pos.height; + else if (pos.hType == DTpercent) + h = tqRound( parentRect.height() / 100.0 * pos.height ); + else if (pos.hType == DTbox) + h = boxHint.height(); + else if (hintedSize.height() > 0) { + if (w && pos.wType != DTnone) + h = (hintedSize.height() * w) / hintedSize.width(); + else + h = hintedSize.height(); + } else + h = 0; + + // we choose to take the hinted size, but it's better to listen to the aspect ratio + if (pos.wType == DTnone && pos.hType != DTnone && h && w) { + w = tqRound(float(hintedSize.width() * h) / hintedSize.height()); + } + + // defaults to center + int dx = -w / 2, dy = -h / 2; + + // anchor the rect to an edge / corner + if (pos.anchor.length() > 0 && pos.anchor.length() < 3) { + if (pos.anchor.find( 'n' ) >= 0) + dy = 0; + if (pos.anchor.find( 's' ) >= 0) + dy = -h; + if (pos.anchor.find( 'w' ) >= 0) + dx = 0; + if (pos.anchor.find( 'e' ) >= 0) + dx = -w; + } + // KdmItem *p = static_cast( parent() ); + kdDebug() << timestamp() << " placementHint " << this << " x=" << x << " dx=" << dx << " w=" << w << " y=" << y << " dy=" << dy << " h=" << h << " " << parentRect << endl; + y += dy; + x += dx; + + // Note: no clipping to parent because this broke many themes! + return TQRect( x, y, w, h ); +} + +// END protected inheritable + + +void +KdmItem::addChildItem( KdmItem *item ) +{ + m_children.append( item ); + switch (currentManager) { + case MNone: // fallback to the 'fixed' case + setFixedLayout(); + case MFixed: + fixedManager->addItem( item ); + break; + case MBox: + boxManager->addItem( item ); + break; + } + + // signal bounce from child to parent + connect( item, TQT_SIGNAL(needUpdate( int, int, int, int )), TQT_SIGNAL(needUpdate( int, int, int, int )) ); + connect( item, TQT_SIGNAL(activated( const TQString & )), TQT_SIGNAL(activated( const TQString & )) ); +} + +void +KdmItem::parseAttribute( const TQString &s, int &val, enum DataType &dType ) +{ + if (s.isEmpty()) + return; + + int p; + if (s == "box") { // box value + dType = DTbox; + val = 0; + } else if ((p = s.find( '%' )) >= 0) { // percent value + dType = DTpercent; + TQString sCopy = s; + sCopy.remove( p, 1 ); + sCopy.replace( ',', '.' ); + val = (int)sCopy.toDouble(); + } else { // int value + dType = DTpixel; + TQString sCopy = s; + if (sCopy.at( 0 ) == '-') { + sCopy.remove( 0, 1 ); + dType = DTnpixel; + } + sCopy.replace( ',', '.' ); + val = (int)sCopy.toDouble(); + } +} + +void +KdmItem::parseFont( const TQString &s, TQFont &font ) +{ + int splitAt = s.findRev( ' ' ); + if (splitAt < 1) + return; + font.setFamily( s.left( splitAt ) ); + int fontSize = s.mid( splitAt + 1 ).toInt(); + if (fontSize > 1) + font.setPointSize( fontSize ); +} + +void +KdmItem::parseColor( const TQString &s, TQColor &color ) +{ + if (s.at( 0 ) != '#') + return; + bool ok; + TQString sCopy = s; + int hexColor = sCopy.remove( 0, 1 ).toInt( &ok, 16 ); + if (ok) + color.setRgb( hexColor ); +} + +void +KdmItem::setBoxLayout( const TQDomNode &node ) +{ + if (!boxManager) + boxManager = new KdmLayoutBox( node ); + currentManager = MBox; +} + +void +KdmItem::setFixedLayout( const TQDomNode &node ) +{ + if (!fixedManager) + fixedManager = new KdmLayoutFixed( node ); + currentManager = MFixed; +} + +TQWidget * +KdmItem::parentWidget() const +{ + if (myWidget) + return myWidget; + if (!this->parent()) + return 0; + + if (parent()->qt_cast(TQWIDGET_OBJECT_NAME_STRING)) + return (TQWidget*)parent(); + return ((KdmItem*)parent())->parentWidget(); +} + +#include "tdmitem.moc" diff --git a/tdm/kfrontend/themer/tdmitem.h b/tdm/kfrontend/themer/tdmitem.h new file mode 100644 index 000000000..27158a7fd --- /dev/null +++ b/tdm/kfrontend/themer/tdmitem.h @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2003 by Unai Garro + * Copyright (C) 2004 by Enrico Ros + * Copyright (C) 2004 by Stephan Kulow + * Copyright (C) 2004 by Oswald Buddenhagen + * + * 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. + */ + +#ifndef TDMITEM_H +#define TDMITEM_H + +#include +#include +#include +#include + +class KdmItem; +class KdmLayoutBox; +class KdmLayoutFixed; + +class TQPainter; +class TQLayoutItem; + +/** class KdmItem + * @short Base class for every tdmthemes' element. + * + * This class provides methods for arranging it and its children to the + * screen (see note below), painting the whole area or a sub-region using + * an opened painter, handling mouse events or events in general dispatching + * them to children and sending some signals to the root (for example on + * mouse click). + * + * KdmItem sits in a hierarchical top to bottom tree with signals that + * traverse the tree back from leafs (or inner nodes) to the root. + * + * To implement a KdmItem only a few virtual protected methods must be + * reimplemented, other virtual functions are there for convenience only - + * the default implementation should satisfy your needs. + */ + +/** + * A note on layouting - how does it work? + * - setgeometry is called by parent (passing the new geometry) + * - item changes its geometry + * - if item embeds a widget, reposition it too + * - call children's box manager. box->update( my geom ) + * - sum up the whole space taken by children (via *hint calls) if + * needed for box width / height computation. note that the computed + * geometry should be equal or similar to parent's geometry. + * - pad the rectangle bounding box' contents + * - for every child + * - if vertical + * ( use a top-to-bottom insertion, spacing insertion lines by + * children's individual height ) + * - set up a zero height Parent (placed at the insertion line's + * position) and get Geom = child->placementHint( p ) + * - set up child's Size using Parent's width and Geom's height. + * - call to child->setGeometry( Parent.topLeft, Size ) + * - if horizontal + * - flows like the vertical one but uses a left-to-right insertion + * and insertion entry points are vertical lines + * - call to children's fix manager. fixed->update( my geom ) + * - for every child + * - S = get child's geometry hint (and we'll give item the whole + * space it needs, without constraints) + * - call to child->setGeometry( S ) + * - TODO: send a selective redraw signal also merging children's areas + */ + +class KdmItem : public TQObject { + Q_OBJECT + + friend class KdmThemer; + +public: + /** + * Item constructor and destructor + */ + KdmItem( KdmItem *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 ); + KdmItem( TQWidget *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 ); // for the root + + virtual ~KdmItem(); + + /** + * Fixup the geometry of an item and its children (even if fixed + * or boxed ones). Note that this will generate repaint signals + * when needed. The default implementation should fit all needs. + */ + virtual void setGeometry( const TQRect &newGeometry, bool force ); + + /** + * Paint the item and its children using the given painter. + * This is the compositing core function. It buffers paint operations + * to speed up rendering of dynamic objects. + */ + void paint( TQPainter *painter, const TQRect &boundaries ); + + /** + * Update representation of contents and repaint. + */ + virtual void update(); + + /** + * Handle mouse motion and dispatch events to children. This + * leads to items prelighting, activation() on click and more.. + */ + void mouseEvent( int x, int y, bool pressed = false, bool released = false ); + + /** + * Similar to sizeHint(..), this returns the area of the item + * given the @p parentGeometry. The default implementation + * takes into account geometric constraints and layoutings. + * @param parentGeometry the geometry of the caller item or a + * null rect if the geometry of the parent is not yet defined. + */ + virtual TQRect placementHint( const TQRect &parentGeometry ); + + /** + * Create the box layout manager; next children will be + * managed by the box layouter + */ + void setBoxLayout( const TQDomNode &node = TQDomNode() ); + + /** + * Create the fixed layout manager; next children will be + * in fixed position relative to this item + */ + void setFixedLayout( const TQDomNode &node = TQDomNode() ); + + TQString type() const { return itemType; } + void setType( const TQString &t ) { itemType = t; } + void setBaseDir( const TQString &bd ) { basedir = bd; } + + TQString baseDir() const + { + if (basedir.isEmpty() && parent()) + return static_cast( parent()->qt_cast( "KdmItem" ) )->baseDir(); + return basedir; + } + + KdmItem *findNode( const TQString &id ) const; + virtual void setWidget( TQWidget *widget ); + TQWidget *widget() const { return myWidget; } + virtual void setLayoutItem( TQLayoutItem *item ); + + virtual void hide( bool force = false ); + virtual void show( bool force = false ); + + bool isHidden() const { return isShown != Shown; } + bool isExplicitlyHidden() const { return isShown == ExplicitlyHidden; } + TQRect rect() const { return area; } + + TQWidget *parentWidget() const; + TQString getId() const { return id; } + +signals: + void needUpdate( int x, int y, int w, int h ); + void activated( const TQString &id ); + +protected slots: + void widgetGone(); + void layoutItemGone(); + +protected: + /** + * Returns the optimal/minimal size for this item. + * This should be reimplemented in items like label and pixmap. + * @return (-1,-1) if no size can be determined (so it should + * default to parent's size). + */ + virtual TQSize sizeHint(); + + /** + * Low level graphical function to paint the item. + * All items must reimplement this function to draw themeselves + * (or a part of) into the @p image keeping inside the @p rect . + * Try to do this as fast as possible. + * @param painter the painter to draw the item with + * @param region the part of the the image to render + */ + virtual void drawContents( TQPainter *painter, const TQRect ®ion ) = 0; + + /** + * Called when item changes its 'state' variable. This must + * handle item's repaint. + */ + virtual void statusChanged(); + + /** + * emits needUpdate( int, int, int, int ) with the full widget area. + */ + void needUpdate(); + + // This enum identifies in which state the item is + enum ItemState { Snormal, Sactive, Sprelight } state; + + static KdmItem *currentActive; + + // This struct can be filled in by derived items + struct { + bool incrementalPaint; + } properties; + + // This is the placement of the item + TQRect area; + + // This struct is filled in by KdmItem base class + enum DataType { DTnone, DTpixel, DTnpixel, DTpercent, DTbox }; + struct { + enum DataType xType, yType, wType, hType; + int x; + int y; + int width; + int height; + TQString anchor; + } pos; + + /* For internal use ONLY + * Add a child item. This function is called automatically + * when constructing an @p item with this as the parent. + */ + void addChildItem( KdmItem *item ); + + /* For internal use ONLY + * Parse type and value of an attribute (pos tag), a font or a + * color. + */ + void parseAttribute( const TQString &, int &, enum DataType & ); + void parseFont( const TQString &, TQFont & ); + void parseColor( const TQString &, TQColor & ); + + void inheritFromButton( KdmItem *button ); + void init( const TQDomNode &node = TQDomNode(), const char *name = 0 ); + + TQString itemType, id; + TQValueList m_children; + + int m_backgroundModifier; + + // Layouting related variables + enum { MNone = 0, MFixed = 1, MBox = 2 } currentManager; + KdmLayoutBox *boxManager; + KdmLayoutFixed *fixedManager; + + // Compositing related variables + TQImage *image; + + // defines the directory the theme is in (may be present in the parent) + TQString basedir; + + TQWidget *myWidget; + TQLayoutItem *myLayoutItem; + + enum { InitialHidden, ExplicitlyHidden, Shown } isShown; + + KdmItem *buttonParent; +}; + +#endif diff --git a/tdm/kfrontend/themer/tdmlabel.cpp b/tdm/kfrontend/themer/tdmlabel.cpp new file mode 100644 index 000000000..5239d48dc --- /dev/null +++ b/tdm/kfrontend/themer/tdmlabel.cpp @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2003 by Unai Garro + * Copyright (C) 2004 by Enrico Ros + * Copyright (C) 2004 by Stephan Kulow + * Copyright (C) 2004 by Oswald Buddenhagen + * + * 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 +#include "tdmlabel.h" +#include "tdmconfig.h" +#include "../kgreeter.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#if !defined(HAVE_GETDOMAINNAME) && defined(HAVE_SYSINFO) +# include +#endif + +KdmLabel::KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name ) + : KdmItem( parent, node, name ), myAccel(0) +{ + itemType = "label"; + + // Set default values for label (note: strings are already Null) + label.active.color.setRgb( 0xFFFFFF ); + label.active.present = false; + label.prelight.present = false; + label.maximumWidth = -1; + + const TQString locale = KGlobal::locale()->language(); + + // Read LABEL ID + TQDomNode n = node; + TQDomElement elLab = n.toElement(); + // ID types: clock, pam-error, pam-message, pam-prompt, + // pam-warning, timed-label + label.id = elLab.attribute( "id", "" ); + label.hasId = !(label.id).isEmpty(); + + // Read LABEL TAGS + TQDomNodeList childList = node.childNodes(); + bool stockUsed = false; + for (uint nod = 0; nod < childList.count(); nod++) { + TQDomNode child = childList.item( nod ); + TQDomElement el = child.toElement(); + TQString tagName = el.tagName(); + + if (tagName == "pos") + label.maximumWidth = el.attribute( "max-width", "-1" ).toInt(); + else if (tagName == "normal") { + parseColor( el.attribute( "color", "#ffffff" ), label.normal.color ); + parseFont( el.attribute( "font", "Sans 14" ), label.normal.font ); + } else if (tagName == "active") { + label.active.present = true; + parseColor( el.attribute( "color", "#ffffff" ), label.active.color ); + parseFont( el.attribute( "font", "Sans 14" ), label.active.font ); + } else if (tagName == "prelight") { + label.prelight.present = true; + parseColor( el.attribute( "color", "#ffffff" ), label.prelight.color ); + parseFont( el.attribute( "font", "Sans 14" ), label.prelight.font ); + } else if (tagName == "text" && el.attributes().count() == 0 && !stockUsed) { + label.text = el.text(); + } else if (tagName == "text" && !stockUsed) { + TQString lang = el.attribute( "xml:lang", "" ); + if (lang == locale) + label.text = el.text(); + } else if (tagName == "stock") { + label.text = lookupStock( el.attribute( "type", "" ) ); + stockUsed = true; + } + } + + // Check if this is a timer label) + label.isTimer = label.text.find( "%c" ) >= 0; + if (label.isTimer) { + timer = new TQTimer( this ); + timer->start( 1000 ); + connect( timer, TQT_SIGNAL(timeout()), TQT_SLOT(update()) ); + } + setTextInt( lookupText( label.text ) ); +} + +void +KdmLabel::setTextInt( const TQString &txt) +{ + // TODO: catch && + cText = txt; + cAccel = txt.find('&'); + delete myAccel; + myAccel = 0; + if (cAccel != -1) { + cText.remove('&'); + myAccel = new TQAccel(parentWidget()); + myAccel->insertItem(ALT + UNICODE_ACCEL + cText.at(cAccel).lower().unicode()); + connect(myAccel, TQT_SIGNAL(activated(int)), TQT_SLOT(slotAccel())); + } +} + +void +KdmLabel::slotAccel() +{ + if (buttonParent) + emit activated(buttonParent->getId()); + else + emit activated(id); +} + +void +KdmLabel::setText( const TQString &txt ) +{ + label.text = txt; + setTextInt( lookupText( label.text ) ); +} + +TQSize +KdmLabel::sizeHint() +{ + // choose the correct label class + struct LabelStruct::LabelClass *l = &label.normal; + if (state == Sactive && label.active.present) + l = &label.active; + else if (state == Sprelight && label.prelight.present) + l = &label.prelight; + // get the hint from font metrics + TQSize hint = TQFontMetrics( l->font ).size( AlignLeft | SingleLine, cText ); + // clip the result using the max-width label(pos) parameter + if (label.maximumWidth > 0 && hint.width() > label.maximumWidth) + hint.setWidth( label.maximumWidth ); + return hint; +} + +void +KdmLabel::drawContents( TQPainter *p, const TQRect &/*r*/ ) +{ + // choose the correct label class + struct LabelStruct::LabelClass *l = &label.normal; + if (state == Sactive && label.active.present) + l = &label.active; + else if (state == Sprelight && label.prelight.present) + l = &label.prelight; + // draw the label + p->setFont( l->font ); + p->setPen( l->color ); + //TODO paint clipped (tested but not working..) + if (cAccel != -1 && (!id.isEmpty() || buttonParent) ) { + TQString left = cText.left(cAccel); + TQString right = cText.mid(cAccel + 1); + p->drawText( area, AlignLeft | SingleLine, left ); + TQRect tarea = area; + TQFontMetrics fm(l->font); + tarea.rLeft() += fm.width(left); + TQFont f(l->font); + f.setUnderline(true); + p->setFont ( f ); + p->drawText( tarea, AlignLeft | SingleLine, TQString(cText.at(cAccel))); + tarea.rLeft() += fm.width(cText.at(cAccel)); + p->setFont( l->font ); + p->drawText( tarea, AlignLeft | SingleLine, right); + } else { + p->drawText( area, AlignLeft | SingleLine, cText); + } +} + +void +KdmLabel::statusChanged() +{ + KdmItem::statusChanged(); + if (!label.active.present && !label.prelight.present) + return; + if ((state == Sprelight && !label.prelight.present) || + (state == Sactive && !label.active.present)) + return; + needUpdate(); +} + +void +KdmLabel::update() +{ + TQString text = lookupText( label.text ); + if (text != cText) { + setTextInt(text); + needUpdate(); + } +} + +static const struct { + const char *type, *text; +} stocks[] = { + { "language", I18N_NOOP("Language") }, + { "session", I18N_NOOP("Session Type") }, + { "system", I18N_NOOP("Menu") }, // i18n("Actions"); + { "admin", I18N_NOOP("&Administration") }, + { "disconnect", I18N_NOOP("Disconnect") }, + { "quit", I18N_NOOP("Quit") }, + { "halt", I18N_NOOP("Power Off") }, + { "suspend", I18N_NOOP("Suspend") }, + { "reboot", I18N_NOOP("Reboot") }, + { "chooser", I18N_NOOP("XDMCP Chooser") }, + { "config", I18N_NOOP("Configure") }, + { "caps-lock-warning", I18N_NOOP("Caps Lock is enabled.") }, + { "timed-label", I18N_NOOP("User %s will login in %d seconds") }, + { "welcome-label", I18N_NOOP("Welcome to %h") }, // _greetString + { "username-label", I18N_NOOP("Username:") }, + { "password-label", I18N_NOOP("Password:") }, + { "domain-label", I18N_NOOP("Domain:") }, + { "login", I18N_NOOP("Login") } +}; + +TQString +KdmLabel::lookupStock( const TQString &stock ) +{ + //FIXME add key accels! + TQString type( stock.lower() ); + + for (uint i = 0; i < sizeof(stocks)/sizeof(stocks[0]); i++) + if (type == stocks[i].type) + return i18n(stocks[i].text); + + kdDebug() << timestamp() << " Invalid element. Check your theme!" << endl; + return stock; +} + +TQString +KdmLabel::lookupText( const TQString &t ) +{ + TQString text = t; + + text.replace( '_', '&' ); + + TQMap m; + struct utsname uts; + uname( &uts ); + m['n'] = TQString::fromLocal8Bit( uts.nodename ); + char buf[256]; + buf[sizeof(buf) - 1] = '\0'; + m['h'] = gethostname( buf, sizeof(buf) - 1 ) ? "localhost" : TQString::fromLocal8Bit( buf ); +#ifdef HAVE_GETDOMAINNAME + m['o'] = getdomainname( buf, sizeof(buf) - 1 ) ? "localdomain" : TQString::fromLocal8Bit( buf ); +#elif defined(HAVE_SYSINFO) + m['o'] = (unsigned)sysinfo( SI_SRPC_DOMAIN, buf, sizeof(buf) ) > sizeof(buf) ? "localdomain" : TQString::fromLocal8Bit( buf ); +#endif + m['d'] = TQString::number( KThemedGreeter::timedDelay ); + m['s'] = KThemedGreeter::timedUser; + // xgettext:no-c-format + KGlobal::locale()->setDateFormat( i18n("date format", "%a %d %B") ); + m['c'] = KGlobal::locale()->formatDateTime( TQDateTime::currentDateTime(), false, false ); + + return KMacroExpander::expandMacros( text, m ); +} + +#include "tdmlabel.moc" diff --git a/tdm/kfrontend/themer/tdmlabel.h b/tdm/kfrontend/themer/tdmlabel.h new file mode 100644 index 000000000..8b955fca5 --- /dev/null +++ b/tdm/kfrontend/themer/tdmlabel.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2003 by Unai Garro + * Copyright (C) 2004 by Enrico Ros + * Copyright (C) 2004 by Stephan Kulow + * Copyright (C) 2004 by Oswald Buddenhagen + * + * 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. + */ + +#ifndef KDELABEL_H +#define KDELABEL_H + +#include "tdmitem.h" + +#include +#include + +class TQTimer; + +/* + * KdmLabel. A label element + */ + +class KdmLabel : public KdmItem { + Q_OBJECT + +public: + KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name = 0 ); + void setText( const TQString &txt ); + +protected: + // reimplemented; returns the minimum size of rendered text + virtual TQSize sizeHint(); + + // draw the label + virtual void drawContents( TQPainter *p, const TQRect &r ); + + // handle switching between normal / active / prelight configurations + virtual void statusChanged(); + +public: + struct LabelStruct { + TQString text; + bool isTimer; + bool hasId; + TQString id; + struct LabelClass { + TQColor color; + TQFont font; + bool present; + } normal, active, prelight; + int maximumWidth; + } label; + + TQTimer *timer; + +public slots: + void update(); + void slotAccel(); + +private: + /* Method to lookup the caption associated with an item */ + TQString lookupStock( const TQString &stock ); + + /* Lookup variables in the text */ + TQString lookupText( const TQString &t ); + + TQString cText; + int cAccel; + TQAccel *myAccel; + + void setTextInt(const TQString &); +}; + +#endif diff --git a/tdm/kfrontend/themer/tdmlayout.cpp b/tdm/kfrontend/themer/tdmlayout.cpp new file mode 100644 index 000000000..9a277a7a3 --- /dev/null +++ b/tdm/kfrontend/themer/tdmlayout.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2003 by Unai Garro + * Copyright (C) 2004 by Enrico Ros + * Copyright (C) 2004 by Stephan Kulow + * Copyright (C) 2004 by Oswald Buddenhagen + * + * 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 "tdmlayout.h" +#include "tdmconfig.h" +#include "tdmitem.h" + +#include + +#include +#include + +KdmLayoutFixed::KdmLayoutFixed( const TQDomNode &/*node*/ ) +{ + //Parsing FIXED parameters on 'node' [NONE!] +} + +void +KdmLayoutFixed::update( const TQRect &parentGeometry, bool force ) +{ + kdDebug() << timestamp() << " KdmLayoutFixed::update " << parentGeometry << endl; + + // I can't layout children if the parent rectangle is not valid + if (parentGeometry.width() < 0 || parentGeometry.height() < 0) { + kdDebug() << timestamp() << " invalid\n"; + return; + } + // For each child in list I ask their hinted size and set it! + for (TQValueList::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) + (*it)->setGeometry( (*it)->placementHint( parentGeometry ), force ); +} + +KdmLayoutBox::KdmLayoutBox( const TQDomNode &node ) +{ + //Parsing BOX parameters + TQDomNode n = node; + TQDomElement el = n.toElement(); + box.isVertical = el.attribute( "orientation", "vertical" ) != "horizontal"; + box.xpadding = el.attribute( "xpadding", "0" ).toInt(); + box.ypadding = el.attribute( "ypadding", "0" ).toInt(); + box.spacing = el.attribute( "spacing", "0" ).toInt(); + box.minwidth = el.attribute( "min-width", "0" ).toInt(); + box.minheight = el.attribute( "min-height", "0" ).toInt(); + box.homogeneous = el.attribute( "homogeneous", "false" ) == "true"; +} + +void +KdmLayoutBox::update( const TQRect &parentGeometry, bool force ) +{ + kdDebug() << this << " update " << parentGeometry << endl; + + // I can't layout children if the parent rectangle is not valid + if (!parentGeometry.isValid() || parentGeometry.isEmpty()) + return; + + // Check if box size was computed. If not compute it + // TODO check if this prevents updating changing items +// if (!hintedSize.isValid()) +// sizeHint(); + +// kdDebug() << this << " hintedSize " << hintedSize << endl; + + //XXX why was this asymmetric? it broke things big time. + TQRect childrenRect = /*box.isVertical ? TQRect( parentGeometry.topLeft(), hintedSize ) :*/ parentGeometry; + // Begin cutting the parent rectangle to attach children on the right place + childrenRect.addCoords( box.xpadding, box.ypadding, -box.xpadding, -box.ypadding ); + + kdDebug() << this << " childrenRect " << childrenRect << endl; + + // For each child in list ... + if (box.homogeneous) { + int ccnt = 0; + for (TQValueList::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) + if (!(*it)->isExplicitlyHidden()) + ccnt++; + int height = (childrenRect.height() - (ccnt - 1) * box.spacing) / ccnt; + int width = (childrenRect.width() - (ccnt - 1) * box.spacing) / ccnt; + + for (TQValueList::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) { + if ((*it)->isExplicitlyHidden()) + continue; + if (box.isVertical) { + TQRect temp( childrenRect.left(), childrenRect.top(), childrenRect.width(), height ); + (*it)->setGeometry( temp, force ); + childrenRect.setTop( childrenRect.top() + height + box.spacing ); + } else { + TQRect temp( childrenRect.left(), childrenRect.top(), width, childrenRect.height() ); + kdDebug() << timestamp() << " placement " << *it << " " << temp << " " << (*it)->placementHint( temp ) << endl; + temp = (*it)->placementHint( temp ); + (*it)->setGeometry( temp, force ); + childrenRect.setLeft( childrenRect.left() + width + box.spacing ); + } + } + } else { + for (TQValueList::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) { + if ((*it)->isExplicitlyHidden()) + continue; + + TQRect temp = childrenRect, itemRect; + if (box.isVertical) { + temp.setHeight( 0 ); + itemRect = (*it)->placementHint( temp ); + temp.setHeight( itemRect.height() ); + childrenRect.setTop( childrenRect.top() + itemRect.size().height() + box.spacing ); + } else { + temp.setWidth( 0 ); + itemRect = (*it)->placementHint( temp ); + kdDebug() << this << " placementHint " << *it << " " << temp << " " << itemRect << endl; + temp.setWidth( itemRect.width() ); + childrenRect.setLeft( childrenRect.left() + itemRect.size().width() + box.spacing ); + kdDebug() << timestamp() << " childrenRect after " << *it << " " << childrenRect << endl; + } + itemRect = (*it)->placementHint( temp ); + kdDebug() << this << " placementHint2 " << *it << " " << temp << " " << itemRect << endl; + (*it)->setGeometry( itemRect, force ); + } + } +} + +//FIXME truly experimental (is so close to greeter_geometry.c) +TQSize +KdmLayoutBox::sizeHint() +{ + // Sum up area taken by children + int w = 0, h = 0; + for (TQValueList::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) { + TQSize s = (*it)->placementHint( TQRect() ).size(); + if (box.isVertical) { + if (s.width() > w) + w = s.width(); + h += s.height(); + } else { + if (s.height() > h) + h = s.height(); + w += s.width(); + } + } + + // Add padding and items spacing + w += 2 * box.xpadding; + h += 2 * box.ypadding; + if (box.isVertical) + h += box.spacing * (m_children.count() - 1); + else + w += box.spacing * (m_children.count() - 1); + + // Make hint at least equal to minimum size (if set) + return TQSize( w < box.minwidth ? box.minwidth : w, + h < box.minheight ? box.minheight : h ); +} diff --git a/tdm/kfrontend/themer/tdmlayout.h b/tdm/kfrontend/themer/tdmlayout.h new file mode 100644 index 000000000..c147fd329 --- /dev/null +++ b/tdm/kfrontend/themer/tdmlayout.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2003 by Unai Garro + * Copyright (C) 2004 by Enrico Ros + * Copyright (C) 2004 by Stephan Kulow + * Copyright (C) 2004 by Oswald Buddenhagen + * + * 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. + */ + +#ifndef TDMLAYOUT_H +#define TDMLAYOUT_H + +/** + * this is a container for a lot of other stuff + * but can be treated like a usual widget + */ + +#include +#include + +class KdmItem; + +class TQDomNode; +class TQRect; + +class KdmLayout { + +public: +// virtual ~KdmLayout() {}; + + // Adds an item that will be managed + void addItem( KdmItem *item ) { m_children.append( item ); } + + // Return false if any item are managed by this layouter + bool isEmpty() { return m_children.isEmpty(); } + + // Updates the layout of all items knowing that the parent + // has the @p parentGeometry geometry +// virtual void update( const TQRect &parentGeometry ) = 0; + +protected: + TQValueList m_children; +}; + +class KdmLayoutFixed : public KdmLayout { + +public: + KdmLayoutFixed( const TQDomNode &node ); + + // Updates the layout of all boxed items knowing that the parent + // has the @p parentGeometry geometry + void update( const TQRect &parentGeometry, bool force ); +}; + +/** + * this is a container for a lot of other stuff + * but can be treated like a usual widget + */ + +class KdmLayoutBox : public KdmLayout { + +public: + KdmLayoutBox( const TQDomNode &node ); + + // Updates the layout of all boxed items knowing that they + // should fit into @p parentGeometry container + void update( const TQRect &parentGeometry, bool force ); + + // Computes the size hint of the box, telling which is the + // smallest size inside which boxed items will fit + TQSize sizeHint(); + +private: + struct { + bool isVertical; + int spacing; + int xpadding; + int ypadding; + int minwidth; + int minheight; + bool homogeneous; + } box; +// TQSize hintedSize; +}; + +#endif diff --git a/tdm/kfrontend/themer/tdmpixmap.cpp b/tdm/kfrontend/themer/tdmpixmap.cpp new file mode 100644 index 000000000..7a8d1a3d2 --- /dev/null +++ b/tdm/kfrontend/themer/tdmpixmap.cpp @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2003 by Unai Garro + * Copyright (C) 2004 by Enrico Ros + * Copyright (C) 2004 by Stephan Kulow + * Copyright (C) 2004 by Oswald Buddenhagen + * + * 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 + +#include "tdmpixmap.h" +#include + +#include +#ifdef HAVE_LIBART +#include +#endif + +#include +#include + +#include +#include +#include +#include + +extern bool argb_visual_available; + +KdmPixmap::KdmPixmap( KdmItem *parent, const TQDomNode &node, const char *name ) + : KdmItem( parent, node, name ) +{ + itemType = "pixmap"; + + // Set default values for pixmap (note: strings are already Null) + pixmap.normal.tint.setRgb( 0x800000 ); + pixmap.normal.alpha = 0.0; + pixmap.active.present = false; + pixmap.prelight.present = false; + bool true_transparency = false; + + // Read PIXMAP ID + // it rarely happens that a pixmap can be a button too! + TQDomNode n = node; + TQDomElement elPix = n.toElement(); + + // Read PIXMAP TAGS + TQDomNodeList childList = node.childNodes(); + for (uint nod = 0; nod < childList.count(); nod++) { + TQDomNode child = childList.item( nod ); + TQDomElement el = child.toElement(); + TQString tagName = el.tagName(); + + if (tagName == "normal") { + pixmap.normal.fullpath = fullPath( el.attribute( "file", "" ) ); + parseColor( el.attribute( "tint", "#ffffff" ), pixmap.normal.tint ); + pixmap.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat(); + + if (el.attribute( "file", "" ) == "@@@TDMBACKGROUND@@@") { + if ((_compositor.isEmpty()) || (!argb_visual_available)) { + // Software blend only (no compositing support) + // Use the preset TDM background... + KStandardDirs *m_pDirs = KGlobal::dirs(); + KSimpleConfig *config = new KSimpleConfig( TQFile::decodeName( _backgroundCfg ) ); + config->setGroup("Desktop0"); + pixmap.normal.fullpath = m_pDirs->findResource("wallpaper", config->readPathEntry("Wallpaper")); + // TODO: Detect when there is no wallpaper and use the background settings instead + delete config; + } + else { + true_transparency = true; + pixmap.normal.alpha = 0.0; + } + } + + } else if (tagName == "active") { + pixmap.active.present = true; + pixmap.active.fullpath = fullPath( el.attribute( "file", "" ) ); + parseColor( el.attribute( "tint", "#ffffff" ), pixmap.active.tint ); + pixmap.active.alpha = el.attribute( "alpha", "1.0" ).toFloat(); + } else if (tagName == "prelight") { + pixmap.prelight.present = true; + pixmap.prelight.fullpath = fullPath(el.attribute( "file", "" ) ); + parseColor( el.attribute( "tint", "#ffffff" ), pixmap.prelight.tint ); + pixmap.prelight.alpha = el.attribute( "alpha", "1.0" ).toFloat(); + } + } + + // look if we have to have the aspect ratio ready + if (((pos.wType == DTnone && pos.hType != DTnone) || + (pos.wType != DTnone && pos.hType == DTnone) || + (pos.wType == DTnone && pos.hType == DTnone)) && + !pixmap.normal.fullpath.endsWith( ".svg" )) + loadPixmap( &pixmap.normal ); +} + +TQSize +KdmPixmap::sizeHint() +{ + // choose the correct pixmap class + PixmapStruct::PixmapClass * pClass = &pixmap.normal; + if (state == Sactive && pixmap.active.present) + pClass = &pixmap.active; + if (state == Sprelight && pixmap.prelight.present) + pClass = &pixmap.prelight; + // use the pixmap size as the size hint + if (!pClass->pixmap.isNull()) + return pClass->pixmap.size(); + return KdmItem::sizeHint(); +} + +void +KdmPixmap::setGeometry( const TQRect &newGeometry, bool force ) +{ + KdmItem::setGeometry( newGeometry, force ); + pixmap.active.readyPixmap.resize( 0, 0 ); + pixmap.prelight.readyPixmap.resize( 0, 0 ); + pixmap.normal.readyPixmap.resize( 0, 0 ); +} + + +TQString +KdmPixmap::fullPath( const TQString &fileName) +{ + if (fileName.isEmpty()) + return TQString::null; + + TQString fullName = fileName; + if (fullName.at( 0 ) != '/') + fullName = baseDir() + "/" + fileName; + return fullName; +} + +void +KdmPixmap::renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area ) +{ +#ifdef HAVE_LIBART + // Special stuff for SVG icons + KSVGIconEngine *svgEngine = new KSVGIconEngine(); + + if (svgEngine->load( area.width(), area.height(), pClass->fullpath )) { + TQImage *t = svgEngine->image(); + pClass->pixmap = *t; + pClass->readyPixmap.resize( 0, 0 ); + delete t; + } else { + kdWarning() << "failed to load " << pClass->fullpath << endl; + pClass->fullpath = TQString::null; + } + + delete svgEngine; +#else + Q_UNUSED(pClass); + Q_UNUSED(area); +#endif +} + +void +KdmPixmap::loadPixmap( PixmapStruct::PixmapClass *pClass ) +{ + TQString fullpath = pClass->fullpath; + + kdDebug() << timestamp() << " load " << fullpath << endl; + int index = fullpath.findRev('.'); + TQString ext = fullpath.right(fullpath.length() - index); + fullpath = fullpath.left(index); + kdDebug() << timestamp() << " ext " << ext << " " << fullpath << endl; + TQString testpath = TQString("-%1x%2").arg(area.width()).arg(area.height()) + ext; + kdDebug() << timestamp() << " testing for " << fullpath + testpath << endl; + if (KStandardDirs::exists(fullpath + testpath)) + pClass->pixmap.load(fullpath + testpath); + else + pClass->pixmap.load( fullpath + ext ); + kdDebug() << timestamp() << " done\n"; +} + +void +KdmPixmap::drawContents( TQPainter *p, const TQRect &r ) +{ + // choose the correct pixmap class + PixmapStruct::PixmapClass *pClass = &pixmap.normal; + if (state == Sactive && pixmap.active.present) + pClass = &pixmap.active; + if (state == Sprelight && pixmap.prelight.present) + pClass = &pixmap.prelight; + + kdDebug() << "draw " << id << " " << pClass->pixmap.isNull() << endl; + + if (pClass->pixmap.isNull()) { + if (pClass->fullpath.isEmpty()) // if neither is set, we're empty + return; + + if (!pClass->fullpath.endsWith( ".svg" ) ) { + loadPixmap(pClass); + } else { + kdDebug() << timestamp() << " renderSVG\n"; + renderSvg( pClass, area ); + kdDebug() << timestamp() << " done\n"; + } + } + + int px = area.left() + r.left(); + int py = area.top() + r.top(); + int sx = r.x(); + int sy = r.y(); + int sw = r.width(); + int sh = r.height(); + if (px < 0) { + px *= -1; + sx += px; + px = 0; + } + if (py < 0) { + py *= -1; + sy += py; + py = 0; + } + + + if (pClass->readyPixmap.isNull()) { + + bool haveTint = pClass->tint.rgb() != 0xFFFFFF; + bool haveAlpha = pClass->alpha < 1.0; + + TQImage scaledImage; + + // use the loaded pixmap or a scaled version if needed + + kdDebug() << timestamp() << " prepare readyPixmap " << pClass->fullpath << " " << area.size() << " " << pClass->pixmap.size() << endl; + if (area.size() != pClass->pixmap.size()) { + if (pClass->fullpath.endsWith( ".svg" )) { + kdDebug() << timestamp() << " renderSVG\n"; + renderSvg( pClass, area ); + scaledImage = pClass->pixmap.convertToImage(); + } else { + kdDebug() << timestamp() << " convertFromImage smoothscale\n"; + if (pClass->pixmap.isNull()) { + scaledImage = TQImage(); + } + else { + TQImage tempImage = pClass->pixmap.convertToImage(); + kdDebug() << timestamp() << " convertToImage done\n"; + scaledImage = tempImage.smoothScale( area.width(), area.height() ); + } + kdDebug() << timestamp() << " done\n"; + } + } else { + if (haveTint || haveAlpha) + { + scaledImage = pClass->pixmap.convertToImage(); + // enforce rgba values for the latter + if (!scaledImage.isNull()) scaledImage = scaledImage.convertDepth( 32 ); + } + else + pClass->readyPixmap = pClass->pixmap; + } + + if (haveTint || haveAlpha) { + // blend image(pix) with the given tint + + if (!scaledImage.isNull()) scaledImage = scaledImage.convertDepth( 32 ); + int w = scaledImage.width(); + int h = scaledImage.height(); + float tint_red = float( pClass->tint.red() ) / 255; + float tint_green = float( pClass->tint.green() ) / 255; + float tint_blue = float( pClass->tint.blue() ) / 255; + float tint_alpha = pClass->alpha; + + for (int y = 0; y < h; ++y) { + QRgb *ls = (QRgb *)scaledImage.scanLine( y ); + for (int x = 0; x < w; ++x) { + QRgb l = ls[x]; + int r = int( tqRed( l ) * tint_red ); + int g = int( tqGreen( l ) * tint_green ); + int b = int( tqBlue( l ) * tint_blue ); + int a = int( tqAlpha( l ) * tint_alpha ); + ls[x] = tqRgba( r, g, b, a ); + } + } + } + if ((_compositor.isEmpty()) || (!argb_visual_available)) { + // Software blend only (no compositing support) + } + else { + // We have a compositor! + // Apply the alpha in the same manner as above, exept we are now + // using the hardware blending engine for all painting + scaledImage = pClass->readyPixmap; + if (!scaledImage.isNull()) scaledImage = scaledImage.convertDepth( 32 ); + int w = scaledImage.width(); + int h = scaledImage.height(); + + for (int y = 0; y < h; ++y) { + QRgb *ls = (QRgb *)scaledImage.scanLine( y ); + for (int x = 0; x < w; ++x) { + QRgb l = ls[x]; + float alpha_adjust = (tqAlpha( l )/256.0); + int r = int( tqRed( l ) * alpha_adjust ); + int g = int( tqGreen( l ) * alpha_adjust ); + int b = int( tqBlue( l ) * alpha_adjust ); + int a = int( tqAlpha( l ) * 1 ); + ls[x] = tqRgba( r, g, b, a ); + } + } + } + + if (!scaledImage.isNull()) { + kdDebug() << timestamp() << " convertFromImage " << id << " " << area << endl; + pClass->readyPixmap.convertFromImage( scaledImage ); + } + } + kdDebug() << timestamp() << " Pixmap::drawContents " << pClass->readyPixmap.size() << " " << px << " " << py << " " << sx << " " << sy << " " << sw << " " << sh << endl; + p->drawPixmap( px, py, pClass->readyPixmap, sx, sy, sw, sh ); +} + +void +KdmPixmap::statusChanged() +{ + KdmItem::statusChanged(); + if (!pixmap.active.present && !pixmap.prelight.present) + return; + if ((state == Sprelight && !pixmap.prelight.present) || + (state == Sactive && !pixmap.active.present)) + return; + needUpdate(); +} + +#include "tdmpixmap.moc" diff --git a/tdm/kfrontend/themer/tdmpixmap.h b/tdm/kfrontend/themer/tdmpixmap.h new file mode 100644 index 000000000..faa71a034 --- /dev/null +++ b/tdm/kfrontend/themer/tdmpixmap.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2003 by Unai Garro + * Copyright (C) 2004 by Enrico Ros + * Copyright (C) 2004 by Stephan Kulow + * Copyright (C) 2004 by Oswald Buddenhagen + * + * 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. + */ + +#ifndef TDMPIXMAP_H +#define TDMPIXMAP_H + +#include "tdmitem.h" + +//#include +#include + +#include +#include + +/* + * KdmPixmap. A pixmap element + */ + +class KdmPixmap : public KdmItem { + Q_OBJECT + +public: + KdmPixmap( KdmItem *parent, const TQDomNode &node, const char *name = 0 ); + +protected: + // reimplemented; returns the size of loaded pixmap + virtual TQSize sizeHint(); + + // draw the pixmap + virtual void drawContents( TQPainter *p, const TQRect &r ); + + // handle switching between normal / active / prelight configurations + virtual void statusChanged(); + + virtual void setGeometry( const TQRect &newGeometry, bool force ); + + struct PixmapStruct { + struct PixmapClass { + TQString fullpath; + TQPixmap pixmap; + TQPixmap readyPixmap; + TQColor tint; + float alpha; //TODO added: not in greeter.dtd + bool present; + } normal, active, prelight; + } pixmap; + +private: + // Method to load the pixmap path given by the theme + TQString fullPath( const TQString &fileName ); + void renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area ); + void loadPixmap( PixmapStruct::PixmapClass *pClass ); +}; + +#endif diff --git a/tdm/kfrontend/themer/tdmrect.cpp b/tdm/kfrontend/themer/tdmrect.cpp new file mode 100644 index 000000000..9056a513c --- /dev/null +++ b/tdm/kfrontend/themer/tdmrect.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2003 by Unai Garro + * Copyright (C) 2004 by Enrico Ros + * Copyright (C) 2004 by Stephan Kulow + * Copyright (C) 2004 by Oswald Buddenhagen + * + * 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 "tdmrect.h" +#include "tdmthemer.h" +#include "tdmconfig.h" + +#include +#include + +#include +#include +#include +#include + +extern bool argb_visual_available; + +KdmRect::KdmRect( KdmItem *parent, const TQDomNode &node, const char *name ) + : KdmItem( parent, node, name ) +{ + init( node, name ); +} + +KdmRect::KdmRect( TQWidget *parent, const TQDomNode &node, const char *name ) + : KdmItem( parent, node, name ) +{ + init( node, name ); +} + +void +KdmRect::init( const TQDomNode &node, const char * ) +{ + itemType = "rect"; + + // Set default values for rect (note: strings are already Null) + rect.normal.alpha = 1; + rect.active.present = false; + rect.prelight.present = false; + rect.hasBorder = false; + + // A rect can have no properties (defaults to parent ones) + if (node.isNull()) + return; + + // Read RECT ID + TQDomNode n = node; + TQDomElement elRect = n.toElement(); + + // Read RECT TAGS + TQDomNodeList childList = node.childNodes(); + for (uint nod = 0; nod < childList.count(); nod++) { + TQDomNode child = childList.item( nod ); + TQDomElement el = child.toElement(); + TQString tagName = el.tagName(); + + if (tagName == "normal") { + parseColor( el.attribute( "color", TQString::null ), rect.normal.color ); + rect.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat(); + parseFont( el.attribute( "font", "Sans 14" ), rect.normal.font ); + } else if (tagName == "active") { + rect.active.present = true; + parseColor( el.attribute( "color", TQString::null ), rect.active.color ); + rect.active.alpha = el.attribute( "alpha", "1.0" ).toFloat(); + parseFont( el.attribute( "font", "Sans 14" ), rect.active.font ); + } else if (tagName == "prelight") { + rect.prelight.present = true; + parseColor( el.attribute( "color", TQString::null ), rect.prelight.color ); + rect.prelight.alpha = el.attribute( "alpha", "1.0" ).toFloat(); + parseFont( el.attribute( "font", "Sans 14" ), rect.prelight.font ); + } else if (tagName == "border") + rect.hasBorder = true; + } +} + +void +KdmRect::drawContents( TQPainter *p, const TQRect &r ) +{ + // choose the correct rect class + RectStruct::RectClass *rClass = &rect.normal; + if (state == Sactive && rect.active.present) + rClass = &rect.active; + if (state == Sprelight && rect.prelight.present) + rClass = &rect.prelight; + + if (rClass->alpha <= 0 || !rClass->color.isValid()) + return; + + if (rClass->alpha == 1) + p->fillRect( area, TQBrush( rClass->color ) ); + else { +// if ((_compositor.isEmpty()) || (!argb_visual_available)) { + // Software blend only (no compositing support) + TQRect backRect = r; + backRect.moveBy( area.x(), area.y() ); + TQPixmap backPixmap( backRect.size() ); + bitBlt( &backPixmap, TQPoint( 0, 0 ), p->device(), backRect ); + TQImage backImage = backPixmap.convertToImage(); + KImageEffect::blend( rClass->color, backImage, rClass->alpha ); + p->drawImage( backRect.x(), backRect.y(), backImage ); + // area.moveBy(1,1); +// } +// else { +// // We have compositing support! +// } + } +} + +void +KdmRect::statusChanged() +{ + KdmItem::statusChanged(); + if (!rect.active.present && !rect.prelight.present) + return; + if ((state == Sprelight && !rect.prelight.present) || + (state == Sactive && !rect.active.present)) + return; + needUpdate(); +} + +/* +void +KdmRect::setAttribs( TQWidget *widget ) +{ + widget->setFont( rect.normal.font ); +} + +void +KdmRect::recursiveSetAttribs( TQLayoutItem *li ) +{ + TQWidget *w; + TQLayout *l; + + if ((w = li->widget())) + setAttribs( w ); + else if ((l = li->layout())) { + TQLayoutIterator it = l->iterator(); + for (TQLayoutItem *itm = it.current(); itm; itm = ++it) + recursiveSetAttribs( itm ); + } +} + +void +KdmRect::setLayoutItem( TQLayoutItem *item ) +{ + KdmItem::setLayoutItem( item ); + recursiveSetAttribs( item ); +} +*/ + +void +KdmRect::setWidget( TQWidget *widget ) +{ + if ( rect.normal.color.isValid() && widget ) + { + TQPalette p = widget->palette(); + p.setColor( TQPalette::Normal, TQColorGroup::Text, rect.normal.color ); + widget->setPalette(p); + } + KdmItem::setWidget( widget ); + //setAttribs( widget ); +} + +#include "tdmrect.moc" diff --git a/tdm/kfrontend/themer/tdmrect.h b/tdm/kfrontend/themer/tdmrect.h new file mode 100644 index 000000000..6dfdc126a --- /dev/null +++ b/tdm/kfrontend/themer/tdmrect.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2003 by Unai Garro + * Copyright (C) 2004 by Enrico Ros + * Copyright (C) 2004 by Stephan Kulow + * Copyright (C) 2004 by Oswald Buddenhagen + * + * 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. + */ + +#ifndef TDMRECT_H +#define TDMRECT_H + +#include "tdmitem.h" + +#include +#include + +/* + * KdmRect: A themed rectangular element + */ + +class KdmRect : public KdmItem { + Q_OBJECT + +public: + KdmRect( KdmItem *parent, const TQDomNode &node, const char *name = 0 ); + KdmRect( TQWidget *parent, const TQDomNode &node, const char *name = 0 ); + +protected: + // draw the rect + virtual void drawContents( TQPainter *p, const TQRect &r ); + + // handle switching between normal / active / prelight configurations + virtual void statusChanged(); + + struct RectStruct { + struct RectClass { + float alpha; + TQColor color; + bool present; + TQFont font; + } normal, active, prelight; + bool hasBorder; + } rect; + + virtual void setWidget( TQWidget *widget ); +// virtual void setLayoutItem( TQLayoutItem *item ); + void init( const TQDomNode &node, const char *name ); + +private: + void setAttribs( TQWidget *widget ); + void recursiveSetAttribs( TQLayoutItem *item ); +}; + +#endif diff --git a/tdm/kfrontend/themer/tdmthemer.cpp b/tdm/kfrontend/themer/tdmthemer.cpp new file mode 100644 index 000000000..d2dc77935 --- /dev/null +++ b/tdm/kfrontend/themer/tdmthemer.cpp @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2003 by Unai Garro + * Copyright (C) 2004 by Enrico Ros + * Copyright (C) 2004 by Stephan Kulow + * Copyright (C) 2004 by Oswald Buddenhagen + * + * 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 "tdmthemer.h" +#include "tdmitem.h" +#include "tdmpixmap.h" +#include "tdmrect.h" +#include "tdmlabel.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include // animation timer - TODO +#include +#include +#include +#include +#include +#include + +#include + +extern bool argb_visual_available; + +/* + * KdmThemer. The main theming interface + */ +KdmThemer::KdmThemer( const TQString &_filename, const TQString &mode, TQWidget *parent ) + : TQObject( parent ) + , rootItem( 0 ) + , backBuffer( 0 ) +{ + // Set the mode we're working in + m_currentMode = mode; + + // read the XML file and create DOM tree + TQString filename = _filename; + if (!::access( TQFile::encodeName( filename + "/GdmGreeterTheme.desktop" ), R_OK )) { + KSimpleConfig cfg( filename + "/GdmGreeterTheme.desktop" ); + cfg.setGroup( "GdmGreeterTheme" ); + filename += '/' + cfg.readEntry( "Greeter" ); + } + TQFile opmlFile( filename ); + if (!opmlFile.open( IO_ReadOnly )) { + FDialog::box( widget(), errorbox, i18n( "Cannot open theme file %1" ).arg(filename) ); + return; + } + if (!domTree.setContent( &opmlFile )) { + FDialog::box( widget(), errorbox, i18n( "Cannot parse theme file %1" ).arg(filename) ); + return; + } + // Set the root (screen) item + rootItem = new KdmRect( parent, TQDomNode(), "tdm root" ); + + connect( rootItem, TQT_SIGNAL(needUpdate( int, int, int, int )), + widget(), TQT_SLOT(update( int, int, int, int )) ); + + rootItem->setBaseDir( TQFileInfo( filename ).dirPath( true ) ); + + // generate all the items defined in the theme + generateItems( rootItem ); + + connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SIGNAL(activated( const TQString & )) ); + connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SLOT(slotActivated( const TQString & )) ); + + TQTimer::singleShot(800, this, TQT_SLOT(slotPaintRoot())); + +/* *TODO* + // Animation timer + TQTimer *time = new TQTimer( this ); + time->start( 500 ); + connect( time, TQT_SIGNAL(timeout()), TQT_SLOT(update()) ) +*/ +} + +KdmThemer::~KdmThemer() +{ + delete rootItem; + delete backBuffer; +} + +inline TQWidget * +KdmThemer::widget() +{ + return static_cast(parent()); +} + +KdmItem * +KdmThemer::findNode( const TQString &item ) const +{ + return rootItem->findNode( item ); +} + +void +KdmThemer::updateGeometry( bool force ) +{ + rootItem->setGeometry( TQRect( TQPoint(), widget()->size() ), force ); +} + +// BEGIN other functions + +void +KdmThemer::widgetEvent( TQEvent *e ) +{ + if (!rootItem) + return; + switch (e->type()) { + case TQEvent::MouseMove: + { + TQMouseEvent *me = TQT_TQMOUSEEVENT(e); + rootItem->mouseEvent( me->x(), me->y() ); + } + break; + case TQEvent::MouseButtonPress: + { + TQMouseEvent *me = TQT_TQMOUSEEVENT(e); + rootItem->mouseEvent( me->x(), me->y(), true ); + } + break; + case TQEvent::MouseButtonRelease: + { + TQMouseEvent *me = TQT_TQMOUSEEVENT(e); + rootItem->mouseEvent( me->x(), me->y(), false, true ); + } + break; + case TQEvent::Show: + rootItem->show(); + break; + case TQEvent::Resize: + updateGeometry( false ); + showStructure( rootItem ); + break; + case TQEvent::Paint: + { + TQRect paintRect = TQT_TQPAINTEVENT(e)->rect(); + kdDebug() << timestamp() << " paint on: " << paintRect << endl; + + if ((_compositor.isEmpty()) || (!argb_visual_available)) { + // Software blend only (no compositing support) + if (!backBuffer) + backBuffer = new TQPixmap( widget()->size() ); + if (backBuffer->size() != widget()->size()) + backBuffer->resize( widget()->size() ); + + TQPainter p; + p.begin( backBuffer ); + rootItem->paint( &p, paintRect ); + p.end(); + + bitBlt( widget(), paintRect.topLeft(), backBuffer, paintRect ); + } + else { + // We have compositing support! + TQRgb blend_color = tqRgba(0, 0, 0, 0); // RGBA + float alpha = tqAlpha(blend_color) / 255.; + int pixel = tqAlpha(blend_color) << 24 | + int(tqRed(blend_color) * alpha) << 16 | + int(tqGreen(blend_color) * alpha) << 8 | + int(tqBlue(blend_color) * alpha); + TQPainter p1; + p1.begin( widget() ); + p1.fillRect( paintRect, TQColor(blend_color, pixel) ); + rootItem->paint( &p1, paintRect ); + p1.end(); + } + + } + break; + default: + break; + } +} + +/* +void +KdmThemer::pixmap( const TQRect &r, TQPixmap *px ) +{ + bitBlt( px, TQPoint( 0, 0 ), widget(), r ); +} +*/ + +void +KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node ) +{ + if (!parent) + return; + + TQDomNodeList subnodeList; //List of subnodes of this node + + /* + * Get the child nodes + */ + if (node.isNull()) { // It's the first node, get its child nodes + TQDomElement theme = domTree.documentElement(); + + // Get its tag, and check it's correct ("greeter") + if (theme.tagName() != "greeter") { + kdDebug() << timestamp() << " This does not seem to be a correct theme file." << endl; + return; + } + // Get the list of child nodes + subnodeList = theme.childNodes(); + } else + subnodeList = node.childNodes(); + + /* + * Go through each of the child nodes + */ + for (uint nod = 0; nod < subnodeList.count(); nod++) { + TQDomNode subnode = subnodeList.item( nod ); + TQDomElement el = subnode.toElement(); + TQString tagName = el.tagName(); + + if (tagName == "item") { + if (!willDisplay( subnode )) + continue; + TQString id = el.attribute("id"); + if (id.startsWith("plugin-specific-")) { + id = id.mid(strlen("plugin-specific-")); + if (!_pluginsLogin.contains(id)) + continue; + } + + // It's a new item. Draw it + TQString type = el.attribute( "type" ); + + KdmItem *newItem = 0; + + if (type == "label") + newItem = new KdmLabel( parent, subnode ); + else if (type == "pixmap") + newItem = new KdmPixmap( parent, subnode ); + else if (type == "rect") + newItem = new KdmRect( parent, subnode ); + else if (type == "entry" || type == "list") { + newItem = new KdmRect( parent, subnode ); + newItem->setType( type ); + } + // newItem = new KdmEntry( parent, subnode ); + else if (type == "svg") + newItem = new KdmPixmap( parent, subnode ); + if (newItem) { + generateItems( newItem, subnode ); + if (el.attribute( "button", "false" ) == "true") + newItem->inheritFromButton( newItem ); + } + } else if (tagName == "box") { + if (!willDisplay( subnode )) + continue; + // It's a new box. Draw it + parent->setBoxLayout( subnode ); + generateItems( parent, subnode ); + } else if (tagName == "fixed") { + if (!willDisplay( subnode )) + continue; + // It's a new box. Draw it + parent->setFixedLayout( subnode ); + generateItems( parent, subnode ); + } + } +} + +bool KdmThemer::willDisplay( const TQDomNode &node ) +{ + TQDomNode showNode = node.namedItem( "show" ); + + // No "show" node means this item can be displayed at all times + if (showNode.isNull()) + return true; + + TQDomElement el = showNode.toElement(); + + TQString modes = el.attribute( "modes" ); + if (!modes.isNull()) { + TQStringList modeList = TQStringList::split( ",", modes ); + + // If current mode isn't in this list, do not display item + if (modeList.find( m_currentMode ) == modeList.end()) + return false; + } + + TQString type = el.attribute( "type" ); + if (type == "config" || type == "suspend") + return false; // not implemented (yet) + if (type == "timed") + return _autoLoginDelay != 0; + if (type == "chooser") +#ifdef XDMCP + return _loginMode != LOGIN_LOCAL_ONLY; +#else + return false; +#endif + if (type == "halt" || type == "reboot") + return _allowShutdown != SHUT_NONE; + else if (type == "userlist") + return _userList; + else if ( type == "!userlist" ) + return !_userList; + +// if (type == "system") +// return true; + + // All tests passed, item will be displayed + return true; +} + +void +KdmThemer::showStructure( TQObject *obj ) +{ + + const TQObjectList wlist = obj->childrenListObject(); + static int counter = 0; + if (counter == 0) + kdDebug() << timestamp() << " \n\n<======= Widget tree =================" << endl; + if (!wlist.isEmpty()) { + counter++; + TQObjectListIterator it( wlist ); + TQObject *object; + + while ((object = it.current()) != 0) { + ++it; + TQString node; + for (int i = 1; i < counter; i++) + node += "-"; + + if (object->inherits( "KdmItem" )) { + KdmItem *widget = (KdmItem *)object; + kdDebug() << node << "|" << widget->type() << " me=" << widget->id << " " << widget->area << endl; + } + + showStructure( object ); + } + counter--; + } + if (counter == 0) + kdDebug() << timestamp() << " \n\n<======= Widget tree =================\n\n" << endl; +} + +void +KdmThemer::slotActivated( const TQString &id ) +{ + TQString toactivate; + if (id == "username-label") + toactivate = "user-entry"; + else if (id == "password-label") + toactivate = "pw-entry"; + else + return; + + KdmItem *item = findNode(toactivate); + if (!item || !item->widget()) + return; + + item->widget()->setFocus(); + TQLineEdit *le = (TQLineEdit*)item->widget()->qt_cast(TQLINEEDIT_OBJECT_NAME_STRING); + if (le) + le->selectAll(); +} + +void +KdmThemer::slotPaintRoot() +{ + KdmItem *back_item = findNode("background"); + if (!back_item) + return; + + TQRect screen = TQApplication::desktop()->screenGeometry(0); + TQPixmap pm(screen.size()); + + TQPainter painter( &pm, true ); + back_item->paint( &painter, back_item->rect()); + painter.end(); + + TQT_TQWIDGET(TQApplication::desktop()->screen())->setErasePixmap(pm); + TQT_TQWIDGET(TQApplication::desktop()->screen())->erase(); +} + +#include "tdmthemer.moc" diff --git a/tdm/kfrontend/themer/tdmthemer.h b/tdm/kfrontend/themer/tdmthemer.h new file mode 100644 index 000000000..2b8865b4d --- /dev/null +++ b/tdm/kfrontend/themer/tdmthemer.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2003 by Unai Garro + * Copyright (C) 2004 by Enrico Ros + * Copyright (C) 2004 by Stephan Kulow + * Copyright (C) 2004 by Oswald Buddenhagen + * + * 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. + */ + +#ifndef TDMTHEMER_H +#define TDMTHEMER_H + +#include +#include +#include + +class KdmThemer; +class KdmItem; +class KdmPixmap; +class KdmRect; +class KdmBox; + +class TQRect; +class TQWidget; +class TQEvent; + +/** +* @author Unai Garro +*/ + + + +/* +* The themer widget. Whatever drawn here is just themed +* according to a XML file set by the user. +*/ + + +class KdmThemer : public TQObject { + Q_OBJECT + +public: + /* + * Construct and destruct the interface + */ + + KdmThemer( const TQString &path, const TQString &mode, TQWidget *parent ); + ~KdmThemer(); + + bool isOK() { return rootItem != 0; } + /* + * Gives a sizeHint to the widget (parent size) + */ + //TQSize sizeHint() const{ return parentWidget()->size(); } + + /* + * Takes a shot of the current widget + */ +// void pixmap( const TQRect &r, TQPixmap *px ); + + virtual // just to put the reference in the vmt + KdmItem *findNode( const TQString & ) const; + + void updateGeometry( bool force ); // force = true for external calls + + // must be called by parent widget + void widgetEvent( TQEvent *e ); + +signals: + void activated( const TQString &id ); + +protected slots: + void slotActivated( const TQString &id ); + void slotPaintRoot(); + +private: + /* + * Our display mode (e.g. console, remote, ...) + */ + TQString m_currentMode; + + /* + * The config file being used + */ + TQDomDocument domTree; + + /* + * Stores the root of the theme + */ + KdmItem *rootItem; + + /* + * The backbuffer + */ + TQPixmap *backBuffer; + + // methods + + /* + * Test whether item needs to be displayed + */ + bool willDisplay( const TQDomNode &node ); + + /* + * Parses the XML file looking for the + * item list and adds those to the themer + */ + void generateItems( KdmItem *parent = 0, const TQDomNode &node = TQDomNode() ); + + void showStructure( TQObject *obj ); + + TQWidget *widget(); +}; + + +#endif diff --git a/tdm/kfrontend/themes/CMakeLists.txt b/tdm/kfrontend/themes/CMakeLists.txt new file mode 100644 index 000000000..f1dd26e15 --- /dev/null +++ b/tdm/kfrontend/themes/CMakeLists.txt @@ -0,0 +1,13 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +add_subdirectory( circles ) +add_subdirectory( o2_enterprise ) diff --git a/tdm/kfrontend/themes/Makefile.am b/tdm/kfrontend/themes/Makefile.am new file mode 100644 index 000000000..7d13b5174 --- /dev/null +++ b/tdm/kfrontend/themes/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = circles o2_enterprise diff --git a/tdm/kfrontend/themes/circles/CMakeLists.txt b/tdm/kfrontend/themes/circles/CMakeLists.txt new file mode 100644 index 000000000..9122c13ea --- /dev/null +++ b/tdm/kfrontend/themes/circles/CMakeLists.txt @@ -0,0 +1,15 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +install( FILES + GdmGreeterTheme.desktop circles.xml background.svg + flower.png help.png options.png screenshot.png + DESTINATION ${DATA_INSTALL_DIR}/tdm/themes/circles ) diff --git a/tdm/kfrontend/themes/circles/GdmGreeterTheme.desktop b/tdm/kfrontend/themes/circles/GdmGreeterTheme.desktop new file mode 100644 index 000000000..72be02f41 --- /dev/null +++ b/tdm/kfrontend/themes/circles/GdmGreeterTheme.desktop @@ -0,0 +1,135 @@ +# This is not really a .desktop file like the rest, but it's useful to treat +# it as such + +[GdmGreeterTheme] +Greeter=circles.xml +Name=Circles +Name[ar]=الدوائر +Name[bn]=সার্কল্‌স +Name[br]=Kelc'hioù +Name[bs]=Krugovi +Name[ca]=Cercles +Name[cs]=Kruhy +Name[csb]=Kółka +Name[cy]=Cylchoedd +Name[da]=Cirkler +Name[de]=Kreise +Name[el]=Κύκλοι +Name[eo]=cirkloj +Name[es]=Círculos +Name[et]=Ringid +Name[fa]=دایره‌ها +Name[fi]=Ympyrät +Name[fy]=Cirkels +Name[ga]=Ciorcail +Name[he]=מעגלים +Name[hi]=वृत्त +Name[hr]=Krugovi +Name[hu]=Körök +Name[is]=Hringir +Name[it]=Cerchi +Name[ja]=サークル +Name[ka]=წრეები +Name[kk]=Дөңгелектер +Name[km]=រង្វង់ +Name[ko]=원 +Name[lt]=Skrituliai +Name[mk]=Кругови +Name[ms]=Bulatan +Name[nb]=Sirkler +Name[nds]=Krinken +Name[ne]=वृत्त +Name[nl]=Cirkels +Name[nn]=Sirklar +Name[pa]=ਚੱਕਰ +Name[pl]=Kółka +Name[pt]=Círculos +Name[pt_BR]=Círculos +Name[ro]=Cercuri +Name[ru]=Круги +Name[rw]=Inziga +Name[se]=Gearddut +Name[sk]=Kruhy +Name[sl]=Krogi +Name[sr]=Кругови +Name[sr@Latn]=Krugovi +Name[sv]=Cirklar +Name[ta]=வட்டங்கள் +Name[te]=వృత్తాలు +Name[tg]=Доираҳо +Name[tr]=Çemberler +Name[uk]=Кола +Name[uz]=Aylanalar +Name[uz@cyrillic]=Айланалар +Name[vi]=Vòng tròn +Name[wa]=Cekes +Name[zh_CN]=圆环 +Description=Theme with blue circles +Description[af]=Tema met blou sirkels +Description[ar]=سمة بلدوائر الزرقاء +Description[be]=Тэма з блакітнымі коламі +Description[bn]=নীল বৃত্ত সম্বলিত থীম +Description[bs]=Tema sa plavim krugovima +Description[ca]=Tema amb cercles blaus +Description[cs]=Motiv s modrými kruhy +Description[csb]=Téma z mòdrima kółkama +Description[da]=Tema med blå cirkler +Description[de]=Thema mit blauen Kreisen +Description[el]=Θέμα με μπλε κύκλους +Description[eo]=Etoso kun bluaj cirkloj +Description[es]=Tema con círculos azules +Description[et]=Siniste ringidega teema +Description[eu]=Biribil urdindun gaia +Description[fa]=چهره با دایره‌های آبی +Description[fi]=Teema sinisillä ympyröillä +Description[fr]=Thème avec des cercles bleus +Description[fy]=Tema mei blauwe sirkels +Description[gl]=Tema con círculos azuis +Description[he]=ערכת נושא עם מעגלים כחולים +Description[hi]=नीले वृत्तों के साथ प्रसंग +Description[hr]=Tema s plavim krugovima +Description[hu]=Téma kék körökkel +Description[is]=Þema með bláum hringjum +Description[it]=Tema con cerchi blu +Description[ja]=青い丸のテーマ +Description[ka]=ლურჯ წრეებიანი თემა +Description[kk]=Көк дөңгелекті нақыш +Description[km]=ស្បែក​មាន​រង្វង់​ពណ៌​ខៀវ +Description[ko]=파란 원이 있는 테마 +Description[lt]=Tema su melsvais skrituliais +Description[lv]=Tēma ar ziliem riņķiem +Description[mk]=Тема со сини кругови +Description[ms]=Tema dengan bulatan biru +Description[nb]=Tema med blå sirkler +Description[nds]=Muster mit blage Krinken +Description[ne]=निलो वृत्तसँग विषयवस्तु +Description[nl]=Thema met blauwe cirkels +Description[nn]=Tema med blåe sirklar +Description[pa]=ਨੀਲੇ ਚੱਕਰਾਂ ਵਾਲਾ ਸਰੂਪ +Description[pl]=Motyw z niebieskimi kółkami +Description[pt]=Tema com círculos azuis +Description[pt_BR]=Tema com círculos azuis +Description[ro]=Temă cu cercuri albastre +Description[ru]=Тема с синими кругами +Description[rw]=Insanganyamatsiko ifite inziga z'ubururu +Description[se]=Fáddá mas lea alit gearddut +Description[sk]=Téma s modrými kruhmi +Description[sl]=Tema z modrimi krogi +Description[sr]=Тема са плавим круговима +Description[sr@Latn]=Tema sa plavim krugovima +Description[sv]=Tema med blåa cirklar +Description[ta]=நீல வட்டங்களுடன் தலைப்பு +Description[tg]=Мавзӯъ бо доираҳои кабуд +Description[th]=ชุดตกแต่งมาพร้อมวงกลมสีน้ำเงิน +Description[tr]=Mavi çemberli tema +Description[tt]=Zäñgär tügäräklär belän tışlaw +Description[uk]=Тема з синіми колами +Description[uz]=Koʻk aylanalarli mavzu +Description[uz@cyrillic]=Кўк айланаларли мавзу +Description[vi]=Sắc thái với các vòng tròn xanh lam +Description[wa]=Tinme avou des bleus cekes +Description[zh_CN]=带蓝环的主题 +Description[zh_TW]=有藍色圓圈的佈景主題 +Author=Bond, James Bond +Copyright=(c) 2002 Bond, James Bond +Screenshot=screenshot.png diff --git a/tdm/kfrontend/themes/circles/Makefile.am b/tdm/kfrontend/themes/circles/Makefile.am new file mode 100644 index 000000000..d88c407c2 --- /dev/null +++ b/tdm/kfrontend/themes/circles/Makefile.am @@ -0,0 +1,11 @@ +circlesdir = $(kde_datadir)/tdm/themes/circles +circles_DATA = \ + GdmGreeterTheme.desktop \ + circles.xml \ + background.svg \ + flower.png \ + help.png \ + options.png \ + screenshot.png + +EXTRA_DIST = $(circles_DATA) diff --git a/tdm/kfrontend/themes/circles/background.svg b/tdm/kfrontend/themes/circles/background.svg new file mode 100644 index 000000000..11abc4f43 --- /dev/null +++ b/tdm/kfrontend/themes/circles/background.svg @@ -0,0 +1,39 @@ + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tdm/kfrontend/themes/circles/circles.xml b/tdm/kfrontend/themes/circles/circles.xml new file mode 100644 index 000000000..0596e0ee7 --- /dev/null +++ b/tdm/kfrontend/themes/circles/circles.xml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %c + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tdm/kfrontend/themes/circles/flower.png b/tdm/kfrontend/themes/circles/flower.png new file mode 100644 index 000000000..92d25f32d Binary files /dev/null and b/tdm/kfrontend/themes/circles/flower.png differ diff --git a/tdm/kfrontend/themes/circles/help.png b/tdm/kfrontend/themes/circles/help.png new file mode 100644 index 000000000..b38b48a6d Binary files /dev/null and b/tdm/kfrontend/themes/circles/help.png differ diff --git a/tdm/kfrontend/themes/circles/options.png b/tdm/kfrontend/themes/circles/options.png new file mode 100644 index 000000000..3c08e02d4 Binary files /dev/null and b/tdm/kfrontend/themes/circles/options.png differ diff --git a/tdm/kfrontend/themes/circles/screenshot.png b/tdm/kfrontend/themes/circles/screenshot.png new file mode 100644 index 000000000..7120b03d5 Binary files /dev/null and b/tdm/kfrontend/themes/circles/screenshot.png differ diff --git a/tdm/kfrontend/themes/o2_enterprise/CMakeLists.txt b/tdm/kfrontend/themes/o2_enterprise/CMakeLists.txt new file mode 100644 index 000000000..bf9f738a0 --- /dev/null +++ b/tdm/kfrontend/themes/o2_enterprise/CMakeLists.txt @@ -0,0 +1,16 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +install( FILES + Dialog.png enter_normal.png enter_over.png enter_pressed.png + enterprise.xml GdmGreeterTheme.desktop preview.png + system_normal.png system_over.png system_pressed.png + DESTINATION ${DATA_INSTALL_DIR}/tdm/themes/o2_enterprise ) diff --git a/tdm/kfrontend/themes/o2_enterprise/Dialog.png b/tdm/kfrontend/themes/o2_enterprise/Dialog.png new file mode 100644 index 000000000..d38a35983 Binary files /dev/null and b/tdm/kfrontend/themes/o2_enterprise/Dialog.png differ diff --git a/tdm/kfrontend/themes/o2_enterprise/GdmGreeterTheme.desktop b/tdm/kfrontend/themes/o2_enterprise/GdmGreeterTheme.desktop new file mode 100644 index 000000000..10ce5cc52 --- /dev/null +++ b/tdm/kfrontend/themes/o2_enterprise/GdmGreeterTheme.desktop @@ -0,0 +1,10 @@ +# This is not really a .desktop file like the rest, but it's useful to treat +# it as such + +[GdmGreeterTheme] +Encoding=UTF-8 +Greeter=enterprise.xml +Name=O2 Enterprise +Description=A sleek and professional looking TDM theme for Trinity +Author=Ken Wimer (wimer@kde.org) and Timothy Pearson (kb9vqf@pearsoncomputing.net) +Screenshot=preview.png diff --git a/tdm/kfrontend/themes/o2_enterprise/Makefile.am b/tdm/kfrontend/themes/o2_enterprise/Makefile.am new file mode 100644 index 000000000..078e370a5 --- /dev/null +++ b/tdm/kfrontend/themes/o2_enterprise/Makefile.am @@ -0,0 +1,14 @@ +o2_enterprisedir = $(kde_datadir)/tdm/themes/o2_enterprise +o2_enterprise_DATA = \ + Dialog.png \ + enter_normal.png \ + enter_over.png \ + enter_pressed.png \ + enterprise.xml \ + GdmGreeterTheme.desktop \ + preview.png \ + system_normal.png \ + system_over.png \ + system_pressed.png + +EXTRA_DIST = $(o2_enterprise_DATA) diff --git a/tdm/kfrontend/themes/o2_enterprise/enter_normal.png b/tdm/kfrontend/themes/o2_enterprise/enter_normal.png new file mode 100644 index 000000000..c859ce5df Binary files /dev/null and b/tdm/kfrontend/themes/o2_enterprise/enter_normal.png differ diff --git a/tdm/kfrontend/themes/o2_enterprise/enter_over.png b/tdm/kfrontend/themes/o2_enterprise/enter_over.png new file mode 100644 index 000000000..f1252a55a Binary files /dev/null and b/tdm/kfrontend/themes/o2_enterprise/enter_over.png differ diff --git a/tdm/kfrontend/themes/o2_enterprise/enter_pressed.png b/tdm/kfrontend/themes/o2_enterprise/enter_pressed.png new file mode 100644 index 000000000..c859ce5df Binary files /dev/null and b/tdm/kfrontend/themes/o2_enterprise/enter_pressed.png differ diff --git a/tdm/kfrontend/themes/o2_enterprise/enterprise.xml b/tdm/kfrontend/themes/o2_enterprise/enterprise.xml new file mode 100644 index 000000000..cf8aecd32 --- /dev/null +++ b/tdm/kfrontend/themes/o2_enterprise/enterprise.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + %c + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tdm/kfrontend/themes/o2_enterprise/gpl.txt b/tdm/kfrontend/themes/o2_enterprise/gpl.txt new file mode 100644 index 000000000..b6f92f3db --- /dev/null +++ b/tdm/kfrontend/themes/o2_enterprise/gpl.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/tdm/kfrontend/themes/o2_enterprise/preview.png b/tdm/kfrontend/themes/o2_enterprise/preview.png new file mode 100644 index 000000000..f7712d7d2 Binary files /dev/null and b/tdm/kfrontend/themes/o2_enterprise/preview.png differ diff --git a/tdm/kfrontend/themes/o2_enterprise/system_normal.png b/tdm/kfrontend/themes/o2_enterprise/system_normal.png new file mode 100644 index 000000000..ea9b1bdfa Binary files /dev/null and b/tdm/kfrontend/themes/o2_enterprise/system_normal.png differ diff --git a/tdm/kfrontend/themes/o2_enterprise/system_over.png b/tdm/kfrontend/themes/o2_enterprise/system_over.png new file mode 100644 index 000000000..7d535efc8 Binary files /dev/null and b/tdm/kfrontend/themes/o2_enterprise/system_over.png differ diff --git a/tdm/kfrontend/themes/o2_enterprise/system_pressed.png b/tdm/kfrontend/themes/o2_enterprise/system_pressed.png new file mode 100644 index 000000000..ea9b1bdfa Binary files /dev/null and b/tdm/kfrontend/themes/o2_enterprise/system_pressed.png differ diff --git a/tdmlib/CMakeLists.txt b/tdmlib/CMakeLists.txt new file mode 100644 index 000000000..a2565fe1d --- /dev/null +++ b/tdmlib/CMakeLists.txt @@ -0,0 +1,85 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/tdm/kfrontend + ${CMAKE_BINARY_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + +if( BUILD_TDM ) + + +##### headers ################################### + +install( FILES kgreeterplugin.h DESTINATION ${INCLUDE_INSTALL_DIR} ) + + +##### kgreet_classic (module) ################### + +tde_add_kpart( kgreet_classic AUTOMOC + SOURCES kgreet_classic.cpp + LINK tdeui-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) + + +##### kgreet_pam (module) ####################### + +tde_add_kpart( kgreet_pam AUTOMOC + SOURCES kgreet_pam.cpp + LINK tdeui-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) + + +##### kgreet_winbind (module) ################### + +tde_add_kpart( kgreet_winbind AUTOMOC + SOURCES kgreet_winbind.cpp + LINK tdeui-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) + + + +endif( BUILD_TDM ) + + +##### dmctl (static) ############################ + +if( BUILD_KICKER OR BUILD_KDESKTOP OR BUILD_TDM OR BUILD_KSMSERVER ) + + tde_add_library( dmctl STATIC_PIC + SOURCES dmctl.cpp + LINK Xau + ) + +endif( ) + +##### tdmtsak (executable) ####################### + +if( BUILD_TSAK ) + tde_add_executable( tdmtsak + SOURCES tdmtsak.cpp + LINK ${TQT_LIBRARIES} + DESTINATION ${BIN_INSTALL_DIR} + SETUID + DESCRIPTION "Secure Attention Key interface for TDM" + AUTHORS "Timothy Pearson" + ) +endif( BUILD_TSAK ) diff --git a/tdmlib/Makefile.am b/tdmlib/Makefile.am new file mode 100644 index 000000000..f21f59bd5 --- /dev/null +++ b/tdmlib/Makefile.am @@ -0,0 +1,30 @@ +AM_CPPFLAGS = -I$(top_srcdir)/tdm/kfrontend $(all_includes) + +kde_module_LTLIBRARIES = kgreet_classic.la kgreet_pam.la kgreet_winbind.la + +kgreet_classic_la_SOURCES = kgreet_classic.cpp +kgreet_classic_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries) +kgreet_classic_la_LIBADD = $(LIB_TDEUI) + +kgreet_pam_la_SOURCES = kgreet_pam.cpp +kgreet_pam_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries) +kgreet_pam_la_LIBADD = $(LIB_TDEUI) + +kgreet_winbind_la_SOURCES = kgreet_winbind.cpp +kgreet_winbind_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries) +kgreet_winbind_la_LIBADD = $(LIB_TDEUI) + +noinst_LTLIBRARIES = libdmctl.la +libdmctl_la_SOURCES = dmctl.cpp +libdmctl_la_LDFLAGS = $(all_libraries) -no-undefined +libdmctl_la_LIBADD = $(LIB_TDECORE) -lXau + +METASOURCES = AUTO + +noinst_HEADERS = dmctl.h kgreet_classic.h kgreet_winbind.h +include_HEADERS = kgreeterplugin.h + +messages: + $(XGETTEXT) $(kgreet_classic_la_SOURCES) -o $(podir)/kgreet_classic.pot + $(XGETTEXT) $(kgreet_winbind_la_SOURCES) -o $(podir)/kgreet_winbind.pot + $(XGETTEXT) $(libdmctl_la_SOURCES) -o $(podir)/libdmctl.pot diff --git a/tdmlib/dmctl.cpp b/tdmlib/dmctl.cpp new file mode 100644 index 000000000..41a5cb206 --- /dev/null +++ b/tdmlib/dmctl.cpp @@ -0,0 +1,442 @@ +/* + Copyright (C) 2004 Oswald Buddenhagen + + This program is free software; you can redistribute it and/or + modify it under the terms of the Lesser 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 Lesser GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "dmctl.h" + +#ifdef Q_WS_X11 + +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static enum { Dunno, NoDM, NewTDM, OldTDM, GDM } DMType = Dunno; +static const char *ctl, *dpy; + +DM::DM() : fd( -1 ) +{ + char *ptr; + struct sockaddr_un sa; + + if (DMType == Dunno) { + if (!(dpy = ::getenv( "DISPLAY" ))) + DMType = NoDM; + else if ((ctl = ::getenv( "DM_CONTROL" ))) + DMType = NewTDM; + else if ((ctl = ::getenv( "XDM_MANAGED" )) && ctl[0] == '/') + DMType = OldTDM; + else if (::getenv( "GDMSESSION" )) + DMType = GDM; + else + DMType = NoDM; + } + switch (DMType) { + default: + return; + case NewTDM: + case GDM: + if ((fd = ::socket( PF_UNIX, SOCK_STREAM, 0 )) < 0) + return; + sa.sun_family = AF_UNIX; + if (DMType == GDM) { + strcpy( sa.sun_path, "/var/run/gdm_socket" ); + if (::connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) { + strcpy( sa.sun_path, "/tmp/.gdm_socket" ); + if (::connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) { + ::close( fd ); + fd = -1; + break; + } + } + GDMAuthenticate(); + } else { + if ((ptr = const_cast(strchr( dpy, ':' )))) + ptr = strchr( ptr, '.' ); + snprintf( sa.sun_path, sizeof(sa.sun_path), + "%s/dmctl-%.*s/socket", + ctl, ptr ? int(ptr - dpy) : 512, dpy ); + if (::connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) { + ::close( fd ); + fd = -1; + } + } + break; + case OldTDM: + { + TQString tf( ctl ); + tf.truncate( tf.find( ',' ) ); + fd = ::open( tf.latin1(), O_WRONLY ); + } + break; + } +} + +DM::~DM() +{ + if (fd >= 0) + close( fd ); +} + +bool +DM::exec( const char *cmd ) +{ + TQCString buf; + + return exec( cmd, buf ); +} + +/** + * Execute a TDM/GDM remote control command. + * @param cmd the command to execute. FIXME: undocumented yet. + * @param buf the result buffer. + * @return result: + * @li If true, the command was successfully executed. + * @p ret might contain addional results. + * @li If false and @p ret is empty, a communication error occurred + * (most probably TDM is not running). + * @li If false and @p ret is non-empty, it contains the error message + * from TDM. + */ +bool +DM::exec( const char *cmd, TQCString &buf ) +{ + bool ret = false; + int tl; + unsigned len = 0; + + if (fd < 0) + goto busted; + + tl = strlen( cmd ); + if (::write( fd, cmd, tl ) != tl) { + bust: + ::close( fd ); + fd = -1; + busted: + buf.resize( 0 ); + return false; + } + if (DMType == OldTDM) { + buf.resize( 0 ); + return true; + } + for (;;) { + if (buf.size() < 128) + buf.resize( 128 ); + else if (buf.size() < len * 2) + buf.resize( len * 2 ); + if ((tl = ::read( fd, buf.data() + len, buf.size() - len)) <= 0) { + if (tl < 0 && errno == EINTR) + continue; + goto bust; + } + len += tl; + if (buf[len - 1] == '\n') { + buf[len - 1] = 0; + if (len > 2 && (buf[0] == 'o' || buf[0] == 'O') && + (buf[1] == 'k' || buf[1] == 'K') && buf[2] <= 32) + ret = true; + break; + } + } + return ret; +} + +bool +DM::canShutdown() +{ + if (DMType == OldTDM) + return strstr( ctl, ",maysd" ) != 0; + + TQCString re; + + if (DMType == GDM) + return exec( "QUERY_LOGOUT_ACTION\n", re ) && re.find("HALT") >= 0; + + return exec( "caps\n", re ) && re.find( "\tshutdown" ) >= 0; +} + +void +DM::shutdown( KApplication::ShutdownType shutdownType, + KApplication::ShutdownMode shutdownMode, /* NOT Default */ + const TQString &bootOption ) +{ + if (shutdownType == KApplication::ShutdownTypeNone) + return; + + bool cap_ask; + if (DMType == NewTDM) { + TQCString re; + cap_ask = exec( "caps\n", re ) && re.find( "\tshutdown ask" ) >= 0; + } else { + if (!bootOption.isEmpty()) + return; + cap_ask = false; + } + if (!cap_ask && shutdownMode == KApplication::ShutdownModeInteractive) + shutdownMode = KApplication::ShutdownModeForceNow; + + TQCString cmd; + if (DMType == GDM) { + cmd.append( shutdownMode == KApplication::ShutdownModeForceNow ? + "SET_LOGOUT_ACTION " : "SET_SAFE_LOGOUT_ACTION " ); + cmd.append( shutdownType == KApplication::ShutdownTypeReboot ? + "REBOOT\n" : "HALT\n" ); + } else { + cmd.append( "shutdown\t" ); + cmd.append( shutdownType == KApplication::ShutdownTypeReboot ? + "reboot\t" : "halt\t" ); + if (!bootOption.isEmpty()) + cmd.append( "=" ).append( bootOption.local8Bit() ).append( "\t" ); + cmd.append( shutdownMode == KApplication::ShutdownModeInteractive ? + "ask\n" : + shutdownMode == KApplication::ShutdownModeForceNow ? + "forcenow\n" : + shutdownMode == KApplication::ShutdownModeTryNow ? + "trynow\n" : "schedule\n" ); + } + exec( cmd.data() ); +} + +bool +DM::bootOptions( TQStringList &opts, int &defopt, int ¤t ) +{ + if (DMType != NewTDM) + return false; + + TQCString re; + if (!exec( "listbootoptions\n", re )) + return false; + + opts = TQStringList::split( '\t', TQString::fromLocal8Bit( re.data() ) ); + if (opts.size() < 4) + return false; + + bool ok; + defopt = opts[2].toInt( &ok ); + if (!ok) + return false; + current = opts[3].toInt( &ok ); + if (!ok) + return false; + + opts = TQStringList::split( ' ', opts[1] ); + for (TQStringList::Iterator it = opts.begin(); it != opts.end(); ++it) + (*it).replace( "\\s", " " ); + + return true; +} + +void +DM::setLock( bool on ) +{ + if (DMType != GDM) + exec( on ? "lock\n" : "unlock\n" ); +} + +bool +DM::isSwitchable() +{ + if (DMType == OldTDM) + return dpy[0] == ':'; + + if (DMType == GDM) + return exec( "QUERY_VT\n" ); + + TQCString re; + + return exec( "caps\n", re ) && re.find( "\tlocal" ) >= 0; +} + +int +DM::numReserve() +{ + if (DMType == GDM) + return 1; /* Bleh */ + + if (DMType == OldTDM) + return strstr( ctl, ",rsvd" ) ? 1 : -1; + + TQCString re; + int p; + + if (!(exec( "caps\n", re ) && (p = re.find( "\treserve " )) >= 0)) + return -1; + return atoi( re.data() + p + 9 ); +} + +void +DM::startReserve() +{ + if (DMType == GDM) + exec("FLEXI_XSERVER\n"); + else + exec("reserve\n"); +} + +bool +DM::localSessions( SessList &list ) +{ + if (DMType == OldTDM) + return false; + + TQCString re; + + if (DMType == GDM) { + if (!exec( "CONSOLE_SERVERS\n", re )) + return false; + TQStringList sess = TQStringList::split( TQChar(';'), re.data() + 3 ); + for (TQStringList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { + TQStringList ts = TQStringList::split( TQChar(','), *it, true ); + SessEnt se; + se.display = ts[0]; + se.user = ts[1]; + se.vt = ts[2].toInt(); + se.session = ""; + se.self = ts[0] == ::getenv( "DISPLAY" ); /* Bleh */ + se.tty = false; + list.append( se ); + } + } else { + if (!exec( "list\talllocal\n", re )) + return false; + TQStringList sess = TQStringList::split( TQChar('\t'), re.data() + 3 ); + for (TQStringList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { + TQStringList ts = TQStringList::split( TQChar(','), *it, true ); + SessEnt se; + se.display = ts[0]; + if (ts[1][0] == '@') + se.from = ts[1].mid( 1 ), se.vt = 0; + else + se.vt = ts[1].mid( 2 ).toInt(); + se.user = ts[2]; + se.session = ts[3]; + se.self = (ts[4].find( '*' ) >= 0); + se.tty = (ts[4].find( 't' ) >= 0); + list.append( se ); + } + } + return true; +} + +void +DM::sess2Str2( const SessEnt &se, TQString &user, TQString &loc ) +{ + if (se.tty) { + user = i18n("user: ...", "%1: TTY login").arg( se.user ); + loc = se.vt ? TQString(TQString("vt%1").arg( se.vt )) : se.display ; + } else { + user = + se.user.isEmpty() ? + se.session.isEmpty() ? + i18n("Unused") : + se.session == "" ? + i18n("X login on remote host") : + TQString(i18n("... host", "X login on %1").arg( se.session )) : + se.session == "" ? + se.user : + TQString(i18n("user: session type", "%1: %2") + .arg( se.user ).arg( se.session )); + loc = + se.vt ? + TQString(TQString("%1, vt%2").arg( se.display ).arg( se.vt )) : + se.display; + } +} + +TQString +DM::sess2Str( const SessEnt &se ) +{ + TQString user, loc; + + sess2Str2( se, user, loc ); + return i18n("session (location)", "%1 (%2)").arg( user ).arg( loc ); +} + +bool +DM::switchVT( int vt ) +{ + if (DMType == GDM) + return exec( TQString(TQString("SET_VT %1\n").arg(vt)).latin1() ); + + return exec( TQString(TQString("activate\tvt%1\n").arg(vt)).latin1() ); +} + +void +DM::lockSwitchVT( int vt ) +{ + if (switchVT( vt )) + kapp->dcopClient()->send( "kdesktop", "KScreensaverIface", "lock()", TQString("") ); +} + +void +DM::GDMAuthenticate() +{ + FILE *fp; + const char *dpy, *dnum, *dne; + int dnl; + Xauth *xau; + + dpy = DisplayString( TQPaintDevice::x11AppDisplay() ); + if (!dpy) { + dpy = ::getenv( "DISPLAY" ); + if (!dpy) + return; + } + dnum = strchr( dpy, ':' ) + 1; + dne = strchr( dpy, '.' ); + dnl = dne ? dne - dnum : strlen( dnum ); + + /* XXX should do locking */ + if (!(fp = fopen( XauFileName(), "r" ))) + return; + + while ((xau = XauReadAuth( fp ))) { + if (xau->family == FamilyLocal && + xau->number_length == dnl && !memcmp( xau->number, dnum, dnl ) && + xau->data_length == 16 && + xau->name_length == 18 && !memcmp( xau->name, "MIT-MAGIC-COOKIE-1", 18 )) + { + TQString cmd( "AUTH_LOCAL " ); + for (int i = 0; i < 16; i++) + cmd += TQString::number( (uchar)xau->data[i], 16 ).rightJustify( 2, '0'); + cmd += "\n"; + if (exec( cmd.latin1() )) { + XauDisposeAuth( xau ); + break; + } + } + XauDisposeAuth( xau ); + } + + fclose (fp); +} + +#endif // Q_WS_X11 diff --git a/tdmlib/dmctl.h b/tdmlib/dmctl.h new file mode 100644 index 000000000..da5aa2b0b --- /dev/null +++ b/tdmlib/dmctl.h @@ -0,0 +1,93 @@ +/* + Copyright (C) 2004,2005 Oswald Buddenhagen + Copyright (C) 2005 Stephan Kulow + + This program is free software; you can redistribute it and/or + modify it under the terms of the Lesser 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 Lesser GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef DMCTL_H +#define DMCTL_H + +#include + +struct SessEnt { + TQString display, from, user, session; + int vt; + bool self:1, tty:1; +}; + +typedef TQValueList SessList; + +class DM { + +#ifdef Q_WS_X11 + +public: + DM(); + ~DM(); + + bool canShutdown(); + void shutdown( KApplication::ShutdownType shutdownType, + KApplication::ShutdownMode shutdownMode, + const TQString &bootOption = TQString::null ); + + void setLock( bool on ); + + bool isSwitchable(); + int numReserve(); + void startReserve(); + bool localSessions( SessList &list ); + bool switchVT( int vt ); + void lockSwitchVT( int vt ); + + bool bootOptions( TQStringList &opts, int &dflt, int &curr ); + + static TQString sess2Str( const SessEnt &se ); + static void sess2Str2( const SessEnt &se, TQString &user, TQString &loc ); + +private: + int fd; + + bool exec( const char *cmd, TQCString &ret ); + bool exec( const char *cmd ); + + void GDMAuthenticate(); + +#else // Q_WS_X11 + +public: + DM() {} + + bool canShutdown() { return false; } + void shutdown( KApplication::ShutdownType shutdownType, + KApplication::ShutdownMode shutdownMode, + const TQString &bootOption = TQString::null ) {} + + void setLock( bool ) {} + + bool isSwitchable() { return false; } + int numReserve() { return -1; } + void startReserve() {} + bool localSessions( SessList &list ) { return false; } + void switchVT( int vt ) {} + + bool bootOptions( TQStringList &opts, int &dflt, int &curr ); + +#endif // Q_WS_X11 + +}; // class DM + +#endif // DMCTL_H diff --git a/tdmlib/kgreet_classic.cpp b/tdmlib/kgreet_classic.cpp new file mode 100644 index 000000000..b37f2bab7 --- /dev/null +++ b/tdmlib/kgreet_classic.cpp @@ -0,0 +1,513 @@ +/* + +Conversation widget for tdm greeter + +Copyright (C) 1997, 1998, 2000 Steffen Hansen +Copyright (C) 2000-2003 Oswald Buddenhagen + + +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 "kgreet_classic.h" +#include "themer/tdmthemer.h" +#include "themer/tdmitem.h" + +#include +#include +#include +#include + +#include +#include +#include + +class TDMPasswordEdit : public KPasswordEdit { +public: + TDMPasswordEdit( TQWidget *parent ) : KPasswordEdit( parent, 0 ) {} + TDMPasswordEdit( KPasswordEdit::EchoModes echoMode, TQWidget *parent ) : KPasswordEdit( echoMode, parent, 0 ) {} +protected: + virtual void contextMenuEvent( TQContextMenuEvent * ) {} +}; + +static int echoMode; + +KClassicGreeter::KClassicGreeter( KGreeterPluginHandler *_handler, + KdmThemer *themer, + TQWidget *parent, TQWidget *pred, + const TQString &_fixedEntity, + Function _func, Context _ctx ) : + TQObject(), + KGreeterPlugin( _handler ), + fixedUser( _fixedEntity ), + func( _func ), + ctx( _ctx ), + exp( -1 ), + pExp( -1 ), + running( false ) +{ + KdmItem *user_entry = 0, *pw_entry = 0; + TQGridLayout *grid = 0; + int line = 0; + + layoutItem = 0; + + if (themer && + (!(user_entry = themer->findNode( "user-entry" )) || + !(pw_entry = themer->findNode( "pw-entry" )))) + themer = 0; + + if (!themer) + grid = new TQGridLayout( 0, 0, 10 ); + layoutItem = TQT_TQLAYOUTITEM(grid); + + loginLabel = passwdLabel = passwd1Label = passwd2Label = 0; + loginEdit = 0; + passwdEdit = passwd1Edit = passwd2Edit = 0; + if (ctx == ExUnlock || ctx == ExChangeTok) + fixedUser = KUser().loginName(); + if (func != ChAuthTok) { + if (fixedUser.isEmpty()) { + loginEdit = new KLineEdit( parent ); + loginEdit->setContextMenuEnabled( false ); + connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotLoginLostFocus()) ); + connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); + connect( loginEdit, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotActivity()) ); + connect( loginEdit, TQT_SIGNAL(selectionChanged()), TQT_SLOT(slotActivity()) ); + if (pred) { + parent->setTabOrder( pred, loginEdit ); + pred = loginEdit; + } + if (!grid) { + loginEdit->adjustSize(); + user_entry->setWidget( loginEdit ); + } else { + loginLabel = new TQLabel( loginEdit, i18n("&Username:"), parent ); + grid->addWidget( loginLabel, line, 0 ); + grid->addWidget( loginEdit, line++, 1 ); + } + } else if (ctx != Login && ctx != Shutdown && grid) { + loginLabel = new TQLabel( i18n("Username:"), parent ); + grid->addWidget( loginLabel, line, 0 ); + grid->addWidget( new TQLabel( fixedUser, parent ), line++, 1 ); + } + if (echoMode == -1) + passwdEdit = new TDMPasswordEdit( parent ); + else + passwdEdit = new TDMPasswordEdit( (KPasswordEdit::EchoModes)echoMode, + parent ); + connect( passwdEdit, TQT_SIGNAL(textChanged( const TQString & )), + TQT_SLOT(slotActivity()) ); + connect( passwdEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); + if (pred) { + parent->setTabOrder( pred, passwdEdit ); + pred = passwdEdit; + } + if (!grid) { + passwdEdit->adjustSize(); + pw_entry->setWidget( passwdEdit ); + } else { + passwdLabel = new TQLabel( passwdEdit, + func == Authenticate ? + i18n("&Password:") : + i18n("Current &password:"), + parent ); + grid->addWidget( passwdLabel, line, 0 ); + grid->addWidget( passwdEdit, line++, 1 ); + } + if (loginEdit) + loginEdit->setFocus(); + else + passwdEdit->setFocus(); + } + if (func != Authenticate) { + if (echoMode == -1) { + passwd1Edit = new TDMPasswordEdit( (KPasswordEdit::EchoModes)echoMode, parent ); + passwd2Edit = new TDMPasswordEdit( (KPasswordEdit::EchoModes)echoMode, parent ); + } else { + passwd1Edit = new TDMPasswordEdit( parent ); + passwd2Edit = new TDMPasswordEdit( parent ); + } + passwd1Label = new TQLabel( passwd1Edit, i18n("&New password:"), parent ); + passwd2Label = new TQLabel( passwd2Edit, i18n("Con&firm password:"), parent ); + if (pred) { + parent->setTabOrder( pred, passwd1Edit ); + parent->setTabOrder( passwd1Edit, passwd2Edit ); + } + if (grid) { + grid->addWidget( passwd1Label, line, 0 ); + grid->addWidget( passwd1Edit, line++, 1 ); + grid->addWidget( passwd2Label, line, 0 ); + grid->addWidget( passwd2Edit, line, 1 ); + } + if (!passwdEdit) + passwd1Edit->setFocus(); + } +} + +// virtual +KClassicGreeter::~KClassicGreeter() +{ + abort(); + if (!layoutItem) { + delete loginEdit; + delete passwdEdit; + return; + } + TQLayoutIterator it = TQT_TQLAYOUT(layoutItem)->iterator(); + for (TQLayoutItem *itm = it.current(); itm; itm = ++it) + delete itm->widget(); + delete layoutItem; +} + +void // virtual +KClassicGreeter::loadUsers( const TQStringList &users ) +{ + KCompletion *userNamesCompletion = new KCompletion; + userNamesCompletion->setItems( users ); + loginEdit->setCompletionObject( userNamesCompletion ); + loginEdit->setAutoDeleteCompletionObject( true ); + loginEdit->setCompletionMode( KGlobalSettings::CompletionAuto ); +} + +void // virtual +KClassicGreeter::presetEntity( const TQString &entity, int field ) +{ + loginEdit->setText( entity ); + if (field == 1) + passwdEdit->setFocus(); + else { + loginEdit->setFocus(); + loginEdit->selectAll(); + if (field == -1) { + passwdEdit->setText( " " ); + passwdEdit->setEnabled( false ); + authTok = false; + } + } + curUser = entity; +} + +TQString // virtual +KClassicGreeter::getEntity() const +{ + return fixedUser.isEmpty() ? loginEdit->text() : fixedUser; +} + +void // virtual +KClassicGreeter::setUser( const TQString &user ) +{ + // assert( fixedUser.isEmpty() ); + curUser = user; + loginEdit->setText( user ); + passwdEdit->setFocus(); + passwdEdit->selectAll(); +} + +void // virtual +KClassicGreeter::setPassword( const TQString &pass ) +{ + passwdEdit->erase(); + passwdEdit->insert( pass ); +} + +void // virtual +KClassicGreeter::setEnabled( bool enable ) +{ + // assert( !passwd1Label ); + // assert( func == Authenticate && ctx == Shutdown ); +// if (loginLabel) +// loginLabel->setEnabled( enable ); + passwdLabel->setEnabled( enable ); + setActive( enable ); + if (enable) + passwdEdit->setFocus(); +} + +void // private +KClassicGreeter::returnData() +{ + switch (exp) { + case 0: + handler->gplugReturnText( (loginEdit ? loginEdit->text() : + fixedUser).local8Bit(), + KGreeterPluginHandler::IsUser ); + break; + case 1: + handler->gplugReturnText( passwdEdit->password(), + KGreeterPluginHandler::IsPassword | + KGreeterPluginHandler::IsSecret ); + break; + case 2: + handler->gplugReturnText( passwd1Edit->password(), + KGreeterPluginHandler::IsSecret ); + break; + default: // case 3: + handler->gplugReturnText( passwd2Edit->password(), + KGreeterPluginHandler::IsNewPassword | + KGreeterPluginHandler::IsSecret ); + break; + } +} + +bool // virtual +KClassicGreeter::textMessage( const char *text, bool err ) +{ + if (!err && + TQString( text ).find( TQRegExp( "^Changing password for [^ ]+$" ) ) >= 0) + return true; + return false; +} + +void // virtual +KClassicGreeter::textPrompt( const char *prompt, bool echo, bool nonBlocking ) +{ + pExp = exp; + if (echo) + exp = 0; + else if (!authTok) + exp = 1; + else { + TQString pr( prompt ); + if (pr.find( TQRegExp( "\\bpassword\\b", false ) ) >= 0) { + if (pr.find( TQRegExp( "\\b(re-?(enter|type)|again|confirm|repeat)\\b", + false ) ) >= 0) + exp = 3; + else if (pr.find( TQRegExp( "\\bnew\\b", false ) ) >= 0) + exp = 2; + else { // TQRegExp( "\\b(old|current)\\b", false ) is too strict + handler->gplugReturnText( "", + KGreeterPluginHandler::IsOldPassword | + KGreeterPluginHandler::IsSecret ); + return; + } + } else { + handler->gplugMsgBox( TQMessageBox::Critical, + i18n("Unrecognized prompt \"%1\"") + .arg( prompt ) ); + handler->gplugReturnText( 0, 0 ); + exp = -1; + return; + } + } + + if (pExp >= 0 && pExp >= exp) { + revive(); + has = -1; + } + + if (has >= exp || nonBlocking) + returnData(); +} + +bool // virtual +KClassicGreeter::binaryPrompt( const char *, bool ) +{ + // this simply cannot happen ... :} + return true; +} + +void // virtual +KClassicGreeter::start() +{ + authTok = !(passwdEdit && passwdEdit->isEnabled()); + exp = has = -1; + running = true; +} + +void // virtual +KClassicGreeter::suspend() +{ +} + +void // virtual +KClassicGreeter::resume() +{ +} + +void // virtual +KClassicGreeter::next() +{ + // assert( running ); + if (loginEdit && loginEdit->hasFocus()) { + passwdEdit->setFocus(); // will cancel running login if necessary + has = 0; + } else if (passwdEdit && passwdEdit->hasFocus()) { + if (passwd1Edit) + passwd1Edit->setFocus(); + has = 1; + } else if (passwd1Edit) { + if (passwd1Edit->hasFocus()) { + passwd2Edit->setFocus(); + has = 1; // sic! + } else + has = 3; + } else + has = 1; + if (exp < 0) + handler->gplugStart(); + else if (has >= exp) + returnData(); +} + +void // virtual +KClassicGreeter::abort() +{ + running = false; + if (exp >= 0) { + exp = -1; + handler->gplugReturnText( 0, 0 ); + } +} + +void // virtual +KClassicGreeter::succeeded() +{ + // assert( running || timed_login ); + if (!authTok) { + setActive( false ); + if (passwd1Edit) { + authTok = true; + return; + } + } else + setActive2( false ); + exp = -1; + running = false; +} + +void // virtual +KClassicGreeter::failed() +{ + // assert( running || timed_login ); + setActive( false ); + setActive2( false ); + exp = -1; + running = false; +} + +void // virtual +KClassicGreeter::revive() +{ + // assert( !running ); + setActive2( true ); + if (authTok) { + passwd1Edit->erase(); + passwd2Edit->erase(); + passwd1Edit->setFocus(); + } else { + passwdEdit->erase(); + if (loginEdit && loginEdit->isEnabled()) + passwdEdit->setEnabled( true ); + else { + setActive( true ); + if (loginEdit && loginEdit->text().isEmpty()) + loginEdit->setFocus(); + else + passwdEdit->setFocus(); + } + } +} + +void // virtual +KClassicGreeter::clear() +{ + // assert( !running && !passwd1Edit ); + passwdEdit->erase(); + if (loginEdit) { + loginEdit->clear(); + loginEdit->setFocus(); + curUser = TQString::null; + } else + passwdEdit->setFocus(); +} + + +// private + +void +KClassicGreeter::setActive( bool enable ) +{ + if (loginEdit) + loginEdit->setEnabled( enable ); + if (passwdEdit) + passwdEdit->setEnabled( enable ); +} + +void +KClassicGreeter::setActive2( bool enable ) +{ + if (passwd1Edit) { + passwd1Edit->setEnabled( enable ); + passwd2Edit->setEnabled( enable ); + } +} + +void +KClassicGreeter::slotLoginLostFocus() +{ + if (!running) + return; + if (exp > 0) { + if (curUser == loginEdit->text()) + return; + exp = -1; + handler->gplugReturnText( 0, 0 ); + } + curUser = loginEdit->text(); + handler->gplugSetUser( curUser ); +} + +void +KClassicGreeter::slotActivity() +{ + if (running) + handler->gplugActivity(); +} + +// factory + +static bool init( const TQString &, + TQVariant (*getConf)( void *, const char *, const TQVariant & ), + void *ctx ) +{ + echoMode = getConf( ctx, "EchoMode", TQVariant( -1 ) ).toInt(); + KGlobal::locale()->insertCatalogue( "kgreet_classic" ); + return true; +} + +static void done( void ) +{ + KGlobal::locale()->removeCatalogue( "kgreet_classic" ); +} + +static KGreeterPlugin * +create( KGreeterPluginHandler *handler, KdmThemer *themer, + TQWidget *parent, TQWidget *predecessor, + const TQString &fixedEntity, + KGreeterPlugin::Function func, + KGreeterPlugin::Context ctx ) +{ + return new KClassicGreeter( handler, themer, parent, predecessor, fixedEntity, func, ctx ); +} + +KDE_EXPORT kgreeterplugin_info kgreeterplugin_info = { + I18N_NOOP("Username + password (classic)"), "classic", + kgreeterplugin_info::Local | kgreeterplugin_info::Presettable, + init, done, create +}; + +#include "kgreet_classic.moc" diff --git a/tdmlib/kgreet_classic.h b/tdmlib/kgreet_classic.h new file mode 100644 index 000000000..1f467a528 --- /dev/null +++ b/tdmlib/kgreet_classic.h @@ -0,0 +1,88 @@ +/* + +Conversation widget for tdm greeter + +Copyright (C) 1997, 1998 Steffen Hansen +Copyright (C) 2000-2003 Oswald Buddenhagen + + +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. + +*/ + + +#ifndef KGREET_CLASSIC_H +#define KGREET_CLASSIC_H + +#include "kgreeterplugin.h" + +#include + +class KLineEdit; +class KPasswordEdit; +class KSimpleConfig; +class TQGridLayout; +class TQLabel; + +class KClassicGreeter : public TQObject, public KGreeterPlugin { + Q_OBJECT + + public: + KClassicGreeter( KGreeterPluginHandler *handler, + KdmThemer *themer, + TQWidget *parent, TQWidget *predecessor, + const TQString &fixedEntitiy, + Function func, Context ctx ); + ~KClassicGreeter(); + virtual void loadUsers( const TQStringList &users ); + virtual void presetEntity( const TQString &entity, int field ); + virtual TQString getEntity() const; + virtual void setUser( const TQString &user ); + virtual void setPassword( const TQString &pass ); + virtual void setEnabled( bool on ); + virtual bool textMessage( const char *message, bool error ); + virtual void textPrompt( const char *prompt, bool echo, bool nonBlocking ); + virtual bool binaryPrompt( const char *prompt, bool nonBlocking ); + virtual void start(); + virtual void suspend(); + virtual void resume(); + virtual void next(); + virtual void abort(); + virtual void succeeded(); + virtual void failed(); + virtual void revive(); + virtual void clear(); + + public slots: + void slotLoginLostFocus(); + void slotActivity(); + + private: + void setActive( bool enable ); + void setActive2( bool enable ); + void returnData(); + + TQLabel *loginLabel, *passwdLabel, *passwd1Label, *passwd2Label; + KLineEdit *loginEdit; + KPasswordEdit *passwdEdit, *passwd1Edit, *passwd2Edit; + KSimpleConfig *stsFile; + TQString fixedUser, curUser; + Function func; + Context ctx; + int exp, pExp, has; + bool running, authTok; +}; + +#endif /* KGREET_CLASSIC_H */ diff --git a/tdmlib/kgreet_pam.cpp b/tdmlib/kgreet_pam.cpp new file mode 100644 index 000000000..82506fb43 --- /dev/null +++ b/tdmlib/kgreet_pam.cpp @@ -0,0 +1,675 @@ +/* + +Conversation widget for tdm greeter + +Copyright (C) 2008 Dirk Mueller + +based on classic tdm greeter: + + Copyright (C) 1997, 1998, 2000 Steffen Hansen + Copyright (C) 2000-2003 Oswald Buddenhagen + + +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 "kgreet_pam.h" +#include "themer/tdmthemer.h" +#include "themer/tdmlabel.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +//#define PAM_GREETER_DEBUG + +class TDMPasswordEdit : public KPasswordEdit { +public: + TDMPasswordEdit( TQWidget *parent ) : KPasswordEdit( parent, 0 ) {} + TDMPasswordEdit( KPasswordEdit::EchoModes echoMode, TQWidget *parent ) : KPasswordEdit( echoMode, parent, 0 ) {} +protected: + virtual void contextMenuEvent( TQContextMenuEvent * ) {} +}; + +static FILE* log; +static void kg_debug(const char* fmt, ...) +{ + va_list lst; + va_start(lst, fmt); + +#ifdef PAM_GREETER_DEBUG +#if 0 + vfprintf(log, fmt, lst); + fflush(log); +#else + char buf[6000]; + sprintf(buf, "*** %s\n", fmt); + vsyslog(LOG_WARNING, buf, lst); +#endif +#endif + va_end(lst); +} + +static KPasswordEdit::EchoModes echoMode; + +KPamGreeter::KPamGreeter( KGreeterPluginHandler *_handler, + KdmThemer *themer, + TQWidget *parent, TQWidget *pred, + const TQString &_fixedEntity, + Function _func, Context _ctx ) : + TQObject(), + KGreeterPlugin( _handler ), + fixedUser( _fixedEntity ), + func( _func ), + ctx( _ctx ), + exp( -1 ), + pExp( -1 ), + running( false ) +{ + ctx = Login; + + kg_debug("KPamGreeter constructed\n"); + + m_parentWidget = parent; + + KdmItem *user_entry = 0, *pw_entry = 0; + int line = 0; + + layoutItem = 0; + + if (themer && + (!(user_entry = themer->findNode( "user-entry" )) || + !(pw_entry = themer->findNode( "pw-entry" )))) + themer = 0; + + m_themer = themer; + + if (!themer) + layoutItem = TQT_TQLAYOUTITEM(new TQGridLayout( 0, 0, 10 )); + + loginLabel = 0; + authLabel.clear(); + authEdit.clear(); + loginLabel = 0; + loginEdit = 0; + if (ctx == ExUnlock || ctx == ExChangeTok) + fixedUser = KUser().loginName(); + if (func != ChAuthTok) { + kg_debug("func != ChAuthTok\n"); + kg_debug("fixedUser: *%s*\n", fixedUser.latin1()); + + if (fixedUser.isEmpty()) { + loginEdit = new KLineEdit( parent ); + loginEdit->setContextMenuEnabled( false ); + connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotLoginLostFocus()) ); + connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); + connect( loginEdit, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotActivity()) ); + connect( loginEdit, TQT_SIGNAL(selectionChanged()), TQT_SLOT(slotActivity()) ); + if (pred) { + parent->setTabOrder( pred, loginEdit ); + pred = loginEdit; + } + if (!getLayoutItem()) { + loginEdit->adjustSize(); + user_entry->setWidget( loginEdit ); + } else { + loginLabel = new TQLabel( loginEdit, i18n("Username:"), parent ); + getLayoutItem()->addWidget( loginLabel, line, 0 ); + getLayoutItem()->addWidget( loginEdit, line++, 1 ); + } + } else if (ctx != Login && ctx != Shutdown && getLayoutItem()) { + loginLabel = new TQLabel( i18n("Username:"), parent ); + getLayoutItem()->addWidget( loginLabel, line, 0 ); + getLayoutItem()->addWidget( new TQLabel( fixedUser, parent ), line++, 1 ); + } +#if 0 + if (echoMode == -1) + passwdEdit = new TDMPasswordEdit( parent ); + else + passwdEdit = new TDMPasswordEdit( echoMode, + parent ); + connect( passwdEdit, TQT_SIGNAL(textChanged( const TQString & )), + TQT_SLOT(slotActivity()) ); + connect( passwdEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); + if (pred) { + parent->setTabOrder( pred, passwdEdit ); + pred = passwdEdit; + } + if (!getLayoutItem()) { + passwdEdit->adjustSize(); + pw_entry->setWidget( passwdEdit ); + } else { + passwdLabel = new TQLabel( passwdEdit, + func == Authenticate ? + i18n("hello &Password:") : + i18n("Current &password:"), + parent ); + getLayoutItem()->addWidget( passwdLabel, line, 0 ); + getLayoutItem()->addWidget( passwdEdit, line++, 1 ); + } +#endif + if (loginEdit) + loginEdit->setFocus(); + } + if (func != Authenticate) { + if (echoMode == -1) { + authEdit << new TDMPasswordEdit( echoMode, parent ); + authEdit << new TDMPasswordEdit( echoMode, parent ); + } else { + authEdit << new TDMPasswordEdit( parent ); + authEdit << new TDMPasswordEdit( parent ); + } + authLabel << new TQLabel( authEdit[0], i18n("&New password:"), parent ); + authLabel << new TQLabel( authEdit[1], i18n("Con&firm password:"), parent ); + if (pred) { + parent->setTabOrder( pred, authEdit[0] ); + parent->setTabOrder( authEdit[0], authEdit[1] ); + } + if (getLayoutItem()) { + getLayoutItem()->addWidget( authLabel[0], line, 0 ); + getLayoutItem()->addWidget( authEdit[0], line++, 1 ); + getLayoutItem()->addWidget( authLabel[1], line, 0 ); + getLayoutItem()->addWidget( authEdit[1], line, 1 ); + } + if (authEdit.size() >= 2) + authEdit[1]->setFocus(); + } +} + +// virtual +KPamGreeter::~KPamGreeter() +{ + kg_debug("KPamGreeter::~KPamGreeter"); + abort(); + if (!layoutItem) { + delete loginEdit; + return; + } + TQLayoutIterator it = TQT_TQLAYOUT(layoutItem)->iterator(); + for (TQLayoutItem *itm = it.current(); itm; itm = ++it) + delete itm->widget(); + delete layoutItem; + kg_debug("destructor finished, good bye"); +} + +void // virtual +KPamGreeter::loadUsers( const TQStringList &users ) +{ + KCompletion *userNamesCompletion = new KCompletion; + userNamesCompletion->setItems( users ); + loginEdit->setCompletionObject( userNamesCompletion ); + loginEdit->setAutoDeleteCompletionObject( true ); + loginEdit->setCompletionMode( KGlobalSettings::CompletionAuto ); +} + +void // virtual +KPamGreeter::presetEntity( const TQString &entity, int field ) +{ + kg_debug("presetEntity(%s,%d) called!\n", entity.latin1(), field); + loginEdit->setText( entity ); + if (field == 1 && authEdit.size() >= 1) + authEdit[0]->setFocus(); + else { + loginEdit->setFocus(); + loginEdit->selectAll(); + if (field == -1 && authEdit.size() >= 1) { + authEdit[0]->setText( " " ); + authEdit[0]->setEnabled( false ); + authTok = false; + } + } + curUser = entity; +} + +TQString // virtual +KPamGreeter::getEntity() const +{ + return fixedUser.isEmpty() ? loginEdit->text() : fixedUser; +} + +void // virtual +KPamGreeter::setUser( const TQString &user ) +{ + // assert( fixedUser.isEmpty() ); + curUser = user; + loginEdit->setText( user ); + if (authEdit.size() >= 1) { + authEdit[0]->setFocus(); + authEdit[0]->selectAll(); + } +} + +void // virtual +KPamGreeter::setPassword( const TQString &pass ) +{ + authEdit[0]->erase(); + authEdit[0]->insert( pass ); +} + +void // virtual +KPamGreeter::setEnabled(bool enable) +{ + // assert( !passwd1Label ); + // assert( func == Authenticate && ctx == Shutdown ); +// if (loginLabel) +// loginLabel->setEnabled( enable ); + authEdit[0]->setEnabled( enable ); + setActive( enable ); + if (enable) + authEdit[0]->setFocus(); + } + +void // private +KPamGreeter::returnData() +{ + kg_debug("*************** returnData called with exp %d\n", exp); + + + switch (exp) { + case 0: + handler->gplugReturnText( (loginEdit ? loginEdit->text() : + fixedUser).local8Bit(), + KGreeterPluginHandler::IsUser ); + break; + case 1: + handler->gplugReturnText( authEdit[0]->password(), + KGreeterPluginHandler::IsPassword | + KGreeterPluginHandler::IsSecret ); + break; + case 2: + handler->gplugReturnText( authEdit[1]->password(), + KGreeterPluginHandler::IsSecret ); + break; + default: // case 3: + handler->gplugReturnText( authEdit[2]->password(), + KGreeterPluginHandler::IsNewPassword | + KGreeterPluginHandler::IsSecret ); + break; + } +} + +bool // virtual +KPamGreeter::textMessage( const char *text, bool err ) +{ + kg_debug(" ************** textMessage(%s, %d)\n", text, err); + + if (!authEdit.size()) + return false; + + if (getLayoutItem()) { + TQLabel* label = new TQLabel(TQString::fromUtf8(text), m_parentWidget); + getLayoutItem()->addWidget(label, state+1, 0, 0); + } + + return true; +} + +void // virtual +KPamGreeter::textPrompt( const char *prompt, bool echo, bool nonBlocking ) +{ + kg_debug("textPrompt called with prompt %s echo %d nonBlocking %d", prompt, echo, nonBlocking); + kg_debug("state is %d, authEdit.size is %d\n", state, authEdit.size()); + + if (state == 0 && echo) { + if (loginLabel) + loginLabel->setText(TQString::fromUtf8(prompt)); + else if (m_themer) { + KdmLabel *tdmlabel = static_cast(m_themer->findNode("user-label")); + if (tdmlabel) { + //userLabel->setText(TQString::fromUtf8(prompt)); + tdmlabel->label.text = TQString::fromUtf8(prompt); + TQTimer::singleShot(0, tdmlabel, TQT_SLOT(update())); + } + } + } + else if (state >= authEdit.size()) { + if (getLayoutItem()) { + TQLabel* label = new TQLabel(TQString::fromUtf8(prompt), m_parentWidget); + getLayoutItem()->addWidget(label, state+1, 0, 0); + kg_debug("added label widget to layout"); + } + else if (m_themer) { + kg_debug("themer found!"); + KdmItem *pw_label = 0; + + KdmLabel *tdmlabel = static_cast(m_themer->findNode("pw-label")); + if (tdmlabel) { + //userLabel->setText(TQString::fromUtf8(prompt)); + TQString str = TQString::fromUtf8(prompt); + tdmlabel->label.text = str; + TQTimer::singleShot(0, tdmlabel, TQT_SLOT(update())); + } + } + + TDMPasswordEdit* passwdEdit; + + if (echoMode == -1) + passwdEdit = new TDMPasswordEdit( m_parentWidget ); + else + passwdEdit = new TDMPasswordEdit( echoMode, m_parentWidget); + connect( passwdEdit, TQT_SIGNAL(textChanged( const TQString & )), + TQT_SLOT(slotActivity()) ); + connect( passwdEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); + authEdit << passwdEdit; + +#if 1 + for(TQValueList::iterator it = authEdit.begin(); + it != authEdit.end(); + ++it) { + if ((*it)->isEnabled() && (*it)->text().isEmpty()) { + (*it)->setFocus(); + break; + } + } +#endif + if (getLayoutItem()) + getLayoutItem()->addWidget(passwdEdit, state+1, 1, 0); + + if (m_themer) { + kg_debug("themer found!"); + KdmItem *pw_entry = 0; + + pw_entry = m_themer->findNode("pw-entry"); + + if (pw_entry && passwdEdit) + pw_entry->setWidget(passwdEdit); + + if (0) { + //userLabel->setText(TQString::fromUtf8(prompt)); + //tdmlabel->label.text = TQString::fromUtf8(prompt); + //TQTimer::singleShot(0, tdmlabel, TQT_SLOT(update())); + } + } + else + kg_debug("no themer found!"); + } + ++state; + pExp = exp; + + exp = authEdit.size(); + kg_debug("state %d exp: %d, has %d\n", state, exp, has); + + if (has >= exp || nonBlocking) + returnData(); +} + +bool // virtual +KPamGreeter::binaryPrompt( const char *, bool ) +{ + // this simply cannot happen ... :} + return true; +} + +void // virtual +KPamGreeter::start() +{ + kg_debug("******* start() called\n"); + + while(authEdit.begin() != authEdit.end()) { + KPasswordEdit* item = *authEdit.remove(authEdit.begin()); + delete item; + } + + while(authLabel.begin() != authLabel.end()) { + TQLabel* item = *authLabel.remove(authLabel.begin()); + delete item; + } + + authTok = !(authEdit.size() >= 2 && authEdit[1]->isEnabled()); + exp = has = -1; + state = 0; + running = true; + handler->gplugStart(); +} + +void // virtual +KPamGreeter::suspend() +{ +} + +void // virtual +KPamGreeter::resume() +{ +} + +void // virtual +KPamGreeter::next() +{ + kg_debug("********* next() called state %d\n", state); + + if (state == 0 && running && handler) { + kg_debug(" **** returned text!\n"); + handler->gplugReturnText( (loginEdit ? loginEdit->text() : + fixedUser).local8Bit(), + KGreeterPluginHandler::IsUser ); + setActive(false); + } + + has = 0; + + for(TQValueList::iterator it = authEdit.begin(); + it != authEdit.end(); + ++it) { + + has++; + if ((*it)->hasFocus()) { + ++it; + if (it != authEdit.end()) + (*it)->setFocus(); + break; + } + if (it == authEdit.end()) + has = -1; + } + + kg_debug(" has %d and exp %d\n", has, exp); + +#if 0 + // assert( running ); + if (loginEdit && loginEdit->hasFocus()) { + passwdEdit->setFocus(); // will cancel running login if necessary + has = 0; + } else if (passwdEdit && passwdEdit->hasFocus()) { + if (passwd1Edit) + passwd1Edit->setFocus(); + has = 1; + } else if (passwd1Edit) { + if (passwd1Edit->hasFocus()) { + passwd2Edit->setFocus(); + has = 1; // sic! + } else + has = 3; + } else + has = 1; + if (exp < 0) + handler->gplugStart(); +#endif + if (has >= exp) + returnData(); +} + +void // virtual +KPamGreeter::abort() +{ + kg_debug("***** abort() called\n"); + + running = false; + if (exp >= 0) { + exp = -1; + handler->gplugReturnText( 0, 0 ); + } +} + +void // virtual +KPamGreeter::succeeded() +{ + kg_debug("**** succeeded() called\n"); + + // assert( running || timed_login ); + if (!authTok) + setActive( false ); + else + setAllActive( false ); + exp = -1; + running = false; +} + +void // virtual +KPamGreeter::failed() +{ + // assert( running || timed_login ); + setActive( false ); + setAllActive( false ); + exp = -1; + running = false; +} + +#include +void // virtual +KPamGreeter::revive() +{ + // assert( !running ); + setAllActive( true ); + +#if 1 + if (authEdit.size() < 1) + return; +#endif + + assert(authEdit.size() >= 1); + if (authTok) { + authEdit[0]->erase(); + if(authEdit.size() >= 2) + authEdit[1]->erase(); + authEdit[0]->setFocus(); + } else { + authEdit[0]->erase(); + if (loginEdit && loginEdit->isEnabled()) + authEdit[0]->setEnabled( true ); + else { + setActive( true ); + if (loginEdit && loginEdit->text().isEmpty()) + loginEdit->setFocus(); + else + authEdit[0]->setFocus(); + } + } +} + +void // virtual +KPamGreeter::clear() +{ + // assert( !running && !passwd1Edit ); + authEdit[0]->erase(); + if (loginEdit) { + loginEdit->clear(); + loginEdit->setFocus(); + curUser = TQString::null; + } else + authEdit[0]->setFocus(); +} + + +// private + +void +KPamGreeter::setActive( bool enable ) +{ + if (loginEdit) + loginEdit->setEnabled( enable ); +} + +void +KPamGreeter::setAllActive( bool enable ) +{ + for(TQValueList::iterator it = authEdit.begin(); + it != authEdit.end(); + ++it) + (*it)->setEnabled( enable ); +} + +void +KPamGreeter::slotLoginLostFocus() +{ + if (!running) + return; + if (exp > 0) { + if (curUser == loginEdit->text()) + return; + exp = -1; + handler->gplugReturnText( 0, 0 ); + } + curUser = loginEdit->text(); + kg_debug("curUser is %s", curUser.latin1()); + handler->gplugSetUser( curUser ); +} + +void +KPamGreeter::slotActivity() +{ + kg_debug("slotActivity"); + + if (running) + handler->gplugActivity(); +} + +// factory + +static bool init( const TQString &, + TQVariant (*getConf)( void *, const char *, const TQVariant & ), + void *ctx ) +{ + echoMode = (KPasswordEdit::EchoModes) getConf( ctx, "EchoMode", TQVariant( -1 ) ).toInt(); + KGlobal::locale()->insertCatalogue( "kgreet_pam" ); + return true; +} + +static void done( void ) +{ + KGlobal::locale()->removeCatalogue( "kgreet_pam" ); + if (log && log != stderr) + fclose(log); + log = 0; +} + +static KGreeterPlugin * +create( KGreeterPluginHandler *handler, KdmThemer *themer, + TQWidget *parent, TQWidget *predecessor, + const TQString &fixedEntity, + KGreeterPlugin::Function func, + KGreeterPlugin::Context ctx ) +{ + return new KPamGreeter( handler, themer, parent, predecessor, fixedEntity, func, ctx ); +} + +KDE_EXPORT kgreeterplugin_info kgreeterplugin_info = { + I18N_NOOP("Pam conversation plugin"), "pam", + kgreeterplugin_info::Local | kgreeterplugin_info::Presettable, + init, done, create +}; + +#include "kgreet_pam.moc" diff --git a/tdmlib/kgreet_pam.h b/tdmlib/kgreet_pam.h new file mode 100644 index 000000000..03c404c1e --- /dev/null +++ b/tdmlib/kgreet_pam.h @@ -0,0 +1,94 @@ +/* + +Conversation widget for tdm greeter + +Copyright (C) 2008 Dirk Mueller + + +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. + +*/ + + +#ifndef KGREET_CLASSIC_H +#define KGREET_CLASSIC_H + +#include "kgreeterplugin.h" + +#include +#include + +class KLineEdit; +class KPasswordEdit; +class KSimpleConfig; +class TQGridLayout; +class TQLabel; + +class KPamGreeter : public TQObject, public KGreeterPlugin { + Q_OBJECT + + public: + KPamGreeter( KGreeterPluginHandler *handler, + KdmThemer *themer, + TQWidget *parent, TQWidget *predecessor, + const TQString &fixedEntitiy, + Function func, Context ctx ); + ~KPamGreeter(); + virtual void loadUsers( const TQStringList &users ); + virtual void presetEntity( const TQString &entity, int field ); + virtual TQString getEntity() const; + virtual void setUser( const TQString &user ); + virtual void setPassword( const TQString &pass ); + virtual void setEnabled( bool on ); + virtual bool textMessage( const char *message, bool error ); + virtual void textPrompt( const char *prompt, bool echo, bool nonBlocking ); + virtual bool binaryPrompt( const char *prompt, bool nonBlocking ); + virtual void start(); + virtual void suspend(); + virtual void resume(); + virtual void next(); + virtual void abort(); + virtual void succeeded(); + virtual void failed(); + virtual void revive(); + virtual void clear(); + + TQGridLayout *getLayoutItem() const { return static_cast(TQT_TQLAYOUT(layoutItem)); } + + public slots: + void slotLoginLostFocus(); + void slotActivity(); + + private: + void setActive( bool enable ); + void setAllActive( bool enable ); + void returnData(); + + TQLabel *loginLabel; + TQValueList authLabel; + KLineEdit *loginEdit; + TQWidget* m_parentWidget; + TQValueList authEdit; + KSimpleConfig *stsFile; + KdmThemer *m_themer; + TQString fixedUser, curUser; + Function func; + Context ctx; + int exp, pExp, has; + unsigned state; + bool running, authTok; +}; + +#endif /* KGREET_CLASSIC_H */ diff --git a/tdmlib/kgreet_winbind.cpp b/tdmlib/kgreet_winbind.cpp new file mode 100644 index 000000000..d5626a3fd --- /dev/null +++ b/tdmlib/kgreet_winbind.cpp @@ -0,0 +1,679 @@ +/* + +Conversation widget for tdm greeter + +Copyright (C) 1997, 1998, 2000 Steffen Hansen +Copyright (C) 2000-2004 Oswald Buddenhagen + + +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 "kgreet_winbind.h" +#include "themer/tdmthemer.h" +#include "themer/tdmitem.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +class TDMPasswordEdit : public KPasswordEdit { +public: + TDMPasswordEdit( TQWidget *parent ) : KPasswordEdit( parent, 0 ) {} + TDMPasswordEdit( KPasswordEdit::EchoModes echoMode, TQWidget *parent ) : KPasswordEdit( echoMode, parent, 0 ) {} +protected: + virtual void contextMenuEvent( TQContextMenuEvent * ) {} +}; + +static int echoMode; +static char separator; +static TQStringList staticDomains; +static TQString defaultDomain; + +static void +splitEntity( const TQString &ent, TQString &dom, TQString &usr ) +{ + int pos = ent.find( separator ); + if (pos < 0) + dom = "", usr = ent; + else + dom = ent.left( pos ), usr = ent.mid( pos + 1 ); +} + +KWinbindGreeter::KWinbindGreeter( KGreeterPluginHandler *_handler, + KdmThemer *themer, + TQWidget *parent, TQWidget *pred, + const TQString &_fixedEntity, + Function _func, Context _ctx ) : + TQObject(), + KGreeterPlugin( _handler ), + func( _func ), + ctx( _ctx ), + exp( -1 ), + pExp( -1 ), + running( false ) +{ + KdmItem *user_entry = 0, *pw_entry = 0, *domain_entry = 0; + TQGridLayout *grid = 0; + + int line = 0; + layoutItem = 0; + + if (themer && + (!(user_entry = themer->findNode( "user-entry" )) || + !(pw_entry = themer->findNode( "pw-entry" )) || + !(domain_entry = themer->findNode( "domain-entry" )))) + themer = 0; + + if (!themer) + grid = new TQGridLayout( 0, 0, 10 ); + layoutItem = TQT_TQLAYOUTITEM(grid); + + domainLabel = loginLabel = passwdLabel = passwd1Label = passwd2Label = 0; + domainCombo = 0; + loginEdit = 0; + passwdEdit = passwd1Edit = passwd2Edit = 0; + m_domainLister = 0; + if (ctx == ExUnlock || ctx == ExChangeTok) + splitEntity( KUser().loginName(), fixedDomain, fixedUser ); + else + splitEntity( _fixedEntity, fixedDomain, fixedUser ); + if (func != ChAuthTok) { + if (fixedUser.isEmpty()) { + domainCombo = new KComboBox( parent ); + connect( domainCombo, TQT_SIGNAL(activated( const TQString & )), + TQT_SLOT(slotChangedDomain( const TQString & )) ); + connect( domainCombo, TQT_SIGNAL(activated( const TQString & )), + TQT_SLOT(slotLoginLostFocus()) ); + connect( domainCombo, TQT_SIGNAL(activated( const TQString & )), + TQT_SLOT(slotActivity()) ); + // should handle loss of focus + loginEdit = new KLineEdit( parent ); + loginEdit->setContextMenuEnabled( false ); + + if (pred) { + parent->setTabOrder( pred, domainCombo ); + parent->setTabOrder( domainCombo, loginEdit ); + pred = loginEdit; + } + if (!grid) { + loginEdit->adjustSize(); + domainCombo->adjustSize(); + user_entry->setWidget( loginEdit ); + domain_entry->setWidget( domainCombo ); + } else { + domainLabel = new TQLabel( domainCombo, i18n("&Domain:"), parent ); + loginLabel = new TQLabel( loginEdit, i18n("&Username:"), parent ); + grid->addWidget( domainLabel, line, 0 ); + grid->addWidget( domainCombo, line++, 1 ); + grid->addWidget( loginLabel, line, 0 ); + grid->addWidget( loginEdit, line++, 1 ); + } + connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotLoginLostFocus()) ); + connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); + connect( loginEdit, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotActivity()) ); + connect( loginEdit, TQT_SIGNAL(selectionChanged()), TQT_SLOT(slotActivity()) ); + connect(&mDomainListTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotStartDomainList())); + domainCombo->insertStringList( staticDomains ); + TQTimer::singleShot(0, this, TQT_SLOT(slotStartDomainList())); + } else if (ctx != Login && ctx != Shutdown && grid) { + domainLabel = new TQLabel( i18n("Domain:"), parent ); + grid->addWidget( domainLabel, line, 0 ); + grid->addWidget( new TQLabel( fixedDomain, parent ), line++, 1 ); + loginLabel = new TQLabel( i18n("Username:"), parent ); + grid->addWidget( loginLabel, line, 0 ); + grid->addWidget( new TQLabel( fixedUser, parent ), line++, 1 ); + } + if (echoMode == -1) + passwdEdit = new TDMPasswordEdit( parent ); + else + passwdEdit = new TDMPasswordEdit( (KPasswordEdit::EchoModes)echoMode, + parent ); + connect( passwdEdit, TQT_SIGNAL(textChanged( const TQString & )), + TQT_SLOT(slotActivity()) ); + connect( passwdEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) ); + + if (!grid) { + passwdEdit->adjustSize(); + pw_entry->setWidget( passwdEdit ); + } else { + passwdLabel = new TQLabel( passwdEdit, + func == Authenticate ? + i18n("&Password:") : + i18n("Current &password:"), + parent ); + if (pred) { + parent->setTabOrder( pred, passwdEdit ); + pred = passwdEdit; + } + grid->addWidget( passwdLabel, line, 0 ); + grid->addWidget( passwdEdit, line++, 1 ); + } + + if (loginEdit) + loginEdit->setFocus(); + else + passwdEdit->setFocus(); + } + if (func != Authenticate) { + if (echoMode == -1) { + passwd1Edit = new TDMPasswordEdit( (KPasswordEdit::EchoModes)echoMode, parent ); + passwd2Edit = new TDMPasswordEdit( (KPasswordEdit::EchoModes)echoMode, parent ); + } else { + passwd1Edit = new TDMPasswordEdit( parent ); + passwd2Edit = new TDMPasswordEdit( parent ); + } + passwd1Label = new TQLabel( passwd1Edit, i18n("&New password:"), parent ); + passwd2Label = new TQLabel( passwd2Edit, i18n("Con&firm password:"), parent ); + if (pred) { + parent->setTabOrder( pred, passwd1Edit ); + parent->setTabOrder( passwd1Edit, passwd2Edit ); + } + if (grid) { + grid->addWidget( passwd1Label, line, 0 ); + grid->addWidget( passwd1Edit, line++, 1 ); + grid->addWidget( passwd2Label, line, 0 ); + grid->addWidget( passwd2Edit, line, 1 ); + } + if (!passwdEdit) + passwd1Edit->setFocus(); + } +} + +// virtual +KWinbindGreeter::~KWinbindGreeter() +{ + abort(); + if (!layoutItem) { + delete loginEdit; + delete passwdEdit; + delete domainCombo; + return; + } + TQLayoutIterator it = TQT_TQLAYOUT(layoutItem)->iterator(); + for (TQLayoutItem *itm = it.current(); itm; itm = ++it) + delete itm->widget(); + delete layoutItem; + delete m_domainLister; +} + +void +KWinbindGreeter::slotChangedDomain( const TQString &dom ) +{ + if (!loginEdit->completionObject()) + return; + TQStringList users; + if (dom == "") { + for (TQStringList::ConstIterator it = allUsers.begin(); it != allUsers.end(); ++it) + if ((*it).find( separator ) < 0) + users << *it; + } else { + TQString st( dom + separator ); + for (TQStringList::ConstIterator it = allUsers.begin(); it != allUsers.end(); ++it) + if ((*it).startsWith( st )) + users << (*it).mid( st.length() ); + } + loginEdit->completionObject()->setItems( users ); +} + +void // virtual +KWinbindGreeter::loadUsers( const TQStringList &users ) +{ + allUsers = users; + KCompletion *userNamesCompletion = new KCompletion; + loginEdit->setCompletionObject( userNamesCompletion ); + loginEdit->setAutoDeleteCompletionObject( true ); + loginEdit->setCompletionMode( KGlobalSettings::CompletionAuto ); + slotChangedDomain( defaultDomain ); +} + +void // virtual +KWinbindGreeter::presetEntity( const TQString &entity, int field ) +{ + TQString dom, usr; + splitEntity( entity, dom, usr ); + domainCombo->setCurrentItem( dom, true ); + slotChangedDomain( dom ); + loginEdit->setText( usr ); + if (field > 1) + passwdEdit->setFocus(); + else if (field == 1 || field == -1) { + if (field == -1) { + passwdEdit->setText( " " ); + passwdEdit->setEnabled( false ); + authTok = false; + } + loginEdit->setFocus(); + loginEdit->selectAll(); + } + curUser = entity; +} + +TQString // virtual +KWinbindGreeter::getEntity() const +{ + TQString dom, usr; + if (fixedUser.isEmpty()) + dom = domainCombo->currentText(), usr = loginEdit->text(); + else + dom = fixedDomain, usr = fixedUser; + return dom == "" ? usr : dom + separator + usr; +} + +void // virtual +KWinbindGreeter::setUser( const TQString &user ) +{ + // assert (fixedUser.isEmpty()); + curUser = user; + TQString dom, usr; + splitEntity( user, dom, usr ); + domainCombo->setCurrentItem( dom, true ); + slotChangedDomain( dom ); + loginEdit->setText( usr ); + passwdEdit->setFocus(); + passwdEdit->selectAll(); +} + +void // virtual +KWinbindGreeter::setPassword( const TQString &pass ) +{ + passwdEdit->erase(); + passwdEdit->insert( pass ); +} + +void // virtual +KWinbindGreeter::setEnabled( bool enable ) +{ + // assert( !passwd1Label ); + // assert( func == Authenticate && ctx == Shutdown ); +// if (domainCombo) +// domainCombo->setEnabled( enable ); +// if (loginLabel) +// loginLabel->setEnabled( enable ); + passwdLabel->setEnabled( enable ); + setActive( enable ); + if (enable) + passwdEdit->setFocus(); +} + +void // private +KWinbindGreeter::returnData() +{ + switch (exp) { + case 0: + handler->gplugReturnText( getEntity().local8Bit(), + KGreeterPluginHandler::IsUser ); + break; + case 1: + handler->gplugReturnText( passwdEdit->password(), + KGreeterPluginHandler::IsPassword | + KGreeterPluginHandler::IsSecret ); + break; + case 2: + handler->gplugReturnText( passwd1Edit->password(), + KGreeterPluginHandler::IsSecret ); + break; + default: // case 3: + handler->gplugReturnText( passwd2Edit->password(), + KGreeterPluginHandler::IsNewPassword | + KGreeterPluginHandler::IsSecret ); + break; + } +} + +bool // virtual +KWinbindGreeter::textMessage( const char *text, bool err ) +{ + if (!err && + TQString( text ).find( TQRegExp( "^Changing password for [^ ]+$" ) ) >= 0) + return true; + return false; +} + +void // virtual +KWinbindGreeter::textPrompt( const char *prompt, bool echo, bool nonBlocking ) +{ + pExp = exp; + if (echo) + exp = 0; + else if (!authTok) + exp = 1; + else { + TQString pr( prompt ); + if (pr.find( TQRegExp( "\\b(old|current)\\b", false ) ) >= 0) { + handler->gplugReturnText( "", + KGreeterPluginHandler::IsOldPassword | + KGreeterPluginHandler::IsSecret ); + return; + } else if (pr.find( TQRegExp( "\\b(re-?(enter|type)|again|confirm|repeat)\\b", + false ) ) >= 0) + exp = 3; + else if (pr.find( TQRegExp( "\\bnew\\b", false ) ) >= 0) + exp = 2; + else { + handler->gplugMsgBox( TQMessageBox::Critical, + i18n("Unrecognized prompt \"%1\"") + .arg( prompt ) ); + handler->gplugReturnText( 0, 0 ); + exp = -1; + return; + } + } + + if (pExp >= 0 && pExp >= exp) { + revive(); + has = -1; + } + + if (has >= exp || nonBlocking) + returnData(); +} + +bool // virtual +KWinbindGreeter::binaryPrompt( const char *, bool ) +{ + // this simply cannot happen ... :} + return true; +} + +void // virtual +KWinbindGreeter::start() +{ + authTok = !(passwdEdit && passwdEdit->isEnabled()); + exp = has = -1; + running = true; +} + +void // virtual +KWinbindGreeter::suspend() +{ +} + +void // virtual +KWinbindGreeter::resume() +{ +} + +void // virtual +KWinbindGreeter::next() +{ + // assert( running ); + if (domainCombo && domainCombo->hasFocus()) + loginEdit->setFocus(); + else if (loginEdit && loginEdit->hasFocus()) { + passwdEdit->setFocus(); // will cancel running login if necessary + has = 0; + } else if (passwdEdit && passwdEdit->hasFocus()) { + if (passwd1Edit) + passwd1Edit->setFocus(); + has = 1; + } else if (passwd1Edit) { + if (passwd1Edit->hasFocus()) { + passwd2Edit->setFocus(); + has = 1; // sic! + } else + has = 3; + } else + has = 1; + if (exp < 0) + handler->gplugStart(); + else if (has >= exp) + returnData(); +} + +void // virtual +KWinbindGreeter::abort() +{ + running = false; + if (exp >= 0) { + exp = -1; + handler->gplugReturnText( 0, 0 ); + } +} + +void // virtual +KWinbindGreeter::succeeded() +{ + // assert( running || timed_login ); + if (!authTok) { + setActive( false ); + if (passwd1Edit) { + authTok = true; + return; + } + } else + setActive2( false ); + exp = -1; + running = false; +} + +void // virtual +KWinbindGreeter::failed() +{ + // assert( running || timed_login ); + setActive( false ); + setActive2( false ); + exp = -1; + running = false; +} + +void // virtual +KWinbindGreeter::revive() +{ + // assert( !running ); + setActive2( true ); + if (authTok) { + passwd1Edit->erase(); + passwd2Edit->erase(); + passwd1Edit->setFocus(); + } else { + passwdEdit->erase(); + if (loginEdit && loginEdit->isEnabled()) + passwdEdit->setEnabled( true ); + else { + setActive( true ); + if (loginEdit && loginEdit->text().isEmpty()) + loginEdit->setFocus(); + else + passwdEdit->setFocus(); + } + } +} + +void // virtual +KWinbindGreeter::clear() +{ + // assert( !running && !passwd1Edit ); + passwdEdit->erase(); + if (loginEdit) { + domainCombo->setCurrentItem( defaultDomain ); + slotChangedDomain( defaultDomain ); + loginEdit->clear(); + loginEdit->setFocus(); + curUser = TQString::null; + } else + passwdEdit->setFocus(); +} + + +// private + +void +KWinbindGreeter::setActive( bool enable ) +{ + if (domainCombo) + domainCombo->setEnabled( enable ); + if (loginEdit) + loginEdit->setEnabled( enable ); + if (passwdEdit) + passwdEdit->setEnabled( enable ); +} + +void +KWinbindGreeter::setActive2( bool enable ) +{ + if (passwd1Edit) { + passwd1Edit->setEnabled( enable ); + passwd2Edit->setEnabled( enable ); + } +} + +void +KWinbindGreeter::slotLoginLostFocus() +{ + if (!running) + return; + TQString ent( getEntity() ); + if (exp > 0) { + if (curUser == ent) + return; + exp = -1; + handler->gplugReturnText( 0, 0 ); + } + curUser = ent; + handler->gplugSetUser( curUser ); +} + +void +KWinbindGreeter::slotActivity() +{ + if (running) + handler->gplugActivity(); +} + +void +KWinbindGreeter::slotStartDomainList() +{ + mDomainListTimer.stop(); + mDomainListing.clear(); + + m_domainLister = new KProcIO; + connect(m_domainLister, TQT_SIGNAL(readReady(KProcIO*)), TQT_SLOT(slotReadDomainList())); + connect(m_domainLister, TQT_SIGNAL(processExited(KProcess*)), TQT_SLOT(slotEndDomainList())); + + (*m_domainLister) << "wbinfo" << "--own-domain" << "--trusted-domains"; + m_domainLister->setComm (KProcess::Stdout); + m_domainLister->start(); +} + +void +KWinbindGreeter::slotReadDomainList() +{ + TQString line; + + while ( m_domainLister->readln( line ) != -1 ) { + mDomainListing.append(line); + } +} + +void +KWinbindGreeter::slotEndDomainList() +{ + delete m_domainLister; + m_domainLister = 0; + + TQStringList domainList; + domainList = staticDomains; + + for (TQStringList::const_iterator it = mDomainListing.begin(); + it != mDomainListing.end(); ++it) { + + if (!domainList.contains(*it)) + domainList.append(*it); + } + + TQString current = domainCombo->currentText(); + + for (int i = 0; i < domainList.count(); ++i) { + if (i < domainCombo->count()) + domainCombo->changeItem(domainList[i], i); + else + domainCombo->insertItem(domainList[i], i); + } + + while (domainCombo->count() > domainList.count()) + domainCombo->removeItem(domainCombo->count()-1); + + domainCombo->setCurrentItem( current ); + + if (domainCombo->currentText() != current) + domainCombo->setCurrentItem( defaultDomain ); + + mDomainListTimer.start(5 * 1000); +} + +// factory + +static bool init( const TQString &, + TQVariant (*getConf)( void *, const char *, const TQVariant & ), + void *ctx ) +{ + echoMode = getConf( ctx, "EchoMode", TQVariant( -1 ) ).toInt(); + staticDomains = TQStringList::split( ':', getConf( ctx, "winbind.Domains", TQVariant( "" ) ).toString() ); + if (!staticDomains.contains("")) + staticDomains << ""; + + defaultDomain = getConf( ctx, "winbind.DefaultDomain", TQVariant( staticDomains.first() ) ).toString(); + TQString sepstr = getConf( ctx, "winbind.Separator", TQVariant( TQString::null ) ).toString(); + if (sepstr.isNull()) { + FILE *sepfile = popen( "wbinfo --separator 2>/dev/null", "r" ); + if (sepfile) { + TQTextIStream( sepfile ) >> sepstr; + if (pclose( sepfile )) + sepstr = "\\"; + } else + sepstr = "\\"; + } + separator = sepstr[0].latin1(); + KGlobal::locale()->insertCatalogue( "kgreet_winbind" ); + return true; +} + +static void done( void ) +{ + KGlobal::locale()->removeCatalogue( "kgreet_winbind" ); + // avoid static deletion problems ... hopefully + staticDomains.clear(); + defaultDomain = TQString::null; +} + +static KGreeterPlugin * +create( KGreeterPluginHandler *handler, KdmThemer *themer, + TQWidget *parent, TQWidget *predecessor, + const TQString &fixedEntity, + KGreeterPlugin::Function func, + KGreeterPlugin::Context ctx ) +{ + return new KWinbindGreeter( handler, themer, parent, predecessor, fixedEntity, func, ctx ); +} + +KDE_EXPORT kgreeterplugin_info kgreeterplugin_info = { + I18N_NOOP("Winbind / Samba"), "classic", + kgreeterplugin_info::Local | kgreeterplugin_info::Fielded | kgreeterplugin_info::Presettable, + init, done, create +}; + +#include "kgreet_winbind.moc" diff --git a/tdmlib/kgreet_winbind.h b/tdmlib/kgreet_winbind.h new file mode 100644 index 000000000..54f2653fc --- /dev/null +++ b/tdmlib/kgreet_winbind.h @@ -0,0 +1,101 @@ +/* + +Conversation widget for tdm greeter + +Copyright (C) 1997, 1998 Steffen Hansen +Copyright (C) 2000-2003 Oswald Buddenhagen + + +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. + +*/ + + +#ifndef KGREET_WINBIND_H +#define KGREET_WINBIND_H + +#include "kgreeterplugin.h" + +#include +#include + +class KComboBox; +class KLineEdit; +class KPasswordEdit; +class KSimpleConfig; +class TQGridLayout; +class TQLabel; +class KdmThemer; +class KProcIO; + +class KWinbindGreeter : public TQObject, public KGreeterPlugin { + Q_OBJECT + + public: + KWinbindGreeter( KGreeterPluginHandler *handler, + KdmThemer *themer, + TQWidget *parent, TQWidget *predecessor, + const TQString &fixedEntitiy, + Function func, Context ctx ); + ~KWinbindGreeter(); + virtual void loadUsers( const TQStringList &users ); + virtual void presetEntity( const TQString &entity, int field ); + virtual TQString getEntity() const; + virtual void setUser( const TQString &user ); + virtual void setPassword( const TQString &pass ); + virtual void setEnabled( bool on ); + virtual bool textMessage( const char *message, bool error ); + virtual void textPrompt( const char *prompt, bool echo, bool nonBlocking ); + virtual bool binaryPrompt( const char *prompt, bool nonBlocking ); + virtual void start(); + virtual void suspend(); + virtual void resume(); + virtual void next(); + virtual void abort(); + virtual void succeeded(); + virtual void failed(); + virtual void revive(); + virtual void clear(); + + public slots: + void slotLoginLostFocus(); + void slotChangedDomain( const TQString &dom ); + void slotActivity(); + void slotStartDomainList(); + void slotReadDomainList(); + void slotEndDomainList(); + + private: + void setActive( bool enable ); + void setActive2( bool enable ); + void returnData(); + + TQLabel *domainLabel, *loginLabel, *passwdLabel, *passwd1Label, *passwd2Label; + KComboBox *domainCombo; + KLineEdit *loginEdit; + KPasswordEdit *passwdEdit, *passwd1Edit, *passwd2Edit; + KSimpleConfig *stsFile; + TQString fixedDomain, fixedUser, curUser; + TQStringList allUsers, mDomainListing; + KProcIO* m_domainLister; + TQTimer mDomainListTimer; + + Function func; + Context ctx; + int exp, pExp, has; + bool running, authTok; +}; + +#endif /* KGREET_WINBIND_H */ diff --git a/tdmlib/kgreeterplugin.h b/tdmlib/kgreeterplugin.h new file mode 100644 index 000000000..edf67f141 --- /dev/null +++ b/tdmlib/kgreeterplugin.h @@ -0,0 +1,407 @@ +/* + + Authentication method specific conversation plugin for KDE's greeter widgets + + Copyright (C) 2003 Oswald Buddenhagen + Copyright (C) 2003 Fabian Kaiser + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KGREETERPLUGIN_H +#define KGREETERPLUGIN_H + +#include +#include +#include + +class KdmThemer; + +class TQWidget; +class TQLayoutItem; + +class KGreeterPluginHandler { +public: + /* keep in sync with V_IS_* */ + enum { IsSecret = 1, IsUser = 2, IsPassword = 4, IsOldPassword = 8, + IsNewPassword = 16 }; + /** + * Reply to textPrompt(). + * @param text text to return to core; null to abort auth cycle + * @param tag zero or one of Is* + */ + virtual void gplugReturnText( const char *text, int tag ) = 0; + /** + * Reply to binaryPrompt(). + * @param data data in pam_client format to return to the core; + * null to abort auth cycle + */ + virtual void gplugReturnBinary( const char *data ) = 0; + /** + * Tell the greeter who is logging in. + * Call this preferably before gplugStart, as otherwise the .dmrc + * load will be delayed. Don't call at all if your plugin doesn't + * have the Local flag set. Call only for internally generated + * user changes. + * @param user the user logging in + */ + virtual void gplugSetUser( const TQString &user ) = 0; + /** + * Start processing. + */ + virtual void gplugStart() = 0; + /** + * Plugins that expect user input from a different device than the mouse or + * keyboard must call this when user activity is detected to prevent the + * greeter from resetting/going away. Events should be compressed to no + * more than ten per second; one every five seconds is actually enough. + * Events should be actual changes to the input fields, not random motion. + */ + virtual void gplugActivity() = 0; + /** + * Show a message box on behalf of the talker. + * @param type message severity + * @param text message text + */ + virtual void gplugMsgBox( TQMessageBox::Icon type, const TQString &text ) = 0; +}; + +/** + * Abstract base class for conversation plugins ("talkers") to be used with + * TDM, kdesktop_lock, etc. + * The authentication method used by a particular instance of a plugin + * may be configurable, but the instance must handle exactly one method, + * i.e., info->method must be determined at the latest at init() time. + */ +class KGreeterPlugin { +public: + KGreeterPlugin( KGreeterPluginHandler *h ) : handler( h ) {} + virtual ~KGreeterPlugin() {} + + /** + * Variations of the talker: + * - Authenticate: authentication + * - AuthChAuthTok: authentication and password change + * - ChAuthTok: password change + */ + enum Function { Authenticate, AuthChAuthTok, ChAuthTok }; + + /** + * Contexts the talker can be used in: + * - Login: tdm login dialog + * - Shutdown: tdm shutdown dialog + * - Unlock: tdm unlock dialog (TODO) + * - ChangeTok: tdm password change dialog (TODO) + * - ExUnlock: kdesktop_lock unlock dialog + * - ExChangeTok: kdepasswd password change dialog (TODO) + * + * The Ex* contexts exist within a running session; the talker must know + * how to obtain the currently logged in user (+ domain/realm, etc.) + * itself (i.e., fixedEntity will be null). The non-Ex variants will have + * a fixedEntity passed in. + */ + enum Context { Login, Shutdown, Unlock, ChangeTok, + ExUnlock, ExChangeTok }; + + /** + * Provide the talker with a list of selectable users. This can be used + * for autocompletion, etc. + * Will be called only when not running. + * @param users the users to load. + */ + virtual void loadUsers( const TQStringList &users ) = 0; + + /** + * Preload the talker with an (opaque to the greeter) entity. + * Will be called only when not running. + * @param entity the entity to preload the talker with. That + * will usually be something like "user" or "user@domain". + * @param field the sub-widget (probably line edit) to put the cursor into. + * If -1, preselect the user for timed login. This means pre-filling + * the password field with anything, disabling it, and placing the + * cursor in the user name field. + */ + virtual void presetEntity( const TQString &entity, int field ) = 0; + + /** + * Obtain the actually logged in entity. + * Will be called only after succeeded() was called. + */ + virtual TQString getEntity() const = 0; + + /** + * "Push" a user into the talker. That can be a click into the user list + * or successful authentication without the talker calling gplugSetUser. + * Will be called only when running. + * @param user the user to set. Note that this is a UNIX login, not a + * canonical entity + */ + virtual void setUser( const TQString &user ) = 0; + + /** + * "Push" a password into the talker. + * @param pass the password to set. + */ + virtual void setPassword( const TQString &pass ) = 0; + + /** + * En-/disable any widgets contained in the talker. + * Will be called only when not running. + * @param on the state to set + */ + virtual void setEnabled( bool on ) = 0; + + /** + * Called when a message from the authentication backend arrives. + * @param message the message received from the backend + * @param error if true, @p message is an error message, otherwise it's + * an informational message + * @return true means that the talker already handled the message, false + * that the greeter should display it in a message box + * + * FIXME: Filtering a message usually means that the backend issued a + * prompt and obtains the authentication data itself. However, in that + * state the backend is unresponsive, e.g., no shutdown is possible. + * The frontend could send the backend a signal, but the "escape path" + * within the backend is unclear (PAM won't like simply longjmp()ing + * out of it). + */ + virtual bool textMessage( const char *message, bool error ) = 0; + + /** + * Prompt the user for data. Reply by calling handler->gplugReturnText(). + * @param propmt the prompt to display. It may be null, in which case + * "Username"/"Password" should be shown and the replies should be tagged + * with the respective Is* flag. + * @param echo if true, a normal input widget can be used, otherwise one that + * visually obscures the user's input. + * @param nonBlocking if true, report whatever is already available, + * otherwise wait for user input. + */ + virtual void textPrompt( const char *prompt, bool echo, bool nonBlocking ) = 0; + + /** + * Request binary authentication data from the talker. Reply by calling + * handler->gplugReturnBinary(). + * @param prompt prompt in pam_client format + * @param nonBlocking if true, report whatever is already available, + * otherwise wait for user input. + * @return always true for now + * + * TODO: + * @return if true, the prompt was handled by the talker, otherwise the + * handler has to use libpam_client to obtain the authentication data. + * In that state the talker still can abort the data fetch by + * gplugReturn()ing a null array. When the data was obtained, another + * binaryPrompt with a null prompt will be issued. + */ + virtual bool binaryPrompt( const char *prompt, bool nonBlocking ) = 0; + + /** + * This can either + * - Start a processing cycle. Will be called only when not running. + * - Restart authTok cycle - will be called while running and implies + * revive(). PAM is a bit too clever, so we need this. + * In any case the talker is running afterwards. + */ + virtual void start() = 0; + + /** + * Request to suspend the auth. Make sure that a second talker of any + * type will be able to operate while this one is suspended (no busy + * device nodes, etc.). + * Will be called only if running within Login context. (Actually it + * won't be called at all, but be prepared.) + */ + virtual void suspend() = 0; + + /** + * Request to resume the auth from the point it was suspended at. + * Will be called only when suspended. + */ + virtual void resume() = 0; + + /** + * The "login" button was pressed in the greeter. + * This might call gplugReturn* or gplugStart. + * Will be called only when running. + */ + virtual void next() = 0; + + /** + * Abort auth cycle. Note that this should _not_ clear out already + * entered auth tokens if they are still on the screen. + * Will be called only when running and stops it. + */ + virtual void abort() = 0; + + /** + * Indicate successful end of the current phase. + * This is more or less a request to disable editable widgets + * responsible for the that phase. + * There will be no further attempt to enter that phase until the + * widget is destroyed. + * Will be called only when running and stops it. + */ + virtual void succeeded() = 0; + + /** + * Indicate unsuccessful end of the current phase. + * This is mostly a request to disable all editable widgets. + * The widget will be treated as dead until revive() is called. + * Will be called only when running and stops it. + */ + virtual void failed() = 0; + + /** + * Prepare retrying the previously failed phase. + * This is mostly a request to re-enable all editable widgets failed() + * disabled previously, clear the probably incorrect authentication tokens + * and to set the input focus appropriately. + * Will be called only after failed() (possibly with clear() in between), + * or after presetEntity() with field -1. + */ + virtual void revive() = 0; + + /** + * Clear any edit widgets, particularily anything set by setUser. + * Will be called only when not running. + */ + virtual void clear() = 0; + + /** + * Obtain the TQLayoutItem containg the widget(s) to actually handle the + * conversation. See TQLayout and TQWidgetItem for possible implementations. + */ + TQLayoutItem *getLayoutItem() const { return layoutItem; } + +protected: + KGreeterPluginHandler *handler; + TQLayoutItem *layoutItem; +}; + +struct KDE_EXPORT kgreeterplugin_info { + /** + * Human readable name of this plugin (should be a little more + * informative than just the libary name). Must be I18N_NOOP()ed. + */ + const char *name; + + /** + * The authentication method to use - the meaning is up to the backend, + * but will usually be related to the PAM service. + */ + const char *method; + + /** + * Capabilities. + */ + enum { + /** + * All users exist on the local system permanently (will be listed + * by getpwent()); an entity corresponds to a UNIX user. + */ + Local = 1, + /** + * The entities consist of multiple fields. + * PluginOptions/.FocusField is used instead of FocusPasswd. + */ + Fielded = 2, + /** + * An entity can be preset, the talker has a widget where a user can + * be selected explicitly. If the method is "classic", timed login + * is possible, too. + * This also means that setUser/gplugSetUser can be used and a + * userlist can be shown at all - provided Local is set as well. + */ + Presettable = 4 + }; + + /* + * Capability flags. + */ + int flags; + + /** + * Call after loading the plugin. + * + * @param method if non-empty and the plugin is unable to handle that + * method, return false. If the plugin has a constant method defined + * above, it can ignore this parameter. + * @param getConf can be used to obtain configuration items from the + * greeter; you have to pass it the @p ctx pointer. + * The only predefined key (in TDM) is "EchoMode", which is an int + * (in fact, KPasswordEdit::EchoModes). + * Other keys are obtained from the PluginOptions option; see tdmrc + * for details. + * If the key is unknown, dflt is returned. + * @param ctx context pointer for @p getConf + * @return if false, unload the plugin again (don't call done() first) + */ + bool (*init)( const TQString &method, + TQVariant (*getConf)( void *ctx, const char *key, + const TQVariant &dflt ), + void *ctx ); + + /** + * Call before unloading the plugin. + * This pointer can be null. + */ + void (*done)( void ); + + /** + * Factory method to create an instance of the plugin. + * Note that multiple instances can exist at one time, but only + * one of them is active at any moment (the others would be suspended + * or not running at all). + * @param handler the object offering the necessary callbacks + * @param parent parent widget + * @param predecessor the focus widget before the conversation widget + * @param fixedEntity see below + * @param func see below + * @param ctx see below + * @return an instance of this conversation plugin + * + * Valid combinations of Function and Context: + * - Authenticate:Login - init + * - Authenticate:Shutdown - init, for now "root" is passed as fixedEntitiy + * and it is not supposed to be displayed. Plugins with Local not set + * might have to conjure something up to make getEntity() return a + * canonical entitiy. FIXME: don't restrict shutdown to root. + * - AuthChAuthTok:Login, AuthChAuthTok:Shutdown - cont/cont, + * only relevant for classic method (as it is relevant only for password- + * less logins, which always use classic). The login should not be shown - + * it is known to the user already; the backend won't ask for it, either. + * - ChAuthTok:Login & ChAuthTok:Shutdown - cont + * - Authenticate:Unlock & Authenticate:ExUnlock - init, + * AuthChAuthTok:ChangeTok & AuthChAuthTok:ExChangeTok - init/cont, + * display fixedEntity as labels. The backend does not ask for the UNIX + * login, as it already knows it - but it will ask for all components of + * the entity if it is no UNIX login. + * + * "init" means that the plugin is supposed to call gplugStart, "cont" + * that the backend is already in a cycle of the method the plugin was + * initialized with. + */ + KGreeterPlugin *(*create)( KGreeterPluginHandler *handler, + KdmThemer *themer, + TQWidget *parent, TQWidget *predecessor, + const TQString &fixedEntity, + KGreeterPlugin::Function func, + KGreeterPlugin::Context ctx ); +}; + +#endif diff --git a/tdmlib/tdmtsak.cpp b/tdmlib/tdmtsak.cpp new file mode 100644 index 000000000..18acd05d2 --- /dev/null +++ b/tdmlib/tdmtsak.cpp @@ -0,0 +1,180 @@ +/* + This file is part of the TDE project + Copyright (C) 2011 Timothy Pearson + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "tdmtsak.h" + +#include + +#define FIFO_FILE "/tmp/ksocket-global/tsak" + +TQString exec(const char * cmd) { + FILE* pipe = popen(cmd, "r"); + if (!pipe) return "ERROR"; + char buffer[128]; + TQString result = ""; + while(!feof(pipe)) { + if(fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + return result; +} + +bool is_vt_local() { + const char * currentDisplay; + currentDisplay = getenv ("DISPLAY"); + if (currentDisplay == NULL) { + return false; + } + else { + TQString cvtName = ""; + TQString output = exec("tdmctl list"); + TQStringList sessionList = TQStringList::split('\t', output, false); + // See if the current session is local + for ( TQStringList::Iterator it = sessionList.begin(); it != sessionList.end(); ++it ) { + TQStringList sessionInfoList = TQStringList::split(',', *it, true); + if ((*(sessionInfoList.at(0))).startsWith(":")) { + if (TQString(currentDisplay).startsWith(*(sessionInfoList.at(0)))) { + return true; + } + } + } + // Not local + return false; + } +} + +bool is_vt_active() { + const char * currentDisplay; + currentDisplay = getenv ("DISPLAY"); + if (currentDisplay == NULL) { + return true; + } + else { + TQString cvtName = ""; + TQString output = exec("tdmctl list"); + TQString curConsole = exec("fgconsole"); + bool intFound; + int curConsoleNum = curConsole.toInt(&intFound); + if (intFound == false) { + return true; + } + curConsole = TQString("vt%1").arg(curConsoleNum);; + TQStringList sessionList = TQStringList::split('\t', output, false); + for ( TQStringList::Iterator it = sessionList.begin(); it != sessionList.end(); ++it ) { + TQStringList sessionInfoList = TQStringList::split(',', *it, true); + if ((*(sessionInfoList.at(0))).startsWith(":")) { + if ((*(sessionInfoList.at(1))) == TQString(curConsole)) { + cvtName = (*(sessionInfoList.at(0))); + } + } + } + if (cvtName != "") { + if (TQString(currentDisplay).startsWith(cvtName)) { + return true; + } + else { + return false; + } + } + else { + // See if the current session is local + // If it is, then the VT is not currently active and the SAK must be requested later when it is active + for ( TQStringList::Iterator it = sessionList.begin(); it != sessionList.end(); ++it ) { + TQStringList sessionInfoList = TQStringList::split(',', *it, true); + if ((*(sessionInfoList.at(0))).startsWith(":")) { + if (TQString(currentDisplay).startsWith(*(sessionInfoList.at(0)))) { + return false; + } + } + } + // Hmm, not local + // Do not reject the SAK + return true; + } + } +} + +int main (int argc, char *argv[]) +{ + int mPipe_fd; + char readbuf[128]; + int numread; + + int verifier_result = tde_sak_verify_calling_process(); + + bool isdm = false; + if (argc == 2) { + if (strcmp(argv[1], "dm") == 0) { + isdm = true; + } + } + + if (!isdm) { + // Verify that the session is local + // Remote sessions cannot press the SAK for obvious reasons + if (!is_vt_local()) { + return 6; // SAK not available + } + } + + if (verifier_result == 0) { + // OK, the calling process is authorized to retrieve SAK data + // First, flush the buffer + mPipe_fd = open(FIFO_FILE, O_RDONLY | O_NONBLOCK); + numread = 1; + while (numread > 0) { + numread = read(mPipe_fd, readbuf, 6); + } + close(mPipe_fd); + // Now wait for SAK press + mPipe_fd = open(FIFO_FILE, O_RDONLY); + while (mPipe_fd > -1) { + numread = read(mPipe_fd, readbuf, 6); + readbuf[numread] = 0; + readbuf[127] = 0; + if (strcmp(readbuf, "SAK\n\r") == 0) { + close(mPipe_fd); + if (is_vt_active()) { + return 0; + } + else { + usleep(100); + // Flush the buffer + mPipe_fd = open(FIFO_FILE, O_RDONLY | O_NONBLOCK); + numread = 1; + while (numread > 0) { + numread = read(mPipe_fd, readbuf, 6); + } + close(mPipe_fd); + mPipe_fd = open(FIFO_FILE, O_RDONLY); + } + } + else { + usleep(100); + } + } + close(mPipe_fd); + return 6; + } + else { + return verifier_result; + } +} \ No newline at end of file diff --git a/tdmlib/tdmtsak.h b/tdmlib/tdmtsak.h new file mode 100644 index 000000000..1987a8218 --- /dev/null +++ b/tdmlib/tdmtsak.h @@ -0,0 +1,144 @@ +/* + This file is part of the TDE project + Copyright (C) 2011 Timothy Pearson + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "config.h" + +// #define DEBUG + +inline int tde_sak_verify_calling_process() +{ + bool authorized = false; + + // Root always has access to everything... + if (getuid() == 0) { + return 0; + } + + pid_t parentproc = getppid(); +#ifdef DEBUG + printf("Parent pid is: %d\n\r", parentproc); +#endif + + char parentexecutable[8192]; + TQString procparent = TQString("/proc/%1/exe").arg(parentproc); + int chars = readlink(procparent.ascii(), parentexecutable, sizeof(parentexecutable)); + parentexecutable[chars] = 0; + parentexecutable[8191] = 0; + procparent = parentexecutable; +#ifdef DEBUG + printf("Parent executable name and full path is: %s\n\r", procparent.ascii()); +#endif + + TQString tdeBinaryPath = TQString(KDE_BINDIR "/"); +#ifdef DEBUG + printf("The TDE binary path is: %s\n\r", tdeBinaryPath.ascii()); +#endif + + if (!procparent.startsWith(tdeBinaryPath)) { + printf("Unauthorized path detected in calling process\n\r"); + return 2; + } + else { + procparent = procparent.mid(tdeBinaryPath.length()); +#ifdef DEBUG + printf("Parent executable name is: %s\n\r", procparent.ascii()); +#endif + if ((procparent == "kdesktop") || (procparent == "kdesktop_lock") || (procparent == "tdm")) { + authorized = true; + } + else if (procparent == "tdeinit") { + printf("tdeinit detected\n\r"); + // A bit more digging is needed to see if this is an authorized process or not + // Get the tdeinit command + char tdeinitcmdline[8192]; + FILE *fp = fopen(TQString("/proc/%1/cmdline").arg(parentproc).ascii(),"r"); + if (fp != NULL) { + if (fgets (tdeinitcmdline, 8192, fp) != NULL) + fclose (fp); + } + tdeinitcmdline[8191] = 0; + TQString tdeinitCommand = tdeinitcmdline; + + // Also get the environment, specifically the path + TQString tdeinitEnvironment; + char tdeinitenviron[8192]; + fp = fopen(TQString("/proc/%1/environ").arg(parentproc).ascii(),"r"); + if (fp != NULL) { + int c; + int pos = 0; + do { + c = fgetc(fp); + tdeinitenviron[pos] = c; + pos++; + if (c == 0) { + TQString curEnvLine = tdeinitenviron; + if (curEnvLine.startsWith("PATH=")) { + tdeinitEnvironment = curEnvLine.mid(5); + } + pos = 0; + } + } while ((c != EOF) && (pos < 8192)); + fclose (fp); + } + tdeinitenviron[8191] = 0; + +#ifdef DEBUG + printf("Called executable name is: %s\n\r", tdeinitCommand.ascii()); + printf("Environment is: %s\n\r", tdeinitEnvironment.ascii()); +#endif + + if ((tdeinitCommand == "kdesktop [tdeinit]") && (tdeinitEnvironment.startsWith(KDE_BINDIR))) { + authorized = true; + } + else { + return 4; + } + } + else { + printf("Unauthorized calling process detected\n\r"); + return 3; + } + + if (authorized == true) { + return 0; + } + } + + return 5; +} + +#undef DEBUG \ No newline at end of file -- cgit v1.2.1