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.