static char *parse(const char *command, struct interface_defn_t *ifd) { size_t old_pos[MAX_OPT_DEPTH] = { 0 }; int okay[MAX_OPT_DEPTH] = { 1 }; int opt_depth = 1; char *result = NULL; while (*command) { switch (*command) { default: addstr(&result, command, 1); command++; break; case '\\': if (command[1]) { addstr(&result, command + 1, 1); command += 2; } else { addstr(&result, command, 1); command++; } break; case '[': if (command[1] == '[' && opt_depth < MAX_OPT_DEPTH) { old_pos[opt_depth] = result ? strlen(result) : 0; okay[opt_depth] = 1; opt_depth++; command += 2; } else { addstr(&result, "[", 1); command++; } break; case ']': if (command[1] == ']' && opt_depth > 1) { opt_depth--; if (!okay[opt_depth]) { result[old_pos[opt_depth]] = '\0'; } command += 2; } else { addstr(&result, "]", 1); command++; } break; case '%': { char *nextpercent; char *varvalue; command++; nextpercent = strchr(command, '%'); if (!nextpercent) { errno = EUNBALPER; free(result); return NULL; } varvalue = get_var(command, nextpercent - command, ifd); if (varvalue) { # if ENABLE_FEATURE_IFUPDOWN_IP /* "hwaddress <class> <address>": * unlike ifconfig, ip doesnt want <class> * (usually "ether" keyword). Skip it. */ if (strncmp(command, "hwaddress", 9) == 0) { varvalue = skip_whitespace(skip_non_whitespace(varvalue)); } # endif addstr(&result, varvalue, strlen(varvalue)); } else { # if ENABLE_FEATURE_IFUPDOWN_IP /* Sigh... Add a special case for 'ip' to convert from * dotted quad to bit count style netmasks. */ if (strncmp(command, "bnmask", 6) == 0) { unsigned res; varvalue = get_var("netmask", 7, ifd); if (varvalue) { res = count_netmask_bits(varvalue); if (res > 0) { const char *argument = utoa(res); addstr(&result, argument, strlen(argument)); command = nextpercent + 1; break; } } } # endif okay[opt_depth - 1] = 0; } command = nextpercent + 1; } break; } } if (opt_depth > 1) { errno = EUNBALBRACK; free(result); return NULL; } if (!okay[0]) { errno = EUNDEFVAR; free(result); return NULL; } return result; }
dead_pool * init_pool(int pool_size, struct in_addr deadrange_base, struct in_addr deadrange_mask, char *sockshost, uint16_t socksport) { int i, deadrange_bits, deadrange_width, deadrange_size; struct in_addr socks_server; dead_pool *newpool = NULL; /* Count bits in netmask and determine deadrange width. */ deadrange_bits = count_netmask_bits(deadrange_mask.s_addr); if(deadrange_bits == -1) { show_msg(MSGERR, "init_pool: invalid netmask for deadrange\n"); return NULL; } deadrange_width = 32 - deadrange_bits; show_msg(MSGDEBUG, "deadrange width is %d bits\n", deadrange_width); /* Now work out how many IPs are available in the deadrange and check that this number makes sense. If the deadpool is bigger than the deadrange we shrink the pool. */ for(i=0, deadrange_size = 1; i < deadrange_width; i++) { deadrange_size *= 2; } if(deadrange_size < pool_size) { show_msg(MSGWARN, "tordns cache size was %d, but deadrange size is %d: " "shrinking pool size to %d entries\n", pool_size, deadrange_size, deadrange_size); pool_size = deadrange_size; } if(pool_size < 1) { show_msg(MSGERR, "tordns cache size is 0, disabling tordns\n"); return NULL; } /* Allocate space for the dead_pool structure */ newpool = (dead_pool *) mmap(0, sizeof(dead_pool), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if(!newpool) { show_msg(MSGERR, "init_pool: unable to mmap deadpool " "(tried to map %d bytes)\n", sizeof(dead_pool)); return NULL; } /* Initialize the dead_pool structure */ #ifdef HAVE_INET_ATON inet_aton(sockshost, &socks_server); #elif defined(HAVE_INET_ADDR) socks_server.s_addr = inet_addr(sockshost); #endif newpool->sockshost = ntohl(socks_server.s_addr); newpool->socksport = socksport; newpool->deadrange_base = ntohl(deadrange_base.s_addr); newpool->deadrange_mask = ntohl(deadrange_mask.s_addr); newpool->deadrange_size = deadrange_size; newpool->write_pos = 0; newpool->dead_pos = 0; newpool->n_entries = pool_size; /* Allocate space for the entries */ newpool->entries = (pool_ent *) mmap(0, newpool->n_entries * sizeof(pool_ent), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if(!newpool->entries) { munmap((void *)newpool, sizeof(dead_pool)); show_msg(MSGERR, "init_pool: unable to mmap deadpool entries " "(tried to map %d bytes)\n", newpool->n_entries * sizeof(pool_ent)); return NULL; } /* Initialize the entries */ for(i=0; i < newpool->n_entries; i++) { newpool->entries[i].ip = -1; newpool->entries[i].name[0] = '\0'; } return newpool; }