Large refactor.

* Good commits be-damned.
* This is bad programming practice. What I should have done is make each
* separate commit atomic. However, the deadline is fast approaching, and
* the codebase is small enough that it all fits in my head anyways.
Proper shutdown protocol.
Factor out recv_acknowledge, generalize n2.
Avoid re-opening necessarily closed pipe.
Missing semicolon in packet.h