diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | capplets/about-me/Makefile.am | 2 | ||||
-rw-r--r-- | capplets/about-me/gnome-about-me-password.c | 238 | ||||
-rw-r--r-- | capplets/about-me/gnome-about-me.c | 9 | ||||
-rw-r--r-- | configure.in | 46 |
5 files changed, 295 insertions, 8 deletions
@@ -1,3 +1,11 @@ +2005-11-25 Brian Cameron <Brian.Cameron@sun.com> + + * configure.in, capplets/about-me/Makefile.am + capplets/about-me/gnome-about-me.c, + capplets/about-me/gnome-about-me-password.c: + Fix so that gnome-about-me works on non-linux + systems which do not have forkpty(). + 2005-11-14 Rodrigo Moya <rodrigo@novell.com> * configure.in: diff --git a/capplets/about-me/Makefile.am b/capplets/about-me/Makefile.am index c353fac20..d08344468 100644 --- a/capplets/about-me/Makefile.am +++ b/capplets/about-me/Makefile.am @@ -5,7 +5,7 @@ pixmap_DATA = \ gnome-about-me-bulb-on.png \ gnome-about-me-bulb-off.png -gnome_about_me_LDADD = $(GNOMECC_CAPPLETS_LIBS) $(LIBEBOOK_LIBS) -lutil +gnome_about_me_LDADD = $(GNOMECC_CAPPLETS_LIBS) $(LIBEBOOK_LIBS) $(ABOUTME_LIBS) gnome_about_me_LDFLAGS = -export-dynamic gnome_about_me_SOURCES = \ eel-alert-dialog.c \ diff --git a/capplets/about-me/gnome-about-me-password.c b/capplets/about-me/gnome-about-me-password.c index 4ebb2fd79..86d948a1a 100644 --- a/capplets/about-me/gnome-about-me-password.c +++ b/capplets/about-me/gnome-about-me-password.c @@ -25,6 +25,7 @@ # include <config.h> #endif +#include <stropts.h> #include <gnome.h> #include <pwd.h> #include <stdlib.h> @@ -35,11 +36,25 @@ #include <sys/wait.h> #include <sys/poll.h> #include <termios.h> +#if HAVE_PTY_H #include <pty.h> +#endif +#if HAVE_STROPTS_H +#include <stropts.h> +#endif + +#if __sun +#include <sys/types.h> +#include <signal.h> +#endif #include "capplet-util.h" #include "eel-alert-dialog.h" +#ifndef HAVE_FORKPTY +pid_t forkpty(int *, char *, struct termios *, struct winsize *); +#endif + typedef struct { GladeXML *xml; @@ -293,8 +308,9 @@ update_password (PasswordDialog *pdialog, gchar **msg) write_to_backend (pdialog, old_password); /* New password */ - s = read_from_backend (pdialog, "assword: ", "failure", NULL); - if (g_strrstr (s, "failure") != NULL) { + s = read_from_backend (pdialog, "assword: ", "failure", "wrong", NULL); + if (g_strrstr (s, "failure") != NULL || + g_strrstr (s, "wrong") != NULL) { g_free (s); return -1; } @@ -308,7 +324,7 @@ update_password (PasswordDialog *pdialog, gchar **msg) write_to_backend (pdialog, retyped_password); - s = read_from_backend (pdialog, "successfully", "short", "panlindrome", "simple", "similar", "wrapped", "recovered", "unchanged", NULL); + s = read_from_backend (pdialog, "successfully", "short", "panlindrome", "simple", "similar", "wrapped", "recovered", "unchanged", "match", "1 numeric or special", NULL); if (g_strrstr (s, "recovered") != NULL) { retcode = -2; } else if (g_strrstr (s, "short") != NULL) { @@ -323,17 +339,229 @@ update_password (PasswordDialog *pdialog, gchar **msg) } else if ((g_strrstr (s, "similar") != NULL) || (g_strrstr (s, "wrapped") != NULL)) { *msg = g_strdup (_("Old and new passwords are too similar")); retcode = -3; - } else if (g_strrstr (s, "unchanged") != NULL) { + } else if (g_strrstr (s, "1 numeric or special") != NULL) { + *msg = g_strdup (_("Must contain numeric or special character(s)")); + retcode = -3; + } else if ((g_strrstr (s, "unchanged") != NULL) || + (g_strrstr (s, "match") != NULL)) { kill (pdialog->backend_pid, SIGKILL); *msg = g_strdup (_("Old and new password are the same")); retcode = -3; - } + } g_free (s); return retcode; } +#ifndef HAVE_FORKPTY +/* +// Emulation of the BSD function forkpty. +// Copied from rootsh (http://sourceforge.net/projects/rootsh) also +// under GPL license. Slightly modified to not copy terminal modes +// or window size from the parent to the child if NULL is passed in +// for termp or winp. The logic still sets the termp or winp values +// if passed in. When launching from the gnome-panel, there are no +// such values for the parent and attempting to copy them was causing +// a lengthy delay. +*/ +#ifndef MASTERPTYDEV +# error you need to specify a master pty device +#endif +pid_t forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp) { + /* + // amaster A pointer to the master pty's file descriptor which + // will be set here. + // + // name If name is NULL, the name of the slave pty will be + // returned in name. + // + // termp If termp is not NULL, the terminal parameters + // of the slave will be set to the values in termp. + // + // winsize If winp is not NULL, the window size of the slave + // will be set to the values in winp. + // + // pid The process id of the forked child process. + // + // master The file descriptor of the master pty. + // + // slave The file descriptor of the slave pty. + // + // slavename The file name of the slave pty. + // + */ + pid_t pid; + int master, slave; + char *slavename; + + /* + // Get a master pseudo-tty. + */ + if ((master = open (MASTERPTYDEV, O_RDWR)) < 0) { + perror (MASTERPTYDEV); + return (-1); + } + + /* + // Set the permissions on the slave pty. + */ + if (grantpt (master) < 0) { + perror ("grantpt"); + close (master); + return (-1); + } + + /* + // Unlock the slave pty. + */ + if (unlockpt(master) < 0) { + perror ("unlockpt"); + close (master); + return (-1); + } + + /* + // Start a child process. + */ + if ((pid = fork ()) < 0) { + perror ("fork in forkpty"); + close (master); + return (-1); + } + + /* + // The child process will open the slave, which will become + // its controlling terminal. + */ + if (pid == 0) { + /* + // Get rid of our current controlling terminal. + */ + setsid (); + + /* + // Get the name of the slave pseudo tty. + */ + if ((slavename = ptsname (master)) == NULL) { + perror ("ptsname"); + close (master); + return (-1); + } + + /* + // Open the slave pseudo tty. + */ + if ((slave = open(slavename, O_RDWR)) < 0) { + perror (slavename); + close (master); + return (-1); + } + +#ifndef AIX_COMPAT + /* + // Push the pseudo-terminal emulation module. + */ + if (ioctl (slave, I_PUSH, "ptem") < 0) { + perror ("ioctl: ptem"); + close (master); + close (slave); + return (-1); + } + + /* + // Push the terminal line discipline module. + */ + if (ioctl (slave, I_PUSH, "ldterm") < 0) { + perror ("ioctl: ldterm"); + close (master); + close (slave); + return (-1); + } + +#ifdef HAVE_TTCOMPAT + /* + // Push the compatibility for older ioctl calls module (solaris). + */ + if (ioctl (slave, I_PUSH, "ttcompat") < 0) { + perror ("ioctl: ttcompat"); + close (master); + close (slave); + return (-1); + } +#endif +#endif + + /* + // Copy the caller's terminal modes to the slave pty. + */ + if (termp != NULL) { + if (tcsetattr (slave, TCSANOW, termp) < 0) { + perror ("tcsetattr: slave pty"); + close (master); + close (slave); + return (-1); + } + } + + /* + // Set the slave pty window size to the caller's size. + */ + if (winp != NULL) { + if (ioctl (slave, TIOCSWINSZ, winp) < 0) { + perror ("ioctl: slave winsz"); + close (master); + close (slave); + return (-1); + } + } + + /* + // Close the master pty. + // No need for this in the slave process. + */ + close (master); + + /* + // Set the slave to be our standard input, output and error output. + // Then get rid of the original file descriptor. + */ + dup2 (slave, 0); + dup2 (slave, 1); + dup2 (slave, 2); + close (slave); + + /* + // If the caller wants it, give him back the slave pty's name. + */ + if (name != NULL) + strcpy (name, slavename); + + return(0); + + } else { + /* + // Return the slave pty device name if caller wishes so. + */ + if (name != NULL) { + if ((slavename = ptsname (master)) == NULL) { + perror ("ptsname"); + close (master); + return (-1); + } + strcpy (name, slavename); + } + + /* + // Return the file descriptor for communicating with the process + // to the caller. + */ + *amaster = master; + return (pid); + } +} +#endif + static gint spawn_passwd (PasswordDialog *pdialog) { diff --git a/capplets/about-me/gnome-about-me.c b/capplets/about-me/gnome-about-me.c index 55b7edc13..5debb89d1 100644 --- a/capplets/about-me/gnome-about-me.c +++ b/capplets/about-me/gnome-about-me.c @@ -267,8 +267,13 @@ get_user_login (void) struct passwd pwd, *err; int i; - i = getpwuid_r(getuid(), &pwd, buf, sizeof(buf), &err); - return ((i == 0) && (err == &pwd)) ? g_strdup(pwd.pw_name) : NULL; +#if __sun + i = getpwuid_r (getuid (), &pwd, buf, sizeof (buf)); + return (i != 0) ? g_strdup (pwd.pw_name) : NULL; +#else + i = getpwuid_r (getuid (), &pwd, buf, sizeof (buf), &err); + return ((i == 0) && (err == &pwd)) ? g_strdup (pwd.pw_name) : NULL; +#endif } /* diff --git a/configure.in b/configure.in index 61d6751ce..741aa0653 100644 --- a/configure.in +++ b/configure.in @@ -279,6 +279,52 @@ dnl ============================================== dnl About-me dnl ============================================== +AC_CHECK_HEADERS([pty.h stropts.h]) +AC_CHECK_FUNCS(forkpty,, AC_CHECK_LIB(util,forkpty, [AC_DEFINE(HAVE_FORKPTY)] [ABOUTME_LIBS="$ABOUTME_LIBS -lutil"])) +AC_SUBST(ABOUTME_LIBS) + +dnl ----- pseudo terminal handling +dnl ----- os pty master streams modules +dnl ----- aix /dev/ptc - (loads ldterm by default) +dnl ----- hpux /dev/ptmx ldterm ptem +dnl ----- solaris /dev/ptmx ldterm ptem ttcompat + +dnl ----- aix loads module ldterm by default and wants no ptem +dnl ----- ptmx takes precedence +AC_MSG_CHECKING([for master pty]) +if test -r /dev/ptc ; then + if test -r /dev/ptmx ; then + AC_DEFINE_UNQUOTED(MASTERPTYDEV, "/dev/ptmx", [hp and sun style pty master]) + AC_MSG_RESULT(ptmx) + else + AC_DEFINE_UNQUOTED(MASTERPTYDEV, "/dev/ptc", [aix style pty master]) + AC_MSG_RESULT(ptc) + fi +elif test -r /dev/ptmx ; then + AC_DEFINE_UNQUOTED(MASTERPTYDEV, "/dev/ptmx", [hp and sun style pty master]) + AC_MSG_RESULT(ptmx) +else + AC_DEFINE_UNQUOTED(MASTERPTYDEV, "/dev/null", [lets see what happens]) +fi + +dnl ----- this will succeed on solaris and fail on hpux +AC_MSG_CHECKING(if your system supports the ttcompat streams module) +AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <stdio.h> +#include <fcntl.h> +#include <stropts.h> +main() +{ int line; + + if ( (line = open("/dev/ptmx", O_RDWR)) >= 0 && + ioctl(line, I_PUSH, "ttcompat") == 0 ) + exit(0); + exit(1); +} +]])],[AC_DEFINE(HAVE_TTCOMPAT, 1, + "Define if your system supports the ttcompat streams module") + AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)],[AC_MSG_RESULT(assuming no)]) + AC_MSG_CHECKING([whether to enable About Me]) AC_ARG_ENABLE([aboutme], AC_HELP_STRING([--enable-aboutme], |