Atrinik Client  4.0
updates.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
32 #include <global.h>
33 #include <toolkit/packet.h>
34 #include <toolkit/path.h>
35 
41 static size_t file_updates_requested = 0;
42 
48 static void file_updates_request(char *filename)
49 {
50  packet_struct *packet;
51 
53 
54  packet = packet_new(SERVER_CMD_REQUEST_UPDATE, 64, 64);
55  packet_append_string_terminated(packet, filename);
56  socket_send_packet(packet);
57 
58 }
59 
61 void socket_command_file_update(uint8_t *data, size_t len, size_t pos)
62 {
63  char filename[MAX_BUF];
64  unsigned long ucomp_len;
65  unsigned char *dest;
66  FILE *fp;
67 
68  if (file_updates_requested != 0) {
70  }
71 
72  packet_to_string(data, len, &pos, filename, sizeof(filename));
73  ucomp_len = packet_to_uint32(data, len, &pos);
74  len -= pos;
75 
76  /* Uncompress it. */
77  dest = emalloc(ucomp_len);
78  uncompress((Bytef *) dest, (uLongf *) & ucomp_len, (const Bytef *) data + pos, (uLong) len);
79  data = dest;
80  len = ucomp_len;
81 
82  fp = path_fopen(filename, "wb");
83 
84  if (!fp) {
85  LOG(BUG, "Could not open file '%s' for writing.", filename);
86  efree(dest);
87  return;
88  }
89 
90  /* Update the file. */
91  fwrite(data, 1, len, fp);
92  fclose(fp);
93  efree(dest);
94 }
95 
102 {
103  return file_updates_requested == 0;
104 }
105 
110 {
111  FILE *fp;
112  char buf[HUGE_BUF];
113 
114  /* Is the feature disabled? */
116  return;
117  }
118 
119  fp = server_file_open_name(SERVER_FILE_UPDATES);
120 
121  if (!fp) {
122  return;
123  }
124 
125  while (fgets(buf, sizeof(buf) - 1, fp)) {
126  char filename[MAX_BUF], crc_buf[MAX_BUF], *contents;
127  uint64_t size;
128  size_t st_size, numread;
129  FILE *fp2;
130  unsigned long crc;
131  struct stat sb;
132 
133  if (sscanf(buf, "%s %"PRIu64 " %s", filename, &size, crc_buf) != 3) {
134  continue;
135  }
136 
137  fp2 = path_fopen(filename, "rb");
138 
139  /* No such file? Then we'll want to update this. */
140  if (!fp2) {
141  file_updates_request(filename);
142  continue;
143  }
144 
145  fstat(fileno(fp2), &sb);
146  st_size = sb.st_size;
147  contents = emalloc(st_size);
148  numread = fread(contents, 1, st_size, fp2);
149  fclose(fp2);
150 
151  /* Get the CRC32... */
152  crc = crc32(1L, (const unsigned char FAR *) contents, numread);
153  efree(contents);
154 
155  /* If the checksum or the size doesn't match, we'll want to update it.
156  * */
157  if (crc != strtoul(crc_buf, NULL, 16) || st_size != (size_t) size) {
158  file_updates_request(filename);
159  }
160  }
161 
162  fclose(fp);
163 }
void socket_command_file_update(uint8_t *data, size_t len, size_t pos)
Definition: updates.c:61
FILE * server_file_open_name(const char *name)
Definition: server_files.c:437
static void file_updates_request(char *filename)
Definition: updates.c:48
static size_t file_updates_requested
Definition: updates.c:41
int64_t setting_get_int(int cat, int setting)
Definition: settings.c:414
void file_updates_parse(void)
Definition: updates.c:109
int file_updates_finished(void)
Definition: updates.c:101