This is sendrecv.c in view mode; [Download] [Up]
/* sendrecv.c:
*
* these routines send messages and receive replies
*
* (c) Copyright 1988, 1989, 1990 Jim Frost. All Rights Reserved. Please see
* the accompanying file "Copyright" for more information.
*/
#include "Copyright"
#include "config.h"
#include "msend.h"
extern int errno;
extern char *sys_errlist[];
char *h_errlist[] = {
"Error 0",
"Unknown host", /* 1 HOST_NOT_FOUND */
"Host name lookup failure", /* 2 TRY_AGAIN */
"Unknown server error", /* 3 NO_RECOVERY */
"No address associated with name", /* 4 NO_ADDRESS */
};
#ifndef NOHERROR
extern int h_errno;
#else
int h_errno;
#endif
static char *wrerr= "communications error with socket";
/* send a message to another server and get a reply
*/
void sendmessage(si,ri,mode)
struct simsg *si; /* message to send */
struct rimsg *ri; /* reply we'll get */
int mode; /* communications mode */
{ int a;
int uid;
static int s= -1;
struct sheader sh;
struct rheader rh;
u_short fwdcount;
u_short mmode;
/* check to see if we have too many forwards
*/
if (si->fwdcount > MAXFORWARD) {
ri->h.errno= RE_FWDLOOP;
strcpy(ri->msg,"Forwarding loop (too many forwards)");
return;
}
/* look for illegal characters in the string. this stops people
* from sending nasty codes with this
*/
for (a= 0; a < strlen(si->msg); a++)
if ((si->msg[a] < ' ') && (si->msg[a] != '\t') && (si->msg[a] != '\n') &&
(si->msg[a] != 010)) {
ri->h.errno= RE_NOTFATAL;
strcpy(ri->msg,"Control characters are not allowed in messages (message not sent)");
ri->h.msglen= strlen(ri->msg);
return;
}
/* s is -1 if we're not already connected
*/
if (s == -1) {
/* if possible, become root for duration of hopen() call so we can
* deal with low port numbers
*/
if (getuid() == ROOTUID) {
uid= geteuid();
seteuid(ROOTUID);
}
/* return immediate error if we can't connect
*/
if ((s= hopen(si->tohost)) < 0) {
if (getuid() == ROOTUID)
seteuid(uid);
if (h_errno == 0) {
sprintf(ri->msg,"%s: %s",si->tohost,sys_errlist[errno]);
ri->h.msglen= strlen(sys_errlist[errno]);
} else {
sprintf(ri->msg,"%s: %s",si->tohost,h_errlist[h_errno]);
ri->h.msglen= strlen(h_errlist[h_errno]);
}
ri->h.errno= RE_SYSERR;
return;
}
if (getuid() == ROOTUID)
seteuid(uid); /* become our old selves again */
}
/* format request and send it across
*/
fwdcount= htons(si->fwdcount);
mmode= htons((u_short)mode);
sh.taddrlen= htons((u_short)strlen(si->taddr));
sh.tttylen= htons((u_short)strlen(si->ttty));
sh.msglen= htons((u_short)strlen(si->msg));
if (hwrite(s,(char *)&sh,sizeof(struct sheader)) < 0) {
hclose(s);
s= -1;
blderr(ri,RE_SYSERR,wrerr);
return;
}
if (hwrite(s,(char *)&fwdcount,sizeof(u_short)) < 0) {
hclose(s);
s= -1;
blderr(ri,RE_SYSERR,wrerr);
return;
}
if (hwrite(s,(char *)&mmode,sizeof(u_short)) < 0) {
hclose(s);
s= -1;
blderr(ri,RE_SYSERR,wrerr);
return;
}
if (hwrite(s,(char *)si->taddr,strlen(si->taddr)) < 0) {
hclose(s);
s= -1;
blderr(ri,RE_SYSERR,wrerr);
return;
}
if (hwrite(s,(char *)si->ttty,strlen(si->ttty)) < 0) {
hclose(s);
s= -1;
blderr(ri,RE_SYSERR,wrerr);
return;
}
if (hwrite(s,(char *)si->msg,strlen(si->msg)) < 0) {
hclose(s);
s= -1;
blderr(ri,RE_SYSERR,wrerr);
return;
}
/* Get the returned structure
*/
hread(s,(char *)&rh,sizeof(struct rheader));
ri->h.errno= ntohs(rh.errno);
ri->h.msglen= ntohs(rh.msglen);
hread(s,(char *)ri->msg,ri->h.msglen);
ri->msg[ri->h.msglen]= '\0';
if ((mode & SM_CLOSE) || (ri->h.errno != RE_OK)) {
hclose(s);
s= -1;
}
}
/* sendreply() and recvmessage() are used only in the daemon
*/
/* send reply back to whomever called us. automatically close connection
* if we were supposed to.
*/
void sendreply(s,ri,mode)
int s;
struct rimsg *ri;
int mode;
{ struct rheader rh;
rh.errno= htons(ri->h.errno);
rh.msglen= htons((u_short)strlen(ri->msg));
hwrite(s,(char *)&rh,sizeof(struct rheader));
hwrite(s,(char *)ri->msg,strlen(ri->msg));
if ((mode & SM_CLOSE) || (ri->h.errno != RE_OK))
hclose(s);
}
/* this gets a message from the socket.
*/
void recvmessage(s,si)
int s;
struct simsg *si;
{ struct sheader sh;
int r;
/* pull the message out of the connection and into a structure
*/
switch (hread(s,(char *)&sh,sizeof(struct sheader))) {
case -1:
error("error reading message header"); /* oh well */
case 0:
hclose(s);
exit(0);
default:
break;
}
/* adjust integer format
*/
sh.taddrlen= ntohs(sh.taddrlen);
sh.tttylen= ntohs(sh.tttylen);
sh.msglen= ntohs(sh.msglen);
/* read the data section
*/
r= hread(s,(char *)&si->fwdcount,sizeof(u_short));
r|= hread(s,(char *)&si->mode,sizeof(u_short));
r|= hread(s,(char *)si->taddr,sh.taddrlen);
r|= hread(s,(char *)si->ttty,sh.tttylen);
r|= hread(s,(char *)si->msg,sh.msglen);
if (r < 0) {
error("packet read error");
hclose(s);
exit(1);
}
si->fwdcount= ntohs(si->fwdcount);
si->mode= ntohs(si->mode);
si->taddr[sh.taddrlen]= '\0';
si->ttty[sh.tttylen]= '\0';
si->msg[sh.msglen]= '\0';
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.