patches/gnome-system-tools-02-forkpty.diff
changeset 7859 8517272aace0
child 8394 bcd58bae020d
--- /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;
+