minix/commands/talk/talk.c
Gianluca Guida cc17b27a2b Build NetBSD libc library in world in ELF mode.
3 sets of libraries are built now:
  . ack: all libraries that ack can compile (/usr/lib/i386/)
  . clang+elf: all libraries with minix headers (/usr/lib/)
  . clang+elf: all libraries with netbsd headers (/usr/netbsd/)

Once everything can be compiled with netbsd libraries and headers, the
/usr/netbsd hierarchy will be obsolete and its libraries compiled with
netbsd headers will be installed in /usr/lib, and its headers
in /usr/include. (i.e. minix libc and current minix headers set
will be gone.)

To use the NetBSD libc system (libraries + headers) before
it is the default libc, see:
   http://wiki.minix3.org/en/DevelopersGuide/UsingNetBSDCode
This wiki page also documents the maintenance of the patch
files of minix-specific changes to imported NetBSD code.

Changes in this commit:
  . libsys: Add NBSD compilation and create a safe NBSD-based libc.
  . Port rest of libraries (except libddekit) to new header system.
  . Enable compilation of libddekit with new headers.
  . Enable kernel compilation with new headers.
  . Enable drivers compilation with new headers.
  . Port legacy commands to new headers and libc.
  . Port servers to new headers.
  . Add <sys/sigcontext.h> in compat library.
  . Remove dependency file in tree.
  . Enable compilation of common/lib/libc/atomic in libsys
  . Do not generate RCSID strings in libc.
  . Temporarily disable zoneinfo as they are incompatible with NetBSD format
  . obj-nbsd for .gitignore
  . Procfs: use only integer arithmetic. (Antoine Leca)
  . Increase ramdisk size to create NBSD-based images.
  . Remove INCSYMLINKS handling hack.
  . Add nbsd_include/sys/exec_elf.h
  . Enable ELF compilation with NBSD libc.
  . Add 'make nbsdsrc' in tools to download reference NetBSD sources.
  . Automate minix-port.patch creation.
  . Avoid using fstavfs() as it is *extremely* slow and unneeded.
  . Set err() as PRIVATE to avoid name clash with libc.
  . [NBSD] servers/vm: remove compilation warnings.
  . u32 is not a long in NBSD headers.
  . UPDATING info on netbsd hierarchy
  . commands fixes for netbsd libc
2011-06-24 11:46:30 +02:00

242 lines
5 KiB
C

