Crossfire Server, Trunk
porting.c
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 #include <sys/param.h>
35 #include <sys/stat.h>
36 #include <sys/wait.h>
37 #endif
38 
39 /* Has to be after above includes so we don't redefine some values */
40 #include "global.h"
41 
42 /*****************************************************************************
43  * File related functions
44  ****************************************************************************/
45 
69 FILE *tempnam_secure(const char *dir, const char *pfx, char **filename) {
70  char *tempname = NULL;
71  int fd;
72  int i;
73  FILE *file = NULL;
74  const int maxretry = 10;
75 
76  /* Limit number of retries to MAXRETRY */
77  for (i = 0; i < maxretry; i++) {
78  tempname = tempnam(dir, pfx);
79  if (!tempname)
80  return NULL;
81 
82  fd = open(tempname, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
83  if (fd != -1)
84  break;
85  if (errno == EEXIST)
86  LOG(llevError, "Created file detected in tempnam_secure. Someone hoping for a race condition?\n");
87  free(tempname);
88  }
89  /* Check that we successfully got an fd. */
90  if (fd == -1)
91  return NULL;
92 
93  file = fdopen(fd, "w+");
94  if (!file) {
95  LOG(llevError, "fdopen() failed in tempnam_secure()!\n");
96  free(tempname);
97  return NULL;
98  }
99 
100  *filename = tempname;
101  return file;
102 }
103 
115 void remove_directory(const char *path) {
116  DIR *dirp;
117  char buf[MAX_BUF];
118  struct stat statbuf;
119  int status;
120 
121  if ((dirp = opendir(path)) != NULL) {
122  struct dirent *de;
123 
124  for (de = readdir(dirp); de; de = readdir(dirp)) {
125  /* Don't remove '.' or '..' In theory we should do a better
126  * check for .., but the directories we are removing are fairly
127  * limited and should not have dot files in them.
128  */
129  if (de->d_name[0] == '.')
130  continue;
131 
132  /* Linux actually has a type field in the dirent structure,
133  * but that is not portable - stat should be portable
134  */
135  status = stat(de->d_name, &statbuf);
136  if ((status != -1) && (S_ISDIR(statbuf.st_mode))) {
137  snprintf(buf, sizeof(buf), "%s/%s", path, de->d_name);
139  continue;
140  }
141  snprintf(buf, sizeof(buf), "%s/%s", path, de->d_name);
142  if (unlink(buf)) {
143  LOG(llevError, "Unable to remove %s\n", path);
144  }
145  }
146  closedir(dirp);
147  }
148  if (rmdir(path)) {
149  LOG(llevError, "Unable to remove directory %s\n", path);
150  }
151 }
152 
162 void make_path_to_file(const char *filename) {
163  char buf[MAX_BUF], *cp = buf;
164  struct stat statbuf;
165 
166  if (!filename || !*filename)
167  return;
168 
169  safe_strncpy(buf, filename, sizeof(buf));
170  while ((cp = strchr(cp+1, (int)'/'))) {
171  *cp = '\0';
172  if (stat(buf, &statbuf) || !S_ISDIR(statbuf.st_mode)) {
173  LOG(llevDebug, "Was not dir: %s\n", buf);
174 #ifdef WIN32
175  if (mkdir(buf)) {
176 #else
177  if (mkdir(buf, SAVE_DIR_MODE)) {
178 #endif
179  LOG(llevError, "Cannot mkdir %s: %s\n", buf, strerror(errno));
180  return;
181  }
182  }
183  *cp = '/';
184  }
185 }
186 
200 void safe_strcat(char *dest, const char *orig, size_t *curlen, size_t maxlen) {
201  assert(curlen != NULL);
202  assert(*curlen < maxlen);
203 #ifdef HAVE_STRLCAT
204  *curlen = strlcat(dest, orig, maxlen);
205 #else
206  if (*curlen == (maxlen-1))
207  return;
208  strncpy(dest+*curlen, orig, maxlen-*curlen-1);
209  dest[maxlen-1] = 0;
210  *curlen += strlen(orig);
211 #endif
212  if (*curlen > (maxlen-1))
213  *curlen = maxlen-1;
214 }
215 
216 #ifndef HAVE_STRLCPY
217 
220 size_t strlcpy(char *dst, const char *src, size_t size) {
221  strncpy(dst, src, size - 1);
222  dst[size - 1] = '\0';
223  return strlen(src);
224 }
225 #endif
226 
227 #ifdef WIN32
228 #include <string.h>
229 #include <ctype.h>
230 const char *strcasestr(const char *s, const char *find)
231 {
232  char c, sc;
233  size_t len;
234 
235  if ((c = *find++) != 0) {
236  c = tolower((unsigned char) c);
237  len = strlen(find);
238  do {
239  do {
240  if ((sc = *s++) == 0)
241  return (NULL);
242  }
243  while ((char) tolower((unsigned char) sc) != c);
244  }
245  while (strncasecmp(s, find, len) != 0);
246  s--;
247  }
248  return s;
249 }
250 #endif
S_IWUSR
#define S_IWUSR
Definition: win32.h:47
global.h
tolower
#define tolower(C)
Definition: c_new.c:30
safe_strncpy
#define safe_strncpy
Definition: compat.h:27
llevError
@ llevError
Definition: logger.h:11
CFBank.open
def open()
Definition: CFBank.py:70
c
static event_registration c
Definition: citylife.cpp:425
python_event.path
path
Definition: python_event.py:11
mad_mage_user.file
file
Definition: mad_mage_user.py:15
SAVE_DIR_MODE
#define SAVE_DIR_MODE
Definition: config.h:556
npc_dialog.filename
filename
Definition: npc_dialog.py:99
make_path_to_file
void make_path_to_file(const char *filename)
Definition: porting.c:162
opendir
DIR * opendir(const char *)
readdir
struct dirent * readdir(DIR *)
tempnam_secure
FILE * tempnam_secure(const char *dir, const char *pfx, char **filename)
Definition: porting.c:69
strcasestr
const char * strcasestr(const char *s, const char *find)
strlcpy
size_t strlcpy(char *dst, const char *src, size_t size)
Definition: porting.c:220
MAX_BUF
#define MAX_BUF
Definition: define.h:35
remove_directory
void remove_directory(const char *path)
Definition: porting.c:115
dirent
#define dirent
Definition: xdir.h:12
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
convert.dest
dest
Definition: convert.py:25
buf
StringBuffer * buf
Definition: readable.c:1606
S_IRUSR
#define S_IRUSR
Definition: win32.h:56
closedir
int closedir(DIR *)
takeitem.status
status
Definition: takeitem.py:35
safe_strcat
void safe_strcat(char *dest, const char *orig, size_t *curlen, size_t maxlen)
Definition: porting.c:200
llevDebug
@ llevDebug
Definition: logger.h:13