1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 2010 EDuke32 developers and contributors
4 
5 This file is part of EDuke32.
6 
7 EDuke32 is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License version 2
9 as published by the Free Software Foundation.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 
15 See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 */
21 //-------------------------------------------------------------------------
22 
23 #ifdef _WIN32
24 
25 #include "compat.h"
26 
27 #define NEED_SHELLAPI_H
28 #define NEED_WINSOCK2_H
29 #define NEED_WS2TCPIP_H
30 #include "windows_inc.h"
31 
32 #include "renderlayer.h"
33 
G_GetVersionFromWebsite(char * buffer)34 int32_t G_GetVersionFromWebsite(char *buffer)
35 {
36     static int32_t wsainitialized = 0;
37     int32_t i=0, j=0, r=0;
38     struct sockaddr_in dest_addr;
39     struct hostent *h;
40     char const *host = "www.eduke32.com";
41     char const *req = "GET http://www.eduke32.com/VERSION HTTP/1.0\r\n\r\n\r\n";
42     char *tok;
43     char tempbuf[2048],otherbuf[16],ver[16];
44     SOCKET mysock;
45     WSADATA ws;
46 
47 #ifdef _WIN32
48     if (wsainitialized == 0)
49     {
50         if (WSAStartup(0x101, &ws) == SOCKET_ERROR)
51             return 0;
52 
53         wsainitialized = 1;
54     }
55 #endif
56 
57     if ((h = gethostbyname(host)) == NULL)
58     {
59         initprintf("Couldn't resolve %s!\n", host);
60         return 0;
61     }
62 
63     dest_addr.sin_addr.s_addr = ((struct in_addr *)(h->h_addr))->s_addr;
64     dest_addr.sin_family = AF_INET;
65     dest_addr.sin_port = htons(80);
66 
67     memset(&(dest_addr.sin_zero), '\0', 8);
68 
69     mysock = socket(PF_INET, SOCK_STREAM, 0);
70 
71     if (mysock == INVALID_SOCKET)
72     {
73         WSACleanup();
74         return 0;
75     }
76 
77     initprintf("Connecting to http://%s\n",host);
78 
79     if (connect(mysock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)) == SOCKET_ERROR)
80         goto done;
81 
82     i = send(mysock, req, strlen(req), 0);
83 
84     if (i == SOCKET_ERROR)
85         goto done;
86 
87     i = recv(mysock, (char *)&tempbuf, sizeof(tempbuf), 0);
88 
89     if (i < 0)
90         goto done;
91 
92     Bmemcpy(&otherbuf, &tempbuf, sizeof(otherbuf));
93 
94     strtok(otherbuf, " ");
95 
96     if ((tok = strtok(NULL, " ")) == NULL)
97         goto done;
98 
99     if (Batol(tok) == 200)
100     {
101         for (i = 0; (unsigned)i < strlen(tempbuf); i++)  // HACK: all of this needs to die a fiery death; we just skip to the content
102         {
103             // instead of actually parsing any of the http headers
104             if (i > 4)
105                 if (tempbuf[i-1] == '\n' && tempbuf[i-2] == '\r' && tempbuf[i-3] == '\n' && tempbuf[i-4] == '\r')
106                 {
107                     while (j < 9)
108                     {
109                         ver[j] = tempbuf[i];
110                         i++, j++;
111                     }
112                     ver[j] = '\0';
113                     break;
114                 }
115         }
116 
117         if (j)
118         {
119             strcpy(buffer, ver);
120             r = 1;
121             goto done;
122         }
123     }
124 
125 done:
126     closesocket(mysock);
127     WSACleanup();
128 
129     return r;
130 }
131 #endif
132