File: 02_unix98_pty.diff

package info (click to toggle)
ttysnoop 0.12d-6.1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 392 kB
  • sloc: ansic: 5,419; makefile: 165
file content (165 lines) | stat: -rw-r--r-- 4,398 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
Description: Implement support for UNIX98 pty's.
Author: Peter Samuelson <peter@p12n.org>
X-Closes: #87371
X-Original: http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=10;filename=ttysnoop_unix98.diff;att=1;bug=87371
Forwarded: unknown
Last-Update: 2011-11-11

--- ttysnoop-0.12d.debian/ttysnoops.c
+++ ttysnoop-0.12d/ttysnoops.c
@@ -18,6 +18,7 @@
 	v0.12d  8-4-98 Carl Declerck	- updated #includes a bit
 */
 
+#define _XOPEN_SOURCE 600 /* ptsname(), posix_openpt() */
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
@@ -54,6 +55,7 @@ int snoopfd = -1, authfd = -1;
 int pgmpid = -1, authpid = -1, servpid = -1;
 int use_socket = 0, fdmax = 0, proctype = DEAD_PROCESS;
 char snoopdev[32], ptynam[32], childproc[128], sockname[128];
+char *short_ptynam, *shorter_ptynam;
 
 
 /* read a single line from a stream, ignoring all irrelevant stuff */
@@ -148,7 +150,17 @@ int process_snooptab (void)
 }
 
 /* find & open a pty to be used by the pty-master */
+int open_unix98_master (char *ptyname)
+{
+	int fd = posix_openpt(O_RDWR);
+	char *name = "unknown";
 
+	if (fd >= 0)
+		name = ptsname(fd);
+	if (name)
+		strcpy(ptyname, name);
+	return fd;
+}
 int find_ptyxx (char *ptyname)
 {
 	int fd, i, j;
@@ -180,6 +192,25 @@ int find_ptyxx (char *ptyname)
 
 /* find & open a pty (tty) to be used by pty-client */
 
+int open_unix98_slave (int ptyfd)
+{
+	int fd;
+	char *name = ptsname(ptyfd);
+
+	grantpt(ptyfd);
+	unlockpt(ptyfd);
+
+	if ((fd = open(name, O_RDWR)) >= 0)
+	{
+#ifdef TIOCSCTTY /* GNU/kFreeBSD */
+		(void) ioctl(fd, TIOCSCTTY, 0);
+#endif
+		return fd;
+	}
+
+	close(ptyfd);
+	return -1;
+}
 int find_ttyxx (char *ttyname, int ptyfd)
 {
 	struct group *grp;
@@ -200,23 +231,36 @@ int find_ttyxx (char *ttyname, int ptyfd
 	return (-1);
 }
 
+void abbreviate_ptyname (char *name, char **shortname, char **shortername)
+{
+	*shortname = *shortername = name;
+	if (!name)
+		return;
+	if (strncmp(name, "/dev/", 5))
+		return;
+	*shortname = *shortername = name + 5;
+	if (!strncmp(name, "/dev/tty", 8))
+		*shortername = name + 8;
+	else if (!strncmp(name, "/dev/pts/", 9))
+		*shortername = name + 9;
+}
+
 /* fork off the pty-client and redirect its stdin/out/err to the pty */
 
 int fork_pty (int *ptyfd, char *ttynam)
 {
 	struct termios term;
 	struct winsize twin;
-	int ttyfd, pid;
-	char name[32];
+	int ttyfd, pid, is_unix98 = 0;
 	
 	tcgetattr (STDIN_FILENO, &term);
 	ioctl (STDIN_FILENO, TIOCGWINSZ, (char *) &twin);
 
-	if ((*ptyfd = find_ptyxx(name)) < 0)
+	if ((*ptyfd = open_unix98_master(ttynam)) >= 0)
+		is_unix98 = 1;
+	else if ((*ptyfd = find_ptyxx(ttynam)) < 0)
 		errorf ("can't open pty\n");
 	
-	strcpy (ttynam, leafname(name));
-	
 	if ((pid = fork()) < 0)
 		errorf ("can't fork\n");
 	
@@ -224,8 +268,12 @@ int fork_pty (int *ptyfd, char *ttynam)
 	{
 		if (setsid() < 0)
 			errorf ("setsid failed\n");
-		
-		if ((ttyfd = find_ttyxx(name, *ptyfd)) < 0)
+
+		if (is_unix98)
+			ttyfd = open_unix98_slave(*ptyfd);
+		else
+			ttyfd = find_ttyxx(ttynam, *ptyfd);
+		if (ttyfd < 0)
 			errorf ("can't open tty\n");
 			
 		close (*ptyfd);
@@ -384,7 +432,7 @@ void cleanup_utmp (char ptynam[])
 void closedown (void)
 {
 	if (servpid == getpid())	/* only server must clear utmp entry */
-		cleanup_utmp (ptynam);
+		cleanup_utmp (short_ptynam);
 	stty_orig ();
 }
 
@@ -455,14 +503,17 @@ int main (int argc, char *argv[])
 	
 	/* fork off the client and load the new image */
 	
-	if ((pgmpid = fork_pty(&ptyfd, ptynam)) == 0)    /* child */
+	if ((pgmpid = fork_pty(&ptyfd, ptynam)) < 0)
+		errorf ("cannot fork\n");
+	abbreviate_ptyname(ptynam, &short_ptynam, &shorter_ptynam);
+	if (pgmpid == 0)    /* child */
 	{
 		/* should we update utmp to reflect the change to ttypX ? */
 
 		if (proctype == LOGIN_PROCESS)
 		{
-			strncopy (utmp.ut_line, ptynam);
-			strncopy (utmp.ut_id, ptynam + 3);
+			strncopy (utmp.ut_line, short_ptynam);
+			strncopy (utmp.ut_id, shorter_ptynam);
 			*utmp.ut_host = 0;
 			utmp.ut_addr = 0;
 			strncopy (utmp.ut_user, "LOGIN");
@@ -497,7 +548,7 @@ int main (int argc, char *argv[])
 		if ((servfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
 			errorf ("can't create server socket\n");
 		
-		sprintf (sockname, "%s/%s", SPOOLDIR, ptynam);
+		sprintf (sockname, "%s/%s", SPOOLDIR, shorter_ptynam);
 		unlink (sockname);
 		serv_addr.sun_family = AF_UNIX;
 		strncopy (serv_addr.sun_path, sockname);