Crossfire Server, Trunk
porting.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
23 #include <assert.h>
24 #include <ctype.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #ifdef WIN32 /* ---win32 exclude/include headers */
32 #include "process.h"
33 #else
34 #ifndef CF_MXE_CROSS_COMPILE
35 #include <sys/param.h>
36 #include <sys/stat.h>
37 #include <sys/wait.h>
38 #endif
39 #endif
40 
41 /* Has to be after above includes so we don't redefine some values */
42 #include "global.h"
43 
44 /*****************************************************************************
45  * File related functions
46  ****************************************************************************/
47 
71 FILE *tempnam_secure(const char *dir, const char *pfx, char **filename) {
72  char *tempname = NULL;
73  int fd;
74  int i;
75  FILE *file = NULL;
76  const int maxretry = 10;
77 
78  /* Limit number of retries to MAXRETRY */
79  for (i = 0; i < maxretry; i++) {
80  tempname = tempnam(dir, pfx);
81  if (!tempname)
82  return NULL;
83 
84  fd = open(tempname, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
85  if (fd != -1)
86  break;
87  if (errno == EEXIST)
88  LOG(llevError, "Created file detected in tempnam_secure. Someone hoping for a race condition?\n");
89  free(tempname);
90  }
91  /* Check that we successfully got an fd. */
92  if (fd == -1)
93  return NULL;
94 
95  file = fdopen(fd, "w+");
96  if (!file) {
97  LOG(llevError, "fdopen() failed in tempnam_secure()!\n");
98  free(tempname);
99  return NULL;
100  }
101 
102  *filename = tempname;
103  return file;
104 }
105 
117 void remove_directory(const char *path) {
118  DIR *dirp;
119  char buf[strlen(path) + sizeof(dirent::d_name) + 1];
120  struct stat statbuf;
121  int status;
122 
123  if ((dirp = opendir(path)) != NULL) {
124  struct dirent *de;
125 
126  for (de = readdir(dirp); de; de = readdir(dirp)) {
127  /* Don't remove '.' or '..' In theory we should do a better
128  * check for .., but the directories we are removing are fairly
129  * limited and should not have dot files in them.
130  */
131  if (de->d_name[0] == '.')
132  continue;
133 
134  /* Linux actually has a type field in the dirent structure,
135  * but that is not portable - stat should be portable
136  */
137  status = stat(de->d_name, &statbuf);
138  if ((status != -1) && (S_ISDIR(statbuf.st_mode))) {
139  snprintf(buf, sizeof(buf), "%s/%s", path, de->d_name);
141  continue;
142  }
143  snprintf(buf, sizeof(buf), "%s/%s", path, de->d_name);
144  if (unlink(buf)) {
145  LOG(llevError, "Unable to remove %s\n", path);
146  }
147  }
148  closedir(dirp);
149  }
150  if (rmdir(path)) {
151  LOG(llevError, "Unable to remove directory %s\n", path);
152  }
153 }
154 
164 void make_path_to_file(const char *filename) {
165  char buf[MAX_BUF], *cp = buf;
166  struct stat statbuf;
167 
168  if (!filename || !*filename)
169  return;
170 
171  safe_strncpy(buf, filename, sizeof(buf));
172  while ((cp = strchr(cp+1, (int)'/'))) {
173  *cp = '\0';
174  if (stat(buf, &statbuf) || !S_ISDIR(statbuf.st_mode)) {
175  LOG(llevDebug, "Was not dir: %s\n", buf);
176 #ifdef WIN32
177  if (mkdir(buf)) {
178 #else
179  if (mkdir(buf, SAVE_DIR_MODE)) {
180 #endif
181  LOG(llevError, "Cannot mkdir %s: %s\n", buf, strerror(errno));
182  return;
183  }
184  }
185  *cp = '/';
186  }
187 }
188 
202 void safe_strcat(char *dest, const char *orig, size_t *curlen, size_t maxlen) {
203  assert(curlen != NULL);
204  assert(*curlen < maxlen);
205 #ifdef HAVE_STRLCAT
206  *curlen = strlcat(dest, orig, maxlen);
207 #else
208  if (*curlen == (maxlen-1))
209  return;
210  strncpy(dest+*curlen, orig, maxlen-*curlen-1);
211  dest[maxlen-1] = 0;
212  *curlen += strlen(orig);
213 #endif
214  if (*curlen > (maxlen-1))
215  *curlen = maxlen-1;
216 }
217 
218 #ifndef HAVE_STRLCPY
219 
222 size_t strlcpy(char *dst, const char *src, size_t size) {
223  strncpy(dst, src, size - 1);
224  dst[size - 1] = '\0';
225  return strlen(src);
226 }
227 #endif
228 
229 #ifdef WIN32
230 #include <string.h>
231 #include <ctype.h>
232 const char *strcasestr(const char *s, const char *find)
233 {
234  char c, sc;
235  size_t len;
236 
237  if ((c = *find++) != 0) {
238  c = tolower((unsigned char) c);
239  len = strlen(find);
240  do {
241  do {
242  if ((sc = *s++) == 0)
243  return (NULL);
244  }
245  while ((char) tolower((unsigned char) sc) != c);
246  }
247  while (strncasecmp(s, find, len) != 0);
248  s--;
249  }
250  return s;
251 }
252 #endif
S_IWUSR
#define S_IWUSR
Definition: win32.h:47
global.h
safe_strncpy
#define safe_strncpy
Definition: compat.h:27
llevError
@ llevError
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:58
safe_strcat
void safe_strcat(char *dest, const char *orig, size_t *curlen, size_t maxlen)
Definition: porting.cpp:202
CFBank.open
def open()
Definition: CFBank.py:69
c
static event_registration c
Definition: citylife.cpp:425
mad_mage_user.file
file
Definition: mad_mage_user.py:15
tolower
#define tolower(C)
Definition: c_new.cpp:30
SAVE_DIR_MODE
#define SAVE_DIR_MODE
Definition: config.h:564
npc_dialog.filename
filename
Definition: npc_dialog.py:99
buf
StringBuffer * buf
Definition: readable.cpp:1565
remove_directory
void remove_directory(const char *path)
Definition: porting.cpp:117
opendir
DIR * opendir(const char *)
readdir
struct dirent * readdir(DIR *)
python_init.path
path
Definition: python_init.py:8
strcasestr
const char * strcasestr(const char *s, const char *find)
MAX_BUF
#define MAX_BUF
Definition: define.h:35
strlcpy
size_t strlcpy(char *dst, const char *src, size_t size)
Definition: porting.cpp:222
convert.dest
dest
Definition: convert.py:25
tempnam_secure
FILE * tempnam_secure(const char *dir, const char *pfx, char **filename)
Definition: porting.cpp:71
S_IRUSR
#define S_IRUSR
Definition: win32.h:56
make_path_to_file
void make_path_to_file(const char *filename)
Definition: porting.cpp:164
closedir
int closedir(DIR *)
takeitem.status
status
Definition: takeitem.py:38
llevDebug
@ llevDebug
Definition: logger.h:13