1 /* talk.c Copyright Michael Temari 08/01/1996 All Rights Reserved */
12 #include <net/gen/netdb.h>
14 #include <net/gen/socket.h>
15 #include <net/gen/in.h>
16 #include <net/gen/inet.h>
17 #include <net/gen/tcp.h>
18 #include <net/gen/udp.h>
25 _PROTOTYPE(int main
, (int argc
, char *argv
[]));
26 _PROTOTYPE(void DoTalk
, (void));
39 if(argc
< 2 || argc
> 3) {
40 fprintf(stderr
, "Usage: talk user[@host] [tty]\n");
44 /* get local host name */
45 if(gethostname(lhost
, HOST_SIZE
) < 0) {
46 fprintf(stderr
, "talk: Error getting local host name\n");
50 /* get local user name and tty */
51 if((slot
= ttyslot()) < 0) {
52 fprintf(stderr
, "talk: You are not on a terminal\n");
55 if((fp
= fopen(UTMP
, "r")) == (FILE *)NULL
) {
56 fprintf(stderr
, "talk: Could not open %s\n", UTMP
);
59 if(fseek(fp
, (off_t
) sizeof(utmp
) * slot
, SEEK_SET
)) {
60 fprintf(stderr
, "talk: Could not seek %s\n", UTMP
);
64 if(fread((char *)&utmp
, sizeof(utmp
), 1 , fp
) != 1) {
65 fprintf(stderr
, "talk: Could not read %s\n", UTMP
);
70 strncpy(luser
, utmp
.ut_user
, USER_SIZE
< sizeof(utmp
.ut_user
) ?
71 USER_SIZE
: sizeof(utmp
.ut_user
));
72 luser
[USER_SIZE
] = '\0';
75 if((p
= ttyname(0)) == (char *)NULL
) {
76 fprintf(stderr
, "talk: You are not on a terminal\n");
79 strncpy(ltty
, p
+5, TTY_SIZE
);
80 ltty
[TTY_SIZE
] = '\0';
82 /* check if local tty is going to be writable */
83 if(stat(p
, &st
) < 0) {
84 perror("talk: Could not stat local tty");
87 if((st
.st_mode
& S_IWGRP
) == 0) {
88 fprintf(stderr
, "talk: Your terminal is not writable. Use: mesg y\n");
92 /* get remote user and host name */
93 if((p
= strchr(argv
[1], '@')) != (char *)NULL
)
97 strncpy(ruser
, argv
[1], USER_SIZE
);
98 ruser
[USER_SIZE
] = '\0';
99 strncpy(rhost
, p
, HOST_SIZE
);
100 rhost
[HOST_SIZE
] = '\0';
104 strncpy(rtty
, argv
[2], TTY_SIZE
);
107 rtty
[TTY_SIZE
] = '\0';
109 if((hp
= gethostbyname(rhost
)) == (struct hostent
*)NULL
) {
110 fprintf(stderr
, "talk: Could not determine address of %s\n", rhost
);
113 memcpy((char *)&raddr
, (char *)hp
->h_addr
, hp
->h_length
);
116 fprintf(stderr
, "talk: Error in NetInit\n");
145 struct termios termios
;
150 ScreenWho(ruser
, rhost
);
152 /* Get and send edit characters */
153 s
= tcgetattr(0, &termios
);
155 perror("talk: tcgetattr");
158 lcc
[0] = termios
.c_cc
[VERASE
];
159 lcc
[1] = termios
.c_cc
[VKILL
];
160 lcc
[2] = 0x17; /* Control - W */
161 s
= write(tcp_fd
, lcc
, sizeof(lcc
));
162 if(s
!= sizeof(lcc
)) {
163 ScreenMsg("Connection Closing due to error");
166 s
= read(tcp_fd
, rcc
, sizeof(rcc
));
167 if(s
!= sizeof(rcc
)) {
168 ScreenMsg("Connection Closing due to error");
171 ScreenEdit(lcc
, rcc
);
175 ScreenMsg("Could not create pipes");
179 if((kid
= fork()) < 0) {
180 ScreenMsg("Could not fork");
190 s
= read(pfd
[0], &pdata
, sizeof(pdata
));
191 if(s
!= sizeof(pdata
)) {
195 ScreenPut(pdata
.buffer
, pdata
.len
, pdata
.win
);
201 if((kid
= fork()) < 0) {
202 ScreenMsg("Could not fork");
208 pdata
.win
= REMOTEWIN
;
210 s
= read(tcp_fd
, pdata
.buffer
, sizeof(pdata
.buffer
));
214 write(pfd
[1], &pdata
, sizeof(pdata
));
218 kill(getppid(), SIGINT
);
222 pdata
.win
= LOCALWIN
;
224 s
= read(0, pdata
.buffer
, sizeof(pdata
.buffer
));
228 write(pfd
[1], &pdata
, sizeof(pdata
));
229 s2
= write(tcp_fd
, pdata
.buffer
, s
);