Atrinik Server  4.0
resources.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/string.h>
34 #include <toolkit/packet.h>
35 #include <resources.h>
36 
40 static resource_t *resources = NULL;
41 
50 static void
51 resources_traverse (DIR *dir, const char *path)
52 {
53  HARD_ASSERT(dir != NULL);
54  HARD_ASSERT(path != NULL);
55 
56  struct dirent *d;
57  while ((d = readdir(dir)) != NULL) {
58  if (d->d_name[0] == '.') {
59  continue;
60  }
61 
62  char path_curr[HUGE_BUF];
63  snprintf(VS(path_curr), "%s/%s", path, d->d_name);
64  DIR *dir_curr = opendir(path_curr);
65  if (dir_curr == NULL) {
66  if (errno != ENOTDIR) {
67  LOG(ERROR, "Failed to open %s: %s (%d)",
68  path_curr, strerror(errno), errno);
69  exit(1);
70  }
71  } else {
72  resources_traverse(dir_curr, path_curr);
73  continue;
74  }
75 
76  SOFT_ASSERT(string_startswith(path_curr, settings.resourcespath),
77  "File path doesn't start with the resource path");
78 
79  /* Plus one for the forward slash */
80  char *cp = string_sub(path_curr, strlen(settings.resourcespath) + 1, 0);
81 
82  resource_t *resource = ecalloc(1, sizeof(*resource));
83  resource->name = cp;
84  HASH_ADD_KEYPTR(hh,
85  resources,
86  resource->name,
87  strlen(resource->name),
88  resource);
89 
90  SHA512_CTX ctx;
91  SOFT_ASSERT(SHA512_Init(&ctx) == 1, "SHA512_Init() failed");
92 
93  FILE *fp = fopen(path_curr, "rb");
94  if (fp == NULL) {
95  LOG(ERROR, "Failed to open %s for reading: %s (%d)",
96  path_curr, strerror(errno), errno);
97  exit(1);
98  }
99 
100  size_t num_read;
101  unsigned char buffer[1024 * 64];
102  while ((num_read = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
103  SOFT_ASSERT(SHA512_Update(&ctx, buffer, num_read) == 1,
104  "SHA512_Update() failed");
105  }
106 
107  fclose(fp);
108  SOFT_ASSERT(SHA512_Final(resource->md, &ctx) == 1,
109  "SHA512_Final() failed");
110 
111  char key[sizeof(resource->md) * 2 + 1];
112  SOFT_ASSERT(string_tohex(VS(resource->md),
113  VS(key),
114  false) == sizeof(key) - 1,
115  "string_tohex failed");
116  string_tolower(key);
117  }
118 
119  closedir(dir);
120 }
121 
125 void
127 {
128  DIR *dir = opendir(settings.resourcespath);
129  if (dir == NULL) {
130  LOG(INFO,
131  "Resources directory cannot be accessed, resource files will "
132  "not be available.");
133  return;
134  }
135 
137 }
138 
142 void
144 {
145  resource_t *resource, *tmp;
146  HASH_ITER(hh, resources, resource, tmp) {
147  HASH_DEL(resources, resource);
148  efree(resource->name);
149  efree(resource);
150  }
151 }
152 
161 resource_t *
162 resources_find (const char *name)
163 {
164  if (name == NULL) {
165  return NULL;
166  }
167 
169  HASH_FIND_STR(resources, name, resource);
170  return resource;
171 }
172 
181 void
183  socket_struct *ns)
184 {
185  HARD_ASSERT(resource != NULL);
186  HARD_ASSERT(ns != NULL);
187 
188  packet_struct *packet = packet_new(CLIENT_CMD_RESOURCE, 256, 0);
189  packet_append_string_terminated(packet, resource->name);
190  packet_append_data_len(packet, VS(resource->md));
191  socket_send_packet(ns, packet);
192 }
resource_t * resources_find(const char *name)
Definition: resources.c:162
unsigned char md[SHA512_DIGEST_LENGTH]
SHA512 message digest.
Definition: resources.h:43
char resourcespath[MAX_BUF]
Definition: global.h:358
void resources_deinit(void)
Definition: resources.c:143
static void resources_traverse(DIR *dir, const char *path)
Definition: resources.c:51
static resource_t * resources
Definition: resources.c:40
struct settings_struct settings
Definition: init.c:55
char * name
Name identifier for the resource.
Definition: resources.h:42
void resources_init(void)
Definition: resources.c:126
void resources_send(resource_t *resource, socket_struct *ns)
Definition: resources.c:182