home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / unix / question / 9442 < prev    next >
Encoding:
Internet Message Format  |  1992-07-26  |  7.3 KB

  1. Path: sparky!uunet!munnari.oz.au!mips!public!thad
  2. From: thad@public.BTR.COM (Thaddeus P. Floryan)
  3. Newsgroups: comp.unix.questions
  4. Subject: Re: recvfrom() problems
  5. Message-ID: <7516@public.BTR.COM>
  6. Date: 26 Jul 92 22:32:03 GMT
  7. References: <1992Jul17.125731.1@hamp.hampshir>
  8. Organization: BTR Public Access UNIX, Mountain View CA
  9. Lines: 248
  10.  
  11. In article <1992Jul17.125731.1@hamp.hampshir> dhirmes@hamp.hampshire.edu writes:
  12. >
  13. >I'm writing a program using BSD socket interface.  I'm trying to 
  14. >utilize the UDP (datagram) service, but when I run my programs, I
  15. >get a "Bad Address" error.  I've tried several examples from tutorials,
  16. > but I get the same error.  I'm working with SunOS 4.0.1 and some of
  17. >the examples were written for Ultrix.  I was told there might be slight 
  18. >differences in the TCP/IP structures used by BSD implementations. I'vewritten
  19. >programs usinSOCK_STREAM which have worked fine, which adds to my
  20. >confusion. Oh, and the error  only occurs when I attempt a recvfrom(),
  21. >it appears to work when I use sendto().
  22. >
  23. >Can anyone help me out here?
  24.  
  25. The enclosed routine has functioned fine on every system upon which I've
  26. tried it; it is a part of the "rsetclk" program I wrote for the 3B1 and
  27. archived at ftp.uu.net and osu-cis (aka archive.cis.ohio-state.edu).
  28.  
  29. The systems upon which I know it works include SunOS 4.1.*, IRIX 4.0.*,
  30. HP-UX 7.* and 8.*, 3B1, 3B2, CTIX 6.2.*, Mac A/UX 2.*, etc.
  31.  
  32. Thad Floryan [ thad@btr.com (OR) {decwrl, mips, fernwood}!btr!thad ]
  33.  
  34. ---- Cut Here and feed the following to sh ----
  35. #!/bin/sh
  36. # This is a shell archive (produced by shar 3.49)
  37. # To extract the files from this archive, save it to a file, remove
  38. # everything above the "!/bin/sh" line above, and type "sh file_name".
  39. #
  40. # made 07/26/1992 22:32 UTC by thad@thadlabs
  41. # Source directory /usr/local/src/rsetclk
  42. #
  43. # existing files will NOT be overwritten unless -c is specified
  44. #
  45. # This shar contains:
  46. # length  mode       name
  47. # ------ ---------- ------------------------------------------
  48. #   4772 -rw-r--r-- rhost_time.c
  49. #
  50. # ============= rhost_time.c ==============
  51. if test -f 'rhost_time.c' -a X"$1" != X"-c"; then
  52.     echo 'x - skipping rhost_time.c (File already exists)'
  53. else
  54. echo 'x - extracting rhost_time.c (Text)'
  55. sed 's/^X//' << 'SHAR_EOF' > 'rhost_time.c' &&
  56. X/****************************************************************************
  57. X *    RHOST_TIME                               RHOST_TIME
  58. X *
  59. X * NAME
  60. X *
  61. X *    rhost_time - gets current time_t value from a remote host adjusted
  62. X *             to UNIX-style time.
  63. X *
  64. X * SYNOPSIS
  65. X *
  66. X *    time_t rhost_time(hostname, errptr)
  67. X *
  68. X *    char *hostname, *errptr
  69. X *
  70. X * DESCRIPTION
  71. X *
  72. X *    Returns the UNIX-style time from a remote host's inetd server.  Note
  73. X *    the time returned by the inetd server is the number of seconds since
  74. X *    midnight, Jan 1, 1900, in a timeval structure.  Since gettimeofday()
  75. X *    returns the number of seconds since midnight, Jan 1, 1970, the value
  76. X *    2208988800 seconds was added to gettimeofday(2)'s returned value and
  77. X *    we have to make an adjustment to normal UNIX system time.  Note that
  78. X *    the tv_usec value will always be zero.  For compilers that cannot
  79. X *    handle such large numbers, 2208988800 is equivalent to 0x83AA7E80.
  80. X *
  81. X *    The returned value is compatible to that from time().  Note that since
  82. X *    we cannot assume we're running on a "real" computer whose byte order
  83. X *    is the same as network byte order, ntohl() is applied to the value
  84. X *    retrieved from the remote host to accomodate "little endian" machines
  85. X *    such as the DEC {VAX or Alpha} or Intel 80?86 platforms.
  86. X *
  87. X *    The hostname is a null-terminated string whose form may be anything
  88. X *    normally used to reach that host (i.e. "host" or "host.domain.com").
  89. X *
  90. X * RETURN VALUES
  91. X *
  92. X *    On successful completion, rhost_time() returns the time as documented
  93. X *    above.
  94. X *
  95. X *    On error, rhost_time() returns a -1, errno will be set, and a pointer
  96. X *    to the error string will be returned via *errptr.
  97. X *
  98. X * BUGS
  99. X *
  100. X *    The return value for the error message points to a static data area
  101. X *    whose content is potentially overwritten by each call to rhost_time.
  102. X *
  103. X * SEE ALSO
  104. X *
  105. X *    time(), stime()
  106. X *    
  107. X */
  108. X
  109. X#include <stdio.h>
  110. X#include <sys/types.h>
  111. X#include <sys/socket.h>
  112. X#include <sys/time.h>
  113. X#include <netinet/in.h>
  114. X#include <netdb.h>
  115. X#include <signal.h>
  116. X#include <setjmp.h>
  117. X#include <errno.h>
  118. X
  119. X#define SERVICE    "time"
  120. X#define TIMEOUT 10        /* seconds to wait for reply from rhost */
  121. X
  122. Xextern    char            *sys_errlist[];    /* system error strings */
  123. X
  124. X    jmp_buf             env;        /* used by timeout handler */
  125. X    char             errmsg[80];    /* text of error message */
  126. X
  127. Xtime_t
  128. Xrhost_time(hostname, errptr)
  129. X    char            *hostname;
  130. X    char               **errptr;
  131. X{
  132. X
  133. X    int             noanswer();
  134. X
  135. X    int             s;
  136. X    int             n;
  137. X    int             len;
  138. X    int             status;
  139. X    struct    timeval         rtimebuf;
  140. X    struct    hostent        *hp;
  141. X    struct    servent        *sp;
  142. X    struct    sockaddr_in     sin;
  143. X
  144. X/*
  145. X *    Get a datagram socket in the Internet domain
  146. X */
  147. X    s = socket(AF_INET, SOCK_DGRAM, 0);
  148. X    if (s < 0) {
  149. X        sprintf(errmsg, "socket: %s\n", sys_errlist[errno]);
  150. X        *errptr = errmsg;
  151. X        return -1;
  152. X    }
  153. X/*
  154. X *    Look up the port number of the service.
  155. X */
  156. X    sp = getservbyname(SERVICE, "udp");
  157. X    if (sp == NULL) {
  158. X        errno = EINVAL;
  159. X        sprintf(errmsg, "%s/udp: unknown service\n", SERVICE);
  160. X        *errptr = errmsg;
  161. X        close(s);
  162. X        return -1;
  163. X    }
  164. X/*
  165. X *    Look up the network number of the host on the command line
  166. X */
  167. X    hp = gethostbyname(hostname);
  168. X    if (hp == NULL) {
  169. X        errno = EINVAL;
  170. X        sprintf(errmsg, "%s: host unknown\n", hostname);
  171. X        *errptr = errmsg;
  172. X        close(s);
  173. X        return -1;
  174. X    }
  175. X/*
  176. X *    Build the address of the server on the remote machine
  177. X */
  178. X    sin.sin_family = AF_INET;
  179. X    sin.sin_port   = sp->s_port;
  180. X
  181. X    bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
  182. X/*
  183. X *    Send a datagram to the server
  184. X */
  185. X    status = sendto(s, &rtimebuf, sizeof(rtimebuf), 0, &sin, sizeof(sin));
  186. X    if (status < 0) {
  187. X        sprintf(errmsg, "sendto(%s): %s\n", hostname, sys_errlist[errno]);
  188. X        *errptr = errmsg;
  189. X        close(s);
  190. X        return -1;
  191. X    }
  192. X/*
  193. X *    Enable timeout signal in case remote host is dead
  194. X */
  195. X    signal(SIGALRM, noanswer);
  196. X    alarm(TIMEOUT);
  197. X/*
  198. X *    Test if we timed out waiting for remote host to respond; presume the
  199. X *    remote host is down if so.
  200. X */
  201. X    status = setjmp(env);
  202. X    if (status > 0) {
  203. X        errno = EHOSTDOWN;
  204. X        sprintf(errmsg, "timeout(%s): %s\n", hostname, sys_errlist[errno]);
  205. X        *errptr = errmsg;
  206. X        close(s);
  207. X        return -1;
  208. X    }
  209. X/*
  210. X *    Receive a datagram back
  211. X */
  212. X    len = sizeof(sin);
  213. X    n   = recvfrom(s, &rtimebuf, sizeof(rtimebuf), 0, &sin, &len);
  214. X/*
  215. X *    Disable timeout signal
  216. X */
  217. X    alarm(0);
  218. X/*
  219. X *    Test state of returned datagram
  220. X */
  221. X    if (n < 0) {
  222. X        sprintf(errmsg, "recvfrom(%s): %s", hostname, sys_errlist[errno]);
  223. X        *errptr = errmsg;
  224. X        close(s);
  225. X        return -1;
  226. X    }
  227. X/*
  228. X *    Accomodate "little endian" architectures.
  229. X */
  230. X    rtimebuf.tv_sec = ntohl(rtimebuf.tv_sec);
  231. X/*
  232. X *    Adjust time with respect to the UNIX epoch of Jan. 1, 1970 00:00:00 GMT
  233. X */
  234. X    rtimebuf.tv_sec -= 2208988800L;
  235. X/*
  236. X *    Release socket
  237. X */
  238. X    close(s);
  239. X
  240. X    return rtimebuf.tv_sec;
  241. X}
  242. X
  243. X/*
  244. X *    rhost_time() timeout handler
  245. X *
  246. X */
  247. Xnoanswer()
  248. X{
  249. X    longjmp(env, 1);
  250. X}
  251. SHAR_EOF
  252. chmod 0644 rhost_time.c ||
  253. echo 'restore of rhost_time.c failed'
  254. Wc_c="`wc -c < 'rhost_time.c'`"
  255. test 4772 -eq "$Wc_c" ||
  256.     echo 'rhost_time.c: original size 4772, current size' "$Wc_c"
  257. fi
  258. exit 0
  259.