1 /* -------------------------------------------------------------------------
2 * util.c - htun miscellaneous utility functions
3 * Copyright (C) 2002 Moshe Jacobson <moshe@runslinux.net>,
4 * Ola Nordström <ola@triblock.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * -------------------------------------------------------------------------
21 /* $Id: util.c,v 2.18 2002/09/11 20:57:26 jehsom Exp $ */
31 #include <sys/types.h>
32 #include <sys/socket.h>
39 int xstrncasecmp( const char *s1
, const char *s2
, int n
){
40 const char *p1
=s1
, *p2
=s2
;
43 if( s1
== s2
) return 0;
45 while( *p1
&& tolower(*p1
) == tolower(*p2
) ) {
48 if( ctr
>= n
) return 0;
52 if( !*p1
&& *p2
) return -1;
53 else if( !*p2
&& *p1
) return 1;
54 else return tolower(*p1
)-tolower(*p2
);
57 int fdprintf(int fd
, char *fmt
, ...) {
58 FILE *fp
= fdopen(dup(fd
), "w");
63 rc
=vfprintf(fp
, fmt
, ap
);
70 char *recvline( char *buf
, int len
, int fd
){
75 if( c
!= '\n' && read(fd
,&c
,1) == 1 ){
83 while( c
!= '\n' && read(fd
,&c
,1) == 1 ) ctr
++;
85 "line exceeded buffer space by %d bytes.",
90 if( *buf
== '\0' ) return NULL
;
94 int recvflush( int s
) {
105 while( (rc
=select(s
+1, &fds
, NULL
, NULL
, &tv
)) ) {
107 lprintf(log
, WARN
, "select() failed: %s",
111 if( (rc
=read(s
, &c
, 1)) < 1 ) {
113 lprintf(log
, WARN
, "connection reset by peer");
115 lprintf(log
, WARN
, "read() failed: %s",
125 dprintf(log
, DEBUG
, "returning %d.", cnt
);
130 * Reads exactly len bytes from fd and returns the data in a dynamically
133 char *readloop( int fd
, size_t len
) {
136 char *buf
= malloc(len
+1);
138 if(!buf
) return NULL
;
140 dprintf(log
, DEBUG
, "attempting to read %d bytes from fd #%d",
143 if( (rc
=read(fd
,buf
+cnt
,len
-cnt
)) <= 0 ) {
145 if( errno
== EINTR
) continue;
146 lprintf(log
, WARN
, "Reading from sock fd %d: %s.", fd
,
150 "Reading from sock fd %d: Read %d bytes, expected %d",
156 dprintf(log
, DEBUG
, "read() returned %d.", rc
);
164 char **splitlines( char *buf
) {
166 char **tmp
, **ret
= NULL
;
169 if( !buf
|| !*buf
) return NULL
;
170 if( (ret
=malloc(1 + cnt
* sizeof(char**))) == NULL
) return NULL
;
173 for( cp
=buf
; *cp
; cp
++ ) {
174 if( *cp
!= '\n' ) continue;
175 if( (tmp
=realloc(ret
, (++cnt
+ 1) * sizeof(char**))) == NULL
) {
189 /* Thread-safe resolve */
191 resolve( const char *name
, struct hostent
*hostbuf
, char *buf
, size_t len
)
196 for( i
=0; i
<3; i
++ ){
197 rc
=gethostbyname_r(name
, hostbuf
, buf
, len
, &hp
, &herr
);
200 } else if( herr
== TRY_AGAIN
){
210 long base64_encode( char *to
, const char *from
, unsigned int len
) {
212 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
213 const char *fromp
= from
;
214 char end
[3], *top
= to
;
215 unsigned char cbyte
, obyte
;
217 for (; len
>= 3; len
-= 3) {
219 *top
++ = b64string
[(int)(cbyte
>> 2)];
220 obyte
= (cbyte
<< 4) & 0x30; /* 0011 0000 */
223 obyte
|= (cbyte
>> 4); /* 0000 1111 */
224 *top
++ = b64string
[(int)obyte
];
225 obyte
= (cbyte
<< 2) & 0x3C; /* 0011 1100 */
228 obyte
|= (cbyte
>> 6); /* 0000 0011 */
229 *top
++ = b64string
[(int)obyte
];
230 *top
++ = b64string
[(int)(cbyte
& 0x3F)];/* 0011 1111 */
235 if (--len
) end
[1] = *fromp
++; else end
[1] = 0;
239 *top
++ = b64string
[(int)(cbyte
>> 2)];
240 obyte
= (cbyte
<< 4) & 0x30; /* 0011 0000 */
243 obyte
|= (cbyte
>> 4);
244 *top
++ = b64string
[(int)obyte
];
245 obyte
= (cbyte
<< 2) & 0x3C; /* 0011 1100 */
247 if (len
) *top
++ = b64string
[(int)obyte
];