/* talk.c Copyright Michael Temari 08/01/1996 All Rights Reserved */
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <utmp.h>
#include <termios.h>
#include <net/gen/netdb.h>
#include <net/hton.h>
#include <net/gen/socket.h>
#include <net/gen/in.h>
#include <net/gen/inet.h>
#include <net/gen/tcp.h>
#include <net/gen/udp.h>
#include "talk.h"
#include "proto.h"
#include "net.h"
#include "screen.h"
_PROTOTYPE(int main, (int argc, char *argv[]));
_PROTOTYPE(void DoTalk, (void));
int main(argc, argv)
int argc;
char *argv[];
{
char *p;
struct hostent *hp;
struct stat st;
struct utmp utmp;
int slot;
FILE *fp;
if(argc < 2 || argc > 3) {
fprintf(stderr, "Usage: talk user[@host] [tty]\n");
return(-1);
}
/* get local host name */
if(gethostname(lhost, HOST_SIZE) < 0) {
fprintf(stderr, "talk: Error getting local host name\n");
return(-1);
}
/* get local user name and tty */
if((slot = ttyslot()) < 0) {
fprintf(stderr, "talk: You are not on a terminal\n");
return(-1);
}
if((fp = fopen(UTMP, "r")) == (FILE *)NULL) {
fprintf(stderr, "talk: Could not open %s\n", UTMP);
return(-1);
}
if(fseek(fp, (off_t) sizeof(utmp) * slot, SEEK_SET)) {
fprintf(stderr, "talk: Could not seek %s\n", UTMP);
fclose(fp);
return(-1);
}
if(fread((char *)&utmp, sizeof(utmp), 1 , fp) != 1) {
fprintf(stderr, "talk: Could not read %s\n", UTMP);
fclose(fp);
return(-1);
}
fclose(fp);
#ifdef __NBSD_LIBC
strncpy(luser, utmp.ut_name, USER_SIZE < sizeof(utmp.ut_name) ?
USER_SIZE : sizeof(utmp.ut_name));
#else
strncpy(luser, utmp.ut_user, USER_SIZE < sizeof(utmp.ut_user) ?
USER_SIZE : sizeof(utmp.ut_user));
#endif
luser[USER_SIZE] = '\0';
/* get local tty */
if((p = ttyname(0)) == (char *)NULL) {
fprintf(stderr, "talk: You are not on a terminal\n");
return(-1);
}
strncpy(ltty, p+5, TTY_SIZE);
ltty[TTY_SIZE] = '\0';
/* check if local tty is going to be writable */
if(stat(p, &st) < 0) {
perror("talk: Could not stat local tty");
return(-1);
}
if((st.st_mode & S_IWGRP) == 0) {
fprintf(stderr, "talk: Your terminal is not writable. Use: mesg y\n");
return(-1);
}
/* get remote user and host name */
if((p = strchr(argv[1], '@')) != (char *)NULL)
*p++ = '\0';
else
p = lhost;
strncpy(ruser, argv[1], USER_SIZE);
ruser[USER_SIZE] = '\0';
strncpy(rhost, p, HOST_SIZE);
rhost[HOST_SIZE] = '\0';
/* get remote tty */
if(argc > 2)
strncpy(rtty, argv[2], TTY_SIZE);
else
rtty[0] = '\0';
rtty[TTY_SIZE] = '\0';
if((hp = gethostbyname(rhost)) == (struct hostent *)NULL) {
fprintf(stderr, "talk: Could not determine address of %s\n", rhost);
return(-1);
}
memcpy((char *)&raddr, (char *)hp->h_addr, hp->h_length);
if(NetInit()) {
fprintf(stderr, "talk: Error in NetInit\n");
return(-1);
}
if(ScreenInit())
return(-1);
if(!TalkInit())
DoTalk();
ScreenEnd();
return(0);
}
struct pdata {
int win;
int len;
char buffer[64];
} pdata;
void DoTalk()
{
int s;
int s2;
int kid;
int pfd[2];
int win;
int len;
struct termios termios;
char lcc[3];
char rcc[3];
ScreenMsg("");
ScreenWho(ruser, rhost);
/* Get and send edit characters */
s = tcgetattr(0, &termios);
if(s < 0) {
perror("talk: tcgetattr");
return;
}
lcc[0] = termios.c_cc[VERASE];
lcc[1] = termios.c_cc[VKILL];
lcc[2] = 0x17; /* Control - W */
s = write(tcp_fd, lcc, sizeof(lcc));
if(s != sizeof(lcc)) {
ScreenMsg("Connection Closing due to error");
return;
}
s = read(tcp_fd, rcc, sizeof(rcc));
if(s != sizeof(rcc)) {
ScreenMsg("Connection Closing due to error");
return;
}
ScreenEdit(lcc, rcc);
s = pipe(pfd);
if(s < 0) {
ScreenMsg("Could not create pipes");
return;
}
if((kid = fork()) < 0) {
ScreenMsg("Could not fork");
close(pfd[0]);
close(pfd[1]);
return;
}
if(kid == 0) {
close(tcp_fd);
close(pfd[1]);
while(1) {
s = read(pfd[0], &pdata, sizeof(pdata));
if(s != sizeof(pdata)) {
close(pfd[0]);
exit(-1);
}
ScreenPut(pdata.buffer, pdata.len, pdata.win);
}
}
close(pfd[0]);
if((kid = fork()) < 0) {
ScreenMsg("Could not fork");
close(pfd[1]);
return;
}
if(kid == 0) {
pdata.win = REMOTEWIN;
while(!ScreenDone) {
s = read(tcp_fd, pdata.buffer, sizeof(pdata.buffer));
if(s <= 0)
break;
pdata.len = s;
write(pfd[1], &pdata, sizeof(pdata));
}
close(pfd[1]);
close(tcp_fd);
kill(getppid(), SIGINT);
exit(-1);
}
pdata.win = LOCALWIN;
while(!ScreenDone) {
s = read(0, pdata.buffer, sizeof(pdata.buffer));
if(s <= 0)
break;
pdata.len = s;
write(pfd[1], &pdata, sizeof(pdata));
s2 = write(tcp_fd, pdata.buffer, s);
if(s2 != s)
break;
}
kill(kid, SIGINT);
close(pfd[1]);
close(tcp_fd);
return;
}