source: trunk/athena/bin/get_message/get_message_from_server.c @ 14063

Revision 14063, 3.5 KB checked in by danw, 25 years ago (diff)
get_message, formerly in athena/bin/gms
RevLine 
[14063]1/* Copyright 1988, 1998 by the Massachusetts Institute of Technology.
2 *
3 * Permission to use, copy, modify, and distribute this
4 * software and its documentation for any purpose and without
5 * fee is hereby granted, provided that the above copyright
6 * notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting
8 * documentation, and that the name of M.I.T. not be used in
9 * advertising or publicity pertaining to distribution of the
10 * software without specific, written prior permission.
11 * M.I.T. makes no representations about the suitability of
12 * this software for any purpose.  It is provided "as is"
13 * without express or implied warranty.
14 */
15
16static const char rcsid[] = "$Id: get_message_from_server.c,v 1.1 1999-12-08 22:06:44 danw Exp $";
17
18#include "globalmessage.h"
19#include <sys/types.h>
20#include <sys/socket.h>
21#include <netinet/in.h>
22#include <netdb.h>
23#include <hesiod.h>
24#include <sys/time.h>
25
26Code_t get_message_from_server(char **ret_message, int *ret_message_size,
27                               char *server)
28{
29  struct sockaddr_in server_insocket;
30  int sck, stat;
31  char *message_data;
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;
52    gms_service = getservbyname(GMS_SERV_NAME, GMS_SERV_PROTO);
53    if(!gms_service) {
54      /* getservbyname failed, fall back... */
55      gms_service = hes_getservbyname(GMS_SERV_NAME, GMS_SERV_PROTO);
56      if(!gms_service) {
57        /* so did getservbyname, fall back to hard coded? */
58        return(GMS_NO_SERVICE_NAME);
59      }
60    }
61    server_insocket.sin_port = gms_service->s_port;
62  }
63
64  /* Set the socket address */
65  {
66    struct hostent *gms_host;
67    gms_host = gethostbyname(server);
68    if(!gms_host) {
69      /* gethostbyname failed */
70      return(gethost_error());
71    }
72    /* Copy in the first (preferred?) address of the server */
73    memcpy(&server_insocket.sin_addr, gms_host->h_addr_list[0],
74          gms_host->h_length);
75  }
76
77  /* Actually make the connection */
78  {
79    stat = connect(sck, (struct sockaddr *) &server_insocket,
80                   sizeof(server_insocket));
81    if(stat == -1) {
82      /* handle connect error */
83      return(errno);
84    }
85  }
86
87  /* send the version string as a datagram */
88  stat = send(sck, GMS_VERSION_STRING, GMS_VERSION_STRING_LEN, 0);
89  if (stat == -1) {
90    /* handle send failed error */
91    return(errno);
92  }
93
94  /* set up a timeout and select on the socket, to catch the return
95   * packet */
96  {
97    fd_set reader;
98    struct timeval timer;
99   
100    FD_ZERO(&reader);
101    FD_SET(sck, &reader);
102
103    timer.tv_sec = GMS_TIMEOUT_SEC;
104    timer.tv_usec = GMS_TIMEOUT_USEC;
105
106    stat = select(sck+1, &reader, 0, 0, &timer);
107    if (stat == -1) {
108      return(errno);
109    }
110    if (stat == 0) {
111      return(GMS_TIMED_OUT);
112    }
113    /* since we only wait on reader, it must have arrived */
114  }
115
116  message_data = malloc(GMS_MAX_MESSAGE_LEN);
117  stat = recv(sck, message_data, GMS_MAX_MESSAGE_LEN-1, 0);
118
119  close(sck); /* regardless of any errors... */
120
121  if(stat == -1) {
122    free(message_data);
123    return(errno);
124  }
125
126  message_data[stat] ='\0';
127  *ret_message_size = stat;
128  *ret_message = message_data;
129  return(0);
130}
Note: See TracBrowser for help on using the repository browser.