httpd: explain IP/mask parsing, and simplify it a bit.

parse_conf                                          1258    1247     -11
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-11)             Total: -11 bytes
   text    data     bss     dec     hex filename
 772602    1058   11092  784752   bf970 busybox_old
 772594    1058   11092  784744   bf968 busybox_unstripped
This commit is contained in:
Denis Vlasenko 2007-08-19 21:15:42 +00:00
parent 921799da4e
commit d867f32a7a

View File

@ -289,17 +289,26 @@ static ALWAYS_INLINE void free_Htaccess_IP_list(Htaccess_IP **pptr)
free_llist((has_next_ptr**)pptr);
}
static int scan_ip(const char **ep, unsigned *ip, unsigned char endc)
//#undef isdigit
//#define isdigit(a) ((unsigned)((a) - '0') <= 9)
//#define notdigit(a) ((unsigned)((a) - '0') > 9)
/* Returns presumed mask width in bits or < 0 on error.
* Updates strp, stores IP at provided pointer */
static int scan_ip(const char **strp, unsigned *ipp, unsigned char endc)
{
const char *p = *ep;
const char *p = *strp;
int auto_mask = 8;
unsigned ip = 0;
int j;
*ip = 0;
if (*p == '/')
return -auto_mask;
for (j = 0; j < 4; j++) {
unsigned octet;
if ((*p < '0' || *p > '9') && (*p != '/' || j == 0) && *p != '\0')
if ((*p < '0' || *p > '9') && *p != '/' && *p)
return -auto_mask;
octet = 0;
while (*p >= '0' && *p <= '9') {
@ -311,55 +320,61 @@ static int scan_ip(const char **ep, unsigned *ip, unsigned char endc)
}
if (*p == '.')
p++;
if (*p != '/' && *p != '\0')
if (*p != '/' && *p)
auto_mask += 8;
*ip = ((*ip) << 8) | octet;
ip = (ip << 8) | octet;
}
if (*p != '\0') {
if (*p) {
if (*p != endc)
return -auto_mask;
p++;
if (*p == '\0')
return -auto_mask;
}
*ep = p;
*ipp = ip;
*strp = p;
return auto_mask;
}
static int scan_ip_mask(const char *ipm, unsigned *ip, unsigned *mask)
/* Returns 0 on success. Stores IP and mask at provided pointers */
static int scan_ip_mask(const char *str, unsigned *ipp, unsigned *maskp)
{
int i;
unsigned msk;
unsigned mask;
char *p;
i = scan_ip(&ipm, ip, '/');
i = scan_ip(&str, ipp, '/');
if (i < 0)
return i;
if (*ipm) {
const char *p = ipm;
i = 0;
while (*p) {
if (*p < '0' || *p > '9') {
if (*str) {
/* there is /xxx after dotted-IP address */
i = bb_strtou(str, &p, 10);
if (*p == '.') {
i = scan_ip(&ipm, mask, 0);
return i != 32;
/* 'xxx' itself is dotted-IP mask, parse it */
/* (return 0 (success) only if it has N.N.N.N form) */
return scan_ip(&str, maskp, '\0') - 32;
}
if (*p)
return -1;
}
i *= 10;
i += *p - '0';
p++;
}
}
if (i > 32 || i < 0)
if (i > 32)
return -1;
msk = 0x80000000;
*mask = 0;
while (i > 0) {
*mask |= msk;
msk >>= 1;
i--;
if (sizeof(unsigned) == 4 && i == 32) {
/* mask >>= 32 below may not work */
mask = 0;
} else {
mask = 0xffffffff;
mask >>= i;
}
/* i == 0 -> *maskp = 0x00000000
* i == 1 -> *maskp = 0x80000000
* i == 4 -> *maskp = 0xf0000000
* i == 31 -> *maskp = 0xfffffffe
* i == 32 -> *maskp = 0xffffffff */
*maskp = (uint32_t)(~mask);
return 0;
}