diff options
author | Martin Peterson <mkp@src.gnome.org> | 1999-04-18 22:08:08 +0000 |
---|---|---|
committer | Martin Peterson <mkp@src.gnome.org> | 1999-04-18 22:08:08 +0000 |
commit | 48dfb0c6fc683eb0512074448bc4418ad8241e40 (patch) | |
tree | cf7b1a5029538937affbbfd917db176d524ed8f6 | |
download | gdm-48dfb0c6fc683eb0512074448bc4418ad8241e40.tar.gz |
Initial revision
-rw-r--r-- | .cvsignore | 29 | ||||
-rw-r--r-- | ABOUT-NLS | 226 | ||||
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | ChangeLog | 672 | ||||
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | NEWS | 0 | ||||
-rw-r--r-- | README | 64 | ||||
-rw-r--r-- | README.install | 23 | ||||
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | acconfig.h | 13 | ||||
-rw-r--r-- | acinclude.m4 | 389 | ||||
-rwxr-xr-x | autogen.sh | 17 | ||||
-rw-r--r-- | config/.cvsignore | 7 | ||||
-rwxr-xr-x | config/:0 | 2 | ||||
-rw-r--r-- | config/Default | 6 | ||||
-rwxr-xr-x | config/Gnome.in | 18 | ||||
-rw-r--r-- | config/Makefile.am | 75 | ||||
-rwxr-xr-x | config/Xsession | 41 | ||||
-rw-r--r-- | config/gdm | 8 | ||||
-rw-r--r-- | config/gdm.conf.in | 60 | ||||
-rw-r--r-- | config/gnomerc.in | 1 | ||||
-rw-r--r-- | config/locale.alias | 54 | ||||
-rw-r--r-- | configure.in | 108 | ||||
-rw-r--r-- | daemon/.cvsignore | 5 | ||||
-rw-r--r-- | daemon/Makefile.am | 30 | ||||
-rw-r--r-- | daemon/auth.c | 157 | ||||
-rw-r--r-- | daemon/cookie.c | 106 | ||||
-rw-r--r-- | daemon/filecheck.c | 120 | ||||
-rw-r--r-- | daemon/gdm.c | 626 | ||||
-rw-r--r-- | daemon/gdm.h | 86 | ||||
-rw-r--r-- | daemon/md5.c | 253 | ||||
-rw-r--r-- | daemon/md5.h | 27 | ||||
-rw-r--r-- | daemon/misc.c | 289 | ||||
-rw-r--r-- | daemon/server.c | 317 | ||||
-rw-r--r-- | daemon/slave.c | 615 | ||||
-rw-r--r-- | daemon/verify.c | 271 | ||||
-rw-r--r-- | daemon/xdmcp.c | 854 | ||||
-rw-r--r-- | docs/Makefile.am | 8 | ||||
-rw-r--r-- | docs/Makefile.in | 255 | ||||
-rw-r--r-- | docs/gdm-manual.txt | 352 | ||||
-rw-r--r-- | gdm.spec | 78 | ||||
-rw-r--r-- | gui/Makefile.am | 25 | ||||
-rw-r--r-- | gui/Makefile.in | 400 | ||||
-rw-r--r-- | gui/gdmchooser.c | 676 | ||||
-rw-r--r-- | gui/gdmchooser.h | 40 | ||||
-rw-r--r-- | gui/gdmgreeter.c | 1713 | ||||
-rw-r--r-- | gui/gdmgreeter.h | 35 | ||||
-rw-r--r-- | gui/gdmlogin.c | 1133 | ||||
-rw-r--r-- | pixmaps/.cvsignore | 2 | ||||
-rw-r--r-- | pixmaps/Makefile.am | 8 | ||||
-rw-r--r-- | pixmaps/gdm.xpm | 285 | ||||
-rw-r--r-- | pixmaps/nophoto.png | bin | 0 -> 6407 bytes | |||
-rw-r--r-- | po/.cvsignore | 9 | ||||
-rw-r--r-- | po/ChangeLog | 4 | ||||
-rw-r--r-- | po/Makefile.in.in | 248 | ||||
-rw-r--r-- | po/POTFILES.in | 11 | ||||
-rw-r--r-- | po/de.po | 865 | ||||
-rw-r--r-- | po/es.po | 954 | ||||
-rw-r--r-- | po/fr.po | 1012 | ||||
-rw-r--r-- | po/no.po | 949 |
60 files changed, 14640 insertions, 0 deletions
diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 00000000..9d2ec3c7 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,29 @@ +Makefile +Makefile.in +aclocal.m4 +config.cache +config.guess +config.h +config.h.in +config.log +config.status +config.sub +configure +configure.scan +libtool +ltconfig +ltmain.sh +missing +mkinstalldirs +stamp-h.in +stamp-h +stamp.h +install-sh +confdefs.h +INSTALL +COPYING +mkinstalldirs +missing +install-sh +stamp-h.in +stamp.h.in diff --git a/ABOUT-NLS b/ABOUT-NLS new file mode 100644 index 00000000..28d38c76 --- /dev/null +++ b/ABOUT-NLS @@ -0,0 +1,226 @@ +Notes on the Free Translation Project +************************************* + + Free software is going international! The Free Translation Project +is a way to get maintainers of free software, translators, and users all +together, so that will gradually become able to speak many languages. +A few packages already provide translations for their messages. + + If you found this `ABOUT-NLS' file inside a distribution, you may +assume that the distributed package does use GNU `gettext' internally, +itself available at your nearest GNU archive site. But you do *not* +need to install GNU `gettext' prior to configuring, installing or using +this package with messages translated. + + Installers will find here some useful hints. These notes also +explain how users should proceed for getting the programs to use the +available translations. They tell how people wanting to contribute and +work at translations should contact the appropriate team. + + When reporting bugs in the `intl/' directory or bugs which may be +related to internationalization, you should tell about the version of +`gettext' which is used. The information can be found in the +`intl/VERSION' file, in internationalized packages. + +One advise in advance +===================== + + If you want to exploit the full power of internationalization, you +should configure it using + + ./configure --with-included-gettext + +to force usage of internationalizing routines provided within this +package, despite the existence of internationalizing capabilities in the +operating system where this package is being installed. So far, only +the `gettext' implementation in the GNU C library version 2 provides as +many features (such as locale alias or message inheritance) as the +implementation here. It is also not possible to offer this additional +functionality on top of a `catgets' implementation. Future versions of +GNU `gettext' will very likely convey even more functionality. So it +might be a good idea to change to GNU `gettext' as soon as possible. + + So you need not provide this option if you are using GNU libc 2 or +you have installed a recent copy of the GNU gettext package with the +included `libintl'. + +INSTALL Matters +=============== + + Some packages are "localizable" when properly installed; the +programs they contain can be made to speak your own native language. +Most such packages use GNU `gettext'. Other packages have their own +ways to internationalization, predating GNU `gettext'. + + By default, this package will be installed to allow translation of +messages. It will automatically detect whether the system provides +usable `catgets' (if using this is selected by the installer) or +`gettext' functions. If neither is available, the GNU `gettext' own +library will be used. This library is wholly contained within this +package, usually in the `intl/' subdirectory, so prior installation of +the GNU `gettext' package is *not* required. Installers may use +special options at configuration time for changing the default +behaviour. The commands: + + ./configure --with-included-gettext + ./configure --with-catgets + ./configure --disable-nls + +will respectively bypass any pre-existing `catgets' or `gettext' to use +the internationalizing routines provided within this package, enable +the use of the `catgets' functions (if found on the locale system), or +else, *totally* disable translation of messages. + + When you already have GNU `gettext' installed on your system and run +configure without an option for your new package, `configure' will +probably detect the previously built and installed `libintl.a' file and +will decide to use this. This might be not what is desirable. You +should use the more recent version of the GNU `gettext' library. I.e. +if the file `intl/VERSION' shows that the library which comes with this +package is more recent, you should use + + ./configure --with-included-gettext + +to prevent auto-detection. + + By default the configuration process will not test for the `catgets' +function and therefore they will not be used. The reasons are already +given above: the emulation on top of `catgets' cannot provide all the +extensions provided by the GNU `gettext' library. If you nevertheless +want to use the `catgets' functions use + + ./configure --with-catgets + +to enable the test for `catgets' (this causes no harm if `catgets' is +not available on your system). If you really select this option we +would like to hear about the reasons because we cannot think of any +good one ourself. + + Internationalized packages have usually many `po/LL.po' files, where +LL gives an ISO 639 two-letter code identifying the language. Unless +translations have been forbidden at `configure' time by using the +`--disable-nls' switch, all available translations are installed +together with the package. However, the environment variable `LINGUAS' +may be set, prior to configuration, to limit the installed set. +`LINGUAS' should then contain a space separated list of two-letter +codes, stating which languages are allowed. + +Using This Package +================== + + As a user, if your language has been installed for this package, you +only have to set the `LANG' environment variable to the appropriate +ISO 639 `LL' two-letter code prior to using the programs in the +package. For example, let's suppose that you speak German. At the +shell prompt, merely execute `setenv LANG de' (in `csh'), +`export LANG; LANG=de' (in `sh') or `export LANG=de' (in `bash'). This +can be done from your `.login' or `.profile' file, once and for all. + + An operating system might already offer message localization for +many of its programs, while other programs have been installed locally +with the full capabilities of GNU `gettext'. Just using `gettext' +extended syntax for `LANG' would break proper localization of already +available operating system programs. In this case, users should set +both `LANGUAGE' and `LANG' variables in their environment, as programs +using GNU `gettext' give preference to `LANGUAGE'. For example, some +Swedish users would rather read translations in German than English for +when Swedish is not available. This is easily accomplished by setting +`LANGUAGE' to `sv:de' while leaving `LANG' to `sv'. + +Translating Teams +================= + + For the Free Translation Project to be a success, we need interested +people who like their own language and write it well, and who are also +able to synergize with other translators speaking the same language. +Each translation team has its own mailing list, courtesy of Linux +International. You may reach your translation team at the address +`LL@li.org', replacing LL by the two-letter ISO 639 code for your +language. Language codes are *not* the same as the country codes given +in ISO 3166. The following translation teams exist, as of December +1997: + + Chinese `zh', Czech `cs', Danish `da', Dutch `nl', English `en', + Esperanto `eo', Finnish `fi', French `fr', German `de', Hungarian + `hu', Irish `ga', Italian `it', Indonesian `id', Japanese `ja', + Korean `ko', Latin `la', Norwegian `no', Persian `fa', Polish + `pl', Portuguese `pt', Russian `ru', Slovenian `sl', Spanish `es', + Swedish `sv', and Turkish `tr'. + +For example, you may reach the Chinese translation team by writing to +`zh@li.org'. + + If you'd like to volunteer to *work* at translating messages, you +should become a member of the translating team for your own language. +The subscribing address is *not* the same as the list itself, it has +`-request' appended. For example, speakers of Swedish can send a +message to `sv-request@li.org', having this message body: + + subscribe + + Keep in mind that team members are expected to participate +*actively* in translations, or at solving translational difficulties, +rather than merely lurking around. If your team does not exist yet and +you want to start one, or if you are unsure about what to do or how to +get started, please write to `translation@iro.umontreal.ca' to reach the +coordinator for all translator teams. + + The English team is special. It works at improving and uniformizing +the terminology in use. Proven linguistic skill are praised more than +programming skill, here. + +Available Packages +================== + + Languages are not equally supported in all packages. The following +matrix shows the current state of internationalization, as of December +1997. The matrix shows, in regard of each package, for which languages +PO files have been submitted to translation coordination. + + Ready PO files cs da de en es fi fr it ja ko nl no pl pt ru sl sv + .----------------------------------------------------. + bash | [] [] [] | 3 + bison | [] [] [] | 3 + clisp | [] [] [] [] | 4 + cpio | [] [] [] [] [] [] | 6 + diffutils | [] [] [] [] [] | 5 + enscript | [] [] [] [] [] [] | 6 + fileutils | [] [] [] [] [] [] [] [] [] [] | 10 + findutils | [] [] [] [] [] [] [] [] [] | 9 + flex | [] [] [] [] | 4 + gcal | [] [] [] [] [] | 5 + gettext | [] [] [] [] [] [] [] [] [] [] [] | 12 + grep | [] [] [] [] [] [] [] [] [] [] | 10 + hello | [] [] [] [] [] [] [] [] [] [] [] | 11 + id-utils | [] [] [] | 3 + indent | [] [] [] [] [] | 5 + libc | [] [] [] [] [] [] [] | 7 + m4 | [] [] [] [] [] [] | 6 + make | [] [] [] [] [] [] | 6 + music | [] [] | 2 + ptx | [] [] [] [] [] [] [] [] | 8 + recode | [] [] [] [] [] [] [] [] [] | 9 + sh-utils | [] [] [] [] [] [] [] [] | 8 + sharutils | [] [] [] [] [] [] | 6 + tar | [] [] [] [] [] [] [] [] [] [] [] | 11 + texinfo | [] [] [] | 3 + textutils | [] [] [] [] [] [] [] [] [] | 9 + wdiff | [] [] [] [] [] [] [] [] | 8 + `----------------------------------------------------' + 17 languages cs da de en es fi fr it ja ko nl no pl pt ru sl sv + 27 packages 6 4 25 1 18 1 26 2 1 12 20 9 19 7 4 7 17 179 + + Some counters in the preceding matrix are higher than the number of +visible blocks let us expect. This is because a few extra PO files are +used for implementing regional variants of languages, or language +dialects. + + For a PO file in the matrix above to be effective, the package to +which it applies should also have been internationalized and +distributed as such by its maintainer. There might be an observable +lag between the mere existence a PO file and its wide availability in a +distribution. + + If December 1997 seems to be old, you may fetch a more recent copy +of this `ABOUT-NLS' file on most GNU archive sites. + diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..7c7f47a8 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Martin Kasper Petersen <mkp@SunSITE.auc.dk> diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..81550a68 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,672 @@ +1999-03-28 Martin Kasper Petersen <mkp@mkp.net> + + * gui/gdmgreeter.c (gdm_greeter_user_alloc): Icon size bug + reported by Clifford Wright. + +1999-03-07 Martin Kasper Petersen <mkp@mkp.net> + + * configure.in, src/Makefile.am: Pass -DGDM_CONFIG_PATH to + compiler to avoid ${prefix}/blah bug in Owen's patch. + +1999-03-06 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_user_alloc): Fixed a memory + corruption bug (Reported by Centove). + +1999-03-05 Martin Kasper Petersen <mkp@mkp.net> + + * gdm.spec: Fix spec file. + + * Misc fixes. + +1999-03-03 Martin Kasper Petersen <mkp@mkp.net> + + * config/Makefile.am, configure.in: Patch from Owen. + + * po/de.po: Added (Patch from Karsten Weiss + <karsten@addx.au.s.shuttle.de>). + +1999-02-26 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (main): Force completion mode on for the time + being. I'll implement a real PAM conversation function within the + next couple of days to take care of the exposed usernames issue. + +1999-02-25 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmchooser.c: Done! + + * src/gdmchooser.c: First shot at reimplementing the code I + lost. Doesn't actually work yet. + +1999-02-24 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmxdmcp.c: Fix gethostbyaddr() lookups. + + * src/gdmslave.c: Various fixes. + + * src/gdm.c (gdm_display_dispose): Call XCloseDisplay to close + remote connections. + + (gdm_child_handler): Fix wrong debug output. + + * config/Makefile.am: Create Default display init file. + +1999-02-23 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmverify.c (gdm_verify_user): Added shadow support (Patch + from Timo Sirainen). + + * src/gdmgreeter.c (main): Added GtkRC support + (Patch from Daniel_Burrows@brown.edu). + +1999-02-23 Miguel de Icaza <miguel@nuclecu.unam.mx> + + * src/gdmgreeter.c (main): Call gnome sound shutdown here. + + * src/gdm.c (main): Show a descriptive message to let the user + locate the stale pid file. + + * configure.in (LIBWRAP_PATH): Use the same configuration + mechanism for detecting a working libwrap library on the system + (fixes crash). + + * src/gdmslave.c (gdm_slave_greeter): Do not use sscanf to get the + password, as it might contain spaces, just copy the string. + (gdm_slave_get_opts): Use fgets directly on the target buffer. + (gdm_slave_get_opts): Make the strings empty at startup. + + * src/gdmgreeter.c (gdm_greeter_logo_init): Use gnome-pixmap + widget instead of gtk-pixmap. Gnome-pixmap correctly uses the + right visual and is simpler to use (and does not crash on + multidepth visuals). + (gdm_greeter_iconify_handler): Use gnome-pixmao here too. + +1999-02-16 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdm.c: Ignore invalid lines in [servers] section. + +1999-02-14 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmserver.c: Changed SA_ONESHOT to SA_RESETHAND. + +1999-02-08 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_parse_config): Disable shutdown + menu on non-local displays. + + * src/gdm.c (gdm_config_parse): Default path belongs in + [system] (msw). + + * src/gdmxdmcp.c (gdm_xdmcp_init): Use GIOChannel to monitor fds. + + * src/gdmmisc.c (gdm_parse_enriched_string): Support %d expansion + for display name. + +1999-02-06 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmxdmcp.c (gdm_xdmcp_send_accept): MIT cookies work for + remote displays now. + + * src/gdmslave.c: Lots of fixes. Should be stable again. + +1999-02-04 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c (gdm_slave_child_handler): Only xping remote + displays to avoid DISPLAY_ABORT for murdered greeters/Xservers. + + * src/gdmmisc.c (gdm_exec_script): Set default path before + executing. + +1999-02-03 Martin Kasper Petersen <mkp@mkp.net> + + * Makefile.am: Stuff the docs dir back in and add the appropriate + Makefile.am. + +1999-02-02 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c: Fixes for XDMCP vs. local display handling. + + * src/gdmxdmcp.c: Numerous fixes. + +1999-01-31 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmxdmcp.c: First shot at XDMCP implentation. + +1999-01-28 Martin Kasper Petersen <mkp@mkp.net> + + * configure.in/Makefile.am: Generate Makefile in docs. Added + README.install to EXTRA_DIST. + +1999-01-27 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_info): Fixed the annoying hanging + Gtk bug caused by my inability to program user interfaces. Ahem. + + * configure.in: Stuff GNOME_GETTEXT back in. + +1999-01-25 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c (gdm_slave_session_start): Moved english->C + locale here. Ugly, but it became a mess in greeter too. + + * src/gdmverify.c (gdm_verify_user): Repetetetive pam_setcred + spotted by gb. Fixed. + +1999-01-22 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmverify.c (gdm_verify_user): syslog ident workaround. + + * src/gdmgreeter.c (gdm_greeter_session_init): Used widget pointer + as session name if no default was found. Fixed. + + * src/gdm.c (gdm_display_unmanage): Avoid killing master daemon + when unmanaging displays. + + * src/gdmslave.c (gdm_slave_session_start): Added call to + initgroups() to set up additional group memberships. + + * src/gdmverify.c (gdm_verify_user): Fix non-PAM password + checking. + +1999-01-20 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmverify.c (gdm_verify_user): Updated PAM stuff. + +1999-01-19 Miguel de Icaza <miguel@nuclecu.unam.mx> + + * src/gdmslave.c (gdm_slave_session_start): Set the umask. + +1999-01-19 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmverify.c (gdm_verify_pam_conv): Quick workaround for PAM + stuff. Real solution due tomorrow. + + * src/gdmgreeter.c: Lots of new stuff. Non completion mode + deprecated. On demand NFS lookups. Language selection. + + * src/gdmslave.c (gdm_slave_greeter): New session/language + selection support. + +1999-01-18 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c (gdm_slave_session_start): Fixed memleak. + +1999-01-15 Miguel de Icaza <miguel@nuclecu.unam.mx> + + * src/gdmslave.c (gdm_slave_greeter): Check return values from + sscanf. Because "\n" scanned with %s returns -1 and the target + buffer has an undefined value. + + * src/gdm.c (main): Set the umask to 066 to make any + default file created indirectly by gnome-config be of mode 066. + +1999-01-13 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_sessions_init): Check that Session + scripts are executable before adding them to the list. + + * src/gdmmisc.c (gdm_file_check): Added an option making the + function return TRUE if it is ok that a file is absent. I.e. the + user has no existing .Xauthority, .gnome/gdm or whatever. + + * src/gdmslave.c (gdm_slave_session_start): Added default + path. Create ~user/.gnome if it doesn't exist. + + * src/gdmslave.c (gdm_slave_session_stop): More setegid(). + + * src/gdmslave.c (gdm_slave_session_start): Added setgid(). + (gdm_slave_greeter): Fixed sigmask. + + * src/gdmauth.c (gdm_auth_user_{add|remove}): Added -i to xauth to + ignore hanging locks. + + * src/gdmgreeter.c (main): Resize only when browser is enabled. + + * src/gdmgreeter.c (gdm_greeter_message_init): Removed debug msg. + + * src/gdm.c (gdm_config_parse): Bail out if gdm user/group doesn't + exist. Root failover made people lazy. + + * src/gdm.c (gdm_child_handler): Minor fix to make gdm work with + more than one local Xserver. + +1999-01-12 Martin Kasper Petersen <mkp@mkp.net> + + * config/gdm.conf.in ([system]): Added UserIconMax{Width,Height}. + + * src/gdmgreeter.c (gdm_greeter_user_alloc): Scales user icons to + sysadmin specified max size. + + * src/gdmgreeter.c (gdm_greeter_iconify_handler): Fixed + iconification bug. + + (gdm_greeter_login_key_handler): Cursor/Tab key restriction. + + * src/gdmslave.c (gdm_slave_greeter): Forgot to setgid() + + (gdm_slave_greeter): Workaround for getenv("HOME") until miguel + fixes gnome_init(). + + * src/gdmmisc.c (gdm_parse_enriched_string): Fallback if + getenv("HOSTNAME")==NULL. + +1999-01-11 Martin Kasper Petersen <mkp@mkp.net> + + * src/<younameit>.[ch] Done rewriting the daemon code to avoid the + race condition caused by simultaneous greeter/session and Xserver + death. + +1998-12-30 Jeff Garzik <jgarzik@pobox.com> + + * src/gdmauth.c, src/gdmgreeter.c, src/gdmmisc.c, + src/gdmslave.c, src/gdmxdmcp.c: + s/g_copy_strings/g_strconcat/ + +1998-12-28 Martin Kasper Petersen <mkp@mkp.net> + + * src/*.c: Loads of fixes over the past couple of days. + + * src/gdmgreeter.c (gdm_greeter_parse_config): gdmUserMaxFile + tunable. + + * src/gdmmisc.c (gdm_file_check): Moved gdm_greeter_file_check + here. Now a generic function. + + * src/gdmslave.c (gdm_slave_windows_kill_error_handler): Ok, + nailed down the bug which caused gdmslave to exit(1) + mysteriously. A race in the windows_recursive_kill function caused + the X default error handler to kick in. Blam. You're dead. + + (gdm_slave_session_init): Run sanity check on ~user/.Xauthority + and ~user/.gnome/gdm. + + (gdm_slave_exec_command): Use the passed pointer instead of + gdmSuspend. + + (gdm_slave_session_init): Added SHELL environment variable so the + user's shell is executed. Not just root's.. + +1998-12-25 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_user_alloc): Rewritten to use + sanity check. + + (gdm_greeter_file_check): New function. Checks file size, + ownership etc. to avoid DoS attacks on greeter. + +1998-12-23 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdm.c (gdm_abort): New function for error logging and + aborting. + + (gdm_config_parse): luser proof permissions checking on authdir. + + * src/gdmgreeter.c: Several oddities fixed. + + * src/gdmgreeter.c (gdm_greeter_buttons_init): Mark login button + as default. + + * src/gdmgreeter.c (gdm_greeter_login_entry_handler): Fixed event + handlers to avoid the obscure emit_stop bug. Turns out my ancient + event handlers were doing the right thing all along. Only the + recent ones were br0ked. *sigh*. Thanks Owen! + +1998-12-22 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c (gdm_slave_greet_init): Removed debug logging of + username and password. Ahem. Thanks Sopwith! + + * src/gdmgreeter.c (gdm_greeter_login_entry_handler): + Fixes. gtk_signal_emit_stop_by_name workaround. + +1998-12-20 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_invalid_passwd_req): Minor hack to + avoid greeter to be reactivated during dialog. + + * src/(gdm_greeter_entry_init): Limit input length in login and + password entry fields. + + * src/gdmslave.c (gdm_slave_greet_init): Avoid potential buffer + overflow, in case something/someone breaks greeter. + +1998-12-15 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmverify.c (gdm_verify_user): Two buglets reported by + <kvajk@ricochet.net>. + +1998-12-14 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_browser_unselect): Catch + BUTTON_RELEASE. + +1998-12-13 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_{reboot,halt}_handler): Use + gnome_question_dialog instead of message_box. + +1998-12-03 Martin Kasper Petersen <mkp@mkp.net> + + * config/Makefile.am: Fixed gnomerc. Both path and INSTALL_SCRIPT + were wrong -- No wonder people have been complaining. *sigh* + + * src/gdm.c (main): Abort with (xdm compliant :) error message if + gdm isn't started by root. + +1998-12-01 Martin Kasper Petersen <mkp@mkp.net> + + * docs/gdm-manual.txt: Crude manual draft. + + * src/gdm.c, config/gdm.conf.in: The PreRoot and PostRoot + directories have been renamed PreSession and PostSession to avoid + confusion. + +1998-11-30 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_message_init): Calls the enriched + string function on the message string to support ``Welcome to + <hostname>''. Need to supply both server and client macros. + + * src/gdmmisc.c (gdm_parse_enriched_string): New function for %h + expansion in strings. + + * src/gdmgreeter.c: Removed legacy labels and such. gettext takes + it from here. + + * src/gdm.c (gdm_config_parse): Check for correct permissions on + vardir. + +1998-11-29 Miguel de Icaza <miguel@nuclecu.unam.mx> + + * src/gdmgreeter.c (gdm_greeter_browser_init): IconList now starts + life in thawed mode. + +1998-11-22 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_browser_select): Reverted to the + old event types (GDK_BUTTON_PRESS) for gnome-icon-list. + + * src/gdmslave.c, src/gdmgreeter.c, src/gdm.c: Added support for + suspending APM-aware machines from greeter. + +1998-11-20 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c: Fixed X server restart stuff. gdmslave rewrite + done. + + * src/gdmslave.c, src/gdm.c, config/gdm.conf.in: Implemented + KillInitClients option (Requested by sct). + +1998-11-18 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c (gdm_slave_display_init): Finally nailed down the + bug that has been haunting me for the past week causing + gdm_slave_windows_kill to hang on second login. The X server takes + a while to recover consciousness after a reset. I take this into + account by sleeping for a while if XOpenDisplay fails. + Unfortunately, dsp was already initialized in second run + (but invalid after the X server reset) causing my retry condition + to be ignored. Always check your pointers! *sigh* + + So, the new gdm should be as fast as xdm (i.e. fewer resets + causing garbled displays and momentary flicker. Visual annoyances + beyond this point - Go bug the X server people). + + SANE tutorial coming up in 6 hours. *Thud* + +1998-11-09 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c More or less a rewrite. + +1998-11-08 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c (gdm_slave_init): Add d->name when starting X + server. + + * src/gdm.c (gdm_config_parse): Added intelligent AuthDir + searching and gdmLogDir. gdmLogFile deprecated. + + * src/gdmslave.c (gdm_slave_init): Moved stdout, stderr logging + here. Logs are now per-display. + +1998-11-08 Martin Kasper Petersen <mkp@mkp.net> + + * #include<errno.h> in *.c. + +1998-11-02 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c (gdm_slave_session_init): Reset display instead + of restarting the X server every time. + +1998-11-01 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c (gdm_slave_session_init): If PreRoot script + returns > 0 abort session. + +1998-10-31 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmauth.c (gdm_auth_user_add): New function. + (gdm_auth_user_remove): New function. ~/.Xauthority management. + +1998-10-30 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmmisc.c (gdm_arg_munch): Zero out the remaining + argv-entries. We use the static array several times. + + * src/gdmslave.c (gdm_slave_session_init): Removed malloc(pwent) - + Duh!. + + * src/gdm.c (gdm_config_parse): Added group lookup. Removed + malloc(pwent). + +1998-10-26 Martin Kasper Petersen <mkp@mkp.net> + + * config/gdm.conf.in: New User and Group keys override NobodyUser + +1998-10-21 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdm.c (gdm_restart_slave): Implemented reboot and halt. + + * src/gdmverify.c: #ifdefs to make it compile on non PAM systems. + + * src/Makefile.am (gdm_SOURCES): Added gdmmisc.c + + * src/gdmmisc.c: Moved arg_much to a seperate file. It is now used + by both gdm.c and gdmslave.c. + +1998-10-20 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c: Send STX through pipeline before sending a + command. + + * src/gdmslave.c (gdm_slave_display_init): Added STX for greeter + communications to avoid problems with Gtk debug errors to stdout. + +1998-10-19 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_browser_init): Added background + color in browser. + + * src/gdmgreeter.c (gdm_greeter_browser_select): Change + GDK_BUTTON_PRESS to ditto RELEASE due to gil. + + * src/gdmgreeter.c (main): Removed buggy icon list workaround. + (main): Center window before realizing it. + (gdm_greeter_browser_init): Added 3D frame to new icon list. + +1998-10-18 Miguel de Icaza <miguel@nuclecu.unam.mx> + + * src/gdmgreeter.c (gdm_greeter_browser_init): Icon List is born + in frozen state, calling freeze and thaw leaves it still in frozen + state (as we have a frozen counter instead of a flag these days.). + +1998-10-16 Christopher Blizzard <blizzard@appliedtheory.com> + + * config/Makefile.am (install-data-hook): Make sure that + install-data-hook depends on targets gdm.conf gnomerc and Gnome. + Otherwise they are never built. Also, if the directories that + these files are supposed to go in don't exist, create them with + the proper mode. + +1998-10-13 Miguel de Icaza <miguel@nuclecu.unam.mx> + + * src/gdmgreeter.c (gdm_greeter_login_entry_handler): Fix use of + the gnome_icon_list_moveto routine + (gdm_greeter_browser_update): ditto. + (gdm_greeter_browser_init): Adapt to the new gnome-icon-list api. + (gdm_greeter_login_entry_handler): Thaw before attempting to use moveto + + Martin, is there any reason why you clear() the icon lists + contents and then reload them when the user changes from the login + field to the password one? + +1998-10-13 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c (gdm_slave_exec_script): New function. + (gdm_slave_display_init): Add support for display init script. + (gdm_slave_session_init): Add support for root pre-login script. + (gdm_slave_session_init): Add support for root post-login script. + + * src/gdm.c (gdm_config_parse): Added new config options for + scripts. + + * config/gdm.conf.in ([daemon]): Default config options for + scripts. + +1998-10-11 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdm.c (main): Redirect all output to a logfile. + + * src/gdm.c (main): Moved the pid checking code to main to avoid + /sbin/init respawns. Checks whether gdm is started by init and + stops forking if this is the case (actually works this time). + + * config/gdm.conf.in (PidFile): I've been ignoring all bug reports + caused by this one. Turns out I made a typo in the config template + file. *sigh* + +1998-10-11 Carsten Schaar <nhadcasc@fs-maphy.uni-hannover.de> + + * src/Makefile.am (gdm_LDADD): Added '$(INTLLIBS). + (gdmgreeter_LDADD): Likewise. + +1998-10-10 Martin Kasper Petersen <mkp@mkp.net> + + * config/gdm.conf.in ([servers]): Modified to default X server + entry to exclude display depth option. + + * config/Makefile.am (install-data-hook): Avoid overwriting + existing config files. + + * acconfig.h: Added HAVE_PAM + + * src/gdmverify.c (gdm_verify_user): Change USE_PAM to HAVE_PAM to + follow conventions. + + * configure.in (have_pam): PAM autodetection. + +1998-10-08 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_invalid_passwd_req): Set focus to + passwd field when auth fails. + + * src/gdmslave.c: Finished the rewrite. Should be almost usable + again. + + * config/Makefile.am: TODO: Need to find a way to prevent + overwriting gdm.conf when doing a make install. + +1998-10-07 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_login): Completely new + communication scheme. Easier to parse in gdmslave.c. + +1998-10-06 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmverify.c: New file. TODO: PAM detection in autoconf. + + * src/gdmslave.c: Gave up on merging CVS and my .ch-work. Started + major rewrite instead. + + * src/gdmgreeter.c: Removed `:' in pipe communication + protocol. Waste. + +1998-10-05 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c: Fixed the race reported on gnome-list the right + way. The posted fix broke X USR1 signalling. + + * src/gdmgreeter.c (gdm_greeter_about): Bumped version + number. Whee. + (gdm_greeter_done): New function. Partly replaces parse_results(). + (gdm_greeter_login): Former login_button_handler. Now passes + password through pipe. Disables input while gdmslave is thinking. + (gdm_greeter_passwd_entry_handler): Replaced parse_results with + gdm_greeter_login to reflect the auth redesign. + (gdm_greeter_invalid_passwd_req): Re-enable input and reset cursor + after requester has been acked. + (main): Added signal handling for gdmslave communication. + +1998-10-04 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdm.c: signal->sigaction stuff. + (gdm_daemonify): Moved openlog to main. + (main): Stop forking when ppid is init. + +1998-10-01 Miguel de Icaza <miguel@nuclecu.unam.mx> + + * src/gdmslave.c (gdm_slave_init): Setup the signal before + forking. FIXME: We need to use sigaction all over the place + instead of signal. + +Thu Sep 24 22:09:39 CEST 1998 Jochen Friedrich <jochen@scram.de> + + * src/gdmgreeter.c: Fixed a memory corruption. + +1998-09-15 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmslave.c (gdm_slave_usr1_handler): Added support for + setting last session in ~/.gnome/gdm/session/last. I had forgotten + all about it after I removed it from greeter. + + * src/gdm.c Gazillions of fixes + + * src/gdmslave.c Gazillions of fixes + +1998-09-14 Martin Kasper Petersen <mkp@mkp.net> + + * src/gdmgreeter.c (gdm_greeter_verify_user): Replaced annoying + LOG_AUTH with LOG_ERR. + + * config/Makefile.am: Changed _DATA to _SCRIPTS for gnomerc et al. + +1998-09-10 Miguel de Icaza <miguel@nuclecu.unam.mx> + + * src/gdm.c (gdm_config_parse): Simplify as well. + + * src/gdmgreeter.c (gdm_greeter_user_alloc): Fix my oversimplication + from last night. + + * src/gdmgreeter.c (gdm_greeter_user_alloc): More simplification + of the use of gnome-config. I think I really should document it. + + * src/gdm.h (gdm_slave_init): Add prototype. Remove include to + gnome.h. + + * src/gdmslave.c (gdm_slave_usr1_handler): Log errors when the + session can not be launched. + Simplify the includes. + + * src/gdmgreeter.c (gdm_greeter_parse_config): Simplify the code + by using gnome_config_push_prefix + (gdm_greeter_parse_config): Do not strdup the resulting strings, + they are already dupped + (gdm_greeter_sessions_init): Removed dependency on static buffer + for s. Find correcly the default session. + +Tue Sep 8 16:11:49 EDT 1998 Gregory McLean + + * acconfig.h : added this file so one can cvs -z3 co gdm, cd gdm + ./autogen.sh; make and have an executable be spit out. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..1845ca8e --- /dev/null +++ b/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = config macros pixmaps gui daemon docs intl po + +EXTRA_DIST = ChangeLog README.install gdm.spec + @@ -0,0 +1,64 @@ + + + GDM - GNOME DISPLAY MANAGER + + +The Gnome Display Manager is a re-implementation of the well known xdm +program. gdm consists of four separate parts: A small daemon, two +slightly different graphical login programs and a host chooser. + +gdm 2.0 implements all significant features required for managing +local and remote displays. + +gdm daemon: + + o X Authentication + o Default and per-display initialization scripts + o Pre and post session scripts + o Pluggable Authentication Modules + o XDMCP + o TCP Wrappers for access control + +gdmgreeter: + + o Logo image (in any GdkImlib supported format) + o A face browser like the one on NeXT/SGI + o Tab-completion (no, doesn't work on passwords) + o Halt, reboot and laptop suspend + o Iconified login window (i.e. for xfishtank) + o Session selection support (Package manager friendly) + o Language selection support + +gdmlogin: + + o Logo image + o Halt and reboot + o Iconified login window + o Session selection support + o Language selection support + +gdmchooser: + + o Visual host browser + o Customizable icons + + +Most features can be turned on and off in the configuration file by +the sysadmin. + +Availability: + + ftp://ftp.gnome.org/pub/GNOME/sources/gdm/ + + +Please consult README.install for instructions on how to configure and +install gdm. + +Send suggestions, patches, bug reports etc. to mkp@SunSITE.auc.dk. +Bear in mind that this is beta software and please enable debug +logging (see README.install) and include your syslog and +<vardir>/gdm/<display>.log when sending bug reports. + + +Martin K. Petersen, The Gnome Project + diff --git a/README.install b/README.install new file mode 100644 index 00000000..fd07aeec --- /dev/null +++ b/README.install @@ -0,0 +1,23 @@ +QUICK NOTES ON INSTALLATION/USE: + +For security reasons a dedicated group id is needed for proper +operation! gdm assumes that the group is called `gdm'. Furthermore gdm +relies on the existence of a `nobody' user. Create these before +running make install. + +You should run ``make install'' as root to get the permissions right +on the authentication directory. + +Configuration is done by editing the gdm.conf file (located in +<prefix>/etc/gdm/gdm.conf). If no config file exists, make install +will create one for you. + +Put your (jpg, gif, png, xpm) picture in ~/.gnome/photo to make it +appear in the face browser. + +When reporting bugs you should first turn on debugging in +gdm.conf. Your syslog daemon might not log debug information per +default so you should make sure daemon.debug events are logged to a +file. Include the resulting log in your bug report. + + @@ -0,0 +1,4 @@ +WORK IN PROGRESS: + + o Picon capplet for selecting the bitmap to appear in the browser. + o gdmconfig - a program for configuring the gdm.conf file. diff --git a/acconfig.h b/acconfig.h new file mode 100644 index 00000000..ede6d248 --- /dev/null +++ b/acconfig.h @@ -0,0 +1,13 @@ +#undef PACKAGE +#undef VERSION +#undef HAVE_LIBSM +#undef GDM_XAUTH_PATH +#undef ENABLE_NLS +#undef HAVE_CATGETS +#undef HAVE_GETTEXT +#undef HAVE_LC_MESSAGES +#undef HAVE_STPCPY +#undef HAVE_PAM +#undef HAVE_TCPWRAPPERS +#undef HAVE_SHADOW + diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 00000000..0655ccda --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,389 @@ + +###################################################################### +# progtest.m4 from gettext 0.32 +###################################################################### +# Search path for a program which passes the given test. +# Ulrich Drepper <drepper@cygnus.com>, 1996. +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN(AM_PATH_PROG_WITH_TEST, +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test -n "[$]$1"; then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + + +###################################################################### +# lcmessage.m4 from gettext 0.32 +###################################################################### +# Check whether LC_MESSAGES is available in <locale.h>. +# Ulrich Drepper <drepper@cygnus.com>, 1995. +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + +AC_DEFUN(AM_LC_MESSAGES, + [if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES) + fi + fi]) + + + +###################################################################### +# gettext.m4 from gettext 0.32 +###################################################################### +# Macro to add for using GNU gettext. +# Ulrich Drepper <drepper@cygnus.com>, 1995. +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 3 + +AC_DEFUN(AM_WITH_NLS, + [AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE(nls, + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT($USE_NLS) + AC_SUBST(USE_NLS) + + USE_INCLUDED_LIBINTL=no + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + AC_DEFINE(ENABLE_NLS) + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH(included-gettext, + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If gettext or catgets are available (in this order) we + dnl use this. Else we have to fall back to GNU NLS library. + dnl catgets is only used if permitted by option --with-catgets. + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + AC_CHECK_HEADER(libintl.h, + [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc, + [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")], + gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)]) + + if test "$gt_cv_func_gettext_libc" != "yes"; then + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CACHE_CHECK([for gettext in libintl], + gt_cv_func_gettext_libintl, + [AC_TRY_LINK([], [return (int) gettext ("")], + gt_cv_func_gettext_libintl=yes, + gt_cv_func_gettext_libintl=no)])]) + fi + + if test "$gt_cv_func_gettext_libc" = "yes" \ + || test "$gt_cv_func_gettext_libintl" = "yes"; then + AC_DEFINE(HAVE_GETTEXT) + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + AC_CHECK_FUNCS(dcgettext) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + INSTOBJEXT=.mo + fi + fi + ]) + + if test "$CATOBJEXT" = "NONE"; then + AC_MSG_CHECKING([whether catgets can be used]) + AC_ARG_WITH(catgets, + [ --with-catgets use catgets functions if available], + nls_cv_use_catgets=$withval, nls_cv_use_catgets=no) + AC_MSG_RESULT($nls_cv_use_catgets) + + if test "$nls_cv_use_catgets" = "yes"; then + dnl No gettext in C library. Try catgets next. + AC_CHECK_LIB(i, main) + AC_CHECK_FUNC(catgets, + [AC_DEFINE(HAVE_CATGETS) + INTLOBJS="\$(CATOBJS)" + AC_PATH_PROG(GENCAT, gencat, no)dnl + if test "$GENCAT" != "no"; then + AC_PATH_PROG(GMSGFMT, gmsgfmt, no) + if test "$GMSGFMT" = "no"; then + AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no) + fi + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.cat + INSTOBJEXT=.cat + DATADIRNAME=lib + INTLDEPS='$(top_builddir)/intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi]) + fi + fi + + if test "$CATOBJEXT" = "NONE"; then + dnl Neither gettext nor catgets in included in the C library. + dnl Fall back on GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + INTLOBJS="\$(GETTOBJS)" + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_SUBST(MSGFMT) + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.gmo + INSTOBJEXT=.mo + DATADIRNAME=share + INTLDEPS='$(top_builddir)/intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext programs is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + else + DATADIRNAME=share + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi + + # If this is used in GNU gettext we have to set USE_NLS to `yes' + # because some of the sources are only built for this goal. + if test "$PACKAGE" = gettext; then + USE_NLS=yes + USE_INCLUDED_LIBINTL=yes + fi + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.in. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLDEPS) + AC_SUBST(INTLLIBS) + AC_SUBST(INTLOBJS) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +AC_DEFUN(AM_GNU_GETTEXT, + [AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_ISC_POSIX])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_C_CONST])dnl + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + + AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \ +unistd.h values.h sys/param.h]) + AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \ +__argz_count __argz_stringify __argz_next]) + + if test "${ac_cv_func_stpcpy+set}" != "set"; then + AC_CHECK_FUNCS(stpcpy) + fi + if test "${ac_cv_func_stpcpy}" = "yes"; then + AC_DEFINE(HAVE_STPCPY) + fi + + AM_LC_MESSAGES + AM_WITH_NLS + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl The reference to <locale.h> in the installed <libintl.h> file + dnl must be resolved because we cannot expect the users of this + dnl to define HAVE_LOCALE_H. + if test $ac_cv_header_locale_h = yes; then + INCLUDE_LOCALE_H="#include <locale.h>" + else + INCLUDE_LOCALE_H="\ +/* The system does not provide the header <locale.h>. Take care yourself. */" + fi + AC_SUBST(INCLUDE_LOCALE_H) + + dnl Determine which catalog format we have (if any is needed) + dnl For now we know about two different formats: + dnl Linux libc-5 and the normal X/Open format + test -d intl || mkdir intl + if test "$CATOBJEXT" = ".cat"; then + AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen) + + dnl Transform the SED scripts while copying because some dumb SEDs + dnl cannot handle comments. + sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed + fi + dnl po2tbl.sed is always needed. + sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ + $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed + + dnl In the intl/Makefile.in we have a special dependency which makes + dnl only sense for gettext. We comment this out for non-gettext + dnl packages. + if test "$PACKAGE" = "gettext"; then + GT_NO="#NO#" + GT_YES= + else + GT_NO= + GT_YES="#YES#" + fi + AC_SUBST(GT_NO) + AC_SUBST(GT_YES) + + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but ($top_srcdir). + dnl Try to locate is. + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + AC_SUBST(MKINSTALLDIRS) + + dnl *** For now the libtool support in intl/Makefile is not for real. + l= + AC_SUBST(l) + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + ]) diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 00000000..a3f75440 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +PKG_NAME="GDM" + +(test -f $srcdir/configure.in \ + && test -d $srcdir/daemon \ + && test -f $srcdir/daemon/gdm.h) || { + echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" + echo " top-level gdm directory" + exit 1 +} + +. $srcdir/macros/autogen.sh diff --git a/config/.cvsignore b/config/.cvsignore new file mode 100644 index 00000000..35baa7a0 --- /dev/null +++ b/config/.cvsignore @@ -0,0 +1,7 @@ +libtool +confdefs.h +Makefile.in +Gnome +gdm.conf +gnomerc +Makefile
\ No newline at end of file diff --git a/config/:0 b/config/:0 new file mode 100755 index 00000000..8e91f69a --- /dev/null +++ b/config/:0 @@ -0,0 +1,2 @@ +#!/bin/sh +# Stuff any local display preparation stuff here (background pics etc). diff --git a/config/Default b/config/Default new file mode 100644 index 00000000..63d9d335 --- /dev/null +++ b/config/Default @@ -0,0 +1,6 @@ +#!/bin/sh + +/usr/bin/X11/xsetroot -solid "#007777" + + + diff --git a/config/Gnome.in b/config/Gnome.in new file mode 100755 index 00000000..cf429391 --- /dev/null +++ b/config/Gnome.in @@ -0,0 +1,18 @@ +#!/bin/bash -login + +for errfile in "$HOME/.gnomerc-errors" "${TMPDIR-/tmp}/gnomerc-$USER" "/tmp/gnomerc-$USER" +do + if ( cp /dev/null "$errfile" 2> /dev/null ) + then + chmod 600 "$errfile" + exec > "$errfile" 2>&1 + break + fi +done + +if [ -x "$HOME/.gnomerc" ]; then + exec "$HOME/.gnomerc" +else + exec "@sysconfdir@/gnomerc" +fi + diff --git a/config/Makefile.am b/config/Makefile.am new file mode 100644 index 00000000..f292ec9b --- /dev/null +++ b/config/Makefile.am @@ -0,0 +1,75 @@ +pixmapdir = $(datadir)/pixmaps +confdir = $(sysconfdir)/gdm +localedir = $(sysconfdir)/gdm +sessdir = $(sysconfdir)/gdm/Sessions +initdir = $(sysconfdir)/gdm/Init +authdir = $(localstatedir)/gdm +gnomercdir = $(sysconfdir) + +gdm.conf: gdm.conf.in Makefile + sed -e 's,\@datadir\@,$(datadir),g' \ + -e 's,\@pixmapdir\@,$(pixmapdir),g' \ + -e 's,\@bindir\@,$(bindir),g' \ + -e 's,\@sysconfdir\@,$(sysconfdir),g' \ + -e 's,\@localedir\@,$(localedir),g' \ + -e 's,\@authdir\@,$(authdir),g' \ + < $(srcdir)/gdm.conf.in > gdm.conf.tmp; \ + mv -f gdm.conf.tmp gdm.conf + +Gnome: Gnome.in Makefile + sed -e 's,\@sysconfdir\@,$(sysconfdir),g' \ + < $(srcdir)/Gnome.in > Gnome.tmp \ + && mv -f Gnome.tmp Gnome + +gnomerc: gnomerc.in Makefile + sed -e 's,\@bindir\@,$(bindir),g' \ + < $(srcdir)/gnomerc.in > gnomerc.tmp \ + && mv -f gnomerc.tmp gnomerc + +conf_SCRIPTS = gdm.conf +locale_SCRIPTS = locale.alias +gnomerc_SCRIPTS = gnomerc +sess_SCRIPTS = Gnome Xsession +init_SCRIPTS = Default + +EXTRA_DIST = \ + gdm.conf.in \ + Gnome.in \ + gnomerc.in \ + Xsession \ + gdm \ + locale.alias \ + Default + +install-data-hook: gdm.conf gnomerc Gnome + if test '!' -d $(confdir); then \ + $(mkinstalldirs) $(confdir); \ + chmod 755 $(confdir); \ + fi + if test '!' -d $(sessdir); then \ + $(mkinstalldirs) $(sessdir); \ + chmod 755 $(sessdir); \ + fi + if test '!' -d $(initdir); then \ + $(mkinstalldirs) $(initdir); \ + chmod 755 $(initdir); \ + fi + if test '!' -d $(authdir); then \ + $(mkinstalldirs) $(authdir); \ + chown gdm.gdm $(authdir); \ + chmod 750 $(authdir); \ + fi + + system=`uname`; \ + if test -f /usr/include/security/pam_appl.h; then \ + if test '!' -d $(sysconfdir)/pam.d; then \ + $(mkinstalldirs) $(sysconfdir)/pam.d; \ + chmod 755 $(sysconfdir)/pam.d; \ + fi; \ + if test $$system = Linux && test '!' -f $(sysconfdir)/pam.d/gdm; then \ + $(INSTALL_DATA) gdm $(sysconfdir)/pam.d/gdm; \ + fi; \ + if test $$system = SunOS; then \ + echo "Please add PAM authentication for gdm in $(sysconfdir)/pam.conf!"; \ + fi; \ + fi diff --git a/config/Xsession b/config/Xsession new file mode 100755 index 00000000..11cfd153 --- /dev/null +++ b/config/Xsession @@ -0,0 +1,41 @@ +#!/bin/bash -login +# $XConsortium: Xsession /main/10 1995/12/18 18:21:28 gildea $ + +case $# in +1) + case $1 in + failsafe) + exec xterm -geometry 80x24-0-0 + ;; + esac +esac + +# redirect errors to a file in user's home directory if we can +for errfile in "$HOME/.xsession-errors" "${TMPDIR-/tmp}/xses-$USER" "/tmp/xses-$USER" +do + if ( cp /dev/null "$errfile" 2> /dev/null ) + then + chmod 600 "$errfile" + exec > "$errfile" 2>&1 + break + fi +done + +# clean up after xbanner +freetemp + +startup=$HOME/.xsession +resources=$HOME/.Xresources + +if [ -x "$startup" ]; then + exec "$startup" +elif [ -x "$HOME/.Xclients" ]; then + exec "$HOME/.Xclients" +elif [ -x /etc/X11/xinit/Xclients ]; then + exec /etc/X11/xinit/Xclients +else + if [ -f "$resources" ]; then + xrdb -load "$resources" + fi + exec xsm +fi diff --git a/config/gdm b/config/gdm new file mode 100644 index 00000000..71ff8d13 --- /dev/null +++ b/config/gdm @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_pwdb.so shadow nullok +auth required /lib/security/pam_nologin.so +account required /lib/security/pam_pwdb.so +password required /lib/security/pam_cracklib.so +password required /lib/security/pam_pwdb.so shadow nullok use_authtok +session required /lib/security/pam_pwdb.so +session optional /lib/security/pam_console.so diff --git a/config/gdm.conf.in b/config/gdm.conf.in new file mode 100644 index 00000000..d5e4fb05 --- /dev/null +++ b/config/gdm.conf.in @@ -0,0 +1,60 @@ +[appearance] +Browser=1 +Completion=1 +Logo=1 +LogoImage=@pixmapdir@/gnome-logo-large.png +NoFaceImage=@pixmapdir@/nophoto.png +GlobalImageDir=@datadir@/faces/ +Quiver=1 +Iconify=1 +IconFile=@pixmapdir@/gdm.xpm +Gtkrc= + +[system] +ShutdownMenu=0 +SuspendCommand= +UserFileCutoffSize=65536 +UserIconMaxWidth=128 +UserIconMaxHeight=128 +DefaultPath=@bindir@:/usr/local/bin:/usr/bin/X11:/usr/bin:/bin +VerboseAuth=0 +AllowRoot=0 +RelaxPermissions=0 +RetryDelay=3 +LocaleFile=@localedir@/locale.alias + +[messages] +Welcome=Welcome to %h + +[daemon] +SessionDir=@sysconfdir@/gdm/Sessions +PidFile=/var/run/gdm.pid +Greeter=@bindir@/gdmlogin --disable-sound +Chooser=@bindir@/gdmchooser --disable-sound +User=nobody +Group=gdm +DisplayInitDir=@sysconfdir@/gdm/Init +KillInitClients=1 +PreSessionScriptDir=@sysconfdir@/gdm/PreSession +PostSessionScriptDir=@sysconfdir@/gdm/PostSession +AuthDir=@authdir@ +LogDir=@authdir@ + +[servers] +0=/usr/bin/X11/X +#1=/usr/bin/X11/X + +[xdmcp] +Enable=1 +MaxLoadAvg=10 +MaxPending=4 +MaxManageWait=20 +MaxSessions=4 +Port=177 + +[chooser] +ImageDir=@datadir@/hosts +DefaultImage=@pixmapdir@/nohost.png + +[debug] +Enable=0 diff --git a/config/gnomerc.in b/config/gnomerc.in new file mode 100644 index 00000000..e45a0d17 --- /dev/null +++ b/config/gnomerc.in @@ -0,0 +1 @@ +@bindir@/gnome-session diff --git a/config/locale.alias b/config/locale.alias new file mode 100644 index 00000000..b3148a4a --- /dev/null +++ b/config/locale.alias @@ -0,0 +1,54 @@ +# Locale name alias data base +# Copyright (C) 1995 Free Software Foundation, Inc. +# +# 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, 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. + +# The format of this file is the same as for the corresponding file of +# the X Window System, which normally can be found in +# /usr/lib/X11/locale/locale.alias +# A single line contains two fields: an alias and a substitution value. +# All entries are case independent. + +# Note: This file is far from being complete. If you have a value for +# your own site which you think might be useful for others too, share it +# with the rest of us. Send it to bug-gnu-utils@prep.ai.mit.edu. + +czech cs_CZ.ISO-8859-2 +danish da_DK.ISO-8859-1 +dansk da_DK.ISO-8859-1 +deutsch de_DE.ISO-8859-1 +dutch nl_NL.ISO-8859-1 +english en.ISO-8859-1 +finnish fi_FI.ISO-8859-1 +français fr_FR.ISO-8859-1 +french fr_FR.ISO-8859-1 +german de_DE.ISO-8859-1 +greek el_GR.ISO-8859-7 +hebrew iw_IL.ISO-8859-8 +hungarian hu_HU.ISO-8859-2 +icelandic is_IS.ISO-8859-1 +italian it_CH.ISO-8859-1 +japanese ja_JP.EUC +norwegian no_NO.ISO-8859-1 +polish pl_PL.ISO-8859-2 +portuguese pt_PT.ISO-8859-1 +rumanian ro_RO.ISO-8859-2 +russian ru_SU.ISO-8859-5 +slovak sk_SK.ISO-8859-2 +slovene sl_CS.ISO-8859-2 +spanish es_ES.ISO-8859-1 +swedish sv_SE.ISO-8859-1 +turkish tr_TR.ISO-8859-9 + diff --git a/configure.in b/configure.in new file mode 100644 index 00000000..f00a9025 --- /dev/null +++ b/configure.in @@ -0,0 +1,108 @@ +AC_INIT(daemon/gdm.h) + +AM_CONFIG_HEADER(config.h) +AM_INIT_AUTOMAKE(gdm,2.0.0) +AM_MAINTAINER_MODE +AM_ACLOCAL_INCLUDE(macros) + +GNOME_INIT + +AC_ISC_POSIX +AC_PROG_CC +AC_STDC_HEADERS +AC_ARG_PROGRAM +AM_PROG_LIBTOOL + +GNOME_X_CHECKS + +AC_SUBST(CFLAGS) +AC_SUBST(CPPFLAGS) +AC_SUBST(LDFLAGS) + +dnl ## internationalization support +ALL_LINGUAS="de es fr no" +AM_GNOME_GETTEXT + +dnl ## Autentication scheme +have_pam=no +AC_CHECK_HEADERS(security/pam_appl.h, [ + have_pam=yes + LIBS="$LIBS -lpam" + AC_DEFINE(HAVE_PAM)]) + +if test $have_pam = no; then + +# Check if -lcrypt is necessary +AC_CHECK_LIB(crypt, crypt, [ + LIBS="$LIBS -lcrypt"]) + +# Check for shadow passwords (hack) + AC_MSG_CHECKING("for /etc/shadow") + + if test -e /etc/shadow; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SHADOW) + else + AC_MSG_RESULT(no) + fi + +fi + + +# TCP Wrappers for XDMCP access control +AC_MSG_CHECKING("whether to use TCP wrappers") +LIBWRAP_PATH="" +for I in $LDFLAGS $LIBS -L/usr/lib; do + case "$I" in + -L*) + THEFILE="`echo $I | sed -e 's,^-L,,'`" + echo "From $I, checking in dir $THEFILE for libwrap.a" 1>&5 + if test -f $THEFILE/libwrap.a; then + LIBWRAP_PATH=$THEFILE/libwrap.a + echo "Found $LIBWRAP_PATH" 1>&5 + break + fi + esac +done +if test -n "$LIBWRAP_PATH"; then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if test -n "$LIBWRAP_PATH"; then + nm $LIBWRAP_PATH | grep 'T setenv' && LIBWRAP_PATH="" + if test -z "$LIBWRAP_PATH"; then + echo "*********************************************************" + echo " You have a broken TCP wrappers library (setenv included)" + echo " Please get the latest TCP wrappers package from your OS" + echo " vendor, or recompile TCP wrappers to not include a" + echo " setenv() implementation." + echo + echo "Not using TCP wrappers after all." + echo "*********************************************************" + else + AC_DEFINE(HAVE_TCPWRAPPERS) + fi +fi +LIBS="$LIBS $LIBWRAP_PATH" + +AC_PATH_PROG(ac_xauth, xauth) +GDM_XAUTH_PATH=$ac_xauth + +AC_DEFINE_UNQUOTED(GDM_XAUTH_PATH, "$ac_xauth") + + +AC_OUTPUT([ +Makefile +daemon/Makefile +gui/Makefile +pixmaps/Makefile +macros/Makefile +config/Makefile +docs/Makefile +po/Makefile.in +intl/Makefile +stamp.h],[sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile]) + + diff --git a/daemon/.cvsignore b/daemon/.cvsignore new file mode 100644 index 00000000..7fe75d04 --- /dev/null +++ b/daemon/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +.deps +gdm +gdmgreeter diff --git a/daemon/Makefile.am b/daemon/Makefile.am new file mode 100644 index 00000000..f59882b4 --- /dev/null +++ b/daemon/Makefile.am @@ -0,0 +1,30 @@ +## Process this file with automake to produce makefile.in +CFLAGS += -g -Wall \ + -Wpointer-arith \ + -Wmissing-prototypes -Wmissing-declarations + +DEFS += -DGDM_CONFIG_FILE=\"@sysconfdir@/gdm/gdm.conf\" + +INCLUDES = -I. -I.. -I$(includedir) \ + -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ + -DLOCALEDIR=\"$(datadir)/locale\" \ + $(GNOME_INCLUDEDIR) + +bin_PROGRAMS = gdm + +gdm_SOURCES = \ + gdm.c \ + gdm.h \ + slave.c \ + server.c \ + verify.c \ + misc.c \ + auth.c \ + cookie.c \ + xdmcp.c \ + filecheck.c \ + md5.c \ + md5.h + +gdm_LDADD = $(GNOME_LIBDIR) $(GNOME_LIBS) -lXdmcp -lX11 $(INTLLIBS) + diff --git a/daemon/auth.c b/daemon/auth.c new file mode 100644 index 00000000..c8ccea4c --- /dev/null +++ b/daemon/auth.c @@ -0,0 +1,157 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@mkp.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 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 + */ + +/* + * This file contains the X Authentication code + */ + +#include <config.h> +#include <gnome.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> + +#include "gdm.h" + +static const gchar RCSid[]="$Id$"; + +extern gchar *GdmAuthDir; +extern gid_t GdmGroupId; + +extern gchar **gdm_arg_munch(gchar *); +extern void gdm_cookie_generate(GdmDisplay *d); +extern void *gdm_debug(const gchar *, ...); +extern void *gdm_error(const gchar *, ...); + +void gdm_auth_secure_display(GdmDisplay *d); +void gdm_auth_user_add(GdmDisplay *d, gchar *home); +void gdm_auth_user_remove(GdmDisplay *d, gchar *home); + + +void gdm_auth_secure_display(GdmDisplay *d) +{ + gchar *authstr; + gchar **argv; + pid_t authpid; + + gdm_debug("gdm_auth_secure_display: Securing %s", d->name); + + gdm_cookie_generate(d); + + d->auth=g_strconcat(GdmAuthDir, "/", d->name, ".xauth", NULL); + + if(unlink(d->auth) == -1) + gdm_debug(_("gdm_auth_secure_display: Could not unlink %s file: %s"),\ + d->auth, strerror(errno)); + + authstr=g_strconcat(GDM_XAUTH_PATH, " -i -f ", d->auth, \ + " add ", d->name, " . ", d->cookie, NULL); + argv=gdm_arg_munch(authstr); + + switch(authpid=fork()) { + + case 0: + execv(argv[0], argv); + gdm_error(_("gdm_auth_secure_display: Error starting xauth process: %s. Running insecure!"), strerror(errno)); + return; + + case -1: + gdm_error(_("gdm_auth_secure_display: Error forking xauth process. Running insecure!")); + return; + + default: + waitpid(authpid, 0, 0); /* Wait for xauth to finish */ + chown(d->auth, 0, GdmGroupId); + chmod(d->auth, S_IRUSR|S_IWUSR|S_IRGRP); + break; + } + +} + + +void gdm_auth_user_add(GdmDisplay *d, gchar *home) +{ + gchar *authfile, *authstr; + gchar **argv; + pid_t authpid; + + gdm_debug("gdm_auth_user_add: Adding cookie to %s", home); + + authfile=g_strconcat(home, "/.Xauthority", NULL); + authstr=g_strconcat(GDM_XAUTH_PATH, " -i -f ", authfile, \ + " add ", d->name, " . ", d->cookie, NULL); + + argv=gdm_arg_munch(authstr); + g_free(authstr); + + switch(authpid=fork()) { + + case 0: + execv(argv[0], argv); + gdm_error(_("gdm_auth_user_add: Error starting xauth process: %s"), strerror(errno)); + return; + + case -1: + gdm_error(_("gdm_auth_user_add: Error forking xauth process.")); + return; + + default: + waitpid(authpid, 0,0); /* Wait for xauth to finish */ + chmod(authfile, S_IRUSR|S_IWUSR); + g_free(authfile); + break; + + } +} + + +void gdm_auth_user_remove(GdmDisplay *d, gchar *home) +{ + gchar *authstr; + gchar **argv; + pid_t authpid; + + gdm_debug("gdm_auth_user_remove: Removing cookie from %s", home); + + authstr=g_strconcat(GDM_XAUTH_PATH, " -i -f ", home, "/.Xauthority", \ + " remove ", d->name, NULL); + argv=gdm_arg_munch(authstr); + g_free(authstr); + + switch(authpid=fork()) { + + case 0: + execv(argv[0], argv); + gdm_error(_("gdm_auth_user_remove: Error starting xauth process: %s"), strerror(errno)); + return; + + case -1: + gdm_error(_("gdm_auth_user_remove: Error forking xauth process.")); + return; + + default: + waitpid(authpid, 0, 0); /* Wait for xauth to finish */ + break; + + } +} + +/* EOF */ diff --git a/daemon/cookie.c b/daemon/cookie.c new file mode 100644 index 00000000..301f479c --- /dev/null +++ b/daemon/cookie.c @@ -0,0 +1,106 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@mkp.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 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 + */ + +/* + * Functions for generating MIT-MAGIC-COOKIEs. + * + * This code was derived (stolen!) from mcookie.c written by Rik Faith + * <faith@cs.unc.edu> + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <syslog.h> +#include <string.h> +#include <fcntl.h> +#include <sys/time.h> +#include <unistd.h> +#include <gnome.h> + +#include "gdm.h" +#include "md5.h" + +#define MAXBUFFERSIZE 512 + +struct rngs { + const char *path; + int length; +} rngs[] = { + { "/dev/random", 16 }, + { "/dev/urandom", 128 }, + { "/proc/stat", MAXBUFFERSIZE }, + { "/proc/loadavg", MAXBUFFERSIZE }, + { "/dev/audio", MAXBUFFERSIZE }, +}; + +#define RNGS (sizeof(rngs)/sizeof(struct rngs)) + +void gdm_cookie_generate(GdmDisplay *); + +void +gdm_cookie_generate(GdmDisplay *d) +{ + int i; + struct MD5Context ctx; + unsigned char digest[16]; + unsigned char buf[MAXBUFFERSIZE]; + int fd; + pid_t pid; + int r; + struct timeval tv; + struct timezone tz; + char sub[8]; + char cookie[40]; + + sub[0]='\0'; + cookie[0]='\0'; + + MD5Init( &ctx ); + gettimeofday( &tv, &tz ); + MD5Update( &ctx, (unsigned char *)&tv, sizeof( tv ) ); + pid = getppid(); + MD5Update( &ctx, (unsigned char *)&pid, sizeof( pid )); + pid = getpid(); + MD5Update( &ctx, (unsigned char *)&pid, sizeof( pid )); + + for (i = 0; i < RNGS; i++) { + if ((fd = open( rngs[i].path, O_RDONLY|O_NONBLOCK )) >= 0) { + r = read( fd, buf, sizeof( buf ) ); + if (r > 0) + MD5Update( &ctx, buf, r ); + else + r = 0; + close( fd ); + if (r >= rngs[i].length) break; + } + } + + MD5Final(digest, &ctx); + + for (i = 0; i < 16; i++) { + sprintf(sub, "%02x", digest[i]); + strcat(cookie, sub); + } + + d->cookie=g_strdup(cookie); + d->bcookie=g_strndup(digest, 16); +} + + +/* EOF */ diff --git a/daemon/filecheck.c b/daemon/filecheck.c new file mode 100644 index 00000000..a2623dd6 --- /dev/null +++ b/daemon/filecheck.c @@ -0,0 +1,120 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@SunSITE.auc.dk> + * + * 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 <config.h> +#include <gnome.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <syslog.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "gdm.h" + +static const gchar RCSid[]="$Id$"; + +gboolean gdm_file_check(gchar *caller, uid_t user, gchar *dir, gchar *file, gboolean absentok); + +extern gint GdmUserMaxFile; +extern gint GdmRelaxPerms; + +gboolean +gdm_file_check(gchar *caller, uid_t user, gchar *dir, gchar *file, gboolean absentok) +{ + struct stat statbuf; + gchar *str; + + /* Stat directory */ + if(stat(dir, &statbuf) == -1) + return(FALSE); + + /* Check if dir is owned by the user */ + if(statbuf.st_uid != user) { + syslog(LOG_WARNING, _("%s: %s is not owned by uid %d."), caller, dir, user); + return(FALSE); + } + + /* Check if group has write permission */ + if(GdmRelaxPerms<1 && (statbuf.st_mode & S_IWGRP) == S_IWGRP) { + syslog(LOG_WARNING, _("%s: %s is writable by group."), caller, dir); + return(FALSE); + } + + /* Check if other has write permission */ + if(GdmRelaxPerms<2 && (statbuf.st_mode & S_IWOTH) == S_IWOTH) { + syslog(LOG_WARNING, _("%s: %s is writable by other."), caller, dir); + return(FALSE); + } + + str=g_strconcat(dir, "/", file, NULL); + + /* Stat file */ + if(stat(str, &statbuf) == -1) { + g_free(str); + + /* Return true if file is absent and that is ok */ + if(absentok) + return(TRUE); + else + return(FALSE); + } + + /* Check that it is a regular file ... */ + if(! S_ISREG(statbuf.st_mode)) { + syslog(LOG_WARNING,_("%s: %s is not a regular file."), caller, str); + g_free(str); + return(FALSE); + } + + /* ... owned by the user ... */ + if(statbuf.st_uid != user) { + syslog(LOG_WARNING, _("%s: %s is not owned by uid %d."), caller, str, user); + g_free(str); + return(FALSE); + } + + /* ... unwritable by group ... */ + if(GdmRelaxPerms<1 && (statbuf.st_mode & S_IWGRP) == S_IWGRP) { + syslog(LOG_WARNING, _("%s: %s is writable by group."), caller, str); + g_free(str); + return(FALSE); + } + + /* ... unwritable by others ... */ + if(GdmRelaxPerms<2 && (statbuf.st_mode & S_IWOTH) == S_IWOTH) { + syslog(LOG_WARNING, _("%s: %s is writable by group/other."), caller, str); + g_free(str); + return(FALSE); + } + + /* ... and smaller than sysadmin specified limit. */ + if(statbuf.st_size > GdmUserMaxFile) { + syslog(LOG_WARNING, _("%s: %s is bigger than sysadmin specified maximum file size."), caller, str); + g_free(str); + return(FALSE); + } + + g_free(str); + + /* Yeap, this file is ok */ + return(TRUE); +} + +/* EOF */ diff --git a/daemon/gdm.c b/daemon/gdm.c new file mode 100644 index 00000000..7481d292 --- /dev/null +++ b/daemon/gdm.c @@ -0,0 +1,626 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@SunSITE.auc.dk> + * + * 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 <gnome.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <signal.h> +#include <strings.h> +#include <pwd.h> +#include <grp.h> +#include <syslog.h> +#include <sys/wait.h> +#include <errno.h> +#include <ctype.h> +#include <config.h> + +#include "gdm.h" + +static const gchar RCSid[]="$Id$"; + +extern void gdm_slave_start(GdmDisplay *); +extern gchar **gdm_arg_munch(const gchar *p); +extern void gdm_fail(const gchar *, ...); +extern void gdm_info(const gchar *, ...); +extern void gdm_error(const gchar *, ...); +extern GdmDisplay *gdm_server_alloc(gint id, gchar *command); +extern void gdm_server_start(GdmDisplay *d); +extern void gdm_server_stop(GdmDisplay *d); +extern void gdm_server_restart(GdmDisplay *d); +extern void gdm_debug(const gchar *format, ...); +extern int gdm_xdmcp_init(void); +extern void gdm_xdmcp_run(void); +extern void gdm_xdmcp_close(void); + +gint gdm_display_manage(GdmDisplay *d); +void gdm_display_dispose (GdmDisplay *d); +static void gdm_local_servers_start(GdmDisplay *d); +static void gdm_display_unmanage(GdmDisplay *d); + +GSList *displays; +gint sessions=0; +static gchar *GdmUser; +static gchar *GdmGroup; + +uid_t GdmUserId; +gid_t GdmGroupId; +gchar *GdmSessDir = NULL; +gchar *GdmGreeter = NULL; +gchar *GdmLogDir = NULL; +gchar *GdmDisplayInit = NULL; +gchar *GdmPreSession = NULL; +gchar *GdmPostSession = NULL; +gchar *GdmHalt = NULL; +gchar *GdmReboot = NULL; +gchar *GdmAuthDir = NULL; +gchar *GdmUserAuthFile = NULL; +gchar *GdmSuspend = NULL; +gchar *GdmPidFile = NULL; +gchar *GdmDefaultPath = NULL; +gint GdmKillInitClients = 0; +gint GdmUserMaxFile = 0; +gint GdmXdmcp; +gint GdmMaxPending; +gint GdmMaxManageWait; +gint GdmMaxSessions; +gint GdmPort; +gint GdmDebug; +gint GdmVerboseAuth; +gint GdmAllowRoot; +gint GdmRelaxPerms; +gint GdmRetryDelay; + +typedef struct _childstat ChildStat; +struct _childstat { pid_t pid; gint status; }; + + +void +gdm_display_dispose (GdmDisplay *d) +{ + if(d->type == DISPLAY_XDMCP) { + displays=g_slist_remove(displays, d); + sessions--; + } + + if(d->name) { + gdm_debug("gdm_display_dispose: Disposing %s", d->name); + g_free(d->name); + } + + if(d->auth) + g_free(d->auth); + + if(d->command) + g_free(d->command); + + if(d->cookie) + g_free(d->cookie); + + if(d->bcookie) + g_free(d->bcookie); + + g_free(d); +} + + +static void +gdm_config_parse (void) +{ + gchar *k, *v; + void *iter; + struct passwd *pwent; + struct group *grent; + struct stat statbuf; + + displays = NULL; + + if(stat(GDM_CONFIG_FILE, &statbuf) == -1) + gdm_fail(_("gdm_config_parse: No configuration file: %s. Aborting."), GDM_CONFIG_FILE); + + gnome_config_push_prefix ("=" GDM_CONFIG_FILE "=/"); + GdmPidFile=g_strdup(gnome_config_get_string("daemon/pidfile=/var/run/gdm.pid")); + GdmUser=g_strdup(gnome_config_get_string("daemon/user=gdm")); + GdmGroup=g_strdup(gnome_config_get_string("daemon/group=gdm")); + GdmGreeter=g_strdup(gnome_config_get_string("daemon/greeter")); + GdmSessDir=g_strdup(gnome_config_get_string("daemon/sessiondir")); + GdmLogDir=g_strdup(gnome_config_get_string("daemon/logdir")); + GdmDisplayInit=g_strdup(gnome_config_get_string("daemon/displayinitdir")); + GdmPreSession=g_strdup(gnome_config_get_string("daemon/presessionscriptdir")); + GdmPostSession=g_strdup(gnome_config_get_string("daemon/postsessionscriptdir")); + GdmHalt=g_strdup(gnome_config_get_string("daemon/haltcommand=/sbin/shutdown -h now")); + GdmReboot=g_strdup(gnome_config_get_string("daemon/rebootcommand=/sbin/shutdown -r now")); + GdmSuspend=g_strdup(gnome_config_get_string("daemon/suspendcommand")); + GdmAuthDir=g_strdup(gnome_config_get_string("daemon/authdir")); + GdmUserAuthFile=g_strdup(gnome_config_get_string("daemon/userauthfile=.Xauthority")); + GdmKillInitClients=gnome_config_get_int("daemon/killinitclients=1"); + GdmVerboseAuth=gnome_config_get_int("system/verboseauth=1"); + GdmAllowRoot=gnome_config_get_int("system/allowroot=0"); + GdmRelaxPerms=gnome_config_get_int("system/relaxpermissions=0"); + GdmRetryDelay=gnome_config_get_int("system/retrydelay=3"); + GdmUserMaxFile=gnome_config_get_int("system/userfilecutoffsize=65536"); + GdmXdmcp=gnome_config_get_int("xdmcp/enable=1"); + GdmMaxPending=gnome_config_get_int("xdmcp/maxpending=4"); + GdmMaxManageWait=gnome_config_get_int("xdmcp/maxmanagewait=20"); + GdmMaxSessions=gnome_config_get_int("xdmcp/maxsessions=4"); + GdmPort=gnome_config_get_int("xdmcp/port=177"); + GdmDebug=gnome_config_get_int("debug/enable=0"); + GdmDefaultPath=g_strdup(gnome_config_get_string("system/defaultpath=/bin:/usr/bin:/usr/X11/bin:/usr/local/bin")); + + if(GdmGreeter==NULL && stat("/usr/local/bin/gdmgreeter", &statbuf)==0) + GdmGreeter="/usr/local/bin/gdmgreeter"; + + if(GdmGreeter==NULL && stat("/usr/bin/gdmgreeter", &statbuf)==0) + GdmGreeter="/usr/bin/gdmgreeter"; + + if(GdmGreeter==NULL && stat("/opt/gnome/bin/gdmgreeter", &statbuf)==0) + GdmGreeter="/opt/gnome/bin/gdmgreeter"; + + if(GdmGreeter==NULL) + gdm_fail(_("gdm_config_parse: No greeter specified and default not found.")); + + if(GdmAuthDir==NULL && stat("/var/gdm", &statbuf)==0) + GdmAuthDir="/var/gdm"; + + if(GdmAuthDir==NULL && stat("/var/lib/gdm", &statbuf)==0) + GdmAuthDir="/var/lib/gdm"; + + if(GdmAuthDir==NULL && stat("/opt/gnome/var/gdm", &statbuf)==0) + GdmAuthDir="/opt/gnome/var/gdm"; + + if(GdmAuthDir==NULL) + gdm_fail(_("gdm_config_parse: No authdir specified and default not found.")); + + if(GdmLogDir==NULL) + GdmLogDir=GdmAuthDir; + + if(GdmSessDir==NULL && stat("/usr/local/etc/gdm/Sessions", &statbuf)==0) + GdmSessDir="/usr/local/etc/gdm/Sessions"; + + if(GdmSessDir==NULL && stat("/usr/etc/gdm/Sessions", &statbuf)==0) + GdmSessDir="/usr/etc/gdm/Sessions"; + + if(GdmSessDir==NULL && stat("/etc/gdm/Sessions", &statbuf)==0) + GdmSessDir="/etc/gdm/Sessions"; + + if(GdmSessDir==NULL && stat("/etc/X11/gdm/Sessions", &statbuf)==0) + GdmSessDir="/etc/X11/gdm/Sessions"; + + if(GdmSessDir==NULL) + gdm_fail(_("gdm_config_parse: No sessions directory specified and default not found.")); + + gnome_config_pop_prefix(); + + iter=gnome_config_init_iterator("=" GDM_CONFIG_FILE "=/servers"); + iter=gnome_config_iterator_next (iter, &k, &v); + + while (iter) { + + if(isdigit(*k)) + displays=g_slist_append(displays, gdm_server_alloc(atoi(k), v)); + else + gdm_info(_("gdm_config_parse: Invalid server line in config file. Ignoring!")); + + iter=gnome_config_iterator_next (iter, &k, &v); + } + + if(!displays && !GdmXdmcp) + gdm_fail(_("gdm_config_parse: Xdmcp disabled and no local servers defined. Aborting!")); + + pwent = getpwnam(GdmUser); + + if(!pwent) + gdm_fail(_("gdm_config_parse: Can't find the gdm user (%s). Aborting!"), GdmUser); + else + GdmUserId=pwent->pw_uid; + + if(GdmUserId==0) + gdm_fail(_("gdm_config_parse: The gdm user should not be root. Aborting!")); + + grent = getgrnam(GdmGroup); + + if(!grent) + gdm_fail(_("gdm_config_parse: Can't find the gdm group (%s). Aborting!"), GdmGroup); + else + GdmGroupId=grent->gr_gid; + + + if(GdmGroupId==0) + gdm_fail(_("gdm_config_parse: The gdm group should not be root. Aborting!")); + + setegid(GdmGroupId); /* gid remains `gdm' */ + seteuid(GdmUserId); + + /* Enter paranoia mode */ + if(stat(GdmAuthDir, &statbuf) == -1) + gdm_fail(_("gdm_config_parse: Authdir %s does not exist. Aborting."), GdmAuthDir); + + if(! S_ISDIR(statbuf.st_mode)) + gdm_fail(_("gdm_config_parse: Authdir %s is not a directory. Aborting."), GdmAuthDir); + + if(statbuf.st_uid != GdmUserId || statbuf.st_gid != GdmGroupId) + gdm_fail(_("gdm_config_parse: Authdir %s is not owned by user %s, group %s. Aborting."), GdmAuthDir, GdmUser, GdmGroup); + + if(statbuf.st_mode != (S_IFDIR|S_IRWXU|S_IRGRP|S_IXGRP)) + gdm_fail(_("gdm_config_parse: Authdir %s has wrong permissions. Should be 750. Aborting."), GdmAuthDir, statbuf.st_mode); + + seteuid(0); +} + + +static void +gdm_local_servers_start(GdmDisplay *d) +{ + if(d && d->type == DISPLAY_LOCAL) { + gdm_debug("gdm_local_servers_start: Starting %s", d->name); + gdm_server_start(d); + } +} + + +gint +gdm_display_manage(GdmDisplay *d) +{ + sigset_t mask, omask; + + if(!d) + return(FALSE); + + gdm_debug("gdm_display_manage: Managing %s", d->name); + + /* If we have an old slave process hanging around, kill it */ + if(d->slavepid) { + sigemptyset(&mask); + sigaddset(&mask, SIGCHLD); + sigprocmask(SIG_BLOCK, &mask, &omask); + + kill(d->slavepid, SIGINT); + waitpid(d->slavepid, 0, 0); + + sigprocmask(SIG_SETMASK, &omask, NULL); + } + + switch(d->slavepid=fork()) { + + case 0: + + setpgid(0, 0); + + /* Close XDMCP fd in slave process */ + gdm_xdmcp_close(); + + if(d->type == DISPLAY_LOCAL && d->servstat == SERVER_RUNNING) + gdm_slave_start(d); + + if(d->type == DISPLAY_XDMCP && d->dispstat == XDMCP_MANAGED) + gdm_slave_start(d); + + break; + + case -1: + gdm_error(_("gdm_display_manage: Failed forking gdm slave process for %d"), d->name); + return(FALSE); + + default: + gdm_debug("gdm_display_manage: Forked slave: %d", d->slavepid); + break; + } + + return(TRUE); +} + + +static void +gdm_child_handler(gint sig) +{ + pid_t pid; + gint exitstatus, status=0; + GSList *list=displays; + GdmDisplay *d; + gchar **argv; + + /* Get status from all dead children */ + while((pid=waitpid(-1, &exitstatus, WNOHANG)) > 0) { + + if(WIFEXITED(exitstatus)) + status=WEXITSTATUS(exitstatus); + + gdm_debug("gdm_child_handler: child %d returned %d", pid, status); + + if(pid < 1) + return; + + while(list && list->data) { + + d=list->data; + gdm_debug("gdm_child_handler: %s", d->name); + + /* X server died */ + if(pid == d->servpid) { + d->servpid=0; + + switch(status) { + + case SERVER_SUCCESS: + case SERVER_FAILURE: + gdm_server_start(d); + break; + + case SERVER_NOTFOUND: + case SERVER_ABORT: + gdm_display_unmanage(d); + break; + + default: + gdm_debug("gdm_child_handler: Server process returned unknown status %d", status); + gdm_display_unmanage(d); + break; + } + } + + /* Slave died */ + if(pid==d->slavepid) { + d->slavepid=0; + + switch(status) { + + case DISPLAY_REMANAGE: + + if(d->type == DISPLAY_LOCAL && d->dispstat != DISPLAY_ABORT) { + d->dispstat=DISPLAY_DEAD; + gdm_server_restart(d); + } + + if(d->type == DISPLAY_XDMCP) + gdm_display_unmanage(d); + + break; + + case DISPLAY_ABORT: + gdm_info(_("gdm_child_action: Aborting display %s"), d->name); + gdm_display_unmanage(d); + break; + + case DISPLAY_REBOOT: + gdm_info(_("gdm_child_action: Master rebooting...")); + g_slist_foreach(displays, (GFunc) gdm_display_unmanage, NULL); + closelog(); + unlink(GdmPidFile); + argv=gdm_arg_munch(GdmReboot); + execv(argv[0], argv); + gdm_error(_("gdm_child_action: Reboot failed: %s"), strerror(errno)); + break; + + case DISPLAY_HALT: + gdm_info(_("gdm_child_action: Master halting...")); + g_slist_foreach(displays, (GFunc) gdm_display_unmanage, NULL); + closelog(); + unlink(GdmPidFile); + argv=gdm_arg_munch(GdmHalt); + execv(argv[0], argv); + gdm_error(_("gdm_child_action: Halt failed: %s"), strerror(errno)); + break; + + case DISPLAY_RESERVER: + default: + gdm_debug("gdm_child_action: Slave process returned %d", status); + + if(d->type == DISPLAY_LOCAL && d->dispstat != DISPLAY_ABORT) { + d->dispstat=DISPLAY_DEAD; + gdm_server_start(d); + } + + if(d->type == DISPLAY_XDMCP) + gdm_display_unmanage(d); + + break; + } + } + + list=list->next; + } + } +} + + +static void +gdm_display_unmanage(GdmDisplay *d) +{ + if(!d) + return; + + gdm_debug("gdm_display_unmanage: Stopping %s", d->name); + + if(d->type == DISPLAY_LOCAL) { + + /* Kill slave and all its children */ + if(d->slavepid) { + kill(-(d->slavepid), SIGTERM); + waitpid(d->slavepid, 0, 0); + d->slavepid=0; + } + + if(d->servpid) { + gdm_server_stop(d); + } + + d->dispstat=DISPLAY_DEAD; + } + else { /* DISPLAY_XDMCP */ + if(d->slavepid) { + kill(d->slavepid, SIGTERM); + waitpid(d->slavepid, 0, 0); + d->slavepid=0; + } + + gdm_display_dispose(d); + } +} + + +static void +gdm_term_handler(int sig) +{ + sigset_t mask; + + gdm_debug("gdm_term_handler: Got TERM/INT. Going down!"); + + sigemptyset(&mask); + sigaddset(&mask, SIGCHLD); + sigprocmask(SIG_BLOCK, &mask, NULL); + + g_slist_foreach(displays, (GFunc) gdm_display_unmanage, NULL); + + closelog(); + unlink(GdmPidFile); + exit(EXIT_SUCCESS); +} + + +static void +gdm_daemonify(void) +{ + FILE *pf; + pid_t pid; + + if((pid=fork())) { + if((pf=fopen(GdmPidFile, "w"))) { + fprintf(pf, "%d\n", pid); + fclose(pf); + } + exit(EXIT_SUCCESS); + } + + if(pid<0) + gdm_fail(_("gdm_daemonify: fork() failed!")); + + if(setsid() < 0) + gdm_fail(_("gdm_daemonify: setsid() failed: %s!"), strerror(errno)); + + chdir(GdmAuthDir); + umask(022); + + close(0); + close(1); + close(2); + + open ("/dev/null", O_RDONLY); + dup2 (0, 1); + dup2 (0, 2); +} + + +int +main (int argc, char *argv[]) +{ + sigset_t mask; + struct sigaction term, child; + FILE *pf; + GMainLoop *main_loop; + + /* xdm compatible error message */ + if(getuid()) { + fprintf(stderr, _("Only root wants to run gdm\n")); + exit(EXIT_FAILURE); + } + + umask (022); + gnomelib_init("gdm", VERSION); + main_loop = g_main_new(FALSE); + openlog("gdm", LOG_PID, LOG_DAEMON); + + gdm_config_parse(); + + if(!access(GdmPidFile, R_OK)) { + /* Check the process is still alive. Don't abort otherwise. */ + int pidv; + + pf=fopen(GdmPidFile, "r"); + if(pf && fscanf(pf, "%d", &pidv)==1 && kill(pidv,0)!=-1) { + fclose(pf); + fprintf(stderr, _("gdm already running. Aborting!\n\n")); + exit(EXIT_FAILURE); + } + + fclose(pf); + fprintf(stderr, _("According to %s, gdm was already running (%d),\n" + "but seems to have been murdered mysteriously.\n"), GdmPidFile, pidv); + unlink(GdmPidFile); + } + + /* Become daemon unless started in -nodaemon mode or child of init */ + if( (argc==2 && strcmp(argv[1],"-nodaemon")==0) || getppid()==1) { + if((pf=fopen(GdmPidFile, "w"))) { + fprintf(pf, "%d\n", getpid()); + fclose(pf); + } + } + else + gdm_daemonify(); + + /* Signal handling */ + term.sa_handler = gdm_term_handler; + term.sa_flags = SA_RESTART; + sigemptyset(&term.sa_mask); + + if(sigaction(SIGTERM, &term, NULL) < 0) + gdm_fail(_("gdm_main: Error setting up TERM signal handler")); + + if(sigaction(SIGINT, &term, NULL) < 0) + gdm_fail(_("gdm_main: Error setting up INT signal handler")); + + child.sa_handler = gdm_child_handler; + child.sa_flags = SA_RESTART|SA_NOCLDSTOP; + sigemptyset(&child.sa_mask); + sigaddset(&child.sa_mask, SIGCHLD); + + if(sigaction(SIGCHLD, &child, NULL) < 0) + gdm_fail(_("gdm_main: Error setting up CHLD signal handler")); + + sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + sigaddset(&mask, SIGCHLD); + sigprocmask(SIG_UNBLOCK, &mask, NULL); + + gdm_debug("gdm_main: Here we go..."); + + /* Init XDMCP if applicable */ + if(GdmXdmcp) + gdm_xdmcp_init(); + + /* Start local X servers */ + g_slist_foreach(displays, (GFunc) gdm_local_servers_start, NULL); + + /* Accept remote connections */ + if(GdmXdmcp) { + gdm_debug("Accepting XDMCP connections..."); + gdm_xdmcp_run(); + } + + g_main_run(main_loop); + + for(;;) + pause(); + + return (EXIT_SUCCESS); +} + +/* EOF */ diff --git a/daemon/gdm.h b/daemon/gdm.h new file mode 100644 index 00000000..463231fe --- /dev/null +++ b/daemon/gdm.h @@ -0,0 +1,86 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998 Martin Kasper Petersen <mkp@mkp.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 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 __GDM_H__ +#define __GDM_H__ + +#define DISPLAY_LOCAL 1 /* Local X server */ +#define DISPLAY_XDMCP 2 /* Remote display */ + +#define SERVER_SUCCESS 0 /* X server default */ +#define SERVER_FAILURE 1 /* X server default */ +#define SERVER_NOTFOUND 127 /* X server default */ +#define SERVER_DEAD 250 /* Server stopped */ +#define SERVER_STARTED 251 /* Server started but not ready for connections yet */ +#define SERVER_RUNNING 252 /* Server running and ready for connections */ +#define SERVER_ABORT 253 /* Server failed badly. Suspending display. */ + +#define DISPLAY_SUCCESS 0 /* All systems are go */ +#define DISPLAY_REMANAGE 2 /* Restart display */ +#define DISPLAY_ABORT 4 /* Houston, we have a problem */ +#define DISPLAY_REBOOT 8 /* Rebewt */ +#define DISPLAY_HALT 16 /* Halt */ +#define DISPLAY_DEAD 32 /* Display not configured/started yet */ +#define DISPLAY_RESERVER 64 /* XIO Error */ + +#define XDMCP_DEAD 0 +#define XDMCP_PENDING 1 +#define XDMCP_MANAGED 2 + +#define GDM_MSGERR 'M' +#define GDM_NOECHO 'K' +#define GDM_PROMPT 'P' +#define GDM_SESS '.' +#define GDM_LANG 'N' +#define GDM_SSESS 'E' +#define GDM_SLANG 'T' +#define GDM_RESET '!' +#define GDM_QUIT 'Q' + + +#define FIELD_SIZE 64 +#define PIPE_SIZE 1024 + +#include <X11/Xlib.h> +#include <X11/Xmd.h> + +typedef struct _GdmDisplay GdmDisplay; + +struct _GdmDisplay { + CARD32 sessionid; + Display *dsp; + gchar *auth; + gchar *command; + gchar *cookie; + gchar *bcookie; + gchar *name; + gint dispstat; + gint id; + gint servstat; + gint type; + gint dispnum; + pid_t greetpid; + pid_t servpid; + pid_t sesspid; + pid_t slavepid; + time_t acctime; +}; + +#endif /* __GDM_H__ */ + +/* EOF */ diff --git a/daemon/md5.c b/daemon/md5.c new file mode 100644 index 00000000..005568b5 --- /dev/null +++ b/daemon/md5.c @@ -0,0 +1,253 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ +#include <string.h> /* for memcpy() */ +#include "md5.h" + +#ifndef HIGHFIRST +#define byteReverse(buf, len) /* Nothing */ +#else +void byteReverse(unsigned char *buf, unsigned longs); + +#ifndef ASM_MD5 +/* + * Note: this code is harmless on little-endian machines. + */ +void byteReverse(unsigned char *buf, unsigned longs) +{ + uint32 t; + do { + t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(uint32 *) buf = t; + buf += 4; + } while (--longs); +} +#endif +#endif + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + uint32 t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void MD5Final(unsigned char digest[16], struct MD5Context *ctx) +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((uint32 *) ctx->in)[14] = ctx->bits[0]; + ((uint32 *) ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (uint32 *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + +#ifndef ASM_MD5 + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#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 MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<<s | 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. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void MD5Transform(uint32 buf[4], uint32 const in[16]) +{ + register uint32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#endif + diff --git a/daemon/md5.h b/daemon/md5.h new file mode 100644 index 00000000..e264f686 --- /dev/null +++ b/daemon/md5.h @@ -0,0 +1,27 @@ +#ifndef MD5_H +#define MD5_H + +#ifdef __alpha +typedef unsigned int uint32; +#else +typedef unsigned long uint32; +#endif + +struct MD5Context { + uint32 buf[4]; + uint32 bits[2]; + unsigned char in[64]; +}; + +void MD5Init(struct MD5Context *context); +void MD5Update(struct MD5Context *context, unsigned char const *buf, + unsigned len); +void MD5Final(unsigned char digest[16], struct MD5Context *context); +void MD5Transform(uint32 buf[4], uint32 const in[16]); + +/* + * This is needed to make RSAREF happy on some MS-DOS compilers. + */ +typedef struct MD5Context MD5_CTX; + +#endif /* !MD5_H */ diff --git a/daemon/misc.c b/daemon/misc.c new file mode 100644 index 00000000..eb1408f0 --- /dev/null +++ b/daemon/misc.c @@ -0,0 +1,289 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@SunSITE.auc.dk> + * + * 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 <config.h> +#include <gnome.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <syslog.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "gdm.h" + +static const gchar RCSid[]="$Id$"; + + +gchar **gdm_arg_munch(gchar *p); +gint gdm_exec_script(GdmDisplay *d, gchar *dir); +void gdm_exec_command(gchar *cmd); +void gdm_fail(const gchar *format, ...); +void gdm_abort(const gchar *format, ...); +void gdm_info(const gchar *format, ...); +void gdm_error(const gchar *format, ...); +void gdm_debug(const gchar *format, ...); +void gdm_remanage(const gchar *format, ...); +void gdm_putenv(gchar *s); + +extern gchar *GdmPidFile; +extern gchar *GdmDefaultPath; +extern gint GdmDebug; + + +gchar ** +gdm_arg_munch(gchar *p) +{ + gchar *x=strdup(p); + gint quoted=0; + gint argn=0; + static gchar *argv[16]; + + while(*x) + { + while(*x && isspace(*x)) + x++; + + if(*x=='"') + { + quoted=1; + x++; + } + + argv[argn]=x; + + while(*x) + { + if(*x=='"' && quoted) + break; + if(*x==' ' && !quoted) + break; + x++; + } + + if(*x) + *x++=0; + argn++; + if(argn==16) + break; + } + + while(argn<=16) { + argv[argn]=NULL; + argn++; + }; + + return argv; +} + + +/* Execute a script and wait for it to finish */ +gint +gdm_exec_script(GdmDisplay *d, gchar *dir) +{ + pid_t pid; + gchar *script, *defscript, *scr; + gchar **argv; + gint status; + + script = g_strconcat(dir, "/", d->name, NULL); + defscript = g_strconcat(dir, "/Default", NULL); + + if(!access(script, R_OK|X_OK)) + scr=script; + else if (!access(defscript, R_OK|X_OK)) + scr=defscript; + else + return(EXIT_SUCCESS); + + switch(pid=fork()) { + + case 0: + gdm_putenv(g_strconcat("PATH=", GdmDefaultPath, NULL)); + argv=gdm_arg_munch(scr); + execv(argv[0], argv); + syslog(LOG_ERR, _("gdm_exec_script: Failed starting: %s"), scr); + return(EXIT_SUCCESS); + + case -1: + syslog(LOG_ERR, _("gdm_exec_script: Can't fork script process!")); + return(EXIT_SUCCESS); + + default: + waitpid(pid, &status, 0); /* Wait for script to finish */ + + if(WIFEXITED(status)) + return(WEXITSTATUS(status)); + else + return(EXIT_SUCCESS); + }; +} + + +void +gdm_exec_command(gchar *cmd) +{ + pid_t pid; + gchar **argv; + + if(!cmd) return; + + switch(pid=fork()) { + + case 0: + gdm_putenv(g_strconcat("PATH=", GdmDefaultPath, NULL)); + argv=gdm_arg_munch(cmd); + execvp(argv[0], argv); + syslog(LOG_ERR, _("gdm_exec_command: Failed starting: %s"), cmd); + exit(EXIT_FAILURE); + + case -1: + syslog(LOG_ERR, _("gdm_exec_command: Can't fork process!")); + break; + + default: + break; + }; +} + + +/* Log error and abort master daemon */ +void +gdm_fail(const gchar *format, ...) +{ + va_list args; + gchar *s; + + va_start(args, format); + s=g_strdup_vprintf(format, args); + va_end(args); + + syslog(LOG_ERR, s); + fprintf(stderr, s); + fprintf(stderr, "\n"); + fflush(stderr); + + g_free(s); + unlink(GdmPidFile); + closelog(); + + exit(EXIT_FAILURE); +} + + +/* Log error and abort the slave daemon */ +void +gdm_abort(const gchar *format, ...) +{ + va_list args; + gchar *s; + + va_start(args, format); + s=g_strdup_vprintf(format, args); + va_end(args); + + syslog(LOG_ERR, s); + + g_free(s); + + exit(DISPLAY_ABORT); +} + + +/* Remanage display */ +void +gdm_remanage(const gchar *format, ...) +{ + va_list args; + gchar *s; + + va_start(args, format); + s=g_strdup_vprintf(format, args); + va_end(args); + + syslog(LOG_ERR, s); + + g_free(s); + + exit(DISPLAY_REMANAGE); +} + + +/* Log non fatal error/message */ +void +gdm_info(const gchar *format, ...) +{ + va_list args; + gchar *s; + + va_start(args, format); + s=g_strdup_vprintf(format, args); + va_end(args); + + syslog(LOG_INFO, s); + + g_free(s); +} + + +/* Log error condition */ +void +gdm_error(const gchar *format, ...) +{ + va_list args; + gchar *s; + + va_start(args, format); + s=g_strdup_vprintf(format, args); + va_end(args); + + syslog(LOG_ERR, s); + + g_free(s); +} + + +/* Log debug messages */ +void +gdm_debug(const gchar *format, ...) +{ + va_list args; + gchar *s; + + if(GdmDebug) { + va_start(args, format); + s=g_strdup_vprintf(format, args); + va_end(args); + + syslog(LOG_DEBUG, s); + + g_free(s); + } +} + + +void +gdm_putenv(gchar *s) +{ + putenv(s); + g_free(s); +} + + +/* EOF */ diff --git a/daemon/server.c b/daemon/server.c new file mode 100644 index 00000000..bc293fa3 --- /dev/null +++ b/daemon/server.c @@ -0,0 +1,317 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@SunSITE.auc.dk> + * + * 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 + */ + +/* This file contains functions for controlling local X servers */ + +#include <config.h> +#include <gnome.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <strings.h> +#include <signal.h> +#include <errno.h> +#include <X11/Xlib.h> + +#include "gdm.h" + +static const gchar RCSid[]="$Id$"; + +extern gchar *GdmDisplayInit; +extern gchar *GdmAuthDir; +extern gchar *GdmLogDir; +extern gint GdmXdmcp; + +extern gchar **gdm_arg_munch(const gchar *p); +extern void gdm_auth_secure_display(GdmDisplay *); +extern void gdm_debug(const gchar *, ...); +extern void gdm_error(const gchar *, ...); +extern gint gdm_display_manage(GdmDisplay *); +extern void gdm_putenv(gchar *); +extern void gdm_xdmcp_close(); + +void gdm_server_start(GdmDisplay *d); +void gdm_server_stop(GdmDisplay *d); +void gdm_server_restart(GdmDisplay *d); +void gdm_server_usr1_handler(gint); +void gdm_server_alarm_handler(gint); +GdmDisplay *gdm_server_alloc (gint id, gchar *command); + + +GdmDisplay *d; +sigset_t mask, omask; + + +void +gdm_server_start(GdmDisplay *disp) +{ + struct sigaction usr1; + sigset_t usr1mask; + int logfd; + gchar *srvcmd=NULL; + gchar **argv=NULL; + + d=disp; + + gdm_debug("gdm_server_start: %s", d->name); + + /* Catch USR1 from X server */ + usr1.sa_handler = gdm_server_usr1_handler; + usr1.sa_flags = SA_RESTART|SA_RESETHAND; + sigemptyset(&usr1.sa_mask); + + if(sigaction(SIGUSR1, &usr1, NULL) < 0) { + gdm_error(_("gdm_server_start: Error setting up USR1 signal handler")); + exit(SERVER_ABORT); + } + + sigemptyset(&usr1mask); + sigaddset(&usr1mask, SIGUSR1); + sigprocmask(SIG_UNBLOCK, &usr1mask, NULL); + + /* Log all output from spawned programs to a file */ + logfd=open(g_strconcat(GdmLogDir, "/", d->name, ".log", NULL), + O_CREAT|O_TRUNC|O_APPEND|O_WRONLY, 0666); + + if(logfd != -1) { + dup2(logfd, 1); + dup2(logfd, 2); + } + else + gdm_error(_("gdm_server_start: Could not open logfile for display %s!"), d->name); + + /* Just in case we have an old server hanging around */ + if(d->servpid) { + gdm_debug("gdm_server_start: Old server found (%d). Killing.", d->servpid); + gdm_server_stop(d); + } + + /* Secure display with cookie */ + gdm_auth_secure_display(d); + gdm_putenv(g_strconcat("XAUTHORITY=", d->auth, NULL)); + gdm_putenv(g_strconcat("DISPLAY=", d->name, NULL)); + + /* Fork into two processes. Parent remains the gdm slave + * process. Child becomes the X server. + */ + + switch(d->servpid=fork()) { + + case 0: + /* Close the XDMCP fd inherited by the daemon process */ + if(GdmXdmcp) + gdm_xdmcp_close(); + + /* The X server expects USR1 to be SIG_IGN */ + usr1.sa_handler = SIG_IGN; + usr1.sa_flags = SA_RESTART; + sigemptyset(&usr1.sa_mask); + + if(sigaction(SIGUSR1, &usr1, NULL) < 0) { + gdm_error(_("gdm_server_start: Error setting USR1 to SIG_IGN")); + exit(SERVER_ABORT); + } + + srvcmd=g_strconcat(d->command, " -auth ", GdmAuthDir, \ + "/", d->name, ".xauth ", + d->name, NULL); + + gdm_debug("gdm_server_start: '%s'", srvcmd); + + argv=gdm_arg_munch(srvcmd); + g_free(srvcmd); + + setpgid(0, 0); + + execv(argv[0], argv); + + gdm_error(_("gdm_server_start: Xserver not found: %s"), d->command); + + exit(SERVER_ABORT); + break; + + case -1: + gdm_error(_("gdm_server_start: Can't fork Xserver process!")); + d->servpid=0; + break; + + default: + break; + } + + d->servstat=SERVER_STARTED; + + /* Wait for X server to send ready signal */ + pause(); +} + + +void +gdm_server_stop(GdmDisplay *d) +{ + gdm_debug("gdm_server_stop: Server for %s going down!", d->name); + + kill(d->servpid, SIGTERM); + waitpid(d->servpid, 0, 0); + d->servpid=0; + d->servstat=SERVER_DEAD; + + if(unlink(d->auth) == -1) + gdm_error(_("gdm_server_stop: Could not unlink auth file: %s!"), strerror(errno)); +} + + +/* FIXME: We have a race here. What if USR1 is delivered before we enable the handler? + * This only succeeds because the X server takes ages to shut down... + * Maybe we should jump directly to display_manage and bail out on error? + * Needs thinking for sure... + */ + +void +gdm_server_restart(GdmDisplay *d) +{ + sigset_t usr1mask; + struct sigaction usr1, sigalarm; + + gdm_debug("gdm_server_restart: Server for %s restarting!", d->name); + + if(d->servpid && kill(d->servpid, 0)<0) { + gdm_debug("gdm_server_restart: Old server for %s still alive. Killing!", d->name); + gdm_server_stop(d); + gdm_server_start(d); + } + + /* Create new cookie */ + gdm_auth_secure_display(d); + gdm_putenv(g_strconcat("XAUTHORITY=", d->auth, NULL)); + gdm_putenv(g_strconcat("DISPLAY=", d->name, NULL)); + + /* Catch USR1 from X server */ + usr1.sa_handler = gdm_server_usr1_handler; + usr1.sa_flags = SA_RESTART|SA_RESETHAND; + sigemptyset(&usr1.sa_mask); + + if(sigaction(SIGUSR1, &usr1, NULL) < 0) { + gdm_error(_("gdm_server_start: Error setting up USR1 signal handler")); + exit(SERVER_ABORT); + } + + sigemptyset(&usr1mask); + sigaddset(&usr1mask, SIGUSR1); + sigprocmask(SIG_UNBLOCK, &usr1mask, NULL); + + /* Reset X and force auth file reread. XCloseDisplay works on most servers but we play it safe */ + /*gdm_debug("gdm_server_restart: Servpid=%d", d->servpid);*/ + /*kill(d->servpid, SIGHUP);*/ + + d->servstat=SERVER_STARTED; + + /* We add a timeout in case the X server fails to start. This + * might happen because X servers take a while to die, close their + * sockets etc. If the old X server isn't completely dead, the new + * one will fail and we'll hang here forever */ + + sigalarm.sa_handler = gdm_server_alarm_handler; + sigalarm.sa_flags = 0; + sigemptyset(&sigalarm.sa_mask); + + if(sigaction(SIGALRM, &sigalarm, NULL) < 0) { + gdm_error(_("gdm_server_restart: Error setting up ALARM signal handler")); + return; + } + + sigemptyset(&mask); + sigaddset(&mask, SIGALRM); + sigprocmask(SIG_UNBLOCK, &mask, &omask); + + alarm(10); + + /* Wait for X server to send ready signal */ + pause(); +} + + +void +gdm_server_alarm_handler(gint signal) +{ + /* Unset alarm and try again */ + alarm(0); + sigprocmask(SIG_SETMASK, &omask, NULL); + + waitpid(d->servpid, 0, WNOHANG); + + gdm_debug("gdm_server_alarm_handler: Temporary server failure"); + gdm_server_restart(d); +} + + +void +gdm_server_usr1_handler(gint sig) +{ + sigset_t usr1mask; + + /* Unset alarm */ + alarm(0); + sigprocmask(SIG_SETMASK, &omask, NULL); + + gdm_debug("gdm_server_usr1_handler: Starting display %s!", d->name); + + d->servstat=SERVER_RUNNING; + + /* Block USR1 */ + sigemptyset(&usr1mask); + sigaddset(&usr1mask, SIGUSR1); + sigprocmask(SIG_BLOCK, &usr1mask, NULL); + + gdm_display_manage(d); +} + + +GdmDisplay * +gdm_server_alloc (gint id, gchar *command) +{ + gchar dname[1024]; + + GdmDisplay *d = g_malloc(sizeof(GdmDisplay)); + + sprintf(dname, ":%d", id); + d->auth = NULL; + d->command = g_strdup(command); + d->cookie = NULL; + d->dispstat = DISPLAY_DEAD; + d->greetpid = 0; + d->id = id; + d->name = strdup(dname); + d->servpid = 0; + d->servstat = SERVER_DEAD; + d->sessionid = 0; + d->sesspid = 0; + d->slavepid = 0; + d->type = DISPLAY_LOCAL; + d->sessionid = 0; + d->acctime = 0; + d->dsp = NULL; + + return (d); +} + + +/* EOF */ diff --git a/daemon/slave.c b/daemon/slave.c new file mode 100644 index 00000000..235788ce --- /dev/null +++ b/daemon/slave.c @@ -0,0 +1,615 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@SunSITE.auc.dk> + * + * 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 + */ + +/* This is the gdm slave process. gdmslave runs the chooser, greeter + * and the user's session scripts. + */ + +#include <config.h> +#include <gnome.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <strings.h> +#include <X11/Xlib.h> +#include <signal.h> +#include <pwd.h> +#include <grp.h> +#include <errno.h> + +#include "gdm.h" + +static const gchar RCSid[]="$Id$"; + +extern uid_t GdmUserId; +extern gid_t GdmGroupId; +extern gchar *GdmSessDir; +extern gchar *GdmGreeter; +extern gchar *GdmDisplayInit; +extern gchar *GdmPreSession; +extern gchar *GdmPostSession; +extern gchar *GdmSuspend; +extern gchar *GdmDefaultPath; +extern gint GdmKillInitClients; +extern gint GdmRetryDelay; + +extern gboolean gdm_file_check(gchar *caller, uid_t user, gchar *dir, gchar *file, gboolean absentok); +extern gchar **gdm_arg_munch(const gchar *p); +extern gint gdm_exec_script(GdmDisplay*, gchar *dir); +extern void gdm_abort(const char*, ...); +extern void gdm_error(const char*, ...); +extern void gdm_debug(const char*, ...); +extern void gdm_remanage(const char*, ...); +extern void gdm_verify_cleanup (void); +extern void gdm_auth_user_add(GdmDisplay *d, gchar *home); +extern void gdm_auth_user_remove(GdmDisplay *d, gchar *home); +extern void gdm_exec_command(gchar *cmd); +extern void gdm_putenv(gchar *s); +extern gchar *gdm_verify_user (gchar *display); + +void gdm_slave_start(GdmDisplay *d); +static gint gdm_slave_xerror_handler(Display *disp, XErrorEvent *evt); +static gint gdm_slave_xioerror_handler(Display *disp); +static void gdm_slave_greeter(void); +static void gdm_slave_session_start(gchar *login, gchar *session, gboolean savesess, gchar *lang, gboolean savelang); +static void gdm_slave_session_stop(void); +static void gdm_slave_session_cleanup(void); +static void gdm_slave_term_handler(int sig); +static void gdm_slave_child_handler(int sig); +static void gdm_slave_windows_kill(void); +static void gdm_slave_xsync_handler(int sig); +static gboolean gdm_slave_xsync_ping(void); +gchar *gdm_slave_greeter_ctl(gchar cmd, gchar *str); + + +GdmDisplay *d; +struct passwd *pwent; +sigset_t mask, omask; +gboolean pingack; +gboolean greet=TRUE; +FILE *greeter; + + +void +gdm_slave_start(GdmDisplay *display) +{ + struct sigaction term, child; + gint openretries=0; + + gdm_debug("gdm_slave_start: Starting slave process for %s", display->name); + + d=display; + + gdm_putenv(g_strconcat("XAUTHORITY=", d->auth, NULL)); + gdm_putenv(g_strconcat("DISPLAY=", d->name, NULL)); + + /* Handle a INT/TERM signals from gdm master */ + term.sa_handler = gdm_slave_term_handler; + term.sa_flags = SA_RESTART; + sigemptyset(&term.sa_mask); + sigaddset(&term.sa_mask, SIGTERM); + sigaddset(&term.sa_mask, SIGINT); + + if((sigaction(SIGTERM, &term, NULL) < 0) || (sigaction(SIGINT, &term, NULL) < 0)) + gdm_abort(_("gdm_slave_init: Error setting up TERM/INT signal handler")); + + /* Child handler. Keeps an eye on greeter/session */ + child.sa_handler = gdm_slave_child_handler; + child.sa_flags = SA_RESTART|SA_NOCLDSTOP; + sigemptyset(&child.sa_mask); + + if(sigaction(SIGCHLD, &child, NULL) < 0) + gdm_abort(_("gdm_slave_init: Error setting up CHLD signal handler")); + + /* The signals we wish to listen to */ + sigfillset(&mask); + sigdelset(&mask, SIGINT); + sigdelset(&mask, SIGTERM); + sigdelset(&mask, SIGCHLD); + sigprocmask(SIG_SETMASK, &mask, NULL); + + /* X error handlers to avoid the default ones: exit(1) */ + XSetErrorHandler(gdm_slave_xerror_handler); + XSetIOErrorHandler(gdm_slave_xioerror_handler); + + /* We keep our own (windowless) connection (dsp) open to avoid the + * X server resetting due to lack of active connections. */ + + gdm_debug("gdm_slave_start: Opening display %s", d->name); + d->dsp=NULL; + + while(openretries < 10 && d->dsp==NULL) { + d->dsp=XOpenDisplay(d->name); + + if(!d->dsp) { + gdm_debug("gdm_slave_start: Sleeping %d on a retry", openretries*2); + sleep(openretries*2); + openretries++; + } + } + + if(d->dsp) + gdm_slave_greeter(); /* Start the greeter */ + else + exit(DISPLAY_ABORT); +} + + +static void +gdm_slave_greeter(void) +{ + gint pipe1[2], pipe2[2]; + gchar *login=NULL, *session, *language; + gboolean savesess=FALSE, savelang=FALSE; + gchar **argv; + + gdm_debug("gdm_slave_greeter: Running greeter on %s", d->name); + + /* Run the init script. gdmslave suspends until script has terminated */ + gdm_exec_script(d, GdmDisplayInit); + + /* Open a pipe for greeter communications */ + if(pipe(pipe1) < 0 || pipe(pipe2) < 0) + gdm_abort(_("gdm_slave_greeter: Can't init pipe to gdmgreeter")); + + greet=TRUE; + + /* Fork. Parent is gdmslave, child is greeter process. */ + switch(d->greetpid=fork()) { + + case 0: + sigfillset(&mask); + sigdelset(&mask, SIGINT); + sigdelset(&mask, SIGTERM); + sigdelset(&mask, SIGHUP); + sigprocmask(SIG_SETMASK, &mask, NULL); + + /* Plumbing */ + close(pipe1[1]); + close(pipe2[0]); + + if(pipe1[0] != STDIN_FILENO) + dup2(pipe1[0], STDIN_FILENO); + + if(pipe2[1] != STDOUT_FILENO) + dup2(pipe2[1], STDOUT_FILENO); + + if(setgid(GdmGroupId) < 0) + gdm_abort(_("gdm_slave_greeter: Couldn't set groupid to %d"), GdmGroupId); + + if(setuid(GdmUserId) < 0) + gdm_abort(_("gdm_slave_greeter: Couldn't set userid to %d"), GdmUserId); + + gdm_putenv(g_strconcat("XAUTHORITY=", d->auth, NULL)); + gdm_putenv(g_strconcat("DISPLAY=", d->name, NULL)); + gdm_putenv(g_strconcat("HOME=/", NULL)); /* Hack */ + gdm_putenv(g_strconcat("PATH=", GdmDefaultPath, NULL)); + + argv=gdm_arg_munch(GdmGreeter); + execv(argv[0], argv); + + gdm_abort(_("gdm_slave_greeter: Error starting greeter on display %s"), d->name); + + case -1: + gdm_abort(_("gdm_slave_greeter: Can't fork gdmgreeter process")); + + default: + close(pipe1[0]); + close(pipe2[1]); + + if(pipe1[1] != STDOUT_FILENO) + dup2(pipe1[1], STDOUT_FILENO); + + if(pipe2[0] != STDIN_FILENO) + dup2(pipe2[0], STDIN_FILENO); + + greeter=fdopen(STDIN_FILENO, "r"); + + gdm_debug("gdm_slave_greeter: Greeter on pid %d", d->greetpid); + break; + } + + /* Chat with greeter */ + while(login==NULL) { + login=gdm_verify_user(d->name); + + if(login==NULL) { + gdm_slave_greeter_ctl(GDM_RESET, ""); + sleep(GdmRetryDelay); + } + } + + session= gdm_slave_greeter_ctl(GDM_SESS, ""); + language=gdm_slave_greeter_ctl(GDM_LANG, ""); + + if(strlen(gdm_slave_greeter_ctl(GDM_SSESS, ""))) + savesess=TRUE; + + if(strlen(gdm_slave_greeter_ctl(GDM_SLANG, ""))) + savelang=TRUE; + + sigemptyset(&mask); + sigaddset(&mask, SIGCHLD); + sigprocmask(SIG_BLOCK, &mask, &omask); + greet=FALSE; + + /* Kill greeter and wait for it to die */ + kill(d->greetpid, SIGINT); + waitpid(d->greetpid, 0, 0); + d->greetpid=0; + + sigprocmask(SIG_UNBLOCK, &omask, NULL); + + if(GdmKillInitClients) + gdm_slave_windows_kill(); + + gdm_slave_session_start(login, session, savesess, language, savelang); +} + + +static void +gdm_slave_session_start(gchar *login, gchar *session, gboolean savesess, gchar *lang, gboolean savelang) +{ + gchar *sessdir, *cfgdir, *cfgstr; + struct stat statbuf; + + gdm_debug("gdm_slave_session_start: %s on %s", login, d->name); + + pwent=getpwnam(login); + + /* If the user doesn't exist, reset the X server and restart greeter */ + if(!pwent) + gdm_remanage(_("gdm_slave_session_init: User '%s' not found. Aborting."), login); + + gdm_putenv(g_strconcat("XAUTHORITY=", pwent->pw_dir, "/.Xauthority", NULL)); + gdm_putenv(g_strconcat("DISPLAY=", d->name, NULL)); + gdm_putenv(g_strconcat("LOGNAME=", login, NULL)); + gdm_putenv(g_strconcat("USER=", login, NULL)); + gdm_putenv(g_strconcat("USERNAME=", login, NULL)); + gdm_putenv(g_strconcat("HOME=", pwent->pw_dir, NULL)); + gdm_putenv(g_strconcat("GDMSESSION=", session, NULL)); + gdm_putenv(g_strconcat("SHELL=", pwent->pw_shell, NULL)); + gdm_putenv(g_strconcat("PATH=", GdmDefaultPath, NULL)); + + if(!strcasecmp(lang, "english")) + putenv("LANG=C"); + else + gdm_putenv(g_strconcat("LANG=", lang, NULL)); + + /* If script fails reset X server and restart greeter */ + if(gdm_exec_script(d, GdmPreSession) != EXIT_SUCCESS) + gdm_remanage(_("gdm_slave_session_init: Execution of PreSession script returned > 0. Aborting.")); + + switch(d->sesspid=fork()) { + + case -1: + gdm_abort(_("gdm_slave_session_init: Error forking user session")); + + case 0: + setpgid(0, 0); + + umask(022); + + if(setgid(pwent->pw_gid) < 0) + gdm_remanage(_("gdm_slave_session_init: Could not setgid %d. Aborting."), pwent->pw_gid); + + if(initgroups(login, pwent->pw_gid) < 0) + gdm_remanage(_("gdm_slave_session_init: initgroups() failed for %s. Aborting."), login); + + if(setuid(pwent->pw_uid) < 0) + gdm_remanage(_("gdm_slave_session_init: Could not become %s. Aborting."), login); + + chdir(pwent->pw_dir); + + /* Run sanity check on ~user/.Xauthority and setup cookie */ + if(!gdm_file_check("gdm_slave_session_init", pwent->pw_uid, pwent->pw_dir, ".Xauthority", TRUE)) { + XCloseDisplay(d->dsp); + exit(DISPLAY_REMANAGE); + } + + gdm_auth_user_add(d, pwent->pw_dir); + + /* Check if ~user/.gnome exists. Create it otherwise. */ + cfgdir=g_strconcat(pwent->pw_dir, "/.gnome", NULL); + + if(stat(cfgdir, &statbuf) == -1) { /* FIXME: Maybe I need to be a bit paranoid here! */ + mkdir(cfgdir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); + chmod(cfgdir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); + } + + /* Sanity check on ~user/.gnome/gdm */ + if(!gdm_file_check("gdm_slave_session_init", pwent->pw_uid, cfgdir, "gdm", TRUE)) { + gdm_slave_session_cleanup(); + XCloseDisplay(d->dsp); + exit(DISPLAY_REMANAGE); + } + + g_free(cfgdir); + + if(savesess) { + /* libgnome sets home to ~root, so we have to write the path ourselves */ + cfgstr = g_strconcat("=", pwent->pw_dir, "/.gnome/gdm=/session/last", NULL); + gnome_config_set_string(cfgstr, session); + gnome_config_sync(); + g_free(cfgstr); + } + + if(savelang) { + cfgstr = g_strconcat("=", pwent->pw_dir, "/.gnome/gdm=/session/lang", NULL); + gnome_config_set_string(cfgstr, lang); + gnome_config_sync(); + g_free(cfgstr); + } + + sessdir = g_strconcat(GdmSessDir, "/", session, NULL); + + gdm_debug("Running %s for %s on %s", sessdir, login, d->name); + + /* Unblock SIGCHLD for broken terminals */ + sigemptyset(&mask); + sigaddset(&mask, SIGCHLD); + sigprocmask(SIG_UNBLOCK, &mask, NULL); + + execl(sessdir, NULL); + + gdm_error(_("gdm_slave_session_init: Could not start session `%s'"), sessdir); + + gdm_slave_session_stop(); + gdm_slave_session_cleanup(); + + exit(DISPLAY_REMANAGE); + + default: + break; + } + + waitpid(d->sesspid, 0, 0); + + gdm_slave_session_stop(); + gdm_slave_session_cleanup(); +} + + +static void +gdm_slave_session_stop(void) +{ + gdm_debug("gdm_slave_session_stop: %s on %s", pwent->pw_name, d->name); + + kill(-(d->sesspid), SIGTERM); + + gdm_verify_cleanup(); + + /* Remove display from ~user/.Xauthority */ + setegid(pwent->pw_gid); + seteuid(pwent->pw_uid); + + if(gdm_file_check("gdm_slave_session_stop", pwent->pw_uid, pwent->pw_dir, ".Xauthority", FALSE)) + gdm_auth_user_remove(d, pwent->pw_dir); + + setegid(GdmGroupId); + seteuid(0); +} + + +/* Only executed if display is still alive */ +static void +gdm_slave_session_cleanup(void) +{ + gdm_debug("gdm_slave_session_cleanup: %s on %s", pwent->pw_name, d->name); + + if(d->dsp && gdm_slave_xsync_ping()) { + + /* Execute post session script */ + gdm_debug("gdm_slave_session_cleanup: Running post session script"); + gdm_exec_script(d, GdmPostSession); + + /* Cleanup */ + gdm_debug("gdm_slave_session_cleanup: Killing windows"); + gdm_slave_windows_kill(); + + XCloseDisplay(d->dsp); + } + + exit(DISPLAY_REMANAGE); +} + + +static void +gdm_slave_term_handler(int sig) +{ + gdm_debug("gdm_slave_term_handler: %s got TERM signal", d->name); + + if(d->greetpid) { + gdm_debug("gdm_slave_term_handler: Whacking greeter"); + kill(d->greetpid, SIGINT); + waitpid(d->greetpid, 0, 0); + d->greetpid=0; + } + else if(pwent) + gdm_slave_session_stop(); + + gdm_debug("gdm_slave_term_handler: Whacking client connections"); + gdm_slave_windows_kill(); + XCloseDisplay(d->dsp); + exit(DISPLAY_ABORT); +} + + +/* Called on every SIGCHLD */ +static void +gdm_slave_child_handler(int sig) +{ + gint status; + pid_t pid; + + while((pid=waitpid(-1, &status, WNOHANG)) > 0) { + gdm_debug("gdm_slave_child_handler: %d died", pid); + + if(WIFEXITED(status)) + gdm_debug("gdm_slave_child_handler: %d returned %d", pid, WEXITSTATUS(status)); + + if(pid==d->greetpid && greet) + if(WIFEXITED(status)) + exit(WEXITSTATUS(status)); + else { + if(d && d->dsp) + XCloseDisplay(d->dsp); + + exit(DISPLAY_REMANAGE); + } + + if(pid==d->sesspid) { + gdm_slave_session_stop(); + gdm_slave_session_cleanup(); + } + } +} + + +/* Only kills clients, not connections. This keeps the server alive */ +static void +gdm_slave_windows_kill(void) +{ + Window root, parent, *children; + gint child, screen, nchildren; + Display *disp=NULL; + + disp=XOpenDisplay(d->name); + + if(!disp) { + gdm_debug("gdm_slave_windows_kill: Could not open display %s", d->name); + return; + } + + gdm_debug("gdm_slave_windows_kill: Killing windows on %s", d->name); + + gdm_putenv(g_strconcat("XAUTHORITY=", d->auth, NULL)); + gdm_putenv(g_strconcat("DISPLAY=", d->name, NULL)); + + for(screen=0 ; screen<ScreenCount(disp) ; screen++) { + + nchildren=0; + + while(XQueryTree(disp, RootWindow(disp, screen), &root, &parent, + &children, &nchildren) && nchildren>0) { + + for(child=0 ; child<nchildren ; child++) { + gdm_debug("gdm_slave_windows_kill: Killing child 0x%x", children[child]); + XKillClient(disp, children[child]); + } + + XFree(children); + } + + } + + XSync(disp, FALSE); +} + + +/* Minor X faults */ +static gint +gdm_slave_xerror_handler(Display *disp, XErrorEvent *evt) +{ + gdm_debug("gdm_slave_windows_kill_error_handler: Blam"); + pingack=FALSE; + return(TRUE); +} + + +/* We respond to fatal errors by restarting the display */ +static gint +gdm_slave_xioerror_handler(Display *disp) +{ + gdm_debug("gdm_slave_xioerror_handler: I/O error for display %s", d->name); + + if(pwent) + gdm_slave_session_stop(); + + gdm_error(_("gdm_slave_windows_kill_ioerror_handler: Fatal X error - Restarting %s"), d->name); + + exit(DISPLAY_RESERVER); +} + + +static void +gdm_slave_xsync_handler(int sig) +{ + gdm_debug("gdm_slave_xsync_handler: Xping failed for display %s", d->name); + pingack=FALSE; +} + + +static gboolean +gdm_slave_xsync_ping(void) +{ + struct sigaction sigalarm; + sigset_t mask, omask; + + gdm_debug("gdm_slave_xsync_ping: Pinging %s", d->name); + + pingack=TRUE; + + XSetErrorHandler(gdm_slave_xerror_handler); + XSetIOErrorHandler(gdm_slave_xioerror_handler); + + sigalarm.sa_handler = gdm_slave_xsync_handler; + sigalarm.sa_flags = 0; + sigemptyset(&sigalarm.sa_mask); + + if(sigaction(SIGALRM, &sigalarm, NULL) < 0) + gdm_abort(_("gdm_slave_xsync_ping: Error setting up ALARM signal handler")); + + sigemptyset(&mask); + sigaddset(&mask, SIGALRM); + sigprocmask(SIG_UNBLOCK, &mask, &omask); + + alarm(10); + + XSync(d->dsp, TRUE); + + alarm(0); + sigprocmask(SIG_SETMASK, &omask, NULL); + + gdm_debug("gdm_slave_xsync_ping: %s returned %d", d->name, pingack); + + return(pingack); +} + + +gchar * +gdm_slave_greeter_ctl(gchar cmd, gchar *str) +{ + gchar buf[FIELD_SIZE]; + + g_print("%c%s\n", cmd, str); + + fgets(buf, FIELD_SIZE-1, greeter); + + if(strlen(buf)) { + buf[strlen(buf)-1]='\0'; + return(g_strndup(buf, strlen(buf))); + } + else + return(NULL); +} + +/* EOF */ diff --git a/daemon/verify.c b/daemon/verify.c new file mode 100644 index 00000000..5c5de89b --- /dev/null +++ b/daemon/verify.c @@ -0,0 +1,271 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@SunSITE.auc.dk> + * + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <syslog.h> +#include <pwd.h> +#include <glib.h> +#include <crypt.h> +#include <config.h> +#include <gnome.h> + +#ifdef HAVE_PAM + #include <security/pam_appl.h> +#endif /* HAVE_PAM */ + +#ifdef HAVE_SHADOW + #include <shadow.h> +#endif /* HAVE_SHADOW */ + +#include "gdm.h" + +static const gchar RCSid[]="$Id$"; + +extern void gdm_abort(const char*, ...); +extern void gdm_debug(const char*, ...); +extern void gdm_error(const char*, ...); +extern gchar *gdm_slave_greeter_ctl(gchar cmd, gchar *str); + +extern gboolean GdmVerboseAuth; +extern gboolean GdmAllowRoot; + +gchar *gdm_verify_user (gchar *display); +void gdm_verify_cleanup (void); + + +#ifdef HAVE_PAM + +pam_handle_t *pamh; + + +static gint +gdm_verify_pam_conv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, + void *appdata_ptr) +{ + gint replies = 0; + struct pam_response *reply = NULL; + gchar *s; + + reply=g_new0(struct pam_response, num_msg); + + if(!reply) + return PAM_CONV_ERR; + + for(replies=0; replies<num_msg; replies++) { + + switch(msg[replies]->msg_style) { + + case PAM_PROMPT_ECHO_ON: + s=gdm_slave_greeter_ctl(GDM_PROMPT, (gchar *)msg[replies]->msg); + reply[replies].resp_retcode=PAM_SUCCESS; + reply[replies].resp=g_strdup(s); + g_free(s); + break; + + case PAM_PROMPT_ECHO_OFF: + s=gdm_slave_greeter_ctl(GDM_NOECHO, (gchar *)msg[replies]->msg); + reply[replies].resp_retcode=PAM_SUCCESS; + reply[replies].resp=g_strdup(s); + g_free(s); + break; + + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + gdm_slave_greeter_ctl(GDM_MSGERR, (gchar *)msg[replies]->msg); + reply[replies].resp_retcode=PAM_SUCCESS; + reply[replies].resp=NULL; + break; + + default: + g_free(reply); + return PAM_CONV_ERR; + } + + } + + *resp=reply; + return(PAM_SUCCESS); +} + + +static struct pam_conv pamc = { + &gdm_verify_pam_conv, + NULL +}; + + +gchar * +gdm_verify_user (gchar *display) +{ + gint pamerr; + gchar *login; + struct passwd *pwent; + + login=gdm_slave_greeter_ctl(GDM_PROMPT, _("Login:")); + + if(!login) + return(NULL); + + pwent=getpwnam(login); + + if(!pwent) { + gdm_error(_("Couldn't authenticate %s"), login); + + if(GdmVerboseAuth) + gdm_slave_greeter_ctl(GDM_MSGERR, _("User unknown")); + + return(NULL); + } + + if(GdmAllowRoot && pwent->pw_uid == 0) { + gdm_error(_("Root login disallowed on display '%s'"), display); + + if(GdmVerboseAuth) + gdm_slave_greeter_ctl(GDM_MSGERR, _("Root login disallowed")); + + return(NULL); + } + + if((pamerr=pam_start("gdm", login, &pamc, &pamh)) != PAM_SUCCESS) { + gdm_error(_("Can't find /etc/pam.d/gdm!")); + } + + if((pamerr=pam_set_item(pamh, PAM_TTY, display)) != PAM_SUCCESS) { + gdm_error(_("Can't set PAM_TTY=%s"), ":0"); + goto pamerr; + } + + if((pamerr=pam_authenticate(pamh, 0)) != PAM_SUCCESS) { + gdm_error(_("Couldn't authenticate %s"), login); + goto pamerr; + } + + if((pamerr=pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS) { + gdm_error(_("Couldn't set acct. mgmt for %s"), login); + goto pamerr; + } + + if((pamerr=pam_setcred(pamh, 0)) != PAM_SUCCESS) { + gdm_error(_("Couldn't set credentials for %s"), login); + goto pamerr; + } + + if((pamerr=pam_open_session(pamh, 0)) != PAM_SUCCESS) { + gdm_error(_("Couldn't open session for %s"), login); + goto pamerr; + } + + return(login); + + pamerr: + + if(GdmVerboseAuth) + gdm_slave_greeter_ctl(GDM_MSGERR, (gchar *)pam_strerror(pamh, pamerr)); + + pam_end(pamh, pamerr); + pamh=NULL; + + /* Workaround to avoid gdm messages being logged as PAM_pwdb */ + closelog(); + openlog("gdm", LOG_PID, LOG_DAEMON); + + return(NULL); +} + +#else /* HAVE_PAM */ + +gchar * +gdm_verify_user (gchar *display) +{ + gchar *login, *passwd, *ppasswd; + struct passwd *pwent; + +#ifdef HAVE_SHADOW + struct spwd *sp; +#endif + + login=gdm_slave_greeter_ctl(GDM_PROMPT, _("Login:")); + pwent=getpwnam(login); + + if(!pwent) { + gdm_error(_("Couldn't authenticate %s"), login); + + if(GdmVerboseAuth) + gdm_slave_greeter_ctl(GDM_MSGERR, _("User unknown")); + + return(NULL); + } + + if(GdmAllowRoot && pwent->pw_uid == 0) { + gdm_error(_("Root login disallowed on display '%s'"), display); + + if(GdmVerboseAuth) + gdm_slave_greeter_ctl(GDM_MSGERR, _("Root login disallowed")); + + return(NULL); + } + + ppasswd=!pwent ? NULL : pwent->pw_passwd; + +#ifdef HAVE_SHADOW + sp=getspnam(login); + + if(sp) + ppasswd=sp->sp_pwdp; + + endspent(); +#endif /* HAVE_SHADOW */ + + passwd=gdm_slave_greeter_ctl(GDM_NOECHO, _("Password:")); + + if (!passwd || !ppasswd || strcmp(crypt(passwd, ppasswd), ppasswd)) { + + if(GdmVerboseAuth) + gdm_slave_greeter_ctl(GDM_MSGERR, _("Incorrect password")); + + return(NULL); + } + + return(login); +} +#endif /* HAVE_PAM */ + + +void +gdm_verify_cleanup (void) +{ +#ifdef HAVE_PAM + gdm_debug("gdm_verify_cleanup: Closing session %d", pamh); + + if(pamh) { + pam_close_session(pamh, 0); + pam_end(pamh, PAM_SUCCESS); + pamh=NULL; + } + + /* Workaround to avoid gdm messages being logged as PAM_pwdb */ + closelog(); + openlog("gdm", LOG_PID, LOG_DAEMON); +#endif /* HAVE_PAM */ +} + +/* EOF */ diff --git a/daemon/xdmcp.c b/daemon/xdmcp.c new file mode 100644 index 00000000..b809a055 --- /dev/null +++ b/daemon/xdmcp.c @@ -0,0 +1,854 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@mkp.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 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 + */ + +/* This file contains the XDMCP implementation for managing remote + * displays. + */ + +/* Theory of operation: + * + * Process idles waiting for UDP packets on port 177. + * Incoming packets are decoded and checked against tcp_wrapper. + * + * A typical session looks like this: + * + * Display sends Query/BroadcastQuery to Manager. + * + * Manager selects an appropriate authentication scheme from the + * display's list of supported ones and sends Willing/Unwilling. + * + * Assuming the display accepts the auth. scheme it sends back a + * Request. + * + * If the manager accepts to service the display (i.e. loadavg is low) + * it sends back an Accept containing a unique SessionID. The + * SessionID is stored in an accept queue by the Manager. Should the + * manager refuse to start a session a Decline is sent to the display. + * + * The display returns a Manage request containing the supplied + * SessionID. The manager will then start a session on the display. In + * case the SessionID is not on the accept queue the manager returns + * Refuse. If the manager fails to open the display for connections + * Failed is returned. + * + * During the session the display periodically sends KeepAlive packets + * to the manager. The manager responds with Alive. + * + * Similarly the manager xpings the display once in a while and shuts + * down the connection on failure. + * + */ + +#include <config.h> +#include <gnome.h> +#include <stdio.h> +#include <stdlib.h> +#include <syslog.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> +#include <X11/Xlib.h> +#include <X11/Xmd.h> +#include <X11/Xdmcp.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#ifdef HAVE_TCPWRAPPERS + #include <tcpd.h> +#endif + +#include "gdm.h" + +static const gchar RCSid[]="$Id$"; + +int XdmcpReallocARRAY8 (ARRAY8Ptr array, int length); + +/* TCP Wrapper syslog control */ +gint allow_severity = LOG_INFO; +gint deny_severity = LOG_WARNING; + +gint xdmcpfd; +gint globsessid; +gint pending=0; +static ARRAY8 servhost; +static XdmcpBuffer buf; + +extern GSList *displays; +extern gint sessions; +extern gchar *GdmLogDir; + +/* Tunables */ +extern gint GdmMaxPending; /* only accept this number of pending sessions */ +extern gint GdmMaxManageWait; /* Dispose sessions not responding with MANAGE after 10 secs */ +extern gint GdmMaxSessions; /* Maximum number of remote sessions */ +extern gint GdmPort; /* UDP port number */ + +/* + * We don't support XDM-AUTHENTICATION-1 and XDM-AUTHORIZATION-1. + * + * The latter would be quite useful to avoid sending unencrypted + * cookies over the wire. Unfortunately it isn't supported without + * XDM-AUTHENTICATION-1 which requires a key database with private + * keys from all X terminals on your LAN. Fun, fun, fun. + * + * Furthermore user passwords go over the wire in cleartext anyway so + * protecting cookies is not that important. + */ + +typedef struct _XdmAuth { + ARRAY8 authentication; + ARRAY8 authorization; +} XdmAuthRec, *XdmAuthPtr; + +static XdmAuthRec serv_authlist = { + { (CARD16) 0, (CARD8 *) 0 }, + { (CARD16) 0, (CARD8 *) 0 } +}; + + +extern gchar *gdm_cookie_generate(void); +extern void gdm_abort(const gchar *format, ...); +extern void gdm_debug(const gchar *format, ...); +extern void gdm_error(const gchar *format, ...); +extern void gdm_putenv(gchar *s); +extern void gdm_auth_secure_display(GdmDisplay *d); +extern gint gdm_display_manage(GdmDisplay *d); +extern void gdm_display_dispose(GdmDisplay *d); + +int gdm_xdmcp_init(void); +void gdm_xdmcp_run(void); +void gdm_xdmcp_close(void); +static void gdm_xdmcp_decode_packet (void); +static void gdm_xdmcp_handle_query (struct sockaddr_in *clnt_sa, gint len, gint type); +static void gdm_xdmcp_handle_request(struct sockaddr_in *clnt_sa, gint len); +static void gdm_xdmcp_handle_manage (struct sockaddr_in *clnt_sa, gint len); +static void gdm_xdmcp_handle_keepalive (struct sockaddr_in *clnt_sa, gint len); +static void gdm_xdmcp_send_willing (struct sockaddr_in *clnt_sa); +static void gdm_xdmcp_send_unwilling(struct sockaddr_in *clnt_sa, gint type); +static void gdm_xdmcp_send_accept (struct sockaddr_in *clnt_sa, gint displaynum); +static void gdm_xdmcp_send_decline (struct sockaddr_in *clnt_sa); +static void gdm_xdmcp_send_refuse (struct sockaddr_in *clnt_sa, CARD32 sessid); +static void gdm_xdmcp_send_failed (struct sockaddr_in *clnt_sa, CARD32 sessid); +static void gdm_xdmcp_send_alive (struct sockaddr_in *clnt_sa, CARD32 sessid); +static gboolean gdm_xdmcp_host_allow(struct sockaddr_in *cnlt_sa); +static GdmDisplay *gdm_xdmcp_display_alloc (struct sockaddr_in *, gint); +static GdmDisplay *gdm_xdmcp_display_lookup(CARD32 sessid); +static void gdm_xdmcp_display_dispose_check(gchar *name); +static void gdm_xdmcp_displays_check(void); + + +int +gdm_xdmcp_init(void) +{ + struct sockaddr_in serv_sa; + gchar hostbuf[256]; + + globsessid=time(NULL); + + /* Fetch and store local hostname in XDMCP friendly format */ + if(gethostname(hostbuf, 255)) + gdm_abort(_("gdm_xdmcp_init: Could not get server hostname: %s!"), strerror(errno)); + + servhost.data=g_strdup(hostbuf); + servhost.length=strlen(servhost.data); + + gdm_debug("Start up on host %s, port %d", hostbuf, GdmPort); + + /* Open socket for communications */ + xdmcpfd = socket(AF_INET, SOCK_DGRAM, 0); /* UDP */ + + if(xdmcpfd == -1) + gdm_abort(_("gdm_xdmcp_init: Could not create socket!")); + + serv_sa.sin_family = AF_INET; + serv_sa.sin_port = htons (GdmPort); /* UDP 177 */ + serv_sa.sin_addr.s_addr = htonl (INADDR_ANY); + + if(bind(xdmcpfd, (struct sockaddr_in *) &serv_sa, sizeof(serv_sa)) == -1) + gdm_abort(_("gdm_xdmcp_init: Could not bind to XDMCP socket!")); + + return (0); +} + + +void +gdm_xdmcp_run(void) +{ + GIOChannel *channel; + + channel = g_io_channel_unix_new(xdmcpfd); + g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, + G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL, + (GIOFunc) gdm_xdmcp_decode_packet, + GINT_TO_POINTER(xdmcpfd), NULL); + g_io_channel_unref(channel); +} + + +void +gdm_xdmcp_close(void) +{ + close(xdmcpfd); +} + + +static void +gdm_xdmcp_decode_packet(void) +{ + struct sockaddr_in clnt_sa; + gint sa_len=sizeof(clnt_sa); + XdmcpHeader header; + + if(!XdmcpFill(xdmcpfd, &buf, &clnt_sa, &sa_len)) { + gdm_error(_("gdm_xdmcp_decode: Could not create XDMCP buffer!")); + return; + } + + if(!XdmcpReadHeader(&buf, &header)) { + gdm_error(_("gdm_xdmcp_decode: Could not read XDMCP header!")); + return; + } + + if(header.version != XDM_PROTOCOL_VERSION) { + gdm_error(_("gdm_xdmcp_decode: Incorrect XDMCP version!")); + return; + } + + switch(header.opcode) { + + case BROADCAST_QUERY: + gdm_xdmcp_handle_query(&clnt_sa, header.length, BROADCAST_QUERY); + break; + + case QUERY: + gdm_xdmcp_handle_query(&clnt_sa, header.length, QUERY); + break; + + case INDIRECT_QUERY: + break; + + case FORWARD_QUERY: + break; + + case REQUEST: + /* Free pending displays if */ + gdm_xdmcp_displays_check(); + + gdm_xdmcp_handle_request(&clnt_sa, header.length); + break; + + case MANAGE: + gdm_xdmcp_handle_manage(&clnt_sa, header.length); + break; + + case KEEPALIVE: + gdm_xdmcp_handle_keepalive(&clnt_sa, header.length); + break; + + default: + gdm_error(_("gdm_xdmcp_decode_packet: Unknown opcode from host %s"), + inet_ntoa(clnt_sa.sin_addr)); + break; + } +} + + +static void +gdm_xdmcp_handle_query(struct sockaddr_in *clnt_sa, gint len, gint type) +{ + ARRAYofARRAY8 clnt_authlist; + gint i, explen=1; + + gdm_debug("gdm_xdmcp_query: Opcode %d from %s", + type, inet_ntoa(clnt_sa->sin_addr)); + + /* Extract array of authentication names from Xdmcp packet */ + if(!XdmcpReadARRAYofARRAY8(&buf, &clnt_authlist)) { + gdm_error(_("gdm_xdmcp_query: Could not extract authlist from packet")); + return; + } + + /* Crude checksumming */ + for(i=0 ; i<clnt_authlist.length ; i++) { + gdm_debug("gdm_xdmcp_query: authlist: %s", clnt_authlist.data); + explen += 2+clnt_authlist.data[i].length; + } + + if(len!=explen) { + gdm_error(_("gdm_xdmcp_query: Error in checksum")); + return; + } + + /* Don't negotiate authentication - Unsupported */ + XdmcpDisposeARRAYofARRAY8(&clnt_authlist); + + /* Check with tcp_wrappers if client is allowed to access */ + if(gdm_xdmcp_host_allow(clnt_sa)) + gdm_xdmcp_send_willing(clnt_sa); + else + gdm_xdmcp_send_unwilling(clnt_sa, type); +} + + +static void +gdm_xdmcp_send_willing(struct sockaddr_in *clnt_sa) +{ + ARRAY8 status; + XdmcpHeader header; + + gdm_debug("gdm_xdmcp_send_willing: Sending WILLING to %s", inet_ntoa(clnt_sa->sin_addr)); + + status.data=_("GNOME"); + status.length=strlen(status.data); + + header.opcode = (CARD16) WILLING; + header.length = 6 + serv_authlist.authentication.length; + header.length += servhost.length + status.length; + header.version = XDM_PROTOCOL_VERSION; + XdmcpWriteHeader (&buf, &header); + + XdmcpWriteARRAY8 (&buf, &serv_authlist.authentication); /* Hardcoded authentication */ + XdmcpWriteARRAY8 (&buf, &servhost); + XdmcpWriteARRAY8 (&buf, &status); + XdmcpFlush (xdmcpfd, &buf, clnt_sa, sizeof(struct sockaddr_in)); +} + + +static void +gdm_xdmcp_send_unwilling(struct sockaddr_in *clnt_sa, gint type) +{ + ARRAY8 status; + XdmcpHeader header; + + gdm_debug("gdm_xdmcp_send_unwilling: Sending UNWILLING to %s", inet_ntoa(clnt_sa->sin_addr)); + + gdm_error(_("Denied XDMCP query from host %s"), inet_ntoa(clnt_sa->sin_addr)); + + status.data=_("Display not authorized to connect"); + status.length=strlen(status.data); + + header.opcode = (CARD16) UNWILLING; + header.length = 4 + servhost.length + status.length; + header.version = XDM_PROTOCOL_VERSION; + XdmcpWriteHeader (&buf, &header); + + XdmcpWriteARRAY8 (&buf, &servhost); + XdmcpWriteARRAY8 (&buf, &status); + XdmcpFlush (xdmcpfd, &buf, clnt_sa, sizeof(struct sockaddr_in)); +} + + +static void +gdm_xdmcp_handle_request(struct sockaddr_in *clnt_sa, gint len) +{ + static CARD16 clnt_dspnum; + static ARRAY16 clnt_conntyp; + static ARRAYofARRAY8 clnt_addr; + static ARRAY8 clnt_authname; + static ARRAY8 clnt_authdata; + static ARRAYofARRAY8 clnt_authorization; + static ARRAY8 clnt_manufacturer; + gint explen; + gint i; + gboolean mitauth=FALSE; + + gdm_debug("gdm_xdmcp_handle_request: Got REQUEST from %s", + inet_ntoa(clnt_sa->sin_addr)); + + /* Check with tcp_wrappers if client is allowed to access */ + if(!gdm_xdmcp_host_allow(clnt_sa)) { + gdm_error(_("gdm_xdmcp_handle_request: Got REQUEST from banned host %s"), + inet_ntoa(clnt_sa->sin_addr)); + return; + } + + /* Remote display number */ + if(!XdmcpReadCARD16(&buf, &clnt_dspnum)) { + gdm_error(_("gdm_xdmcp_handle_request: Could not read Display Number")); + return; + } + + /* We don't care about connection type. Address says it all */ + if(!XdmcpReadARRAY16(&buf, &clnt_conntyp)) { + gdm_error(_("gdm_xdmcp_handle_request: Could not read Connection Type")); + return; + } + + /* This is TCP/IP - we don't care */ + if(!XdmcpReadARRAYofARRAY8 (&buf, &clnt_addr)) { + gdm_error(_("gdm_xdmcp_handle_request: Could not read Client Address")); + return; + } + + /* Read authentication type */ + if(!XdmcpReadARRAY8 (&buf, &clnt_authname)) { + gdm_error(_("gdm_xdmcp_handle_request: Could not read Authentication Names")); + return; + } + + /* Read authentication data */ + if(!XdmcpReadARRAY8 (&buf, &clnt_authdata)) { + gdm_error(_("gdm_xdmcp_handle_request: Could not read Authentication Data")); + return; + } + + /* Read and select from supported authorization list */ + if(!XdmcpReadARRAYofARRAY8(&buf, &clnt_authorization)) { + gdm_error(_("gdm_xdmcp_handle_request: Could not read Authorization List")); + return; + } + + /* libXdmcp doesn't terminate strings properly so we cheat and use strncmp() */ + for(i=0 ; i<clnt_authorization.length ; i++) + if(!strncmp(clnt_authorization.data[i].data, "MIT-MAGIC-COOKIE-1", 18)) + mitauth=TRUE; + + /* Manufacturer ID */ + if(!XdmcpReadARRAY8 (&buf, &clnt_manufacturer)) { + gdm_error(_("gdm_xdmcp_handle_request: Could not read Manufacturer ID")); + return; + } + + /* Crude checksumming */ + explen = 2; /* Display Number */ + explen += 1+2*clnt_conntyp.length; /* Connection Type */ + explen += 1; /* Connection Address */ + for(i=0 ; i<clnt_addr.length ; i++) + explen += 2+clnt_addr.data[i].length; + explen += 2+clnt_authname.length; /* Authentication Name */ + explen += 2+clnt_authdata.length; /* Authentication Data */ + explen += 1; /* Authorization Names */ + for(i=0 ; i<clnt_authorization.length ; i++) + explen += 2+clnt_authorization.data[i].length; + explen += 2+clnt_manufacturer.length; + + if(explen != len) { + gdm_error(_("gdm_xdmcp_handle_request: Failed checksum from %s"), + inet_ntoa(clnt_sa->sin_addr)); + return; + } + + gdm_debug("gdm_xdmcp_handle_request: pending=%d, MaxPending=%d, sessions=%d, MaxSessions=%d", + pending, GdmMaxPending, sessions, GdmMaxSessions); + + /* if load<maxload */ + if(mitauth && + pending < GdmMaxPending && + sessions < GdmMaxSessions) + gdm_xdmcp_send_accept(clnt_sa, clnt_dspnum); + else + gdm_xdmcp_send_decline(clnt_sa); +} + + +static void +gdm_xdmcp_send_accept(struct sockaddr_in *clnt_sa, gint displaynum) +{ + XdmcpHeader header; + ARRAY8 authentype; + ARRAY8 authendata; + ARRAY8 authname; + ARRAY8 authdata; + GdmDisplay *d; + + d=gdm_xdmcp_display_alloc(clnt_sa, displaynum); + + authentype.data=(CARD8 *) 0; + authentype.length=(CARD16) 0; + + authendata.data=(CARD8 *) 0; + authendata.length=(CARD16) 0; + + authname.data="MIT-MAGIC-COOKIE-1"; + authname.length=strlen(authname.data); + + authdata.data=d->bcookie; + authdata.length=strlen(d->bcookie); /* I.e. 16 */ + + header.version=XDM_PROTOCOL_VERSION; + header.opcode=(CARD16) ACCEPT; + header.length = 4; + header.length += 2 + authentype.length; + header.length += 2 + authendata.length; + header.length += 2 + authname.length; + header.length += 2 + authdata.length; + + XdmcpWriteHeader (&buf, &header); + + XdmcpWriteCARD32 (&buf, d->sessionid); + XdmcpWriteARRAY8 (&buf, &authentype); + XdmcpWriteARRAY8 (&buf, &authendata); + XdmcpWriteARRAY8 (&buf, &authname); + XdmcpWriteARRAY8 (&buf, &authdata); + + XdmcpFlush (xdmcpfd, &buf, clnt_sa, sizeof(struct sockaddr_in)); + + gdm_debug("gdm_xdmcp_send_accept: Sending ACCEPT to %s with SessionID=%d", + inet_ntoa(clnt_sa->sin_addr), d->sessionid); +} + + +static void +gdm_xdmcp_send_decline(struct sockaddr_in *clnt_sa) +{ + XdmcpHeader header; + ARRAY8 authentype; + ARRAY8 authendata; + ARRAY8 status; + + gdm_debug("gdm_xdmcp_send_decline: Sending DECLINE to %s", + inet_ntoa(clnt_sa->sin_addr)); + + authentype.data=(CARD8 *) 0; + authentype.length=(CARD16) 0; + + authendata.data=(CARD8 *) 0; + authendata.length=(CARD16) 0; + + status.data="Service refused"; + status.length=strlen(status.data); + + header.version=XDM_PROTOCOL_VERSION; + header.opcode=(CARD16) DECLINE; + header.length = 2 + status.length; + header.length += 2 + authentype.length; + header.length += 2 + authendata.length; + XdmcpWriteHeader (&buf, &header); + + XdmcpWriteARRAY8 (&buf, &status); + XdmcpWriteARRAY8 (&buf, &authentype); + XdmcpWriteARRAY8 (&buf, &authendata); + + XdmcpFlush (xdmcpfd, &buf, clnt_sa, sizeof(struct sockaddr_in)); +} + + +static void +gdm_xdmcp_handle_manage(struct sockaddr_in *clnt_sa, gint len) +{ + CARD32 clnt_sessid; + CARD16 clnt_dspnum; + static ARRAY8 clnt_dspclass; + GdmDisplay *d; + gint logfd; + + gdm_debug("gdm_xdmcp_manage: Got MANAGE from %s", inet_ntoa(clnt_sa->sin_addr)); + + /* if (RcvSessId == SavedSessId) { run session } + elseif (SessId already in use) { nop; } + else { send refuse }; + */ + + /* Check with tcp_wrappers if client is allowed to access */ + if(!gdm_xdmcp_host_allow(clnt_sa)) { + gdm_error(_("gdm_xdmcp_handle_manage: Got Manage from banned host %s"), + inet_ntoa(clnt_sa->sin_addr)); + return; + } + + /* SessionID */ + if(!XdmcpReadCARD32(&buf, &clnt_sessid)) { + gdm_error(_("gdm_xdmcp_handle_manage: Could not read Session ID")); + return; + } + + /* Remote display number */ + if(!XdmcpReadCARD16(&buf, &clnt_dspnum)) { + gdm_error(_("gdm_xdmcp_handle_manage: Could not read Display Number")); + return; + } + + gdm_debug("gdm_xdmcp_manage: Got Display=%d, SessionID=%d from %s", + clnt_dspnum, clnt_sessid, inet_ntoa(clnt_sa->sin_addr)); + + /* Display Class */ + if(!XdmcpReadARRAY8(&buf, &clnt_dspclass)) { + gdm_error(_("gdm_xdmcp_manage: Could not read Display Class")); + return; + } + + d=gdm_xdmcp_display_lookup(clnt_sessid); + + if(d && d->dispstat==XDMCP_PENDING) { + + gdm_debug("gdm_xdmcp_handle_manage: Looked up %s", d->name); + + /* Log all output from spawned programs to a file */ + logfd=open(g_strconcat(GdmLogDir, "/", d->name, ".log", NULL), + O_CREAT|O_TRUNC|O_APPEND|O_WRONLY, 0666); + + if(logfd != -1) { + dup2(logfd, 1); + dup2(logfd, 2); + } + else + gdm_error(_("gdm_xdmcp_handle_manage: Could not open logfile for display %s!"), d->name); + + d->dispstat=XDMCP_MANAGED; + sessions++; + pending--; + + /* Start greeter/session */ + if(!gdm_display_manage(d)) { + gdm_xdmcp_send_failed(clnt_sa, clnt_sessid); + return; + } + } + else if (d && d->dispstat==XDMCP_MANAGED) { + gdm_debug("gdm_xdmcp_handle_manage: Session id %d already managed", clnt_sessid); + } + else { + gdm_debug("gdm_xdmcp_handle_manage: Failed to look up session id %d", clnt_sessid); + gdm_xdmcp_send_refuse(clnt_sa, clnt_sessid); + } +} + + +static void +gdm_xdmcp_send_refuse(struct sockaddr_in *clnt_sa, CARD32 sessid) +{ + XdmcpHeader header; + + gdm_debug("gdm_xdmcp_send_refuse: Sending REFUSE to %d", sessid); + + header.version=XDM_PROTOCOL_VERSION; + header.opcode=(CARD16) REFUSE; + header.length=4; + + XdmcpWriteHeader(&buf, &header); + XdmcpWriteCARD32(&buf, sessid); + XdmcpFlush(xdmcpfd, &buf, clnt_sa, sizeof(struct sockaddr_in)); +} + + +static void +gdm_xdmcp_send_failed(struct sockaddr_in *clnt_sa, CARD32 sessid) +{ + XdmcpHeader header; + ARRAY8 status; + + gdm_debug("gdm_xdmcp_send_failed: Sending FAILED to %d", sessid); + + status.data=g_strdup("Failed to start session"); + status.length=strlen(status.data); + + header.version=XDM_PROTOCOL_VERSION; + header.opcode=(CARD16) FAILED; + header.length=6+status.length; + + XdmcpWriteHeader(&buf, &header); + XdmcpWriteCARD32(&buf, sessid); + XdmcpWriteARRAY8(&buf, &status); + XdmcpFlush(xdmcpfd, &buf, clnt_sa, sizeof(struct sockaddr_in)); +} + + +static void +gdm_xdmcp_handle_keepalive(struct sockaddr_in *clnt_sa, gint len) +{ + CARD16 clnt_dspnum; + CARD32 clnt_sessid; + + gdm_debug("gdm_xdmcp_handle_keepalive: Got KEEPALIVE from %s", + inet_ntoa(clnt_sa->sin_addr)); + + /* Check with tcp_wrappers if client is allowed to access */ + if(!gdm_xdmcp_host_allow(clnt_sa)) { + gdm_error(_("gdm_xdmcp_handle_keepalive: Got KEEPALIVE from banned host %s"), + inet_ntoa(clnt_sa->sin_addr)); + return; + } + + /* Remote display number */ + if(!XdmcpReadCARD16(&buf, &clnt_dspnum)) { + gdm_error(_("gdm_xdmcp_handle_keepalive: Could not read Display Number")); + return; + } + + /* SessionID */ + if(!XdmcpReadCARD32(&buf, &clnt_sessid)) { + gdm_error(_("gdm_xdmcp_handle_keepalive: Could not read Session ID")); + return; + } + + gdm_xdmcp_send_alive(clnt_sa, clnt_sessid); +} + + +static void +gdm_xdmcp_send_alive(struct sockaddr_in *clnt_sa, CARD32 sessid) +{ + XdmcpHeader header; + + gdm_debug("Sending ALIVE to %d", sessid); + + header.version=XDM_PROTOCOL_VERSION; + header.opcode=(CARD16) ALIVE; + header.length=5; + + XdmcpWriteHeader(&buf, &header); + XdmcpWriteCARD8 (&buf, 1); + XdmcpWriteCARD32(&buf, sessid); + XdmcpFlush(xdmcpfd, &buf, clnt_sa, sizeof(struct sockaddr_in)); +} + + +static gboolean +gdm_xdmcp_host_allow(struct sockaddr_in *clnt_sa) +{ +#ifdef HAVE_TCPWRAPPERS + struct hostent *client_he; + gchar *client; + + /* Find client hostname */ + client_he=gethostbyaddr((gchar *) &clnt_sa->sin_addr, + sizeof(struct in_addr), + AF_INET); + + client=(client_he && client_he->h_name) ? client_he->h_name : NULL; + + /* Check with tcp_wrappers if client is allowed to access */ + return(hosts_ctl("gdm", client ? client : "unknown", inet_ntoa(clnt_sa->sin_addr), "")); +#else + return(TRUE); +#endif +} + + +static GdmDisplay * +gdm_xdmcp_display_alloc (struct sockaddr_in *clnt_sa, gint displaynum) +{ + GdmDisplay *d; + struct hostent *client_he; + + d = g_malloc(sizeof(GdmDisplay)); + d->auth = NULL; + d->command = NULL; + d->greetpid = 0; + d->id = 0; + d->servpid = 0; + d->servstat = 0; + d->sessionid = 0; + d->sesspid = 0; + d->slavepid = 0; + d->type = DISPLAY_XDMCP; + d->dispstat = XDMCP_PENDING; + d->sessionid = globsessid++; + d->acctime = time(NULL); + d->dispnum = displaynum; + + /* Find client hostname */ + client_he=gethostbyaddr((gchar *) &clnt_sa->sin_addr, + sizeof(struct in_addr), + AF_INET); + + if(client_he) { + d->name=g_strdup_printf("%s:%d", client_he->h_name, + displaynum); + } + else + d->name=g_strdup_printf("%s:%d", inet_ntoa(clnt_sa->sin_addr), + displaynum); + + /* Check if we are already talking to this host */ + gdm_xdmcp_display_dispose_check(d->name); + + /* Secure display with cookie */ + gdm_auth_secure_display(d); + + displays=g_slist_append(displays, d); + + pending++; + + gdm_debug("gdm_xdmcp_display_alloc: display=%s, session id=%d, pending=%d ", + d->name, d->sessionid, pending); + + return(d); +} + + +static GdmDisplay * +gdm_xdmcp_display_lookup(CARD32 sessid) +{ + GSList *dlist=displays; + GdmDisplay *d; + + while(dlist) { + d=(GdmDisplay *)dlist->data; + + if(d && d->sessionid == sessid) + return(d); + + dlist=dlist->next; + } + + return(NULL); +} + + +static void +gdm_xdmcp_display_dispose_check(gchar *name) +{ + GSList *dlist=displays; + GdmDisplay *d; + + gdm_debug("gdm_xdmcp_display_dispose_check(%s)", name); + + while(dlist) { + d=(GdmDisplay *)dlist->data; + + if(d && !strcmp(d->name, name)) + gdm_display_dispose(d); + + dlist=dlist->next; + } +} + + +static void +gdm_xdmcp_displays_check(void) +{ + GSList *dlist=displays; + GdmDisplay *d; + + while(dlist) { + d=(GdmDisplay *)dlist->data; + + if(d && + d->type==DISPLAY_XDMCP && + d->dispstat==XDMCP_PENDING && + time(NULL) > d->acctime + GdmMaxManageWait) + { + gdm_debug("gdm_xdmcp_displays_check: Disposing session id %d", + d->sessionid); + gdm_display_dispose(d); + pending--; + } + + dlist=dlist->next; + } +} + + +/* EOF */ diff --git a/docs/Makefile.am b/docs/Makefile.am new file mode 100644 index 00000000..35720621 --- /dev/null +++ b/docs/Makefile.am @@ -0,0 +1,8 @@ +TEXT_FILES = \ + gdm-manual.txt + +docdir = $(prefix)/doc +doc_DATA = $(TEXT_FILES) + +EXTRA_DIST = $(TEXT_FILES) + diff --git a/docs/Makefile.in b/docs/Makefile.in new file mode 100644 index 00000000..61a42584 --- /dev/null +++ b/docs/Makefile.in @@ -0,0 +1,255 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOMEGNORBA_LIBS = @GNOMEGNORBA_LIBS@ +GNOMEUI_LIBS = @GNOMEUI_LIBS@ +GNOME_APPLET_LIBS = @GNOME_APPLET_LIBS@ +GNOME_CONFIG = @GNOME_CONFIG@ +GNOME_INCLUDEDIR = @GNOME_INCLUDEDIR@ +GNOME_LIBDIR = @GNOME_LIBDIR@ +GNOME_LIBS = @GNOME_LIBS@ +GNORBA_CFLAGS = @GNORBA_CFLAGS@ +GNORBA_LIBS = @GNORBA_LIBS@ +GTKXMHTML_LIBS = @GTKXMHTML_LIBS@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_CONFIG = @GTK_CONFIG@ +GTK_LIBS = @GTK_LIBS@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +ORBIT_CFLAGS = @ORBIT_CFLAGS@ +ORBIT_CONFIG = @ORBIT_CONFIG@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_LIBS = @ORBIT_LIBS@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +PTHREAD_LIB = @PTHREAD_LIB@ +RANLIB = @RANLIB@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XPM_LIBS = @XPM_LIBS@ +ZVT_LIBS = @ZVT_LIBS@ +ac_xauth = @ac_xauth@ +l = @l@ + +TEXT_FILES = gdm-manual.txt + + +docdir = $(prefix)/doc +doc_DATA = $(TEXT_FILES) + +EXTRA_DIST = $(TEXT_FILES) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +DATA = $(doc_DATA) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +install-docDATA: $(doc_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(docdir) + @list='$(doc_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(docdir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(docdir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(docdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(docdir)/$$p; \ + fi; fi; \ + done + +uninstall-docDATA: + @$(NORMAL_UNINSTALL) + list='$(doc_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(docdir)/$$p; \ + done +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = docs + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu docs/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-docDATA +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-docDATA +uninstall: uninstall-am +all-am: Makefile $(DATA) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(docdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: uninstall-docDATA install-docDATA tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/docs/gdm-manual.txt b/docs/gdm-manual.txt new file mode 100644 index 00000000..b4b883b1 --- /dev/null +++ b/docs/gdm-manual.txt @@ -0,0 +1,352 @@ + +The Gnome Display Manager + +1. Theory of operation + +gdm is a replacement for xdm, the X Display Manager. Unlike its +competitors (x3dm, kdm, wdm) gdm was written from scratch and does not +contain any original xdm code. + +gdm was written with simplicity and security in mind. The overall +design concept is this: + +When gdm starts it parses the config file gdm.conf. For each of the +local displays gdm forks a slave process. The main gdm process will +listen to XDMCP requests from remote displays and monitor the local +display sessions. + +The gdm slave process starts an Xserver according to information read +from the config file. gdm sets up proper X authentication and starts +up the greeter window requesting the user for login and password. + +The gdm master and slave processes are deliberately kept small and +they are believed to be secure. The program providing the user +interface is significantly more complex and is linked to several +unaudited libraries. Therefore it runs as a dedicated gdm user and +communicates with gdm through a pipe. + + +2. Overview of the config directory. + +The configuration files for gdm are located in the <prefix>/etc/gdm/ +directory. + +This is a listing of the config directory contents: + + Init/ + PostSession/ + PreSession/ + Sessions/ + gdm.conf + +gdm.conf is the main gdm configuration file. The options will be +described later in this document. + +The remaining configuration is done by dropping scripts in the +subdirectories of the gdm folder. This approach makes it easy for +package management systems to install window managers and different +session types without requiring the sysadmin/user to edit files. + +In this section we will explain the Init, PreRoot and PostRoot +directories as they are very similar. + +When the X server has been successfully started, gdm will try to run +the script called Init/<displayname>. I.e. Init/:0 for the first local +display. If this file is not found, gdm will attempt to to run +Init/Default. The script will be run as root and gdm blocks until it +terminates. Use the Init/* script for programs that are supposed to +run alongside with the gdm login window. xconsole for +instance. Commands to set the background etc. goes in this file too. + +It is up to the sysadmin to decide whether clients started by the Init +script should be killed before starting the user session. This is +controlled with the KillInitClient option in gdm.conf. + +When the user has been successfully authenticated, gdm tries to run +the PreSession script. Similar to the Init-scripts, +PreSession/<displayname> will be executed first, if that is not found +gdm will attempt to run PreSession/Default. The script will be run as +root and gdm blocks until it terminates. Use this script for local +session management or accounting stuff. The USER environment variable +contains the login of the authenticated user. The script should return +0 on success. Any other value will cause gdm to terminate the current +login process. + +Then the session script is run. Session scripts are located in the +etc/gdm/Session directory. Which one gdm runs depends on the session +the user chose in the Sessions-menu in the gdm greeter. If no session +is selected and the user has no last session stored in his +~/.gnome/gdm file, the system will choose or first script found or -- +if Sessions/Default exists -- this will be run. For instance you can +create a symlink from Gnome to Default to make Gnome the default +desktop environment. + +When the user terminates his session the PostSession script will be +run. Operation is similar to Init and PreSession. That is, gdm will +attempt to execute the script PostSession/<displayname> and if that +doesn't exist: PostSession/Default. Again the script will be run with +root priviledges, gdm will block and the USER environment variable +will contain the name of the user who just logged out. + +Neither of the Init, PreSession or PostSession scripts are necessary +and can be left out. At least one session script is required for +proper operation. + + +3. The Login Window + +gdm supports two different login modes (which happen to be selected +by changing greeter programs). + + +The gdmlogin program is a bare bones gui application providing only a +few menus and a login prompt. A graphical version of the textmode +login program, if you wish. + +gdmlogin was designed for use in environments, where usernames can't +be exposed. + + +gdmgreeter is slightly more powerful. It consists of a browser window +containing faces of all users on the system. + +~user/.gnome/photo is expected to contain an Imlib supported +image. gdmgreeter will scale down large images to the sysadmin +specified maximum. + + +4. The config file + + +4.1 Section: [appearance] + +LogoImage=@pixmapdir@/gnome-logo-large.png + Filename to display in the logo box. The image must be in an + Imlib supported format and it must be readable for the gdm + user. + +Quiver=1 + Controls whether gdmgreeter should shake the display when an + incorrect username/password is entered. Default: 1. + +Iconify=1 + The greeter window can be iconified (For TV and fish). You can + turn the iconify option off by setting this to 0. Default: 1. + +IconFile=@pixmapdir@/gdm.xpm + File to use for gdmgreeter when it's in iconified state. The + image must be in an Imlib supported format and it must be + readable for the gdm user. + +Gtkrc= + Path to a gtkrc containing the theme for use in + gdmgreeter/gdmlogin/gdmchooser. + +NoFaceImage=@pixmapdir@/nophoto.png + (Only used by gdmgreeter) + + Default icon file for users without a personal picture in + ~/gnome/photo. The image must be in an Imlib supported format + and it must be readable for the gdm user. + +GlobalImageDir=@datadir@/faces/ + (Only used by gdmgreeter) + + Systemwide directory for icon files. The sysadmin can place + icons for users here without touching their homedirs. The + iconname represents a user name. I.e. GlobalImageDir/johndoe + would contain the icon for the user johndoe (No + extension!). The images must be in an Imlib supported format + and they must be readable for the gdm user. + + A user's own icon file will take precedence over the sysadmin + provided one. + + +4.2 Section: [system] + +ShutdownMenu=0 + Turns the Shutdown/Halt menu on/off. Default: 0 + +SuspendCommand= + If specified a Suspend item will appear in the System menu in + gdmgreeter. The command specified here will be executed + asynchronously. Please use full path! + + For instance + + SuspendCommand=/usr/bin/apm --suspend + +UserFileCutoffSize=65535 + User files larger than this value (in bytes) will be ignored + by gdm/gdmgreeter. Handy for users putting gigantic pictures + in their ~/.gnome/photo. + + In addition to the size check both gdm and gdmgreeter are + extremely picky about accessing files in user directories. + Neither will follow symlinks and they refuse to read files and + directories writable by other than the owner. + +UserIconMaxWidth=128 +UserIconMaxHeight=128 + Specifies the maximum icon sizes in the face browser. + +DefaultPath=@bindir@:/usr/local/bin:/usr/bin/X11:/usr/bin:/bin + Specifies the path which will be set in the user's session. + +VerboseAuth=0 + Specifies whether gdm should print authentication + errors. Depending on authentication type usernames might be + exposed when this option is on. + +AllowRoot=0 + Set to 1 to enable root logins. + +RelaxPermissions=0 + By default gdm ignores files/dirs writable to other users than + the owner. + + Changing the value of RelaxPermissions makes it possible to + alter this behaviour: + + 0 - Paranoia option. Only accepts user owned files and dirs. + 1 - Allow group writable files/dirs + 2 - Allow world writable files/dirs + +RetryDelay=3 + The number of seconds gdm should wait before reactivating the + entry field after a failed login. + + +4.3 Section: [messages] + +Welcome=Welcome to %h + Controls which text to display next to the logo image in the + greeter. + + `%h' will be expanded to the hostname + `%d' will be replaced by the display's hostname + `%%' will print the %-character + + +4.4 Section: [daemon] + +SessionDir=@sysconfdir@/gdm/Sessions + Directory containing the Session scripts. + +PidFile=/var/run/gdm.pid + Name of the gdm daemon pidfile. + +Greeter=@bindir@/gdmgreeter + Path and name of the login program executable. + + @bindir@/gdmlogin for the secure login window. + + @bindir@/gdmgreeter for the face browser. + +Chooser=@bindir@/gdmchooser + Path and name of the gdmchooser executable. + +User=gdm + The username under which gdm is run. + +Group=gdm + The group id under which gdmgreeter is run. + +DisplayInitDir=@sysconfdir@/gdm/Init + Directory containing the Init scripts. + +KillInitClients=1 + Determines whether gdm should kill X clients started by the + Init scripts when the user logs in. Default: 1. + +PreSessionScriptDir=@sysconfdir@/gdm/PreSession + Directory containing the PreSession scripts. + +PostSessionScriptDir=@sysconfdir@/gdm/PostSession + Directory containing the PostSession scripts. + +AuthDir=@authdir@ + Directory containing the X authentication files for the + displays. Should be owned by gdm.gdm with permissions 750. + +LogDir=@authdir@ + Directory containing the log files for the displays. By + default this is the same as the AuthDir. + + +4.5 Section: [servers] + +0=/usr/bin/X11/X +1=/usr/bin/X11/X -bpp 8 + + Control section for local X servers. Each line indicates the + local display number and which command needs to be run to + start the X server(s). + + +4.6 Section: [xdmcp] + +Enable=1 + Enables XDMCP support allowing remote displays/X terminals to + be managed by gdm. + + gdm listens for requests on UDP port 177. Access from remote + displays is controlled by the TCP Wrappers library. The + service name is `gdm'. + + You should add + + gdm: .my.domain + + or something similar to /etc/hosts.allow. See the + hosts_access(5) man page for details. + + Please note that XDMCP is not a particularly secure protocol + and that it is a good idea to block UDP port 177 on your + firewall unless you really need it. + +MaxPending=4 + To avoid denial of service attacks, gdm has fixed size queue + of pending connections. Only MaxPending displays can start at + the same time. + + Please note that this parameter does *not* limit the number of + remote displays which can be managed. It only limits the + number of simultaneous displays initiating a connection. + +MaxManageWait=20 + When gdm is ready to manage a display an ACCEPT packet is sent + to it containing a unique session id which will be used in + future conversations. + + gdm will then place the session id in the pending queue + waiting for the display to respond with a MANAGE request. + + If no response is received within MaxManageWait seconds, gdm + will declare the display dead and erase it from the pending + queue freeing up the slot for other displays. + +MaxSessions=4 + Determines the maximum number of remote display connections + which will be accepted. + +Port=177 + The UDP port number gdm should listen to for XDMCP requests. + + +4.7 Section: [chooser] + +ImageDir=@datadir@/hosts + Repository for host icon files. The sysadmin can place icons + for remote hosts here and they will appear in gdmchooser. + + The file name must match the FQDN for the host (No extension!). + Icons must be in an Imlib supported format and must be + readable to the gdm user. + +DefaultImage=@pixmapdir@/nohost.png + File name for the default host icon. + + +$Id$ diff --git a/gdm.spec b/gdm.spec new file mode 100644 index 00000000..77ad68a3 --- /dev/null +++ b/gdm.spec @@ -0,0 +1,78 @@ +# Note that this is NOT a relocatable package +%define ver 1.0.1 +%define rel 1 +%define prefix /usr + +Summary: GNOME Display Manager +Name: gdm +Version: %ver +Release: %rel +Copyright: GPL +Group: User Interface/X +Source: ftp://ftp.gnome.org/sources/gdm/gdm-%{ver}.tar.gz + +BuildRoot: /var/tmp/gdm-%{PACKAGE_VERSION}-root +Docdir: %{prefix}/doc +Requires: gnome-libs >= 1.0.0 + +%description +GNOME Display Manager allows you to log into your system with the +X Window System running. It is highly configurable, allowing you +to run several different X sessions at once on your local machine, +and can manage login connections from remote machines as well. + +%changelog + +%prep +%setup + +%build +libtoolize --copy --force +CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix --sysconfdir=/etc --localstatedir=/var +make + +%install +rm -rf $RPM_BUILD_ROOT + +/usr/sbin/useradd -u 42 -r gdm > /dev/null 2>&1 || /bin/true + +make prefix=$RPM_BUILD_ROOT%{prefix} sysconfdir=$RPM_BUILD_ROOT/etc localstatedir=$RPM_BUILD_ROOT/var install +# docs go elsewhere +rm -rf $RPM_BUILD_ROOT/%{prefix}/doc + +%clean +[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT + +%pre +/usr/sbin/useradd -u 42 -r gdm > /dev/null 2>&1 +# ignore errors, as we can't disambiguate between gdm already existed +# and couldn't create account with the current adduser. +exit 0 + +%files +%defattr(-, root, root) + +%doc AUTHORS COPYING ChangeLog NEWS README README.install docs/gdm-manual.txt +%{prefix}/bin/* +%config /etc/pam.d/gdm +%config /etc/gnomerc +%config /etc/gdm/gdm.conf +%config /etc/gdm/Sessions/* +%{prefix}/share/locale/*/*/* +%{prefix}/share/pixmaps/* +%attr(750, gdm, gdm) %dir /var/gdm + +%changelog +* Thu Mar 4 1999 Martin K. Petersen <mkp@mkp.net> +- misc. fixes. Red Hatters: I removed your gdm.conf/Xsession patch + from this spec file. Stuff it back in for your own builds. + +* Thu Feb 25 1999 Michael Fulbright <drmike@redhat.com> +- moved files from /usr/etc to /etc + +* Tue Feb 16 1999 Michael Johnson <johnsonm@redhat.com> +- removed commented-out #1 definition -- put back after testing gnome-libs + comment patch + +* Sat Feb 06 1999 Michael Johnson <johnsonm@redhat.com> +- initial packaging diff --git a/gui/Makefile.am b/gui/Makefile.am new file mode 100644 index 00000000..fffcd01f --- /dev/null +++ b/gui/Makefile.am @@ -0,0 +1,25 @@ +## Process this file with automake to produce makefile.in +CFLAGS += -g -Wall \ + -Wpointer-arith \ + -Wmissing-prototypes -Wmissing-declarations + +DEFS += -DGDM_CONFIG_FILE=\"@sysconfdir@/gdm/gdm.conf\" + +INCLUDES = -I. -I.. -I$(top_srcdir)/daemon -I$(includedir) \ + -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ + -DLOCALEDIR=\"$(datadir)/locale\" \ + $(GNOME_INCLUDEDIR) + +bin_PROGRAMS = gdmchooser gdmlogin + +gdmchooser_SOURCES = \ + gdmchooser.c \ + gdmchooser.h + +gdmlogin_SOURCES = \ + gdmlogin.c \ + filecheck.c + +gdmchooser_LDADD = $(GNOME_LIBDIR) $(GNOME_LIBS) $(GNOMEUI_LIBS) -lXdmcp -lX11 $(INTLLIBS) +gdmlogin_LDADD = $(GNOME_LIBDIR) $(GNOME_LIBS) $(GNOMEUI_LIBS) $(INTLLIBS) + diff --git a/gui/Makefile.in b/gui/Makefile.in new file mode 100644 index 00000000..f09d6c95 --- /dev/null +++ b/gui/Makefile.in @@ -0,0 +1,400 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CPPFLAGS = @CPPFLAGS@ +DATADIRNAME = @DATADIRNAME@ +DLLTOOL = @DLLTOOL@ +GENCAT = @GENCAT@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOMEGNORBA_LIBS = @GNOMEGNORBA_LIBS@ +GNOMEUI_LIBS = @GNOMEUI_LIBS@ +GNOME_APPLET_LIBS = @GNOME_APPLET_LIBS@ +GNOME_CONFIG = @GNOME_CONFIG@ +GNOME_INCLUDEDIR = @GNOME_INCLUDEDIR@ +GNOME_LIBDIR = @GNOME_LIBDIR@ +GNOME_LIBS = @GNOME_LIBS@ +GNORBA_CFLAGS = @GNORBA_CFLAGS@ +GNORBA_LIBS = @GNORBA_LIBS@ +GTKXMHTML_LIBS = @GTKXMHTML_LIBS@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_CONFIG = @GTK_CONFIG@ +GTK_LIBS = @GTK_LIBS@ +GT_NO = @GT_NO@ +GT_YES = @GT_YES@ +INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ +INSTOBJEXT = @INSTOBJEXT@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +NM = @NM@ +ORBIT_CFLAGS = @ORBIT_CFLAGS@ +ORBIT_CONFIG = @ORBIT_CONFIG@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_LIBS = @ORBIT_LIBS@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +PTHREAD_LIB = @PTHREAD_LIB@ +RANLIB = @RANLIB@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XPM_LIBS = @XPM_LIBS@ +ZVT_LIBS = @ZVT_LIBS@ +ac_xauth = @ac_xauth@ +l = @l@ + +CFLAGS = @CFLAGS@ -g -Wall -Wpointer-arith -Wmissing-prototypes -Wmissing-declarations + + +DEFS = -DGDM_CONFIG_FILE=\"@sysconfdir@/gdm/gdm.conf\" + +INCLUDES = -I. -I.. -I$(top_srcdir)/daemon -I$(includedir) -DGNOMELOCALEDIR=\""$(datadir)/locale"\" -DLOCALEDIR=\"$(datadir)/locale\" $(GNOME_INCLUDEDIR) + + +bin_PROGRAMS = gdmchooser gdmlogin + +gdmchooser_SOURCES = gdmchooser.c gdmchooser.h + + +gdmlogin_SOURCES = gdmlogin.c filecheck.c + + +gdmchooser_LDADD = $(GNOME_LIBDIR) $(GNOME_LIBS) $(GNOMEUI_LIBS) -lXdmcp -lX11 $(INTLLIBS) +gdmlogin_LDADD = $(GNOME_LIBDIR) $(GNOME_LIBS) $(GNOMEUI_LIBS) $(INTLLIBS) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(bin_PROGRAMS) + +LIBS = @LIBS@ +gdmchooser_OBJECTS = gdmchooser.o +gdmchooser_DEPENDENCIES = +gdmchooser_LDFLAGS = +gdmlogin_OBJECTS = gdmlogin.o filecheck.o +gdmlogin_DEPENDENCIES = +gdmlogin_LDFLAGS = +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +DEP_FILES = .deps/filecheck.P .deps/gdmchooser.P .deps/gdmlogin.P +SOURCES = $(gdmchooser_SOURCES) $(gdmlogin_SOURCES) +OBJECTS = $(gdmchooser_OBJECTS) $(gdmlogin_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu gui/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +gdmchooser: $(gdmchooser_OBJECTS) $(gdmchooser_DEPENDENCIES) + @rm -f gdmchooser + $(LINK) $(gdmchooser_LDFLAGS) $(gdmchooser_OBJECTS) $(gdmchooser_LDADD) $(LIBS) + +gdmlogin: $(gdmlogin_OBJECTS) $(gdmlogin_DEPENDENCIES) + @rm -f gdmlogin + $(LINK) $(gdmlogin_LDFLAGS) $(gdmlogin_OBJECTS) $(gdmlogin_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = gui + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu gui/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-binPROGRAMS +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-binPROGRAMS +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags mostlyclean-depend \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-binPROGRAMS clean-compile clean-libtool clean-tags \ + clean-depend clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-binPROGRAMS distclean-compile distclean-libtool \ + distclean-tags distclean-depend distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-depend \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ +maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir \ +mostlyclean-depend distclean-depend clean-depend \ +maintainer-clean-depend info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/gui/gdmchooser.c b/gui/gdmchooser.c new file mode 100644 index 00000000..7cdf970b --- /dev/null +++ b/gui/gdmchooser.c @@ -0,0 +1,676 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@SunSITE.auc.dk> + * + * 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 <config.h> +#include <gnome.h> +#include <stdio.h> +#include <stdlib.h> +#include <dirent.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> +#include <X11/Xlib.h> +#include <X11/Xmd.h> +#include <X11/Xdmcp.h> +#include <gdk/gdkx.h> +#include <gdk/gdkkeysyms.h> +#include <pwd.h> +#include <syslog.h> +#include <ctype.h> +#include <signal.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <net/if.h> + +#include "gdmchooser.h" + +static const gchar RCSid[]="$Id$"; + +static void gdm_chooser_decode_packet(void); +static GdmChooserHost *gdm_chooser_host_alloc (gchar *hostname, gchar *description); +static void gdm_chooser_abort(const gchar *format, ...); +static void gdm_chooser_browser_update(void); +static void gdm_chooser_xdmcp_init(void); +static void gdm_chooser_host_dispose(GdmChooserHost *host); + +int XdmcpReallocARRAY8 (ARRAY8Ptr array, int length); + + +typedef struct _XdmAuth { + ARRAY8 authentication; + ARRAY8 authorization; +} XdmAuthRec, *XdmAuthPtr; + +static XdmAuthRec authlist = { + { (CARD16) 0, (CARD8 *) 0 }, + { (CARD16) 0, (CARD8 *) 0 } +}; + + +gint sockfd; +static XdmcpBuffer querybuf; +GSList *bcaddr; + +gint GdmIconMaxHeight; +gint GdmIconMaxWidth; +gint GdmDebug; +gint GdmRescanTime; +gint GdmDeadTime; +gchar *GdmHostIconDir; +gchar *GdmHostDefaultIcon; +gchar *GdmGtkRC; + +GtkWidget *chooser; +GtkWidget *manage; +GtkWidget *rescan; +GtkWidget *cancel; + +gint maxwidth=0; +guint tid; +GIOChannel *channel; + +GList *hosts=NULL; +GdkImlibImage *nohostimg; +GnomeIconList *browser; + +GdmChooserHost *curhost; + + +static gint +gdm_chooser_sort_func(gpointer d1, gpointer d2) +{ + GdmChooserHost *a=d1; + GdmChooserHost *b=d2; + + return strcmp(a->name, b->name); +} + + +static void +gdm_chooser_decode_packet(void) +{ + struct sockaddr_in clnt_sa; + gint sa_len=sizeof(clnt_sa); + static XdmcpBuffer buf; + XdmcpHeader header; + struct hostent *he; + gchar *hostname, *status=NULL; + ARRAY8 auth, host, stat; + + if(!XdmcpFill(sockfd, &buf, &clnt_sa, &sa_len)) + return; + + if(!XdmcpReadHeader(&buf, &header)) + return; + + if(header.version != XDM_PROTOCOL_VERSION) + return; + + if(header.opcode == WILLING) { + if(!XdmcpReadARRAY8(&buf, &auth)) + goto done; + + if(!XdmcpReadARRAY8(&buf, &host)) + goto done; + + if(!XdmcpReadARRAY8(&buf, &stat)) + goto done; + + status=g_strndup(stat.data, stat.length); + + he=gethostbyaddr((gchar *) &clnt_sa.sin_addr, + sizeof(struct in_addr), + AF_INET); + + hostname=(he && he->h_name) ? he->h_name : inet_ntoa(clnt_sa.sin_addr); + + hosts=g_list_insert_sorted(hosts, + gdm_chooser_host_alloc(hostname, (gchar *) status), + (GCompareFunc) gdm_chooser_sort_func); + + done: + XdmcpDisposeARRAY8(&auth); + XdmcpDisposeARRAY8(&host); + XdmcpDisposeARRAY8(&stat); + + g_free(status); + + return; + } + +} + + +/* Find broadcast address for all active, non pointopoint interfaces */ +static void +gdm_chooser_find_bcaddr(void) +{ + gint i=0; + struct ifconf ifcfg; + struct ifreq ifr[MAXIF]; + struct in_addr *ia; + + ifcfg.ifc_buf=(gchar *)𝔦 + ifcfg.ifc_len=sizeof(ifr); + + memset(ifr, 0, sizeof(ifr)); + + if(ioctl(sockfd, SIOCGIFCONF, &ifcfg) < 0) + gdm_chooser_abort("Could not get SIOCIFCONF"); + + for(i=0 ; i < MAXIF ; i++) + if(strlen(ifr[i].ifr_name)) { + struct ifreq *ifreq; + struct sockaddr_in *ba; + + ifreq=g_new0(struct ifreq, 1); + + strncpy(ifreq->ifr_name, ifr[i].ifr_name, sizeof(ifr[i].ifr_name)); + + if(ioctl(sockfd, SIOCGIFFLAGS, ifreq) < 0) + gdm_chooser_abort("Could not get SIOCGIFFLAGS for %s", ifr[i].ifr_name); + + if((ifreq->ifr_flags & IFF_UP) == 0) + goto done; + + if((ifreq->ifr_flags & IFF_BROADCAST) == 0) + goto done; + + if(ioctl(sockfd, SIOCGIFBRDADDR, ifreq) < 0) { + goto done; + } + + ba=(struct sockaddr_in *)&ifreq->ifr_broadaddr; + + ia=g_new0(struct in_addr, 1); + + ia->s_addr = ba->sin_addr.s_addr; + + bcaddr=g_slist_append(bcaddr, ia); + + done: + g_free(ifreq); + } +} + + +static gboolean +gdm_chooser_xdmcp_discover(void) +{ + struct sockaddr_in sock; + GSList *bl=bcaddr; + struct in_addr *ia; + GList *hl=hosts; + + gtk_widget_set_sensitive (chooser, FALSE); + gnome_icon_list_freeze(browser); + gnome_icon_list_clear(browser); + + while(hl) { + gdm_chooser_host_dispose((GdmChooserHost *) hl->data); + hl=hl->next; + } + + g_list_free(hosts); + + hosts=NULL; + + sock.sin_family = AF_INET; + sock.sin_port = htons (XDM_UDP_PORT); + + while(bl) { + ia = (struct in_addr *)bl->data; + + sock.sin_addr.s_addr = ia->s_addr; + XdmcpFlush (sockfd, &querybuf, &sock, sizeof(struct sockaddr_in)); + bl=bl->next; + } + + tid=g_timeout_add(GdmRescanTime*1000, + (GSourceFunc) gdm_chooser_browser_update, NULL); + + return(TRUE); +} + + +static void +gdm_chooser_xdmcp_init(void) +{ + static XdmcpHeader header; + gint sockopts=1; + + /* Open socket for communication */ + if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + gdm_chooser_abort("Could not create socket()!"); + + if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (char *)&sockopts, sizeof (sockopts)) < 0) + gdm_chooser_abort("Could not set socket options!"); + + gdm_chooser_find_bcaddr(); + + /* Assemble XDMCP BROADCAST_QUERY packet in static buffer */ + header.opcode = (CARD16) BROADCAST_QUERY; + header.length = 1; + header.version = XDM_PROTOCOL_VERSION; + XdmcpWriteHeader(&querybuf, &header); + XdmcpWriteARRAY8(&querybuf, &authlist.authentication); + + channel = g_io_channel_unix_new(sockfd); + g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, + G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL, + (GIOFunc) gdm_chooser_decode_packet, + GINT_TO_POINTER(sockfd), NULL); + g_io_channel_unref(channel); + + gdm_chooser_xdmcp_discover(); +} + + +static gboolean +gdm_chooser_cancel(void) +{ + closelog(); + gtk_main_quit(); + + return(TRUE); +} + + +static gboolean +gdm_chooser_manage(void) +{ + if(curhost) + g_print("%s\n", curhost->name); + + closelog(); + gtk_main_quit(); + + return(TRUE); +} + + +static void +gdm_chooser_abort(const gchar *format, ...) +{ + va_list args; + gchar *s; + + va_start(args, format); + s=g_strdup_vprintf(format, args); + va_end(args); + + syslog(LOG_ERR, s); + + closelog(); + exit(EXIT_FAILURE); +} + + +static void +gdm_chooser_parse_config(void) +{ + struct stat unused; + + if(stat(GDM_CONFIG_FILE, &unused) == -1) + gdm_chooser_abort(_("gdm_chooser_parse_config: No configuration file: %s. Aborting."), GDM_CONFIG_FILE); + + gnome_config_push_prefix ("=" GDM_CONFIG_FILE "=/"); + + GdmGtkRC=gnome_config_get_string("appearance/gtkrc"); + + GdmRescanTime=gnome_config_get_int("chooser/rescantime=3"); + GdmDeadTime=gnome_config_get_int("chooser/deadtime=3"); + GdmHostDefaultIcon=gnome_config_get_string("chooser/defaultimage=nohost.xpm"); + GdmHostIconDir=gnome_config_get_string("chooser/imagedir"); + + GdmIconMaxWidth=gnome_config_get_int("system/UserIconMaxWidth=128"); + GdmIconMaxHeight=gnome_config_get_int("system/UserIconMaxHeight=128"); + + GdmDebug=gnome_config_get_int("debug/enable=0"); + + gnome_config_pop_prefix (); +} + + +static gboolean +gdm_chooser_browser_select(GtkWidget *widget, gint selected, GdkEvent *event) +{ + if(!event) + return(TRUE); + else + switch(event->type) { + + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + curhost=g_list_nth_data(hosts, selected); + gtk_widget_set_sensitive (manage, TRUE); + break; + + default: + break; + } + + return(TRUE); +} + + +static gboolean +gdm_chooser_browser_unselect(GtkWidget *widget, gint selected, GdkEvent *event) +{ + if(event) { + switch(event->type) { + + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + curhost=NULL; + gtk_widget_set_sensitive (manage, FALSE); + break; + + default: + break; + } + } + + return(TRUE); +} + + +static void +gdm_chooser_browser_update(void) +{ + GList *list=hosts; + + g_source_remove(tid); + + while(list) { + GdmChooserHost *host; + gchar *temp; + + host=(GdmChooserHost *)list->data; + + temp=g_strconcat(host->name, "\n", host->desc, NULL); + gnome_icon_list_append_imlib(browser, host->picture, temp); + g_free(temp); + + list=list->next; + } + + gnome_icon_list_thaw(browser); + + gtk_widget_set_sensitive(chooser, TRUE); + gtk_widget_set_sensitive(manage, FALSE); + gtk_widget_show_all(chooser); +} + + +static void +gdm_chooser_gui_init (void) +{ + GdkWindow *rootwin; + GtkWidget *frame; + GtkWidget *vbox; + GtkWidget *bbox; + GtkWidget *buttonpane; + GtkWidget *scrollbar; + GtkWidget *bframe; + GtkStyle *style; + GdkColor bbg = { 0, 0xFFFF, 0xFFFF, 0xFFFF }; + struct stat statbuf; + + /* Enable theme */ + if(GdmGtkRC) + gtk_rc_parse(GdmGtkRC); + + /* Load default host image */ + if(stat(GdmHostDefaultIcon, &statbuf)) + gdm_chooser_abort(_("Can't open default host icon: %s"), GdmHostDefaultIcon); + else { + nohostimg=gdk_imlib_load_image(GdmHostDefaultIcon); + maxwidth=nohostimg->rgb_width; + } + + /* Root Window */ + rootwin=gdk_window_foreign_new (GDK_ROOT_WINDOW ()); + + /* Main window */ + chooser = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_container_border_width (GTK_CONTAINER (chooser), 0); + + /* 3D frame for main window */ + frame = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME (frame), GTK_SHADOW_OUT); + gtk_container_border_width (GTK_CONTAINER (frame), 0); + gtk_container_add(GTK_CONTAINER (chooser), frame); + + /* Vertical box containing browser box and button pane */ + vbox = gtk_vbox_new(FALSE, 10); + gtk_container_border_width (GTK_CONTAINER (vbox), 10); + gtk_container_add(GTK_CONTAINER (frame), vbox); + + /* Find background style for browser */ + style = gtk_style_copy (chooser->style); + style->bg[GTK_STATE_NORMAL] = bbg; + gtk_widget_push_style(style); + + /* Icon list */ + if(maxwidth < GdmIconMaxWidth/2) + maxwidth=(gint) GdmIconMaxWidth/2; + + browser = GNOME_ICON_LIST (gnome_icon_list_new (maxwidth+20, NULL, FALSE)); + gnome_icon_list_freeze (GNOME_ICON_LIST (browser)); + gnome_icon_list_set_separators (browser, " /-_."); + gnome_icon_list_set_row_spacing (browser, 2); + gnome_icon_list_set_col_spacing (browser, 2); + gnome_icon_list_set_icon_border (browser, 2); + gnome_icon_list_set_text_spacing (browser, 2); + gnome_icon_list_set_selection_mode (browser, GTK_SELECTION_SINGLE); + gtk_signal_connect (GTK_OBJECT (browser), "select_icon", + GTK_SIGNAL_FUNC (gdm_chooser_browser_select), NULL); + gtk_signal_connect (GTK_OBJECT (browser), "unselect_icon", + GTK_SIGNAL_FUNC (gdm_chooser_browser_unselect), NULL); + gtk_widget_pop_style(); + + /* Browser 3D frame */ + bframe = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME (bframe), GTK_SHADOW_IN); + gtk_container_add(GTK_CONTAINER(bframe), GTK_WIDGET(browser)); + + /* Browser scroll bar */ + scrollbar = gtk_vscrollbar_new (browser->adj); + + /* Box containing all browser functionality */ + bbox = gtk_hbox_new (0, 0); + gtk_box_pack_start (GTK_BOX (bbox), GTK_WIDGET (bframe), 1, 1, 0); + gtk_box_pack_start (GTK_BOX (bbox), scrollbar, 0, 0, 0); + gtk_widget_show_all(GTK_WIDGET(bbox)); + + /* Put browser box in main window */ + gtk_box_pack_start(GTK_BOX (vbox), GTK_WIDGET(bbox), TRUE, TRUE, 0); + + /* Buttons */ + manage = gtk_button_new_with_label(_("Connect")); + gtk_signal_connect(GTK_OBJECT (manage), "clicked", + GTK_SIGNAL_FUNC (gdm_chooser_manage), NULL); + GTK_WIDGET_SET_FLAGS(manage, GTK_CAN_DEFAULT); + gtk_widget_set_sensitive (manage, FALSE); + gtk_widget_show(manage); + + rescan = gtk_button_new_with_label(_("Rescan")); + gtk_signal_connect(GTK_OBJECT (rescan), "clicked", + GTK_SIGNAL_FUNC (gdm_chooser_xdmcp_discover), NULL); + GTK_WIDGET_SET_FLAGS(rescan, GTK_CAN_DEFAULT); + gtk_widget_show(rescan); + + cancel = gtk_button_new_with_label(_("Cancel")); + gtk_signal_connect(GTK_OBJECT (cancel), "clicked", + GTK_SIGNAL_FUNC (gdm_chooser_cancel), NULL); + GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT); + gtk_widget_show(cancel); + + /* Button pane */ + buttonpane = gtk_hbox_new(TRUE, 0); + gtk_container_set_border_width(GTK_CONTAINER (buttonpane), 0); + gtk_box_pack_start(GTK_BOX (buttonpane), + manage, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX (buttonpane), + rescan, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX (buttonpane), + cancel, TRUE, TRUE, 0); + gtk_window_set_default(GTK_WINDOW(chooser), GTK_WIDGET(manage)); + gtk_widget_show_all(buttonpane); + + /* Put button pane in main window */ + gtk_box_pack_end(GTK_BOX (vbox), + buttonpane, FALSE, FALSE, 0); + + gtk_widget_show(vbox); + gtk_widget_show(frame); + + gtk_window_set_policy(GTK_WINDOW (chooser), 1, 1, 1); + gtk_window_set_focus(GTK_WINDOW (chooser), manage); + + /* Geometry fun */ + gtk_widget_show_all(GTK_WIDGET(browser)); + gnome_icon_list_thaw (GNOME_ICON_LIST (browser)); + gtk_widget_set_usize(GTK_WIDGET (chooser), + (gint) gdk_screen_width() * 0.4, + (gint) gdk_screen_height() * 0.6); + + gtk_window_position(GTK_WINDOW (chooser), GTK_WIN_POS_CENTER); + gtk_widget_show_all(chooser); +} + + +static void +gdm_chooser_signals_init(void) +{ + struct sigaction hup; + sigset_t mask; + + hup.sa_handler = (void *) gdm_chooser_cancel; + hup.sa_flags = 0; + sigemptyset(&hup.sa_mask); + + if(sigaction(SIGHUP, &hup, NULL) < 0) + gdm_chooser_abort(_("main: Error setting up HUP signal handler")); + + if(sigaction(SIGINT, &hup, NULL) < 0) + gdm_chooser_abort(_("main: Error setting up INT signal handler")); + + if(sigaction(SIGTERM, &hup, NULL) < 0) + gdm_chooser_abort(_("main: Error setting up TERM signal handler")); + + sigfillset(&mask); + sigdelset(&mask, SIGTERM); + sigdelset(&mask, SIGHUP); + sigdelset(&mask, SIGINT); + + if(sigprocmask(SIG_SETMASK, &mask, NULL) == -1) { + syslog(LOG_ERR, "Could not set signal mask!"); + exit(EXIT_FAILURE); + } +} + +static GdmChooserHost * +gdm_chooser_host_alloc (gchar *hostname, gchar *description) +{ + GdmChooserHost *host; + GdkImlibImage *imlibimg; + gint w, h; + gchar *hostimg; + struct stat statbuf; + + host=g_malloc(sizeof(GdmChooserHost)); + host->name=g_strdup(hostname); + host->desc=g_strdup(description); + + hostimg=g_strconcat(GdmHostIconDir, "/", hostname, NULL); + + if (!stat(hostimg, &statbuf) && (imlibimg=gdk_imlib_load_image(hostimg))) { + + w=imlibimg->rgb_width; + h=imlibimg->rgb_height; + + if(w>h && w>GdmIconMaxWidth) { + h=h*((gfloat) GdmIconMaxWidth/w); + w=GdmIconMaxWidth; + } + else if(h>GdmIconMaxHeight) { + w=w*((gfloat) GdmIconMaxHeight/h); + h=GdmIconMaxHeight; + } + + maxwidth=MAX(maxwidth, w); + + host->picture=gdk_imlib_clone_scaled_image(imlibimg, w, h); + + gdk_imlib_destroy_image(imlibimg); + } + else + host->picture=nohostimg; + + g_free(hostimg); + + return (host); +} + + +static void +gdm_chooser_host_dispose(GdmChooserHost *host) +{ + if(!host) + return; + + if(host->picture != nohostimg) + gdk_imlib_destroy_image(host->picture); + + g_free(host->name); + g_free(host->desc); + g_free(host); +} + + +int +main (int argc, char *argv[]) +{ + /* Avoid creating ~gdm/.gnome stuff */ + gnome_do_not_create_directories = TRUE; + + openlog("gdmchooser", LOG_PID, LOG_DAEMON); + + gnome_init("gdmchooser", VERSION, argc, argv); + gnome_sound_shutdown(); + + gdm_chooser_parse_config(); + gdm_chooser_gui_init(); + gdm_chooser_signals_init(); + + gdm_chooser_xdmcp_init(); + + gtk_main(); + + exit(EXIT_SUCCESS); +} + +/* EOF */ diff --git a/gui/gdmchooser.h b/gui/gdmchooser.h new file mode 100644 index 00000000..97ddfd04 --- /dev/null +++ b/gui/gdmchooser.h @@ -0,0 +1,40 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@SunSITE.auc.dk> + * + * 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 __GDM_CHOOSER_H__ +#define __GDM_CHOOSER_H__ + +#include <gnome.h> + +/* If you (for some odd reason) have more than 16 interfaces in your + * machine, redefine this */ + +#define MAXIF 16 + + +typedef struct _GdmChooserHost GdmChooserHost; + +struct _GdmChooserHost { + gchar *name; + gchar *desc; + GdkImlibImage *picture; +}; + +#endif /* __GDM_CHOOSER_H__ */ + +/* EOF */ diff --git a/gui/gdmgreeter.c b/gui/gdmgreeter.c new file mode 100644 index 00000000..2c55c722 --- /dev/null +++ b/gui/gdmgreeter.c @@ -0,0 +1,1713 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@SunSITE.auc.dk> + * + * 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 + */ + +/* gdmgreeter is the graphical login part of gdm, The Gnome Display + * Manager. The greeter runs as a dedicated gdm user and communicates + * with gdm through a pipe. Thus, all files used by the program must + * be accessible for `gdm' (or whatever you set the userid to in + * gdm.conf). + */ + +#include <config.h> +#include <gnome.h> +#include <stdio.h> +#include <stdlib.h> +#include <dirent.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> +#include <gdk/gdkx.h> +#include <gdk/gdkkeysyms.h> +#include <pwd.h> +#include <syslog.h> +#include <ctype.h> +#include <signal.h> + +#include "gdmgreeter.h" + +static const gchar RCSid[]="$Id$"; + +extern gboolean gdm_file_check(gchar *caller, uid_t user, gchar *dir, gchar *file, gboolean absentok); + +gchar *gdm_greeter_session_lookup(gchar *session); +gchar *gdm_greeter_language_lookup(gchar *language); +static gdmUserType *gdm_greeter_user_alloc (gchar *logname, gint uid, gchar *homedir); + + +gint GdmCompletion; +gint GdmDebug; +gint GdmDisplayBrowser; +gint GdmDisplayLogo; +gint GdmIconMaxHeight; +gint GdmIconMaxWidth; +gint GdmIconify; +gint GdmNumberOfCols; +gint GdmQuiver; +gint GdmShutdownMenu; +gint GdmUserMaxFile; +gint GdmRelaxPerms=0; +gchar *GdmSuspend; +gchar *GdmGlobalImageDir; +gchar *GdmLogoFilename; +gchar *GdmMessageText; +gchar *GdmNofaceImageFile; +gchar *GdmConfigFilename=GDM_CONFIG_FILE; +gchar *GdmSessionDir; +gchar *GdmIconFile; +gchar *GdmMessageFont; +gchar *GdmLocaleFile; +gchar *GdmDefaultLocale; +gchar *GdmPidFile; /* Hack, not used in greeter */ +gchar *GdmDefaultPath; /* Hack Part II */ +gchar *GdmGtkRC; + +GtkWidget *greeterframe; +GtkWidget *gdmMain; +GtkWidget *logobox; +GtkWidget *msgbox; +GtkWidget *msglabel; +GtkWidget *loginentry; +GtkWidget *passwdentry; +GtkWidget *greeter; +GtkWidget *buttonpane; +GtkWidget *entrypane; +GdkWindow *rootwin; +GtkWidget *win; +GtkWidget *optionmenu; +GtkWidget *sessmenu; +GtkWidget *langmenu; +GtkWidget *loginbutton; +GtkWidget *optionbutton; +GtkWidget *browser_hbox; + +gchar *login, *passwd; +gchar *defsess = NULL; +gchar *deflang = NULL; +gchar *cursess = NULL; +gchar *curlang = NULL; +gchar *usrsess = NULL; +gchar *usrlang = NULL; + +gboolean sessmatch=FALSE; +gboolean langmatch=TRUE; +gboolean sessmod=FALSE; +gboolean langmod=TRUE; + +GCompletion *cmpl; +GList *result; +GList *users; +GSList *languages=NULL; +GSList *sessions=NULL; +GdkImlibImage *nofaceimg; +GnomeIconList *browser; + + + +/* Normal program termination */ +static void +gdm_greeter_done(void) +{ + closelog(); + gtk_main_quit(); +} + + +/* Log formatted error message and exit */ +static void +gdm_greeter_abort(const gchar *format, ...) +{ + va_list args; + gchar *s; + + va_start(args, format); + s=g_strdup_vprintf(format, args); + va_end(args); + + syslog(LOG_ERR, s); + + closelog(); + g_print("%cA", 0x2); + exit(EXIT_FAILURE); +} + + +/* Show about dialog */ +static void +gdm_greeter_about (void) +{ + const gchar *authors[] = {"Martin Kasper Petersen <mkp@mkp.net>", NULL}; + + GtkWidget *about = gnome_about_new ( _("Gnome Display Manager"), + "" VERSION "", + _("Copyright Martin K. Petersen (C) 1998, 1999"), + authors, + _("gdm manages local and remote displays and provides the user with a login window."), + NULL); + gtk_widget_show (about); +} + + +static gchar * +gdm_parse_enriched_string(gchar *s) +{ + gchar cmd, *buffer, *start; + gchar hostbuf[256]; + gchar *hostname, *temp1, *temp2, *display; + + display=getenv("DISPLAY"); + + if(!display) + return(NULL); + + temp1=strchr(display, '.'); + temp2=strchr(display, ':'); + + if(temp1) + *temp1='\0'; + else if(temp2) + *temp2='\0'; + else + return(NULL); /* Display isn't */ + + gethostname(hostbuf, 255); + hostname=g_strdup(hostbuf); + + if(!hostname) + hostname=g_strdup("Gnome"); + + if(strlen(s) > 1023) { + syslog(LOG_ERR, _("gdm_parse_enriched_string: String too long!")); + return(g_strconcat(_("Welcome to "), hostname, NULL)); + } + + if(!(buffer = g_malloc(4096))) { + syslog(LOG_ERR, _("gdm_parse_enriched_string: Could not malloc temporary buffer!")); + return(NULL); + } + + start = buffer; + + while(*s) { + + if(*s=='%' && (cmd = s[1]) != 0) { + s+=2; + + switch(cmd) { + + case 'h': + memcpy(buffer, hostname, strlen(hostname)); + buffer+=strlen(hostname); + break; + + case 'd': + memcpy(buffer, display, strlen(display)); + buffer+=strlen(display); + break; + + case '%': + *buffer++='%'; + break; + + default: + break; + }; + } + else + *buffer++=*s++; + } + + *buffer=0; + + return(g_strdup(start)); +} + + +static void +gdm_greeter_message_init(void) +{ + GtkStyle *style; + gchar *msg=NULL; + + msg=gdm_parse_enriched_string(GdmMessageText); + + msgbox = gtk_vbox_new(FALSE, 0); + + if(msg) { + style = gtk_style_new(); + gdk_font_unref(style->font); + style->font = gdk_font_load (GdmMessageFont); + gtk_widget_push_style(style); + + msglabel = gtk_label_new(msg); + gtk_box_pack_start(GTK_BOX (msgbox), msglabel, TRUE, TRUE, 0); + gtk_widget_show(msglabel); + gtk_widget_pop_style(); + } + + gtk_widget_show_all(msgbox); +} + + +static void +gdm_greeter_logo_init (void) +{ + GtkWidget *logo; + GtkWidget *frame; + + if(access(GdmLogoFilename, R_OK)) { + syslog(LOG_WARNING, _("Logo not found. No image will be displayed!")); + } + else { + logo = gnome_pixmap_new_from_file (GdmLogoFilename); + gtk_widget_show(logo); + + frame = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME (frame), GTK_SHADOW_IN); + gtk_container_add(GTK_CONTAINER(frame), logo); + gtk_widget_show(frame); + + logobox = gtk_vbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX (logobox), + frame, FALSE, FALSE, 0); + gtk_widget_show(logobox); + } +} + + +static void +gdm_greeter_parse_config(void) +{ + struct stat unused; + gchar *display; + + if(stat(GDM_CONFIG_FILE, &unused) == -1) + gdm_greeter_abort(_("gdm_greeter_parse_config: No configuration file: %s. Aborting."), GDM_CONFIG_FILE); + + gnome_config_push_prefix ("=" GDM_CONFIG_FILE "=/"); + + GdmCompletion=gnome_config_get_int("appearance/Completion=1"); + GdmDisplayBrowser=gnome_config_get_int("appearance/Browser=1"); + GdmDisplayLogo=gnome_config_get_int("appearance/Logo=1"); + GdmLogoFilename=gnome_config_get_string("appearance/LogoImage"); + GdmQuiver=gnome_config_get_int("appearance/Quiver=1"); + GdmIconify=gnome_config_get_int("appearance/iconify=1"); + GdmIconFile=gnome_config_get_string("appearance/iconfile=gdm.xpm"); + GdmNofaceImageFile= gnome_config_get_string("appearance/NoFaceImage"); + GdmGlobalImageDir=gnome_config_get_string("appearance/GlobalImageDir"); + GdmMessageFont=gnome_config_get_string("appearance/msgfont=-adobe-helvetica-bold-r-normal-*-*-180-*-*-*-*-*-*"); + GdmGtkRC=gnome_config_get_string("appearance/gtkrc"); + + GdmShutdownMenu=gnome_config_get_int("system/ShutdownMenu=0"); + GdmUserMaxFile=gnome_config_get_int("system/UserFileCutoffSize=65536"); + GdmIconMaxWidth=gnome_config_get_int("system/UserIconMaxWidth=128"); + GdmIconMaxHeight=gnome_config_get_int("system/UserIconMaxHeight=128"); + GdmSuspend=g_strdup(gnome_config_get_string("system/SuspendCommand")); + GdmLocaleFile=g_strdup(gnome_config_get_string("system/LocaleFile=/usr/share/locale/locale.alias")); + GdmDefaultLocale=g_strdup(gnome_config_get_string("system/DefaultLocale=english")); + + GdmMessageText=gnome_config_get_string(_("messages/welcome=Welcome to %h")); + + GdmSessionDir=gnome_config_get_string("daemon/sessiondir"); + + GdmDebug=gnome_config_get_int("debug/enable=0"); + + gnome_config_pop_prefix (); + + if(stat(GdmLocaleFile, &unused) == -1) + gdm_greeter_abort("gdm_greeter_parse_config: Could not open locale file %s. Aborting!", GdmLocaleFile); + + /* Disable System menu on non-local displays */ + display=getenv("DISPLAY"); + + if(!display) + gdm_greeter_abort("gdm_greeter_parse_config: DISPLAY variable not set!"); + + if(strncmp(display, ":", 1)) + GdmShutdownMenu=0; +} + + +static gboolean +gdm_greeter_query(gchar *msg) +{ + GtkWidget *req; + + req=gnome_message_box_new(msg, + GNOME_MESSAGE_BOX_QUESTION, + GNOME_STOCK_BUTTON_YES, + GNOME_STOCK_BUTTON_NO, + NULL); + + gtk_window_set_modal(GTK_WINDOW(req), TRUE); + return(!gnome_dialog_run(GNOME_DIALOG(req))); +} + + +static void +gdm_greeter_info_handler(GtkWidget *widget, GtkWidget *dialog) +{ + GdkCursor *cursor; + + cursor=gdk_cursor_new(GDK_LEFT_PTR); + gdk_window_set_cursor (gdmMain->window, cursor); + gdk_cursor_destroy(cursor); + gtk_widget_set_sensitive (gdmMain, TRUE); +} + + +static void +gdm_greeter_info(gchar *msg) +{ + GtkWidget *req; + + req=gnome_message_box_new(msg, + GNOME_MESSAGE_BOX_INFO, + GNOME_STOCK_BUTTON_OK, + NULL); + + gnome_dialog_button_connect(GNOME_DIALOG(req), + 0, + gdm_greeter_info_handler, + NULL); + + gtk_window_set_modal(GTK_WINDOW(req), TRUE); + gtk_widget_show_all(req); +} + + +static gboolean +gdm_greeter_login (GtkWidget *widget, gpointer data) +{ + GdkCursor *cursor; + + if(!strlen(gtk_entry_get_text(GTK_ENTRY(loginentry)))) + return(TRUE); + + cursor=gdk_cursor_new(GDK_WATCH); + gdk_window_set_cursor(gdmMain->window, cursor); + gdk_cursor_destroy(cursor); + gtk_widget_set_sensitive(gdmMain, FALSE); + gtk_widget_show(gdmMain); + + g_print("%cU%s\n%s\n", 0x2, gtk_entry_get_text(GTK_ENTRY (loginentry)), + gtk_entry_get_text(GTK_ENTRY (passwdentry))); + + return(TRUE); +} + + +static void +gdm_greeter_sesslang_send(void) +{ + gboolean savesess=FALSE, savelang=FALSE; + static gchar msg[1024]; + + if(strcasecmp(cursess, usrsess)) { + + if(sessmatch && sessmod) { + g_snprintf(msg, 1023, + _("You have chosen %s for this session, but your default setting is %s.\n" \ + "Do you wish to make %s the default for future sessions?"), + cursess, usrsess, cursess); + savesess=gdm_greeter_query(msg); + } + + if(!sessmatch && sessmod) { + g_snprintf(msg, 1023, + _("Your previous session type %s is not installed on this machine.\n" \ + "Do you wish to make %s the default for future sessions?"), + usrsess, cursess); + savesess=gdm_greeter_query(msg); + } + + if(!sessmatch && !sessmod) { + g_snprintf(msg, 1023, + _("Your previous session type %s is not installed on this machine.\n" \ + "You will be logged in using the %s environment."), + usrsess, cursess); + gdm_greeter_info(msg); + } + } + else + savesess=TRUE; + + if(strcasecmp(curlang, usrlang)) { + + if(langmatch && langmod) { + g_snprintf(msg, 1023, + _("You have chosen the language %s for this session, but your default setting is %s.\n" \ + "Do you wish to make %s the default language for future sessions?"), + curlang, usrlang, curlang); + savelang=gdm_greeter_query(msg); + } + + if(!langmatch && langmod) { + g_snprintf(msg, 1023, + _("Your previous language %s is not installed on this machine.\n" \ + "Do you wish to make %s the default language for future sessions?"), + usrlang, curlang); + savelang=gdm_greeter_query(msg); + } + + if(!langmatch && !langmod) { + g_snprintf(msg, 1023, + _("Your previous language %s is not installed on this machine.\n" \ + "Your environment will be %s."), + usrlang, curlang); + gdm_greeter_info(msg); + } + } + else + savelang=TRUE; + + g_print("%c%s\n%d\n%s\n%d\n", 0x3, cursess, savesess, curlang, savelang); +} + + +static void +gdm_greeter_invalid_passwd_req (void) +{ + gint i; + gint x,y; + + /* FIXME: esound! */ + if(GdmQuiver) { + gdk_window_get_position(greeter->window, &x, &y); + + for (i=32 ; i > 0 ; i=i/2) { + gdk_window_move(greeter->window, i+x, y); + gdk_window_move(greeter->window, x, y); + gdk_window_move(greeter->window, -i+x, y); + gdk_window_move(greeter->window, x, y); + } + } + + gdm_greeter_info(_("Invalid username or password!")); + + gtk_window_set_focus(GTK_WINDOW (greeter), passwdentry); +} + + +static void +gdm_greeter_reboot(gint reply, gpointer data) +{ + if (reply == GNOME_YES) { + closelog(); + g_print("%cR", 0x2); + gtk_main_quit(); + } + + gtk_widget_set_sensitive(gdmMain, TRUE); + gtk_window_set_focus(GTK_WINDOW(greeter), passwdentry); +} + + +static gboolean +gdm_greeter_reboot_handler(GtkWidget *widget, gpointer data) +{ + static GtkWidget *box=NULL; + + gtk_widget_set_sensitive(gdmMain, FALSE); + box=gnome_question_dialog_modal(_("Are you sure you want to reboot the machine?"), + GTK_SIGNAL_FUNC (gdm_greeter_reboot), + NULL); + gtk_widget_show(box); + + return(TRUE); +} + + +static void +gdm_greeter_halt(gint reply, gpointer data) +{ + if (reply == GNOME_YES) { + closelog(); + g_print("%cH", 0x2); + gtk_main_quit(); + } + + gtk_widget_set_sensitive(gdmMain, TRUE); + gtk_window_set_focus(GTK_WINDOW (greeter), passwdentry); +} + + +static gboolean +gdm_greeter_halt_handler(GtkWidget *widget, gpointer data) +{ + static GtkWidget *box=NULL; + + gtk_widget_set_sensitive (gdmMain, FALSE); + box=gnome_question_dialog_modal(_("Are you sure you want to halt the machine?"), + GTK_SIGNAL_FUNC (gdm_greeter_halt), + NULL); + gtk_widget_show(box); + + return(TRUE); +} + + +static gboolean +gdm_greeter_suspend_handler(GtkWidget *widget, int button, gpointer data) +{ + g_print("%cS", 0x2); + + return(TRUE); +} + + +typedef struct _cursoroffset {gint x,y;} CursorOffset; + + +static void +gdm_greeter_icon_pressed(GtkWidget *widget, GdkEventButton *event) +{ + CursorOffset *p; + + if(event->type == GDK_2BUTTON_PRESS) { + gtk_widget_destroy(win); + gdk_window_show(greeter->window); + return; + } + + if (event->type != GDK_BUTTON_PRESS) + return; + + p=gtk_object_get_user_data(GTK_OBJECT (widget)); + p->x=(gint)event->x; + p->y=(gint)event->y; + + gtk_grab_add(widget); + gdk_pointer_grab(widget->window, TRUE, + GDK_BUTTON_RELEASE_MASK | + GDK_BUTTON_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK, + NULL, NULL, 0); +} + + +static void +gdm_greeter_icon_released(GtkWidget *widget) +{ + gtk_grab_remove(widget); + gdk_pointer_ungrab(0); +} + + +static void +gdm_greeter_icon_motion(GtkWidget *widget, GdkEventMotion *event) +{ + gint xp, yp; + CursorOffset *p; + GdkModifierType mask; + + p=gtk_object_get_user_data(GTK_OBJECT (widget)); + gdk_window_get_pointer(rootwin, &xp, &yp, &mask); + gtk_widget_set_uposition(widget, xp-p->x, yp-p->y); +} + + +static gboolean +gdm_greeter_iconify_handler(GtkWidget *widget, gpointer data) +{ + GtkWidget *fixed; + GtkWidget *icon; + GdkGC *gc; + GtkStyle *style; + CursorOffset *icon_pos; + gint rw, rh, iw, ih; + + gdk_window_hide(greeter->window); + style=gtk_widget_get_default_style(); + gc=style->black_gc; + win=gtk_window_new(GTK_WINDOW_POPUP); + + gtk_widget_set_events(win, + gtk_widget_get_events(win) | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK); + + gtk_widget_realize(win); + + fixed=gtk_fixed_new(); + gtk_container_add(GTK_CONTAINER (win), fixed); + gtk_widget_show(fixed); + + icon=gnome_pixmap_new_from_file (GdmIconFile); + gdk_window_get_size ((GdkWindow *) GNOME_PIXMAP (icon)->pixmap, &iw, &ih); + + gtk_fixed_put(GTK_FIXED (fixed), icon, 0, 0); + gtk_widget_show(icon); + + gtk_signal_connect(GTK_OBJECT (win), "button_press_event", + GTK_SIGNAL_FUNC (gdm_greeter_icon_pressed),NULL); + gtk_signal_connect(GTK_OBJECT (win), "button_release_event", + GTK_SIGNAL_FUNC (gdm_greeter_icon_released),NULL); + gtk_signal_connect(GTK_OBJECT (win), "motion_notify_event", + GTK_SIGNAL_FUNC (gdm_greeter_icon_motion),NULL); + + icon_pos=g_new(CursorOffset, 1); + gtk_object_set_user_data(GTK_OBJECT(win), icon_pos); + + gtk_widget_show(win); + + rw=gdk_screen_width(); + rh=gdk_screen_height(); + + gtk_widget_set_uposition(win, rw-iw, rh-ih); + + return(TRUE); +} + + +static gboolean +gdm_greeter_opt_button_handler (GtkWidget *widget, GdkEvent *event) +{ + if (event->type == GDK_BUTTON_PRESS) { + GdkEventButton *bevent = (GdkEventButton *) event; + gtk_menu_popup(GTK_MENU(widget), NULL, NULL, NULL, NULL, + bevent->button, bevent->time); + return(TRUE); + } + + /* This code will probably never be reached */ + if (event->type == GDK_KEY_PRESS) { + GdkEventKey *kevent = (GdkEventKey *) event; + switch(kevent->keyval) { + + case GDK_Left: + gtk_window_set_focus(GTK_WINDOW (greeter), loginbutton); + return(TRUE); + + case GDK_Right: + return(TRUE); + + case GDK_Up: + case GDK_Tab: + gtk_window_set_focus(GTK_WINDOW (greeter), passwdentry); + return(TRUE); + + case GDK_Down: + gtk_window_set_focus(GTK_WINDOW (greeter), loginentry); + return(TRUE); + + default: + break; + } + } + + return(FALSE); +} + + +static gboolean +gdm_greeter_login_key_handler (GtkWidget *widget, GdkEventKey *event) +{ + switch(event->keyval) { + + case GDK_Return: + gdm_greeter_login(NULL, NULL); + break; + + case GDK_Up: + case GDK_Tab: + case GDK_Left: + gtk_signal_emit_stop_by_name(GTK_OBJECT (loginbutton), "key_press_event"); + gtk_window_set_focus(GTK_WINDOW (greeter), passwdentry); + break; + + case GDK_Down: + gtk_signal_emit_stop_by_name(GTK_OBJECT (loginbutton), "key_press_event"); + gtk_window_set_focus(GTK_WINDOW (greeter), loginentry); + break; + + case GDK_Right: + gtk_signal_emit_stop_by_name(GTK_OBJECT (loginbutton), "key_press_event"); + break; + + default: + break; + } + + return(TRUE); +} + + +gchar * +gdm_greeter_session_lookup(gchar *session) +{ + GSList *sess=sessions; + gchar *temp; + + if(!session) { + sessmatch=TRUE; + return(defsess); + } + + while(sess) { + gtk_label_get(GTK_LABEL(GTK_BIN(sess->data)->child), &temp); + + if(!strcmp(temp, session)) { + sessmatch=TRUE; + return(g_strdup(session)); + } + + sess=sess->next; + } + + sessmatch=FALSE; + return(defsess); +} + + +static void +gdm_greeter_session_select(GtkWidget *widget, gchar *sess) +{ + gchar *temp; + + if(!widget || !sess) + return; + + gtk_label_get(GTK_LABEL(GTK_BIN(widget)->child), &temp); + + if(!strcasecmp(temp, sess)) + gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (widget), TRUE); +} + + +static void +gdm_greeter_session_handler (GtkWidget *widget) +{ + gtk_label_get(GTK_LABEL(GTK_BIN(widget)->child), &cursess); + sessmod=TRUE; +} + + +static void +gdm_greeter_session_init(GtkWidget *parent) +{ + DIR *sessdir; + struct dirent *dent; + struct stat statbuf; + gint linklen; + GtkWidget *submenu, *item; + + /* Check that session dir is readable */ + if (access(GdmSessionDir, R_OK|X_OK)) + gdm_greeter_abort(_("gdm_greeter_session_init: Session script directory not found!")); + + /* Create submenu */ + submenu=gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent), submenu); + + /* Read directory entries in session dir */ + sessdir=opendir(GdmSessionDir); + dent=readdir(sessdir); + + while(dent != NULL) { + gchar *s; + + s=g_strconcat(GdmSessionDir, "/", dent->d_name, NULL); + lstat(s, &statbuf); + + /* If default session link exists, find out what it points to */ + if(S_ISLNK(statbuf.st_mode) && !strcasecmp(dent->d_name, "default")) { + gchar t[_POSIX_PATH_MAX]; + + linklen=readlink(s, t, _POSIX_PATH_MAX); + t[linklen]=0; + defsess=g_strdup(t); + } + + /* If session script is readable/executable add it to the list */ + if(S_ISREG(statbuf.st_mode)) { + + if((statbuf.st_mode & (S_IRUSR|S_IXUSR)) == (S_IRUSR|S_IXUSR) && + (statbuf.st_mode & (S_IRGRP|S_IXGRP)) == (S_IRGRP|S_IXGRP) && + (statbuf.st_mode & (S_IROTH|S_IXOTH)) == (S_IROTH|S_IXOTH)) + { + item=gtk_radio_menu_item_new_with_label(sessions, dent->d_name); + sessions=gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM (item)); + gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM (item), TRUE); + gtk_menu_append(GTK_MENU (submenu), item); + + gtk_signal_connect(GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (gdm_greeter_session_handler), NULL); + + gtk_widget_show(item); + } + else + syslog(LOG_ERR, "Wrong permissions on %s/%s. Should be readable/executable for all.", + GdmSessionDir, dent->d_name); + + } + + dent=readdir(sessdir); + g_free(s); + } + + if(!g_slist_length(sessions)) + gdm_greeter_abort(_("No session scripts found. Aborting!")); + + if(!defsess) { + gtk_label_get(GTK_LABEL(GTK_BIN(g_slist_nth_data(sessions, 0))->child), &defsess); + syslog(LOG_WARNING, _("No default session link found. Using %s.\n"), defsess); + } + +} + + +gchar * +gdm_greeter_language_lookup(gchar *language) +{ + GSList *lang=languages; + gchar *temp; + + if(!language) { + langmatch=TRUE; + return(deflang); + } + + while(lang) { + gtk_label_get(GTK_LABEL(GTK_BIN(lang->data)->child), &temp); + + if(!strcasecmp(temp, language)) { + langmatch=TRUE; + return(g_strdup(language)); + } + + lang=lang->next; + } + + langmatch=FALSE; + return(deflang); +} + + +static void +gdm_greeter_language_select(GtkWidget *widget, gchar *lang) +{ + gchar *temp; + + if(!widget || !lang) + return; + + gtk_label_get(GTK_LABEL(GTK_BIN(widget)->child), &temp); + + if(!strcasecmp(temp, lang)) + gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (widget), TRUE); +} + + +static void +gdm_greeter_language_handler (GtkWidget *widget) +{ + gtk_label_get(GTK_LABEL(GTK_BIN(widget)->child), &curlang); + langmod=TRUE; +} + + +static void +gdm_greeter_language_init(GtkWidget *parent) +{ + GtkWidget *submenu, *item; + FILE *langlist; + char curline[256]; + char *ctmp, *ctmp1, *ctmp2; + + deflang=GdmDefaultLocale; + + submenu = gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent), submenu); + + langlist = fopen(GdmLocaleFile, "r"); + + item = gtk_radio_menu_item_new_with_label(NULL, "English"); + languages = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(item)); + gtk_widget_show(item); + + gtk_container_add(GTK_CONTAINER(submenu), item); + gtk_signal_connect(GTK_OBJECT(item), "activate", gdm_greeter_language_handler, NULL); + + while(fgets(curline, sizeof(curline), langlist)) { + if(!isalpha(curline[0])) continue; + + ctmp1 = strchr(curline, ' '); + ctmp2 = strchr(curline, '\t'); + ctmp = curline + strlen(curline) - 1; + if(ctmp1 && (ctmp1 < ctmp)) + ctmp = ctmp1; + if(ctmp2 && (ctmp2 < ctmp)) + ctmp = ctmp2; + *ctmp = '\0'; + curline[0] = toupper(curline[0]); + + item = gtk_radio_menu_item_new_with_label(languages, curline); + languages = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(item)); + gtk_widget_show(item); + + gtk_container_add(GTK_CONTAINER(submenu), item); + gtk_signal_connect(GTK_OBJECT(item), "activate", gdm_greeter_language_handler, NULL); + } + + fclose(langlist); +} + + +static void +gdm_greeter_sl_update(gdmUserType *user) +{ + gboolean fileok; + gchar *dir=NULL, *cfg=NULL; + + /* Check if ~user/.gnome/gdm passes sanity check */ + dir=g_strconcat(user->homedir, "/.gnome", NULL); + fileok=gdm_file_check("gdm_greeter_sl_update", user->uid, dir, "gdm", TRUE); + g_free(dir); + + /* Find user's last session and language if available */ + if(fileok) { + cfg=g_strconcat("=", user->homedir, "/.gnome/gdm=/session/last", NULL); + usrsess=gnome_config_get_string(cfg); + g_free(cfg); + + cfg=g_strconcat("=", user->homedir, "/.gnome/gdm=/session/lang", NULL); + usrlang=gnome_config_get_string(cfg); + g_free(cfg); + } + + sessmatch=FALSE; + sessmod=FALSE; + cursess=gdm_greeter_session_lookup(usrsess); + + if(!usrsess) + usrsess=g_strdup(cursess); + + g_slist_foreach(sessions, (GFunc) gdm_greeter_session_select, cursess); + gtk_widget_set_sensitive (sessmenu, TRUE); + + langmatch=FALSE; + langmod=FALSE; + curlang=gdm_greeter_language_lookup(usrlang); + + if(!usrlang) + if(curlang) + usrlang=g_strdup(curlang); + else + usrlang=gdm_greeter_language_lookup("english"); + + g_slist_foreach(languages, (GFunc) gdm_greeter_language_select, curlang); + gtk_widget_set_sensitive (langmenu, TRUE); + + /* Widget magic */ + gtk_entry_set_text (GTK_ENTRY (loginentry), user->login); + gtk_window_set_focus(GTK_WINDOW (greeter), passwdentry); +} + + +static void +gdm_greeter_buttons_init(void) +{ + GtkWidget *submenu, *item; + + /* Login button */ + loginbutton = gtk_button_new_with_label(_("Login")); + gtk_signal_connect(GTK_OBJECT (loginbutton), "clicked", + GTK_SIGNAL_FUNC (gdm_greeter_login), NULL); + gtk_signal_connect(GTK_OBJECT (loginbutton), "key_press_event", + GTK_SIGNAL_FUNC (gdm_greeter_login_key_handler), NULL); + GTK_WIDGET_SET_FLAGS(loginbutton, GTK_CAN_DEFAULT); + gtk_widget_show(loginbutton); + + /* Option button drop down menu */ + optionmenu = gtk_menu_new(); + + /* Init sessions menu */ + sessmenu = gtk_menu_item_new_with_label(_("Sessions")); + gtk_menu_append(GTK_MENU (optionmenu), sessmenu); + gdm_greeter_session_init(sessmenu); + gtk_widget_show(sessmenu); + gtk_widget_set_sensitive (sessmenu, FALSE); + + /* Language selection support */ + langmenu = gtk_menu_item_new_with_label (_("Languages")); + gtk_menu_append(GTK_MENU (optionmenu), langmenu); + gdm_greeter_language_init(langmenu); + gtk_widget_show(langmenu); + gtk_widget_set_sensitive (langmenu, FALSE); + + /* If sysadmin enabled shutdown menu */ + if (GdmShutdownMenu) { + submenu = gtk_menu_new(); + + item = gtk_menu_item_new_with_label (_("Reboot...")); + gtk_menu_append(GTK_MENU (submenu), item); + gtk_signal_connect(GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (gdm_greeter_reboot_handler), NULL); + gtk_widget_show(item); + + item = gtk_menu_item_new_with_label (_("Halt...")); + gtk_menu_append(GTK_MENU (submenu), item); + gtk_signal_connect(GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (gdm_greeter_halt_handler), NULL); + gtk_widget_show(item); + + if(GdmSuspend) { + item = gtk_menu_item_new_with_label (_("Suspend")); + gtk_menu_append(GTK_MENU (submenu), item); + gtk_signal_connect(GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (gdm_greeter_suspend_handler), NULL); + gtk_widget_show(item); + } + + item = gtk_menu_item_new_with_label (_("System")); + gtk_menu_append(GTK_MENU (optionmenu), item); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); + gtk_widget_show(item); + } + + if(GdmIconify) { + if(access(GdmIconFile, R_OK)) { + syslog(LOG_WARNING, _("Can't open icon file: %s. Suspending iconify feature!"), GdmIconFile); + GdmIconify=0; + } + else { + item = gtk_menu_item_new_with_label (_("Iconify")); + gtk_menu_append(GTK_MENU (optionmenu), item); + gtk_signal_connect(GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (gdm_greeter_iconify_handler), NULL); + gtk_widget_show(item); + } + } + + /* Option button */ + optionbutton = gtk_button_new_with_label(_("Options...")); + gtk_signal_connect_object(GTK_OBJECT (optionbutton), "event", + GTK_SIGNAL_FUNC (gdm_greeter_opt_button_handler), + GTK_OBJECT(optionmenu)); + GTK_WIDGET_SET_FLAGS(optionbutton, GTK_CAN_DEFAULT); + gtk_widget_show(optionbutton); + + buttonpane = gtk_hbox_new(TRUE, 0); + gtk_container_set_border_width(GTK_CONTAINER (buttonpane), 0); + + gtk_box_pack_start(GTK_BOX (buttonpane), + loginbutton, TRUE, TRUE, 5); + gtk_box_pack_start(GTK_BOX (buttonpane), + optionbutton, TRUE, TRUE, 5); + + gtk_window_set_default(GTK_WINDOW(greeter), GTK_WIDGET(loginbutton)); + gtk_widget_show_all(buttonpane); +} + + +static gboolean +gdm_greeter_browser_select(GtkWidget *widget, gint selected, GdkEvent *event) +{ + gdmUserType *user; + + if(!event) + return(TRUE); + else + switch(event->type) { + + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + user=g_list_nth_data(result, selected); + gdm_greeter_sl_update(user); + break; + + default: + break; + } + + return(TRUE); +} + + +static gboolean +gdm_greeter_browser_unselect(GtkWidget *widget, gint selected, GdkEvent *event) +{ + if(event) { + switch(event->type) { + + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + gnome_icon_list_unselect_all((GnomeIconList *) widget, NULL, NULL); + gtk_entry_set_text (GTK_ENTRY (loginentry), ""); + gtk_window_set_focus(GTK_WINDOW (greeter), loginentry); + gtk_widget_set_sensitive (sessmenu, FALSE); + gtk_widget_set_sensitive (langmenu, FALSE); + break; + + default: + break; + } + } + + return(TRUE); +} + + +static void +gdm_greeter_browser_foreach (gdmUserType *user) +{ + if(browser) + gnome_icon_list_append_imlib (browser, user->picture, user->login); +} + + +static void +gdm_greeter_browser_init (void) +{ + GtkWidget *scrollbar; + gchar *lmatch=NULL; + GtkWidget *bframe; + GtkStyle *style; + GdkColor bbg = { 0, 0xFFFF, 0xFFFF, 0xFFFF }; + + /* + * Create icon list and scrollbar + */ + + style = gtk_style_copy (greeter->style); + style->bg[GTK_STATE_NORMAL] = bbg; + gtk_widget_push_style(style); + + browser = GNOME_ICON_LIST (gnome_icon_list_new (GdmIconMaxWidth+20, NULL, FALSE)); + gnome_icon_list_freeze (GNOME_ICON_LIST (browser)); + gtk_widget_pop_style(); + + scrollbar = gtk_vscrollbar_new (browser->adj); + bframe = gtk_frame_new(NULL); + + gtk_frame_set_shadow_type(GTK_FRAME (bframe), GTK_SHADOW_IN); + gtk_container_add(GTK_CONTAINER(bframe), GTK_WIDGET(browser)); + + browser_hbox = gtk_hbox_new (0, 0); + gtk_box_pack_start (GTK_BOX (browser_hbox), GTK_WIDGET (bframe), 1, 1, 0); + gtk_box_pack_start (GTK_BOX (browser_hbox), scrollbar, 0, 0, 0); + + gnome_icon_list_set_separators (browser, " /-_."); + gnome_icon_list_set_row_spacing (browser, 2); + gnome_icon_list_set_col_spacing (browser, 2); + gnome_icon_list_set_icon_border (browser, 2); + gnome_icon_list_set_text_spacing (browser, 2); + gnome_icon_list_set_selection_mode (browser, GTK_SELECTION_SINGLE); + + gtk_signal_connect (GTK_OBJECT (browser), "select_icon", + GTK_SIGNAL_FUNC (gdm_greeter_browser_select), NULL); + + gtk_signal_connect (GTK_OBJECT (browser), "unselect_icon", + GTK_SIGNAL_FUNC (gdm_greeter_browser_unselect), NULL); + + result = g_completion_complete(cmpl, "", &lmatch); + + if(lmatch) + gtk_entry_set_text(GTK_ENTRY (loginentry), lmatch); + + gnome_icon_list_clear (browser); + g_list_foreach(users, (GFunc) gdm_greeter_browser_foreach, NULL); + gnome_icon_list_thaw (browser); + gtk_widget_show_all(GTK_WIDGET(browser_hbox)); +} + + +static gboolean +gdm_greeter_login_entry_handler (GtkWidget *widget, GdkEventKey *event) +{ + gchar *lmatch=NULL; + gchar *entry=NULL; + gint i; + gdmUserType *user=NULL; + + gtk_widget_set_sensitive (sessmenu, FALSE); + gtk_widget_set_sensitive (langmenu, FALSE); + + switch(event->keyval) { + + case GDK_Return: + case GDK_Down: + case GDK_Tab: /* Where the nightmare begins */ + + gtk_signal_emit_stop_by_name(GTK_OBJECT (loginentry), "key_press_event"); + + entry=gtk_entry_get_text(GTK_ENTRY (loginentry)); + + if(!strlen(entry)) + entry=g_strdup(""); + + result = g_completion_complete(cmpl, entry, &lmatch); + + /* Unambiguous match => Move to passwd field and enable + * session selection + */ + if(g_list_length(result) == 1) { + gtk_window_set_focus(GTK_WINDOW (greeter), passwdentry); + gtk_widget_set_sensitive (sessmenu, TRUE); + gtk_widget_set_sensitive (langmenu, TRUE); + } + + /* One or no completions => Show all users */ + if(g_list_length(result) <= 1) + result = g_completion_complete(cmpl, "", NULL); + + /* If partial match write greatest common string in login + * field + */ + if(lmatch) + gtk_entry_set_text(GTK_ENTRY (loginentry), lmatch); + + if(GdmDisplayBrowser) { + gnome_icon_list_freeze(browser); + gnome_icon_list_clear(browser); + g_list_foreach(result, (GFunc) gdm_greeter_browser_foreach, NULL); + gnome_icon_list_thaw (browser); + } + + for (i=0 ; i<g_list_length(result) ; i++) { + user=g_list_nth_data(result, i); + + if(!strcasecmp(gtk_entry_get_text(GTK_ENTRY(loginentry)), user->login)) { + + if(GdmDisplayBrowser) { + gnome_icon_list_moveto(browser, i, 0.5); + gnome_icon_list_select_icon(browser, i); + } + + gdm_greeter_sl_update(user); + } + } + + break; + + case GDK_Up: + gtk_signal_emit_stop_by_name(GTK_OBJECT (loginentry), "key_press_event"); + break; + + case GDK_F1: + gdm_greeter_about(); + break; + + default: + break; + } + + return(TRUE); +} + + +static gboolean +gdm_greeter_passwd_entry_handler (GtkWidget *widget, GdkEventKey *event) +{ + switch(event->keyval) { + + case GDK_Return: + gdm_greeter_login(NULL, NULL); + break; + + case GDK_Up: + case GDK_Tab: + gtk_signal_emit_stop_by_name(GTK_OBJECT (passwdentry), "key_press_event"); + gtk_window_set_focus(GTK_WINDOW (greeter), loginentry); + break; + + case GDK_Down: + gtk_signal_emit_stop_by_name(GTK_OBJECT (passwdentry), "key_press_event"); + break; + + default: + break; + } + + return(TRUE); +} + + +static void +gdm_greeter_entry_init(void) +{ + GtkWidget *topsep; + GtkWidget *botsep; + GtkWidget *labelvbox; + GtkWidget *loginlabel; + GtkWidget *passwdlabel; + GtkWidget *entryvbox; + GtkWidget *gdminputhbox; + + entrypane = gtk_vbox_new(FALSE, 0); + gdminputhbox = gtk_hbox_new(FALSE, 10); + labelvbox = gtk_vbox_new(TRUE, 0); + entryvbox = gtk_vbox_new(TRUE, 0); + + topsep = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX (entrypane), topsep, + FALSE, FALSE, 10); + gtk_widget_show (topsep); + + loginlabel = gtk_label_new(_("Login:")); + gtk_misc_set_alignment (GTK_MISC (loginlabel), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX (labelvbox), loginlabel, + FALSE, FALSE, 5); + gtk_widget_show(loginlabel); + + passwdlabel = gtk_label_new(_("Password:")); + gtk_misc_set_alignment (GTK_MISC (passwdlabel), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX (labelvbox), passwdlabel, + FALSE, FALSE, 0); + gtk_widget_show(passwdlabel); + + loginentry = gtk_entry_new_with_max_length (32); + gtk_entry_set_text (GTK_ENTRY (loginentry), ""); + gtk_entry_select_region (GTK_ENTRY (loginentry), 0, + GTK_ENTRY (loginentry)->text_length); + gtk_signal_connect_object(GTK_OBJECT (loginentry), + "key_press_event", + GTK_SIGNAL_FUNC (gdm_greeter_login_entry_handler), + NULL); + + gtk_box_pack_start(GTK_BOX (entryvbox), loginentry, + FALSE, TRUE, 5); + gtk_widget_show(loginentry); + + passwdentry = gtk_entry_new_with_max_length (32); + gtk_entry_set_text (GTK_ENTRY (passwdentry), ""); + gtk_entry_set_visibility(GTK_ENTRY (passwdentry), FALSE); + gtk_signal_connect_object(GTK_OBJECT (passwdentry), + "key_press_event", + GTK_SIGNAL_FUNC (gdm_greeter_passwd_entry_handler), + NULL); + gtk_box_pack_start(GTK_BOX (entryvbox), passwdentry, + FALSE, TRUE, 5); + gtk_widget_show(passwdentry); + + gtk_box_pack_start(GTK_BOX (gdminputhbox), labelvbox, + FALSE, FALSE, 10); + gtk_widget_show (labelvbox); + + gtk_box_pack_start(GTK_BOX (gdminputhbox), entryvbox, + TRUE, TRUE, 10); + gtk_widget_show (entryvbox); + + gtk_box_pack_start(GTK_BOX (entrypane), gdminputhbox, + FALSE, FALSE, 0); + gtk_widget_show (gdminputhbox); + + botsep = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX (entrypane), botsep, + FALSE, FALSE, 10); + gtk_widget_show(botsep); + + gtk_widget_show(entrypane); +} + + +gdmUserType * +gdm_greeter_user_alloc (gchar *logname, gint uid, gchar *homedir) +{ + gdmUserType *user; + gchar *dir=NULL, *img=NULL; + gboolean fileok; + GdkImlibImage *imlibimg=NULL; + gint w, h; + + /* Allocate mem for user info struct */ + user=g_malloc(sizeof(gdmUserType)); + + if(!user) + return(NULL); + + user->uid=uid; + user->login=g_strdup(logname); + user->homedir=g_strdup(homedir); + + /* If browser enabled choose an appropriate picture */ + if(GdmDisplayBrowser) { + + /* Check if ~user/.gnome/photo passes sanity check */ + dir=g_strconcat(homedir, "/.gnome", NULL); + fileok=gdm_file_check("gdm_greeter_user_alloc", uid, dir, "photo", FALSE); + g_free(dir); + + /* If user's picture passed sanity check/size cutoff value load it */ + if(fileok) { + img=g_strconcat(homedir, "/.gnome/photo", NULL); + imlibimg=gdk_imlib_load_image(img); + g_free(img); + } + else { + img=g_strconcat(GdmGlobalImageDir, "/", logname, NULL); + if (!access(img, R_OK)) + imlibimg=gdk_imlib_load_image(img); + g_free(img); + } + + if(imlibimg) { + w=imlibimg->rgb_width; + h=imlibimg->rgb_height; + + if(w>h && w>GdmIconMaxWidth) { + h=h*((gfloat) GdmIconMaxWidth/w); + w=GdmIconMaxWidth; + } + else if(h>GdmIconMaxHeight) { + w=w*((gfloat) GdmIconMaxHeight/h); + h=GdmIconMaxHeight; + } + + user->picture=gdk_imlib_clone_scaled_image(imlibimg, w, h); + + gdk_imlib_destroy_image(imlibimg); + } + else + user->picture=nofaceimg; + + } + + return (user); +} + + +static gint +gdm_greeter_sort_func(gpointer d1, gpointer d2) +{ + gdmUserType *a=d1; + gdmUserType *b=d2; + + return strcmp(a->login, b->login); +} + + +static gchar * +gdm_greeter_complete_func(gpointer d1) +{ + gdmUserType *a=d1; + + return (a->login); +} + + +static gint +gdm_greeter_check_shell (gchar *usersh) +{ + gint found=0; + gchar *csh; + + setusershell(); + + while((csh=getusershell()) != NULL) + if(!strcmp(csh, usersh)) + found=1; + + endusershell(); + + return(found); +} + + +static void +gdm_greeter_users_init (void) +{ + gdmUserType *user; + struct passwd *pwent; + + if(GdmDisplayBrowser) { + if(access(GdmNofaceImageFile, R_OK)) { + syslog(LOG_WARNING, _("Can't open NofaceImageFile: %s. Suspending face browser!"), GdmNofaceImageFile); + GdmDisplayBrowser=0; + } + else + nofaceimg=gdk_imlib_load_image(GdmNofaceImageFile); + } + + pwent = getpwent(); + + while (pwent != NULL) { + + if (pwent->pw_shell && gdm_greeter_check_shell(pwent->pw_shell)) { + + user=gdm_greeter_user_alloc(pwent->pw_name, + pwent->pw_uid, + pwent->pw_dir); + if(user) + users=g_list_insert_sorted(users, + user, + (GCompareFunc) gdm_greeter_sort_func); + } + + pwent = getpwent(); + } + + cmpl = g_completion_new ((GCompletionFunc) gdm_greeter_complete_func); + + /* FIXME: Gross hack */ + users = g_list_reverse(users); + g_completion_add_items (cmpl, users); + users = g_list_reverse(users); +} + + +int +main (int argc, char *argv[]) +{ + struct sigaction usr1, usr2, hup; + sigset_t mask; + GtkWidget *gdmLogoCtrlHbox; + GtkWidget *gdmCtrlVbox; + + /* Avoid creating ~gdm/.gnome stuff */ + gnome_do_not_create_directories = TRUE; + + openlog("gdmgreeter", LOG_PID, LOG_DAEMON); + + gnome_init("gdmgreeter", VERSION, argc, argv); + gnome_sound_shutdown (); + + gdm_greeter_parse_config(); + + /* If completion is disabled => Disable browser */ + /* if(!GdmCompletion) + GdmDisplayBrowser=FALSE; */ + + /* If browser is enabled => Force completion */ + /* if(GdmDisplayBrowser) */ + + /* Force completion until PAM conversation function is implemented */ + GdmCompletion=TRUE; + + if(GdmCompletion) + gdm_greeter_users_init(); + + if(GdmGtkRC) + gtk_rc_parse(GdmGtkRC); + + greeter = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + gtk_container_border_width (GTK_CONTAINER (greeter), 0); + + greeterframe = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME (greeterframe), GTK_SHADOW_OUT); + gtk_container_border_width (GTK_CONTAINER (greeterframe), 0); + gtk_container_add(GTK_CONTAINER (greeter), greeterframe); + + gdmMain = gtk_vbox_new(FALSE, 20); + gtk_container_border_width (GTK_CONTAINER (gdmMain), 0); + gtk_container_add(GTK_CONTAINER (greeterframe), gdmMain); + + if(GdmDisplayBrowser) { + gdm_greeter_browser_init(); + gtk_box_pack_start(GTK_BOX (gdmMain), + GTK_WIDGET(browser_hbox), TRUE, TRUE, 0); + } + + gdmLogoCtrlHbox = gtk_hbox_new(FALSE, 10); + gtk_container_border_width (GTK_CONTAINER (gdmMain), 20); + gtk_box_pack_end(GTK_BOX (gdmMain), + gdmLogoCtrlHbox, FALSE, FALSE, 0); + + if ((GdmDisplayLogo) && (GdmLogoFilename)) { + gdm_greeter_logo_init(); + gtk_box_pack_start(GTK_BOX (gdmLogoCtrlHbox), + logobox, FALSE, FALSE, 0); + } + + gdmCtrlVbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER (gdmLogoCtrlHbox), gdmCtrlVbox); + + gdm_greeter_message_init(); + gtk_box_pack_start(GTK_BOX (gdmCtrlVbox), + msgbox, TRUE, FALSE, 0); + + gdm_greeter_buttons_init(); + gtk_box_pack_end(GTK_BOX (gdmCtrlVbox), + buttonpane, FALSE, FALSE, 0); + + gdm_greeter_entry_init(); + gtk_box_pack_end(GTK_BOX (gdmCtrlVbox), + entrypane, FALSE, FALSE, 0); + + gtk_widget_show(gdmCtrlVbox); + gtk_widget_show(gdmLogoCtrlHbox); + gtk_widget_show(gdmMain); + gtk_widget_show(greeterframe); + + gtk_window_set_policy(GTK_WINDOW (greeter), 1, 1, 1); + gtk_window_set_focus(GTK_WINDOW (greeter), loginentry); + gtk_window_activate_focus(GTK_WINDOW (greeter)); + gtk_widget_grab_focus(loginentry); + + rootwin=gdk_window_foreign_new (GDK_ROOT_WINDOW ()); + + if(GdmDisplayBrowser) { + gtk_widget_show_all(GTK_WIDGET(browser)); + + gtk_widget_set_usize(GTK_WIDGET (greeter), + (gint) gdk_screen_width() * 0.6, + (gint) gdk_screen_height() * 0.8); + } + + gtk_window_position(GTK_WINDOW (greeter), GTK_WIN_POS_CENTER); + gtk_widget_show_all(greeter); + + hup.sa_handler = (void *) gdm_greeter_done; + hup.sa_flags = 0; + sigemptyset(&hup.sa_mask); + + if(sigaction(SIGHUP, &hup, NULL) < 0) + gdm_greeter_abort(_("main: Error setting up HUP signal handler")); + + if(sigaction(SIGINT, &hup, NULL) < 0) + gdm_greeter_abort(_("main: Error setting up INT signal handler")); + + if(sigaction(SIGTERM, &hup, NULL) < 0) + gdm_greeter_abort(_("main: Error setting up TERM signal handler")); + + usr1.sa_handler = (void *) gdm_greeter_invalid_passwd_req; + usr1.sa_flags = SA_RESTART; + sigemptyset(&usr1.sa_mask); + sigaddset(&usr2.sa_mask, SIGUSR2); + + if(sigaction(SIGUSR1, &usr1, NULL) < 0) + gdm_greeter_abort(_("main: Error setting up USR1 signal handler")); + + usr2.sa_handler = (void *) gdm_greeter_sesslang_send; + usr2.sa_flags = SA_RESTART; + sigemptyset(&usr2.sa_mask); + sigaddset(&usr2.sa_mask, SIGUSR1); + + if(sigaction(SIGUSR2, &usr2, NULL) < 0) + gdm_greeter_abort(_("main: Error setting up USR2 signal handler")); + + sigfillset(&mask); + sigdelset(&mask, SIGUSR1); + sigdelset(&mask, SIGUSR2); + sigdelset(&mask, SIGTERM); + sigdelset(&mask, SIGHUP); + sigdelset(&mask, SIGINT); + + if(sigprocmask(SIG_SETMASK, &mask, NULL) == -1) { + syslog(LOG_ERR, "Could not set signal mask!"); + exit(EXIT_FAILURE); + } + + gtk_main(); + + return 0; +} + +/* EOF */ diff --git a/gui/gdmgreeter.h b/gui/gdmgreeter.h new file mode 100644 index 00000000..521b0f0e --- /dev/null +++ b/gui/gdmgreeter.h @@ -0,0 +1,35 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@SunSITE.auc.dk> + * + * 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 __GDM_GREETER_H__ +#define __GDM_GREETER_H__ + +#include <gnome.h> + +typedef struct _gdmUserType gdmUserType; + +struct _gdmUserType { + uid_t uid; + gchar *login; + gchar *homedir; + GdkImlibImage *picture; +}; + +#endif /* __GDM_GREETER_H__ */ + +/* EOF */ diff --git a/gui/gdmlogin.c b/gui/gdmlogin.c new file mode 100644 index 00000000..82fb5967 --- /dev/null +++ b/gui/gdmlogin.c @@ -0,0 +1,1133 @@ +/* GDM - The Gnome Display Manager + * Copyright (C) 1998, 1999 Martin Kasper Petersen <mkp@SunSITE.auc.dk> + * + * 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 + */ + +/* gdmlogin is a stripped down greeter for environments where: + * + * 1. Users are not trusted (i.e. gdmlogin is less vulnerable to DoS + * attacks ) + * + * 2. Usernames should not be exposed + */ + +#include <config.h> +#include <gnome.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> +#include <syslog.h> +#include <ctype.h> +#include <signal.h> +#include <dirent.h> +#include <gdk/gdkx.h> +#include <pwd.h> + +#include "gdm.h" + +static const gchar RCSid[]="$Id$"; + +extern gboolean gdm_file_check(gchar *caller, uid_t user, gchar *dir, gchar *file, gboolean absentok); + +gint GdmDebug; +gint GdmIconify; +gint GdmShutdownMenu; +gint GdmVerboseAuth; +gint GdmQuiver; +gint GdmChooserMenu; +gint GdmRelaxPerms; +gint GdmUserMaxFile; +gchar *GdmLogoFilename; +gchar *GdmMessageText; +gchar *GdmMessageFont; +gchar *GdmConfigFilename=GDM_CONFIG_FILE; +gchar *GdmMessageFont; +gchar *GdmGtkRC; +gchar *GdmIconFile; +gchar *GdmSessionDir; +gchar *GdmLocaleFile; +gchar *GdmDefaultLocale; + +GtkWidget *login; +GtkWidget *label; +GtkWidget *entry; +GtkWidget *msg; +GtkWidget *win; +GtkWidget *sessmenu; +GtkWidget *langmenu; +GdkWindow *rootwin; + +/* Eew. Loads of global vars. It's hard to be event controlled while maintaining state */ +GSList *sessions=NULL; +GSList *languages=NULL; + +gchar *defsess=NULL; +gchar *cursess=NULL; +gchar *curlang=NULL; +gchar *curuser=NULL; +gchar *lastsess=NULL; +gchar *lastlang=NULL; +gchar *session=NULL; +gchar *language=NULL; + +gboolean savesess; +gboolean savelang; + + +/* Log debug messages */ +void +static gdm_debug(const gchar *format, ...) +{ + va_list args; + gchar *s; + + if(GdmDebug) { + va_start(args, format); + s=g_strdup_vprintf(format, args); + va_end(args); + + syslog(LOG_DEBUG, s); + + g_free(s); + } +} + + +static void +gdm_login_done(void) +{ + closelog(); + gtk_main_quit(); + exit(DISPLAY_SUCCESS); +} + + +typedef struct _cursoroffset {gint x,y;} CursorOffset; + + +static void +gdm_login_icon_pressed(GtkWidget *widget, GdkEventButton *event) +{ + CursorOffset *p; + + if(event->type == GDK_2BUTTON_PRESS) { + gtk_widget_destroy(win); + gdk_window_show(login->window); + return; + } + + if (event->type != GDK_BUTTON_PRESS) + return; + + p=gtk_object_get_user_data(GTK_OBJECT (widget)); + p->x=(gint)event->x; + p->y=(gint)event->y; + + gtk_grab_add(widget); + gdk_pointer_grab(widget->window, TRUE, + GDK_BUTTON_RELEASE_MASK | + GDK_BUTTON_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK, + NULL, NULL, 0); +} + + +static void +gdm_login_icon_released(GtkWidget *widget) +{ + gtk_grab_remove(widget); + gdk_pointer_ungrab(0); +} + + +static void +gdm_login_icon_motion(GtkWidget *widget, GdkEventMotion *event) +{ + gint xp, yp; + CursorOffset *p; + GdkModifierType mask; + + p=gtk_object_get_user_data(GTK_OBJECT (widget)); + gdk_window_get_pointer(rootwin, &xp, &yp, &mask); + gtk_widget_set_uposition(widget, xp-p->x, yp-p->y); +} + + +static gboolean +gdm_login_iconify_handler(GtkWidget *widget, gpointer data) +{ + GtkWidget *fixed; + GtkWidget *icon; + GdkGC *gc; + GtkStyle *style; + CursorOffset *icon_pos; + gint rw, rh, iw, ih; + + gdk_window_hide(login->window); + style=gtk_widget_get_default_style(); + gc=style->black_gc; + win=gtk_window_new(GTK_WINDOW_POPUP); + + gtk_widget_set_events(win, + gtk_widget_get_events(win) | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK); + + gtk_widget_realize(win); + + fixed=gtk_fixed_new(); + gtk_container_add(GTK_CONTAINER (win), fixed); + gtk_widget_show(fixed); + + icon=gnome_pixmap_new_from_file (GdmIconFile); + gdk_window_get_size ((GdkWindow *) GNOME_PIXMAP (icon)->pixmap, &iw, &ih); + + gtk_fixed_put(GTK_FIXED (fixed), icon, 0, 0); + gtk_widget_show(icon); + + gtk_signal_connect(GTK_OBJECT (win), "button_press_event", + GTK_SIGNAL_FUNC (gdm_login_icon_pressed),NULL); + gtk_signal_connect(GTK_OBJECT (win), "button_release_event", + GTK_SIGNAL_FUNC (gdm_login_icon_released),NULL); + gtk_signal_connect(GTK_OBJECT (win), "motion_notify_event", + GTK_SIGNAL_FUNC (gdm_login_icon_motion),NULL); + + icon_pos=g_new(CursorOffset, 1); + gtk_object_set_user_data(GTK_OBJECT(win), icon_pos); + + gtk_widget_show(win); + + rw=gdk_screen_width(); + rh=gdk_screen_height(); + + gtk_widget_set_uposition(win, rw-iw, rh-ih); + + return(TRUE); +} + + +static void +gdm_login_abort(const gchar *format, ...) +{ + va_list args; + gchar *s; + + va_start(args, format); + s=g_strdup_vprintf(format, args); + va_end(args); + + syslog(LOG_ERR, s); + closelog(); + exit(DISPLAY_ABORT); +} + + +static gchar * +gdm_parse_enriched_string(gchar *s) +{ + gchar cmd, *buffer, *start; + gchar hostbuf[256]; + gchar *hostname, *temp1, *temp2, *display; + + display=getenv("DISPLAY"); + + if(!display) + return(NULL); + + temp1=strchr(display, '.'); + temp2=strchr(display, ':'); + + if(temp1) + *temp1='\0'; + else if(temp2) + *temp2='\0'; + else + return(NULL); /* Display isn't */ + + gethostname(hostbuf, 255); + hostname=g_strdup(hostbuf); + + if(!hostname) + hostname=g_strdup("Gnome"); + + if(strlen(s) > 1023) { + syslog(LOG_ERR, _("gdm_parse_enriched_string: String too long!")); + return(g_strconcat(_("Welcome to "), hostname, NULL)); + } + + if(!(buffer = g_malloc(4096))) { + syslog(LOG_ERR, _("gdm_parse_enriched_string: Could not malloc temporary buffer!")); + return(NULL); + } + + start = buffer; + + while(*s) { + + if(*s=='%' && (cmd = s[1]) != 0) { + s+=2; + + switch(cmd) { + + case 'h': + memcpy(buffer, hostname, strlen(hostname)); + buffer+=strlen(hostname); + break; + + case 'd': + memcpy(buffer, display, strlen(display)); + buffer+=strlen(display); + break; + + case '%': + *buffer++='%'; + break; + + default: + break; + }; + } + else + *buffer++=*s++; + } + + *buffer=0; + + return(g_strdup(start)); +} + + +static void +gdm_login_about(void) +{ + const gchar *authors[]={"Martin Kasper Petersen <mkp@mkp.net>", NULL}; + + GtkWidget *about; + + about=gnome_about_new("Gnome Display Manager", + "" VERSION "", + "Copyright Martin K. Petersen (C) 1998, 1999", + authors, + _("gdm manages local and remote displays and provides the user with a login window."), + NULL); + + gtk_widget_show(about); +} + + +static gboolean +gdm_login_query(gchar *msg) +{ + GtkWidget *req; + + req=gnome_message_box_new(msg, + GNOME_MESSAGE_BOX_QUESTION, + GNOME_STOCK_BUTTON_YES, + GNOME_STOCK_BUTTON_NO, + NULL); + + gtk_window_set_modal(GTK_WINDOW(req), TRUE); + gtk_window_set_position(GTK_WINDOW(req), GTK_WIN_POS_CENTER); + + return(!gnome_dialog_run(GNOME_DIALOG(req))); +} + + +static gboolean +gdm_login_reboot_handler(void) +{ + if(gdm_login_query(_("Are you sure you want to reboot the machine?"))) { + closelog(); + exit(DISPLAY_REBOOT); + } + + return(TRUE); +} + + +static gboolean +gdm_login_halt_handler(void) +{ + if(gdm_login_query(_("Are you sure you want to halt the machine?"))) { + closelog(); + exit(DISPLAY_HALT); + } + + return(TRUE); +} + + +static void +gdm_login_parse_config(void) +{ + gchar *display; + struct stat unused; + + if(stat(GDM_CONFIG_FILE, &unused) == -1) + gdm_login_abort(_("gdm_login_parse_config: No configuration file: %s. Aborting."), GDM_CONFIG_FILE); + + gnome_config_push_prefix ("=" GDM_CONFIG_FILE "=/"); + + GdmLogoFilename=gnome_config_get_string("appearance/logoimage"); + GdmMessageFont=gnome_config_get_string("appearance/msgfont=-adobe-helvetica-bold-r-normal-*-*-180-*-*-*-*-*-*"); + GdmGtkRC=gnome_config_get_string("appearance/gtkrc"); + GdmIconify=gnome_config_get_int("appearance/iconify=1"); + GdmIconFile=gnome_config_get_string("appearance/iconfile=gdm.xpm"); + GdmQuiver=gnome_config_get_int("appearance/quiver=1"); + + GdmChooserMenu=gnome_config_get_int("system/choosermenu=0"); + GdmShutdownMenu=gnome_config_get_int("system/shutdownmenu=0"); + GdmUserMaxFile=gnome_config_get_int("system/UserFileCutoffSize=65536"); + GdmRelaxPerms=gnome_config_get_int("system/relaxpermissions=0"); + + GdmLocaleFile=g_strdup(gnome_config_get_string("system/LocaleFile")); + GdmDefaultLocale=g_strdup(gnome_config_get_string("system/DefaultLocale=english")); + GdmSessionDir=gnome_config_get_string("daemon/sessiondir"); + + GdmMessageText=gnome_config_get_string(_("messages/welcome=Welcome to %h")); + + GdmDebug=gnome_config_get_int("debug/enable=0"); + + gnome_config_pop_prefix (); + + if(stat(GdmLocaleFile, &unused) == -1) + gdm_login_abort("gdm_login_parse_config: Could not open locale file %s. Aborting!", GdmLocaleFile); + + /* Disable System menu on non-local displays */ + display=getenv("DISPLAY"); + + if(!display) + gdm_login_abort("gdm_login_parse_config: DISPLAY variable not set!"); + + if(strncmp(display, ":", 1)) + GdmShutdownMenu=0; +} + + +static gboolean +gdm_login_list_lookup(GSList *l, gchar *data) +{ + GSList *list=l; + + if(!list || !data) + return(FALSE); + + while(list) { + + if(!strcasecmp(list->data, data)) + return(TRUE); + + list=list->next; + } + + return(FALSE); +} + + +static void +gdm_login_sesslang_lookup(void) /* Input validation sucks */ +{ + struct passwd *pwent; + gboolean fileok; + gchar msg[1024]; + gchar *dir=NULL, *cfg=NULL; + gchar *usrlang=NULL, *usrsess=NULL; + + gtk_widget_set_sensitive(sessmenu, FALSE); + gtk_widget_set_sensitive(langmenu, FALSE); + + /* Lookup verified user */ + pwent=getpwnam(curuser); + + dir=g_strconcat(pwent->pw_dir, "/.gnome", NULL); + fileok=gdm_file_check("gdm_login_sesslang_lookup", pwent->pw_uid, dir, "gdm", TRUE); + g_free(dir); + + if(!fileok) { /* User's settings can't be retrieved */ + + /* If cursess==last use system default session */ + if(!strcasecmp(cursess, lastsess)) + session=defsess; + else + session=cursess; + + /* If curlang==last use default */ + if(!strcasecmp(curlang, lastlang)) + language=GdmDefaultLocale; + else + language=curlang; + + savesess=FALSE; + savelang=FALSE; + + return; + } + + /* Find user's last session and language if available */ + cfg=g_strconcat("=", pwent->pw_dir, "/.gnome/gdm=/session/last", NULL); + usrsess=gnome_config_get_string(cfg); + g_free(cfg); + + cfg=g_strconcat("=", pwent->pw_dir, "/.gnome/gdm=/session/lang", NULL); + usrlang=gnome_config_get_string(cfg); + g_free(cfg); + + /* If ``Last'' session is selected */ + if(!strcasecmp(cursess, lastsess)) { + + /* User has no saved session. Use default. */ + if(!usrsess) { + session=defsess; + savesess=TRUE; + } + /* User's saved session exists on this box */ + else if(gdm_login_list_lookup(sessions, usrsess)) { + session=usrsess; + savesess=FALSE; + } + /* User's saved session type unknown */ + else { + session=defsess; + g_snprintf(msg, 1023, + _("Your preferred session type %s is not installed on this machine.\n" \ + "Do you wish to make %s the default for future sessions?"), + usrsess, defsess); + savesess=gdm_login_query(msg); + } + } + /* One of the other available session types is selected */ + else { + session=cursess; + + /* User has no saved session type. Use current */ + if(!usrsess) + savesess=TRUE; + /* User's saved session is also the chosen one */ + else if(!strcasecmp(usrsess, cursess)) + savesess=FALSE; + /* User selected a new session type */ + else { + g_snprintf(msg, 1023, + _("You have chosen %s for this session, but your default setting is %s.\n" \ + "Do you wish to make %s the default for future sessions?"), + cursess, usrsess, cursess); + savesess=gdm_login_query(msg); + } + } + + /* If ``Last'' language is selected */ + if(!strcasecmp(curlang, lastlang)) { + + /* User has no saved language. Use default. */ + if(!usrlang) { + language=GdmDefaultLocale; + savelang=TRUE; + } + else { + language=usrlang; + savelang=FALSE; + } + } + /* One of the available languages is selected */ + else { + language=curlang; + + /* User has no saved language. Use current */ + if(!usrlang) + savelang=TRUE; + /* User selected a new language */ + else { + g_snprintf(msg, 1023, + _("You have chosen %s for this session, but your default setting is %s.\n" \ + "Do you wish to make %s the default for future sessions?"), + curlang, usrlang, curlang); + savelang=gdm_login_query(msg); + } + } + + return; +} + + +static gboolean +gdm_login_entry_handler (GtkWidget *widget, GdkEventKey *event) +{ + if(!event) + return(TRUE); + + switch(event->keyval) { + + case GDK_Return: + gtk_widget_set_sensitive(entry, FALSE); + + /* Save login. I'm making the assumption that login is always + * the first thing entered. This might not be true for all PAM + * setups. Needs thinking! + */ + + if(!curuser) + curuser=g_strdup(gtk_entry_get_text(GTK_ENTRY(entry))); + + g_print("%s\n", gtk_entry_get_text(GTK_ENTRY(entry))); + break; + + case GDK_Up: + case GDK_Down: + case GDK_Tab: + gtk_signal_emit_stop_by_name(GTK_OBJECT(entry), "key_press_event"); + break; + + break; + + case GDK_F1: + gdm_login_about(); + break; + + default: + break; + } + + return(TRUE); +} + + +static void +gdm_login_session_handler (GtkWidget *widget) +{ + gchar *s; + + gtk_label_get(GTK_LABEL(GTK_BIN(widget)->child), &cursess); + s=g_strdup_printf(_("%s session selected"), cursess); + gtk_label_set(GTK_LABEL(msg), s); + g_free(s); +} + + +static void +gdm_login_session_init(GtkWidget *menu) +{ + GSList *sessgrp=NULL; + GtkWidget *item; + DIR *sessdir; + struct dirent *dent; + struct stat statbuf; + gint linklen; + + lastsess=_("Last"); + + cursess=lastsess; + item = gtk_radio_menu_item_new_with_label(NULL, lastsess); + sessgrp = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(item)); + gtk_menu_append(GTK_MENU(menu), item); + gtk_signal_connect(GTK_OBJECT(item), "activate", gdm_login_session_handler, NULL); + gtk_widget_show(item); + + item = gtk_menu_item_new(); + gtk_menu_append(GTK_MENU(menu), item); + gtk_widget_show(item); + + /* Check that session dir is readable */ + if (access(GdmSessionDir, R_OK|X_OK)) + gdm_login_abort(_("gdm_login_session_init: Session script directory not found!")); + + /* Read directory entries in session dir */ + sessdir=opendir(GdmSessionDir); + dent=readdir(sessdir); + + while(dent != NULL) { + gchar *s; + + s=g_strconcat(GdmSessionDir, "/", dent->d_name, NULL); + lstat(s, &statbuf); + + /* If default session link exists, find out what it points to */ + if(S_ISLNK(statbuf.st_mode) && !strcasecmp(dent->d_name, "default")) { + gchar t[_POSIX_PATH_MAX]; + + linklen=readlink(s, t, _POSIX_PATH_MAX); + t[linklen]=0; + defsess=g_strdup(t); + } + + /* If session script is readable/executable add it to the list */ + if(S_ISREG(statbuf.st_mode)) { + + if((statbuf.st_mode & (S_IRUSR|S_IXUSR)) == (S_IRUSR|S_IXUSR) && + (statbuf.st_mode & (S_IRGRP|S_IXGRP)) == (S_IRGRP|S_IXGRP) && + (statbuf.st_mode & (S_IROTH|S_IXOTH)) == (S_IROTH|S_IXOTH)) + { + item=gtk_radio_menu_item_new_with_label(sessgrp, dent->d_name); + sessgrp=gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM (item)); + sessions=g_slist_append(sessions, dent->d_name); + gtk_menu_append(GTK_MENU(menu), item); + gtk_signal_connect(GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (gdm_login_session_handler), NULL); + gtk_widget_show(item); + } + else + syslog(LOG_ERR, "Wrong permissions on %s/%s. Should be readable/executable for all.", + GdmSessionDir, dent->d_name); + + } + + dent=readdir(sessdir); + g_free(s); + } + + if(!g_slist_length(sessgrp)) + gdm_login_abort(_("No session scripts found. Aborting!")); + + if(!defsess) { + gtk_label_get(GTK_LABEL(GTK_BIN(g_slist_nth_data(sessgrp, 0))->child), &defsess); + syslog(LOG_WARNING, _("No default session link found. Using %s.\n"), defsess); + } +} + + +static void +gdm_login_language_handler (GtkWidget *widget) +{ + gchar *s; + + gtk_label_get(GTK_LABEL(GTK_BIN(widget)->child), &curlang); + s=g_strdup_printf(_("%s language selected"), curlang); + gtk_label_set(GTK_LABEL(msg), s); + g_free(s); +} + + +static void +gdm_login_language_init(GtkWidget *menu) +{ + GtkWidget *item, *ammenu, *nzmenu, *omenu; + FILE *langlist; + char curline[256]; + char *ctmp, *ctmp1, *ctmp2; + + lastlang=_("Last"); + curlang=lastlang; + + item=gtk_radio_menu_item_new_with_label(NULL, lastlang); + languages=gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(item)); + gtk_menu_append(GTK_MENU(menu), item); + gtk_signal_connect(GTK_OBJECT(item), "activate", gdm_login_language_handler, NULL); + gtk_widget_show(item); + + item=gtk_menu_item_new(); + gtk_menu_append(GTK_MENU(menu), item); + gtk_widget_show(item); + + item=gtk_menu_item_new_with_label(_("A-M")); + ammenu=gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), ammenu); + gtk_menu_append(GTK_MENU(menu), item); + gtk_widget_show(item); + + item=gtk_menu_item_new_with_label(_("N-Z")); + nzmenu=gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), nzmenu); + gtk_menu_append(GTK_MENU(menu), item); + gtk_widget_show(item); + + item=gtk_menu_item_new_with_label(_("Other")); + omenu=gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), omenu); + gtk_menu_append(GTK_MENU(menu), item); + gtk_widget_show(item); + + langlist = fopen(GdmLocaleFile, "r"); + + if(!langlist) + return; + + while(fgets(curline, sizeof(curline), langlist)) { + + if(!isalpha(curline[0])) + continue; + + ctmp1 = strchr(curline, ' '); + ctmp2 = strchr(curline, '\t'); + ctmp = curline + strlen(curline) - 1; + + if(ctmp1 && (ctmp1 < ctmp)) + ctmp = ctmp1; + + if(ctmp2 && (ctmp2 < ctmp)) + ctmp = ctmp2; + + *ctmp = '\0'; + curline[0] = toupper(curline[0]); + + item=gtk_radio_menu_item_new_with_label(languages, curline); + languages=gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(item)); + + if(curline[0] >= 'A' && curline[0] <= 'M') + gtk_menu_append(GTK_MENU(ammenu), item); + else if(curline[0] >= 'N' && curline[0] <= 'Z') + gtk_menu_append(GTK_MENU(nzmenu), item); + else + gtk_menu_append(GTK_MENU(omenu), item); + + gtk_signal_connect(GTK_OBJECT(item), "activate", gdm_login_language_handler, NULL); + gtk_widget_show(item); + } + + fclose(langlist); +} + + +static gboolean +gdm_login_ctrl_handler(GIOChannel *source, GIOCondition cond, gint fd) +{ + gchar buf[PIPE_SIZE]; + gint len; + gint i, x, y; + + if(cond != G_IO_IN) + return(TRUE); + + g_io_channel_read(source, buf, 1, &len); + + if(len!=1) + return(TRUE); + + switch(buf[0]) { + case GDM_PROMPT: + g_io_channel_read(source, buf, PIPE_SIZE-1, &len); + buf[len-1]='\0'; + gtk_label_set(GTK_LABEL(label), buf); + gtk_widget_show(label); + gtk_entry_set_text(GTK_ENTRY(entry), ""); + gtk_entry_set_visibility(GTK_ENTRY(entry), TRUE); + gtk_widget_set_sensitive(entry, TRUE); + gtk_widget_grab_focus(entry); + gtk_widget_show(entry); + break; + + case GDM_NOECHO: + g_io_channel_read(source, buf, PIPE_SIZE-1, &len); + buf[len-1]='\0'; + gtk_label_set(GTK_LABEL(label), buf); + gtk_widget_show(label); + gtk_entry_set_text(GTK_ENTRY(entry), ""); + gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); + gtk_widget_set_sensitive(entry, TRUE); + gtk_widget_grab_focus(entry); + gtk_widget_show(entry); + break; + + case GDM_MSGERR: + g_io_channel_read(source, buf, PIPE_SIZE-1, &len); + buf[len-1]='\0'; + gtk_label_set(GTK_LABEL(msg), buf); + gtk_widget_show(msg); + g_print("\n"); + break; + + case GDM_SESS: + g_io_channel_read(source, buf, PIPE_SIZE-1, &len); /* Empty */ + gdm_login_sesslang_lookup(); /* Lookup session and language */ + g_print("%s\n", session); + break; + + case GDM_LANG: + g_io_channel_read(source, buf, PIPE_SIZE-1, &len); /* Empty */ + g_print("%s\n", language); + break; + + case GDM_SSESS: + g_io_channel_read(source, buf, PIPE_SIZE-1, &len); /* Empty */ + + if(savesess) + g_print("Y\n"); + else + g_print("\n"); + + break; + + case GDM_SLANG: + g_io_channel_read(source, buf, PIPE_SIZE-1, &len); /* Empty */ + + if(savelang) + g_print("Y\n"); + else + g_print("\n"); + + break; + + case GDM_RESET: + g_io_channel_read(source, buf, PIPE_SIZE-1, &len); + buf[len-1]='\0'; + + if(GdmQuiver) { + gdk_window_get_position(login->window, &x, &y); + + for (i=32 ; i > 0 ; i=i/2) { + gdk_window_move(login->window, i+x, y); + gdk_window_move(login->window, x, y); + gdk_window_move(login->window, -i+x, y); + gdk_window_move(login->window, x, y); + } + } + + if(curuser) { + g_free(curuser); + curuser=NULL; + } + + g_print("\n"); + break; + + case GDM_QUIT: + exit(EXIT_SUCCESS); + break; + + default: + break; + } + + return(TRUE); +} + + +static void +gdm_login_gui_init(void) +{ + GtkStyle *style; + GtkWidget *frame, *frame2, *hbox, *hline, *item, *lebox, *logo, *logobox; + GtkWidget *logoframe, *mbox, *menu, *menubar, *vbox, *welcome; + gchar *greeting; + + if(GdmGtkRC) + gtk_rc_parse(GdmGtkRC); + + rootwin=gdk_window_foreign_new (GDK_ROOT_WINDOW ()); + + login=gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_container_border_width(GTK_CONTAINER(login), 0); + + frame=gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT); + gtk_container_border_width(GTK_CONTAINER(frame), 0); + gtk_container_add(GTK_CONTAINER(login), frame); + gtk_widget_show(frame); + + frame2=gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(frame2), GTK_SHADOW_IN); + gtk_container_border_width(GTK_CONTAINER(frame2), 2); + gtk_container_add(GTK_CONTAINER(frame), frame2); + gtk_widget_show(frame2); + + mbox=gtk_vbox_new(FALSE,0); + gtk_container_add(GTK_CONTAINER(frame2), mbox); + gtk_widget_show(mbox); + + menubar=gtk_menu_bar_new(); + gtk_box_pack_start(GTK_BOX(mbox), menubar, FALSE, FALSE, 0); + + menu=gtk_menu_new(); + gdm_login_session_init(menu); + sessmenu=gtk_menu_item_new_with_label(_("Session")); + gtk_menu_bar_append(GTK_MENU_BAR(menubar), sessmenu); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(sessmenu), menu); + gtk_widget_show(sessmenu); + + menu=gtk_menu_new(); + gdm_login_language_init(menu); + langmenu=gtk_menu_item_new_with_label(_("Language")); + gtk_menu_bar_append(GTK_MENU_BAR(menubar), langmenu); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(langmenu), menu); + gtk_widget_show(langmenu); + + if(GdmShutdownMenu) { + menu=gtk_menu_new(); + item=gtk_menu_item_new_with_label(_("Reboot...")); + gtk_menu_append(GTK_MENU(menu), item); + gtk_signal_connect(GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC(gdm_login_reboot_handler), NULL); + gtk_widget_show(item); + + item=gtk_menu_item_new_with_label(_("Halt...")); + gtk_menu_append(GTK_MENU(menu), item); + gtk_signal_connect(GTK_OBJECT(item), "activate", + GTK_SIGNAL_FUNC(gdm_login_halt_handler), NULL); + gtk_widget_show(item); + + item=gtk_menu_item_new_with_label(_("System")); + gtk_menu_bar_append(GTK_MENU_BAR(menubar), item); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu); + gtk_widget_show(item); + } + + if(GdmChooserMenu) { + item=gtk_menu_item_new_with_label(_("Host chooser")); + gtk_menu_bar_append(GTK_MENU_BAR(menubar), item); + gtk_widget_show(item); + } + + if(GdmIconify) { + if(access(GdmIconFile, R_OK)) { + syslog(LOG_WARNING, _("Can't open icon file: %s. Suspending iconify feature!"), GdmIconFile); + GdmIconify=0; + } + else { + item=gtk_menu_item_new_with_label(_("Iconify")); + gtk_menu_bar_append(GTK_MENU_BAR(menubar), item); + gtk_signal_connect(GTK_OBJECT(item), "activate", + GTK_SIGNAL_FUNC(gdm_login_iconify_handler), NULL); + gtk_widget_show(item); + } + } + + hbox=gtk_hbox_new(FALSE, 0); + gtk_container_border_width(GTK_CONTAINER(hbox), 10); + gtk_box_pack_end(GTK_BOX(mbox), hbox, FALSE, FALSE, 0); + gtk_widget_show(hbox); + + if (GdmLogoFilename && !access(GdmLogoFilename, R_OK)) { + logobox=gtk_vbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), logobox, FALSE, FALSE, 0); + + logoframe=gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(logoframe), GTK_SHADOW_IN); + gtk_box_pack_start(GTK_BOX(logobox), logoframe, FALSE, FALSE, 0); + gtk_widget_show(logoframe); + + logo=gnome_pixmap_new_from_file(GdmLogoFilename); + gtk_container_add(GTK_CONTAINER(logoframe), logo); + gtk_widget_show(logo); + + gtk_widget_show(logobox); + } + + vbox=gtk_vbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); + gtk_container_border_width(GTK_CONTAINER(vbox), 10); + gtk_widget_show(vbox); + + style = gtk_style_new(); + gdk_font_unref(style->font); + style->font = gdk_font_load (GdmMessageFont); + gtk_widget_push_style(style); + greeting=gdm_parse_enriched_string(GdmMessageText); + welcome=gtk_label_new(greeting); + g_free(greeting); + gtk_box_pack_start(GTK_BOX(vbox), welcome, TRUE, FALSE, 10); + gtk_widget_show(welcome); + gtk_widget_pop_style(); + + msg=gtk_label_new("Please enter your login"); + gtk_box_pack_end(GTK_BOX(vbox), msg, FALSE, TRUE, 0); + gtk_widget_show(msg); + + hline=gtk_hseparator_new(); + gtk_box_pack_end(GTK_BOX(vbox), hline, FALSE, FALSE, 10); + gtk_widget_show(hline); + + lebox=gtk_vbox_new(FALSE, 0); + gtk_container_border_width(GTK_CONTAINER(lebox), 5); + gtk_box_pack_end(GTK_BOX(vbox), lebox, FALSE, FALSE, 5); + gtk_widget_show(lebox); + + label=gtk_label_new("Login:"); + gtk_box_pack_start(GTK_BOX(lebox), label, FALSE, FALSE, 5); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + gtk_widget_show(label); + + entry=gtk_entry_new_with_max_length(32); + gtk_box_pack_start(GTK_BOX(lebox), entry, FALSE, FALSE, 5); + gtk_entry_set_text(GTK_ENTRY(entry), ""); + gtk_signal_connect_object(GTK_OBJECT(entry), + "key_press_event", + GTK_SIGNAL_FUNC(gdm_login_entry_handler), + NULL); + gtk_widget_show(entry); + + hline=gtk_hseparator_new(); + gtk_box_pack_end(GTK_BOX(vbox), hline, FALSE, FALSE, 10); + gtk_widget_show(hline); + + gtk_widget_grab_focus(entry); + gtk_window_set_focus(GTK_WINDOW (login), entry); + gtk_window_set_policy(GTK_WINDOW (login), 1, 1, 1); + gtk_window_position(GTK_WINDOW (login), GTK_WIN_POS_CENTER); + + gtk_widget_set_usize(GTK_WIDGET(login), + (gint)gdk_screen_width() * 0.5, + 0); + + gtk_widget_show_all(login); +} + + +int +main (int argc, char *argv[]) +{ + struct sigaction hup; + sigset_t mask; + GIOChannel *ctrlch; + + /* Avoid creating ~gdm/.gnome stuff */ + gnome_do_not_create_directories = TRUE; + + openlog("gdmlogin", LOG_PID, LOG_DAEMON); + + gnome_init("gdmlogin", VERSION, argc, argv); + gnome_sound_shutdown (); + + gdm_login_parse_config(); + gdm_login_gui_init(); + + hup.sa_handler = (void *) gdm_login_done; + hup.sa_flags = 0; + sigemptyset(&hup.sa_mask); + + if(sigaction(SIGHUP, &hup, NULL) < 0) + gdm_login_abort(_("main: Error setting up HUP signal handler")); + + if(sigaction(SIGINT, &hup, NULL) < 0) + gdm_login_abort(_("main: Error setting up INT signal handler")); + + if(sigaction(SIGTERM, &hup, NULL) < 0) + gdm_login_abort(_("main: Error setting up TERM signal handler")); + + sigfillset(&mask); + sigdelset(&mask, SIGTERM); + sigdelset(&mask, SIGHUP); + sigdelset(&mask, SIGINT); + + if(sigprocmask(SIG_SETMASK, &mask, NULL) == -1) { + syslog(LOG_ERR, "Could not set signal mask!"); + exit(EXIT_FAILURE); + } + + ctrlch = g_io_channel_unix_new(STDIN_FILENO); + g_io_channel_init(ctrlch); + g_io_add_watch(ctrlch, + G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL, + (GIOFunc) gdm_login_ctrl_handler, + NULL); + g_io_channel_unref(ctrlch); + + gtk_main(); + + exit(EXIT_SUCCESS); +} + +/* EOF */ diff --git a/pixmaps/.cvsignore b/pixmaps/.cvsignore new file mode 100644 index 00000000..282522db --- /dev/null +++ b/pixmaps/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/pixmaps/Makefile.am b/pixmaps/Makefile.am new file mode 100644 index 00000000..f5ca7b8a --- /dev/null +++ b/pixmaps/Makefile.am @@ -0,0 +1,8 @@ +pixmapdir = $(datadir)/pixmaps + +BITMAPS = gdm.xpm nophoto.png + +pixmap_DATA = $(BITMAPS) + +EXTRA_DIST = $(BITMAPS) + diff --git a/pixmaps/gdm.xpm b/pixmaps/gdm.xpm new file mode 100644 index 00000000..201895f1 --- /dev/null +++ b/pixmaps/gdm.xpm @@ -0,0 +1,285 @@ +/* XPM */ +static char * image_name[] = { +"48 48 234 2", +" c #C71BCB2BC71B", +". c #BEFBBEFBBEFB", +"X c #BEFBBAEABEFB", +"o c #B6DABAEABEFB", +"O c #BEFBC30BC71B", +"+ c #BEFBBEFBB6DA", +"@ c #B6DAB6DAB6DA", +"# c #C71BC71BC71B", +"$ c #A699AEBAAEBA", +"% c #EFBEF3CEF7DE", +"& c #E79DEBADEFBE", +"* c #CF3CD34CD75C", +"= c #CF3CCF3CCF3C", +"- c #D75CD75CD75C", +"; c #D75CDB6CD75C", +": c #DF7DDF7DD75C", +"> c #DF7DE38DE79D", +", c #D75CD75CCF3C", +"< c #71C679E779E7", +"1 c #514451445144", +"2 c #A699AAAAAEBA", +"3 c #A699AAAAA699", +"4 c #9E79A699A699", +"5 c #9E79A289A699", +"6 c #9E799E79A699", +"7 c #9E799E799E79", +"8 c #96589A699E79", +"9 c #965896589658", +"0 c #8E3892489658", +"q c #8E388E388E38", +"w c #861786178617", +"e c #79E782078617", +"r c #86178A288617", +"t c #96589A699658", +"y c #514459655965", +"u c #49244D344924", +"i c #8E3892488E38", +"p c #9E79A2899E79", +"a c #410341034103", +"s c #492449244924", +"d c #38E33CF338E3", +"f c #410345144103", +"g c #86178A288E38", +"h c #8E388E389E79", +"j c #861786179E79", +"k c #79E77DF779E7", +"l c #8E3886178617", +"z c #AEBAB2CAAEBA", +"x c #AEBAB6DAB6DA", +"c c #79E77DF78E38", +"v c #71C675D671C6", +"b c #86177DF779E7", +"n c #69A675D671C6", +"m c #69A671C671C6", +"M c #B6DAB2CABEFB", +"N c #EFBEEBADDF7D", +"B c #E79DE79DDF7D", +"V c #E79DE38DD75C", +"C c #DF7DDB6CD75C", +"Z c #DF7DDB6CCF3C", +"A c #D75CD34CBEFB", +"S c #D75CCF3CC71B", +"D c #CF3CCF3CC71B", +"F c #CF3CCB2BBEFB", +"G c #CF3CC71BBEFB", +"H c #C71BC71BBEFB", +"J c #C71BC30BB6DA", +"K c #C71BBEFBB6DA", +"L c #BEFBBAEAB6DA", +"P c #BEFBB6DAAEBA", +"I c #B6DAAEBAA699", +"U c #96588E388E38", +"Y c #79E779E779E7", +"T c #38E338E338E3", +"R c #DF7DD75CCF3C", +"E c #BEFBB2CAAEBA", +"W c #AEBAA699A699", +"Q c #A6999E799658", +"! c #618561856185", +"~ c #861779E779E7", +"^ c #79E775D671C6", +"/ c #69A669A679E7", +"( c #69A66DB671C6", +") c #618565956185", +"_ c #5965596569A6", +"` c #596555555144", +"' c #5144555571C6", +"] c #4924492469A6", +"[ c #410345145965", +"{ c #492445145144", +"} c #96588A288E38", +"| c #B6DAB2CAAEBA", +" . c #8E388A288617", +".. c #9E799A699658", +"X. c #71C675D68617", +"o. c #6185659579E7", +"O. c #5144514471C6", +"+. c #49244D3479E7", +"@. c #4924492471C6", +"#. c #965892488E38", +"$. c #30C234D330C2", +"%. c #51444D344924", +"&. c #9E799E79B6DA", +"*. c #71C671C69658", +"=. c #71C671C68E38", +"-. c #514455558617", +";. c #492449249658", +":. c #492449248617", +">. c #492445148E38", +",. c #410341036185", +"<. c #208124922081", +"1. c #492445144103", +"2. c #79E779E79658", +"3. c #AEBAAAAAB6DA", +"4. c #71C675D69E79", +"5. c #596559659658", +"6. c #514455559658", +"7. c #38E33CF39E79", +"8. c #410345149658", +"9. c #596559658617", +"0. c #69A665956185", +"q. c #38E33CF35144", +"w. c #208120812081", +"e. c #59655D755965", +"r. c #69A66DB68E38", +"t. c #618561858E38", +"y. c #69A669A69E79", +"u. c #410345149E79", +"i. c #618565959658", +"p. c #49244924A699", +"a. c #59655965A699", +"s. c #69A66DB6B6DA", +"d. c #49244D34A699", +"f. c #49244924B6DA", +"g. c #38E338E38617", +"h. c #A699A289B6DA", +"j. c #30C234D34924", +"k. c #30C230C238E3", +"l. c #20811C711861", +"z. c #514455555144", +"x. c #618569A66185", +"c. c #41034514B6DA", +"v. c #51445144B6DA", +"b. c #71C675D6AEBA", +"n. c #8E388E38B6DA", +"m. c #61856595AEBA", +"M. c #59655D758E38", +"N. c #38E33CF369A6", +"B. c #30C230C25144", +"V. c #30C230C230C2", +"C. c #186118611861", +"Z. c #28A22CB228A2", +"A. c #86178207AEBA", +"S. c #DF7DDB6CBEFB", +"D. c #30C234D371C6", +"F. c #186114511040", +"G. c #28A228A228A2", +"H. c #596561855965", +"J. c #492451444924", +"K. c #E79DDF7DD75C", +"L. c #8E388E38A699", +"P. c #38E334D379E7", +"I. c #28A22CB26185", +"U. c #28A22CB24103", +"Y. c #28A228A25144", +"T. c #AEBAB2CAB6DA", +"R. c #51445555AEBA", +"E. c #28A22CB28E38", +"W. c #208124924924", +"Q. c #38E33CF34924", +"!. c #D75CD75CBEFB", +"~. c #E79DE38DBEFB", +"^. c #96589248AEBA", +"/. c #28A228A271C6", +"(. c #AEBAAEBAA699", +"). c #69A66DB669A6", +"_. c #59655D75A699", +"`. c #208124928617", +"'. c #28A22CB279E7", +"]. c #208120814924", +"[. c #8617820779E7", +"{. c #618569A669A6", +"}. c #79E779E7B6DA", +"|. c #28A228A29658", +" X c #30C230C28E38", +".X c #30C234D38E38", +"XX c #20811C718E38", +"oX c #79E779E771C6", +"OX c #5965596579E7", +"+X c #71C671C6A699", +"@X c #104014514103", +"#X c #618561859E79", +"$X c #30C234D39658", +"%X c #186118616185", +"&X c #186114515144", +"*X c #1040104038E3", +"=X c #79E771C671C6", +"-X c #514455556185", +";X c #38E338E379E7", +":X c #30C230C269A6", +">X c #2081208179E7", +",X c #18611C7169A6", +"<X c #10400C3028A2", +"1X c #71C671C669A6", +"2X c #104010401040", +"3X c #49244D349658", +"4X c #49244D3469A6", +"5X c #18611C714924", +"6X c #A699A2899E79", +"7X c #69A669A66185", +"8X c #AEBA79E769A6", +"9X c #A6998A288617", +"0X c #A6996DB669A6", +"qX c #9E797DF769A6", +"wX c #9E7979E769A6", +"eX c #8E3896585965", +"rX c #9658BAEA2081", +"tX c #8E389A6938E3", +"yX c #71C66DB669A6", +"uX c #71C669A669A6", +"iX c #514469A66185", +"pX c #8E3886176185", +"aX c #9E7996588E38", +"sX c #861779E771C6", +"dX c #596559655144", +"fX c #410351445144", +"gX c #082008200820", +"hX c #082004100000", +"jX c #10400C300820", +"kX c #69A661855965", +"lX c #69A669A669A6", +"zX c #96588E388617", +"xX c #DF7DDF7DDF7D", +"cX c #514459655144", +" . . . . . . X X o o . . . . O + . . + . . . . O O O O . o @ o @ @ @ o . O O # # # . @ X $ $ ", +"o % & * * * * = * - - * * * - - - ; - - ; - - : > : : : ; ; , ; - - ; ; ; ; ; : : > : ; ; o < 1 ", +"X : # $ 2 $ $ 3 4 5 4 5 4 4 2 2 2 2 2 2 $ $ $ 6 7 8 9 9 0 q w e r r q 0 8 7 5 4 6 8 q q 9 t y u ", +"@ ; 4 0 9 9 9 0 i i q i 0 9 9 9 9 9 t t 8 9 0 9 9 0 q q q r e w r i i 0 9 7 p 8 i q q i p q a s ", +"@ ; $ i 0 9 9 9 0 0 i q 0 0 i i 0 i 0 9 0 i q q i q q q r w e e r q q 9 t 8 9 q w r i 8 p r d f ", +"@ , $ 9 i 0 9 0 9 0 q q q 0 q g q g h g g w j q q g w w w e k e l g q 0 9 t q w r 9 8 8 7 w d s ", +"o ; z 9 i 9 9 i i h g w g g g w g r w w w w w g q r w e w k k e e w g i 0 g e e i 8 t t 7 w d u ", +"x - $ 7 0 i q g g g e e e w r w w e k < k e w g w c k c < < < c e e w g g e < w h 9 9 9 7 q a u ", +"x , 2 7 0 g g l w k v < k c b < v n n m v < < k k v n n m n n v v < c e c n n w w q 0 8 p i a s ", +"M - 3 7 h e e e , N N N N N B B V V : : C Z ; , A S D F D G H J K + L P I 8 U Y < e q 7 $ q T a ", +"x - 4 t q e b , N N N N N & B B V : > C R R ; A * * F F G H J K + L L E I W Q e ! n g 5 3 w T f ", +"@ - 4 9 g e e N N X Y Y ~ v Y ^ v v / ( ) ) ! _ _ ` ' u ] ] ] [ { a f a a l Q } s ! e 0 8 k T u ", +"| , 4 0 q w e N N Y .H ..9 .Y c c X./ o.o.o.' O.+.O.@.] ] ] { [ { { f a T ..#.$.%.m e r n $.s ", +"@ * 5 g g w Y N N .@ V @ &.*./ o.o.=.' -.-.@.;.:.:.>.>.>.>.>.@.] ,.{ T T T ..9 <.f ! < l n $.1.", +"@ - p r l r k N % ^ W # h 2.2.*.-.*.3.4.5.6.6.6.6.7.8.;.;.>.:.9.] 0.q.q.T $.9 i w.d e.< w m $.f ", +"@ * 5 g q g Y N B 2.W @ r.t.y.6.u.>.i.p.>.p.a.a.s.a.p.d.f.g.8.8.t.h.' T j.k.9 } l.T z.( e x.$.s ", +"@ * p q 0 q k B B < &.h 4.y.t.5.d.p.f.p.f.c.f.v.b.h.n.&.n.m.f.g.7.M.N.q.B.V.#. .C.Z.s ! n x.$.u ", +"@ * 7 0 0 i c V B c j h i.5.p.p.p.p.f.f.f.f.f.f.s.A.h.S.# W A.d.g.g.D.B.B.k.i .F.G.f H.v m T J.", +"x * 7 i 0 q k V K.j L.j A.m.d.a.f.c.p.y.f.f.c.f.f.f.v.&.# * F h.a.u.P.I.U.Y.} l F.G.a ! e k d J.", +"T.= p 0 9 h v K.: y.2.y.5.d.p.u.f.f.s.M s.c.f.f.c.c.f.a.X A , 3.R.E.E.D.Y.W.U l F.G.f ) k < Q.s ", +"$ 5 9 9 q v > : / i.d.5.p.p.p.f.c.R.s.f.f.c.f.f.c.f.c.X !.~.M ^.f.E./.I.Y.} l F.G.f ! < n T s ", +"(.D 5 9 8 g ).C : *.*.d.a.d.d.c.p.f.f.c.f._.f.f.f.f.f.f.H ~.B M &.7.`.'.Y.]. .[.F.Z.1.! < ).$.f ", +"T.= 5 9 i e {.C , 9.5.;.8.>._.p.p.f.f.f.v.s.v.f.f.f.f.}.!.A ~.H &.f.|.`.D.W.l b F.Z.1.! < m $.f ", +"@ * 7 0 q e {.R ; M.9.p.u._.^._.f.p.c.f.c.v.f.c.c.c.f.^.~.A S.S n.7.`. Xj I.[.b F.G.f ! < m T f ", +"+ - 8 0 g e n - A 9.9.>.d.p.a.u.f.p.f.f.f.v.f.f.f.c.n.R S.!.!.O A.7.|.d.X O.l ~ F.Z.f ! < ).$.1.", +"O * 8 i w e m A A -.-.;.p.>.p.p.p.p.f.f.b.b.b.m.s.3.S.S.F !.G 3.f.|.|..Xj W.[.k F.G.s ! v m T f ", +"O - t q w e v S * ' -.O.6.p.;.u.p.p.f.m.3.^.F O S S * F F H h.}.|.XX Xn.F O.b oXC.G.f ! < ).T f ", +"O - 9 i e w < S F OXO.' -.i.>.>.;.p.>.f.A.}.G H !.S.~.A F h.+XR.|.XXXX'.O.@XoX^ F.Z.1.! v m $.s ", +"O , 0 q w e < F F _ _ O.' 2.-.>.>.y.u.u.f.u.#X+X}.A.^.4.y.7.$X|.XXXX%X%X&X*XY =XF.Z.f ) < m $.s ", +"# - 0 g w w < F F y -XO.O.' @.@.y.M y.>.7.7.7.g.P.P.;X:X/.>X,X>X,X%X%X&X*X<X=X1X2XG.f ! v m T f ", +"# , 0 q g w c G H ` y -X-XO.-X_ O.4.;.:.3X;.;.;.+.:.O.@.' 4XO.+.+.:.:.4X4X<X=X=X2XG.a ! < ).T s ", +"O ; i g g g k G J 9 u u u 1.,.u [ ,.N.N.;X:X:XI.Y.W.Y.W.].5X5X5X@X@X@X*X<X) ^ =X2X<.a ! < n T J.", +"O , 0 g g w < | J o P P E | (.I I W W W 6X6 Q 6 ..#.9 9 U . .h r [.[.oX^ =X1X0.2X<.a e.k < T u ", +" ; 0 q g w k 7X9 I I 2 2 W 6XQ Q 8X9X..U 0XqXi #.0XwXl } e m [.eXrXtX=XyXuXe.` 2X<.d ! Y n T s ", +"# ; 9 i q g e ).y iXpX..Q ....aX9 #.#.U U .} l [.e [.[.~ sX^ oX1X1X0.0.dXfXfXgX2X<.d y m {.V.a ", +"# ; 9 i q g e < ! 1 T Z.l.C.a a %.yXuX%.dX^ oXdX0.^ 1X` dXe.s %.hXhXgXgXjXgXjX2XC.G.d z.7X) k.f ", +"H ; 8 9 i q w b ).! %.a k.G.%.s e.H.1 1 e.e.z.e.7XkXz.dXlXuXdXe.hXjX2X2XF.F.F.C.w.V.f e.n m T s ", +"# ; 7 9 h q r w < ).H.b w zX} U . .l l [.l b b b oXv ^ ^ ^ 1XuX0.e.e.` l.w.w.G.$.f z.).k < $.s ", +"# ; 8 9 q q q g e < x.q q ..#.9 #.#.U U .U l [.[.b [.b oXsX< 1XuXyX` dXG.Z.$.T 1.z.) v g k T s ", +"O ; 7 9 0 U q i .k v x.z.f $.G.l.C.2XF.2X2X2X2X2X2XF.2XF.F.F.C.C.l.<.Z.$.d f u ` x.v w q k T s ", +"O ; t 9 9 i q i q r b v e.u a T V.Z.<.<.<.<.w.<.<.<.G.G.G.<.G.G.Z.k.T a s 1 y ! lXn e q 9 e T u ", +"# ; 9 t 9 9 i q 9 i q e m H.` u s f 1.a a a d d a a a 1.1.s 1.s s u 1 z.e.) ).n k w g i t e T s ", +"# xX9 8 t 9 0 9 7 7 9 q e v m 7Xx.x.) ) ) 7X! ! ! ) ) ) 0.) ) 7X0.7X).).v < e r g i 0 9 8 w d u ", +"O ; 7 8 9 0 9 7 5 5 7 9 q w k < oXk k k e w w k b k < < w w e e w e e w l q q 0 9 8 7 7 7 w d u ", +"# xX8 9 9 i 9 4 3 4 5 9 i r r w w q q i i 8 9 i g g r g 9 9 q q 9 9 9 9 9 t 8 8 8 7 p 7 7 e T u ", +" = t i i 9 p 3 4 5 t i q r r r q i 9 9 t 8 p 8 q i i i e e k k k k k k k c k e w w e e k m d s ", +"+ &.cXV.$.$.T d d $.G.<.G.<.<.<.<.<.G.G.G.G.G.G.G.G.<.G.T $.$.j.T T $.$.$.T T T T $.$.$.$.Z.G.s ", +"r -Xu a f u J.1 u u z.z.J.J.J.J.-XcXcXy y y e.cXz.z.cXcXcXe.e.cXcXcXcX-XcXcXcXy cXy cXe.cXz.1.e."}; diff --git a/pixmaps/nophoto.png b/pixmaps/nophoto.png Binary files differnew file mode 100644 index 00000000..085fe26d --- /dev/null +++ b/pixmaps/nophoto.png diff --git a/po/.cvsignore b/po/.cvsignore new file mode 100644 index 00000000..d66a1d6d --- /dev/null +++ b/po/.cvsignore @@ -0,0 +1,9 @@ +*.gmo +*.mo +Makefile +Makefile.in +POTFILES +cat-id-tbl.c +gdm.pot +stamp-cat-id + diff --git a/po/ChangeLog b/po/ChangeLog new file mode 100644 index 00000000..8bda9ab1 --- /dev/null +++ b/po/ChangeLog @@ -0,0 +1,4 @@ +1999-02-17 Kjartan Maraas <kmaraas@fib.hl.no> + + * no.po: Updated + diff --git a/po/Makefile.in.in b/po/Makefile.in.in new file mode 100644 index 00000000..111b40fc --- /dev/null +++ b/po/Makefile.in.in @@ -0,0 +1,248 @@ +# Makefile for program source directory in GNU NLS utilities package. +# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu> +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datadir = $(prefix)/@DATADIRNAME@ +localedir = $(datadir)/locale +gnulocaledir = $(prefix)/share/locale +gettextsrcdir = $(prefix)/share/gettext/po +subdir = po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = $(top_srcdir)/@MKINSTALLDIRS@ + +CC = @CC@ +GENCAT = @GENCAT@ +GMSGFMT = PATH=../src:$$PATH @GMSGFMT@ +MSGFMT = @MSGFMT@ +XGETTEXT = PATH=../src:$$PATH @XGETTEXT@ +MSGMERGE = PATH=../src:$$PATH msgmerge + +DEFS = @DEFS@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ + +INCLUDES = -I.. -I$(top_srcdir)/intl + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +SOURCES = cat-id-tbl.c +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \ +stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES) + +POTFILES = \ + +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +INSTOBJEXT = @INSTOBJEXT@ + +.SUFFIXES: +.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat + +.c.o: + $(COMPILE) $< + +.po.pox: + $(MAKE) $(PACKAGE).pot + $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \ + && rm -f $$file && $(GMSGFMT) -o $$file $< + +.po.cat: + sed -f ../intl/po2msg.sed < $< > $*.msg \ + && rm -f $@ && $(GENCAT) $@ $*.msg + + +all: all-@USE_NLS@ + +all-yes: cat-id-tbl.c $(CATALOGS) +all-no: + +$(srcdir)/$(PACKAGE).pot: $(POTFILES) + $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \ + --add-comments --keyword=_ --keyword=N_ \ + --files-from=$(srcdir)/POTFILES.in \ + && test ! -f $(PACKAGE).po \ + || ( rm -f $(srcdir)/$(PACKAGE).pot \ + && mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot ) + +$(srcdir)/cat-id-tbl.c: stamp-cat-id; @: +$(srcdir)/stamp-cat-id: $(PACKAGE).pot + rm -f cat-id-tbl.tmp + sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \ + | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp + if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \ + rm cat-id-tbl.tmp; \ + else \ + echo cat-id-tbl.c changed; \ + rm -f $(srcdir)/cat-id-tbl.c; \ + mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \ + fi + cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id + + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ +install-data-no: all +install-data-yes: all + if test -r "$(MKINSTALLDIRS)"; then \ + $(MKINSTALLDIRS) $(datadir); \ + else \ + $(SHELL) $(top_srcdir)/mkinstalldirs $(datadir); \ + fi + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + case "$$cat" in \ + *.gmo) destdir=$(gnulocaledir);; \ + *) destdir=$(localedir);; \ + esac; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + dir=$$destdir/$$lang/LC_MESSAGES; \ + if test -r "$(MKINSTALLDIRS)"; then \ + $(MKINSTALLDIRS) $$dir; \ + else \ + $(SHELL) $(top_srcdir)/mkinstalldirs $$dir; \ + fi; \ + if test -r $$cat; then \ + $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \ + else \ + $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \ + fi; \ + if test -r $$cat.m; then \ + $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ + else \ + if test -r $(srcdir)/$$cat.m ; then \ + $(INSTALL_DATA) $(srcdir)/$$cat.m \ + $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ + else \ + true; \ + fi; \ + fi; \ + done + if test "$(PACKAGE)" = "gettext"; then \ + if test -r "$(MKINSTALLDIRS)"; then \ + $(MKINSTALLDIRS) $(gettextsrcdir); \ + else \ + $(SHELL) $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \ + fi; \ + $(INSTALL_DATA) $(srcdir)/Makefile.in.in \ + $(gettextsrcdir)/Makefile.in.in; \ + else \ + : ; \ + fi + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + done + rm -f $(gettextsrcdir)/po-Makefile.in.in + +check: all + +cat-id-tbl.o: ../intl/libgettext.h + +dvi info tags TAGS ID: + +mostlyclean: + rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f $(GMOFILES) + +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: update-po $(DISTFILES) + dists="$(DISTFILES)"; \ + for file in $$dists; do \ + ln $(srcdir)/$$file $(distdir) 2> /dev/null \ + || cp -p $(srcdir)/$$file $(distdir); \ + done + +update-po: Makefile + $(MAKE) $(PACKAGE).pot + PATH=`pwd`/../src:$$PATH; \ + cd $(srcdir); \ + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + mv $$lang.po $$lang.old.po; \ + echo "$$lang:"; \ + if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \ + rm -f $$lang.old.po; \ + else \ + echo "msgmerge for $$cat failed!"; \ + rm -f $$lang.po; \ + mv $$lang.old.po $$lang.po; \ + fi; \ + done + +POTFILES: POTFILES.in + ( if test 'x$(srcdir)' != 'x.'; then \ + posrcprefix='$(top_srcdir)/'; \ + else \ + posrcprefix="../"; \ + fi; \ + rm -f $@-t $@ \ + && (sed -e '/^#/d' -e '/^[ ]*$$/d' \ + -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \ + | sed -e '$$s/\\$$//') > $@-t \ + && chmod a-w $@-t \ + && mv $@-t $@ ) + +Makefile: Makefile.in.in ../config.status POTFILES + cd .. \ + && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ + $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 00000000..cf5a1857 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,11 @@ +daemon/gdm.c +daemon/auth.c +daemon/filecheck.c +daemon/misc.c +daemon/server.c +daemon/slave.c +daemon/verify.c +daemon/xdmcp.c +gui/gdmchooser.c +gui/gdmgreeter.c +gui/gdmlogin.c diff --git a/po/de.po b/po/de.po new file mode 100644 index 00000000..ce920fa4 --- /dev/null +++ b/po/de.po @@ -0,0 +1,865 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 1999-04-08 02:02+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: ENCODING\n" + +#: daemon/gdm.c:136 +#, c-format +msgid "gdm_config_parse: No configuration file: %s. Aborting." +msgstr "gdm_config_parse: Keine Konfigurationsdatei: %s. Breche ab." + +#: daemon/gdm.c:177 +msgid "gdm_config_parse: No greeter specified and default not found." +msgstr "" +"gdm_config_parse: Es wurde kein Greeter angegeben und Default nicht gefunden." + +#: daemon/gdm.c:189 +msgid "gdm_config_parse: No authdir specified and default not found." +msgstr "" +"gdm_config_parse: Es wurde kein authdir angegeben und Default nicht gefunden." + +#: daemon/gdm.c:207 +msgid "" +"gdm_config_parse: No sessions directory specified and default not found." +msgstr "" +"gdm_config_parse: Es wurde kein Sitzungsverzeichnis angegeben und Default " +"nicht gefunden." + +#: daemon/gdm.c:219 +#, fuzzy +msgid "gdm_config_parse: Invalid server line in config file. Ignoring!" +msgstr "gdm_config_parse: Keine Konfigurationsdatei: %s. Breche ab." + +#: daemon/gdm.c:225 +#, fuzzy +msgid "" +"gdm_config_parse: Xdmcp disabled and no local servers defined. Aborting!" +msgstr "gdm_config_parse: Es wurden keine lokalen Server definiert." + +#: daemon/gdm.c:230 +#, c-format +msgid "gdm_config_parse: Can't find the gdm user (%s). Aborting!" +msgstr "gdm_config_parse: Kann den gdm Benutzer (%s) nicht finden. Breche ab!" + +#: daemon/gdm.c:235 +#, fuzzy +msgid "gdm_config_parse: The gdm user should not be root. Aborting!" +msgstr "gdm_config_parse: Authdir %s existiert nicht. Breche ab." + +#: daemon/gdm.c:240 +#, c-format +msgid "gdm_config_parse: Can't find the gdm group (%s). Aborting!" +msgstr "gdm_config_parse: Kann die gdm Gruppe (%s) nicht finden. Breche ab!" + +#: daemon/gdm.c:246 +#, fuzzy +msgid "gdm_config_parse: The gdm group should not be root. Aborting!" +msgstr "gdm_config_parse: Kann die gdm Gruppe (%s) nicht finden. Breche ab!" + +#: daemon/gdm.c:253 +#, c-format +msgid "gdm_config_parse: Authdir %s does not exist. Aborting." +msgstr "gdm_config_parse: Authdir %s existiert nicht. Breche ab." + +#: daemon/gdm.c:256 +#, c-format +msgid "gdm_config_parse: Authdir %s is not a directory. Aborting." +msgstr "gdm_config_parse: Authdir %s ist kein Verzeichnis. Breche ab." + +#: daemon/gdm.c:259 +#, c-format +msgid "" +"gdm_config_parse: Authdir %s is not owned by user %s, group %s. Aborting." +msgstr "" +"gdm_config_parse: Authdir %s gehört nicht Benutzer %s und Gruppe %s. Breche " +"ab." + +#: daemon/gdm.c:262 +#, c-format +msgid "" +"gdm_config_parse: Authdir %s has wrong permissions. Should be 750. Aborting." +msgstr "" +"gdm_config_parse: Authdir %s hat falsche Zugriffsrechte. Sollte 750 sein. " +"Breche ab." + +#: daemon/gdm.c:318 +#, c-format +msgid "gdm_display_manage: Failed forking gdm slave process for %d" +msgstr "" + +#: daemon/gdm.c:397 +#, c-format +msgid "gdm_child_action: Aborting display %s" +msgstr "gdm_child_action: Breche Display %s ab" + +#: daemon/gdm.c:402 +msgid "gdm_child_action: Master rebooting..." +msgstr "gdm_child_action: Master rebooting..." + +#: daemon/gdm.c:408 +#, c-format +msgid "gdm_child_action: Reboot failed: %s" +msgstr "gdm_child_action: Neustart fehlgeschlagen: %s" + +#: daemon/gdm.c:412 +msgid "gdm_child_action: Master halting..." +msgstr "" + +#: daemon/gdm.c:418 +#, c-format +msgid "gdm_child_action: Halt failed: %s" +msgstr "gdm_child_action: Anhalten fehlgeschlagen: %s" + +#: daemon/gdm.c:512 +msgid "gdm_daemonify: fork() failed!" +msgstr "gdm_daemonify: fork() fehlgeschlagen!" + +#: daemon/gdm.c:515 +#, c-format +msgid "gdm_daemonify: setsid() failed: %s!" +msgstr "gdm_daemonify: setsid() fehlgeschlagen: %s!" + +#: daemon/gdm.c:540 +msgid "Only root wants to run gdm\n" +msgstr "Nur root darf gdm starten\n" + +#: daemon/gdm.c:558 +msgid "" +"gdm already running. Aborting!\n" +"\n" +msgstr "" +"gdm läuft schon. Breche ab!\n" +"\n" + +#: daemon/gdm.c:563 +#, c-format +msgid "" +"According to %s, gdm was already running (%d),\n" +"but seems to have been murdered mysteriously.\n" +msgstr "" + +#: daemon/gdm.c:584 +msgid "gdm_main: Error setting up TERM signal handler" +msgstr "" + +#: daemon/gdm.c:587 +msgid "gdm_main: Error setting up INT signal handler" +msgstr "" + +#: daemon/gdm.c:595 +msgid "gdm_main: Error setting up CHLD signal handler" +msgstr "" + +#: daemon/auth.c:62 +#, c-format +msgid "gdm_auth_secure_display: Could not unlink %s file: %s" +msgstr "" + +#: daemon/auth.c:73 +#, c-format +msgid "" +"gdm_auth_secure_display: Error starting xauth process: %s. Running insecure!" +msgstr "" + +#: daemon/auth.c:77 +msgid "gdm_auth_secure_display: Error forking xauth process. Running insecure!" +msgstr "" + +#: daemon/auth.c:109 +#, c-format +msgid "gdm_auth_user_add: Error starting xauth process: %s" +msgstr "" + +#: daemon/auth.c:113 +msgid "gdm_auth_user_add: Error forking xauth process." +msgstr "" + +#: daemon/auth.c:143 +#, c-format +msgid "gdm_auth_user_remove: Error starting xauth process: %s" +msgstr "" + +#: daemon/auth.c:147 +msgid "gdm_auth_user_remove: Error forking xauth process." +msgstr "" + +#: daemon/filecheck.c:50 daemon/filecheck.c:83 +#, c-format +msgid "%s: %s is not owned by uid %d. Skipping." +msgstr "%s: %s is not owned by uid %d. Skipping." + +#: daemon/filecheck.c:57 +#, c-format +msgid "%s: %s is writable by group/other. Should be 755. Skipping." +msgstr "" +"%s: %s ist beschreibbar durch Gruppe/Andere. Sollte 755 sein. Überspringe." + +#: daemon/filecheck.c:76 +#, c-format +msgid "%s: %s is not a regular file. Skipping." +msgstr "%s: %s ist keine reguläre Datei. Überspringe." + +#: daemon/filecheck.c:90 +#, fuzzy, c-format +msgid "%s: %s is writable by group. Should be 644. Skipping." +msgstr "" +"%s: %s ist schreibbar durch Gruppe/Andere. Sollte 644 sein. Überspringe." + +#: daemon/filecheck.c:97 +#, c-format +msgid "%s: %s is writable by group/other. Should be 644. Skipping." +msgstr "" +"%s: %s ist schreibbar durch Gruppe/Andere. Sollte 644 sein. Überspringe." + +#: daemon/filecheck.c:104 +#, c-format +msgid "%s: %s is bigger than sysadmin specified maximum file size. Skipping." +msgstr "" +"%s: %s ist größer als die durch den Systemadministrator spezifizierte " +"maximale Dateigröße. Überspringe." + +#: daemon/misc.c:121 +#, c-format +msgid "gdm_exec_script: Failed starting: %s" +msgstr "" + +#: daemon/misc.c:125 +msgid "gdm_exec_script: Can't fork script process!" +msgstr "" + +#: daemon/misc.c:153 +#, c-format +msgid "gdm_exec_command: Failed starting: %s" +msgstr "" + +#: daemon/misc.c:157 +msgid "gdm_exec_command: Can't fork process!" +msgstr "" + +#: daemon/server.c:82 daemon/server.c:213 +#, fuzzy +msgid "gdm_server_start: Error setting up USR1 signal handler" +msgstr "gdm_slave_xsync_ping: Fehler beim Einrichten des ALARM signal handlers" + +#: daemon/server.c:99 +#, fuzzy, c-format +msgid "gdm_server_start: Could not open logfile for display %s!" +msgstr "gdm_xdmcp_handle_manage: Konnte Logdatei für Display %s nicht öffnen!" + +#: daemon/server.c:129 +msgid "gdm_server_start: Error setting USR1 to SIG_IGN" +msgstr "" + +#: daemon/server.c:146 +#, fuzzy, c-format +msgid "gdm_server_start: Xserver not found: %s" +msgstr "gdm_local_servers_start: Starte %s" + +#: daemon/server.c:152 +msgid "gdm_server_start: Can't fork Xserver process!" +msgstr "" + +#: daemon/server.c:178 +#, c-format +msgid "gdm_server_stop: Could not unlink auth file: %s!" +msgstr "" + +#: daemon/server.c:237 +#, fuzzy +msgid "gdm_server_restart: Error setting up ALARM signal handler" +msgstr "gdm_slave_xsync_ping: Fehler beim Einrichten des ALARM signal handlers" + +#: daemon/slave.c:112 +msgid "gdm_slave_init: Error setting up TERM/INT signal handler" +msgstr "" + +#: daemon/slave.c:120 +msgid "gdm_slave_init: Error setting up CHLD signal handler" +msgstr "" + +#: daemon/slave.c:171 +msgid "gdm_slave_greeter: Can't init pipe to gdmgreeter" +msgstr "" + +#: daemon/slave.c:196 +#, c-format +msgid "gdm_slave_greeter: Couldn't set groupid to %d" +msgstr "" + +#: daemon/slave.c:199 +#, c-format +msgid "gdm_slave_greeter: Couldn't set userid to %d" +msgstr "" + +#: daemon/slave.c:209 +#, c-format +msgid "gdm_slave_greeter: Error starting greeter on display %s" +msgstr "" + +#: daemon/slave.c:212 +msgid "gdm_slave_greeter: Can't fork gdmgreeter process" +msgstr "" + +#: daemon/slave.c:280 +#, c-format +msgid "gdm_slave_session_init: User '%s' not found. Aborting." +msgstr "" + +#: daemon/slave.c:299 +msgid "" +"gdm_slave_session_init: Execution of PreSession script returned > 0. " +"Aborting." +msgstr "" + +#: daemon/slave.c:304 +msgid "gdm_slave_session_init: Error forking user session" +msgstr "" + +#: daemon/slave.c:312 +#, c-format +msgid "gdm_slave_session_init: Could not setgid %d. Aborting." +msgstr "" + +#: daemon/slave.c:315 +#, c-format +msgid "gdm_slave_session_init: initgroups() failed for %s. Aborting." +msgstr "" + +#: daemon/slave.c:318 +#, c-format +msgid "gdm_slave_session_init: Could not become %s. Aborting." +msgstr "" + +#: daemon/slave.c:373 +#, c-format +msgid "gdm_slave_session_init: Could not start session `%s'" +msgstr "" + +#: daemon/slave.c:547 +#, c-format +msgid "gdm_slave_windows_kill_ioerror_handler: Fatal X error - Restarting %s" +msgstr "" +"gdm_slave_windows_kill_ioerror_handler: Fataler X Fehler - Starte %s erneut" + +#: daemon/slave.c:579 +msgid "gdm_slave_xsync_ping: Error setting up ALARM signal handler" +msgstr "gdm_slave_xsync_ping: Fehler beim Einrichten des ALARM signal handlers" + +#: daemon/verify.c:122 daemon/verify.c:185 gui/gdmgreeter.c:1363 +msgid "Login:" +msgstr "" + +#: daemon/verify.c:128 +msgid "Can't find /etc/pam.d/gdm!" +msgstr "Kann /etc/pam.d/gdm nicht finden!" + +#: daemon/verify.c:132 +#, c-format +msgid "Can't set PAM_TTY=%s" +msgstr "Kann PAM_TTY=%s nicht setzen" + +#: daemon/verify.c:137 daemon/verify.c:189 +#, c-format +msgid "Couldn't authenticate %s" +msgstr "Konnte %s nicht beglaubigen" + +#: daemon/verify.c:142 +#, c-format +msgid "Couldn't set acct. mgmt for %s" +msgstr "Konnte acct. mgmt für %s nicht setzen" + +#: daemon/verify.c:147 +#, c-format +msgid "Couldn't set credentials for %s" +msgstr "Konnte Berechtigungsnachweise für %s nicht setzen" + +#: daemon/verify.c:152 +#, c-format +msgid "Couldn't open session for %s" +msgstr "Konnte Session für %s nicht öffnen" + +#: daemon/verify.c:192 +msgid "User unknown" +msgstr "" + +#: daemon/verify.c:208 gui/gdmgreeter.c:1369 +msgid "Password:" +msgstr "Passwort:" + +#: daemon/verify.c:213 +msgid "Incorrect password" +msgstr "" + +#: daemon/xdmcp.c:172 +#, c-format +msgid "gdm_xdmcp_init: Could not get server hostname: %s!" +msgstr "gdm_xdmcp_init: Konnte Server Hostname nicht bekommen: %s!" + +#: daemon/xdmcp.c:183 +msgid "gdm_xdmcp_init: Could not create socket!" +msgstr "gdm_xdmcp_init: Konnte Socket nicht erzeugen!" + +#: daemon/xdmcp.c:190 +msgid "gdm_xdmcp_init: Could not bind to XDMCP socket!" +msgstr "gdm_xdmcp_init: Konnte nicht an XDMCP Socket binden!" + +#: daemon/xdmcp.c:225 +msgid "gdm_xdmcp_decode: Could not create XDMCP buffer!" +msgstr "gdm_xdmcp_decode: Konnte XDMCP Buffer nicht erzeugen!" + +#: daemon/xdmcp.c:230 +msgid "gdm_xdmcp_decode: Could not read XDMCP header!" +msgstr "gdm_xdmcp_decode: Konnte XDMCP Header nicht lesen!" + +#: daemon/xdmcp.c:235 +msgid "gdm_xdmcp_decode: Incorrect XDMCP version!" +msgstr "gdm_xdmcp_decode: Falsche XDMCP Version!" + +#: daemon/xdmcp.c:271 +#, c-format +msgid "gdm_xdmcp_decode_packet: Unknown opcode from host %s" +msgstr "gdm_xdmcp_decode_packet: Unbekannter Opcode von Host %s" + +#: daemon/xdmcp.c:289 +msgid "gdm_xdmcp_query: Could not extract authlist from packet" +msgstr "gdm_xdmcp_query: Konnte authlist vom Paket nicht extrahieren" + +#: daemon/xdmcp.c:300 +msgid "gdm_xdmcp_query: Error in checksum" +msgstr "gdm_xdmcp_query: Fehler in Prüfsumme" + +#: daemon/xdmcp.c:323 +msgid "GNOME" +msgstr "" + +#: daemon/xdmcp.c:347 +#, c-format +msgid "Denied XDMCP query from host %s" +msgstr "" + +#: daemon/xdmcp.c:349 +msgid "Display not authorized to connect" +msgstr "Display ist nicht autorisiert zu verbinden" + +#: daemon/xdmcp.c:382 +#, c-format +msgid "gdm_xdmcp_handle_request: Got REQUEST from banned host %s" +msgstr "gdm_xdmcp_handle_request: REQUEST von gesperrtem Host %s bekommen" + +#: daemon/xdmcp.c:389 +msgid "gdm_xdmcp_handle_request: Could not read Display Number" +msgstr "gdm_xdmcp_handle_request: Konnte Display Nummer nicht lesen" + +#: daemon/xdmcp.c:395 +msgid "gdm_xdmcp_handle_request: Could not read Connection Type" +msgstr "gdm_xdmcp_handle_request: Konnte Verbindungstyp nicht lesen" + +#: daemon/xdmcp.c:401 +msgid "gdm_xdmcp_handle_request: Could not read Client Address" +msgstr "gdm_xdmcp_handle_request: Konnte Client Adresse nicht lesen" + +#: daemon/xdmcp.c:407 +msgid "gdm_xdmcp_handle_request: Could not read Authentication Names" +msgstr "gdm_xdmcp_handle_request: Konnte Authentication Namen nicht lesen" + +#: daemon/xdmcp.c:413 +msgid "gdm_xdmcp_handle_request: Could not read Authentication Data" +msgstr "gdm_xdmcp_handle_request: Konnte Authentication Data nicht lesen" + +#: daemon/xdmcp.c:419 +msgid "gdm_xdmcp_handle_request: Could not read Authorization List" +msgstr "gdm_xdmcp_handle_request: Konnte Authorization List nicht lesen" + +#: daemon/xdmcp.c:430 +msgid "gdm_xdmcp_handle_request: Could not read Manufacturer ID" +msgstr "gdm_xdmcp_handle_request: Konnte Manufacturer ID nicht lesen" + +#: daemon/xdmcp.c:448 +#, c-format +msgid "gdm_xdmcp_handle_request: Failed checksum from %s" +msgstr "gdm_xdmcp_handle_request: Fehlgeschlagene Prüfsumme von %s" + +#: daemon/xdmcp.c:566 +#, c-format +msgid "gdm_xdmcp_handle_manage: Got Manage from banned host %s" +msgstr "gdm_xdmcp_handle_manage: Manage von gesperrtem Host %s bekommen" + +#: daemon/xdmcp.c:573 +msgid "gdm_xdmcp_handle_manage: Could not read Session ID" +msgstr "gdm_xdmcp_handle_manage: Konnte Session ID nicht lese" + +#: daemon/xdmcp.c:579 +msgid "gdm_xdmcp_handle_manage: Could not read Display Number" +msgstr "gdm_xdmcp_handle_manage: Konnte Display Nummer nicht lesen" + +#: daemon/xdmcp.c:588 +msgid "gdm_xdmcp_manage: Could not read Display Class" +msgstr "gdm_xdmcp_manage: Konnte Display Class nicht lesen" + +#: daemon/xdmcp.c:607 +#, c-format +msgid "gdm_xdmcp_handle_manage: Could not open logfile for display %s!" +msgstr "gdm_xdmcp_handle_manage: Konnte Logdatei für Display %s nicht öffnen!" + +#: daemon/xdmcp.c:679 +#, c-format +msgid "gdm_xdmcp_handle_keepalive: Got KEEPALIVE from banned host %s" +msgstr "gdm_xdmcp_handle_keepalive: KEEPALIVE von gesperrtem Host %s bekommen" + +#: daemon/xdmcp.c:686 +msgid "gdm_xdmcp_handle_keepalive: Could not read Display Number" +msgstr "gdm_xdmcp_handle_keepalive: Konnte Display Nummer nicht lesen" + +#: daemon/xdmcp.c:692 +msgid "gdm_xdmcp_handle_keepalive: Could not read Session ID" +msgstr "gdm_xdmcp_handle_keepalive: Konnte Session ID nicht lesen" + +#: gui/gdmchooser.c:336 +#, fuzzy, c-format +msgid "gdm_chooser_parse_config: No configuration file: %s. Aborting." +msgstr "gdm_greeter_parse_config: Keine Konfigurationsdatei: %s. Breche ab." + +#: gui/gdmchooser.c:447 +#, fuzzy, c-format +msgid "Can't open default host icon: %s" +msgstr "Konnte Session für %s nicht öffnen" + +#. Buttons +#: gui/gdmchooser.c:512 +msgid "Connect" +msgstr "" + +#: gui/gdmchooser.c:519 +msgid "Rescan" +msgstr "" + +#: gui/gdmchooser.c:525 +msgid "Cancel" +msgstr "" + +#: gui/gdmchooser.c:576 gui/gdmgreeter.c:1672 gui/gdmlogin.c:1102 +msgid "main: Error setting up HUP signal handler" +msgstr "" + +#: gui/gdmchooser.c:579 gui/gdmgreeter.c:1675 gui/gdmlogin.c:1105 +msgid "main: Error setting up INT signal handler" +msgstr "" + +#: gui/gdmchooser.c:582 gui/gdmgreeter.c:1678 gui/gdmlogin.c:1108 +msgid "main: Error setting up TERM signal handler" +msgstr "" + +#: gui/gdmgreeter.c:155 +msgid "Gnome Display Manager" +msgstr "" + +#: gui/gdmgreeter.c:157 +msgid "Copyright Martin K. Petersen (C) 1998, 1999" +msgstr "" + +#: gui/gdmgreeter.c:159 gui/gdmlogin.c:328 +msgid "" +"gdm manages local and remote displays and provides the user with a login " +"window." +msgstr "" +"gdm verwaltet lokale und entfernte Displays und stellt dem Benutzer ein " +"Login-Fenster bereit." + +#: gui/gdmgreeter.c:194 gui/gdmlogin.c:271 +msgid "gdm_parse_enriched_string: String too long!" +msgstr "gdm_parse_enriched_string: String ist zu lang!" + +#: gui/gdmgreeter.c:195 gui/gdmlogin.c:272 +msgid "Welcome to " +msgstr "Willkommen bei " + +#: gui/gdmgreeter.c:199 gui/gdmlogin.c:276 +msgid "gdm_parse_enriched_string: Could not malloc temporary buffer!" +msgstr "gdm_parse_enriched_string: Konnte temporären Buffer nicht allokieren!" + +#: gui/gdmgreeter.c:273 +msgid "Logo not found. No image will be displayed!" +msgstr "Logo wurde nicht gefunden. Es wird kein Bild angezeigt!" + +#: gui/gdmgreeter.c:299 +#, c-format +msgid "gdm_greeter_parse_config: No configuration file: %s. Aborting." +msgstr "gdm_greeter_parse_config: Keine Konfigurationsdatei: %s. Breche ab." + +#: gui/gdmgreeter.c:323 gui/gdmlogin.c:403 +#, c-format +msgid "messages/welcome=Welcome to %h" +msgstr "" + +#: gui/gdmgreeter.c:424 gui/gdmlogin.c:527 gui/gdmlogin.c:557 +#, c-format +msgid "" +"You have chosen %s for this session, but your default setting is %s.\n" +"Do you wish to make %s the default for future sessions?" +msgstr "" +"Sie haben %s für diese Sitzung ausgewählt. Ihr Default-Einstellung ist aber " +"%s.\n" +"Möchten Sie %s zu Ihrer Default-Einstellung für zukünftige Sitzungen machen?" + +#: gui/gdmgreeter.c:432 +#, c-format +msgid "" +"Your previous session type %s is not installed on this machine.\n" +"Do you wish to make %s the default for future sessions?" +msgstr "" +"Ihr vorheriger Sitzungstyp %s ist auf diesem Rechner nicht installiert.\n" +"Möchten Sie %s zu Ihrer Default-Einstellung für zukünftige Sitzungen machen?" + +#: gui/gdmgreeter.c:440 +#, c-format +msgid "" +"Your previous session type %s is not installed on this machine.\n" +"You will be logged in using the %s environment." +msgstr "" +"Ihr vorheriger Sitzungstyp %s ist auf diesem Rechner nicht installiert.\n" +"Sie werden mit der %s Umgebung eingeloggt werden." + +#: gui/gdmgreeter.c:453 +#, c-format +msgid "" +"You have chosen the language %s for this session, but your default setting " +"is %s.\n" +"Do you wish to make %s the default language for future sessions?" +msgstr "" +"Sie haben die Sprache %s für diese Sitzung ausgewählt. Ihre " +"Default-Einstellung ist %s.\n" +"Möchten Sie %s zu Ihrer Default-Sprache für zukünftige Sitzungen machen?" + +#: gui/gdmgreeter.c:461 +#, c-format +msgid "" +"Your previous language %s is not installed on this machine.\n" +"Do you wish to make %s the default language for future sessions?" +msgstr "" +"Ihre vorherige Sprache %s ist auf diesem Rechner nicht installiert.\n" +"Möchten Sie %s zu Ihrer Default-Sprache für zukünftige Sitzungen machen?" + +#: gui/gdmgreeter.c:469 +#, c-format +msgid "" +"Your previous language %s is not installed on this machine.\n" +"Your environment will be %s." +msgstr "" +"Ihre vorherige Sprache %s ist auf diesem Rechner nicht installiert.\n" +"Ihre Umgebung wird %s sein." + +#: gui/gdmgreeter.c:500 +msgid "Invalid username or password!" +msgstr "Ungültiger Benutzername oder Passwort!" + +#: gui/gdmgreeter.c:526 gui/gdmlogin.c:354 +msgid "Are you sure you want to reboot the machine?" +msgstr "Sind Sie sicher, daß sie den Rechner neu starten möchten?" + +#: gui/gdmgreeter.c:555 gui/gdmlogin.c:366 +msgid "Are you sure you want to halt the machine?" +msgstr "Sind Sie sicher, daß sie den Rechner anhalten möchten?" + +#: gui/gdmgreeter.c:812 +msgid "gdm_greeter_session_init: Session script directory not found!" +msgstr "gdm_greeter_session_init: Sitzungs-Skript Verzeichnis nicht gefunden!" + +#: gui/gdmgreeter.c:865 gui/gdmlogin.c:694 +msgid "No session scripts found. Aborting!" +msgstr "Keine Sitzungs-Skripte gefunden. Breche ab!" + +#: gui/gdmgreeter.c:869 gui/gdmlogin.c:698 +#, c-format +msgid "No default session link found. Using %s.\n" +msgstr "Keinen Default Sitzungs-Link gefunden. Benutze %s.\n" + +#. Login button +#: gui/gdmgreeter.c:1029 +msgid "Login" +msgstr "" + +#. Init sessions menu +#: gui/gdmgreeter.c:1041 +msgid "Sessions" +msgstr "Sitzungen" + +#. Language selection support +#: gui/gdmgreeter.c:1048 +msgid "Languages" +msgstr "Sprachen" + +#: gui/gdmgreeter.c:1058 gui/gdmlogin.c:960 +msgid "Reboot..." +msgstr "Neustart..." + +#: gui/gdmgreeter.c:1064 gui/gdmlogin.c:966 +msgid "Halt..." +msgstr "Anhalten (Halt)" + +#: gui/gdmgreeter.c:1071 +msgid "Suspend" +msgstr "Suspendieren" + +#: gui/gdmgreeter.c:1078 gui/gdmlogin.c:972 +msgid "System" +msgstr "" + +#: gui/gdmgreeter.c:1086 gui/gdmlogin.c:986 +#, c-format +msgid "Can't open icon file: %s. Suspending iconify feature!" +msgstr "" + +#: gui/gdmgreeter.c:1090 gui/gdmlogin.c:990 +msgid "Iconify" +msgstr "Ikonifizieren" + +#. Option button +#: gui/gdmgreeter.c:1099 +msgid "Options..." +msgstr "Optionen..." + +#: gui/gdmgreeter.c:1531 +#, c-format +msgid "Can't open NofaceImageFile: %s. Suspending face browser!" +msgstr "" + +#: gui/gdmgreeter.c:1686 +msgid "main: Error setting up USR1 signal handler" +msgstr "" + +#: gui/gdmgreeter.c:1694 +msgid "main: Error setting up USR2 signal handler" +msgstr "" + +#: gui/gdmlogin.c:382 +#, fuzzy, c-format +msgid "gdm_login_parse_config: No configuration file: %s. Aborting." +msgstr "gdm_greeter_parse_config: Keine Konfigurationsdatei: %s. Breche ab." + +#: gui/gdmlogin.c:508 +#, fuzzy, c-format +msgid "" +"Your preferred session type %s is not installed on this machine.\n" +"Do you wish to make %s the default for future sessions?" +msgstr "" +"Ihr vorheriger Sitzungstyp %s ist auf diesem Rechner nicht installiert.\n" +"Möchten Sie %s zu Ihrer Default-Einstellung für zukünftige Sitzungen machen?" + +#: gui/gdmlogin.c:616 +#, c-format +msgid "%s session selected" +msgstr "" + +#: gui/gdmlogin.c:632 gui/gdmlogin.c:723 +msgid "Last" +msgstr "" + +#: gui/gdmlogin.c:647 +#, fuzzy +msgid "gdm_login_session_init: Session script directory not found!" +msgstr "gdm_greeter_session_init: Sitzungs-Skript Verzeichnis nicht gefunden!" + +#: gui/gdmlogin.c:709 +#, c-format +msgid "%s language selected" +msgstr "" + +#: gui/gdmlogin.c:736 +msgid "A-M" +msgstr "" + +#: gui/gdmlogin.c:742 +msgid "N-Z" +msgstr "" + +#: gui/gdmlogin.c:748 +msgid "Other" +msgstr "" + +#: gui/gdmlogin.c:946 +#, fuzzy +msgid "Session" +msgstr "Sitzungen" + +#: gui/gdmlogin.c:953 +#, fuzzy +msgid "Language" +msgstr "Sprachen" + +#: gui/gdmlogin.c:979 +msgid "Host chooser" +msgstr "" + +#, fuzzy +#~ msgid "gdm_server_usr1_handler: Could not open display %s" +#~ msgstr "gdm_slave_windows_kill: Konnte Display %s nicht öffnen" + +#, fuzzy +#~ msgid "gdm_display_dispose: Closing display %s" +#~ msgstr "gdm_child_action: Breche Display %s ab" + +#~ msgid "gdm_display_manage: Managing %s" +#~ msgstr "gdm_display_manage: Verwalte %s" + +#~ msgid "gdm_child_action: Server process returned unknown status %d" +#~ msgstr "" +#~ "gdm_child_action: Der Server Prozeß hat einen unbekannten Status %d " +#~ "zurückgegeben" + +#, fuzzy +#~ msgid "gdm_child_action: Slave process returned unknown status %d" +#~ msgstr "" +#~ "gdm_child_action: Slave Proceß hat unbekannten Status zurückgegeben!" + +#~ msgid "gdm_child_handler: child %d returned %d" +#~ msgstr "gdm_child_handler: Kind %d gab %d zurück" + +#~ msgid "gdm_display_unmanage: Stopping %s" +#~ msgstr "gdm_display_unmanage: Stoppe %s" + +#~ msgid "gdm_term_handler: Got TERM/INT. Going down!" +#~ msgstr "gdm_term_handler: TERM/INT empfangen. Fahre runter!" + +#~ msgid "gdm_slave_xioerror_handler: I/O error for display %s" +#~ msgstr "gdm_slave_xioerror_handler: I/O Fehler für Display %s" + +#~ msgid "gdm_slave_xsync_handler: Xping failed for display %s" +#~ msgstr "gdm_slave_xsync_handler: Xping für Display %s fehlgeschlagen" + +#~ msgid "gdm_slave_xsync_ping: Pinging %s returned %d" +#~ msgstr "gdm_slave_xsync_ping: Ping an %s ergab %d" + +#~ msgid "gdm_xdmcp_send_willing: Sending WILLING to %s" +#~ msgstr "gdm_xdmcp_send_willing: Sende WILLING an %s" + +#~ msgid "gdm_xdmcp_send_unwilling: Sending UNWILLING to %s" +#~ msgstr "gdm_xdmcp_send_unwilling: Sende UNWILLING an %s" + +#~ msgid "gdm_xdmcp_handle_request: Got REQUEST from %s" +#~ msgstr "gdm_xdmcp_handle_request: REQUEST von %s bekommen" + +#~ msgid "gdm_xdmcp_send_accept: Sending ACCEPT to %s with SessionID=%d" +#~ msgstr "gdm_xdmcp_send_accept: Sende ACCEPT an %s mit SessionID=%d" + +#~ msgid "gdm_xdmcp_send_decline: Sending DECLINE to %s" +#~ msgstr "gdm_xdmcp_send_decline: Sende DECLINE an %s" + +#~ msgid "gdm_xdmcp_manage: Got MANAGE from %s" +#~ msgstr "gdm_xdmcp_manage: MANAGE von %s bekommen" + +#~ msgid "gdm_xdmcp_manage: Got Display=%d, SessionID=%d from %s" +#~ msgstr "gdm_xdmcp_manage: Display=%d, SessionID=%d von %s bekommen" + +#~ msgid "gdm_xdmcp_handle_keepalive: Got KEEPALIVE from %s" +#~ msgstr "gdm_xdmcp_handle_keepalive: KEEPALIVE von %s bekommen" diff --git a/po/es.po b/po/es.po new file mode 100644 index 00000000..869d2405 --- /dev/null +++ b/po/es.po @@ -0,0 +1,954 @@ +msgid "" +msgstr "" +"Project-Id-Version: gdm 0.7.9\n" +"POT-Creation-Date: 1999-04-08 02:02+0200\n" +"PO-Revision-Date: 1998-11-21 01:59:37+0100\n" +"Last-Translator: Pablo Saratxaga <srtxg@chanae.alphanet.ch>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" +"Date: 1998-11-21 01:59:37+0100\n" +"From: Pablo Saratxaga <srtxg@chanae.alphanet.ch>\n" +"Xgettext-Options: --default-domain=gdm --directory=.. --add-comments " +"--keyword=_ --keyword=N_ --files-from=./POTFILES.in\n" +"Files: src/gdm.c src/gdmauth.c src/gdmgreeter.c src/gdmslave.c " +"src/gdmverify.c\n" + +#: daemon/gdm.c:136 +#, c-format +msgid "gdm_config_parse: No configuration file: %s. Aborting." +msgstr "gdm_config_parse: Ningún archivo de configuración: %s. Abortando." + +#: daemon/gdm.c:177 +msgid "gdm_config_parse: No greeter specified and default not found." +msgstr "" +"gdm_config_parse: no se especificó un programa de bienvenida y no se " +"encontró a gdmgreeter" + +#: daemon/gdm.c:189 +msgid "gdm_config_parse: No authdir specified and default not found." +msgstr "" +"gdm_config_parse: no se especificó el directorio authdir y no se encontró el " +"normal" + +#: daemon/gdm.c:207 +msgid "" +"gdm_config_parse: No sessions directory specified and default not found." +msgstr "" +"gdm_config_parse: No se especificó el directorio de sesiones y no encontré " +"el mio" + +#: daemon/gdm.c:219 +#, fuzzy +msgid "gdm_config_parse: Invalid server line in config file. Ignoring!" +msgstr "gdm_config_parse: Ningún archivo de configuración: %s. Abortando." + +#: daemon/gdm.c:225 +#, fuzzy +msgid "" +"gdm_config_parse: Xdmcp disabled and no local servers defined. Aborting!" +msgstr "gdm_config_parse: No hay servidores locales definidos." + +#: daemon/gdm.c:230 +#, c-format +msgid "gdm_config_parse: Can't find the gdm user (%s). Aborting!" +msgstr "gdm_config_parse: No se encuentra el usuario de gdm (%s). Abortando." + +#: daemon/gdm.c:235 +#, fuzzy +msgid "gdm_config_parse: The gdm user should not be root. Aborting!" +msgstr "" +"gdm_config_parse: El directorio de autorizaciones %s no existe. Abortando." + +#: daemon/gdm.c:240 +#, c-format +msgid "gdm_config_parse: Can't find the gdm group (%s). Aborting!" +msgstr "gdm_config_parse: No se encuentra el grupo de gdm (%s). Abortando." + +#: daemon/gdm.c:246 +#, fuzzy +msgid "gdm_config_parse: The gdm group should not be root. Aborting!" +msgstr "gdm_config_parse: No se encuentra el grupo de gdm (%s). Abortando." + +#: daemon/gdm.c:253 +#, c-format +msgid "gdm_config_parse: Authdir %s does not exist. Aborting." +msgstr "" +"gdm_config_parse: El directorio de autorizaciones %s no existe. Abortando." + +#: daemon/gdm.c:256 +#, c-format +msgid "gdm_config_parse: Authdir %s is not a directory. Aborting." +msgstr "gdm_config_parse: %s no es un directorio. Abortando." + +#: daemon/gdm.c:259 +#, c-format +msgid "" +"gdm_config_parse: Authdir %s is not owned by user %s, group %s. Aborting." +msgstr "" +"gdm_config_parse: El directorio de autorizaciones %s no pertenece al usuario " +"%s, grupo %s. Abortando." + +#: daemon/gdm.c:262 +#, c-format +msgid "" +"gdm_config_parse: Authdir %s has wrong permissions. Should be 750. Aborting." +msgstr "" +"gdm_config_parse: El directorio de autorizaciones %s tiene permisos " +"incorrectos. Debe de ser 750. Abortando." + +#: daemon/gdm.c:318 +#, c-format +msgid "gdm_display_manage: Failed forking gdm slave process for %d" +msgstr "gdm_display_manager: falla al crear el proceso esclavo para %d" + +#: daemon/gdm.c:397 +#, c-format +msgid "gdm_child_action: Aborting display %s" +msgstr "gdm_child_action: Abortando el despliegue %s" + +#: daemon/gdm.c:402 +msgid "gdm_child_action: Master rebooting..." +msgstr "gdm_child_action: Reiniciando el maestro" + +#: daemon/gdm.c:408 +#, c-format +msgid "gdm_child_action: Reboot failed: %s" +msgstr "gdm_child_action: Falla al reiniciar: %s" + +#: daemon/gdm.c:412 +msgid "gdm_child_action: Master halting..." +msgstr "gdm_child_action: Deteniendo al maestro" + +#: daemon/gdm.c:418 +#, c-format +msgid "gdm_child_action: Halt failed: %s" +msgstr "gdm_child_action: Falla al detener: %s" + +#: daemon/gdm.c:512 +msgid "gdm_daemonify: fork() failed!" +msgstr "gdm_daemonify: falla en fork()" + +#: daemon/gdm.c:515 +#, c-format +msgid "gdm_daemonify: setsid() failed: %s!" +msgstr "gdm_daemonify: setsid () falló: %s" + +#: daemon/gdm.c:540 +msgid "Only root wants to run gdm\n" +msgstr "Solamente root puede ejecutar gdm\n" + +#: daemon/gdm.c:558 +msgid "" +"gdm already running. Aborting!\n" +"\n" +msgstr "" +"gdm ya se encuentra ejecutándose. Abortando!\n" +"\n" + +#: daemon/gdm.c:563 +#, fuzzy, c-format +msgid "" +"According to %s, gdm was already running (%d),\n" +"but seems to have been murdered mysteriously.\n" +msgstr "" +"gdm ya se encontraba corriendo (%d) pero parece que fue matado " +"misteriosamente\n" + +#: daemon/gdm.c:584 +msgid "gdm_main: Error setting up TERM signal handler" +msgstr "gdm_main: Error al configurar el controlador de la señal TERM" + +#: daemon/gdm.c:587 +msgid "gdm_main: Error setting up INT signal handler" +msgstr "gdm_main: Error al configurar el controlador de la señal INT" + +#: daemon/gdm.c:595 +msgid "gdm_main: Error setting up CHLD signal handler" +msgstr "gdm_main: Error al configurar el controlador de la señal CHLD" + +#: daemon/auth.c:62 +#, c-format +msgid "gdm_auth_secure_display: Could not unlink %s file: %s" +msgstr "gdm_auth_secure_display: No se pudo hacer un unlink del archivo %s: %s" + +#: daemon/auth.c:73 +#, c-format +msgid "" +"gdm_auth_secure_display: Error starting xauth process: %s. Running insecure!" +msgstr "" +"gdm_auth_secure_display: Error al lanzar el proceso xauth: %s. ¡Corriendo de " +"manera no segura!" + +#: daemon/auth.c:77 +msgid "gdm_auth_secure_display: Error forking xauth process. Running insecure!" +msgstr "" +"gdm_auth_secure_display: Error al hacer un fork del proceso xauth. " +"¡Corriendo de manera no segura!" + +#: daemon/auth.c:109 +#, c-format +msgid "gdm_auth_user_add: Error starting xauth process: %s" +msgstr "gdm_auth_user_add: Error al lanzar el proceso xauth: %s" + +#: daemon/auth.c:113 +msgid "gdm_auth_user_add: Error forking xauth process." +msgstr "gdm_auth_user_add: Error al hacer un fork del proceso xauth." + +#: daemon/auth.c:143 +#, c-format +msgid "gdm_auth_user_remove: Error starting xauth process: %s" +msgstr "gdm_auth_user_remove: Error al lanzar el proceso xauth: %s" + +#: daemon/auth.c:147 +msgid "gdm_auth_user_remove: Error forking xauth process." +msgstr "gdm_auth_user_remove: Error al hacer un fork del proceso xauth." + +#: daemon/filecheck.c:50 daemon/filecheck.c:83 +#, c-format +msgid "%s: %s is not owned by uid %d. Skipping." +msgstr "%s: %s no tiene como dueño el uid %d. Ignorando." + +#: daemon/filecheck.c:57 +#, c-format +msgid "%s: %s is writable by group/other. Should be 755. Skipping." +msgstr "" +"%s: %s puede ser escrito por el grupo y otros. Debería de tener permisos " +"0755. Ignorando" + +#: daemon/filecheck.c:76 +#, c-format +msgid "%s: %s is not a regular file. Skipping." +msgstr "%s: %s no es un archivo regular. Ignorando" + +#: daemon/filecheck.c:90 +#, fuzzy, c-format +msgid "%s: %s is writable by group. Should be 644. Skipping." +msgstr "" +"%s: %s puede ser escrito por el grupo y otros. Debería de ser 644. " +"Ignorando." + +#: daemon/filecheck.c:97 +#, c-format +msgid "%s: %s is writable by group/other. Should be 644. Skipping." +msgstr "" +"%s: %s puede ser escrito por el grupo y otros. Debería de ser 644. " +"Ignorando." + +#: daemon/filecheck.c:104 +#, c-format +msgid "%s: %s is bigger than sysadmin specified maximum file size. Skipping." +msgstr "" +"%s: %s es mayor que el tamaño máximo de archivos especificado por el " +"administrador. Salteandolo." + +#: daemon/misc.c:121 +#, c-format +msgid "gdm_exec_script: Failed starting: %s" +msgstr "gdm_exec_script: Falló el lanzamiento: %s" + +#: daemon/misc.c:125 +msgid "gdm_exec_script: Can't fork script process!" +msgstr "gdm_exec_script: ¡Imposible de hacer un fork para el proceso script!" + +#: daemon/misc.c:153 +#, c-format +msgid "gdm_exec_command: Failed starting: %s" +msgstr "gdm_exec_command: Falló el lanzamiento: %s" + +#: daemon/misc.c:157 +msgid "gdm_exec_command: Can't fork process!" +msgstr "gdm_exec_command: ¡Imposible de hacer un fork para el proceso!" + +#: daemon/server.c:82 daemon/server.c:213 +#, fuzzy +msgid "gdm_server_start: Error setting up USR1 signal handler" +msgstr "main: Error al configurar el controlador de la señal USR1" + +#: daemon/server.c:99 +#, fuzzy, c-format +msgid "gdm_server_start: Could not open logfile for display %s!" +msgstr "gdm_slave_windows_kill: No pude abrir el display %s" + +#: daemon/server.c:129 +msgid "gdm_server_start: Error setting USR1 to SIG_IGN" +msgstr "" + +#: daemon/server.c:146 +#, fuzzy, c-format +msgid "gdm_server_start: Xserver not found: %s" +msgstr "gdm_local_servers_start: Lanzando %s" + +#: daemon/server.c:152 +#, fuzzy +msgid "gdm_server_start: Can't fork Xserver process!" +msgstr "gdm_exec_script: ¡Imposible de hacer un fork para el proceso script!" + +#: daemon/server.c:178 +#, fuzzy, c-format +msgid "gdm_server_stop: Could not unlink auth file: %s!" +msgstr "gdm_auth_secure_display: No se pudo hacer un unlink del archivo %s: %s" + +#: daemon/server.c:237 +#, fuzzy +msgid "gdm_server_restart: Error setting up ALARM signal handler" +msgstr "main: Error al configurar el controlador de la señal USR1" + +#: daemon/slave.c:112 +msgid "gdm_slave_init: Error setting up TERM/INT signal handler" +msgstr "" +"gdm_slave_init: Error al configurar el controlador de la señal TERM/INIT" + +#: daemon/slave.c:120 +msgid "gdm_slave_init: Error setting up CHLD signal handler" +msgstr "gdm_slave_init: Error al configurar el controlador de la señal CHLD" + +#: daemon/slave.c:171 +msgid "gdm_slave_greeter: Can't init pipe to gdmgreeter" +msgstr "gdm_slave_greeter: Imposible iniciar un tubo hacia gdmgreeter" + +#: daemon/slave.c:196 +#, c-format +msgid "gdm_slave_greeter: Couldn't set groupid to %d" +msgstr "gdm_slave_greeter: No pude configurar el grupo como gid %d" + +#: daemon/slave.c:199 +#, c-format +msgid "gdm_slave_greeter: Couldn't set userid to %d" +msgstr "gdm_slave_greeter: No pude configurar el usuario como uid %d" + +#: daemon/slave.c:209 +#, c-format +msgid "gdm_slave_greeter: Error starting greeter on display %s" +msgstr "gdm_slave_greeter: Error al lanzar la ventana de bienvenida en %s" + +#: daemon/slave.c:212 +msgid "gdm_slave_greeter: Can't fork gdmgreeter process" +msgstr "gdm_slave_greeter: Imposible hacer un fork para el proceso gdmgreeter" + +#: daemon/slave.c:280 +#, c-format +msgid "gdm_slave_session_init: User '%s' not found. Aborting." +msgstr "" +"gdm_slave_session_init: No se encuentró ningún usuario '%s'. Abortando." + +#: daemon/slave.c:299 +msgid "" +"gdm_slave_session_init: Execution of PreSession script returned > 0. " +"Aborting." +msgstr "" +"gdm_slave_session_init: La ejecución del script de Pre-sesión devolvió > 0. " +"Abortando." + +#: daemon/slave.c:304 +msgid "gdm_slave_session_init: Error forking user session" +msgstr "" +"gdm_slave_session_init: Error al hacer un fork para la sesión del usuario" + +#: daemon/slave.c:312 +#, c-format +msgid "gdm_slave_session_init: Could not setgid %d. Aborting." +msgstr "gdm_slave_session_init: No pude hacer un setgid %d. Abortando" + +#: daemon/slave.c:315 +#, c-format +msgid "gdm_slave_session_init: initgroups() failed for %s. Aborting." +msgstr "gdm_slave_session_init: Falló initgroups() para %s. Abortando." + +#: daemon/slave.c:318 +#, c-format +msgid "gdm_slave_session_init: Could not become %s. Aborting." +msgstr "gdm_slave_session_init: No pude cambiarme en %s. Abortando." + +#: daemon/slave.c:373 +#, c-format +msgid "gdm_slave_session_init: Could not start session `%s'" +msgstr "gdm_slave_session_init: No pude lanzar la sesión `%s'" + +#: daemon/slave.c:547 +#, c-format +msgid "gdm_slave_windows_kill_ioerror_handler: Fatal X error - Restarting %s" +msgstr "" +"gdm_slave_windows_kill_ioerror_handler: Error fatal de X - Reiniciando %s" + +#: daemon/slave.c:579 +msgid "gdm_slave_xsync_ping: Error setting up ALARM signal handler" +msgstr "" +"gdm_slave_xsync_ping: Error al configurar el controlador de la señal ALARM" + +#: daemon/verify.c:122 daemon/verify.c:185 gui/gdmgreeter.c:1363 +msgid "Login:" +msgstr "Login:" + +#: daemon/verify.c:128 +msgid "Can't find /etc/pam.d/gdm!" +msgstr "¡No se encuentra ningún /etc/pam.d/gdm!" + +#: daemon/verify.c:132 +#, c-format +msgid "Can't set PAM_TTY=%s" +msgstr "Imposible de definir PAM_TTY=%s" + +#: daemon/verify.c:137 daemon/verify.c:189 +#, c-format +msgid "Couldn't authenticate %s" +msgstr "No pude autentificar a %s" + +#: daemon/verify.c:142 +#, c-format +msgid "Couldn't set acct. mgmt for %s" +msgstr "No pude configurar la gestión de cuentas para %s" + +#: daemon/verify.c:147 +#, c-format +msgid "Couldn't set credentials for %s" +msgstr "No pude configurar las credenciales para %s" + +#: daemon/verify.c:152 +#, c-format +msgid "Couldn't open session for %s" +msgstr "No pude abrir una sesión para %s" + +#: daemon/verify.c:192 +msgid "User unknown" +msgstr "" + +#: daemon/verify.c:208 gui/gdmgreeter.c:1369 +msgid "Password:" +msgstr "Contraseña:" + +#: daemon/verify.c:213 +msgid "Incorrect password" +msgstr "" + +#: daemon/xdmcp.c:172 +#, c-format +msgid "gdm_xdmcp_init: Could not get server hostname: %s!" +msgstr "gdm_xdmcp_init: ¡No pude obtener el nombre del servidor: %s!" + +#: daemon/xdmcp.c:183 +msgid "gdm_xdmcp_init: Could not create socket!" +msgstr "gdm_xdmcp_init: ¡No pude crear el zócalo!" + +#: daemon/xdmcp.c:190 +msgid "gdm_xdmcp_init: Could not bind to XDMCP socket!" +msgstr "gdm_xdmcp_init: ¡No pude conectarme al zócalo XDMCP!" + +#: daemon/xdmcp.c:225 +msgid "gdm_xdmcp_decode: Could not create XDMCP buffer!" +msgstr "gdm_xdmcp_decode: ¡No pude crear un buffer XDMCP!" + +#: daemon/xdmcp.c:230 +msgid "gdm_xdmcp_decode: Could not read XDMCP header!" +msgstr "gdm_xdmcp_decode: ¡No pude leer la cabecera XDMCP!" + +#: daemon/xdmcp.c:235 +msgid "gdm_xdmcp_decode: Incorrect XDMCP version!" +msgstr "gdm_xdmcp_decode: ¡Versión de XDMCP incorrecta!" + +#: daemon/xdmcp.c:271 +#, c-format +msgid "gdm_xdmcp_decode_packet: Unknown opcode from host %s" +msgstr "" + +#: daemon/xdmcp.c:289 +msgid "gdm_xdmcp_query: Could not extract authlist from packet" +msgstr "" + +#: daemon/xdmcp.c:300 +msgid "gdm_xdmcp_query: Error in checksum" +msgstr "" + +#: daemon/xdmcp.c:323 +msgid "GNOME" +msgstr "GNOME" + +#: daemon/xdmcp.c:347 +#, c-format +msgid "Denied XDMCP query from host %s" +msgstr "" + +#: daemon/xdmcp.c:349 +msgid "Display not authorized to connect" +msgstr "Display no autorizado a conectarse" + +#: daemon/xdmcp.c:382 +#, c-format +msgid "gdm_xdmcp_handle_request: Got REQUEST from banned host %s" +msgstr "" + +#: daemon/xdmcp.c:389 +msgid "gdm_xdmcp_handle_request: Could not read Display Number" +msgstr "" + +#: daemon/xdmcp.c:395 +msgid "gdm_xdmcp_handle_request: Could not read Connection Type" +msgstr "" + +#: daemon/xdmcp.c:401 +msgid "gdm_xdmcp_handle_request: Could not read Client Address" +msgstr "" + +#: daemon/xdmcp.c:407 +msgid "gdm_xdmcp_handle_request: Could not read Authentication Names" +msgstr "" + +#: daemon/xdmcp.c:413 +msgid "gdm_xdmcp_handle_request: Could not read Authentication Data" +msgstr "" + +#: daemon/xdmcp.c:419 +msgid "gdm_xdmcp_handle_request: Could not read Authorization List" +msgstr "" + +#: daemon/xdmcp.c:430 +msgid "gdm_xdmcp_handle_request: Could not read Manufacturer ID" +msgstr "" + +#: daemon/xdmcp.c:448 +#, c-format +msgid "gdm_xdmcp_handle_request: Failed checksum from %s" +msgstr "" + +#: daemon/xdmcp.c:566 +#, c-format +msgid "gdm_xdmcp_handle_manage: Got Manage from banned host %s" +msgstr "" + +#: daemon/xdmcp.c:573 +msgid "gdm_xdmcp_handle_manage: Could not read Session ID" +msgstr "" + +#: daemon/xdmcp.c:579 +msgid "gdm_xdmcp_handle_manage: Could not read Display Number" +msgstr "" + +#: daemon/xdmcp.c:588 +msgid "gdm_xdmcp_manage: Could not read Display Class" +msgstr "" + +#: daemon/xdmcp.c:607 +#, c-format +msgid "gdm_xdmcp_handle_manage: Could not open logfile for display %s!" +msgstr "" + +#: daemon/xdmcp.c:679 +#, c-format +msgid "gdm_xdmcp_handle_keepalive: Got KEEPALIVE from banned host %s" +msgstr "" + +#: daemon/xdmcp.c:686 +msgid "gdm_xdmcp_handle_keepalive: Could not read Display Number" +msgstr "" + +#: daemon/xdmcp.c:692 +msgid "gdm_xdmcp_handle_keepalive: Could not read Session ID" +msgstr "" + +#: gui/gdmchooser.c:336 +#, fuzzy, c-format +msgid "gdm_chooser_parse_config: No configuration file: %s. Aborting." +msgstr "" +"gdm_greeter_parse_config: Ningún archivo de configuración: %s. Abortando." + +#: gui/gdmchooser.c:447 +#, fuzzy, c-format +msgid "Can't open default host icon: %s" +msgstr "No pude abrir una sesión para %s" + +#. Buttons +#: gui/gdmchooser.c:512 +msgid "Connect" +msgstr "" + +#: gui/gdmchooser.c:519 +msgid "Rescan" +msgstr "" + +#: gui/gdmchooser.c:525 +msgid "Cancel" +msgstr "" + +#: gui/gdmchooser.c:576 gui/gdmgreeter.c:1672 gui/gdmlogin.c:1102 +msgid "main: Error setting up HUP signal handler" +msgstr "main: Error al configurar el controlador de la señal HUP" + +#: gui/gdmchooser.c:579 gui/gdmgreeter.c:1675 gui/gdmlogin.c:1105 +msgid "main: Error setting up INT signal handler" +msgstr "main: Error al configurar el controlador de la señal INT" + +#: gui/gdmchooser.c:582 gui/gdmgreeter.c:1678 gui/gdmlogin.c:1108 +msgid "main: Error setting up TERM signal handler" +msgstr "main: Error al configurar el controlador de la señal TERM" + +#: gui/gdmgreeter.c:155 +msgid "Gnome Display Manager" +msgstr "Gestor de Display de Gnome" + +#: gui/gdmgreeter.c:157 +msgid "Copyright Martin K. Petersen (C) 1998, 1999" +msgstr "Copyright Martin K. Petersen © 1998, 1999" + +#: gui/gdmgreeter.c:159 gui/gdmlogin.c:328 +msgid "" +"gdm manages local and remote displays and provides the user with a login " +"window." +msgstr "" +"gdm se ocupa de la gestión de pantallas locales y remotas y proporciona al " +"usuario una ventana de login." + +#: gui/gdmgreeter.c:194 gui/gdmlogin.c:271 +msgid "gdm_parse_enriched_string: String too long!" +msgstr "gdm_parse_enriched_string: ¡Cadena demasiado larga!" + +#: gui/gdmgreeter.c:195 gui/gdmlogin.c:272 +msgid "Welcome to " +msgstr "Bientenido a" + +#: gui/gdmgreeter.c:199 gui/gdmlogin.c:276 +msgid "gdm_parse_enriched_string: Could not malloc temporary buffer!" +msgstr "" +"gdm_parse_enriched_string: ¡No pude hacer un malloc para un buffer temporal!" + +#: gui/gdmgreeter.c:273 +msgid "Logo not found. No image will be displayed!" +msgstr "No se encuentra el logotipo. ¡Ninguna imagen sera usada!" + +#: gui/gdmgreeter.c:299 +#, c-format +msgid "gdm_greeter_parse_config: No configuration file: %s. Aborting." +msgstr "" +"gdm_greeter_parse_config: Ningún archivo de configuración: %s. Abortando." + +#: gui/gdmgreeter.c:323 gui/gdmlogin.c:403 +#, c-format +msgid "messages/welcome=Welcome to %h" +msgstr "messages/welcome=Bienvenido a %h" + +#: gui/gdmgreeter.c:424 gui/gdmlogin.c:527 gui/gdmlogin.c:557 +#, c-format +msgid "" +"You have chosen %s for this session, but your default setting is %s.\n" +"Do you wish to make %s the default for future sessions?" +msgstr "" +"Ha escogido %s para esta sesión, pero su sesión por omisión es %s.\n" +"¿Desea hacer de %s su sesión por omisión a partir de ahora?" + +#: gui/gdmgreeter.c:432 +#, c-format +msgid "" +"Your previous session type %s is not installed on this machine.\n" +"Do you wish to make %s the default for future sessions?" +msgstr "" +"Su tipo de sesión anterior %s no está disponible en esta máquina.\n" +"¿Desea hacer de %s su sesión por omisión a partir de ahora?" + +#: gui/gdmgreeter.c:440 +#, c-format +msgid "" +"Your previous session type %s is not installed on this machine.\n" +"You will be logged in using the %s environment." +msgstr "" +"Su tipo de sesión %s no está instalada en esta máquina.\n" +"Será iniciada con el entorno %s." + +#: gui/gdmgreeter.c:453 +#, c-format +msgid "" +"You have chosen the language %s for this session, but your default setting " +"is %s.\n" +"Do you wish to make %s the default language for future sessions?" +msgstr "" +"Escogió el idioma %s para su sesión, pero su valor normal es %s\n" +"¿Desea que %s sea el idioma por omisión para sus sesiones futuras?" + +#: gui/gdmgreeter.c:461 +#, c-format +msgid "" +"Your previous language %s is not installed on this machine.\n" +"Do you wish to make %s the default language for future sessions?" +msgstr "" +"El idioma anterior %s no está instalado en esta máquina.\n" +"¿Desea hacer de %s el idioma por omisión para sus sesiones futuras?" + +#: gui/gdmgreeter.c:469 +#, c-format +msgid "" +"Your previous language %s is not installed on this machine.\n" +"Your environment will be %s." +msgstr "" +"Su idioma anterior %s no está instalado en esta máquina\n" +"Su entorno será %s." + +#: gui/gdmgreeter.c:500 +msgid "Invalid username or password!" +msgstr "¡Nombre de usuario o contraseña inválidos!" + +#: gui/gdmgreeter.c:526 gui/gdmlogin.c:354 +msgid "Are you sure you want to reboot the machine?" +msgstr "¿Está seguro que quiere reiniciar el sistema?" + +#: gui/gdmgreeter.c:555 gui/gdmlogin.c:366 +msgid "Are you sure you want to halt the machine?" +msgstr "¿Está seguro que quiere apagar el sistema?" + +#: gui/gdmgreeter.c:812 +msgid "gdm_greeter_session_init: Session script directory not found!" +msgstr "" +"gdm_greeter_session_init: ¡No se encuentra el directorio de los scripts de " +"sesión!" + +#: gui/gdmgreeter.c:865 gui/gdmlogin.c:694 +msgid "No session scripts found. Aborting!" +msgstr "¡No se encuentran scripts de sesión. Abortando!" + +#: gui/gdmgreeter.c:869 gui/gdmlogin.c:698 +#, c-format +msgid "No default session link found. Using %s.\n" +msgstr "No se encuentra un lazo de sesión por omisión. Usando %s.\n" + +#. Login button +#: gui/gdmgreeter.c:1029 +msgid "Login" +msgstr "Login" + +#. Init sessions menu +#: gui/gdmgreeter.c:1041 +msgid "Sessions" +msgstr "Sesiones" + +#. Language selection support +#: gui/gdmgreeter.c:1048 +msgid "Languages" +msgstr "Idiomas" + +#: gui/gdmgreeter.c:1058 gui/gdmlogin.c:960 +msgid "Reboot..." +msgstr "Reiniciar..." + +#: gui/gdmgreeter.c:1064 gui/gdmlogin.c:966 +msgid "Halt..." +msgstr "Detener..." + +#: gui/gdmgreeter.c:1071 +msgid "Suspend" +msgstr "Suspender" + +#: gui/gdmgreeter.c:1078 gui/gdmlogin.c:972 +msgid "System" +msgstr "Sistema" + +#: gui/gdmgreeter.c:1086 gui/gdmlogin.c:986 +#, c-format +msgid "Can't open icon file: %s. Suspending iconify feature!" +msgstr "" +"¡Imposible de abrir el archivo de ícono: %s. Suspendiendo la posibilidad de " +"iconificar!" + +#: gui/gdmgreeter.c:1090 gui/gdmlogin.c:990 +msgid "Iconify" +msgstr "Iconificar" + +#. Option button +#: gui/gdmgreeter.c:1099 +msgid "Options..." +msgstr "Opciones..." + +#: gui/gdmgreeter.c:1531 +#, c-format +msgid "Can't open NofaceImageFile: %s. Suspending face browser!" +msgstr "" +"¡Imposible de abrir NofaceImageFile: %s. Suspendiendo el visualizador de " +"fotos!" + +#: gui/gdmgreeter.c:1686 +msgid "main: Error setting up USR1 signal handler" +msgstr "main: Error al configurar el controlador de la señal USR1" + +#: gui/gdmgreeter.c:1694 +msgid "main: Error setting up USR2 signal handler" +msgstr "main: Error al configurar el controlador de la señal USR2" + +#: gui/gdmlogin.c:382 +#, fuzzy, c-format +msgid "gdm_login_parse_config: No configuration file: %s. Aborting." +msgstr "" +"gdm_greeter_parse_config: Ningún archivo de configuración: %s. Abortando." + +#: gui/gdmlogin.c:508 +#, fuzzy, c-format +msgid "" +"Your preferred session type %s is not installed on this machine.\n" +"Do you wish to make %s the default for future sessions?" +msgstr "" +"Su tipo de sesión anterior %s no está disponible en esta máquina.\n" +"¿Desea hacer de %s su sesión por omisión a partir de ahora?" + +#: gui/gdmlogin.c:616 +#, c-format +msgid "%s session selected" +msgstr "" + +#: gui/gdmlogin.c:632 gui/gdmlogin.c:723 +msgid "Last" +msgstr "" + +#: gui/gdmlogin.c:647 +#, fuzzy +msgid "gdm_login_session_init: Session script directory not found!" +msgstr "" +"gdm_greeter_session_init: ¡No se encuentra el directorio de los scripts de " +"sesión!" + +#: gui/gdmlogin.c:709 +#, c-format +msgid "%s language selected" +msgstr "" + +#: gui/gdmlogin.c:736 +msgid "A-M" +msgstr "" + +#: gui/gdmlogin.c:742 +msgid "N-Z" +msgstr "" + +#: gui/gdmlogin.c:748 +msgid "Other" +msgstr "" + +#: gui/gdmlogin.c:946 +#, fuzzy +msgid "Session" +msgstr "Sesiones" + +#: gui/gdmlogin.c:953 +#, fuzzy +msgid "Language" +msgstr "Idiomas" + +#: gui/gdmlogin.c:979 +msgid "Host chooser" +msgstr "" + +#, fuzzy +#~ msgid "gdm_server_usr1_handler: Could not open display %s" +#~ msgstr "gdm_slave_windows_kill: No pude abrir el display %s" + +#, fuzzy +#~ msgid "gdm_display_dispose: Closing display %s" +#~ msgstr "gdm_display_dispose: Disponiendo %s" + +#~ msgid "gdm_display_dispose: Disposing %s" +#~ msgstr "gdm_display_dispose: Disponiendo %s" + +#~ msgid "gdm_display_manage: Managing %s" +#~ msgstr "gdm_display_manage: controlando %s" + +#~ msgid "gdm_display_manage: Forked slave: %d...\n" +#~ msgstr "gdm_display_manage: esclavo creado: %d\n" + +#~ msgid "gdm_child_action: %s" +#~ msgstr "gdm_child_action: %s" + +#~ msgid "gdm_child_action: Server process returned unknown status %d" +#~ msgstr "" +#~ "gdm_child_action: El proceso servidor regreso un estado desconocido: %d" + +#, fuzzy +#~ msgid "gdm_child_action: Slave process returned unknown status %d" +#~ msgstr "gdm_child_action: Proceso esclavo regreso un estaod desconocido" + +#~ msgid "gdm_child_handler: child %d returned %d" +#~ msgstr "gdm_child_handler: hijo %d regreso %d" + +#~ msgid "gdm_display_unmanage: Stopping %s" +#~ msgstr "gdm_display_unmanage: Deteniendo %s" + +#~ msgid "gdm_term_handler: Got TERM/INT. Going down!" +#~ msgstr "gdm_term_handler: Recibí un TERM/INT. Deteniendonos!" + +#~ msgid "gdm_main: Here we go..." +#~ msgstr "gdm_main: allá vamos..." + +#~ msgid "gdm_auth_secure_display: Securing %s" +#~ msgstr "gdm_auth_secure_display: Asegurando %s" + +#~ msgid "gdm_auth_user_add: Adding cookie to %s" +#~ msgstr "gdm_auth_user_add: Añadiendo cookie para %s" + +#~ msgid "gdm_auth_user_remove: Removing cookie from %s" +#~ msgstr "gdm_auth_user_remove: Borrando cookia de %s" + +#~ msgid "gdm_slave_start: Starting slave process for %s" +#~ msgstr "gdm_slave_start: Lanzando proceso esclavo para %s" + +#~ msgid "gdm_slave_start: Opening display %s" +#~ msgstr "gdm_slave_start: Abriendo el display %s" + +#~ msgid "gdm_slave_greeter: Running greeter on %s" +#~ msgstr "gdm_slave_greeter: Lanzando la ventana de bienvenida en %s" + +#~ msgid "gdm_slave_greeter: Greeter on pid %d" +#~ msgstr "gdm_slave_greeter: Ventana de bienvenida con pid %d" + +#~ msgid "gdm_slave_greeter: No command followed STX" +#~ msgstr "gdm_slave_greeter: Ningún comando siguió STX" + +#~ msgid "gdm_slave_greeter: Insufficient data from greeter in pipe" +#~ msgstr "" +#~ "gdm_slave_greeter: Datos insuficientes de la ventana de bienvenida en el tubo" + +#~ msgid "gdm_slave_get_opts: Insufficient data from greeter in pipe" +#~ msgstr "" +#~ "gdm_slave_get_opts: Datos insuficientes de la ventana de bienvenida en el " +#~ "tubo" + +#~ msgid "gdm_slave_session_start: %s on %s" +#~ msgstr "gdm_slave_session_start: %s en %s" + +#~ msgid "gdm_slave_session_stop: %s on %s" +#~ msgstr "gdm_slave_session_stop: %s en %s" + +#~ msgid "gdm_slave_session_cleanup: %s on %s" +#~ msgstr "gdm_slave_session_cleanup: %s en %s" + +#~ msgid "gdm_slave_session_cleanup: Running post session script" +#~ msgstr "gdm_slave_session_cleanup: Corriendo script de post-sesión" + +#~ msgid "gdm_slave_session_cleanup: Killing windows" +#~ msgstr "gdm_slave_session_cleanup: Matando las ventanas" + +#~ msgid "gdm_slave_term_handler: %s got TERM signal" +#~ msgstr "gdm_slave_term_handler: %s recibió la señal TERM" + +#~ msgid "gdm_slave_term_handler: Whacking greeter" +#~ msgstr "gdm_slave_term_handler: Despertando la ventana de bienvenida" + +#~ msgid "gdm_slave_term_handler: Whacking client connections" +#~ msgstr "gdm_slave_term_handler: Despertando las conexiones clientes" + +#~ msgid "gdm_slave_child_handler: %d died" +#~ msgstr "gdm_slave_child_handler: murió %d" + +#~ msgid "gdm_slave_child_handler: %d returned %d" +#~ msgstr "gdm_slave_child_handler: %d devolvió %d" + +#~ msgid "gdm_slave_windows_kill: Killing windows on %s" +#~ msgstr "gdm_slave_windows_kill: Matando las ventanas en %s" + +#~ msgid "gdm_slave_windows_kill: Killing child 0x%x" +#~ msgstr "gdm_slave_windows_kill: Matando el hijo 0x%x" + +#~ msgid "gdm_slave_xioerror_handler: I/O error for display %s" +#~ msgstr "gdm_slave_xioerror_handler: Error de E/S en el display %s" + +#~ msgid "gdm_slave_xsync_handler: Xping failed for display %s" +#~ msgstr "gdm_slave_xsync_handler: Falló Xping para el display %s" + +#~ msgid "gdm_slave_xsync_ping: Pinging %s" +#~ msgstr "gdm_slave_xsync_ping: Haciendo un ping a %s" + +#~ msgid "gdm_slave_xsync_ping: Pinging %s returned %d" +#~ msgstr "gdm_slave_xsync_ping: El ping a %s devolvió %d" diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 00000000..79962558 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,1012 @@ +# gdm fr.po +# Copyright (C) 1998 Free Software Foundation, Inc. +# Vincent Renardias <vincent@debian.org>, 1998. +# +msgid "" +msgstr "" +"Project-Id-Version: gdm VERSION\n" +"POT-Creation-Date: 1999-04-08 02:02+0200\n" +"PO-Revision-Date: 1998-09-12 21:08+0200\n" +"Last-Translator: Vincent Renardias <vincent@debian.org>\n" +"Language-Team: Vincent Renardias <vincent@debian.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: daemon/gdm.c:136 +#, c-format +msgid "gdm_config_parse: No configuration file: %s. Aborting." +msgstr "gdm_config_parse: Pas de fichier de configuration: %s. Abandon." + +#: daemon/gdm.c:177 +msgid "gdm_config_parse: No greeter specified and default not found." +msgstr "" + +#: daemon/gdm.c:189 +msgid "gdm_config_parse: No authdir specified and default not found." +msgstr "" + +#: daemon/gdm.c:207 +msgid "" +"gdm_config_parse: No sessions directory specified and default not found." +msgstr "" + +#: daemon/gdm.c:219 +#, fuzzy +msgid "gdm_config_parse: Invalid server line in config file. Ignoring!" +msgstr "gdm_config_parse: Pas de fichier de configuration: %s. Abandon." + +#: daemon/gdm.c:225 +#, fuzzy +msgid "" +"gdm_config_parse: Xdmcp disabled and no local servers defined. Aborting!" +msgstr "gdm_config_parse: Pas de serveurs locaux définis." + +#: daemon/gdm.c:230 +#, c-format +msgid "gdm_config_parse: Can't find the gdm user (%s). Aborting!" +msgstr "" +"gdm_config_parse: Impossible de trouver l'utilisateur gdm (%s). Abandon!" + +#: daemon/gdm.c:235 +#, fuzzy +msgid "gdm_config_parse: The gdm user should not be root. Aborting!" +msgstr "gdm_config_parse: Le répertoire Authdir %s n'existe pas. Abandon." + +#: daemon/gdm.c:240 +#, c-format +msgid "gdm_config_parse: Can't find the gdm group (%s). Aborting!" +msgstr "gdm_config_parse: Impossible de trouver le groupe gdm (%s). Abandon!" + +#: daemon/gdm.c:246 +#, fuzzy +msgid "gdm_config_parse: The gdm group should not be root. Aborting!" +msgstr "gdm_config_parse: Impossible de trouver le groupe gdm (%s). Abandon!" + +#: daemon/gdm.c:253 +#, c-format +msgid "gdm_config_parse: Authdir %s does not exist. Aborting." +msgstr "gdm_config_parse: Le répertoire Authdir %s n'existe pas. Abandon." + +#: daemon/gdm.c:256 +#, c-format +msgid "gdm_config_parse: Authdir %s is not a directory. Aborting." +msgstr "gdm_config_parse: Authdir %s n'est pas un répertoire. Abandon." + +#: daemon/gdm.c:259 +#, fuzzy, c-format +msgid "" +"gdm_config_parse: Authdir %s is not owned by user %s, group %s. Aborting." +msgstr "" +"gdm_config_parse: l'utilisateur gdm ne peux pas accéder au répertoire " +"d'authentification %s. Abandon." + +#: daemon/gdm.c:262 +#, fuzzy, c-format +msgid "" +"gdm_config_parse: Authdir %s has wrong permissions. Should be 750. Aborting." +msgstr "gdm_config_parse: Pas de fichier de configuration: %s. Abandon." + +#: daemon/gdm.c:318 +#, fuzzy, c-format +msgid "gdm_display_manage: Failed forking gdm slave process for %d" +msgstr "gdm_display_run: Echec du lancement d'un processus esclave pour %d" + +#: daemon/gdm.c:397 +#, c-format +msgid "gdm_child_action: Aborting display %s" +msgstr "" + +#: daemon/gdm.c:402 +#, fuzzy +msgid "gdm_child_action: Master rebooting..." +msgstr "gdm_restart_slave: Redémarrage du maitre..." + +#: daemon/gdm.c:408 +#, fuzzy, c-format +msgid "gdm_child_action: Reboot failed: %s" +msgstr "gdm_restart_slave: Echec du redémarrage: %s" + +#: daemon/gdm.c:412 +#, fuzzy +msgid "gdm_child_action: Master halting..." +msgstr "gdm_restart_slave: Arrêt du maitre..." + +#: daemon/gdm.c:418 +#, fuzzy, c-format +msgid "gdm_child_action: Halt failed: %s" +msgstr "gdm_restart_slave: Echec de l'arrêt: %s" + +#: daemon/gdm.c:512 +msgid "gdm_daemonify: fork() failed!" +msgstr "gdm_daemonify: echec de fork()!" + +#: daemon/gdm.c:515 +#, c-format +msgid "gdm_daemonify: setsid() failed: %s!" +msgstr "gdm_daemonify: echec de setid(): %s!" + +#: daemon/gdm.c:540 +msgid "Only root wants to run gdm\n" +msgstr "" + +#: daemon/gdm.c:558 +msgid "" +"gdm already running. Aborting!\n" +"\n" +msgstr "gdm est déjà lancé. Abandon!\n" + +#: daemon/gdm.c:563 +#, fuzzy, c-format +msgid "" +"According to %s, gdm was already running (%d),\n" +"but seems to have been murdered mysteriously.\n" +msgstr "" +"gdm est déjà lancé (%d) mais semble avoir été mystérieusement assassiné.\n" + +#: daemon/gdm.c:584 +msgid "gdm_main: Error setting up TERM signal handler" +msgstr "" +"gdm_main: Erreur lors de la configuration du gestionnaire du signal TERM" + +#: daemon/gdm.c:587 +msgid "gdm_main: Error setting up INT signal handler" +msgstr "" +"gdm_main: Erreur lors de la configuration du gestionnaire du signal INT" + +#: daemon/gdm.c:595 +msgid "gdm_main: Error setting up CHLD signal handler" +msgstr "" +"gdm_main: Erreur lors de la configuration du gestionnaire du signal CHLD" + +#: daemon/auth.c:62 +#, c-format +msgid "gdm_auth_secure_display: Could not unlink %s file: %s" +msgstr "gdm_auth_secure_display: Impossible d'effacer le fichier %s" + +#: daemon/auth.c:73 +#, c-format +msgid "" +"gdm_auth_secure_display: Error starting xauth process: %s. Running insecure!" +msgstr "" + +#: daemon/auth.c:77 +msgid "gdm_auth_secure_display: Error forking xauth process. Running insecure!" +msgstr "" + +#: daemon/auth.c:109 +#, c-format +msgid "gdm_auth_user_add: Error starting xauth process: %s" +msgstr "" + +#: daemon/auth.c:113 +msgid "gdm_auth_user_add: Error forking xauth process." +msgstr "" + +#: daemon/auth.c:143 +#, c-format +msgid "gdm_auth_user_remove: Error starting xauth process: %s" +msgstr "" + +#: daemon/auth.c:147 +msgid "gdm_auth_user_remove: Error forking xauth process." +msgstr "" + +#: daemon/filecheck.c:50 daemon/filecheck.c:83 +#, c-format +msgid "%s: %s is not owned by uid %d. Skipping." +msgstr "" + +#: daemon/filecheck.c:57 +#, c-format +msgid "%s: %s is writable by group/other. Should be 755. Skipping." +msgstr "" + +#: daemon/filecheck.c:76 +#, c-format +msgid "%s: %s is not a regular file. Skipping." +msgstr "" + +#: daemon/filecheck.c:90 +#, c-format +msgid "%s: %s is writable by group. Should be 644. Skipping." +msgstr "" + +#: daemon/filecheck.c:97 +#, c-format +msgid "%s: %s is writable by group/other. Should be 644. Skipping." +msgstr "" + +#: daemon/filecheck.c:104 +#, c-format +msgid "%s: %s is bigger than sysadmin specified maximum file size. Skipping." +msgstr "" + +#: daemon/misc.c:121 +#, c-format +msgid "gdm_exec_script: Failed starting: %s" +msgstr "" + +#: daemon/misc.c:125 +#, fuzzy +msgid "gdm_exec_script: Can't fork script process!" +msgstr "gdm_slave_server_init: Impossible de forker le processus Xserver!" + +#: daemon/misc.c:153 +#, c-format +msgid "gdm_exec_command: Failed starting: %s" +msgstr "" + +#: daemon/misc.c:157 +#, fuzzy +msgid "gdm_exec_command: Can't fork process!" +msgstr "gdm_slave_server_init: Impossible de forker le processus Xserver!" + +#: daemon/server.c:82 daemon/server.c:213 +#, fuzzy +msgid "gdm_server_start: Error setting up USR1 signal handler" +msgstr "" +"gdm_slave_server_start: Erreur lors de la configuration du gestionnaire du " +"signal USR1" + +#: daemon/server.c:99 +#, fuzzy, c-format +msgid "gdm_server_start: Could not open logfile for display %s!" +msgstr "Impossible d'ouvrir le fichier d'historique pour l'affichage %s!" + +#: daemon/server.c:129 +#, fuzzy +msgid "gdm_server_start: Error setting USR1 to SIG_IGN" +msgstr "" +"gdm_slave_server_start: Erreur lors de la configuration du gestionnaire du " +"signal USR1" + +#: daemon/server.c:146 +#, fuzzy, c-format +msgid "gdm_server_start: Xserver not found: %s" +msgstr "gdm_slave_server_init: Serveur X non trouvé: %s" + +#: daemon/server.c:152 +#, fuzzy +msgid "gdm_server_start: Can't fork Xserver process!" +msgstr "gdm_slave_server_init: Impossible de forker le processus Xserver!" + +#: daemon/server.c:178 +#, fuzzy, c-format +msgid "gdm_server_stop: Could not unlink auth file: %s!" +msgstr "gdm_slave_server_init: Serveur X non trouvé: %s" + +#: daemon/server.c:237 +#, fuzzy +msgid "gdm_server_restart: Error setting up ALARM signal handler" +msgstr "" +"gdm_slave_server_start: Erreur lors de la configuration du gestionnaire du " +"signal USR1" + +#: daemon/slave.c:112 +msgid "gdm_slave_init: Error setting up TERM/INT signal handler" +msgstr "" + +#: daemon/slave.c:120 +msgid "gdm_slave_init: Error setting up CHLD signal handler" +msgstr "" + +#: daemon/slave.c:171 +#, fuzzy +msgid "gdm_slave_greeter: Can't init pipe to gdmgreeter" +msgstr "gdm_slave_server_init: Impossible de forker le processus Xserver!" + +#: daemon/slave.c:196 +#, fuzzy, c-format +msgid "gdm_slave_greeter: Couldn't set groupid to %d" +msgstr "gdm_slave_session_init: Impossible de démarrer la session `%s'" + +#: daemon/slave.c:199 +#, fuzzy, c-format +msgid "gdm_slave_greeter: Couldn't set userid to %d" +msgstr "gdm_slave_session_init: Impossible de démarrer la session `%s'" + +#: daemon/slave.c:209 +#, fuzzy, c-format +msgid "gdm_slave_greeter: Error starting greeter on display %s" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/slave.c:212 +#, fuzzy +msgid "gdm_slave_greeter: Can't fork gdmgreeter process" +msgstr "gdm_slave_server_init: Impossible de forker le processus Xserver!" + +#: daemon/slave.c:280 +#, c-format +msgid "gdm_slave_session_init: User '%s' not found. Aborting." +msgstr "" + +#: daemon/slave.c:299 +#, fuzzy +msgid "" +"gdm_slave_session_init: Execution of PreSession script returned > 0. " +"Aborting." +msgstr "gdm_slave_session_init: Fin de la session!" + +#: daemon/slave.c:304 +msgid "gdm_slave_session_init: Error forking user session" +msgstr "" + +#: daemon/slave.c:312 +#, fuzzy, c-format +msgid "gdm_slave_session_init: Could not setgid %d. Aborting." +msgstr "gdm_slave_session_init: Impossible de démarrer la session `%s'" + +#: daemon/slave.c:315 +#, fuzzy, c-format +msgid "gdm_slave_session_init: initgroups() failed for %s. Aborting." +msgstr "gdm_slave_session_init: Fin de la session!" + +#: daemon/slave.c:318 +#, c-format +msgid "gdm_slave_session_init: Could not become %s. Aborting." +msgstr "" + +#: daemon/slave.c:373 +#, c-format +msgid "gdm_slave_session_init: Could not start session `%s'" +msgstr "gdm_slave_session_init: Impossible de démarrer la session `%s'" + +#: daemon/slave.c:547 +#, c-format +msgid "gdm_slave_windows_kill_ioerror_handler: Fatal X error - Restarting %s" +msgstr "" + +#: daemon/slave.c:579 +#, fuzzy +msgid "gdm_slave_xsync_ping: Error setting up ALARM signal handler" +msgstr "" +"gdm_main: Erreur lors de la configuration du gestionnaire du signal TERM" + +#: daemon/verify.c:122 daemon/verify.c:185 gui/gdmgreeter.c:1363 +msgid "Login:" +msgstr "" + +#: daemon/verify.c:128 +msgid "Can't find /etc/pam.d/gdm!" +msgstr "" + +#: daemon/verify.c:132 +#, c-format +msgid "Can't set PAM_TTY=%s" +msgstr "" + +#: daemon/verify.c:137 daemon/verify.c:189 +#, c-format +msgid "Couldn't authenticate %s" +msgstr "" + +#: daemon/verify.c:142 +#, c-format +msgid "Couldn't set acct. mgmt for %s" +msgstr "" + +#: daemon/verify.c:147 +#, c-format +msgid "Couldn't set credentials for %s" +msgstr "" + +#: daemon/verify.c:152 +#, fuzzy, c-format +msgid "Couldn't open session for %s" +msgstr "Impossible d'ouvrir le fichier d'historique pour l'affichage %s!" + +#: daemon/verify.c:192 +msgid "User unknown" +msgstr "" + +#: daemon/verify.c:208 gui/gdmgreeter.c:1369 +msgid "Password:" +msgstr "" + +#: daemon/verify.c:213 +msgid "Incorrect password" +msgstr "" + +#: daemon/xdmcp.c:172 +#, fuzzy, c-format +msgid "gdm_xdmcp_init: Could not get server hostname: %s!" +msgstr "gdm_slave_session_init: Impossible de démarrer la session `%s'" + +#: daemon/xdmcp.c:183 +#, fuzzy +msgid "gdm_xdmcp_init: Could not create socket!" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/xdmcp.c:190 +msgid "gdm_xdmcp_init: Could not bind to XDMCP socket!" +msgstr "" + +#: daemon/xdmcp.c:225 +msgid "gdm_xdmcp_decode: Could not create XDMCP buffer!" +msgstr "" + +#: daemon/xdmcp.c:230 +msgid "gdm_xdmcp_decode: Could not read XDMCP header!" +msgstr "" + +#: daemon/xdmcp.c:235 +msgid "gdm_xdmcp_decode: Incorrect XDMCP version!" +msgstr "" + +#: daemon/xdmcp.c:271 +#, c-format +msgid "gdm_xdmcp_decode_packet: Unknown opcode from host %s" +msgstr "" + +#: daemon/xdmcp.c:289 +#, fuzzy +msgid "gdm_xdmcp_query: Could not extract authlist from packet" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/xdmcp.c:300 +msgid "gdm_xdmcp_query: Error in checksum" +msgstr "" + +#: daemon/xdmcp.c:323 +msgid "GNOME" +msgstr "" + +#: daemon/xdmcp.c:347 +#, c-format +msgid "Denied XDMCP query from host %s" +msgstr "" + +#: daemon/xdmcp.c:349 +msgid "Display not authorized to connect" +msgstr "" + +#: daemon/xdmcp.c:382 +#, c-format +msgid "gdm_xdmcp_handle_request: Got REQUEST from banned host %s" +msgstr "" + +#: daemon/xdmcp.c:389 +#, fuzzy +msgid "gdm_xdmcp_handle_request: Could not read Display Number" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/xdmcp.c:395 +#, fuzzy +msgid "gdm_xdmcp_handle_request: Could not read Connection Type" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/xdmcp.c:401 +#, fuzzy +msgid "gdm_xdmcp_handle_request: Could not read Client Address" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/xdmcp.c:407 +#, fuzzy +msgid "gdm_xdmcp_handle_request: Could not read Authentication Names" +msgstr "gdm_slave_session_init: Impossible de démarrer la session `%s'" + +#: daemon/xdmcp.c:413 +#, fuzzy +msgid "gdm_xdmcp_handle_request: Could not read Authentication Data" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/xdmcp.c:419 +#, fuzzy +msgid "gdm_xdmcp_handle_request: Could not read Authorization List" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/xdmcp.c:430 +#, fuzzy +msgid "gdm_xdmcp_handle_request: Could not read Manufacturer ID" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/xdmcp.c:448 +#, c-format +msgid "gdm_xdmcp_handle_request: Failed checksum from %s" +msgstr "" + +#: daemon/xdmcp.c:566 +#, c-format +msgid "gdm_xdmcp_handle_manage: Got Manage from banned host %s" +msgstr "" + +#: daemon/xdmcp.c:573 +#, fuzzy +msgid "gdm_xdmcp_handle_manage: Could not read Session ID" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/xdmcp.c:579 +#, fuzzy +msgid "gdm_xdmcp_handle_manage: Could not read Display Number" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/xdmcp.c:588 +#, fuzzy +msgid "gdm_xdmcp_manage: Could not read Display Class" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/xdmcp.c:607 +#, fuzzy, c-format +msgid "gdm_xdmcp_handle_manage: Could not open logfile for display %s!" +msgstr "Impossible d'ouvrir le fichier d'historique pour l'affichage %s!" + +#: daemon/xdmcp.c:679 +#, c-format +msgid "gdm_xdmcp_handle_keepalive: Got KEEPALIVE from banned host %s" +msgstr "" + +#: daemon/xdmcp.c:686 +#, fuzzy +msgid "gdm_xdmcp_handle_keepalive: Could not read Display Number" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: daemon/xdmcp.c:692 +#, fuzzy +msgid "gdm_xdmcp_handle_keepalive: Could not read Session ID" +msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#: gui/gdmchooser.c:336 +#, fuzzy, c-format +msgid "gdm_chooser_parse_config: No configuration file: %s. Aborting." +msgstr "gdm_config_parse: Pas de fichier de configuration: %s. Abandon." + +#: gui/gdmchooser.c:447 +#, fuzzy, c-format +msgid "Can't open default host icon: %s" +msgstr "Impossible d'ouvrir le fichier d'historique pour l'affichage %s!" + +#. Buttons +#: gui/gdmchooser.c:512 +msgid "Connect" +msgstr "" + +#: gui/gdmchooser.c:519 +msgid "Rescan" +msgstr "" + +#: gui/gdmchooser.c:525 +msgid "Cancel" +msgstr "" + +#: gui/gdmchooser.c:576 gui/gdmgreeter.c:1672 gui/gdmlogin.c:1102 +msgid "main: Error setting up HUP signal handler" +msgstr "" + +#: gui/gdmchooser.c:579 gui/gdmgreeter.c:1675 gui/gdmlogin.c:1105 +msgid "main: Error setting up INT signal handler" +msgstr "main: Erreur lors de la configuration du gestionnaire du signal INT" + +#: gui/gdmchooser.c:582 gui/gdmgreeter.c:1678 gui/gdmlogin.c:1108 +msgid "main: Error setting up TERM signal handler" +msgstr "main: Erreur lors de la configuration du gestionnaire du signal TERM" + +#: gui/gdmgreeter.c:155 +msgid "Gnome Display Manager" +msgstr "Gestionnaire d'Affichage Gnome" + +#: gui/gdmgreeter.c:157 +#, fuzzy +msgid "Copyright Martin K. Petersen (C) 1998, 1999" +msgstr "Copyright Martin K. Petersen (C) 1998" + +#: gui/gdmgreeter.c:159 gui/gdmlogin.c:328 +msgid "" +"gdm manages local and remote displays and provides the user with a login " +"window." +msgstr "" + +#: gui/gdmgreeter.c:194 gui/gdmlogin.c:271 +msgid "gdm_parse_enriched_string: String too long!" +msgstr "" + +#: gui/gdmgreeter.c:195 gui/gdmlogin.c:272 +msgid "Welcome to " +msgstr "Bienvenue sur " + +#: gui/gdmgreeter.c:199 gui/gdmlogin.c:276 +msgid "gdm_parse_enriched_string: Could not malloc temporary buffer!" +msgstr "" + +#: gui/gdmgreeter.c:273 +msgid "Logo not found. No image will be displayed!" +msgstr "Logo non trouvé. Aucune image ne sera affichée!" + +#: gui/gdmgreeter.c:299 +#, fuzzy, c-format +msgid "gdm_greeter_parse_config: No configuration file: %s. Aborting." +msgstr "gdm_config_parse: Pas de fichier de configuration: %s. Abandon." + +#: gui/gdmgreeter.c:323 gui/gdmlogin.c:403 +#, c-format +msgid "messages/welcome=Welcome to %h" +msgstr "messages/welcome=Bienvenue sur %h" + +#: gui/gdmgreeter.c:424 gui/gdmlogin.c:527 gui/gdmlogin.c:557 +#, c-format +msgid "" +"You have chosen %s for this session, but your default setting is %s.\n" +"Do you wish to make %s the default for future sessions?" +msgstr "" + +#: gui/gdmgreeter.c:432 +#, c-format +msgid "" +"Your previous session type %s is not installed on this machine.\n" +"Do you wish to make %s the default for future sessions?" +msgstr "" + +#: gui/gdmgreeter.c:440 +#, c-format +msgid "" +"Your previous session type %s is not installed on this machine.\n" +"You will be logged in using the %s environment." +msgstr "" + +#: gui/gdmgreeter.c:453 +#, c-format +msgid "" +"You have chosen the language %s for this session, but your default setting " +"is %s.\n" +"Do you wish to make %s the default language for future sessions?" +msgstr "" + +#: gui/gdmgreeter.c:461 +#, c-format +msgid "" +"Your previous language %s is not installed on this machine.\n" +"Do you wish to make %s the default language for future sessions?" +msgstr "" + +#: gui/gdmgreeter.c:469 +#, c-format +msgid "" +"Your previous language %s is not installed on this machine.\n" +"Your environment will be %s." +msgstr "" + +#: gui/gdmgreeter.c:500 +msgid "Invalid username or password!" +msgstr "Mot de passe ou nom d'utilisateur invalide!" + +#: gui/gdmgreeter.c:526 gui/gdmlogin.c:354 +msgid "Are you sure you want to reboot the machine?" +msgstr "Voulez-vous vraiment redémarrer?" + +#: gui/gdmgreeter.c:555 gui/gdmlogin.c:366 +msgid "Are you sure you want to halt the machine?" +msgstr "Voulez-vous vraiment arréter le système?" + +#: gui/gdmgreeter.c:812 +#, fuzzy +msgid "gdm_greeter_session_init: Session script directory not found!" +msgstr "gdm_slave_session_init: Fin de la session!" + +#: gui/gdmgreeter.c:865 gui/gdmlogin.c:694 +msgid "No session scripts found. Aborting!" +msgstr "" + +#: gui/gdmgreeter.c:869 gui/gdmlogin.c:698 +#, c-format +msgid "No default session link found. Using %s.\n" +msgstr "" + +#. Login button +#: gui/gdmgreeter.c:1029 +msgid "Login" +msgstr "Login" + +#. Init sessions menu +#: gui/gdmgreeter.c:1041 +msgid "Sessions" +msgstr "Sessions" + +#. Language selection support +#: gui/gdmgreeter.c:1048 +msgid "Languages" +msgstr "" + +#: gui/gdmgreeter.c:1058 gui/gdmlogin.c:960 +msgid "Reboot..." +msgstr "Redémarrage..." + +#: gui/gdmgreeter.c:1064 gui/gdmlogin.c:966 +msgid "Halt..." +msgstr "Arrêt..." + +#: gui/gdmgreeter.c:1071 +msgid "Suspend" +msgstr "" + +#: gui/gdmgreeter.c:1078 gui/gdmlogin.c:972 +msgid "System" +msgstr "Système" + +#: gui/gdmgreeter.c:1086 gui/gdmlogin.c:986 +#, c-format +msgid "Can't open icon file: %s. Suspending iconify feature!" +msgstr "" + +#: gui/gdmgreeter.c:1090 gui/gdmlogin.c:990 +msgid "Iconify" +msgstr "" + +#. Option button +#: gui/gdmgreeter.c:1099 +msgid "Options..." +msgstr "" + +#: gui/gdmgreeter.c:1531 +#, c-format +msgid "Can't open NofaceImageFile: %s. Suspending face browser!" +msgstr "" + +#: gui/gdmgreeter.c:1686 +msgid "main: Error setting up USR1 signal handler" +msgstr "main: Erreur lors de la configuration du gestionnaire du signal USR1" + +#: gui/gdmgreeter.c:1694 +#, fuzzy +msgid "main: Error setting up USR2 signal handler" +msgstr "main: Erreur lors de la configuration du gestionnaire du signal USR1" + +#: gui/gdmlogin.c:382 +#, fuzzy, c-format +msgid "gdm_login_parse_config: No configuration file: %s. Aborting." +msgstr "gdm_config_parse: Pas de fichier de configuration: %s. Abandon." + +#: gui/gdmlogin.c:508 +#, c-format +msgid "" +"Your preferred session type %s is not installed on this machine.\n" +"Do you wish to make %s the default for future sessions?" +msgstr "" + +#: gui/gdmlogin.c:616 +#, c-format +msgid "%s session selected" +msgstr "" + +#: gui/gdmlogin.c:632 gui/gdmlogin.c:723 +msgid "Last" +msgstr "" + +#: gui/gdmlogin.c:647 +#, fuzzy +msgid "gdm_login_session_init: Session script directory not found!" +msgstr "gdm_slave_session_init: Fin de la session!" + +#: gui/gdmlogin.c:709 +#, c-format +msgid "%s language selected" +msgstr "" + +#: gui/gdmlogin.c:736 +msgid "A-M" +msgstr "" + +#: gui/gdmlogin.c:742 +msgid "N-Z" +msgstr "" + +#: gui/gdmlogin.c:748 +msgid "Other" +msgstr "" + +#: gui/gdmlogin.c:946 +#, fuzzy +msgid "Session" +msgstr "Sessions" + +#: gui/gdmlogin.c:953 +msgid "Language" +msgstr "" + +#: gui/gdmlogin.c:979 +msgid "Host chooser" +msgstr "" + +#, fuzzy +#~ msgid "gdm_server_usr1_handler: Could not open display %s" +#~ msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#, fuzzy +#~ msgid "gdm_display_dispose: Closing display %s" +#~ msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#, fuzzy +#~ msgid "gdm_local_servers_start: Starting %s" +#~ msgstr "gdm_slave_server_init: Serveur X non trouvé: %s" + +#, fuzzy +#~ msgid "gdm_display_manage: Forked slave: %d...\n" +#~ msgstr "gdm_display_run: Echec du lancement d'un processus esclave pour %d" + +#, fuzzy +#~ msgid "gdm_child_action: Server process returned unknown status %d" +#~ msgstr "gdm_restart_slave: Le processus esclave a retourné un état inconnu!" + +#, fuzzy +#~ msgid "gdm_child_action: Slave process returned unknown status %d" +#~ msgstr "gdm_restart_slave: Le processus esclave a retourné un état inconnu!" + +#~ msgid "gdm_term_handler: Got TERM/INT. Going down!" +#~ msgstr "gdm_term_handler: TERM/INT reçu. Arrêt!" + +#, fuzzy +#~ msgid "gdm_auth_secure_display: Securing %s" +#~ msgstr "gdm_auth_secure_display: Impossible d'effacer le fichier %s" + +#, fuzzy +#~ msgid "gdm_slave_start: Starting slave process for %s" +#~ msgstr "gdm_display_run: Echec du lancement d'un processus esclave pour %d" + +#, fuzzy +#~ msgid "gdm_slave_start: Opening display %s" +#~ msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#, fuzzy +#~ msgid "gdm_slave_greeter: Running greeter on %s" +#~ msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#, fuzzy +#~ msgid "gdm_slave_greeter: Greeter on pid %d" +#~ msgstr "gdm_slave_server_init: Xserver au pid %d" + +#, fuzzy +#~ msgid "gdm_slave_greeter: Insufficient data from greeter in pipe" +#~ msgstr "gdm_slave_server_init: Impossible de forker le processus Xserver!" + +#, fuzzy +#~ msgid "gdm_slave_get_opts: Insufficient data from greeter in pipe" +#~ msgstr "gdm_slave_server_init: Impossible de forker le processus Xserver!" + +#, fuzzy +#~ msgid "gdm_slave_session_start: %s on %s" +#~ msgstr "gdm_slave_session_init: Impossible de démarrer la session `%s'" + +#, fuzzy +#~ msgid "gdm_slave_session_stop: %s on %s" +#~ msgstr "gdm_slave_session_init: Attente de %d" + +#, fuzzy +#~ msgid "gdm_slave_session_cleanup: %s on %s" +#~ msgstr "gdm_slave_session_init: Attente de %d" + +#, fuzzy +#~ msgid "gdm_slave_session_cleanup: Running post session script" +#~ msgstr "gdm_slave_session_init: Fin de la session!" + +#, fuzzy +#~ msgid "gdm_slave_session_cleanup: Killing windows" +#~ msgstr "gdm_slave_session_init: Fin de la session!" + +#, fuzzy +#~ msgid "gdm_slave_term_handler: %s got TERM signal" +#~ msgstr "gdm_term_handler: TERM/INT reçu. Arrêt!" + +#, fuzzy +#~ msgid "gdm_slave_child_handler: %d died" +#~ msgstr "gdm_slave_display_init: gdmgreeter a retourné 'User'!" + +#, fuzzy +#~ msgid "gdm_slave_child_handler: %d returned %d" +#~ msgstr "gdm_slave_display_init: gdmgreeter a retourné 'User'!" + +#, fuzzy +#~ msgid "gdm_slave_windows_kill: Could not open display %s" +#~ msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#, fuzzy +#~ msgid "gdm_slave_windows_kill: Killing windows on %s" +#~ msgstr "gdm_slave_server_init: Xserver au pid %d" + +#, fuzzy +#~ msgid "gdm_slave_windows_kill: Killing child 0x%x" +#~ msgstr "gdm_slave_server_init: Xserver au pid %d" + +#, fuzzy +#~ msgid "gdm_slave_xioerror_handler: I/O error for display %s" +#~ msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#, fuzzy +#~ msgid "gdm_slave_xsync_handler: Xping failed for display %s" +#~ msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#, fuzzy +#~ msgid "gdm_slave_xsync_ping: Pinging %s" +#~ msgstr "gdm_slave_session_init: Attente de %d" + +#, fuzzy +#~ msgid "gdm_slave_xsync_ping: Pinging %s returned %d" +#~ msgstr "gdm_slave_server_init: Xserver au pid %d" + +#, fuzzy +#~ msgid "gdm_server_start: %s" +#~ msgstr "gdm_slave_session_init: Impossible de démarrer la session `%s'" + +#, fuzzy +#~ msgid "gdm_server_start: Old server found (%d). Killing." +#~ msgstr "gdm_slave_server_init: Serveur X non trouvé: %s" + +#, fuzzy +#~ msgid "gdm_server_start: '%s'" +#~ msgstr "gdm_slave_session_init: Impossible de démarrer la session `%s'" + +#, fuzzy +#~ msgid "gdm_server_restart: Server for %s restarting!" +#~ msgstr "gdm_slave_server_init: Serveur X non trouvé: %s" + +#, fuzzy +#~ msgid "gdm_server_usr1_handler: Starting display %s!" +#~ msgstr "gdm_slave_server_init: Impossible d'ouvrir le display %s\n" + +#, fuzzy +#~ msgid "gdm_server_usr1_handler: Sleeping %d on a retry" +#~ msgstr "gdm_slave_server_init: Xserver au pid %d" + +#~ msgid "Unknown session '%s' using default!" +#~ msgstr "Session '%s'inconnue; utilisation de la session par défaut!" + +#~ msgid "Not supported yet. Please restart gdm to reread config!" +#~ msgstr "Pas encore supporté. Relancez gdm pour relire la configuration!" + +#~ msgid "gdm_restart_slave: Giving up on display %s" +#~ msgstr "gdm_restart_slave: Abandon sur l'affichage %s" + +#~ msgid "gdm_main: Error setting up HUP signal handler" +#~ msgstr "" +#~ "gdm_main: Erreur lors de la configuration du gestionnaire du signal HUP" + +#~ msgid "No configuration file: %s. Aborting." +#~ msgstr "Pas de fichier de configuration: %s. Abandon." + +#, fuzzy +#~ msgid "gdm_slave_greet_init: Error setting up PIPE signal handler" +#~ msgstr "" +#~ "gdm_main: Erreur lors de la configuration du gestionnaire du signal INT" + +#, fuzzy +#~ msgid "gdm_slave_greet_init: Error: %s" +#~ msgstr "gdm_slave_server_init: Serveur X non trouvé: %s" + +#, fuzzy +#~ msgid "gdm_slave_greet_init: login: %d, passwd: %d\n" +#~ msgstr "gdm_slave_server_init: Serveur X non trouvé: %s" + +#, fuzzy +#~ msgid "gdm_slave_greet_init: login: %s, passwd: %s\n" +#~ msgstr "gdm_slave_server_init: Serveur X non trouvé: %s" + +#~ msgid "messages/session=Sessions" +#~ msgstr "messages/session=Sessions" + +#~ msgid "messages/system=System" +#~ msgstr "messages/system=Système" + +#~ msgid "messages/halt=Halt system..." +#~ msgstr "messages/halt=Arréter le système..." + +#~ msgid "messages/reboot=Reboot system..." +#~ msgstr "messages/reboot=Redémarrer le système..." + +#~ msgid "messages/iconify=Iconify login window" +#~ msgstr "messages/iconify=Iconifier la fenêtre de login" + +#~ msgid "messages/loginbutton=Login" +#~ msgstr "messages/loginbutton=Login" + +#~ msgid "messages/optionbutton=Optiones" +#~ msgstr "messages/optionbutton=Options" + +#~ msgid "messages/loginentry=Login:" +#~ msgstr "messages/loginentry=Utilisateur:" + +#~ msgid "messages/passwordentry=Password:" +#~ msgstr "messages/passwordentry=Mot de passe:" + +#~ msgid "Error: %s" +#~ msgstr "Erreur: %s" + +#~ msgid "User is: %s!" +#~ msgstr "L'utilisateur est: %s!" diff --git a/po/no.po b/po/no.po new file mode 100644 index 00000000..59f9a3e9 --- /dev/null +++ b/po/no.po @@ -0,0 +1,949 @@ +# Norwegian translation of gdm (bokmål dialect). +# Copyright (C) 1998,1999 Free Software Foundation, Inc. +# Kjartan Maraas <kmaraas@fib.hl.no>, 1998,1999. +# +msgid "" +msgstr "" +"Project-Id-Version: gdm 0.5\n" +"POT-Creation-Date: 1999-04-08 02:02+0200\n" +"PO-Revision-Date: 1999-02-16 00:30+0100\n" +"Last-Translator: Kjartan Maraas <kmaraas@fib.hl.no>\n" +"Language-Team: Norwegian <no@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8-bit\n" + +#: daemon/gdm.c:136 +#, c-format +msgid "gdm_config_parse: No configuration file: %s. Aborting." +msgstr "gdm_config_parse: Ingen konfigurasjonsfil: %s. Avbryter." + +#: daemon/gdm.c:177 +msgid "gdm_config_parse: No greeter specified and default not found." +msgstr "gdm_config_parse: Ingen velkomst spesifisert og forvalg ikke funnet." + +#: daemon/gdm.c:189 +msgid "gdm_config_parse: No authdir specified and default not found." +msgstr "" +"gdm_config_parse: Ingen autentiseringskatalog spesifisert og forvalg ikke " +"funnet." + +#: daemon/gdm.c:207 +msgid "" +"gdm_config_parse: No sessions directory specified and default not found." +msgstr "" +"gdm_config_parse: Ingen sesjonskatalog spesifisert og forvalgt ikke funnet." + +#: daemon/gdm.c:219 +msgid "gdm_config_parse: Invalid server line in config file. Ignoring!" +msgstr "gdm_config_parse: Ugyldig tjenerlinje i konfigurasjonsfil. Ignorerer!" + +#: daemon/gdm.c:225 +msgid "" +"gdm_config_parse: Xdmcp disabled and no local servers defined. Aborting!" +msgstr "" +"gdm_config_parse: Xdmcp slått av og ingen lokale tjenere definert. Avbryter!" + +#: daemon/gdm.c:230 +#, c-format +msgid "gdm_config_parse: Can't find the gdm user (%s). Aborting!" +msgstr "gdm_config_parse: Kan ikke finne gdm brukeren (%s). Avbryter!" + +#: daemon/gdm.c:235 +msgid "gdm_config_parse: The gdm user should not be root. Aborting!" +msgstr "gdm_config_parse: Brukeren for gdm bør ikke være root. Avbryter!" + +#: daemon/gdm.c:240 +#, c-format +msgid "gdm_config_parse: Can't find the gdm group (%s). Aborting!" +msgstr "gdm_config_parse: Kan ikke finne gdm gruppen (%s). Avbryter." + +#: daemon/gdm.c:246 +msgid "gdm_config_parse: The gdm group should not be root. Aborting!" +msgstr "gdm_config_parse: Gruppen for gdm bør ikke være root. Avbryter!" + +#: daemon/gdm.c:253 +#, c-format +msgid "gdm_config_parse: Authdir %s does not exist. Aborting." +msgstr "" +"gdm_config_parse: Autentiseringskatalogen %s eksisterer ikke. Avbryter." + +#: daemon/gdm.c:256 +#, c-format +msgid "gdm_config_parse: Authdir %s is not a directory. Aborting." +msgstr "" +"gdm_config_parse: Autentiseringskatalogen %s er ikke en katalog. Avbryter." + +#: daemon/gdm.c:259 +#, c-format +msgid "" +"gdm_config_parse: Authdir %s is not owned by user %s, group %s. Aborting." +msgstr "" +"gdm_config_parse: Autentiseringskatalogen %s er eies ikke av bruker %s, " +"gruppe %s. Avbryter." + +#: daemon/gdm.c:262 +#, c-format +msgid "" +"gdm_config_parse: Authdir %s has wrong permissions. Should be 750. Aborting." +msgstr "" +"gdm_config_parse: Autentiseringskatalogen %s har ikke riktige " +"tilgangsrettigheter. Skal være 750. Avbryter." + +#: daemon/gdm.c:318 +#, c-format +msgid "gdm_display_manage: Failed forking gdm slave process for %d" +msgstr "gdm_display_manage: Feil under starting av gdm slaveprosess for %d" + +#: daemon/gdm.c:397 +#, c-format +msgid "gdm_child_action: Aborting display %s" +msgstr "gdm_child_action: Avbryter skjerm %s" + +#: daemon/gdm.c:402 +msgid "gdm_child_action: Master rebooting..." +msgstr "gdm_child_action: Mester starter på nytt..." + +#: daemon/gdm.c:408 +#, c-format +msgid "gdm_child_action: Reboot failed: %s" +msgstr "gdm_child_action: Omstart feilet: %s" + +#: daemon/gdm.c:412 +msgid "gdm_child_action: Master halting..." +msgstr "gdm_child_action: Mester stopper..." + +#: daemon/gdm.c:418 +#, c-format +msgid "gdm_child_action: Halt failed: %s" +msgstr "gdm_child_action: Stopp feilet: %s" + +#: daemon/gdm.c:512 +msgid "gdm_daemonify: fork() failed!" +msgstr "gdm_daemonify: fork() feilet!" + +#: daemon/gdm.c:515 +#, c-format +msgid "gdm_daemonify: setsid() failed: %s!" +msgstr "gdm_daemonify: setsid() feilet: %s!" + +#: daemon/gdm.c:540 +msgid "Only root wants to run gdm\n" +msgstr "Bare root vil kjøre gdm\n" + +#: daemon/gdm.c:558 +msgid "" +"gdm already running. Aborting!\n" +"\n" +msgstr "" +"gdm kjører allerede. Avbryter!\n" +"\n" + +#: daemon/gdm.c:563 +#, c-format +msgid "" +"According to %s, gdm was already running (%d),\n" +"but seems to have been murdered mysteriously.\n" +msgstr "" +"I følge %s, kjørte gdm allerede (%d), \n" +"men ser ut til å ha blitt myrdet på mysterisk vis.\n" + +#: daemon/gdm.c:584 +msgid "gdm_main: Error setting up TERM signal handler" +msgstr "gdm_main: Feil under oppsett av TERM signalhåndtereren" + +#: daemon/gdm.c:587 +msgid "gdm_main: Error setting up INT signal handler" +msgstr "gdm_main: Feil under oppsett av INT signalhåndtereren" + +#: daemon/gdm.c:595 +msgid "gdm_main: Error setting up CHLD signal handler" +msgstr "gdm_main: Feil under oppsett av CHLD signalhåndtereren" + +#: daemon/auth.c:62 +#, c-format +msgid "gdm_auth_secure_display: Could not unlink %s file: %s" +msgstr "gdm_auth_secure_display: Kunne ikke kjøre unlink på %s fil: %s" + +#: daemon/auth.c:73 +#, c-format +msgid "" +"gdm_auth_secure_display: Error starting xauth process: %s. Running insecure!" +msgstr "" +"gdm_auth_secure_display: Feil under oppstart av xauth prosessen: %s. Kjører " +"usikkert!" + +#: daemon/auth.c:77 +msgid "gdm_auth_secure_display: Error forking xauth process. Running insecure!" +msgstr "" +"gdm_auth_secure_display: Feil under splitting av xauth prosess. Kjører " +"usikkert!" + +#: daemon/auth.c:109 +#, c-format +msgid "gdm_auth_user_add: Error starting xauth process: %s" +msgstr "gdm_auth_user_add: Feil under oppstart av xauth prosess: %s" + +#: daemon/auth.c:113 +msgid "gdm_auth_user_add: Error forking xauth process." +msgstr "gdm_auth_user_add: Feil under splitting av xauth prosess." + +#: daemon/auth.c:143 +#, c-format +msgid "gdm_auth_user_remove: Error starting xauth process: %s" +msgstr "gdm_auth_user_remove: Feil under oppstart av xauth prosess: %s" + +#: daemon/auth.c:147 +msgid "gdm_auth_user_remove: Error forking xauth process." +msgstr "gdm_auth_user_remove: Feil under splitting av xauth prosess." + +#: daemon/filecheck.c:50 daemon/filecheck.c:83 +#, c-format +msgid "%s: %s is not owned by uid %d. Skipping." +msgstr "%s: %s er ikke eiet av uid %d. Hopper over." + +#: daemon/filecheck.c:57 +#, c-format +msgid "%s: %s is writable by group/other. Should be 755. Skipping." +msgstr "%s: %s er skrivbar av gruppe/andre. Skal være 755. Hopper over." + +#: daemon/filecheck.c:76 +#, c-format +msgid "%s: %s is not a regular file. Skipping." +msgstr "%s: %s er ikke en vanlig fil. Hopper over." + +#: daemon/filecheck.c:90 +#, fuzzy, c-format +msgid "%s: %s is writable by group. Should be 644. Skipping." +msgstr "%s: %s er skrivbar av gruppe/andre. Skal være 644. Hopper over." + +#: daemon/filecheck.c:97 +#, c-format +msgid "%s: %s is writable by group/other. Should be 644. Skipping." +msgstr "%s: %s er skrivbar av gruppe/andre. Skal være 644. Hopper over." + +#: daemon/filecheck.c:104 +#, c-format +msgid "%s: %s is bigger than sysadmin specified maximum file size. Skipping." +msgstr "" +"%s: %s er større enn maksimum filstørrelse spesifisert av " +"systemadministrator. Hopper over." + +#: daemon/misc.c:121 +#, c-format +msgid "gdm_exec_script: Failed starting: %s" +msgstr "gdm_exec_script: Feil under oppstart: %s" + +#: daemon/misc.c:125 +msgid "gdm_exec_script: Can't fork script process!" +msgstr "gdm_exec_script: Kan ikke splitte skriptprosess!" + +#: daemon/misc.c:153 +#, c-format +msgid "gdm_exec_command: Failed starting: %s" +msgstr "gdm_exec_command: Feil under oppstart: %s" + +#: daemon/misc.c:157 +msgid "gdm_exec_command: Can't fork process!" +msgstr "gdm_exec_command: Kan ikke splitte prosessen!" + +#: daemon/server.c:82 daemon/server.c:213 +#, fuzzy +msgid "gdm_server_start: Error setting up USR1 signal handler" +msgstr "main: Feil under oppsett av USR1 signalhåndtereren" + +#: daemon/server.c:99 +#, fuzzy, c-format +msgid "gdm_server_start: Could not open logfile for display %s!" +msgstr "gdm_xdmcp_handle_manage: Kunne ikke åpne loggfil for skjerm %s!" + +#: daemon/server.c:129 +msgid "gdm_server_start: Error setting USR1 to SIG_IGN" +msgstr "" + +#: daemon/server.c:146 +#, fuzzy, c-format +msgid "gdm_server_start: Xserver not found: %s" +msgstr "gdm_local_servers_start: Starter %s" + +#: daemon/server.c:152 +#, fuzzy +msgid "gdm_server_start: Can't fork Xserver process!" +msgstr "gdm_exec_script: Kan ikke splitte skriptprosess!" + +#: daemon/server.c:178 +#, fuzzy, c-format +msgid "gdm_server_stop: Could not unlink auth file: %s!" +msgstr "gdm_auth_secure_display: Kunne ikke kjøre unlink på %s fil: %s" + +#: daemon/server.c:237 +#, fuzzy +msgid "gdm_server_restart: Error setting up ALARM signal handler" +msgstr "main: Feil under oppsett av USR1 signalhåndtereren" + +#: daemon/slave.c:112 +msgid "gdm_slave_init: Error setting up TERM/INT signal handler" +msgstr "gdm_slave_init: Feil under oppsett av TERM/INT signalhåndtereren" + +#: daemon/slave.c:120 +msgid "gdm_slave_init: Error setting up CHLD signal handler" +msgstr "gdm_slave_init: Feil under oppsett av CHLD signalhåndtereren" + +#: daemon/slave.c:171 +msgid "gdm_slave_greeter: Can't init pipe to gdmgreeter" +msgstr "gdm_slave_greeter: Kan ikke åpne rør til gdmvelkomst" + +#: daemon/slave.c:196 +#, c-format +msgid "gdm_slave_greeter: Couldn't set groupid to %d" +msgstr "gdm_slave_greeter: Kunne ikke sette gruppe-id til %d" + +#: daemon/slave.c:199 +#, c-format +msgid "gdm_slave_greeter: Couldn't set userid to %d" +msgstr "gdm_slave_greeter: Kunne ikke sette bruker-id til %d" + +#: daemon/slave.c:209 +#, c-format +msgid "gdm_slave_greeter: Error starting greeter on display %s" +msgstr "gdm_slave_greeter: Feil under oppstart av velkomst på skjerm %s" + +#: daemon/slave.c:212 +msgid "gdm_slave_greeter: Can't fork gdmgreeter process" +msgstr "gdm_slave_greeter: Kan ikke splitte gdmvelkomst prosess" + +#: daemon/slave.c:280 +#, c-format +msgid "gdm_slave_session_init: User '%s' not found. Aborting." +msgstr "gdm_slave_session_init: Bruker '%s' ikke funnet. Avbryter." + +#: daemon/slave.c:299 +msgid "" +"gdm_slave_session_init: Execution of PreSession script returned > 0. " +"Aborting." +msgstr "" +"gdm_slave_session_init: Kjøring av PreSession skript returnerte > 0. " +"Avbryter." + +#: daemon/slave.c:304 +msgid "gdm_slave_session_init: Error forking user session" +msgstr "gdm_slave_session_init: Feil under splitting av brukersesjon" + +#: daemon/slave.c:312 +#, c-format +msgid "gdm_slave_session_init: Could not setgid %d. Aborting." +msgstr "gdm_slave_session_init: Kunne ikke kjøre setgid på %d. Avbryter." + +#: daemon/slave.c:315 +#, c-format +msgid "gdm_slave_session_init: initgroups() failed for %s. Aborting." +msgstr "gdm_slave_session_init: initgroups() feilet for %s. Avbryter." + +#: daemon/slave.c:318 +#, c-format +msgid "gdm_slave_session_init: Could not become %s. Aborting." +msgstr "gdm_slave_session_init: Kunne ikke bli %s. Avbryter." + +#: daemon/slave.c:373 +#, c-format +msgid "gdm_slave_session_init: Could not start session `%s'" +msgstr "gdm_slave_session_init: Kunne ikke starte sesjon `%s'" + +#: daemon/slave.c:547 +#, c-format +msgid "gdm_slave_windows_kill_ioerror_handler: Fatal X error - Restarting %s" +msgstr "" +"gdm_slave_windows_kill_ioerror_handler: Fatal X feil - Starter %s på nytt" + +#: daemon/slave.c:579 +msgid "gdm_slave_xsync_ping: Error setting up ALARM signal handler" +msgstr "gdm_slave_xsync_ping: Feil under oppsett av ALARM signalhåndtereren" + +#: daemon/verify.c:122 daemon/verify.c:185 gui/gdmgreeter.c:1363 +msgid "Login:" +msgstr "Innlogging:" + +#: daemon/verify.c:128 +msgid "Can't find /etc/pam.d/gdm!" +msgstr "Kan ikke finne /etc/pam.d/gdm!" + +#: daemon/verify.c:132 +#, c-format +msgid "Can't set PAM_TTY=%s" +msgstr "Kan ikke sette PAM_TTY=%s" + +#: daemon/verify.c:137 daemon/verify.c:189 +#, c-format +msgid "Couldn't authenticate %s" +msgstr "Kunne ikke autentisere %s" + +#: daemon/verify.c:142 +#, c-format +msgid "Couldn't set acct. mgmt for %s" +msgstr "Kunne ikke sette kontohåndtering for %s" + +#: daemon/verify.c:147 +#, c-format +msgid "Couldn't set credentials for %s" +msgstr "Kunne ikke sette credentials for %s" + +#: daemon/verify.c:152 +#, c-format +msgid "Couldn't open session for %s" +msgstr "Kunne ikke åpne sesjon for %s" + +#: daemon/verify.c:192 +msgid "User unknown" +msgstr "" + +#: daemon/verify.c:208 gui/gdmgreeter.c:1369 +msgid "Password:" +msgstr "Passord:" + +#: daemon/verify.c:213 +msgid "Incorrect password" +msgstr "" + +#: daemon/xdmcp.c:172 +#, c-format +msgid "gdm_xdmcp_init: Could not get server hostname: %s!" +msgstr "gdm_xdmcp_init: Fikk ikke tjenerens vertsnavn: %s!" + +#: daemon/xdmcp.c:183 +msgid "gdm_xdmcp_init: Could not create socket!" +msgstr "gdm_xdmcp_init: Kunne ikke opprette socket!" + +#: daemon/xdmcp.c:190 +msgid "gdm_xdmcp_init: Could not bind to XDMCP socket!" +msgstr "gdm_xdmcp_init: Kunne ikke binde til XDMCP socket!" + +#: daemon/xdmcp.c:225 +msgid "gdm_xdmcp_decode: Could not create XDMCP buffer!" +msgstr "gdm_xdmcp_decode: Kunne ikke opprette XDMCP buffer!" + +#: daemon/xdmcp.c:230 +msgid "gdm_xdmcp_decode: Could not read XDMCP header!" +msgstr "gdm_xdmcp_decode: Kunne ikke lese XDMCP header!" + +#: daemon/xdmcp.c:235 +msgid "gdm_xdmcp_decode: Incorrect XDMCP version!" +msgstr "gdm_xdmcp_decode: Feil XDMCP versjon!" + +#: daemon/xdmcp.c:271 +#, c-format +msgid "gdm_xdmcp_decode_packet: Unknown opcode from host %s" +msgstr "gdm_xdmcp_decode_packet: Ukjent opkode fra vert %s" + +#: daemon/xdmcp.c:289 +msgid "gdm_xdmcp_query: Could not extract authlist from packet" +msgstr "gdm_xdmcp_query: Kunne ikke hente ut autentiseringsliste fra pakke" + +#: daemon/xdmcp.c:300 +msgid "gdm_xdmcp_query: Error in checksum" +msgstr "gdm_xdmcp_query: Feil i sjekksum" + +#: daemon/xdmcp.c:323 +msgid "GNOME" +msgstr "GNOME" + +#: daemon/xdmcp.c:347 +#, c-format +msgid "Denied XDMCP query from host %s" +msgstr "" + +#: daemon/xdmcp.c:349 +msgid "Display not authorized to connect" +msgstr "Skjerm ikke autorisert til å koble til" + +#: daemon/xdmcp.c:382 +#, c-format +msgid "gdm_xdmcp_handle_request: Got REQUEST from banned host %s" +msgstr "gdm_xdmcp_handle_request: Mottok REQUEST fra bannlyst vert %s" + +#: daemon/xdmcp.c:389 +msgid "gdm_xdmcp_handle_request: Could not read Display Number" +msgstr "gdm_xdmcp_handle_request: Kunne ikke lese skjermnummer" + +#: daemon/xdmcp.c:395 +msgid "gdm_xdmcp_handle_request: Could not read Connection Type" +msgstr "gdm_xdmcp_handle_request: Kunne ikke lese forbindelsestype" + +#: daemon/xdmcp.c:401 +msgid "gdm_xdmcp_handle_request: Could not read Client Address" +msgstr "gdm_xdmcp_handle_request: Kunne ikke lese klientadresse" + +#: daemon/xdmcp.c:407 +msgid "gdm_xdmcp_handle_request: Could not read Authentication Names" +msgstr "gdm_xdmcp_handle_request: Kunne ikke lese autentiseringsnavn" + +#: daemon/xdmcp.c:413 +msgid "gdm_xdmcp_handle_request: Could not read Authentication Data" +msgstr "gdm_xdmcp_handle_request: Kunne ikke lese autentiseringsdata" + +#: daemon/xdmcp.c:419 +msgid "gdm_xdmcp_handle_request: Could not read Authorization List" +msgstr "gdm_xdmcp_handle_request: Kunne ikke lese autorisasjonslisten" + +#: daemon/xdmcp.c:430 +msgid "gdm_xdmcp_handle_request: Could not read Manufacturer ID" +msgstr "gdm_xdmcp_handle_request: Kunne ikke lese produsent-ID" + +#: daemon/xdmcp.c:448 +#, c-format +msgid "gdm_xdmcp_handle_request: Failed checksum from %s" +msgstr "gdm_xdmcp_handle_request: Feilet sjekksum fra %s" + +#: daemon/xdmcp.c:566 +#, c-format +msgid "gdm_xdmcp_handle_manage: Got Manage from banned host %s" +msgstr "gdm_xdmcp_handle_manage: Mottok Manage fra bannlyst vert %s" + +#: daemon/xdmcp.c:573 +msgid "gdm_xdmcp_handle_manage: Could not read Session ID" +msgstr "gdm_xdmcp_handle_manage: Kunne ikke lese sesjons-ID" + +#: daemon/xdmcp.c:579 +msgid "gdm_xdmcp_handle_manage: Could not read Display Number" +msgstr "gdm_xdmcp_handle_manage: Kunne ikke lese skjermnummer" + +#: daemon/xdmcp.c:588 +msgid "gdm_xdmcp_manage: Could not read Display Class" +msgstr "gdm_xdmcp_manage: Kunne ikke lese skjermklasse" + +#: daemon/xdmcp.c:607 +#, c-format +msgid "gdm_xdmcp_handle_manage: Could not open logfile for display %s!" +msgstr "gdm_xdmcp_handle_manage: Kunne ikke åpne loggfil for skjerm %s!" + +#: daemon/xdmcp.c:679 +#, c-format +msgid "gdm_xdmcp_handle_keepalive: Got KEEPALIVE from banned host %s" +msgstr "gdm_xdmcp_handle_keepalive: Mottok KEEPALIVE fra bannlyst vert %s" + +#: daemon/xdmcp.c:686 +msgid "gdm_xdmcp_handle_keepalive: Could not read Display Number" +msgstr "gdm_xdmcp_handle_keepalive: Kunne ikke lese skjermnummer" + +#: daemon/xdmcp.c:692 +msgid "gdm_xdmcp_handle_keepalive: Could not read Session ID" +msgstr "gdm_xdmcp_handle_keepalive: Kunne ikke lese sesjons-ID" + +#: gui/gdmchooser.c:336 +#, fuzzy, c-format +msgid "gdm_chooser_parse_config: No configuration file: %s. Aborting." +msgstr "gdm_greeter_parse_config: Ingen konfigurasjonsfil: %s. Avbryter." + +#: gui/gdmchooser.c:447 +#, fuzzy, c-format +msgid "Can't open default host icon: %s" +msgstr "Kunne ikke åpne sesjon for %s" + +#. Buttons +#: gui/gdmchooser.c:512 +msgid "Connect" +msgstr "" + +#: gui/gdmchooser.c:519 +msgid "Rescan" +msgstr "" + +#: gui/gdmchooser.c:525 +msgid "Cancel" +msgstr "" + +#: gui/gdmchooser.c:576 gui/gdmgreeter.c:1672 gui/gdmlogin.c:1102 +msgid "main: Error setting up HUP signal handler" +msgstr "main: Feil under oppsett av HUP signalhåndtereren" + +#: gui/gdmchooser.c:579 gui/gdmgreeter.c:1675 gui/gdmlogin.c:1105 +msgid "main: Error setting up INT signal handler" +msgstr "main: Feil under oppsett av INT signalhåndtereren" + +#: gui/gdmchooser.c:582 gui/gdmgreeter.c:1678 gui/gdmlogin.c:1108 +msgid "main: Error setting up TERM signal handler" +msgstr "main: Feil under oppsett av TERM signalhåndtereren" + +#: gui/gdmgreeter.c:155 +msgid "Gnome Display Manager" +msgstr "Gnome skjermhåndtering" + +#: gui/gdmgreeter.c:157 +msgid "Copyright Martin K. Petersen (C) 1998, 1999" +msgstr "Copyright Martin K. Petersen (C) 1998, 1999" + +#: gui/gdmgreeter.c:159 gui/gdmlogin.c:328 +msgid "" +"gdm manages local and remote displays and provides the user with a login " +"window." +msgstr "" +"gdm håndterer lokale og eksterne skjermer og presenterer brukeren for et " +"innloggingsvindu." + +#: gui/gdmgreeter.c:194 gui/gdmlogin.c:271 +msgid "gdm_parse_enriched_string: String too long!" +msgstr "gdm_parse_enriched_string: Strengen er for lang!" + +#: gui/gdmgreeter.c:195 gui/gdmlogin.c:272 +msgid "Welcome to " +msgstr "Velkommen til " + +#: gui/gdmgreeter.c:199 gui/gdmlogin.c:276 +msgid "gdm_parse_enriched_string: Could not malloc temporary buffer!" +msgstr "gdm_parse_enriched_string: Klarte ikke å malloc midlertidig buffer! " + +#: gui/gdmgreeter.c:273 +msgid "Logo not found. No image will be displayed!" +msgstr "Logo ikke funnet. Bilde vil ikke bli vist!" + +#: gui/gdmgreeter.c:299 +#, c-format +msgid "gdm_greeter_parse_config: No configuration file: %s. Aborting." +msgstr "gdm_greeter_parse_config: Ingen konfigurasjonsfil: %s. Avbryter." + +#: gui/gdmgreeter.c:323 gui/gdmlogin.c:403 +#, c-format +msgid "messages/welcome=Welcome to %h" +msgstr "beskjeder/velkomst=Velkommen til %h" + +#: gui/gdmgreeter.c:424 gui/gdmlogin.c:527 gui/gdmlogin.c:557 +#, c-format +msgid "" +"You have chosen %s for this session, but your default setting is %s.\n" +"Do you wish to make %s the default for future sessions?" +msgstr "" +"Du har valgt %s for denne sesjonen, men forvalgt innstilling er %s.\n" +"Ønsker du å gjøre %s til forvalg for fremtidige sesjoner?" + +#: gui/gdmgreeter.c:432 +#, c-format +msgid "" +"Your previous session type %s is not installed on this machine.\n" +"Do you wish to make %s the default for future sessions?" +msgstr "" +"Din forrige sesjonstype %s er ikke installert på denne maskinen.\n" +"Ønsker du å gjøre %s til forvalg for fremtidige sesjoner?" + +#: gui/gdmgreeter.c:440 +#, c-format +msgid "" +"Your previous session type %s is not installed on this machine.\n" +"You will be logged in using the %s environment." +msgstr "" +"Din forrige sesjonstype %s er ikke installert på denne maskinen.\n" +"Du vil bli logget inn til %s miljøet." + +#: gui/gdmgreeter.c:453 +#, c-format +msgid "" +"You have chosen the language %s for this session, but your default setting " +"is %s.\n" +"Do you wish to make %s the default language for future sessions?" +msgstr "" +"Du har valgt språket %s for denne sesjonen, men din forvalgte innstilling er " +"%s.\n" +"Ønsker du å gjøre %s til forvalgt språk for fremtidige sesjoner?" + +#: gui/gdmgreeter.c:461 +#, c-format +msgid "" +"Your previous language %s is not installed on this machine.\n" +"Do you wish to make %s the default language for future sessions?" +msgstr "" +"Ditt forrige språk %s er ikke installert på denne maskinen.\n" +"Ønsker du å gjøre %s til forvalgt språk for fremtidige sesjoner?" + +#: gui/gdmgreeter.c:469 +#, c-format +msgid "" +"Your previous language %s is not installed on this machine.\n" +"Your environment will be %s." +msgstr "" +"Ditt forrige språk %s er ikke installert på denne maskinen.\n" +"Ditt miljø vil være %s." + +#: gui/gdmgreeter.c:500 +msgid "Invalid username or password!" +msgstr "Ugyldig brukernavn eller passord!" + +#: gui/gdmgreeter.c:526 gui/gdmlogin.c:354 +msgid "Are you sure you want to reboot the machine?" +msgstr "Er du sikker på at du vil starte maskinen på nytt?" + +#: gui/gdmgreeter.c:555 gui/gdmlogin.c:366 +msgid "Are you sure you want to halt the machine?" +msgstr "Er du sikker på at du vil stoppe maskinen?" + +#: gui/gdmgreeter.c:812 +msgid "gdm_greeter_session_init: Session script directory not found!" +msgstr "gdm_greeter_session_init: Sesjonens skriptkatalog ikke funnet!" + +#: gui/gdmgreeter.c:865 gui/gdmlogin.c:694 +msgid "No session scripts found. Aborting!" +msgstr "Ingen sesjonsskript funnet. Avbryter!" + +#: gui/gdmgreeter.c:869 gui/gdmlogin.c:698 +#, c-format +msgid "No default session link found. Using %s.\n" +msgstr "Ingen forvalgt sesjonlenke funnet. Bruker %s.\n" + +#. Login button +#: gui/gdmgreeter.c:1029 +msgid "Login" +msgstr "Innlogging" + +#. Init sessions menu +#: gui/gdmgreeter.c:1041 +msgid "Sessions" +msgstr "Sesjoner" + +#. Language selection support +#: gui/gdmgreeter.c:1048 +msgid "Languages" +msgstr "Språk" + +#: gui/gdmgreeter.c:1058 gui/gdmlogin.c:960 +msgid "Reboot..." +msgstr "Omstart..." + +#: gui/gdmgreeter.c:1064 gui/gdmlogin.c:966 +msgid "Halt..." +msgstr "Stopp..." + +#: gui/gdmgreeter.c:1071 +msgid "Suspend" +msgstr "Suspender" + +#: gui/gdmgreeter.c:1078 gui/gdmlogin.c:972 +msgid "System" +msgstr "System" + +#: gui/gdmgreeter.c:1086 gui/gdmlogin.c:986 +#, c-format +msgid "Can't open icon file: %s. Suspending iconify feature!" +msgstr "Kan ikke åpne ikonfilen: %s. Suspenderer ikonofiseringsfunksjonen!" + +#: gui/gdmgreeter.c:1090 gui/gdmlogin.c:990 +msgid "Iconify" +msgstr "Ikonifiser" + +#. Option button +#: gui/gdmgreeter.c:1099 +msgid "Options..." +msgstr "Alternativer..." + +#: gui/gdmgreeter.c:1531 +#, c-format +msgid "Can't open NofaceImageFile: %s. Suspending face browser!" +msgstr "Kan ikke åpne NofaceImageFile: %s. Suspenderer ansiktsvisning!" + +#: gui/gdmgreeter.c:1686 +msgid "main: Error setting up USR1 signal handler" +msgstr "main: Feil under oppsett av USR1 signalhåndtereren" + +#: gui/gdmgreeter.c:1694 +msgid "main: Error setting up USR2 signal handler" +msgstr "main: Feil under oppsett av USR2 signalhåndtereren" + +#: gui/gdmlogin.c:382 +#, fuzzy, c-format +msgid "gdm_login_parse_config: No configuration file: %s. Aborting." +msgstr "gdm_greeter_parse_config: Ingen konfigurasjonsfil: %s. Avbryter." + +#: gui/gdmlogin.c:508 +#, fuzzy, c-format +msgid "" +"Your preferred session type %s is not installed on this machine.\n" +"Do you wish to make %s the default for future sessions?" +msgstr "" +"Din forrige sesjonstype %s er ikke installert på denne maskinen.\n" +"Ønsker du å gjøre %s til forvalg for fremtidige sesjoner?" + +#: gui/gdmlogin.c:616 +#, c-format +msgid "%s session selected" +msgstr "" + +#: gui/gdmlogin.c:632 gui/gdmlogin.c:723 +msgid "Last" +msgstr "" + +#: gui/gdmlogin.c:647 +#, fuzzy +msgid "gdm_login_session_init: Session script directory not found!" +msgstr "gdm_greeter_session_init: Sesjonens skriptkatalog ikke funnet!" + +#: gui/gdmlogin.c:709 +#, c-format +msgid "%s language selected" +msgstr "" + +#: gui/gdmlogin.c:736 +msgid "A-M" +msgstr "" + +#: gui/gdmlogin.c:742 +msgid "N-Z" +msgstr "" + +#: gui/gdmlogin.c:748 +msgid "Other" +msgstr "" + +#: gui/gdmlogin.c:946 +#, fuzzy +msgid "Session" +msgstr "Sesjoner" + +#: gui/gdmlogin.c:953 +#, fuzzy +msgid "Language" +msgstr "Språk" + +#: gui/gdmlogin.c:979 +msgid "Host chooser" +msgstr "" + +#, fuzzy +#~ msgid "gdm_server_usr1_handler: Could not open display %s" +#~ msgstr "gdm_slave_windows_kill: Kunne ikke åpne skjerm %s" + +#~ msgid "gdm_display_dispose: Closing display %s" +#~ msgstr "gdm_display_dispose: Lukke skjerm %s" + +#~ msgid "gdm_display_dispose: Disposing %s" +#~ msgstr "gdm_display_dispose: Fjerner %s" + +#~ msgid "gdm_display_manage: Managing %s" +#~ msgstr "gdm_display_manage: Håndterer %s" + +#~ msgid "gdm_display_manage: Forked slave: %d...\n" +#~ msgstr "gdm_display_manage: Splittet slave: %d...\n" + +#~ msgid "gdm_child_action: %s" +#~ msgstr "gdm_child_action: %s" + +#~ msgid "gdm_child_action: Server process returned unknown status %d" +#~ msgstr "gdm_child_action: Tjenerprosessen returnerte ukjent status %d" + +#~ msgid "gdm_child_action: Slave process returned unknown status %d" +#~ msgstr "gdm_child_action: Slaveprosessen returnerte ukjent status %d" + +#~ msgid "gdm_child_handler: child %d returned %d" +#~ msgstr "gdm_child_handler: barn %d returnerte %d" + +#~ msgid "gdm_display_unmanage: Stopping %s" +#~ msgstr "gdm_display_unmanage: Stopper %s" + +#~ msgid "gdm_term_handler: Got TERM/INT. Going down!" +#~ msgstr "gdm_term_handler: Fikk TERM/INT. Går ned!" + +#~ msgid "gdm_main: Here we go..." +#~ msgstr "gdm_main: Så bærer det avsted..." + +#~ msgid "gdm_auth_secure_display: Securing %s" +#~ msgstr "gdm_auth_secure_display: Sikrer %s" + +#~ msgid "gdm_auth_user_add: Adding cookie to %s" +#~ msgstr "gdm_auth_user_add: Legger til cookie til %s" + +#~ msgid "gdm_auth_user_remove: Removing cookie from %s" +#~ msgstr "gdm_auth_user_remove: Fjerner cookie fra %s" + +#~ msgid "gdm_slave_start: Starting slave process for %s" +#~ msgstr "gdm_slave_start: Starter slaveprosess for %s" + +#~ msgid "gdm_slave_start: Opening display %s" +#~ msgstr "gdm_slave_start: Åpner skjerm %s" + +#~ msgid "gdm_slave_greeter: Running greeter on %s" +#~ msgstr "gdm_slave_greeter: Kjører velkomst på %s" + +#~ msgid "gdm_slave_greeter: Greeter on pid %d" +#~ msgstr "gdm_slave_greeter: Velkomst på pid %d" + +#~ msgid "gdm_slave_greeter: No command followed STX" +#~ msgstr "gdm_slave_greeter: Ingen kommando fulgte STX" + +#~ msgid "gdm_slave_greeter: Insufficient data from greeter in pipe" +#~ msgstr "gdm_slave_greeter: Utilstrekkelig med data fra velkomst i røret" + +#~ msgid "gdm_slave_get_opts: Insufficient data from greeter in pipe" +#~ msgstr "gdm_slave_get_opts: Utilstrekkelig med data fra velkomst i røret" + +#~ msgid "gdm_slave_session_start: %s on %s" +#~ msgstr "gdm_slave_session_start: %s på %s" + +#~ msgid "gdm_slave_session_stop: %s on %s" +#~ msgstr "gdm_slave_session_stop: %s på %s" + +#~ msgid "gdm_slave_session_cleanup: %s on %s" +#~ msgstr "gdm_slave_session_cleanup: %s på %s" + +#~ msgid "gdm_slave_session_cleanup: Running post session script" +#~ msgstr "gdm_slave_session_cleanup: Kjører avsluttende sesjonsskript" + +#~ msgid "gdm_slave_session_cleanup: Killing windows" +#~ msgstr "gdm_slave_session_cleanup: Dreper vinduer" + +#~ msgid "gdm_slave_term_handler: %s got TERM signal" +#~ msgstr "gdm_slave_term_handler: %s fikk TERM signalet" + +#~ msgid "gdm_slave_term_handler: Whacking greeter" +#~ msgstr "gdm_slave_term_handler: Fjerner velkomst" + +#~ msgid "gdm_slave_term_handler: Whacking client connections" +#~ msgstr "gdm_slave_term_handler: Fjerner klientforbindelser" + +#~ msgid "gdm_slave_child_handler: %d died" +#~ msgstr "gdm_slave_child_handler: %d døde" + +#~ msgid "gdm_slave_child_handler: %d returned %d" +#~ msgstr "gdm_slave_child_handler: %d returnerte %d" + +#~ msgid "gdm_slave_windows_kill: Killing windows on %s" +#~ msgstr "gdm_slave_windows_kill: Dreper vinduer på %s" + +#~ msgid "gdm_slave_windows_kill: Killing child 0x%x" +#~ msgstr "gdm_slave_windows_kill: Dreper barn 0x%x" + +#~ msgid "gdm_slave_windows_kill_error_handler: Blam" +#~ msgstr "gdm_slave_windows_kill_error_handler: Pang" + +#~ msgid "gdm_slave_xioerror_handler: I/O error for display %s" +#~ msgstr "gdm_slave_xioerror_handler: I/O feil for skjerm %s" + +#~ msgid "gdm_slave_xsync_handler: Xping failed for display %s" +#~ msgstr "gdm_slave_xsync_handler: Xping feilet for skjerm %s" + +#~ msgid "gdm_slave_xsync_ping: Pinging %s" +#~ msgstr "gdm_slave_xsync_ping: Pinger %s" + +#~ msgid "gdm_slave_xsync_ping: Pinging %s returned %d" +#~ msgstr "gdm_slave_xsync_ping: Pinging av %s returnerte %d" + +#~ msgid "gdm_xdmcp_send_willing: Sending WILLING to %s" +#~ msgstr "gdm_xdmcp_send_willing: Sender WILLING til %s" + +#~ msgid "gdm_xdmcp_send_unwilling: Sending UNWILLING to %s" +#~ msgstr "gdm_xdmcp_send_unwilling: Sender UNWILLING til %s" + +#~ msgid "gdm_xdmcp_handle_request: Got REQUEST from %s" +#~ msgstr "gdm_xdmcp_handle_request: Mottok REQUEST fra %s" + +#~ msgid "gdm_xdmcp_send_accept: Sending ACCEPT to %s with SessionID=%d" +#~ msgstr "gdm_xdmcp_send_accept: Sender ACCEPT til %s med SejonsID=%d" + +#~ msgid "gdm_xdmcp_send_decline: Sending DECLINE to %s" +#~ msgstr "gdm_xdmcp_send_decline: Sender DECLINE til %s" + +#~ msgid "gdm_xdmcp_manage: Got MANAGE from %s" +#~ msgstr "gdm_xdmcp_manage: Mottok MANAGE fra %s" + +#~ msgid "gdm_xdmcp_manage: Got Display=%d, SessionID=%d from %s" +#~ msgstr "gdm_xdmcp_manage: Mottok skjerm=%d, sesjons-ID=%d fra %s" + +#~ msgid "gdm_xdmcp_handle_manage: Sleeping %d on a retry" +#~ msgstr "gdm_xdmcp_handle_manage: Sover %d ved gjentatt forsøk" + +#~ msgid "gdm_xdmcp_handle_keepalive: Got KEEPALIVE from %s" +#~ msgstr "gdm_xdmcp_handle_keepalive: Mottok KEEPALIVE fra %s" |