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

Revision 8855, 3.4 KB checked in by ghudson, 28 years ago (diff)
BSD -> ANSI string and memory functions
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: ghudson $
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.4 1996-09-19 22:39:17 ghudson 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      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, &server_insocket, sizeof(server_insocket));
80    if(stat == -1) {
81      /* handle connect error */
82      return(errno);
83    }
84  }
85
86  /* send the version string as a datagram */
87  stat = send(sck, GMS_VERSION_STRING, GMS_VERSION_STRING_LEN, 0);
88  if (stat == -1) {
89    /* handle send failed error */
90    return(errno);
91  }
92
93  /* set up a timeout and select on the socket, to catch the return
94   * packet */
95  {
96    fd_set reader;
97    struct timeval timer;
98   
99    FD_ZERO(&reader);
100    FD_SET(sck, &reader);
101
102    timer.tv_sec = GMS_TIMEOUT_SEC;
103    timer.tv_usec = GMS_TIMEOUT_USEC;
104
105    stat = select(sck+1, &reader, 0, 0, &timer);
106    if (stat == -1) {
107      return(errno);
108    }
109    if (stat == 0) {
110      return(GMS_TIMED_OUT);
111    }
112    /* since we only wait on reader, it must have arrived */
113  }
114
115  message_data = malloc(GMS_MAX_MESSAGE_LEN);
116  stat = recv(sck, message_data, GMS_MAX_MESSAGE_LEN-1, 0);
117
118  close(sck); /* regardless of any errors... */
119
120  if(stat == -1) {
121    free(message_data);
122    return(errno);
123  }
124
125  message_data[stat] ='\0';
126  *ret_message_size = stat;
127  *ret_message = message_data;
128  return(0);
129}
Note: See TracBrowser for help on using the repository browser.