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); 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; int auto_mask = 8;
unsigned ip = 0;
int j; int j;
*ip = 0; if (*p == '/')
return -auto_mask;
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
unsigned octet; unsigned octet;
if ((*p < '0' || *p > '9') && (*p != '/' || j == 0) && *p != '\0') if ((*p < '0' || *p > '9') && *p != '/' && *p)
return -auto_mask; return -auto_mask;
octet = 0; octet = 0;
while (*p >= '0' && *p <= '9') { while (*p >= '0' && *p <= '9') {
@ -311,55 +320,61 @@ static int scan_ip(const char **ep, unsigned *ip, unsigned char endc)
} }
if (*p == '.') if (*p == '.')
p++; p++;
if (*p != '/' && *p != '\0') if (*p != '/' && *p)
auto_mask += 8; auto_mask += 8;
*ip = ((*ip) << 8) | octet; ip = (ip << 8) | octet;
} }
if (*p != '\0') { if (*p) {
if (*p != endc) if (*p != endc)
return -auto_mask; return -auto_mask;
p++; p++;
if (*p == '\0') if (*p == '\0')
return -auto_mask; return -auto_mask;
} }
*ep = p; *ipp = ip;
*strp = p;
return auto_mask; 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; int i;
unsigned msk; unsigned mask;
char *p;
i = scan_ip(&ipm, ip, '/'); i = scan_ip(&str, ipp, '/');
if (i < 0) if (i < 0)
return i; return i;
if (*ipm) {
const char *p = ipm;
i = 0; if (*str) {
while (*p) { /* there is /xxx after dotted-IP address */
if (*p < '0' || *p > '9') { i = bb_strtou(str, &p, 10);
if (*p == '.') { if (*p == '.') {
i = scan_ip(&ipm, mask, 0); /* 'xxx' itself is dotted-IP mask, parse it */
return i != 32; /* (return 0 (success) only if it has N.N.N.N form) */
return scan_ip(&str, maskp, '\0') - 32;
} }
if (*p)
return -1; return -1;
} }
i *= 10;
i += *p - '0'; if (i > 32)
p++;
}
}
if (i > 32 || i < 0)
return -1; return -1;
msk = 0x80000000;
*mask = 0; if (sizeof(unsigned) == 4 && i == 32) {
while (i > 0) { /* mask >>= 32 below may not work */
*mask |= msk; mask = 0;
msk >>= 1; } else {
i--; 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; return 0;
} }