ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/porting.C
(Generate patch)

Comparing deliantra/server/common/porting.C (file contents):
Revision 1.2 by root, Tue Aug 29 08:01:35 2006 UTC vs.
Revision 1.8 by pippijn, Sat Dec 9 17:28:37 2006 UTC

1/*
2 * static char *rcsid_porting_c =
3 * "$Id: porting.C,v 1.2 2006/08/29 08:01:35 root Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
9 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
21 16
22 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 20
26 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
27*/ 22*/
28 23
29/* This file contains various functions that are not really unique for 24/* This file contains various functions that are not really unique for
30 * crossfire, but rather provides what should be standard functions 25 * crossfire, but rather provides what should be standard functions
31 * for systems that do not have them. In this way, most of the 26 * for systems that do not have them. In this way, most of the
32 * nasty system dependent stuff is contained here, with the program 27 * nasty system dependent stuff is contained here, with the program
33 * calling these functions. 28 * calling these functions.
34 */ 29 */
35 30
36 31
37#ifdef WIN32 /* ---win32 exclude/include headers */ 32#ifdef WIN32 /* ---win32 exclude/include headers */
38#include "process.h" 33# include "process.h"
39#define pid_t int /* we include it non global, because there is a redefinition in python.h */ 34# define pid_t int /* we include it non global, because there is a redefinition in python.h */
40#else 35#else
41#include <ctype.h> 36# include <ctype.h>
42#include <sys/stat.h> 37# include <sys/stat.h>
43#include <sys/wait.h> 38# include <sys/wait.h>
44 39
45#include <sys/param.h> 40# include <sys/param.h>
46#include <stdio.h> 41# include <stdio.h>
47 42
48/* Need to pull in the HAVE_... values somehow */ 43/* Need to pull in the HAVE_... values somehow */
44
49/* win32 reminder: always put this in a ifndef win32 block */ 45/* win32 reminder: always put this in a ifndef win32 block */
50#include <autoconf.h> 46# include <autoconf.h>
51#endif 47#endif
52 48
53 49
54#ifdef HAVE_STDLIB_H 50#ifdef HAVE_STDLIB_H
55#include <stdlib.h> 51# include <stdlib.h>
56#endif 52#endif
57 53
58#ifdef HAVE_UNISTD_H 54#ifdef HAVE_UNISTD_H
59#include <unistd.h> 55# include <unistd.h>
60#endif 56#endif
61 57
62#include <stdarg.h> 58#include <stdarg.h>
59
63/* Has to be after above includes so we don't redefine some values */ 60/* Has to be after above includes so we don't redefine some values */
64#include "global.h" 61#include "global.h"
65 62
66static unsigned int curtmp = 0; 63static unsigned int curtmp = 0;
67
68/* This is a list of the suffix, uncompress and compress functions. Thus,
69 * if you have some other compress program you want to use, the only thing
70 * that needs to be done is to extended this.
71 * The first entry must be NULL - this is what is used for non
72 * compressed files.
73 */
74EXTERN char *uncomp[NROF_COMPRESS_METHODS][3] = {
75 {NULL, NULL, NULL},
76 {".Z", UNCOMPRESS, COMPRESS},
77 {".gz", GUNZIP, GZIP},
78 {".bz2", BUNZIP, BZIP}
79};
80 64
81/***************************************************************************** 65/*****************************************************************************
82 * File related functions 66 * File related functions
83 ****************************************************************************/ 67 ****************************************************************************/
84 68
85/* 69/*
86 * A replacement for the tempnam() function since it's not defined 70 * A replacement for the tempnam() function since it's not defined
87 * at some unix variants. 71 * at some unix variants.
88 */ 72 */
89 73
74char *
90char *tempnam_local(const char *dir, const char *pfx) 75tempnam_local (const char *dir, const char *pfx)
91{ 76{
92 char *name; 77 char *name;
93 pid_t pid=getpid(); 78 pid_t pid = getpid ();
94 79
95/* HURD does not have a hard limit, but we do */ 80/* HURD does not have a hard limit, but we do */
96#ifndef MAXPATHLEN 81#ifndef MAXPATHLEN
97#define MAXPATHLEN 4096 82# define MAXPATHLEN 4096
98#endif 83#endif
99 84
100 if (!(name = (char *) malloc(MAXPATHLEN))) 85 if (!(name = (char *) malloc (MAXPATHLEN)))
101 return(NULL); 86 return (NULL);
102 87
103 if (!pfx) 88 if (!pfx)
104 pfx = "cftmp."; 89 pfx = "cftmp.";
105 90
106 /* This is a pretty simple method - put the pid as a hex digit and 91 /* This is a pretty simple method - put the pid as a hex digit and
107 * just keep incrementing the last digit. Check to see if the file 92 * just keep incrementing the last digit. Check to see if the file
108 * already exists - if so, we'll just keep looking - eventually we should 93 * already exists - if so, we'll just keep looking - eventually we should
109 * find one that is free. 94 * find one that is free.
110 */ 95 */
111 if (dir!=NULL) { 96 if (dir != NULL)
97 {
98 do
112 do { 99 {
113#ifdef HAVE_SNPRINTF 100#ifdef HAVE_SNPRINTF
114 (void)snprintf(name, MAXPATHLEN, "%s/%s%hx.%d", dir, pfx, pid, curtmp); 101 (void) snprintf (name, MAXPATHLEN, "%s/%s%hx.%d", dir, pfx, pid, curtmp);
115#else 102#else
116 (void)sprintf(name,"%s/%s%hx%d", dir, pfx, pid, curtmp); 103 (void) sprintf (name, "%s/%s%hx%d", dir, pfx, pid, curtmp);
117#endif 104#endif
118 curtmp++; 105 curtmp++;
106 }
119 } while (access(name, F_OK)!=-1); 107 while (access (name, F_OK) != -1);
120 return(name); 108 return (name);
121 } 109 }
122 return(NULL); 110 return (NULL);
123} 111}
124 112
125 113
126 114
127/* This function removes everything in the directory. */ 115/* This function removes everything in the directory. */
116void
128void remove_directory(const char *path) 117remove_directory (const char *path)
129{ 118{
130 DIR *dirp; 119 DIR *dirp;
131 char buf[MAX_BUF]; 120 char buf[MAX_BUF];
132 struct stat statbuf; 121 struct stat statbuf;
133 int status; 122 int status;
134 123
135 if ((dirp=opendir(path))!=NULL) { 124 if ((dirp = opendir (path)) != NULL)
125 {
136 struct dirent *de; 126 struct dirent *de;
137 127
138 for (de=readdir(dirp); de; de = readdir(dirp)) { 128 for (de = readdir (dirp); de; de = readdir (dirp))
129 {
139 /* Don't remove '.' or '..' In theory we should do a better 130 /* Don't remove '.' or '..' In theory we should do a better
140 * check for .., but the directories we are removing are fairly 131 * check for .., but the directories we are removing are fairly
141 * limited and should not have dot files in them. 132 * limited and should not have dot files in them.
142 */ 133 */
143 if (de->d_name[0] == '.') continue; 134 if (de->d_name[0] == '.')
135 continue;
144 136
145 /* Linux actually has a type field in the dirent structure, 137 /* Linux actually has a type field in the dirent structure,
146 * but that is not portable - stat should be portable 138 * but that is not portable - stat should be portable
147 */ 139 */
148 status=stat(de->d_name, &statbuf); 140 status = stat (de->d_name, &statbuf);
149 if ((status!=-1) && (S_ISDIR(statbuf.st_mode))) { 141 if ((status != -1) && (S_ISDIR (statbuf.st_mode)))
142 {
150 sprintf(buf,"%s/%s", path, de->d_name); 143 sprintf (buf, "%s/%s", path, de->d_name);
151 remove_directory(buf); 144 remove_directory (buf);
152 continue; 145 continue;
153 } 146 }
154 sprintf(buf,"%s/%s", path, de->d_name); 147 sprintf (buf, "%s/%s", path, de->d_name);
155 if (unlink(buf)) { 148 if (unlink (buf))
149 {
156 LOG(llevError,"Unable to remove directory %s\n", path); 150 LOG (llevError, "Unable to remove directory %s\n", path);
157 } 151 }
158 } 152 }
159 closedir(dirp); 153 closedir (dirp);
160 } 154 }
161 if (rmdir(path)) { 155 if (rmdir (path))
156 {
162 LOG(llevError,"Unable to remove directory %s\n", path); 157 LOG (llevError, "Unable to remove directory %s\n", path);
163 } 158 }
164} 159}
165 160
166#if defined(sgi) 161#if defined(sgi)
167 162
168#include <stdio.h> 163# include <stdio.h>
169#include <stdlib.h> 164# include <stdlib.h>
170#include <string.h> 165# include <string.h>
171 166
172#define popen fixed_popen 167# define popen fixed_popen
173 168
169FILE *
174FILE *popen_local(const char *command, const char *type) 170popen_local (const char *command, const char *type)
175{ 171{
176 int fd[2]; 172 int fd[2];
177 int pd; 173 int pd;
178 FILE *ret; 174 FILE *ret;
175
179 if (!strcmp(type,"r")) 176 if (!strcmp (type, "r"))
177 pd = STDOUT_FILENO;
178 else if (!strcmp (type, "w"))
179 pd = STDIN_FILENO;
180 else
181 return NULL;
182
183 if (pipe (fd) != -1)
184 {
185 switch (fork ())
180 { 186 {
181 pd=STDOUT_FILENO; 187 case -1:
188 close (fd[0]);
189 close (fd[1]);
190 break;
191 case 0:
192 close (fd[0]);
193 if ((fd[1] == pd) || (dup2 (fd[1], pd) == pd))
194 {
195 if (fd[1] != pd)
196 {
197 close (fd[1]);
198 }
199 execl ("/bin/sh", "sh", "-c", command, NULL);
200 close (pd);
201 }
202 _exit (1);
203 break;
204 default:
205 close (fd[1]);
206 if (ret = fdopen (fd[0], type))
207 {
208 return ret;
209 }
210 close (fd[0]);
211 break;
182 } 212 }
183 else if (!strcmp(type,"w")) 213 }
184 {
185 pd=STDIN_FILENO;
186 }
187 else
188 {
189 return NULL;
190 }
191 if (pipe(fd)!=-1)
192 {
193 switch (fork())
194 {
195 case -1:
196 close(fd[0]);
197 close(fd[1]);
198 break;
199 case 0:
200 close(fd[0]);
201 if ((fd[1]==pd)||(dup2(fd[1],pd)==pd))
202 {
203 if (fd[1]!=pd)
204 {
205 close(fd[1]);
206 }
207 execl("/bin/sh","sh","-c",command,NULL);
208 close(pd);
209 }
210 exit(1);
211 break;
212 default:
213 close(fd[1]);
214 if (ret=fdopen(fd[0],type))
215 {
216 return ret;
217 }
218 close(fd[0]);
219 break;
220 }
221 }
222 return NULL; 214 return NULL;
223} 215}
224 216
225#endif /* defined(sgi) */ 217#endif /* defined(sgi) */
226 218
227 219
228/***************************************************************************** 220/*****************************************************************************
229 * String related function 221 * String related function
230 ****************************************************************************/ 222 ****************************************************************************/
231 223
232
233
234/* 224/*
235 * A replacement of strdup(), since it's not defined at some 225 * A replacement of strdup(), since it's not defined at some
236 * unix variants. 226 * unix variants.
237 */ 227 */
228char *
238char *strdup_local(const char *str) { 229strdup_local (const char *str)
230{
239 char *c=(char *)malloc(sizeof(char)*(strlen(str)+1)); 231 char *c = (char *) malloc (sizeof (char) * (strlen (str) + 1));
232
240 strcpy(c,str); 233 strcpy (c, str);
241 return c; 234 return c;
242} 235}
243 236
244 237
245#define DIGIT(x) (isdigit(x) ? (x) - '0' : \ 238#define DIGIT(x) (isdigit(x) ? (x) - '0' : \
246islower (x) ? (x) + 10 - 'a' : (x) + 10 - 'A') 239islower (x) ? (x) + 10 - 'a' : (x) + 10 - 'A')
247#define MBASE ('z' - 'a' + 1 + 10) 240#define MBASE ('z' - 'a' + 1 + 10)
248 241
249/* This seems to be lacking on some system */ 242/* This seems to be lacking on some system */
250#if !defined(HAVE_STRNCASECMP) 243#if !defined(HAVE_STRNCASECMP)
244int
251int strncasecmp(const char *s1, const char *s2, int n) 245strncasecmp (const char *s1, const char *s2, int n)
252{ 246{
253 register int c1, c2; 247 register int c1, c2;
254 248
255 while (*s1 && *s2 && n) { 249 while (*s1 && *s2 && n)
250 {
256 c1 = tolower(*s1); 251 c1 = tolower (*s1);
257 c2 = tolower(*s2); 252 c2 = tolower (*s2);
258 if (c1 != c2) 253 if (c1 != c2)
259 return (c1 - c2); 254 return (c1 - c2);
260 s1++; 255 s1++;
261 s2++; 256 s2++;
262 n--; 257 n--;
263 } 258 }
264 if (!n) 259 if (!n)
265 return(0); 260 return (0);
266 return (int) (*s1 - *s2); 261 return (int) (*s1 - *s2);
267} 262}
268#endif 263#endif
269 264
270#if !defined(HAVE_STRCASECMP) 265#if !defined(HAVE_STRCASECMP)
266int
271int strcasecmp(const char *s1, const char*s2) 267strcasecmp (const char *s1, const char *s2)
272{ 268{
273 register int c1, c2; 269 register int c1, c2;
274 270
275 while (*s1 && *s2) { 271 while (*s1 && *s2)
272 {
276 c1 = tolower(*s1); 273 c1 = tolower (*s1);
277 c2 = tolower(*s2); 274 c2 = tolower (*s2);
278 if (c1 != c2) 275 if (c1 != c2)
279 return (c1 - c2); 276 return (c1 - c2);
280 s1++; 277 s1++;
281 s2++; 278 s2++;
282 } 279 }
283 if (*s1=='\0' && *s2=='\0') 280 if (*s1 == '\0' && *s2 == '\0')
284 return 0; 281 return 0;
285 return (int) (*s1 - *s2); 282 return (int) (*s1 - *s2);
286} 283}
287#endif 284#endif
288 285
286char *
289char *strcasestr_local(const char *s, const char *find) 287strcasestr_local (const char *s, const char *find)
290{ 288{
291 char c, sc; 289 char c, sc;
292 size_t len; 290 size_t len;
293 291
294 if ((c = *find++) != 0) { 292 if ((c = *find++) != 0)
293 {
295 c = tolower(c); 294 c = tolower (c);
296 len = strlen(find); 295 len = strlen (find);
296 do
297 do { 297 {
298 do
298 do { 299 {
299 if ((sc = *s++) == 0) 300 if ((sc = *s++) == 0)
300 return NULL; 301 return NULL;
302 }
301 } while (tolower(sc) != c); 303 while (tolower (sc) != c);
304 }
302 } while (strncasecmp(s, find, len) != 0); 305 while (strncasecmp (s, find, len) != 0);
303 s--; 306 s--;
304 } 307 }
305 return (char *)s; 308 return (char *) s;
306} 309}
307 310
308#if !defined(HAVE_SNPRINTF) 311#if !defined(HAVE_SNPRINTF)
309 312
313int
310int snprintf(char *dest, int max, const char *format, ...) 314snprintf (char *dest, int max, const char *format, ...)
311{ 315{
312 va_list var; 316 va_list var;
313 int ret; 317 int ret;
314 318
315 va_start(var, format); 319 va_start (var, format);
316 ret = vsprintf(dest, format, var); 320 ret = vsprintf (dest, format, var);
317 va_end(var); 321 va_end (var);
318 if (ret > max) abort(); 322 if (ret > max)
323 abort ();
319 324
320 return ret; 325 return ret;
321} 326}
322#endif 327#endif
323 328
324
325/* This takes an err number and returns a string with a description of
326 * the error.
327 */
328char *strerror_local(int errnum)
329{
330#if defined(HAVE_STRERROR)
331 return(strerror(errnum));
332#else
333 return("strerror_local not implemented");
334#endif
335}
336 329
337/* 330/*
338 * Based on (n+1)^2 = n^2 + 2n + 1 331 * Based on (n+1)^2 = n^2 + 2n + 1
339 * given that 1^2 = 1, then 332 * given that 1^2 = 1, then
340 * 2^2 = 1 + (2 + 1) = 1 + 3 = 4 333 * 2^2 = 1 + (2 + 1) = 1 + 3 = 4
343 * ... 336 * ...
344 * In other words, a square number can be express as the sum of the 337 * In other words, a square number can be express as the sum of the
345 * series n^2 = 1 + 3 + ... + (2n-1) 338 * series n^2 = 1 + 3 + ... + (2n-1)
346 */ 339 */
347int 340int
348isqrt(int n) 341isqrt (int n)
349{ 342{
350 int result, sum, prev; 343 int result, sum, prev;
344
351 result = 0; 345 result = 0;
352 prev = sum = 1; 346 prev = sum = 1;
353 while (sum <= n) { 347 while (sum <= n)
348 {
354 prev += 2; 349 prev += 2;
355 sum += prev; 350 sum += prev;
356 ++result; 351 ++result;
357 } 352 }
358 return result; 353 return result;
359} 354}
360 355
361 356
362/* 357/*
363 * returns a char-pointer to a static array, in which a representation 358 * returns a char-pointer to a static array, in which a representation
364 * of the decimal number given will be stored. 359 * of the decimal number given will be stored.
365 */ 360 */
366 361
362char *
367char *ltostr10(signed long n) { 363ltostr10 (signed long n)
364{
368 static char buf[12]; /* maximum size is n=-2 billion, i.e. 11 characters+1 365 static char buf[12]; /* maximum size is n=-2 billion, i.e. 11 characters+1
369 character for the trailing nul character */ 366 character for the trailing nul character */
370 snprintf(buf, sizeof(buf), "%ld", n); 367 snprintf (buf, sizeof (buf), "%ld", n);
371 return buf; 368 return buf;
372} 369}
370
371char *
373char *doubletostr10(double v){ 372doubletostr10 (double v)
373{
374 static char tbuf[200]; 374 static char tbuf[200];
375
375 sprintf(tbuf,"%f",v); 376 sprintf (tbuf, "%f", v);
376 return tbuf; 377 return tbuf;
377}
378
379/*
380 * A fast routine which appends the name and decimal number specified
381 * to the given buffer.
382 * Could be faster, though, if the strcat()s at the end could be changed
383 * into alternate strcat which returned a pointer to the _end_, not the
384 * start!
385 *
386 * Hey good news, it IS faster now, according to changes in get_ob_diff
387 * Completly redone prototype and made define in loader.l. See changes there.
388 * Didn't touch those for speed reason (don't use them anymore) .
389 * Tchize
390 */
391
392void save_long(char *buf, char *name, long n) {
393 char buf2[MAX_BUF];
394 strcpy(buf2,name);
395 strcat(buf2," ");
396 strcat(buf2,ltostr10(n));
397 strcat(buf2,"\n");
398 strcat(buf,buf2);
399}
400
401
402
403void save_long_long(char *buf, char *name, sint64 n) {
404 char buf2[MAX_BUF];
405
406#ifndef WIN32
407 sprintf(buf2,"%s %lld\n", name, n);
408#else
409 sprintf(buf2,"%s %I64d\n", name, n);
410#endif
411 strcat(buf,buf2);
412}
413
414/**
415 * Open and possibly uncompress a file.
416 *
417 * @param ext the extension if the file is compressed.
418 *
419 * @param uncompressor the command to uncompress the file if the file is
420 * compressed.
421 *
422 * @param name the base file name without compression extension
423 *
424 * @param flag only used for compressed files: if set, uncompress and open the
425 * file; if unset, uncompress the file via pipe
426 *
427 * @param *compressed set to zero if the file was uncompressed
428 */
429static FILE *open_and_uncompress_file(const char *ext, const char *uncompressor, const char *name, int flag, int *compressed) {
430 struct stat st;
431 char buf[MAX_BUF];
432 char buf2[MAX_BUF];
433 int ret;
434
435 if (ext == NULL) {
436 ext = "";
437 }
438
439 if (strlen(name)+strlen(ext) >= sizeof(buf)) {
440 errno = ENAMETOOLONG; /* File name too long */
441 return NULL;
442 }
443 sprintf(buf, "%s%s", name, ext);
444
445 if (stat(buf, &st) != 0) {
446 return NULL;
447 }
448
449 if (!S_ISREG(st.st_mode)) {
450 errno = EISDIR; /* Not a regular file */
451 return NULL;
452 }
453
454 if (uncompressor == NULL) {
455 /* open without uncompression */
456
457 return fopen(buf, "r");
458 }
459
460 /* The file name buf (and its substring name) is passed as an argument to a
461 * shell command, therefore check for characters that could confuse the
462 * shell.
463 */
464 if (strpbrk(buf, "'\\\r\n") != NULL) {
465 errno = ENOENT; /* Pretend the file does not exist */
466 return NULL;
467 }
468
469 if (!flag) {
470 /* uncompress via pipe */
471
472 if (strlen(uncompressor)+4+strlen(buf)+1 >= sizeof(buf2)) {
473 errno = ENAMETOOLONG; /* File name too long */
474 return NULL;
475 }
476 sprintf(buf2, "%s < '%s'", uncompressor, buf);
477
478 return popen(buf2, "r");
479 }
480
481 /* remove compression from file, then open file */
482
483 if (stat(name, &st) == 0 && !S_ISREG(st.st_mode)) {
484 errno = EISDIR;
485 return NULL;
486 }
487
488 if (strlen(uncompressor)+4+strlen(buf)+5+strlen(name)+1 >= sizeof(buf2)) {
489 errno = ENAMETOOLONG; /* File name too long */
490 return NULL;
491 }
492 sprintf(buf2, "%s < '%s' > '%s'", uncompressor, buf, name);
493
494 ret = system(buf2);
495 if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) {
496 LOG(llevError, "system(%s) returned %d\n", buf2, ret);
497 errno = ENOENT;
498 return NULL;
499 }
500
501 unlink(buf); /* Delete the original */
502 *compressed = 0; /* Change to "uncompressed file" */
503 chmod(name, st.st_mode); /* Copy access mode from compressed file */
504
505 return fopen(name, "r");
506} 378}
507 379
508/** 380/**
509 * open_and_uncompress() first searches for the original filename. If it exist, 381 * open_and_uncompress() first searches for the original filename. If it exist,
510 * then it opens it and returns the file-pointer. 382 * then it opens it and returns the file-pointer.
511 * 383 */
512 * If not, it does two things depending on the flag. If the flag is set, it 384FILE *
513 * tries to create the original file by appending a compression suffix to name
514 * and uncompressing it. If the flag is not set, it creates a pipe that is used
515 * for reading the file (NOTE - you can not use fseek on pipes).
516 *
517 * The compressed pointer is set to nonzero if the file is compressed (and
518 * thus, fp is actually a pipe.) It returns 0 if it is a normal file.
519 */
520FILE *open_and_uncompress(const char *name, int flag, int *compressed) { 385open_and_uncompress (const char *name, int flag, int *compressed)
521 size_t i; 386{
522 FILE *fp;
523
524 for (i = 0; i < NROF_COMPRESS_METHODS; i++) {
525 *compressed = i; 387 *compressed = 0;
526 fp = open_and_uncompress_file(uncomp[i][0], uncomp[i][1], name, flag, compressed); 388 return fopen (name, "r");
527 if (fp != NULL) {
528 return fp;
529 }
530 }
531
532 errno = ENOENT;
533 return NULL;
534} 389}
535 390
536/* 391/*
537 * See open_and_uncompress(). 392 * See open_and_uncompress().
538 */ 393 */
539 394
395void
540void close_and_delete(FILE *fp, int compressed) { 396close_and_delete (FILE * fp, int compressed)
541 if (compressed) 397{
542 pclose(fp);
543 else
544 fclose(fp); 398 fclose (fp);
545} 399}
546 400
547/* 401/*
548 * If any directories in the given path doesn't exist, they are created. 402 * If any directories in the given path doesn't exist, they are created.
549 */ 403 */
550 404
405void
551void make_path_to_file (char *filename) 406make_path_to_file (char *filename)
552{ 407{
553 char buf[MAX_BUF], *cp = buf; 408 char buf[MAX_BUF], *cp = buf;
554 struct stat statbuf; 409 struct stat statbuf;
555 410
556 if (!filename || !*filename) 411 if (!filename || !*filename)
557 return; 412 return;
558 strcpy (buf, filename); 413 strcpy (buf, filename);
559 414
560 while ((cp = strchr (cp + 1, (int) '/'))) { 415 while ((cp = strchr (cp + 1, (int) '/')))
416 {
561 *cp = '\0'; 417 *cp = '\0';
562 if (stat(buf, &statbuf) || !S_ISDIR (statbuf.st_mode)) { 418 if (stat (buf, &statbuf) || !S_ISDIR (statbuf.st_mode))
419 {
563 if (mkdir (buf, SAVE_DIR_MODE)) { 420 if (mkdir (buf, SAVE_DIR_MODE))
421 {
564 LOG(llevError, "Cannot mkdir %s: %s\n", buf, strerror_local(errno)); 422 LOG (llevError, "Cannot mkdir %s: %s\n", buf, strerror (errno));
565 return; 423 return;
566 } 424 }
567 } 425 }
568 *cp = '/'; 426 *cp = '/';
569 } 427 }
570} 428}
571

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines