//Read in and initialize the leases void LoadLeases(void) { //We need to make sure the leases we load actually fit in the address pool, so we'll be //tracking the index to the lease file and the index to the allocated list int leaseindex, allocindex; // From Nick : I realized that there was a race condition in that code, // particularly with the reading and saving of KEY_LEASE_NUMLEASES // I’ve added a function, which LoadLeases calls immediately on entry: WaitForMsgQueueToFinish (LL_ID_SETTINGS); nAllocatedIP = 0; ReadKey(TFTPD32_DHCP_KEY, KEY_LEASE_NUMLEASES, &nAllocatedIP, sizeof(nAllocatedIP), REG_DWORD, szTftpd32IniFile); if (nAllocatedIP > sParamDHCP.nPoolSize) { SVC_WARNING ("The pool size is too small for the number of leases, ignoring extra leases"); nAllocatedIP = sParamDHCP.nPoolSize; } allocindex = 0; for(leaseindex = 0; leaseindex < nAllocatedIP; ++leaseindex) { char key [_MAX_PATH]; char tmpval [_MAX_PATH]; tFirstIP[allocindex] = malloc (sizeof(struct LL_IP)); memset(tFirstIP[allocindex], 0, sizeof(struct LL_IP)); tFirstIP[allocindex]->dwAllocNum = leaseindex; sprintf(key, "%s%d%s", KEY_LEASE_PREFIX, leaseindex, KEY_LEASE_MAC); if(ReadKey(TFTPD32_DHCP_KEY, key, tmpval, _MAX_PATH, REG_SZ, szTftpd32IniFile)) atohaddr(tmpval, tFirstIP[allocindex]->sMacAddr, 6); sprintf(key, "%s%d%s", KEY_LEASE_PREFIX, leaseindex, KEY_LEASE_IP); if(ReadKey(TFTPD32_DHCP_KEY, key, tmpval, _MAX_PATH, REG_SZ, szTftpd32IniFile)) tFirstIP[allocindex]->dwIP.s_addr = inet_addr(tmpval); sprintf(key, "%s%d%s", KEY_LEASE_PREFIX, leaseindex, KEY_LEASE_ALLOC); if(ReadKey(TFTPD32_DHCP_KEY, key, tmpval, _MAX_PATH, REG_SZ, szTftpd32IniFile)) tFirstIP[allocindex]->tAllocated = atotime(tmpval); sprintf(key, "%s%d%s", KEY_LEASE_PREFIX, leaseindex, KEY_LEASE_RENEW); if(ReadKey(TFTPD32_DHCP_KEY, key, tmpval, _MAX_PATH, REG_SZ, szTftpd32IniFile)) tFirstIP[allocindex]->tRenewed = atotime(tmpval); // fix errors in date conversion (registry modified at hand) if (tFirstIP[allocindex]->tAllocated == -1) tFirstIP[allocindex]->tAllocated = 0; if (tFirstIP[allocindex]->tRenewed == -1) tFirstIP[allocindex]->tRenewed = 0; //If the address doesn't fit in the pool, don't add it after all //Since we are assuming the leases were written in order, do a quick check for dups //and invalid macaddrs if((!AddrFitsPool(&tFirstIP[allocindex]->dwIP)) || (IsMacEmpty(tFirstIP[allocindex])) || ((allocindex > 0) && (tFirstIP[allocindex]->dwIP.s_addr == tFirstIP[allocindex - 1]->dwIP.s_addr))) { free(tFirstIP[allocindex]); tFirstIP[allocindex] = NULL; } else { tMAC[allocindex] = tFirstIP[allocindex]; //Copy to cross index ++allocindex; //Move on to the next one } } if(allocindex != nAllocatedIP) SetNumAllocated(allocindex); // ensure that data base is sorted (especially if we've dropped some leases in the load) qsort (tMAC, nAllocatedIP, sizeof *tMAC, MACCompare); qsort (tFirstIP, nAllocatedIP, sizeof *tFirstIP, QsortCompare); ReorderLeases(); } // LoadLeases
// returns false on bad mime bool HttpMime::parse ( char *mime , long mimeLen , Url *url ) { // reset locUrl to 0 m_locUrl.reset(); // return if we have no valid complete mime if ( mimeLen == 0 ) return false; // status is on first line m_status = -1; // skip HTTP/x.x till we hit a space char *p = mime; char *pend = mime + mimeLen; while ( p < pend && !is_wspace_a(*p) ) p++; // then skip over spaces while ( p < pend && is_wspace_a(*p) ) p++; // return false on a problem if ( p == pend ) return false; // then read in the http status m_status = atol2 ( p , pend - p ); // if no Content-Type: mime field was provided, assume html m_contentType = CT_HTML; // assume default charset m_charset = NULL; m_charsetLen = 0; // set contentLen, lastModifiedDate, m_cookie p = mime; while ( p < pend ) { // compute the length of the string starting at p and ending // at a \n or \r long len = 0; while ( &p[len] < pend && p[len]!='\n' && p[len]!='\r' ) len++; // . if we could not find a \n or \r there was an error // . MIMEs must always end in \n or \r if ( &p[len] >= pend ) return false; // . stick a NULL at the end of the line // . overwrites \n or \r TEMPORARILY char c = p [ len ]; p [ len ] = '\0'; // parse out some meaningful data if ( strncasecmp ( p , "Content-Length:" ,15) == 0 ) { m_contentLengthPos = p + 15; m_contentLen = atol( m_contentLengthPos); } else if ( strncasecmp ( p , "Last-Modified:" ,14) == 0 ) { m_lastModifiedDate=atotime(p+14); // do not let them exceed current time for purposes // of sorting by date using datedb (see Msg16.cpp) time_t now = time(NULL); if (m_lastModifiedDate > now) m_lastModifiedDate = now; } else if ( strncasecmp ( p , "Content-Type:" ,13) == 0 ) m_contentType = getContentTypePrivate ( p + 13 ); else if ( strncasecmp ( p , "Set-Cookie: " ,11) == 0 ) { m_cookie = p + 11; m_cookieLen = gbstrlen ( p + 11 ); } else if ( strncasecmp ( p , "Location:" , 9) == 0 ) { // point to it char *tt = p + 9; // skip if space if ( *tt == ' ' ) tt++; if ( *tt == ' ' ) tt++; // at least set this for Msg13.cpp to use m_locationField = tt; m_locationFieldLen = gbstrlen(tt); // . we don't add the "www." because of slashdot.com // . we skip initial spaces in this Url::set() routine if(url) m_locUrl.set ( url, p + 9, len - 9, false/*addWWW?*/); } else if ( strncasecmp ( p , "Content-Encoding:", 17) == 0 ) { //only support gzip now, it doesn't seem like servers //implement the other types much m_contentEncodingPos = p+17; if(strstr(m_contentEncodingPos, "gzip")) { m_contentEncoding = ET_GZIP; } else if(strstr(m_contentEncodingPos, "deflate")) { //zlib's compression m_contentEncoding = ET_DEFLATE; } } //else if ( strncasecmp ( p, "Cookie:", 7) == 0 ) // log (LOG_INFO, "mime: Got Cookie = %s", (p+7)); // re-insert the character that we replaced with a '\0' p [ len ] = c; // go to next line p += len; // skip over the cruft at the end of this line while ( p < pend && ( *p=='\r' || *p=='\n' ) ) p++; } return true; }