--- deliantra/server/common/porting.C 2006/08/30 16:30:37 1.3 +++ deliantra/server/common/porting.C 2006/12/14 22:45:40 1.10 @@ -1,9 +1,4 @@ /* - * static char *rcsid_porting_c = - * "$Id: porting.C,v 1.3 2006/08/30 16:30:37 root Exp $"; - */ - -/* CrossFire, A Multiplayer game for X-windows Copyright (C) 2002 Mark Wedel & Crossfire Development Team @@ -23,7 +18,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - The authors can be reached via e-mail at crossfire-devel@real-time.com + The authors can be reached via e-mail at */ /* This file contains various functions that are not really unique for @@ -34,280 +29,102 @@ */ -#ifdef WIN32 /* ---win32 exclude/include headers */ -#include "process.h" -#define pid_t int /* we include it non global, because there is a redefinition in python.h */ -#else -#include -#include -#include - -#include -#include - /* Need to pull in the HAVE_... values somehow */ -/* win32 reminder: always put this in a ifndef win32 block */ + #include -#endif +#include +#include +#include + +#include -#ifdef HAVE_STDLIB_H -#include -#endif +#include +#include + +#include -#ifdef HAVE_UNISTD_H #include -#endif -#include /* Has to be after above includes so we don't redefine some values */ #include "global.h" static unsigned int curtmp = 0; -/***************************************************************************** - * File related functions - ****************************************************************************/ - -/* - * A replacement for the tempnam() function since it's not defined - * at some unix variants. - */ - -char *tempnam_local(const char *dir, const char *pfx) -{ - char *name; - pid_t pid=getpid(); - -/* HURD does not have a hard limit, but we do */ -#ifndef MAXPATHLEN -#define MAXPATHLEN 4096 -#endif - - if (!(name = (char *) malloc(MAXPATHLEN))) - return(NULL); - - if (!pfx) - pfx = "cftmp."; - - /* This is a pretty simple method - put the pid as a hex digit and - * just keep incrementing the last digit. Check to see if the file - * already exists - if so, we'll just keep looking - eventually we should - * find one that is free. - */ - if (dir!=NULL) { - do { -#ifdef HAVE_SNPRINTF - (void)snprintf(name, MAXPATHLEN, "%s/%s%hx.%d", dir, pfx, pid, curtmp); -#else - (void)sprintf(name,"%s/%s%hx%d", dir, pfx, pid, curtmp); -#endif - curtmp++; - } while (access(name, F_OK)!=-1); - return(name); - } - return(NULL); -} - - - /* This function removes everything in the directory. */ -void remove_directory(const char *path) +void +remove_directory (const char *path) { - DIR *dirp; - char buf[MAX_BUF]; - struct stat statbuf; - int status; - - if ((dirp=opendir(path))!=NULL) { - struct dirent *de; - - for (de=readdir(dirp); de; de = readdir(dirp)) { - /* Don't remove '.' or '..' In theory we should do a better - * check for .., but the directories we are removing are fairly - * limited and should not have dot files in them. - */ - if (de->d_name[0] == '.') continue; - - /* Linux actually has a type field in the dirent structure, - * but that is not portable - stat should be portable - */ - status=stat(de->d_name, &statbuf); - if ((status!=-1) && (S_ISDIR(statbuf.st_mode))) { - sprintf(buf,"%s/%s", path, de->d_name); - remove_directory(buf); - continue; + DIR *dirp; + char buf[MAX_BUF]; + struct stat statbuf; + int status; + + if ((dirp = opendir (path)) != NULL) + { + struct dirent *de; + + for (de = readdir (dirp); de; de = readdir (dirp)) + { + /* Don't remove '.' or '..' In theory we should do a better + * check for .., but the directories we are removing are fairly + * limited and should not have dot files in them. + */ + if (de->d_name[0] == '.') + continue; + + /* Linux actually has a type field in the dirent structure, + * but that is not portable - stat should be portable + */ + status = stat (de->d_name, &statbuf); + if ((status != -1) && (S_ISDIR (statbuf.st_mode))) + { + sprintf (buf, "%s/%s", path, de->d_name); + remove_directory (buf); + continue; } - sprintf(buf,"%s/%s", path, de->d_name); - if (unlink(buf)) { - LOG(llevError,"Unable to remove directory %s\n", path); + sprintf (buf, "%s/%s", path, de->d_name); + if (unlink (buf)) + { + LOG (llevError, "Unable to remove directory %s\n", path); } } - closedir(dirp); + closedir (dirp); } - if (rmdir(path)) { - LOG(llevError,"Unable to remove directory %s\n", path); + if (rmdir (path)) + { + LOG (llevError, "Unable to remove directory %s\n", path); } } -#if defined(sgi) - -#include -#include -#include - -#define popen fixed_popen - -FILE *popen_local(const char *command, const char *type) -{ - int fd[2]; - int pd; - FILE *ret; - if (!strcmp(type,"r")) - { - pd=STDOUT_FILENO; - } - else if (!strcmp(type,"w")) - { - pd=STDIN_FILENO; - } - else - { - return NULL; - } - if (pipe(fd)!=-1) - { - switch (fork()) - { - case -1: - close(fd[0]); - close(fd[1]); - break; - case 0: - close(fd[0]); - if ((fd[1]==pd)||(dup2(fd[1],pd)==pd)) - { - if (fd[1]!=pd) - { - close(fd[1]); - } - execl("/bin/sh","sh","-c",command,NULL); - close(pd); - } - exit(1); - break; - default: - close(fd[1]); - if (ret=fdopen(fd[0],type)) - { - return ret; - } - close(fd[0]); - break; - } - } - return NULL; -} - -#endif /* defined(sgi) */ - - -/***************************************************************************** - * String related function - ****************************************************************************/ - - - -/* - * A replacement of strdup(), since it's not defined at some - * unix variants. - */ -char *strdup_local(const char *str) { - char *c=(char *)malloc(sizeof(char)*(strlen(str)+1)); - strcpy(c,str); - return c; -} - - #define DIGIT(x) (isdigit(x) ? (x) - '0' : \ islower (x) ? (x) + 10 - 'a' : (x) + 10 - 'A') #define MBASE ('z' - 'a' + 1 + 10) -/* This seems to be lacking on some system */ -#if !defined(HAVE_STRNCASECMP) -int strncasecmp(const char *s1, const char *s2, int n) -{ - register int c1, c2; - - while (*s1 && *s2 && n) { - c1 = tolower(*s1); - c2 = tolower(*s2); - if (c1 != c2) - return (c1 - c2); - s1++; - s2++; - n--; - } - if (!n) - return(0); - return (int) (*s1 - *s2); -} -#endif - -#if !defined(HAVE_STRCASECMP) -int strcasecmp(const char *s1, const char*s2) -{ - register int c1, c2; - - while (*s1 && *s2) { - c1 = tolower(*s1); - c2 = tolower(*s2); - if (c1 != c2) - return (c1 - c2); - s1++; - s2++; - } - if (*s1=='\0' && *s2=='\0') - return 0; - return (int) (*s1 - *s2); -} -#endif - -char *strcasestr_local(const char *s, const char *find) -{ - char c, sc; - size_t len; - - if ((c = *find++) != 0) { - c = tolower(c); - len = strlen(find); - do { - do { - if ((sc = *s++) == 0) - return NULL; - } while (tolower(sc) != c); - } while (strncasecmp(s, find, len) != 0); - s--; - } - return (char *)s; -} - -#if !defined(HAVE_SNPRINTF) - -int snprintf(char *dest, int max, const char *format, ...) +char * +strcasestr_local (const char *s, const char *find) { - va_list var; - int ret; + char c, sc; + size_t len; - va_start(var, format); - ret = vsprintf(dest, format, var); - va_end(var); - if (ret > max) abort(); - - return ret; + if ((c = *find++) != 0) + { + c = tolower (c); + len = strlen (find); + do + { + do + { + if ((sc = *s++) == 0) + return NULL; + } + while (tolower (sc) != c); + } + while (strncasecmp (s, find, len) != 0); + s--; + } + return (char *) s; } -#endif - /* * Based on (n+1)^2 = n^2 + 2n + 1 @@ -320,189 +137,89 @@ * series n^2 = 1 + 3 + ... + (2n-1) */ int -isqrt(int n) +isqrt (int n) { - int result, sum, prev; - result = 0; - prev = sum = 1; - while (sum <= n) { - prev += 2; - sum += prev; - ++result; - } - return result; -} + int result, sum, prev; + result = 0; + prev = sum = 1; + while (sum <= n) + { + prev += 2; + sum += prev; + ++result; + } + return result; +} /* * returns a char-pointer to a static array, in which a representation * of the decimal number given will be stored. */ - -char *ltostr10(signed long n) { - static char buf[12]; /* maximum size is n=-2 billion, i.e. 11 characters+1 - character for the trailing nul character */ - snprintf(buf, sizeof(buf), "%ld", n); +char * +ltostr10 (signed long n) +{ + static char buf[12]; /* maximum size is n=-2 billion, i.e. 11 characters+1 + character for the trailing nul character */ + snprintf (buf, sizeof (buf), "%ld", n); return buf; } -char *doubletostr10(double v){ - static char tbuf[200]; - sprintf(tbuf,"%f",v); - return tbuf; -} -/** - * Open and possibly uncompress a file. - * - * @param ext the extension if the file is compressed. - * - * @param uncompressor the command to uncompress the file if the file is - * compressed. - * - * @param name the base file name without compression extension - * - * @param flag only used for compressed files: if set, uncompress and open the - * file; if unset, uncompress the file via pipe - * - * @param *compressed set to zero if the file was uncompressed - */ -static FILE *open_and_uncompress_file(const char *ext, const char *uncompressor, const char *name, int flag, int *compressed) { - struct stat st; - char buf[MAX_BUF]; - char buf2[MAX_BUF]; - int ret; - - if (ext == NULL) { - ext = ""; - } - - if (strlen(name)+strlen(ext) >= sizeof(buf)) { - errno = ENAMETOOLONG; /* File name too long */ - return NULL; - } - sprintf(buf, "%s%s", name, ext); - - if (stat(buf, &st) != 0) { - return NULL; - } - - if (!S_ISREG(st.st_mode)) { - errno = EISDIR; /* Not a regular file */ - return NULL; - } - - if (uncompressor == NULL) { - /* open without uncompression */ - - return fopen(buf, "r"); - } - - /* The file name buf (and its substring name) is passed as an argument to a - * shell command, therefore check for characters that could confuse the - * shell. - */ - if (strpbrk(buf, "'\\\r\n") != NULL) { - errno = ENOENT; /* Pretend the file does not exist */ - return NULL; - } - - if (!flag) { - /* uncompress via pipe */ - - if (strlen(uncompressor)+4+strlen(buf)+1 >= sizeof(buf2)) { - errno = ENAMETOOLONG; /* File name too long */ - return NULL; - } - sprintf(buf2, "%s < '%s'", uncompressor, buf); - - return popen(buf2, "r"); - } - - /* remove compression from file, then open file */ - - if (stat(name, &st) == 0 && !S_ISREG(st.st_mode)) { - errno = EISDIR; - return NULL; - } - - if (strlen(uncompressor)+4+strlen(buf)+5+strlen(name)+1 >= sizeof(buf2)) { - errno = ENAMETOOLONG; /* File name too long */ - return NULL; - } - sprintf(buf2, "%s < '%s' > '%s'", uncompressor, buf, name); - - ret = system(buf2); - if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) { - LOG(llevError, "system(%s) returned %d\n", buf2, ret); - errno = ENOENT; - return NULL; - } - - unlink(buf); /* Delete the original */ - *compressed = 0; /* Change to "uncompressed file" */ - chmod(name, st.st_mode); /* Copy access mode from compressed file */ +char * +doubletostr10 (double v) +{ + static char tbuf[200]; - return fopen(name, "r"); + sprintf (tbuf, "%f", v); + return tbuf; } /** * open_and_uncompress() first searches for the original filename. If it exist, * then it opens it and returns the file-pointer. - * - * If not, it does two things depending on the flag. If the flag is set, it - * tries to create the original file by appending a compression suffix to name - * and uncompressing it. If the flag is not set, it creates a pipe that is used - * for reading the file (NOTE - you can not use fseek on pipes). - * - * The compressed pointer is set to nonzero if the file is compressed (and - * thus, fp is actually a pipe.) It returns 0 if it is a normal file. */ -FILE *open_and_uncompress(const char *name, int flag, int *compressed) { - size_t i; - FILE *fp; - - fp = open_and_uncompress_file(0,0, name, flag, compressed); - if (fp != NULL) { - return fp; - } - - errno = ENOENT; - return NULL; +FILE * +open_and_uncompress (const char *name, int flag, int *compressed) +{ + *compressed = 0; + return fopen (name, "r"); } /* * See open_and_uncompress(). */ -void close_and_delete(FILE *fp, int compressed) { - if (compressed) - pclose(fp); - else - fclose(fp); +void +close_and_delete (FILE * fp, int compressed) +{ + fclose (fp); } /* * If any directories in the given path doesn't exist, they are created. */ -void make_path_to_file (char *filename) +void +make_path_to_file (char *filename) { - char buf[MAX_BUF], *cp = buf; - struct stat statbuf; + char buf[MAX_BUF], *cp = buf; + struct stat statbuf; - if (!filename || !*filename) - return; - strcpy (buf, filename); - - while ((cp = strchr (cp + 1, (int) '/'))) { - *cp = '\0'; - if (stat(buf, &statbuf) || !S_ISDIR (statbuf.st_mode)) { - if (mkdir (buf, SAVE_DIR_MODE)) { - LOG(llevError, "Cannot mkdir %s: %s\n", buf, strerror(errno)); - return; + if (!filename || !*filename) + return; + strcpy (buf, filename); + + while ((cp = strchr (cp + 1, (int) '/'))) + { + *cp = '\0'; + if (stat (buf, &statbuf) || !S_ISDIR (statbuf.st_mode)) + { + if (mkdir (buf, SAVE_DIR_MODE)) + { + LOG (llevError, "Cannot mkdir %s: %s\n", buf, strerror (errno)); + return; } } - *cp = '/'; + *cp = '/'; } } -