Joel G Mathew
Joel G Mathew

Reputation: 8061

Inadvertent Infinite loop

I'm just beginning Python, and while trying out an exercise in Ardit Suice's course, I wrote the following code to implement a custom website blocker:

#!/usr/bin/env python3
import time
import os
from datetime import datetime as dt
hosts_path = '/etc/hosts'
tmp_path = '/tmp/hosts.tmp'
site_list = [ 'www.facebook.com', 'mail.google.com']

def write_hosts():
    hostfile = open(hosts_path, 'r')
    filecont = hostfile.read()
    hostfile.close
    for site in site_list:
        if not site in filecont:
            try:
                with open(hosts_path, 'a') as fh:
                    fh.write('127.0.1.1 ' + site + '\n')
                    print ("Wrote %s to hosts file %s" % (site, hosts_path))
            except PermissionError:
                print ("Sorry, you need to be admin to do this")

def write_fresh_hosts():
    testfile = open(tmp_path, 'w')
    hostfile = open(hosts_path, 'r')
    line=hostfile.readline()
    while line:
        for site in site_list:
            if not site in line:
                testfile.write(line)
            else:
                print ("Deleting %s from our blocked list" % site)
        line=hostfile.readline()

    testfile.close
    hostfile.close
    os.rename(tmp_path, hosts_path)

while True:
    print(1)
    print (dt.now())
    upper=dt(dt.now().year, dt.now().month, dt.now().day, 20, 0)
    lower=dt(dt.now().year, dt.now().month, dt.now().day, 17, 0)
    if lower <= dt.now() <= upper:
        print ("Blocking now")
        write_hosts()
        time.sleep(5)
    else:
        print ("Checking website lists for already blocked sites:")
        write_fresh_hosts()
        time.sleep(5)

What I wanted to do, was to write a list of sites to the hosts file during a specified time interval, and to delete those lines if the time was outside those hours.

However I found that my hosts file quickly grew to 110MB size, and it just contained the line 127.0.0.1 localhost repeated over and over:

127.0.0.1       localhost
127.0.0.1       localhost
127.0.0.1       localhost
127.0.0.1       localhost
... (repeated)

While at the end of my file, I found the lines:

127.0.1.1   www.facebook.com
127.0.1.1   mail.google.com

Originally the hosts file had only contained the single line:

127.0.0.1       localhost

Output:

sudo python siteblocker.py 
Checking website lists for already blocked sites:
Checking website lists for already blocked sites:
... (repeated)

Where did I go wrong?

Upvotes: 2

Views: 113

Answers (1)

cryptoplex
cryptoplex

Reputation: 1253

In this part of your code:

while line:
    for site in site_list:
        if not site in line:
            testfile.write(line)
        else:
            print ("Deleting %s from our blocked list" % site)
    line=hostfile.readline()

You are iterating over your site_list for every line of the host file. Every time the given site isn't found within line, you are writing line. Since there are two entries in your site_list, and neither of them are in your localhost line, you write each line twice.

Since you then make the newly generated output file your new input file, you are effectively doubling the number of lines in the file with every call.

Upvotes: 1

Related Questions