media/mtransport/third_party/nrappkit/src/util/util.c

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /**
     2    util.c
     5    Copyright (C) 2001-2003, Network Resonance, Inc.
     6    Copyright (C) 2006, Network Resonance, Inc.
     7    All Rights Reserved
     9    Redistribution and use in source and binary forms, with or without
    10    modification, are permitted provided that the following conditions
    11    are met:
    13    1. Redistributions of source code must retain the above copyright
    14       notice, this list of conditions and the following disclaimer.
    15    2. Redistributions in binary form must reproduce the above copyright
    16       notice, this list of conditions and the following disclaimer in the
    17       documentation and/or other materials provided with the distribution.
    18    3. Neither the name of Network Resonance, Inc. nor the name of any
    19       contributors to this software may be used to endorse or promote
    20       products derived from this software without specific prior written
    21       permission.
    23    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
    24    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    25    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    26    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    27    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    28    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    29    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    30    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    31    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    32    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    33    POSSIBILITY OF SUCH DAMAGE.
    36    ekr@rtfm.com  Wed Dec 26 17:19:36 2001
    37  */
    40 static char *RCSSTRING __UNUSED__ ="$Id: util.c,v 1.5 2007/11/21 00:09:13 adamcain Exp $";
    42 #ifndef WIN32
    43 #include <sys/uio.h>
    44 #include <pwd.h>
    45 #include <dirent.h>
    46 #endif
    47 #include <string.h>
    48 #include <errno.h>
    49 #include <ctype.h>
    50 #include <sys/stat.h>
    51 #ifdef OPENSSL
    52 #include <openssl/evp.h>
    53 #endif
    54 #include "nr_common.h"
    55 #include "r_common.h"
    56 #include "registry.h"
    57 #include "util.h"
    58 #include "r_log.h"
    60 int nr_util_default_log_facility=LOG_COMMON;
    62 int nr_get_filename(base,name,namep)
    63   char *base;
    64   char *name;
    65   char **namep;
    66   {
    67     int len=strlen(base)+strlen(name)+2;
    68     char *ret=0;
    69     int _status;
    71     if(!(ret=(char *)RMALLOC(len)))
    72       ABORT(R_NO_MEMORY);
    73     if(base[strlen(base)-1]!='/'){
    74       sprintf(ret,"%s/%s",base,name);
    75     }
    76     else{
    77       sprintf(ret,"%s%s",base,name);
    78     }
    79     *namep=ret;
    80     _status=0;
    81   abort:
    82     return(_status);
    83   }
    85 #if 0
    86 int read_RSA_private_key(base,name,keyp)
    87   char *base;
    88   char *name;
    89   RSA **keyp;
    90   {
    91     char *keyfile=0;
    92     BIO *bio=0;
    93     FILE *fp=0;
    94     RSA *rsa=0;
    95     int r,_status;
    97     /* Load the keyfile */
    98     if(r=get_filename(base,name,&keyfile))
    99       ABORT(r);
   100     if(!(fp=fopen(keyfile,"r")))
   101       ABORT(R_NOT_FOUND);
   102     if(!(bio=BIO_new(BIO_s_file())))
   103       ABORT(R_NO_MEMORY);
   104     BIO_set_fp(bio,fp,BIO_NOCLOSE);
   106     if(!(rsa=PEM_read_bio_RSAPrivateKey(bio,0,0,0)))
   107       ABORT(R_NOT_FOUND);
   109     *keyp=rsa;
   110     _status=0;
   111   abort:
   112     return(_status);
   113   }
   114 #endif
   117 void nr_errprintf_log(const char *format,...)
   118   {
   119     va_list ap;
   121     va_start(ap,format);
   123     r_vlog(nr_util_default_log_facility,LOG_ERR,format,ap);
   125     va_end(ap);
   126   }
   128 void nr_errprintf_log2(void *ignore, const char *format,...)
   129   {
   130     va_list ap;
   132     va_start(ap,format);
   134     r_vlog(nr_util_default_log_facility,LOG_ERR,format,ap);
   136     va_end(ap);
   137   }
   140 int nr_fwrite_all(FILE *fp,UCHAR *buf,int len)
   141   {
   142     int r,_status;
   144     while(len){
   145       r=fwrite(buf,1,len,fp);
   146       if(r==0)
   147         ABORT(R_IO_ERROR);
   149       len-=r;
   150       buf+=r;
   151     }
   153     _status=0;
   154   abort:
   155     return(_status);
   156   }
   158 int nr_read_data(fd,buf,len)
   159   int fd;
   160   char *buf;
   161   int len;
   162   {
   163     int r,_status;
   165     while(len){
   166       r=NR_SOCKET_READ(fd,buf,len);
   167       if(r<=0)
   168         ABORT(R_EOD);
   170       buf+=r;
   171       len-=r;
   172     }
   175     _status=0;
   176   abort:
   177     return(_status);
   178   }
   180 #ifdef WIN32
   181   // TODO
   182 #else
   183 int nr_drop_privileges(char *username)
   184   {
   185     int _status;
   187     /* Drop privileges */
   188     if ((getuid() == 0) || geteuid()==0) {
   189       struct passwd *passwd;
   191       if ((passwd = getpwnam(CAPTURE_USER)) == 0){
   192         r_log(LOG_GENERIC,LOG_EMERG,"Couldn't get user %s",CAPTURE_USER);
   193         ABORT(R_INTERNAL);
   194       }
   196       if(setuid(passwd->pw_uid)!=0){
   197         r_log(LOG_GENERIC,LOG_EMERG,"Couldn't drop privileges");
   198         ABORT(R_INTERNAL);
   199       }
   200     }
   202     _status=0;
   203   abort:
   204     return(_status);
   205   }
   206 #endif
   208 int nr_bin2hex(UCHAR *in,int len,UCHAR *out)
   209   {
   210     while(len){
   211       sprintf((char*)out,"%.2x",in[0] & 0xff);
   213       in+=1;
   214       out+=2;
   216       len--;
   217     }
   219     return(0);
   220   }
   222 int nr_hex_ascii_dump(Data *data)
   223   {
   224     UCHAR *ptr=data->data;
   225     int len=data->len;
   227     while(len){
   228       int i;
   229       int bytes=MIN(len,16);
   231       for(i=0;i<bytes;i++)
   232         printf("%.2x ",ptr[i]&255);
   233       /* Fill */
   234       for(i=0;i<(16-bytes);i++)
   235         printf("   ");
   236       printf("   ");
   238       for(i=0;i<bytes;i++){
   239         if(isprint(ptr[i]))
   240           printf("%c",ptr[i]);
   241         else
   242           printf(".");
   243       }
   244       printf("\n");
   246       len-=bytes;
   247       ptr+=bytes;
   248     }
   249     return(0);
   250   }
   252 #ifdef OPENSSL
   253 int nr_sha1_file(char *filename,UCHAR *out)
   254   {
   255     EVP_MD_CTX md_ctx;
   256     FILE *fp=0;
   257     int r,_status;
   258     UCHAR buf[1024];
   259     int out_len;
   261     EVP_MD_CTX_init(&md_ctx);
   263     if(!(fp=fopen(filename,"r"))){
   264       r_log(LOG_COMMON,LOG_ERR,"Couldn't open file %s",filename);
   265       ABORT(R_NOT_FOUND);
   266     }
   268     EVP_DigestInit_ex(&md_ctx,EVP_sha1(),0);
   270     while(1){
   271       r=fread(buf,1,sizeof(buf),fp);
   273       if(r<0){
   274         r_log(LOG_COMMON,LOG_ERR,"Error reading from %s",filename);
   275         ABORT(R_INTERNAL);
   276       }
   278       if(!r)
   279         break;
   281       EVP_DigestUpdate(&md_ctx,buf,r);
   282     }
   284     EVP_DigestFinal(&md_ctx,out,(unsigned int*)&out_len);
   285     if(out_len!=20)
   286       ABORT(R_INTERNAL);
   288     _status=0;
   289   abort:
   290     EVP_MD_CTX_cleanup(&md_ctx);
   291     if(fp) fclose(fp);
   293     return(_status);
   294   }
   296 #endif
   298 #ifdef WIN32
   299   // TODO
   300 #else
   302 #if 0
   304 #include <fts.h>
   306 int nr_rm_tree(char *path)
   307   {
   308     FTS *fts=0;
   309     FTSENT *p;
   310     int failed=0;
   311     int _status;
   312     char *argv[2];
   314     argv[0]=path;
   315     argv[1]=0;
   317     if(!(fts=fts_open(argv,0,NULL))){
   318       r_log_e(LOG_COMMON,LOG_ERR,"Couldn't open directory %s",path);
   319       ABORT(R_FAILED);
   320     }
   322     while(p=fts_read(fts)){
   323       switch(p->fts_info){
   324         case FTS_D:
   325           break;
   326         case FTS_DOT:
   327           break;
   328         case FTS_ERR:
   329           r_log_e(LOG_COMMON,LOG_ERR,"Problem reading %s",p->fts_path);
   330           break;
   331         default:
   332           r_log(LOG_COMMON,LOG_DEBUG,"Removing %s",p->fts_path);
   333           errno=0;
   334           if(remove(p->fts_path)){
   335             r_log_e(LOG_COMMON,LOG_ERR,"Problem removing %s",p->fts_path);
   336             failed=1;
   337           }
   338       }
   339     }
   341     if(failed)
   342       ABORT(R_FAILED);
   344     _status=0;
   345   abort:
   346     if(fts) fts_close(fts);
   347     return(_status);
   348   }
   349 #endif
   351 int nr_write_pid_file(char *pid_filename)
   352   {
   353     FILE *fp;
   354     int _status;
   356     if(!pid_filename)
   357       ABORT(R_BAD_ARGS);
   359     unlink(pid_filename);
   361     if(!(fp=fopen(pid_filename,"w"))){
   362       r_log(LOG_GENERIC,LOG_CRIT,"Couldn't open PID file: %s",strerror(errno));
   363       ABORT(R_NOT_FOUND);
   364     }
   366     fprintf(fp,"%d\n",getpid());
   368     fclose(fp);
   370     chmod(pid_filename,S_IRUSR | S_IRGRP | S_IROTH);
   372     _status=0;
   373   abort:
   374     return(_status);
   375   }
   376 #endif
   378 int nr_reg_uint4_fetch_and_check(NR_registry key, UINT4 min, UINT4 max, int log_fac, int die, UINT4 *val)
   379   {
   380     int r,_status;
   381     UINT4 my_val;
   383     if(r=NR_reg_get_uint4(key,&my_val)){
   384       r_log(log_fac,LOG_ERR,"Couldn't get key '%s', error %d",key,r);
   385       ABORT(r);
   386     }
   388     if((min>0) && (my_val<min)){
   389       r_log(log_fac,LOG_ERR,"Invalid value for key '%s'=%lu, (min = %lu)",key,(unsigned long)my_val,(unsigned long)min);
   390       ABORT(R_BAD_DATA);
   391     }
   393     if(my_val>max){
   394       r_log(log_fac,LOG_ERR,"Invalid value for key '%s'=%lu, (max = %lu)",key,(unsigned long)my_val,(unsigned long)max);
   395       ABORT(R_BAD_DATA);
   396     }
   398     *val=my_val;
   399     _status=0;
   401   abort:
   402     if(die && _status){
   403       r_log(log_fac,LOG_CRIT,"Exiting due to invalid configuration (key '%s')",key);
   404       exit(1);
   405     }
   406     return(_status);
   407   }
   409 int nr_reg_uint8_fetch_and_check(NR_registry key, UINT8 min, UINT8 max, int log_fac, int die, UINT8 *val)
   410   {
   411     int r,_status;
   412     UINT8 my_val;
   414     if(r=NR_reg_get_uint8(key,&my_val)){
   415       r_log(log_fac,LOG_ERR,"Couldn't get key '%s', error %d",key,r);
   416       ABORT(r);
   417     }
   419     if(my_val<min){
   420       r_log(log_fac,LOG_ERR,"Invalid value for key '%s'=%llu, (min = %llu)",key,my_val,min);
   421       ABORT(R_BAD_DATA);
   422     }
   424     if(my_val>max){
   425       r_log(log_fac,LOG_ERR,"Invalid value for key '%s'=%llu, (max = %llu)",key,my_val,max);
   426       ABORT(R_BAD_DATA);
   427     }
   429     *val=my_val;
   430     _status=0;
   432   abort:
   433     if(die && _status){
   434       r_log(log_fac,LOG_CRIT,"Exiting due to invalid configuration (key '%s')",key);
   435       exit(1);
   436     }
   437     return(_status);
   438   }
   440 #if defined(LINUX) || defined(WIN32)
   441 /*-
   442  * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
   443  * All rights reserved.
   444  *
   445  * Redistribution and use in source and binary forms, with or without
   446  * modification, are permitted provided that the following conditions
   447  * are met:
   448  * 1. Redistributions of source code must retain the above copyright
   449  *    notice, this list of conditions and the following disclaimer.
   450  * 2. Redistributions in binary form must reproduce the above copyright
   451  *    notice, this list of conditions and the following disclaimer in the
   452  *    documentation and/or other materials provided with the distribution.
   453  * 3. The name of the author may not be used to endorse or promote products
   454  *    derived from this software without specific prior written permission.
   455  *
   456  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   457  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
   458  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   459  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   460  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   461  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   462  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   463  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   464  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   465  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   466  */
   469 /*
   470  * Appends src to string dst of size siz (unlike strncat, siz is the
   471  * full size of dst, not space left).  At most siz-1 characters
   472  * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
   473  * Returns strlen(src) + MIN(siz, strlen(initial dst)).
   474  * If retval >= siz, truncation occurred.
   475  */
   476 size_t
   477 strlcat(dst, src, siz)
   478         char *dst;
   479         const char *src;
   480         size_t siz;
   481 {
   482         char *d = dst;
   483         const char *s = src;
   484         size_t n = siz;
   485         size_t dlen;
   487         /* Find the end of dst and adjust bytes left but don't go past end */
   488         while (n-- != 0 && *d != '\0')
   489                 d++;
   490         dlen = d - dst;
   491         n = siz - dlen;
   493         if (n == 0)
   494                 return(dlen + strlen(s));
   495         while (*s != '\0') {
   496                 if (n != 1) {
   497                         *d++ = *s;
   498                         n--;
   499                 }
   500                 s++;
   501         }
   502         *d = '\0';
   504         return(dlen + (s - src));       /* count does not include NUL */
   505 }
   507 #endif  /* LINUX or WIN32 */
   509 #if defined(USE_OWN_INET_NTOP) || defined(WIN32)
   510 #include <errno.h>
   511 #ifdef WIN32
   512 #include <Ws2ipdef.h>
   513 #ifndef EAFNOSUPPORT
   514 #define EAFNOSUPPORT            WSAEAFNOSUPPORT
   515 #endif
   516 #else
   517 #include <sys/socket.h>
   518 #endif
   519 #define INET6
   521 /* inet_ntop implementation from NetBSD */
   523 /*
   524  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
   525  * Copyright (c) 1996-1999 by Internet Software Consortium.
   526  *
   527  * Permission to use, copy, modify, and distribute this software for any
   528  * purpose with or without fee is hereby granted, provided that the above
   529  * copyright notice and this permission notice appear in all copies.
   530  *
   531  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
   532  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   533  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
   534  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   535  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   536  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
   537  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   538  */
   540 #if !defined(NS_INADDRSZ)
   541 # define NS_INADDRSZ  4
   542 #endif
   543 #if !defined(NS_IN6ADDRSZ)
   544 # define NS_IN6ADDRSZ  16
   545 #endif
   546 #if !defined(NS_INT16SZ)
   547 # define NS_INT16SZ  2
   548 #endif
   550 /*
   551  * WARNING: Don't even consider trying to compile this on a system where
   552  * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
   553  */
   555 static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size);
   556 #ifdef INET6
   557 static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size);
   558 #endif /* INET6 */
   560 /* char *
   561  * inet_ntop(af, src, dst, size)
   562  *  convert a network format address to presentation format.
   563  * return:
   564  *  pointer to presentation format address (`dst'), or NULL (see errno).
   565  * author:
   566  *  Paul Vixie, 1996.
   567  */
   568 const char *
   569 inet_ntop(int af, const void *src, char *dst, size_t size)
   570 {
   572   switch (af) {
   573   case AF_INET:
   574     return (inet_ntop4(src, dst, size));
   575 #ifdef INET6
   576   case AF_INET6:
   577     return (inet_ntop6(src, dst, size));
   578 #endif /* INET6 */
   579   default:
   580     errno = EAFNOSUPPORT;
   581     return (NULL);
   582   }
   583   /* NOTREACHED */
   584 }
   586 /* const char *
   587  * inet_ntop4(src, dst, size)
   588  *  format an IPv4 address, more or less like inet_ntoa()
   589  * return:
   590  *  `dst' (as a const)
   591  * notes:
   592  *  (1) uses no statics
   593  *  (2) takes a unsigned char* not an in_addr as input
   594  * author:
   595  *  Paul Vixie, 1996.
   596  */
   597 static const char *
   598 inet_ntop4(const unsigned char *src, char *dst, size_t size)
   599 {
   600   char tmp[sizeof "255.255.255.255"];
   601   int l;
   603   l = snprintf(tmp, sizeof(tmp), "%u.%u.%u.%u",
   604       src[0], src[1], src[2], src[3]);
   605   if (l <= 0 || (size_t) l >= size) {
   606     errno = ENOSPC;
   607     return (NULL);
   608   }
   609   strlcpy(dst, tmp, size);
   610   return (dst);
   611 }
   613 #ifdef INET6
   614 /* const char *
   615  * inet_ntop6(src, dst, size)
   616  *  convert IPv6 binary address into presentation (printable) format
   617  * author:
   618  *  Paul Vixie, 1996.
   619  */
   620 static const char *
   621 inet_ntop6(const unsigned char *src, char *dst, size_t size)
   622 {
   623   /*
   624    * Note that int32_t and int16_t need only be "at least" large enough
   625    * to contain a value of the specified size.  On some systems, like
   626    * Crays, there is no such thing as an integer variable with 16 bits.
   627    * Keep this in mind if you think this function should have been coded
   628    * to use pointer overlays.  All the world's not a VAX.
   629    */
   630   char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
   631   char *tp, *ep;
   632   struct { int base, len; } best, cur;
   633   unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
   634   int i;
   635   int advance;
   637   /*
   638    * Preprocess:
   639    *  Copy the input (bytewise) array into a wordwise array.
   640    *  Find the longest run of 0x00's in src[] for :: shorthanding.
   641    */
   642   memset(words, '\0', sizeof words);
   643   for (i = 0; i < NS_IN6ADDRSZ; i++)
   644     words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
   645   best.base = -1;
   646   cur.base = -1;
   647   best.len = -1;  /* XXX gcc */
   648   cur.len = -1;  /* XXX gcc */
   649   for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
   650     if (words[i] == 0) {
   651       if (cur.base == -1)
   652         cur.base = i, cur.len = 1;
   653       else
   654         cur.len++;
   655     } else {
   656       if (cur.base != -1) {
   657         if (best.base == -1 || cur.len > best.len)
   658           best = cur;
   659         cur.base = -1;
   660       }
   661     }
   662   }
   663   if (cur.base != -1) {
   664     if (best.base == -1 || cur.len > best.len)
   665       best = cur;
   666   }
   667   if (best.base != -1 && best.len < 2)
   668     best.base = -1;
   670   /*
   671    * Format the result.
   672    */
   673   tp = tmp;
   674   ep = tmp + sizeof(tmp);
   675   for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
   676     /* Are we inside the best run of 0x00's? */
   677     if (best.base != -1 && i >= best.base &&
   678         i < (best.base + best.len)) {
   679       if (i == best.base)
   680         *tp++ = ':';
   681       continue;
   682     }
   683     /* Are we following an initial run of 0x00s or any real hex? */
   684     if (i != 0) {
   685       if (tp + 1 >= ep)
   686         return (NULL);
   687       *tp++ = ':';
   688     }
   689     /* Is this address an encapsulated IPv4? */
   690     if (i == 6 && best.base == 0 &&
   691         (best.len == 6 ||
   692         (best.len == 7 && words[7] != 0x0001) ||
   693         (best.len == 5 && words[5] == 0xffff))) {
   694       if (!inet_ntop4(src+12, tp, (size_t)(ep - tp)))
   695         return (NULL);
   696       tp += strlen(tp);
   697       break;
   698     }
   699     advance = snprintf(tp, (size_t)(ep - tp), "%x", words[i]);
   700     if (advance <= 0 || advance >= ep - tp)
   701       return (NULL);
   702     tp += advance;
   703   }
   704   /* Was it a trailing run of 0x00's? */
   705   if (best.base != -1 && (best.base + best.len) ==
   706       (NS_IN6ADDRSZ / NS_INT16SZ)) {
   707     if (tp + 1 >= ep)
   708       return (NULL);
   709     *tp++ = ':';
   710   }
   711   if (tp + 1 >= ep)
   712     return (NULL);
   713   *tp++ = '\0';
   715   /*
   716    * Check for overflow, copy, and we're done.
   717    */
   718   if ((size_t)(tp - tmp) > size) {
   719     errno = ENOSPC;
   720     return (NULL);
   721   }
   722   strlcpy(dst, tmp, size);
   723   return (dst);
   724 }
   725 #endif /* INET6 */
   727 #endif
   729 #ifdef WIN32
   730 #include <time.h>
   731 /* this is only millisecond-accurate, but that should be OK */
   733 int gettimeofday(struct timeval *tv, void *tz)
   734   {
   735     SYSTEMTIME st;
   736     FILETIME ft;
   737     ULARGE_INTEGER u;
   739     GetLocalTime (&st);
   741     /* strangely, the FILETIME is the number of 100 nanosecond (0.1 us) intervals
   742      * since the Epoch */
   743     SystemTimeToFileTime(&st, &ft);
   744     u.HighPart = ft.dwHighDateTime;
   745     u.LowPart = ft.dwLowDateTime;
   747     tv->tv_sec = (long) (u.QuadPart / 10000000L);
   748     tv->tv_usec = (long) (st.wMilliseconds * 1000);;
   750     return 0;
   751   }
   753 int snprintf(char *buffer, size_t n, const char *format, ...)
   754 {
   755   va_list argp;
   756   int ret;
   757   va_start(argp, format);
   758   ret = _vscprintf(format, argp);
   759   vsnprintf_s(buffer, n, _TRUNCATE, format, argp);
   760   va_end(argp);
   761   return ret;
   762 }
   764 #endif

mercurial