File: meta.c

package info (click to toggle)
freeciv 1.9.0-2.1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 11,004 kB
  • ctags: 6,284
  • sloc: ansic: 65,037; makefile: 634; sh: 418; sed: 93
file content (196 lines) | stat: -rw-r--r-- 5,209 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/********************************************************************** 
 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
***********************************************************************/

/*
 * This bit sends "I'm here" packages to the metaserver.
 */

/*
The desc block should look like this:
1) GameName   - Freeciv
2) Version    - 1.5.0
3) State      - Running(Open for new players)
4) Host       - Empty
5) Port       - 5555
6) NoPlayers  - 3
7) InfoText   - Warfare - starts at 8:00 EMT

The info string should look like this:
  GameSpecific text block
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <string.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif 

#ifdef HAVE_OPENTRANSPORT
#include <OpenTransport.h>
#include <OpenTptInternet.h>
#endif

#include "fcintl.h"
#include "packets.h"
#include "console.h"
#include "meta.h"

#ifndef INADDR_NONE
#define INADDR_NONE     0xffffffff
#endif

#ifdef GENERATING_MAC    /* mac network globals */
TEndpointInfo meta_info;
EndpointRef meta_ep;
InetAddress serv_addr;
#else /* Unix network globals */
static int			sockfd,n,in_size;
static struct sockaddr_in	cli_addr,serv_addr;
#endif /* end network global selector */

extern char metaserver_addr[];

int send_to_metaserver(char *desc, char *info)
{
  unsigned char buffer[MAX_LEN_PACKET], *cptr;
#ifdef GENERATING_MAC       /* mac alternate networking */
  struct TUnitData xmit;
  OSStatus err;
  xmit.udata.maxlen = MAX_LEN_PACKET;
  xmit.udata.buf=buffer;
#else  
  if(sockfd==0)
    return 0;
#endif
  cptr=put_uint16(buffer+2,  PACKET_UDP_PCKT);
  cptr=put_string(cptr, desc);
  cptr=put_string(cptr, info);
  put_uint16(buffer, cptr-buffer);
#ifdef GENERATING_MAC  /* mac networking */
  xmit.udata.len=strlen((const char *)buffer);
  err=OTSndUData(meta_ep, &xmit);
#else
  n=sendto(sockfd, buffer, cptr-buffer,0, 
	   (struct sockaddr *) &serv_addr, sizeof(serv_addr) );
#endif
  return 1;
}

void server_close_udp(void)
{
#ifdef GENERATING_MAC  /* mac networking */
  OTUnbind(meta_ep);
#else
  close(sockfd);
#endif
}

void server_open_udp(void)
{
  char *servername=metaserver_addr;
  int bad;
#ifdef GENERATING_MAC  /* mac networking */
  OSStatus err1;
  OSErr err2;
  InetSvcRef ref=OTOpenInternetServices(kDefaultInternetServicesPath, 0, &err1);
  InetHostInfo hinfo;
#else
  struct hostent *hp;
  u_int bin;
#endif
  
  /*
   * Fill in the structure "serv_addr" with the address of the
   * server that we want to connect with, checks if server address 
   * is valid, both decimal-dotted and name.
   */
#ifdef GENERATING_MAC  /* mac networking */
  if (err1 == 0)
  {
    err1=OTInetStringToAddress(ref, servername,&hinfo);
    serv_addr.fHost=hinfo.addrs[0];
    bad = ((serv_addr.fHost == 0) || (err1 != 0));
  } else
    bad=true;
#else
  in_size = sizeof(inet_addr(servername));
  bin = inet_addr(servername);
  bad = (((hp = gethostbyaddr((char *) &bin,in_size,AF_INET)) == NULL)
	 && ((hp = gethostbyname(servername)) == NULL));
#endif
  if (bad) {
    perror(_("Metaserver: address error"));
    con_puts(C_METAERROR, _("Not reporting to the metaserver in this game."));
    con_flush();
    return;
  }
  /*
   * Open a UDP socket (an Internet datagram socket).
   */
#ifdef GENERATING_MAC  /* mac networking */
  meta_ep=OTOpenEndpoint(OTCreateConfiguration(kUDPName), 0, &meta_info, &err1);
  bad = (err1 != 0);
#else  
  memset(&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sin_family      = AF_INET;
  serv_addr.sin_port        = htons(METASERVER_PORT);
  memcpy(&serv_addr.sin_addr, hp->h_addr, hp->h_length); 
  bad = ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0);
#endif
  if (bad) {
    perror(_("Metaserver: can't open datagram socket"));
    con_puts(C_METAERROR, _("Not reporting to the metaserver in this game."));
    con_flush();
    return;
  }
  /*
   * Bind any local address for us.
   */
  
#ifdef GENERATING_MAC  /* mac networking */
  err1=OTBind(meta_ep, NULL, NULL);
  bad = (err1 != 0);
#else
  memset( &cli_addr, 0, sizeof(cli_addr));	/* zero out */
  cli_addr.sin_family      = AF_INET;
  cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  cli_addr.sin_port        = htons(0);
  bad = (bind(sockfd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0);
#endif
  if (bad) {
    perror(_("Metaserver: can't bind local address"));
    con_puts(C_METAERROR, _("Not reporting to the metaserver in this game."));
    con_flush();
    return;
  }
}