home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume36 / msend / part01 / sendrecv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-22  |  5.2 KB  |  235 lines

  1. /* sendrecv.c:
  2.  *
  3.  * these routines send messages and receive replies
  4.  *
  5.  * (c) Copyright 1988, 1989, 1990 Jim Frost.  All Rights Reserved.  Please see
  6.  * the accompanying file "Copyright" for more information.
  7.  */
  8.  
  9. #include "Copyright"
  10. #include "config.h"
  11. #include "msend.h"
  12.  
  13. extern int  errno;
  14. extern char *sys_errlist[];
  15.  
  16. #ifdef NOHERROR
  17. int h_errno;
  18. char    *h_errlist[] = {
  19.   "Error 0",
  20.   "Unknown host",            /* 1 HOST_NOT_FOUND */
  21.   "Host name lookup failure",        /* 2 TRY_AGAIN */
  22.   "Unknown server error",        /* 3 NO_RECOVERY */
  23.   "No address associated with name",    /* 4 NO_ADDRESS */
  24. };
  25.  
  26. #else
  27. extern int h_errno;
  28. extern char *h_errlist;
  29. #endif
  30.  
  31. static char *wrerr= "communications error with socket";
  32.  
  33. /* send a message to another server and get a reply
  34.  */
  35.  
  36. void sendmessage(si,ri,mode)
  37. struct simsg *si; /* message to send */
  38. struct rimsg *ri; /* reply we'll get */
  39. int    mode;      /* communications mode */
  40. { int     a;
  41.   int     uid;
  42.   static  int     s= -1;
  43.   struct  sheader sh;
  44.   struct  rheader rh;
  45.   u_short fwdcount;
  46.   u_short mmode;
  47.  
  48.   /* check to see if we have too many forwards
  49.    */
  50.  
  51.   if (si->fwdcount > MAXFORWARD) {
  52.     ri->h.errno= RE_FWDLOOP;
  53.     strcpy(ri->msg,"Forwarding loop (too many forwards)");
  54.     return;
  55.   }
  56.  
  57.   /* look for illegal characters in the string.  this stops people
  58.    * from sending nasty codes with this
  59.    */
  60.  
  61.   for (a= 0; a < strlen(si->msg); a++)
  62.     if ((si->msg[a] < ' ') && (si->msg[a] != '\t') && (si->msg[a] != '\n') &&
  63.         (si->msg[a] != 010)) {
  64.       ri->h.errno= RE_NOTFATAL;
  65.       strcpy(ri->msg,"Control characters are not allowed in messages (message not sent)");
  66.       ri->h.msglen= strlen(ri->msg);
  67.       return;
  68.     }
  69.  
  70.   /* s is -1 if we're not already connected
  71.    */
  72.  
  73.   if (s == -1) {
  74.  
  75.     /* if possible, become root for duration of hopen() call so we can
  76.      * deal with low port numbers
  77.      */
  78.  
  79.     if (getuid() == ROOTUID) {
  80.       uid= geteuid();
  81.       seteuid(ROOTUID);
  82.     }
  83.  
  84.     /* return immediate error if we can't connect
  85.      */
  86.  
  87.     if ((s= hopen(si->tohost)) < 0) {
  88.       if (getuid() == ROOTUID)
  89.         seteuid(uid);
  90.       if (h_errno == 0) { 
  91.     sprintf(ri->msg,"%s: %s",si->tohost,sys_errlist[errno]);
  92.     ri->h.msglen= strlen(sys_errlist[errno]);
  93.       } else { 
  94.     sprintf(ri->msg,"%s: %s",si->tohost,h_errlist[h_errno]);
  95.     ri->h.msglen= strlen(h_errlist[h_errno]);
  96.       }
  97.       ri->h.errno= RE_SYSERR;
  98.       return;
  99.     }
  100.     if (getuid() == ROOTUID)
  101.       seteuid(uid); /* become our old selves again */
  102.   }
  103.  
  104.   /* format request and send it across
  105.    */
  106.  
  107.   fwdcount= htons(si->fwdcount);
  108.   mmode= htons((u_short)mode);
  109.   sh.taddrlen= htons((u_short)strlen(si->taddr));
  110.   sh.tttylen= htons((u_short)strlen(si->ttty));
  111.   sh.msglen= htons((u_short)strlen(si->msg));
  112.  
  113.   if (hwrite(s,(char *)&sh,sizeof(struct sheader)) < 0) {
  114.     hclose(s);
  115.     s= -1;
  116.     blderr(ri,RE_SYSERR,wrerr);
  117.     return;
  118.   }
  119.   if (hwrite(s,(char *)&fwdcount,sizeof(u_short)) < 0) {
  120.     hclose(s);
  121.     s= -1;
  122.     blderr(ri,RE_SYSERR,wrerr);
  123.     return;
  124.   }
  125.   if (hwrite(s,(char *)&mmode,sizeof(u_short)) < 0) {
  126.     hclose(s);
  127.     s= -1;
  128.     blderr(ri,RE_SYSERR,wrerr);
  129.     return;
  130.   }
  131.   if (hwrite(s,(char *)si->taddr,strlen(si->taddr)) < 0) {
  132.     hclose(s);
  133.     s= -1;
  134.     blderr(ri,RE_SYSERR,wrerr);
  135.     return;
  136.   }
  137.   if (hwrite(s,(char *)si->ttty,strlen(si->ttty)) < 0) {
  138.     hclose(s);
  139.     s= -1;
  140.     blderr(ri,RE_SYSERR,wrerr);
  141.     return;
  142.   }
  143.   if (hwrite(s,(char *)si->msg,strlen(si->msg)) < 0) {
  144.     hclose(s);
  145.     s= -1;
  146.     blderr(ri,RE_SYSERR,wrerr);
  147.     return;
  148.   }
  149.  
  150.   /* Get the returned structure
  151.    */
  152.  
  153.   hread(s,(char *)&rh,sizeof(struct rheader));
  154.   ri->h.errno= ntohs(rh.errno);
  155.   ri->h.msglen= ntohs(rh.msglen);
  156.   hread(s,(char *)ri->msg,ri->h.msglen);
  157.   ri->msg[ri->h.msglen]= '\0';
  158.   if ((mode & SM_CLOSE) || (ri->h.errno != RE_OK)) {
  159.     hclose(s);
  160.     s= -1;
  161.   }
  162. }
  163.  
  164. /* sendreply() and recvmessage() are used only in the daemon
  165.  */
  166.  
  167. /* send reply back to whomever called us.  automatically close connection
  168.  * if we were supposed to.
  169.  */
  170.  
  171. void sendreply(s,ri,mode)
  172. int s;
  173. struct rimsg *ri;
  174. int mode;
  175. { struct rheader rh;
  176.  
  177.   rh.errno= htons(ri->h.errno);
  178.   rh.msglen= htons((u_short)strlen(ri->msg));
  179.   hwrite(s,(char *)&rh,sizeof(struct rheader));
  180.   hwrite(s,(char *)ri->msg,strlen(ri->msg));
  181.   if ((mode & SM_CLOSE) || (ri->h.errno != RE_OK))
  182.     hclose(s);
  183. }
  184.  
  185. /* this gets a message from the socket.
  186.  */
  187.  
  188. void recvmessage(s,si)
  189. int s;
  190. struct simsg *si;
  191. { struct sheader sh;
  192.   int    r;
  193.  
  194.   /* pull the message out of the connection and into a structure
  195.    */
  196.  
  197.   switch (hread(s,(char *)&sh,sizeof(struct sheader))) {
  198.   case -1:
  199.     error("error reading message header"); /* oh well */
  200.   case 0:
  201.     hclose(s);
  202.     exit(0);
  203.   default:
  204.     break;
  205.   }
  206.  
  207.   /* adjust integer format
  208.    */
  209.  
  210.   sh.taddrlen= ntohs(sh.taddrlen);
  211.   sh.tttylen= ntohs(sh.tttylen);
  212.   sh.msglen= ntohs(sh.msglen);
  213.  
  214.   /* read the data section
  215.    */
  216.  
  217.   r= hread(s,(char *)&si->fwdcount,sizeof(u_short));
  218.   r|= hread(s,(char *)&si->mode,sizeof(u_short));
  219.   r|= hread(s,(char *)si->taddr,sh.taddrlen);
  220.   r|= hread(s,(char *)si->ttty,sh.tttylen);
  221.   r|= hread(s,(char *)si->msg,sh.msglen);
  222.  
  223.   if (r < 0) {
  224.     error("packet read error");
  225.     hclose(s);
  226.     exit(1);
  227.   }
  228.  
  229.   si->fwdcount= ntohs(si->fwdcount);
  230.   si->mode= ntohs(si->mode);
  231.   si->taddr[sh.taddrlen]= '\0';
  232.   si->ttty[sh.tttylen]= '\0';
  233.   si->msg[sh.msglen]= '\0';
  234. }
  235.