--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-system-tools-02-forkpty.diff Fri Aug 04 09:34:07 2006 +0000
@@ -0,0 +1,205 @@
+diff -u ./src/common/gst-auth.c-clean ./src/common/gst-auth.c
+--- ./src/common/gst-auth.c-clean Tue May 9 13:09:57 2006
++++ ./src/common/gst-auth.c Thu May 11 16:18:00 2006
+@@ -43,6 +43,13 @@
+ #ifdef __FreeBSD__
+ # include <errno.h>
+ # include <libutil.h>
++#elif defined(__sun)
++#include <fcntl.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include <sys/ioctl.h>
++#include <sys/stream.h>
++#include <sys/stropts.h>
+ #else
+ #include <pty.h>
+ #endif
+@@ -53,6 +60,10 @@
+
+ #define GST_AUTH_RESPONSE_NP 1
+
++#ifdef __sun
++#define EMBEDDED_SU "/usr/lib/embedded_su"
++#endif /* __sun */
++
+ static int root; /* if we are root, no password is
+ required */
+
+@@ -118,6 +129,122 @@
+ return TRUE;
+ }
+
++#ifdef __sun
++/* forkpty() rmplacement for Solaris.
++ * This ignore the last two arguments
++ * for the moment
++ */
++#ifdef NOPTY
++/*
++ * This is implemented using pipes instead of pseudo tty to avoid
++ * bug 4907342.
++ */
++static
++int forkpty (int *amaster, char *name, void *unused1, void *unused2)
++{
++ pid_t pid;
++ int pp[2];
++
++ pipe (pp);
++ pid = fork ();
++ switch (pid)
++ {
++ case -1: /* Error */
++ return -1;
++ case 0: /* Child */
++ if (setsid() < 0)
++ return -1;
++ close (pp[1]);
++ dup2 (pp[0], 0);
++ return 0;
++ default: /* Parent */
++ close (pp[0]);
++ *amaster = pp[1];
++ return pid;
++ }
++
++ return -1;
++}
++#else
++int forkpty (int *amaster, char *name, void *unused1, void *unused2)
++{
++ int master, slave, fd;
++ char *slave_name;
++ pid_t pid;
++ void (*sig_saved)(int);
++
++ master = open("/dev/ptmx", O_RDWR | O_NOCTTY);
++ if (master < 0)
++ return -1;
++
++ sig_saved = signal (SIGCHLD, SIG_DFL);
++ if (grantpt (master) < 0)
++ {
++ signal (SIGCHLD, sig_saved);
++ close (master);
++ return -1;
++ }
++
++ if (unlockpt (master) < 0)
++ {
++ signal (SIGCHLD, sig_saved);
++ close (master);
++ return -1;
++ }
++ signal (SIGCHLD, sig_saved);
++
++ slave_name = ptsname (master);
++ if (slave_name == NULL)
++ {
++ close (master);
++ return -1;
++ }
++
++ slave = open (slave_name, O_RDWR | O_NOCTTY);
++ if (slave < 0)
++ {
++ close (master);
++ return -1;
++ }
++
++ if (ioctl (slave, I_PUSH, "ptem") < 0
++ || ioctl (slave, I_PUSH, "ldterm") < 0
++ || ioctl (slave, I_PUSH, "ttcompat") < 0)
++ {
++ close (slave);
++ close (master);
++ return -1;
++ }
++
++ if (amaster)
++ *amaster = master;
++
++ if (name)
++ strcpy (name, slave_name);
++
++ pid = fork ();
++ switch (pid)
++ {
++ case -1: /* Error */
++ return -1;
++ case 0: /* Child */
++ if (setsid() < 0)
++ return -1;
++ close (master);
++ dup2 (slave, STDIN_FILENO);
++ dup2 (slave, STDOUT_FILENO);
++ dup2 (slave, STDERR_FILENO);
++ return 0;
++ default: /* Parent */
++ close (slave);
++ return pid;
++ }
++
++ return -1;
++}
++#endif
++#endif
++
+ /* runs a term with su in it */
+ static void
+ gst_auth_run_term (GstTool *tool, gchar *args[])
+@@ -177,8 +304,15 @@
+ gchar *s, *str;
+ gint ret;
+
++#if defined(__sun) && defined (EMBEDDED_SU)
++ gst_tool_write_to_backend(tool, (gchar*)".\n"); /* Send empty text block to start conversation */
++#endif
+ while (!cont) {
++#if defined(__sun) && defined (EMBEDDED_SU)
++ s = gst_tool_read_from_backend (tool, "SUCCESS", "\n.\n", NULL); /* Look for end of text block - a period (.) on a line by itself */
++#else
+ s = gst_tool_read_from_backend (tool, "assword:", "/no)?", "\n", NULL);
++#endif /* __sun */
+ str = g_ascii_strup (s, -1);
+
+ /* FIXME: hope that someday we can get rid of this ssh output string parsing */
+@@ -189,6 +323,11 @@
+ /* it's asking for the password */
+ cont = TRUE;
+ ret = GST_AUTH_PASSWORD;
++#if defined(__sun) && defined (EMBEDDED_SU)
++ } else if (g_strrstr (str, "SUCCESS") != NULL) {
++ cont = TRUE;
++ ret = GST_AUTH_PASSWORDLESS;
++#endif /* __sun */
+ } else if (g_strrstr (str, "\n") != NULL) {
+ /* this is the last case to test, it's the CR
+ used to synchronize communication */
+@@ -296,6 +435,12 @@
+
+ if (strlen (password) > 0)
+ memset (password, 0, strlen (password));
++#if defined(__sun) && defined (EMBEDDED_SU) && 0
++ {
++ gchar *s = gst_tool_read_from_backend (tool, "\n.\n", "SUCCESS", "\n", NULL);
++ g_free(s);
++ }
++#endif /* __sun */
+ }
+
+ tool->root_access = ROOT_ACCESS_REAL;
+@@ -378,7 +523,11 @@
+ }
+
+ /* these are the su args */
++#if defined(__sun) && defined (EMBEDDED_SU)
++ su_args[0] = EMBEDDED_SU;
++#else
+ su_args[0] = SU_PATH;
++#endif /* __sun */
+ su_args[1] = "root";
+ su_args[2] = "-c";
+ su_args[3] = command->str;
+