util.c

00001 #include <stdlib.h>
00002 #include <string.h>
00003 #include <time.h>
00004 #include <ctype.h>
00005 
00006 #if defined(unix) || defined(__unix__) || defined(__MACH__)
00007 #include <unistd.h>
00008 #endif
00009 
00010 #include "config.h"
00011 #ifdef CP_HAS_REGEX_H
00012 #include <regex.h>
00013 #else
00014 #ifdef CP_HAS_PCRE
00015 #include <pcreposix.h>
00016 #endif
00017 #endif /* CP_HAS_REGEX_H */
00018 #ifdef CP_HAS_DIRENT_H
00019 #include <dirent.h>
00020 #endif
00021 #include <errno.h>
00022 #ifdef CP_HAS_SYS_TIME_H
00023 #include <sys/time.h>
00024 #endif
00025 
00026 #include <sys/types.h>
00027 #include <sys/stat.h>
00028 
00029 #ifdef CP_HAS_NETDB_H
00030 #include <netdb.h>
00031 #endif
00032 
00033 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__)
00034 #include <sys/types.h>
00035 #include <sys/socket.h>
00036 #include <netinet/in.h>
00037 #endif
00038 
00039 #ifdef _WINDOWS
00040 #include <Winsock2.h>
00041 #include <WS2SPI.H>
00042 #include <Windows.h>
00043 #endif
00044 
00045 #include "util.h"
00046 #include "log.h"
00047 #include "common.h"
00048 
00049 #ifndef CP_HAS_STRDUP
00050 char *strdup(char *src)
00051 {
00052     char *dst = NULL;
00053 
00054     if (src != NULL) // || *src == '\0') 
00055     {
00056         int len = strlen(src);
00057         dst = (char *) malloc((len + 1) * sizeof(char));
00058         cp_assert(*dst != NULL);
00059 
00060         memcpy(*dst, src, len);
00061         dst[len] = '\0';
00062     }
00063 
00064     return dst;
00065 }
00066 #endif /* no strdup */
00067 
00068 #ifndef CP_HAS_STRNDUP
00069 char *strndup(char *src, int maxlen)
00070 {
00071     int len;
00072     char *p;
00073     char *dst = NULL;
00074 
00075     if (maxlen < 0)
00076     {
00077         cp_error(CP_INVALID_VALUE, "negative string length requested");
00078         errno = EINVAL;
00079         return NULL;
00080     }
00081 
00082     if (src != NULL) 
00083     {
00084         /* null termination not guaranteed - can't use strlen */ 
00085         for (p = src; *p && p - src < maxlen; p++); 
00086         len = p - src;
00087         if (len > maxlen) len = maxlen; 
00088         dst = (char *) malloc((len + 1) * sizeof(char));
00089         if (dst == NULL)
00090         {
00091             errno = ENOMEM;
00092             return NULL;
00093         }
00094 
00095         memcpy(dst, src, len); 
00096         dst[len] = '\0';
00097     }
00098 
00099     return dst;
00100 }
00101 #endif /* no strndup */
00102 
00103 #ifndef CP_HAS_STRCASECMP
00104 #ifndef _WINDOWS
00105 int strcasecmp(const char *a, const char *b)
00106 {
00107     while (*a && *b && tolower(*a) == tolower(*b)) 
00108     {
00109         a++;
00110         b++;
00111     }
00112 
00113     return *a - *b;
00114 }
00115 #endif
00116 #endif /* no strcasecmp */
00117 
00118 #ifndef CP_HAS_STRNCASECMP
00119 #ifndef _WINDOWS
00120 int strncasecmp(const char *a, const char *b, size_t len)
00121 {
00122     while (len-- > 0 && *a && *b && tolower(*a) == tolower(*b)) 
00123     {
00124         a++;
00125         b++;
00126     }
00127 
00128     return *a - *b;
00129 }
00130 #endif
00131 #endif /* no strncasecmp */
00132 
00133 #ifndef CP_HAS_GETTIMEOFDAY
00134 #ifdef _WINDOWS
00135 
00136 /* the following implementation of gettimeofday for windows is taken from
00137  * https://projects.cecs.pdx.edu/~brael/j2++/index.cgi/browser/trunk/subst/gettimeofday.c/?rev=46
00138  * 
00139  * Here is the copyright notice for this function: 
00140  * 
00141  * Copyright (c) 2003 SRA, Inc. 
00142  * Copyright (c) 2003 SKC, Inc. 
00143  * 
00144  * Permission to use, copy, modify, and distribute this software and 
00145  * its documentation for any purpose, without fee, and without a 
00146  * written agreement is hereby granted, provided that the above 
00147  * copyright notice and this paragraph and the following two 
00148  * paragraphs appear in all copies. 
00149  * 
00150  * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, 
00151  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING 
00152  * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS 
00153  * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED 
00154  * OF THE POSSIBILITY OF SUCH DAMAGE. 
00155  * 
00156  * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT 
00157  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
00158  * A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS 
00159  * IS" BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, 
00160  * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 
00161  */ 
00162 
00163 /* FILETIME of Jan 1 1970 00:00:00. */ 
00164 static const unsigned __int64 epoch = 116444736000000000L; 
00165  
00166 /* 
00167  * timezone information is stored outside the kernel so tzp isn't used anymore. 
00168  */ 
00169  
00170 int 
00171 gettimeofday(struct timeval * tp, struct timezone * tzp) 
00172 { 
00173         FILETIME        file_time; 
00174         SYSTEMTIME      system_time; 
00175         ULARGE_INTEGER ularge; 
00176  
00177         GetSystemTime(&system_time); 
00178         SystemTimeToFileTime(&system_time, &file_time); 
00179         ularge.LowPart = file_time.dwLowDateTime; 
00180         ularge.HighPart = file_time.dwHighDateTime; 
00181  
00182         tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L); 
00183         tp->tv_usec = (long) (system_time.wMilliseconds * 1000); 
00184  
00185         return 0; 
00186 } 
00187 #endif /* _WINDOWS */
00188 #endif /* no gettimeofday */
00189 
00190 /* cp_sleep - a platform independent function to sleep n seconds */
00191 int cp_sleep(int sec)
00192 {
00193     int rc = -1;
00194 #if defined(unix) || defined(__unix__) || defined(__MACH__)
00195     struct timeval delay;
00196     delay.tv_sec = sec; /* run session cleanup every 15 minutes */
00197     delay.tv_usec = 0;
00198     rc = select(0, NULL, NULL, NULL, &delay); 
00199 #else
00200 #ifdef _WINDOWS
00201     rc = 0;
00202     Sleep(sec * 1000);
00203 #endif /* _WINDOWS */
00204 #endif /* unix */
00205     return rc;
00206 }
00207 
00208 char *hex_url_encode(char *hex)
00209 {
00210     int len = strlen(hex) * 3 / 2 + 1;
00211     char *res = (char *) malloc(len * sizeof(char));
00212     char *idx = res;
00213 
00214     while (*hex)
00215     {
00216         *idx++ = '%';
00217         *idx++ = *hex++;
00218         if (*hex == 0) break;
00219         *idx++ = *hex++;
00220     }
00221 
00222     *idx = '\0';
00223 
00224     return res;
00225 }
00226 
00227 char *strnchr(char *str, char ch, int len)
00228 {
00229     char *res = NULL;
00230 
00231     if (len < 0)
00232     {
00233         cp_error(CP_INVALID_VALUE, "negative string length requested");
00234         errno = EINVAL;
00235         return NULL;
00236     }
00237 
00238     while (len-- > 0)
00239     {
00240         if (*str == ch)
00241         {
00242             res = str;
00243             break;
00244         }
00245         if (*str++ == '\0')
00246             break;
00247     }
00248 
00249     return res;
00250 }
00251 
00252 
00253 char *str_trim_cpy(char *dst, char *src)
00254 {
00255     char *top;
00256     char *last;
00257     top = dst;
00258     while (isspace(*src)) src++;
00259     last = dst;
00260     while ((*dst = *src)) {
00261         dst++;
00262         if (!isspace(*src)) last = dst;
00263         src++;
00264     }
00265 
00266     *last = '\0';
00267     return top;
00268 }
00269 
00270 int parse_boolean(char *value)
00271 {
00272     return value != NULL && (*value == 't' || *value =='T');
00273 }
00274 
00275 long get_timestamp()
00276 {
00277     return time(NULL);
00278 }
00279 
00283 static char *empty_cp_string = "";
00284 
00285 char *dbfmt(char *str)
00286 {
00287     return str ? str : empty_cp_string;
00288 }
00289 
00290 unsigned long get_current_ip()
00291 {
00292     char hostname[256];
00293     int rc;
00294 
00295     rc = gethostname(hostname, 256);
00296     return rc ? 0 : get_host_ip(hostname);
00297 }
00298 
00299 unsigned long get_host_ip(char *hostname)
00300 {
00301 #ifdef CP_HAS_GETADDRINFO
00302     struct addrinfo hints, *res, *res0;
00303     int rc;
00304     unsigned long ip = 0;
00305     unsigned long addr = 0;
00306 
00307     memset(&hints, 0, sizeof(hints));
00308     hints.ai_family = AF_INET;
00309     hints.ai_socktype = SOCK_STREAM;
00310 
00311     rc = getaddrinfo(hostname, "http", &hints, &res0);
00312     for (res = res0; res; res = res->ai_next) {
00313         addr = ((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr;
00314         if (ip && (addr & 0xff) == 0x7f) continue;
00315         ip = addr;
00316     }
00317 
00318     return ip;
00319 #else
00320     unsigned long ulIP; 
00321     struct hostent* phostent;   
00322 
00323     phostent = gethostbyname(hostname); 
00324     if (phostent == NULL) return -1;
00325 #ifdef _WINDOWS
00326     ulIP = *(DWORD*)(*phostent->h_addr_list);
00327 #else
00328     ulIP = *(unsigned long *)(*phostent->h_addr_list);
00329 #endif
00330 
00331     return ulIP;
00332 #endif
00333 }
00334 
00335 char *ip_to_string(unsigned long ip, char *buf, size_t len)
00336 {
00337 #ifdef CP_HAS_SNPRINTF
00338     snprintf(buf, len, "%ld.%ld.%ld.%ld", ip & 0xff, (ip >> 8) & 0xff
00339            , (ip >> 16) & 0xff, (ip >> 24) & 0xff);
00340 #else
00341     sprintf(buf, "%ld.%ld.%ld.%ld", ip & 0xff, (ip >> 8) & 0xff
00342            , (ip >> 16) & 0xff, (ip >> 24) & 0xff);
00343 #endif /* CP_HAS_SNPRINTF */
00344     return buf;
00345 }
00346 
00347 char *regex_compilation_error(int rc)
00348 {
00349     char *msg = NULL;
00350 
00351     switch (rc)
00352     {
00353         case REG_BADRPT:
00354             msg = "Invalid use of repetition operators such as using `*' as the first character."; 
00355             break;
00356 
00357         case REG_BADBR: 
00358             msg = "Invalid use of back reference operator.";
00359             break;
00360 
00361         case REG_EBRACE:
00362             msg = "Un-matched brace interval operators.";
00363             break;
00364 
00365         case REG_EBRACK:
00366             msg = "Un-matched bracket list operators.";
00367             break;
00368 
00369         case REG_ERANGE:
00370             msg = "Invalid  use  of  the  range operator, eg. the ending point of the range occurs prior to the starting point.";
00371             break;
00372 
00373         case REG_ECTYPE:
00374             msg = "Unknown character class name.";
00375             break;
00376 
00377         case REG_ECOLLATE:
00378             msg = "Invalid collating element.";
00379             break;
00380 
00381         case REG_EPAREN:
00382             msg = "Un-matched parenthesis group operators.";
00383             break;
00384 
00385         case REG_ESUBREG:
00386             msg = "Invalid back reference to a subexpression.";
00387             break;
00388 
00389 #ifdef linux
00390         case REG_EEND:
00391             msg = "Non specific error.";
00392             break;
00393 #endif
00394 
00395         case REG_EESCAPE:
00396             msg = "Trailing backslash.";
00397             break;
00398 
00399         case REG_BADPAT:
00400             msg = "Invalid use of pattern operators such as group or list.";
00401             break;
00402 
00403 #ifdef linux
00404         case REG_ESIZE:
00405             msg = "Compiled regular expression requires a pattern buffer larger than  64Kb.";
00406             break;
00407 #endif
00408 
00409         case REG_ESPACE:
00410             msg = "The regex routines ran out of memory.";
00411             break;
00412     }
00413 
00414     return msg;
00415 }
00416 
00417 char *stat_error_fmt(int err)
00418 {
00419     char *fmt = "%s: resolving %s: unknown stat error\n";
00420     switch (err)
00421     {
00422         case ENOENT: 
00423             fmt = "%s: A component of the path \'%s\' does not exist\n";
00424             break;
00425 
00426         case ENOTDIR: 
00427             fmt = "%s: A component of the path \'%s\' is not a directory\n";
00428             break;
00429 
00430 #ifdef ELOOP
00431         case ELOOP:
00432             fmt = "%s: Too many symbolic links encountered while "
00433                   "traversing the path %s\n";
00434             break;
00435 #endif
00436 
00437         case EFAULT:
00438             fmt = "%s: Bad address resolving %s\n";
00439             break;
00440 
00441         case EACCES:
00442             fmt = "%s: %s: Permission denied.\n";
00443             break;
00444 
00445         case ENOMEM: 
00446             fmt = "%s: resolving %s: Out of memory\n";
00447             break;
00448 
00449         case ENAMETOOLONG:
00450             fmt = "%s: resolving %s: File name too long.\n";
00451             break;
00452     }
00453 
00454     return fmt;
00455 }
00456 
00457 time_t last_change_time(char *path)
00458 {
00459 #ifdef CP_HAS_STAT
00460     struct stat buf;
00461 
00462     if (stat(path, &buf)) return -1;
00463 
00464     return buf.st_mtime;
00465 #else
00466 #ifdef _WINDOWS
00467     struct _stat buf;
00468     if (_stat(path, &buf)) return -1;
00469     return buf.st_mtime;
00470 #endif
00471 #endif /* CP_HAS_STAT */
00472 }
00473 
00477 int checkdir(char *path)
00478 {
00479 #ifdef CP_HAS_DIRENT_H
00480     int rc = 0;
00481     DIR *dir = opendir(path);
00482 
00483     /*  opendir may set:
00484      *  EACCES  Permission denied.
00485      *  EMFILE  Too many file descriptors in use by process.
00486      *  ENFILE  Too many files are currently open in the system.
00487      *  ENOENT  Directory does not exist, or name is an empty string.
00488      *  ENOMEM  Insufficient memory to complete the operation.
00489      *  ENOTDIR name is not a directory.
00490      */
00491     if (dir == NULL)
00492     {
00493         int rc = errno;
00494         char *err = strerror(rc);
00495         cp_error(rc, "%s: opendir failed - %s", path, err);
00496     }
00497     else
00498         closedir(dir);
00499 
00500     return rc;
00501 #else
00502 #ifdef _WINDOWS
00503     struct _stat buf;
00504     return _stat(path, &buf) != 0;
00505 #endif
00506 #endif /* CP_HAS_DIRENT_H */
00507 }
00508 
00513 void gen_id_str(char *buf)
00514 {
00515     struct timeval tm;
00516     gettimeofday(&tm, NULL);
00517     gen_tm_id_str(buf, &tm);
00518 }
00519 
00520 static int id_factor[] = {   2,   3,   5,   7,  11, 
00521                             13,  17,  19,  23,  29, 
00522                             31,  37,  41,  43,  47, 
00523                             53,  59,  61,  67,  71,
00524                             73,  79,  83,  89,  97, 
00525                            101, 103, 107, 109, 113,
00526                            127, 131};
00527 
00532 void gen_tm_id_str(char *buf, struct timeval *tm)
00533 {
00534     int i;
00535     unsigned long t = 0;
00536     unsigned long v = 0;
00537     
00538     memset(buf, 0, 17);
00539     t = tm->tv_sec;
00540     for (i = 0; i < 32; i++)
00541     {
00542         v |= (t % id_factor[i]);
00543         v <<= 1;
00544         buf[i % 16] = (unsigned char)
00545             ('a' + (((((t * (i + 1)) % 26) | (buf[i % 16] % 'a')) ^ (unsigned char)(v % 26))) % 26);
00546     }
00547     t = tm->tv_usec;
00548     for (i = 0; i < 32; i++)
00549     {
00550         v ^= (t % id_factor[i]);
00551         v <<= 1;
00552         buf[i % 16] = (unsigned char) 
00553             ('a' + (((((t * (i + 1)) % 26) | (buf[i % 16] % 'a')) ^ (unsigned char)(v % 26))) % 26);
00554     }
00555 }
00556 
00558 int *intdup(int *src)
00559 {
00560     int *res = malloc(sizeof(int));
00561     if (res) *res = *src;
00562     return res;
00563 }
00564 
00566 long *longdup(long *src)
00567 {
00568     long *res = malloc(sizeof(long));
00569     if (res) *res = *src;
00570     return res;
00571 }
00572 
00574 float *floatdup(float *src)
00575 {
00576     float *res = malloc(sizeof(float));
00577     if (res) *res = *src;
00578     return res;
00579 }
00580 
00582 double *doubledup(double *src)
00583 {
00584     double *res = malloc(sizeof(double));
00585     if (res) *res = *src;
00586     return res;
00587 }
00588 
00590 void *memdup(void *src, int len)
00591 {
00592     void *res = malloc(len);
00593     if (res)
00594         memcpy(res, src, len);
00595     return res;
00596 }
00597 
00598 #define C2HEX(ch) ((ch) >= '0' && (ch) <= '9' ? (ch) - '0' : \
00599                    (ch) >= 'A' && (ch) <= 'F' ? (ch) - 'A' + 10 : \
00600                    (ch) >= 'a' && (ch) <= 'f' ? (ch) - 'a' + 10 : -1)
00601 
00603 int xtoi(char *p)
00604 {
00605     int curr;
00606     int res = 0;
00607 
00608     while (*p)
00609     {
00610         curr = C2HEX(*p);
00611         if (curr == -1) break;
00612         res = res * 0x10 + curr;
00613         p++;
00614     }
00615     
00616     return res;
00617 }
00618 
00620 int xtol(char *p)
00621 {
00622     int curr;
00623     long res = 0;
00624 
00625     while (*p)
00626     {
00627         curr = C2HEX(*p);
00628         if (curr == -1) break;
00629         res = res * 0x10 + curr;
00630         p++;
00631     }
00632     
00633     return res;
00634 }
00635 
00636 char *reverse_string(char *str)
00637 {
00638     int len;
00639     char *res;
00640     char *src, *dst;
00641 
00642     if (str == NULL) return NULL;
00643 
00644     len = strlen(str);
00645     res = malloc(len * sizeof(char) + 1);
00646     if (res == NULL) return NULL;
00647 
00648     dst = res;
00649     src = &str[len -1];
00650     while (src > str)
00651         *dst++ = *src--;
00652     *dst = '\0';
00653 
00654     return res;
00655 }
00656 
00657 
00658 char *reverse_string_in_place(char *str)
00659 {
00660     char *i, *f;
00661     char ch;
00662     int len = strlen(str);
00663     if (len == 0) return str;
00664     i = str;
00665     f = &str[len - 1];
00666     while (i < f)
00667     {
00668         ch = *i;
00669         *i = *f;
00670         *f = ch;
00671         i++;
00672         f--;
00673     }
00674 
00675     return str;
00676 }
00677 
00678 char *filter_string(char *str, char *letters)
00679 {
00680     char *i;
00681     char *f;
00682     int len = strlen(str);
00683 
00684     i = str;
00685     while ((f = strpbrk(i, letters)))
00686     {
00687         i = f;
00688         while (*f && strchr(letters, *f)) f++;
00689         if (*f)
00690         {
00691             memmove(i, f, len - (f - str));
00692             len -= f - i;
00693             str[len] = '\0';
00694         }
00695         else
00696         {
00697             *i = '\0';
00698             len -= len - (i - str);
00699             break;
00700         }
00701     }
00702 
00703     return str;
00704 }
00705 
00706 char *to_lowercase(char *str)
00707 {
00708     char *p;
00709     for (p = str; *p; p++)
00710         if (isupper(*p)) *p += 'a' - 'A';
00711     return str;
00712 }
00713 
00714 char *to_uppercase(char *str)
00715 {
00716     char *p;
00717     for (p = str; *p; p++)
00718         if (islower(*p)) *p -= 'a' - 'A';
00719     return str;
00720 }
00721 
00722 #ifndef CP_HAS_GETOPT
00723 CPROPS_DLL char *optarg;
00724 static int opt_idx = 0;
00725 
00726 int getopt(int argc, char *argv[], char *fmt)
00727 {
00728     char *p;
00729 
00730     opt_idx++;
00731     if (opt_idx == argc) return -1;
00732 
00733     if ((p = strchr(fmt, argv[opt_idx][1])) != NULL)
00734     {
00735         if (p[1] == ':') optarg = argv[++opt_idx];
00736         return p[0];
00737     }
00738 
00739     return 0;
00740 }
00741 #endif /* CP_HAS_GETOPT */
00742 
00743 #ifndef CP_HAS_INET_NTOP
00744 #ifdef _WINDOWS
00745 char *inet_ntop(int af, void *src, char *dst, size_t cnt)
00746 {
00747     int rc;
00748 
00749     WSAPROTOCOL_INFO pinfo;
00750     memset(&pinfo, 0, sizeof(WSAPROTOCOL_INFO));
00751     pinfo.iAddressFamily = AF_INET;
00752     rc = WSAAddressToString(src, sizeof(struct sockaddr_in), &pinfo, dst, &cnt);
00753 #ifdef DEBUG
00754     if (rc)
00755     {
00756         rc = WSAGetLastError();
00757         DEBUGMSG("WSAAddressToString: %d", rc);
00758     }
00759 #endif /* DEBUG */
00760     return dst;
00761 }
00762 
00763 #if 0 //~~ check windows version - some platforms don't have getnameinfo
00764 char *inet_ntop(int af, const void *src, char *dst, size_t cnt)
00765 {
00766     if (af == AF_INET)
00767     {
00768         struct sockaddr_in in;
00769         memset(&in, 0, sizeof(in));
00770         in.sin_family = AF_INET;
00771         memcpy(&in.sin_addr, src, sizeof(struct in_addr));
00772         getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), 
00773                     dst, cnt, NULL, 0, 0); //NI_NUMERICHOST);
00774         return dst;
00775     }
00776     else if (af == AF_INET6)
00777     {
00778         struct sockaddr_in6 in;
00779         memset(&in, 0, sizeof(in));
00780         in.sin6_family = AF_INET6;
00781         memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
00782         getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), 
00783                     dst, cnt, NULL, 0, NI_NUMERICHOST);
00784         return dst;
00785     }
00786     return NULL;
00787 }
00788 #endif //~~ platform check
00789 
00790 #endif /* _WINDOWS */
00791 #endif /* CP_HAS_INET_NTOP */
00792 
00793 #ifndef CP_HAS_DLFCN_H
00794 #ifdef _WINDOWS
00795 void *dlopen(char *file, int mode)
00796 {
00797     return LoadLibrary(file);
00798 }
00799 
00800 int dlclose(void *handle)
00801 {
00802     return FreeLibrary(handle);
00803 }
00804 
00805 void *dlsym(void *handle, char *name)
00806 {
00807     return GetProcAddress(handle, name);
00808 }
00809 
00810 char *dlerror()
00811 {
00812     static char msg[0x400];
00813     DWORD err = GetLastError();
00814     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 
00815             NULL, err, 0, msg, 0x400 - 1, NULL);
00816     return msg;
00817 }
00818 
00819 #endif /* _WINDOWS */
00820 #endif /* CP_HAS_DLFCN_H */
00821 
00822 #ifdef _WINDOWS
00823 char *flat_env(char *env, char **envp)
00824 {
00825     int len;
00826     int i = 0;
00827     char *p = env;
00828     while (envp[i])
00829     {
00830         strcpy(p, envp[i]);
00831         len = strlen(envp[i]);
00832         p[len] = '\0';
00833         p = &p[len + 1];
00834         i++;
00835     }
00836     *p = '\0';
00837 
00838     return p;
00839 }
00840 
00841 int create_proc(char *path, 
00842                 void *child_stdin, 
00843                 void *child_stdout, 
00844                 void *child_stderr,
00845                 char **envp)
00846 {
00847     TCHAR *szCmdline; 
00848     PROCESS_INFORMATION piProcInfo; 
00849     STARTUPINFO siStartInfo;
00850     BOOL bFuncRetn = FALSE; 
00851     char env[0x1000]; /* 4K of environment is enough for anyone */
00852  
00853     flat_env(env, envp);
00854 // Set up members of the PROCESS_INFORMATION structure. 
00855     ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
00856  
00857 // Set up members of the STARTUPINFO structure. 
00858     ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
00859     siStartInfo.cb = sizeof(STARTUPINFO); 
00860     siStartInfo.hStdError = child_stderr;
00861     siStartInfo.hStdOutput = child_stdout;
00862     siStartInfo.hStdInput = child_stdin;
00863     siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
00864  
00865     szCmdline = (TCHAR *) malloc(strlen(path) + 3);
00866     sprintf(szCmdline, "\"%s\"", path);
00867     
00868 // Create the child process. 
00869     bFuncRetn = CreateProcess(NULL, 
00870         szCmdline,     // command line 
00871         NULL,          // process security attributes 
00872         NULL,          // primary thread security attributes 
00873         TRUE,          // handles are inherited 
00874         0,             // creation flags 
00875         env,           // environment 
00876         NULL,          // use parent's current directory 
00877         &siStartInfo,  // STARTUPINFO pointer 
00878         &piProcInfo);  // receives PROCESS_INFORMATION 
00879    
00880     free(szCmdline);
00881 
00882     if (bFuncRetn == 0) return -1;
00883 
00884     CloseHandle(piProcInfo.hProcess);
00885     CloseHandle(piProcInfo.hThread);
00886     return bFuncRetn;
00887 }
00888 
00889 unsigned int __inline msc_clz( unsigned int x )
00890 {
00891    int r = 0;
00892    _BitScanForward(&r, x);
00893    return r;
00894 }
00895 
00896 unsigned int _inline msc_clz64(unsigned long long x)
00897 {
00898     int r = 0;
00899     _BitScanForward64(&r, x);
00900     return r;
00901 }
00902 #endif /* _WINDOWS */
00903 
00904 void replace_char(char *buf, char from, char to)
00905 {
00906     while (*buf)
00907     {
00908         if (*buf == from) *buf = to;
00909         buf++;
00910     }
00911 }
00912 

Generated on Mon Dec 5 23:00:22 2011 for cprops by  doxygen 1.4.7