LCOV - code coverage report
Current view: top level - media/mtransport/third_party/nrappkit/src/util - util.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 135 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /**
       2             :    util.c
       3             : 
       4             : 
       5             :    Copyright (C) 2001-2003, Network Resonance, Inc.
       6             :    Copyright (C) 2006, Network Resonance, Inc.
       7             :    All Rights Reserved
       8             : 
       9             :    Redistribution and use in source and binary forms, with or without
      10             :    modification, are permitted provided that the following conditions
      11             :    are met:
      12             : 
      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.
      22             : 
      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.
      34             : 
      35             : 
      36             :    ekr@rtfm.com  Wed Dec 26 17:19:36 2001
      37             :  */
      38             : 
      39             : 
      40             : static char *RCSSTRING __UNUSED__ ="$Id: util.c,v 1.5 2007/11/21 00:09:13 adamcain Exp $";
      41             : 
      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"
      59             : 
      60             : int nr_util_default_log_facility=LOG_COMMON;
      61             : 
      62           0 : int nr_get_filename(base,name,namep)
      63             :   char *base;
      64             :   char *name;
      65             :   char **namep;
      66             :   {
      67           0 :     int len=strlen(base)+strlen(name)+2;
      68           0 :     char *ret=0;
      69             :     int _status;
      70             : 
      71           0 :     if(!(ret=(char *)RMALLOC(len)))
      72           0 :       ABORT(R_NO_MEMORY);
      73           0 :     if(base[strlen(base)-1]!='/'){
      74           0 :       sprintf(ret,"%s/%s",base,name);
      75             :     }
      76             :     else{
      77           0 :       sprintf(ret,"%s%s",base,name);
      78             :     }
      79           0 :     *namep=ret;
      80           0 :     _status=0;
      81             :   abort:
      82           0 :     return(_status);
      83             :   }
      84             : 
      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;
      96             : 
      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);
     105             : 
     106             :     if(!(rsa=PEM_read_bio_RSAPrivateKey(bio,0,0,0)))
     107             :       ABORT(R_NOT_FOUND);
     108             : 
     109             :     *keyp=rsa;
     110             :     _status=0;
     111             :   abort:
     112             :     return(_status);
     113             :   }
     114             : #endif
     115             : 
     116             : 
     117           0 : void nr_errprintf_log(const char *format,...)
     118             :   {
     119             :     va_list ap;
     120             : 
     121           0 :     va_start(ap,format);
     122             : 
     123           0 :     r_vlog(nr_util_default_log_facility,LOG_ERR,format,ap);
     124             : 
     125           0 :     va_end(ap);
     126           0 :   }
     127             : 
     128           0 : void nr_errprintf_log2(void *ignore, const char *format,...)
     129             :   {
     130             :     va_list ap;
     131             : 
     132           0 :     va_start(ap,format);
     133             : 
     134           0 :     r_vlog(nr_util_default_log_facility,LOG_ERR,format,ap);
     135             : 
     136           0 :     va_end(ap);
     137           0 :   }
     138             : 
     139             : 
     140           0 : int nr_fwrite_all(FILE *fp,UCHAR *buf,int len)
     141             :   {
     142             :     int r,_status;
     143             : 
     144           0 :     while(len){
     145           0 :       r=fwrite(buf,1,len,fp);
     146           0 :       if(r==0)
     147           0 :         ABORT(R_IO_ERROR);
     148             : 
     149           0 :       len-=r;
     150           0 :       buf+=r;
     151             :     }
     152             : 
     153           0 :     _status=0;
     154             :   abort:
     155           0 :     return(_status);
     156             :   }
     157             : 
     158           0 : int nr_read_data(fd,buf,len)
     159             :   int fd;
     160             :   char *buf;
     161             :   int len;
     162             :   {
     163             :     int r,_status;
     164             : 
     165           0 :     while(len){
     166           0 :       r=NR_SOCKET_READ(fd,buf,len);
     167           0 :       if(r<=0)
     168           0 :         ABORT(R_EOD);
     169             : 
     170           0 :       buf+=r;
     171           0 :       len-=r;
     172             :     }
     173             : 
     174             : 
     175           0 :     _status=0;
     176             :   abort:
     177           0 :     return(_status);
     178             :   }
     179             : 
     180             : #ifdef WIN32
     181             :   // TODO
     182             : #else
     183           0 : int nr_drop_privileges(char *username)
     184             :   {
     185             :     int _status;
     186             : 
     187             :     /* Drop privileges */
     188           0 :     if ((getuid() == 0) || geteuid()==0) {
     189             :       struct passwd *passwd;
     190             : 
     191           0 :       if ((passwd = getpwnam(CAPTURE_USER)) == 0){
     192           0 :         r_log(LOG_GENERIC,LOG_EMERG,"Couldn't get user %s",CAPTURE_USER);
     193           0 :         ABORT(R_INTERNAL);
     194             :       }
     195             : 
     196           0 :       if(setuid(passwd->pw_uid)!=0){
     197           0 :         r_log(LOG_GENERIC,LOG_EMERG,"Couldn't drop privileges");
     198           0 :         ABORT(R_INTERNAL);
     199             :       }
     200             :     }
     201             : 
     202           0 :     _status=0;
     203             :   abort:
     204           0 :     return(_status);
     205             :   }
     206             : #endif
     207             : 
     208           0 : int nr_bin2hex(UCHAR *in,int len,UCHAR *out)
     209             :   {
     210           0 :     while(len){
     211           0 :       sprintf((char*)out,"%.2x",in[0] & 0xff);
     212             : 
     213           0 :       in+=1;
     214           0 :       out+=2;
     215             : 
     216           0 :       len--;
     217             :     }
     218             : 
     219           0 :     return(0);
     220             :   }
     221             : 
     222           0 : int nr_hex_ascii_dump(Data *data)
     223             :   {
     224           0 :     UCHAR *ptr=data->data;
     225           0 :     int len=data->len;
     226             : 
     227           0 :     while(len){
     228             :       int i;
     229           0 :       int bytes=MIN(len,16);
     230             : 
     231           0 :       for(i=0;i<bytes;i++)
     232           0 :         printf("%.2x ",ptr[i]&255);
     233             :       /* Fill */
     234           0 :       for(i=0;i<(16-bytes);i++)
     235           0 :         printf("   ");
     236           0 :       printf("   ");
     237             : 
     238           0 :       for(i=0;i<bytes;i++){
     239           0 :         if(isprint(ptr[i]))
     240           0 :           printf("%c",ptr[i]);
     241             :         else
     242           0 :           printf(".");
     243             :       }
     244           0 :       printf("\n");
     245             : 
     246           0 :       len-=bytes;
     247           0 :       ptr+=bytes;
     248             :     }
     249           0 :     return(0);
     250             :   }
     251             : 
     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;
     260             : 
     261             :     EVP_MD_CTX_init(&md_ctx);
     262             : 
     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             :     }
     267             : 
     268             :     EVP_DigestInit_ex(&md_ctx,EVP_sha1(),0);
     269             : 
     270             :     while(1){
     271             :       r=fread(buf,1,sizeof(buf),fp);
     272             : 
     273             :       if(r<0){
     274             :         r_log(LOG_COMMON,LOG_ERR,"Error reading from %s",filename);
     275             :         ABORT(R_INTERNAL);
     276             :       }
     277             : 
     278             :       if(!r)
     279             :         break;
     280             : 
     281             :       EVP_DigestUpdate(&md_ctx,buf,r);
     282             :     }
     283             : 
     284             :     EVP_DigestFinal(&md_ctx,out,(unsigned int*)&out_len);
     285             :     if(out_len!=20)
     286             :       ABORT(R_INTERNAL);
     287             : 
     288             :     _status=0;
     289             :   abort:
     290             :     EVP_MD_CTX_cleanup(&md_ctx);
     291             :     if(fp) fclose(fp);
     292             : 
     293             :     return(_status);
     294             :   }
     295             : 
     296             : #endif
     297             : 
     298             : #ifdef WIN32
     299             :   // TODO
     300             : #else
     301             : 
     302             : #if 0
     303             : 
     304             : #include <fts.h>
     305             : 
     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];
     313             : 
     314             :     argv[0]=path;
     315             :     argv[1]=0;
     316             : 
     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             :     }
     321             : 
     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             :     }
     340             : 
     341             :     if(failed)
     342             :       ABORT(R_FAILED);
     343             : 
     344             :     _status=0;
     345             :   abort:
     346             :     if(fts) fts_close(fts);
     347             :     return(_status);
     348             :   }
     349             : #endif
     350             : 
     351           0 : int nr_write_pid_file(char *pid_filename)
     352             :   {
     353             :     FILE *fp;
     354             :     int _status;
     355             : 
     356           0 :     if(!pid_filename)
     357           0 :       ABORT(R_BAD_ARGS);
     358             : 
     359           0 :     unlink(pid_filename);
     360             : 
     361           0 :     if(!(fp=fopen(pid_filename,"w"))){
     362           0 :       r_log(LOG_GENERIC,LOG_CRIT,"Couldn't open PID file: %s",strerror(errno));
     363           0 :       ABORT(R_NOT_FOUND);
     364             :     }
     365             : 
     366           0 :     fprintf(fp,"%d\n",getpid());
     367             : 
     368           0 :     fclose(fp);
     369             : 
     370           0 :     chmod(pid_filename,S_IRUSR | S_IRGRP | S_IROTH);
     371             : 
     372           0 :     _status=0;
     373             :   abort:
     374           0 :     return(_status);
     375             :   }
     376             : #endif
     377             : 
     378           0 : 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;
     382             : 
     383           0 :     if(r=NR_reg_get_uint4(key,&my_val)){
     384           0 :       r_log(log_fac,LOG_ERR,"Couldn't get key '%s', error %d",key,r);
     385           0 :       ABORT(r);
     386             :     }
     387             : 
     388           0 :     if((min>0) && (my_val<min)){
     389           0 :       r_log(log_fac,LOG_ERR,"Invalid value for key '%s'=%lu, (min = %lu)",key,(unsigned long)my_val,(unsigned long)min);
     390           0 :       ABORT(R_BAD_DATA);
     391             :     }
     392             : 
     393           0 :     if(my_val>max){
     394           0 :       r_log(log_fac,LOG_ERR,"Invalid value for key '%s'=%lu, (max = %lu)",key,(unsigned long)my_val,(unsigned long)max);
     395           0 :       ABORT(R_BAD_DATA);
     396             :     }
     397             : 
     398           0 :     *val=my_val;
     399           0 :     _status=0;
     400             : 
     401             :   abort:
     402           0 :     if(die && _status){
     403           0 :       r_log(log_fac,LOG_CRIT,"Exiting due to invalid configuration (key '%s')",key);
     404           0 :       exit(1);
     405             :     }
     406           0 :     return(_status);
     407             :   }
     408             : 
     409           0 : 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;
     413             : 
     414           0 :     if(r=NR_reg_get_uint8(key,&my_val)){
     415           0 :       r_log(log_fac,LOG_ERR,"Couldn't get key '%s', error %d",key,r);
     416           0 :       ABORT(r);
     417             :     }
     418             : 
     419           0 :     if(my_val<min){
     420           0 :       r_log(log_fac,LOG_ERR,"Invalid value for key '%s'=%llu, (min = %llu)",key,my_val,min);
     421           0 :       ABORT(R_BAD_DATA);
     422             :     }
     423             : 
     424           0 :     if(my_val>max){
     425           0 :       r_log(log_fac,LOG_ERR,"Invalid value for key '%s'=%llu, (max = %llu)",key,my_val,max);
     426           0 :       ABORT(R_BAD_DATA);
     427             :     }
     428             : 
     429           0 :     *val=my_val;
     430           0 :     _status=0;
     431             : 
     432             :   abort:
     433           0 :     if(die && _status){
     434           0 :       r_log(log_fac,LOG_CRIT,"Exiting due to invalid configuration (key '%s')",key);
     435           0 :       exit(1);
     436             :     }
     437           0 :     return(_status);
     438             :   }
     439             : 
     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             :  */
     467             : 
     468             : 
     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           0 : strlcat(dst, src, siz)
     478             :         char *dst;
     479             :         const char *src;
     480             :         size_t siz;
     481             : {
     482           0 :         char *d = dst;
     483           0 :         const char *s = src;
     484           0 :         size_t n = siz;
     485             :         size_t dlen;
     486             : 
     487             :         /* Find the end of dst and adjust bytes left but don't go past end */
     488           0 :         while (n-- != 0 && *d != '\0')
     489           0 :                 d++;
     490           0 :         dlen = d - dst;
     491           0 :         n = siz - dlen;
     492             : 
     493           0 :         if (n == 0)
     494           0 :                 return(dlen + strlen(s));
     495           0 :         while (*s != '\0') {
     496           0 :                 if (n != 1) {
     497           0 :                         *d++ = *s;
     498           0 :                         n--;
     499             :                 }
     500           0 :                 s++;
     501             :         }
     502           0 :         *d = '\0';
     503             : 
     504           0 :         return(dlen + (s - src));       /* count does not include NUL */
     505             : }
     506             : 
     507             : #endif  /* LINUX or WIN32 */
     508             : 
     509             : #if defined(USE_OWN_INET_NTOP) || (defined(WIN32) && WINVER < 0x0600)
     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
     520             : 
     521             : /* inet_ntop implementation from NetBSD */
     522             : 
     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             :  */
     539             : 
     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
     549             : 
     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             :  */
     554             : 
     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 */
     559             : 
     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             : {
     571             : 
     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             : }
     585             : 
     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;
     602             : 
     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             : }
     612             : 
     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;
     636             : 
     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;
     669             : 
     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';
     714             : 
     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 */
     726             : 
     727             : #ifdef WIN32
     728             : /* Not exactly, will forgive stuff like <addr>:<port> */
     729             : int inet_pton(int af, const char *src, void *dst)
     730             : {
     731             :   struct sockaddr_storage ss;
     732             :   int addrlen = sizeof(ss);
     733             : 
     734             :   if (af != AF_INET && af != AF_INET6) {
     735             :     return -1;
     736             :   }
     737             : 
     738             :   if (!WSAStringToAddressA(src, af, NULL, (struct sockaddr*)&ss, &addrlen)) {
     739             :     if (af == AF_INET) {
     740             :       struct sockaddr_in *in = (struct sockaddr_in*)&ss;
     741             :       memcpy(dst, &in->sin_addr, sizeof(struct in_addr));
     742             :     } else {
     743             :       struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&ss;
     744             :       memcpy(dst, &in6->sin6_addr, sizeof(struct in6_addr));
     745             :     }
     746             :     return 1;
     747             :   }
     748             :   return 0;
     749             : }
     750             : #endif /* WIN32 */
     751             : 
     752             : #endif
     753             : 
     754             : #ifdef WIN32
     755             : #include <time.h>
     756             : /* this is only millisecond-accurate, but that should be OK */
     757             : 
     758             : int gettimeofday(struct timeval *tv, void *tz)
     759             :   {
     760             :     SYSTEMTIME st;
     761             :     FILETIME ft;
     762             :     ULARGE_INTEGER u;
     763             : 
     764             :     GetLocalTime (&st);
     765             : 
     766             :     /* strangely, the FILETIME is the number of 100 nanosecond (0.1 us) intervals
     767             :      * since the Epoch */
     768             :     SystemTimeToFileTime(&st, &ft);
     769             :     u.HighPart = ft.dwHighDateTime;
     770             :     u.LowPart = ft.dwLowDateTime;
     771             : 
     772             :     tv->tv_sec = (long) (u.QuadPart / 10000000L);
     773             :     tv->tv_usec = (long) (st.wMilliseconds * 1000);;
     774             : 
     775             :     return 0;
     776             :   }
     777             : #endif
     778             : 

Generated by: LCOV version 1.13