Initial revision
This commit is contained in:
Executable
+30
@@ -0,0 +1,30 @@
|
||||
# Makefile for talkd
|
||||
#
|
||||
# 07/22/96 Michael Temari, <temari@ix.netcom.com>
|
||||
#
|
||||
|
||||
CFLAGS= -O -D_MINIX -D_POSIX_SOURCE
|
||||
LDFLAGS=-i
|
||||
BINDIR= /usr/bin
|
||||
PROG= talkd
|
||||
|
||||
OBJS= talkd.o net.o process.o finduser.o
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
$(PROG): $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS)
|
||||
install -S 8kw $@
|
||||
|
||||
clean:
|
||||
rm -f $(PROG) $(OBJS)
|
||||
|
||||
install: $(BINDIR)/$(PROG)
|
||||
|
||||
$(BINDIR)/$(PROG): $(PROG)
|
||||
install -cs -o bin $? $@
|
||||
|
||||
talkd.o: talkd.c talk.h talkd.h process.h net.h
|
||||
net.o: net.c talk.h talkd.h net.h
|
||||
process.o: process.c talk.h talkd.h finduser.h process.h
|
||||
finduser.o: finduser.c talk.h finduser.h
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
/* finduser.c Copyright Michael Temari 07/22/1996 All Rights Reserved */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <utmp.h>
|
||||
#include <net/gen/in.h>
|
||||
|
||||
#include "talk.h"
|
||||
#include "finduser.h"
|
||||
|
||||
int find_user(name, tty)
|
||||
char *name;
|
||||
char *tty;
|
||||
{
|
||||
int fd;
|
||||
int ret;
|
||||
struct utmp utmp;
|
||||
|
||||
/* Now find out if the requested user is logged in. */
|
||||
if((fd = open(UTMP, O_RDONLY)) < 0) {
|
||||
perror("talkd: opening UTMP file");
|
||||
return(FAILED);
|
||||
}
|
||||
|
||||
ret = NOT_HERE;
|
||||
|
||||
while(read(fd, &utmp, sizeof(struct utmp)) == sizeof(struct utmp)) {
|
||||
if(utmp.ut_type != USER_PROCESS) continue;
|
||||
if(strncmp(utmp.ut_user, name, sizeof(utmp.ut_user))) continue;
|
||||
if(*tty && strncmp(utmp.ut_line, tty, sizeof(utmp.ut_line))) continue;
|
||||
strcpy(tty, utmp.ut_line);
|
||||
ret = SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
/* finduser.h Copyright Michael Temari 07/22/1996 All Rights Reserved */
|
||||
|
||||
_PROTOTYPE(int find_user, (char *name, char *tty));
|
||||
Executable
+188
@@ -0,0 +1,188 @@
|
||||
/* net.c Copyright Michael Temari 07/22/1996 All Rights Reserved */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <net/netlib.h>
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/netdb.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/udp.h>
|
||||
#include <net/gen/udp_io.h>
|
||||
#include <net/gen/udp_hdr.h>
|
||||
|
||||
#include "talk.h"
|
||||
#include "talkd.h"
|
||||
#include "net.h"
|
||||
|
||||
static unsigned char buffer[8192];
|
||||
|
||||
static int udp_in;
|
||||
static int udp_out;
|
||||
|
||||
static udpport_t ntalk_port;
|
||||
|
||||
int NetInit()
|
||||
{
|
||||
int s;
|
||||
struct servent *servent;
|
||||
char *udp_device;
|
||||
nwio_udpopt_t udpopt;
|
||||
|
||||
if((udp_device = getenv("UDP_DEVICE")) == (char *)NULL)
|
||||
udp_device = UDP_DEVICE;
|
||||
|
||||
if((udp_in = open(udp_device, O_RDWR)) < 0) {
|
||||
fprintf(stderr, "talkd: Could not open %s: %s\n",
|
||||
udp_device, strerror(errno));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if((udp_out = open(udp_device, O_RDWR)) < 0) {
|
||||
fprintf(stderr, "talkd: Could not open %s: %s\n",
|
||||
udp_device, strerror(errno));
|
||||
close(udp_in);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if((servent = getservbyname("ntalk", "udp")) == (struct servent *)NULL) {
|
||||
fprintf(stderr, "talkd: Could not find ntalk udp service\n");
|
||||
close(udp_in);
|
||||
close(udp_out);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
ntalk_port = (udpport_t)servent->s_port;
|
||||
|
||||
udpopt.nwuo_flags = NWUO_NOFLAGS;
|
||||
udpopt.nwuo_flags |= NWUO_COPY | NWUO_LP_SET | NWUO_EN_LOC;
|
||||
udpopt.nwuo_flags |= NWUO_DI_BROAD | NWUO_RP_ANY | NWUO_RA_ANY;
|
||||
udpopt.nwuo_flags |= NWUO_RWDATALL | NWUO_DI_IPOPT;
|
||||
udpopt.nwuo_locport = ntalk_port;
|
||||
|
||||
s = ioctl(udp_in, NWIOSUDPOPT, &udpopt);
|
||||
if(s < 0) {
|
||||
perror("talkd: ioctl NWIOSUDPOPT");
|
||||
close(udp_in);
|
||||
close(udp_out);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
s = ioctl(udp_in, NWIOGUDPOPT, &udpopt);
|
||||
if(s < 0) {
|
||||
perror("talkd: ioctl NWIOGUDPOPT");
|
||||
close(udp_in);
|
||||
close(udp_out);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int getrequest(request)
|
||||
struct talk_request *request;
|
||||
{
|
||||
int s;
|
||||
udp_io_hdr_t *udp_io_hdr;
|
||||
|
||||
s = read(udp_in, buffer, sizeof(buffer));
|
||||
if(s < 0) {
|
||||
perror("talkd: Read error in getrequest");
|
||||
return(-1);
|
||||
}
|
||||
if(s < sizeof(udp_io_hdr_t)) {
|
||||
fprintf(stderr, "talkd: Packet size read %d is smaller the udp_io_hdr\n", s);
|
||||
return(-1);
|
||||
}
|
||||
udp_io_hdr = (udp_io_hdr_t *)buffer;
|
||||
s = s - sizeof(udp_io_hdr_t);
|
||||
|
||||
/* why is uih_data_len already in host order??? */
|
||||
|
||||
if(udp_io_hdr->uih_data_len != s) {
|
||||
fprintf(stderr, "talkd: Size mismatch Packet %d Udp Data %d\n",
|
||||
s, udp_io_hdr->uih_data_len);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if(s != sizeof(struct talk_request)) {
|
||||
fprintf(stderr, "talkd: Size mismatch in request %d %d\n",
|
||||
s, sizeof(struct talk_request));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
memcpy((char *)request, buffer + sizeof(udp_io_hdr_t), s);
|
||||
|
||||
if(opt_d) {
|
||||
fprintf(stderr, "Request: ");
|
||||
fprintf(stderr, "%02x %02x %02x %02x ",
|
||||
request->version, request->type, request->answer, request->junk);
|
||||
fprintf(stderr, "%08lx ", request->id);
|
||||
fprintf(stderr, "%04x %08lx:%04x\n",
|
||||
request->addr.sa_family, request->addr.sin_addr, request->addr.sin_port);
|
||||
fprintf(stderr, " %08lx ", request->pid);
|
||||
fprintf(stderr, "%04x %08lx:%04x\n",
|
||||
request->ctl_addr.sa_family, request->ctl_addr.sin_addr, request->ctl_addr.sin_port);
|
||||
fprintf(stderr, " %-12.12s %-12.12s %-16.16s\n",
|
||||
request->luser, request->ruser, request->rtty);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int sendreply(request, reply)
|
||||
struct talk_request *request;
|
||||
struct talk_reply *reply;
|
||||
{
|
||||
int s;
|
||||
nwio_udpopt_t udpopt;
|
||||
udp_io_hdr_t *udp_io_hdr;
|
||||
|
||||
udpopt.nwuo_flags = NWUO_NOFLAGS;
|
||||
udpopt.nwuo_flags |= NWUO_COPY | NWUO_LP_SET | NWUO_EN_LOC;
|
||||
udpopt.nwuo_flags |= NWUO_DI_BROAD | NWUO_RP_SET | NWUO_RA_SET;
|
||||
udpopt.nwuo_flags |= NWUO_RWDATONLY | NWUO_DI_IPOPT;
|
||||
udpopt.nwuo_locport = ntalk_port;
|
||||
udpopt.nwuo_remaddr = request->ctl_addr.sin_addr;
|
||||
udpopt.nwuo_remport = request->ctl_addr.sin_port;
|
||||
|
||||
s = ioctl(udp_out, NWIOSUDPOPT, &udpopt);
|
||||
if(s < 0) {
|
||||
perror("talkd: ioctl NWIOSUDPOPT");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
s = ioctl(udp_out, NWIOGUDPOPT, &udpopt);
|
||||
if(s < 0) {
|
||||
perror("talkd: ioctl NWIOGUDPOPT");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if(opt_d) {
|
||||
fprintf(stderr, "Reply: ");
|
||||
fprintf(stderr, "%02x %02x %02x %02x ",
|
||||
reply->version, reply->type, reply->answer, reply->junk);
|
||||
fprintf(stderr, "%08lx ", reply->id);
|
||||
fprintf(stderr, "%04x %08lx:%04x",
|
||||
reply->addr.sa_family, reply->addr.sin_addr, reply->addr.sin_port);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
s = write(udp_out, reply, sizeof(struct talk_reply));
|
||||
if(s < 0) {
|
||||
perror("talkd: write");
|
||||
return(-1);
|
||||
}
|
||||
if(s != sizeof(struct talk_reply)) {
|
||||
fprintf(stderr, "talkd: write size mismatch %d %d\n",
|
||||
s, sizeof(struct talk_reply));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
/* net.h Copyright Michael Temari 07/22/1996 All Rights Reserved */
|
||||
|
||||
_PROTOTYPE(int NetInit, (void));
|
||||
_PROTOTYPE(int getrequest, (struct talk_request *request));
|
||||
_PROTOTYPE(int sendreply, (struct talk_request *request, struct talk_reply *reply));
|
||||
Executable
+269
@@ -0,0 +1,269 @@
|
||||
/* process.c Copyright Michael Temari 07/22/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 <ctype.h>
|
||||
#include <time.h>
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/socket.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/netdb.h>
|
||||
|
||||
#include "talk.h"
|
||||
#include "talkd.h"
|
||||
#include "process.h"
|
||||
#include "finduser.h"
|
||||
|
||||
struct entry {
|
||||
struct entry *prev;
|
||||
struct talk_request rq;
|
||||
time_t expire;
|
||||
struct entry *next;
|
||||
};
|
||||
|
||||
_PROTOTYPE(static int announce, (struct talk_request *request, char *rhost));
|
||||
_PROTOTYPE(static struct talk_request *lookup, (struct talk_request *request, int type));
|
||||
_PROTOTYPE(static int addreq, (struct talk_request *request));
|
||||
_PROTOTYPE(static delete_invite, (long id));
|
||||
_PROTOTYPE(static long nextid, (void));
|
||||
_PROTOTYPE(static void delete, (struct entry *e));
|
||||
|
||||
static struct entry *entry = (struct entry *)NULL;
|
||||
|
||||
int processrequest(request, reply)
|
||||
struct talk_request *request;
|
||||
struct talk_reply *reply;
|
||||
{
|
||||
char *p;
|
||||
struct talk_request *rq;
|
||||
struct hostent *hp;
|
||||
|
||||
reply->version = TALK_VERSION;
|
||||
reply->type = request->type;
|
||||
reply->answer = 0;
|
||||
reply->junk = 0;
|
||||
reply->id = htonl(0);
|
||||
|
||||
|
||||
/* check version */
|
||||
if(request->version != TALK_VERSION) {
|
||||
reply->answer = BADVERSION;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* check address family */
|
||||
if(ntohs(request->addr.sa_family) != AF_INET) {
|
||||
reply->answer = BADADDR;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* check control address family */
|
||||
if(ntohs(request->ctl_addr.sa_family) != AF_INET) {
|
||||
reply->answer = BADCTLADDR;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* check local name */
|
||||
p = request->luser;
|
||||
while(*p)
|
||||
if(!isprint(*p)) {
|
||||
reply->answer = FAILED;
|
||||
return(0);
|
||||
} else
|
||||
p++;
|
||||
|
||||
switch(request->type) {
|
||||
case ANNOUNCE:
|
||||
reply->answer = find_user(request->ruser, request->rtty);
|
||||
if(reply->answer != SUCCESS) break;
|
||||
hp = gethostbyaddr((char *)&request->ctl_addr.sin_addr, sizeof(ipaddr_t), AF_INET);
|
||||
if(hp == (struct hostent *)NULL) {
|
||||
reply->answer = MACHINE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
if((rq = lookup(request, 1)) == (struct talk_request *)NULL) {
|
||||
reply->id = addreq(request);
|
||||
reply->answer = announce(request, hp->h_name);
|
||||
break;
|
||||
}
|
||||
if(ntohl(request->id) > ntohl(rq->id)) {
|
||||
rq->id = nextid();
|
||||
reply->id = rq->id;
|
||||
reply->answer = announce(request, hp->h_name);
|
||||
} else {
|
||||
reply->id = rq->id;
|
||||
reply->answer = SUCCESS;
|
||||
}
|
||||
break;
|
||||
case LEAVE_INVITE:
|
||||
rq = lookup(request, 1);
|
||||
if(rq == (struct talk_request *)NULL)
|
||||
reply->id = addreq(request);
|
||||
else {
|
||||
reply->id = rq->id;
|
||||
reply->answer = SUCCESS;
|
||||
}
|
||||
break;
|
||||
case LOOK_UP:
|
||||
if((rq = lookup(request, 0)) == (struct talk_request *)NULL)
|
||||
reply->answer = NOT_HERE;
|
||||
else {
|
||||
reply->id = rq->id;
|
||||
memcpy((char *)&reply->addr, (char *)&rq->addr, sizeof(reply->addr));
|
||||
reply->answer = SUCCESS;
|
||||
}
|
||||
break;
|
||||
case DELETE:
|
||||
reply->answer = delete_invite(request->id);
|
||||
break;
|
||||
default:
|
||||
reply->answer = UNKNOWN_REQUEST;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int announce(request, rhost)
|
||||
struct talk_request *request;
|
||||
char *rhost;
|
||||
{
|
||||
char tty[5+TTY_SIZE+1];
|
||||
struct stat st;
|
||||
FILE *fp;
|
||||
time_t now;
|
||||
struct tm *tm;
|
||||
|
||||
sprintf(tty, "/dev/%s", request->rtty);
|
||||
|
||||
if(stat(tty, &st) < 0)
|
||||
return(PERMISSION_DENIED);
|
||||
|
||||
if(!(st.st_mode & S_IWGRP))
|
||||
return(PERMISSION_DENIED);
|
||||
|
||||
if((fp = fopen(tty, "w")) == (FILE *)NULL)
|
||||
return(PERMISSION_DENIED);
|
||||
|
||||
(void) time(&now);
|
||||
|
||||
tm = localtime(&now);
|
||||
|
||||
fprintf(fp, "\007\007\007\rtalkd: Message from talkd@%s at %d:%02d:%02d\r\n",
|
||||
myhostname, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
fprintf(fp, "talkd: %s@%s would like to talk to you\r\n",
|
||||
request->luser, rhost);
|
||||
fprintf(fp, "talkd: to answer type: talk %s@%s\r\n",
|
||||
request->luser, rhost);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return(SUCCESS);
|
||||
}
|
||||
|
||||
static struct talk_request *lookup(request, type)
|
||||
struct talk_request *request;
|
||||
int type;
|
||||
{
|
||||
time_t now;
|
||||
struct entry *e;
|
||||
|
||||
(void) time(&now);
|
||||
|
||||
for(e = entry; e != (struct entry *)NULL; e = e->next) {
|
||||
if(now > e->expire) {
|
||||
delete(e);
|
||||
continue;
|
||||
}
|
||||
if(type == 0) {
|
||||
if(!strncmp(request->luser, e->rq.ruser, USER_SIZE) &&
|
||||
!strncmp(request->ruser, e->rq.luser, USER_SIZE) &&
|
||||
e->rq.type == LEAVE_INVITE)
|
||||
return(&e->rq);
|
||||
} else {
|
||||
if(request->type == e->rq.type &&
|
||||
request->pid == e->rq.pid &&
|
||||
!strncmp(request->luser, e->rq.luser, USER_SIZE) &&
|
||||
!strncmp(request->ruser, e->rq.ruser, USER_SIZE)) {
|
||||
e->expire = now + MAX_LIFE;
|
||||
return(&e->rq);
|
||||
}
|
||||
}
|
||||
}
|
||||
return((struct talk_request *)NULL);
|
||||
}
|
||||
|
||||
static int addreq(request)
|
||||
struct talk_request *request;
|
||||
{
|
||||
time_t now;
|
||||
struct entry *e;
|
||||
|
||||
(void) time(&now);
|
||||
request->id = nextid();
|
||||
e = (struct entry *) malloc(sizeof(struct entry));
|
||||
if(e == (struct entry *)NULL) {
|
||||
fprintf(stderr, "talkd: out of memory in insert table\n");
|
||||
exit(1);
|
||||
}
|
||||
e->expire = now + MAX_LIFE;
|
||||
memcpy((char *)&e->rq, (char *)request, sizeof(struct talk_request));
|
||||
e->next = entry;
|
||||
if(e->next != (struct entry *)NULL)
|
||||
e->next->prev = e;
|
||||
e->prev = (struct entry *)NULL;
|
||||
entry = e;
|
||||
return(request->id);
|
||||
}
|
||||
|
||||
static int delete_invite(id)
|
||||
long id;
|
||||
{
|
||||
time_t now;
|
||||
struct entry *e;
|
||||
|
||||
(void) time(&now);
|
||||
|
||||
for(e = entry; e != (struct entry *)NULL; e = e->next) {
|
||||
if(now > e->expire) {
|
||||
delete(e);
|
||||
continue;
|
||||
}
|
||||
if(e->rq.id == id) {
|
||||
delete(e);
|
||||
return(SUCCESS);
|
||||
}
|
||||
}
|
||||
return(NOT_HERE);
|
||||
}
|
||||
|
||||
static void delete(e)
|
||||
struct entry *e;
|
||||
{
|
||||
if(e == (struct entry *)NULL) return;
|
||||
|
||||
if(entry == e)
|
||||
entry = e->next;
|
||||
else
|
||||
if(e->prev != (struct entry *)NULL)
|
||||
e->prev->next = e->next;
|
||||
|
||||
if(e->next != (struct entry *)NULL)
|
||||
e->next->prev = e->prev;
|
||||
|
||||
free((char *)e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static long nextid()
|
||||
{
|
||||
static long id = 0;
|
||||
|
||||
id++;
|
||||
if(id <= 0) id = 1;
|
||||
return(htonl(id));
|
||||
}
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
/* process.h Copyright Michael Temari 07/22/1996 All Rights Reserved */
|
||||
|
||||
_PROTOTYPE(int processrequest, (struct talk_request *request, struct talk_reply *reply));
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
/* talk.h Copyright Michael Temari 07/22/1996 All Rights Reserved */
|
||||
|
||||
#define USER_SIZE 12
|
||||
#define TTY_SIZE 16
|
||||
#define HOST_SIZE 255
|
||||
|
||||
struct osockaddr {
|
||||
u16_t sa_family;
|
||||
u16_t sin_port;
|
||||
ipaddr_t sin_addr;
|
||||
char junk[8];
|
||||
};
|
||||
|
||||
struct talk_request {
|
||||
u8_t version;
|
||||
u8_t type;
|
||||
u8_t answer;
|
||||
u8_t junk;
|
||||
u32_t id;
|
||||
struct osockaddr addr;
|
||||
struct osockaddr ctl_addr;
|
||||
long pid;
|
||||
char luser[USER_SIZE];
|
||||
char ruser[USER_SIZE];
|
||||
char rtty[TTY_SIZE];
|
||||
};
|
||||
|
||||
struct talk_reply {
|
||||
u8_t version;
|
||||
u8_t type;
|
||||
u8_t answer;
|
||||
u8_t junk;
|
||||
u32_t id;
|
||||
struct osockaddr addr;
|
||||
};
|
||||
|
||||
#define TALK_VERSION 1
|
||||
|
||||
/* message type values */
|
||||
#define LEAVE_INVITE 0 /* leave invitation with server */
|
||||
#define LOOK_UP 1 /* check for invitation by callee */
|
||||
#define DELETE 2 /* delete invitation by caller */
|
||||
#define ANNOUNCE 3 /* announce invitation by caller */
|
||||
|
||||
/* answer values */
|
||||
#define SUCCESS 0 /* operation completed properly */
|
||||
#define NOT_HERE 1 /* callee not logged in */
|
||||
#define FAILED 2 /* operation failed for unexplained reason */
|
||||
#define MACHINE_UNKNOWN 3 /* caller's machine name unknown */
|
||||
#define PERMISSION_DENIED 4 /* callee's tty doesn't permit announce */
|
||||
#define UNKNOWN_REQUEST 5 /* request has invalid type value */
|
||||
#define BADVERSION 6 /* request has invalid protocol version */
|
||||
#define BADADDR 7 /* request has invalid addr value */
|
||||
#define BADCTLADDR 8 /* request has invalid ctl_addr value */
|
||||
|
||||
#define MAX_LIFE 60 /* max time daemon saves invitations */
|
||||
#define RING_WAIT 30 /* time to wait before resending invitation */
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
/* talkd.c Copyright Michael Temari 07/22/1996 All Rights Reserved */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <net/gen/in.h>
|
||||
|
||||
#include "talk.h"
|
||||
#include "talkd.h"
|
||||
#include "net.h"
|
||||
#include "process.h"
|
||||
|
||||
_PROTOTYPE(int main, (int argc, char *argv[]));
|
||||
|
||||
int opt_d = 0;
|
||||
char myhostname[HOST_SIZE+1];
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
struct talk_request request;
|
||||
struct talk_reply reply;
|
||||
|
||||
if(argc > 1)
|
||||
if(strcmp(argv[1], "-d") || argc > 2) {
|
||||
fprintf(stderr, "Usage: talkd [-d]\n");
|
||||
return(-1);
|
||||
} else
|
||||
opt_d = 1;
|
||||
|
||||
if(getuid() != 0) {
|
||||
fprintf(stderr, "talkd: Must be run as super user\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if(gethostname(myhostname, HOST_SIZE) < 0) {
|
||||
fprintf(stderr, "talkd: Error getting hostname\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if(NetInit()) {
|
||||
fprintf(stderr, "talkd: Error in NetInit\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
while(getrequest(&request) == 0) {
|
||||
if(processrequest(&request, &reply)) break;
|
||||
if(sendreply(&request, &reply)) break;
|
||||
}
|
||||
|
||||
return(-1);
|
||||
}
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
/* talkd.h Copyright Michael Temari 07/22/1996 All Rights Reserved */
|
||||
|
||||
extern int opt_d; /* debug option */
|
||||
extern char myhostname[];
|
||||
Reference in New Issue
Block a user