source: trunk/athena/bin/gms/get_message_from_server.c @ 1484

Revision 1484, 3.6 KB checked in by eichin, 36 years ago (diff)
Initial revision
Line 
1/* This file is part of the Project Athena Global Message System.
2 * Created by: Mark W. Eichin <eichin@athena.mit.edu>
3 * $Source: /afs/dev.mit.edu/source/repository/athena/bin/gms/get_message_from_server.c,v $
4 * $Author: eichin $
5 *
6 *      Copyright (c) 1988 by the Massachusetts Institute of Technology.
7 *      For copying and distribution information, see the file
8 *      "mit-copyright.h".
9 */
10#include <mit-copyright.h>
11#ifndef lint
12static char rcsid_get_message_from_server_c[] = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/gms/get_message_from_server.c,v 1.1 1988-09-26 15:40:43 eichin Exp $";
13#endif lint
14
15#include "globalmessage.h"
16#include <sys/types.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <netdb.h>
20#include <hesiod.h>
21#include <sys/time.h>
22
23Code_t get_message_from_server(ret_message, ret_message_size, server)
24     char **ret_message;
25     int *ret_message_size;
26     char *server;
27{
28  struct sockaddr_in server_insocket;
29  int sck, stat;
30  char *message_data;
31  int message_size;
32 
33  /* guard against NULL arguments */
34  if ((!ret_message)||(!server)) {
35    return(GMS_NULL_ARG_ERR);
36  }
37
38  /* contact the server, send the request name, get the message back */
39  /* create the socket */
40  sck = socket(AF_INET, SOCK_DGRAM, 0); /* 0 is VERY special... */
41  if(sck == -1) {
42    /* handle socket error */
43    return(errno);
44  }
45
46  /* Set the socket family */
47  server_insocket.sin_family = AF_INET;
48
49  /* Set the socket port */
50  {
51    struct servent *gms_service, *hes_getservbyname();
52    gms_service = getservbyname(GMS_SERV_NAME, GMS_SERV_PROTO);
53    if(!gms_service) {
54      /* getservbyname failed, fall back... */
55      /* Note that hes_getservbyname is broken currently, and does not
56       * convert the service name to host byte order. This should be
57       * fixed in the library; it will not be fixed here, since that
58       * will make it break later.
59       */
60      gms_service = hes_getservbyname(GMS_SERV_NAME, GMS_SERV_PROTO);
61      if(!gms_service) {
62        /* so did getservbyname, fall back to hard coded? */
63        return(GMS_NO_SERVICE_NAME);
64      }
65    }
66    server_insocket.sin_port = gms_service->s_port;
67  }
68
69  /* Set the socket address */
70  {
71    struct hostent *gms_host;
72    gms_host = gethostbyname(server);
73    if(!gms_host) {
74      /* gethostbyname failed */
75      return(gethost_error());
76    }
77    /* Copy in the first (preferred?) address of the server */
78    bcopy(gms_host->h_addr_list[0], &server_insocket.sin_addr,
79          gms_host->h_length);
80  }
81
82  /* Actually make the connection */
83  {
84    stat = connect(sck, &server_insocket, sizeof(server_insocket));
85    if(stat == -1) {
86      /* handle connect error */
87      return(errno);
88    }
89  }
90
91  /* send the version string as a datagram */
92  stat = send(sck, GMS_VERSION_STRING, GMS_VERSION_STRING_LEN, 0);
93  if (stat == -1) {
94    /* handle send failed error */
95    return(errno);
96  }
97
98  /* set up a timeout and select on the socket, to catch the return
99   * packet */
100  {
101    fd_set reader;
102    struct timeval timer;
103   
104    FD_ZERO(&reader);
105    FD_SET(sck, &reader);
106
107    timer.tv_sec = GMS_TIMEOUT_SEC;
108    timer.tv_usec = GMS_TIMEOUT_USEC;
109
110    stat = select(sck+1, &reader, 0, 0, &timer);
111    if (stat == -1) {
112      return(errno);
113    }
114    if (stat == 0) {
115      return(GMS_TIMED_OUT);
116    }
117    /* since we only wait on reader, it must have arrived */
118  }
119
120  message_data = malloc(GMS_MAX_MESSAGE_LEN);
121  stat = recv(sck, message_data, GMS_MAX_MESSAGE_LEN, 0);
122
123  close(sck); /* regardless of any errors... */
124
125  if(stat == -1) {
126    free(*message_data);
127    return(errno);
128  }
129
130  *ret_message_size = stat;
131  *ret_message = message_data;
132  return(0);
133}
Note: See TracBrowser for help on using the repository browser.