<?xml version="1.0" encoding="utf-8"?> 
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <generator uri="https://gohugo.io/" version="0.78.2">Hugo</generator><title type="html"><![CDATA[code on Roy's Blog]]></title>
    
        <subtitle type="html"><![CDATA[Mainly about tech stuff I have a hand in]]></subtitle>
    
    
    
            <link href="https://roy.marples.name/blog/tags/code/" rel="alternate" type="text/html" title="HTML" />
            <link href="https://roy.marples.name/blog/tags/code/atom.xml" rel="self" type="application/atom+xml" title="Atom" />
            <link href="https://roy.marples.name/blog/tags/code/feed.json" rel="alternate" type="application/json" title="Json" />
    <updated>2021-03-12T11:08:32+00:00</updated>
    
    <id>https://roy.marples.name/blog/tags/code/</id>
        
        <entry>
            <title type="html"><![CDATA[GoAccess improvements and the importance of error checking]]></title>
            <link href="https://roy.marples.name/blog/posts/goaccess_improvements/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/goaccess_improvements/</id>
            
            <published>2021-01-03T14:45:00+00:00</published>
            <updated>2021-01-03T14:45:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p><a href="https://goaccess.io/">GoAccess</a> is an open-source real-time web log analyzer.
It sports curses and web interfaces.
It looks really pretty and I like that :)</p>
<p>Upstream has already accepted <a href="https://github.com/allinurl/goaccess/pull/1989">my patch to allow a build on NetBSD</a> which is nice.</p>
<p>However, there is still a serious issue - GoAccess burns a LOT of CPU.
With older versions it wasn&rsquo;t too onerous, but now it uses 4 threads and CPU
was going through the roof on my poor web server.
Luckily it turned out it was <a href="https://github.com/allinurl/goaccess/pull/1990">a simple patch</a>.</p>
<p>This is a good example of why we always want to check for errors.
<a href="https://pubs.opengroup.org/onlinepubs/007904875/functions/usleep.html">POSIX usleep</a> documents that if a value of 1000000 or greater is given then
<code>EINVAL</code> is returned immediately.
The default value GoAccess was using for following the tail of the web log
file was also defined as 1000000, which means on a POSIX compliant OS like say
NetBSD, the usleep call did exactly nothing. Hence burning the CPU time.
With this patch, CPU time is now barely measureable :)</p>
<p>But we can still make it <strong>GoFaster</strong> :D</p>
<p>While the CPU was being pegged I noticed it was stuck in the select state.
Well, <a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html">select(2)</a> is not the greatest API ever made.
Luckiy, we now have <a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html">poll(2)</a> which is a massive improvement and as it&rsquo;s a POSIX standard,
highly portable as well.
After a few hours of work, I turned out a <a href="https://github.com/allinurl/goaccess/pull/1991">a fairly complex patch</a> and it works very well!
It&rsquo;s been running on my web server all night and the websocket just ticks over.
The web page I&rsquo;m looking at constantly updated itself.</p>
<p>Huge win for my low powered server, now consuming less power and a great
start to the New Year!</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/tech" term="tech" label="tech" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[Capsicum vs Pledge Final Thoughts]]></title>
            <link href="https://roy.marples.name/blog/posts/capsicum_vs_pledge_final_thoughts/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/capsicum_vs_pledge_final_thoughts/</id>
            
            <published>2020-06-15T17:15:00+00:00</published>
            <updated>2020-06-15T17:15:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p>Following on from <a href="../capsicum_vs_pledge_part2">Capsicum vs Pledge Part 2</a>
I thought I would post my final thougts on the topic as the development
on these sandbox technologies draws to a close in <a href="/projects/dhcpcd">dhcpcd</a>.</p>
<p>But first, let us discuss &hellip;</p>
<h2 id="the-posix-resource-limited-sandbox">The POSIX Resource Limited sandbox</h2>
<p>POSIX documents
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html">setrlimit(2)</a>.
Disabling the ability to open new files, sockets, etc, or create new processes
is actually pretty powerful.</p>
<p>Thanks to the privsep dhcpcd now has to support both Capsicum and Pledge, this
turned out to be pretty easy to implement.
The <em>only</em> issue with this is the
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html">poll(2)</a>
interface which dhcpcd makes great use of.
Implementations found on Linux, OpenBSD and Solaris return <code>EINVAL</code> when the
<code>nfds</code> argument is greater than <code>RLIMIT_NOFILE</code> where-as the other OS&rsquo;s dhcpcd
supports don&rsquo;t.
This means that on Linux, OpenBSD and Solaris an attacker could close
an exiting file descriptor and try to open a new one.
On OpenBSD this is not that much of a big deal because pledge should stop
that from happening.
On Linux and Solaris, they can&rsquo;t open a file thanks to the chrooted empty
directory but they can create a new one.
But thanks to <code>RLIMIT_FSIZE</code> they can&rsquo;t actually write to it.
At most they could create a network socket and send arbitary data over it.
For Linux, we could look into using seccomp to stop this.</p>
<p>For implementations such as NetBSD and FreeBSD, setting <code>RLIMIT_NOFILE</code> to zero
with poll(2) still working means they cannot create any few file descriptor.
This means that if an attacker breaches a resource limited process it
<strong>can only work with the resources it has</strong> because it cannot fork another
process, nor open any files, sockets, etc.
It&rsquo;s also running as an unpriviledged user locked in an empty directory,
so there is nothing to see or do there.
All the resources it currently has are:</p>
<ul>
<li>PF_INET, PF_LINK, etc sockets that can only query for data</li>
<li>network proxy process (receives only, does not send)</li>
<li>BPF processes (send and receive, the read and write filters are also locked)</li>
<li>privileged actioneer (filters ioctls, validates paths and outbound traffic)</li>
</ul>
<p>So the only way to do anything outside of what dhcpcd normally does is to use
a facility that does not need to create a file or socket, or fork a process.
The only remaining avenue of attack is to break the privileged actioneer
process- that cannot be protected by any sandboxing as it needs to do a lot
of stuff. Both OpenBSD&rsquo;s and FreeBSD&rsquo;s dhclient have such a privileged
process as well.</p>
<p>The priviledged actioneer process itself doesn&rsquo;t do a great deal.
For example to add a route on BSD you create a RTM_ADD message.
The master process will do this and instead of writing to the PF_ROUTE socket
itself it will pass the message to the privilged actioneer process which
in turn writes to it&rsquo;s PF_ROUTE socket.
Every ioctl, path accessed or network bound packet is validated by the
privileged actioneer. Even though it&rsquo;s generic, it&rsquo;s also locked down.</p>
<h2 id="so-what-extra-to-capsicum-and-pledge-bring-to-the-table">So what extra to Capsicum and Pledge bring to the table?</h2>
<p>Both bring system call filtering.
For example,
<a href="https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+3+NetBSD-current">sysctl(2)</a>
does not need to create a new resource.
Information available to the ordinal user such as
<a href="https://en.wikipedia.org/wiki/Uname">uname</a> may not be
desirable to leak to these sandboxed processes.
But then the question to ask is what can they do with it?</p>
<p>Pledge overcomes the <code>RLIMIT_NOFILE</code> limitation for poll(2) on OpenBSD.</p>
<p>Capsicum goes a bit futher by limiting rights of each resource you
have in terms of what you can do with them.</p>
<p>What they both bring to the table though is making sandboxing easier.
Here, Pledge is the outright winner. As I pointed out in my initial blog
post, Pledge is really easy.
But make it too easy and it&rsquo;s not as secure as it could be.
Capsicum is harder and the resource limited sandbox is harder still.</p>
<p>The take-away point from this is while Capsicum and Pledge are nice,
they don&rsquo;t beat a good design.</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/tech" term="tech" label="tech" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/dhcpcd" term="dhcpcd" label="dhcpcd" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/sandbox" term="sandbox" label="sandbox" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[Capsicum vs Pledge in a Network Management Tool ... Part 2]]></title>
            <link href="https://roy.marples.name/blog/posts/capsicum_vs_pledge_part2/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/capsicum_vs_pledge_part2/</id>
            
            <published>2020-05-14T14:00:00+00:00</published>
            <updated>2020-05-14T14:00:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p>A few days ago I posted about <a href="../capsicum_vs_pledge">Capsicum vs Pledge</a>
in dhcpcd. Well, I finished the Capsicum integration yesterday so I thought
I would take some time to revisit my findings.</p>
<h2 id="capsicum-is-hard-to-develop-for">Capsicum is hard to develop for</h2>
<p>It&rsquo;s either on or off.
You can limit each FD with capabilites mode off, but I&rsquo;m not sure what that gains
as it&rsquo;s mainly there to allow the FD to be used in the restricted world so
we can treat it as either on or off really.</p>
<p>Pledge is granular, you can turn areas on or off.
For example, you can allow full file access while restricting various ioctls.
Ideally, the only thing you want to pledge is stdio, which is kinda needed
for the Privilege Separation IPC to work.
However, we end up pledging dns inet and route as well.</p>
<p>So why is Capsicum harder? Well, the short answer is that it&rsquo;s not.
The long answer is that it&rsquo;s perceived to be harder because you have to
do all the work up front to get your code working whereas Pledge allows you
do it it piece meal.</p>
<h2 id="pledge-is-as-secure-as-capsicum">Pledge is as secure as Capsicum</h2>
<p>As I said in my prior post, I&rsquo;m not a security expert, but here&rsquo;s my findings:</p>
<p>You can make Pledge as secure as Capsicum, <strong>but you don&rsquo;t have to</strong>.</p>
<p>As a user on OpenBSD I can see lots of processes marked with <code>p</code> to indicate
they have pledged something.
<del>What that something is though is a black box.</del>
You can use <code>ps-o pledge-p $pid</code> to show the promises a process has pledged.
The more promises you see the more that process is allowed to do.
Short list good, long list bad.</p>
<p>As a user on FreeBSD I can see lots of processes marked with &lsquo;C&rsquo; to indicate
they are in Capsicum Capabilites Mode. Because this is just on or off, I
know exactly what this process can and cannot do.</p>
<p>Armed with this knowledge I would trust a Capsicum enabled application more
than a Pledge enabled application. But to fully trust either you still need
to audit the code.</p>
<h2 id="they-both-have-limitations">They both have limitations</h2>
<p>With a Pledged process you cannot change a BPF filter with the bpf pledge.
This is unfortunate, a possible solution could be to spawn a process AND filter
for every address you want to monitor for DaD or ARP pinging.
That <em>could</em> be a lot of resources wasted as BPF is neither infinite nor cheap.</p>
<p>With a Capsicum Capability Mode enabled process you cannot call sendto(2)
that is not connected.
Unlike the above, there is no easy solution.
I can&rsquo;t spawn off another process because unlike normal communication,
because I <strong>need</strong> to bind to the <code>bootpc</code> and <code>dhcpv6-client</code> ports
so I can dictate which source port is used to send the message.
The binding would then fail because the network proxy process
is already using the port.
A possible solution is to call RTM_GET to work out which host I send to
on the local network, craft the packet by hand and send it out using a BPF
socket.</p>
<p>I strongly feel that both should be fixed upstream:</p>
<ul>
<li>the bpf Pledge should allow changing the BPF filter.</li>
<li>Capsicum should allow sendto unconnected if bound to a priviledged port or another capability created to grant to the socket.</li>
</ul>
<p>As it stands, dhcpcd does not Pledge for BPF processes and does not run
the generic network proxy process in Capsicum Capabilites mode.
However, both processes are using the unprivileged user and chrooted to an
empty directory. Neither do any processing of data coming in, they just
ferry it back to the master process via IPC which runs under the same
restrictions but is also sandboxed with Pledge or Capsicum so I&rsquo;m
confident that it&rsquo;s good enough.</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/tech" term="tech" label="tech" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/dhcpcd" term="dhcpcd" label="dhcpcd" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/sandbox" term="sandbox" label="sandbox" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[Capsicum vs Pledge in a Network Management Tool]]></title>
            <link href="https://roy.marples.name/blog/posts/capsicum_vs_pledge/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/capsicum_vs_pledge/</id>
            
            <published>2020-05-12T11:46:00+00:00</published>
            <updated>2020-05-12T11:46:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p>So one of the big goals of <a href="/projects/dhcpcd">dhcpcd</a> was to implement
<a href="https://en.wikipedia.org/wiki/Privilege_separation">Privilege Separation</a>.
This was achieved in <a href="/blog/dhcpcd-9-0-0-released.html">dhcpcd-9</a> which was
important because it was a required step of work to
<a href="https://lists.freebsd.org/pipermail/freebsd-net/2019-October/054535.html">merge dhcpcd into FreeBSD base system</a>. Once done, we can then look at what is
required to enable <a href="https://wiki.freebsd.org/Capsicum">Capsicum</a> support,
which is the last required step before dhcpcd can even be considered for
importing into FreeBSD base system.</p>
<p>The good news is that <em>basic</em> Capsicum support has been enabled in
<a href="https://roy.marples.name/cgit/dhcpcd.git/commit/?id=727b7e9bf8b2fe810913c76c5fd36767869944bb">this commit</a> by ensuring all the file descriptors of the
network facing processes are limited in their capability.
The bad news is that <a href="https://www.freebsd.org/cgi/man.cgi?capsicum(4)">capability mode</a> is only enabled for the BPF processes- the end goal is that
the master process is at least placed in capability mode.</p>
<p>So what&rsquo;s the problem? Well, the first problem is that Capsicum is really
hard to use, a lot of this is not helped by the documentation.
It took a long time to work out how it works and how to use it.
The second problem is that capability mode is really hard core- it stops
a lot of stuff working dead in it&rsquo;s tracks by killing access not capability
limited in the global namespace.</p>
<p>From dhcpcds perspective the big issue is that
<del>gethostname(3) and</del> getifaddrs(3) won&rsquo;t work.
This is the biggest show stopper, hard to IPC.</p>
<p><em>EDIT: gethostname(3) does work in Capsicum capabilities mode.</em></p>
<p>Let&rsquo;s just take a moment to talk about getifaddrs(3)- it&rsquo;s a really
powerful interface to work out what interfaces are available to work with.
In some OS it&rsquo;s the only mechanism to get the hardware address assigned
to an interface. Also, it&rsquo;s possible for the route(4) (or netlink(7))
socket to overflow so it&rsquo;s required to re-learn the system state which means
it cannot be cached.
Not that FreeBSD supports reporting route(4) overflow, but that&rsquo;s another story.</p>
<p>Due to the getifaddrs(3) show stopper, I decided to look into
<a href="https://man.openbsd.org/pledge.2">OpenBSDs pledge(2)</a>. While the documentation
is still very technical, it&rsquo;s easier to read and understand compared to
Capsicum. It&rsquo;s also really <em>really</em> <strong>really</strong> easy to implement in comparison
as you only pledge features rather than each file descriptor.
Because of this, it&rsquo;s also very granular.
<a href="https://roy.marples.name/cgit/dhcpcd.git/commit/?id=2f9d9eae5fb8fb1922b0e096e157987ac0df110e">The initial commit to enable pledge</a> is mainly allowing the
current ioctl IPC framework to pass data back again.</p>
<p>But can we do better? Can we operate with the same Pledges that OpenBSDs
dhclient(8) uses? The answer is of course <strong>YES</strong>!
By caching some initial data that does not change such as utsname and
machine uuid AND moving all file IO to privsep,
<a href="https://roy.marples.name/cgit/dhcpcd.git/commit/?id=2f9d9eae5fb8fb1922b0e096e157987ac0df110e">this commit</a>
allows almost perfect Pledge support.
We could go better if privsep gains support for the <code>SIOCGIFGROUP</code> ioctl as
this would allow the <code>inet</code> pledge to be dropped.
It&rsquo;s not quite perfect because
<a href="http://openbsd-archive.7691.n7.nabble.com/pledge-bpf-32bit-arch-unbreak-td299901.html">a Pledged process cannot change a BPF filter</a>.
We would need to space a BPF process per address which is then limited by the
number of BPF instances you are allowed. I&rsquo;m not sure this a good thing, and
ironically BPF processes are the one thing we have in Capsicums capability mode.
This is also a massive improvement over the initial dhcpcd-9 release because
it means we no longer need any files in the chroot directory and <code>/var/empty</code>
can be used again.
This alone should make current and new FreeBSD users of dhcpcd quite happy.
It will also go some way to enabling capabilities mode for the master
dhcpcd process in the future.</p>
<p>Now, I can&rsquo;t say which technology is more secure- that&rsquo;s really not my field
of expertise.
I can&rsquo;t even say if either are really needed or actually make security worse
because Privilege Separation
<a href="https://en.wikipedia.org/wiki/Inter-process_communication">IPC</a>
adds more code, complexity and as such could make it more prone
to bugs some of which could be a security attack vector in itself.</p>
<p>But what I can say is that Pledge is much easier to develop for
because it&rsquo;s really granular unlike Capsicum which is either on or off or
per fd limited.</p>
<p>I&rsquo;ll continue working on Capsicum support in dhcpcd just to see if I can
enable Capabilites Mode in the master process.
When that&rsquo;s finished I will do a more in-depth comparison of these two
technologies.</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/tech" term="tech" label="tech" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/dhcpcd" term="dhcpcd" label="dhcpcd" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/sandbox" term="sandbox" label="sandbox" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[NetBSD curses erase functions fixed]]></title>
            <link href="https://roy.marples.name/blog/posts/curses_erase_fixes/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/curses_erase_fixes/</id>
            
            <published>2020-03-15T07:55:00+00:00</published>
            <updated>2020-03-15T07:55:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p><a href="http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=23910">NetBSD PR lib/23910</a>
was filed over 16 years ago.
It describes how NetBSD curses fails to work with <a href="https://vifm.info/">Vifm</a>,
a <a href="https://www.vim.org/">Vim</a> interface for a curses GUI file manager.
It&rsquo;s quite a nice idea after playing around with it some as Vim is my favourite
text editor.</p>
<p>Since I was the main protagonist in bringing <a href="terminfo_married_to_curses.html">terminfo to NetBSD</a>, I had a reasonable grasp on how our curses worked and
I had looked at this bug before, but left scratching my head over it.</p>
<p>Since I looked at it, Valery Ushakov added a simple test case to demonstrate
the issue.</p>
<div class="highlight"><pre style="background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-c" data-lang="c"><span style="color:#099">#include</span> <span style="color:#099">&lt;curses.h&gt;</span><span style="color:#099">
</span><span style="color:#099">#include</span> <span style="color:#099">&lt;err.h&gt;</span><span style="color:#099">
</span><span style="color:#099">#include</span> <span style="color:#099">&lt;stdio.h&gt;</span><span style="color:#099">
</span><span style="color:#099">#include</span> <span style="color:#099">&lt;stdlib.h&gt;</span><span style="color:#099">
</span><span style="color:#099">#include</span> <span style="color:#099">&lt;unistd.h&gt;</span><span style="color:#099">
</span><span style="color:#099"></span>
<span style="color:#078;font-weight:bold">int</span>
<span style="color:#c0f">main</span>()
{
	<span style="color:#069;font-weight:bold">const</span> <span style="color:#078;font-weight:bold">char</span> <span style="color:#555">*</span>errmsg <span style="color:#555">=</span> <span style="color:#366">NULL</span>;
	<span style="color:#078;font-weight:bold">int</span> err;

<span style="color:#099">#define CHECKERR(_msg)					\
</span><span style="color:#099">	do {						\
</span><span style="color:#099">		if (err != OK) {			\
</span><span style="color:#099">			errmsg = _msg &#34; failed&#34;;	\
</span><span style="color:#099">			goto out;			\
</span><span style="color:#099">		}                                       \
</span><span style="color:#099">	} while (0)
</span><span style="color:#099"></span>

	WINDOW <span style="color:#555">*</span>scrw <span style="color:#555">=</span> initscr();
	<span style="color:#069;font-weight:bold">if</span> (scrw <span style="color:#555">==</span> <span style="color:#366">NULL</span>)
		errx(EXIT_FAILURE, <span style="color:#c30">&#34;initscr failed</span><span style="color:#c30;font-weight:bold">\n</span><span style="color:#c30">&#34;</span>);

	<span style="color:#069;font-weight:bold">if</span> (<span style="color:#555">!</span>has_colors()) {
		errmsg <span style="color:#555">=</span> <span style="color:#c30">&#34;no colors&#34;</span>;
		<span style="color:#069;font-weight:bold">goto</span> out;
	}

	err <span style="color:#555">=</span> start_color();
	CHECKERR(<span style="color:#c30">&#34;start_color&#34;</span>);

	err <span style="color:#555">=</span> init_pair(<span style="color:#f60">2</span>, COLOR_WHITE, COLOR_RED);
	CHECKERR(<span style="color:#c30">&#34;init_pair&#34;</span>);

	<span style="color:#078;font-weight:bold">int</span> maxy, maxx;
	getmaxyx(stdscr, maxy, maxx);

	WINDOW <span style="color:#555">*</span>lborder <span style="color:#555">=</span> newwin(maxy<span style="color:#555">-</span> <span style="color:#f60">1</span>, <span style="color:#f60">1</span>, <span style="color:#f60">0</span>, <span style="color:#f60">0</span>);
	<span style="color:#069;font-weight:bold">if</span> (lborder <span style="color:#555">==</span> <span style="color:#366">NULL</span>) {
		errmsg <span style="color:#555">=</span> <span style="color:#c30">&#34;newwin failed&#34;</span>;
		<span style="color:#069;font-weight:bold">goto</span> out;
	}

	wbkgdset(lborder, COLOR_PAIR(<span style="color:#f60">2</span>));

	werase(lborder);

	mvwaddstr(lborder, <span style="color:#f60">0</span>, <span style="color:#f60">0</span>, <span style="color:#c30">&#34;A&#34;</span>);
	mvwaddstr(lborder, maxy<span style="color:#555">-</span> <span style="color:#f60">2</span>, <span style="color:#f60">0</span>, <span style="color:#c30">&#34;Z&#34;</span>);

	wnoutrefresh(stdscr);
	wnoutrefresh(lborder);
	doupdate();

	sleep(<span style="color:#f60">5</span>);
<span style="color:#99f">out</span>:
	endwin();

	<span style="color:#069;font-weight:bold">if</span> (err <span style="color:#555">!=</span> OK) {
		<span style="color:#069;font-weight:bold">if</span> (errmsg <span style="color:#555">==</span> <span style="color:#366">NULL</span>)
			errmsg <span style="color:#555">=</span> <span style="color:#c30">&#34;unknown error&#34;</span>;
		fprintf(stderr, <span style="color:#c30">&#34;%s</span><span style="color:#c30;font-weight:bold">\n</span><span style="color:#c30">&#34;</span>, errmsg);
		<span style="color:#069;font-weight:bold">return</span> EXIT_FAILURE;
	}

	<span style="color:#069;font-weight:bold">return</span> EXIT_SUCCESS;
}
</code></pre></div><p>He then noted that using <code>wbkgd</code> instead of <code>wbkgdset</code> makes it work.</p>
<p>Now, the difference between the two is that <code>wbkgd</code> forces new attributes on
the whole window background, whereas <code>wbkgdset</code> sets new attributes
<strong>for new actions on the window</strong>.
Keen observers will notice that the following function called is <code>werase</code>,
which does what it says on the tin and erases the window but also
<strong>resetting the attributes</strong> of the contents.
So, I looked at this function and noticed the attribute checking code was
faulty and a <a href="http://anonhg.netbsd.org/src/rev/068b7d4abae7">simple fix</a>
was enough to solve it!</p>
<p>Valery then pointed out that <code>wclrtoeol</code> probably needed fixing to and as it
turned out, <code>wclrtobot</code> likewise.
As it transpired, all 3 had different logic in working out when to erase
something!
We went through a few iterations of patches to harmonise the code and have
settled on a macro that all 3 now share, so hopefully no more erasing issues
in our curses.</p>
<p>As a follow on task, I should go through the NetBSD bug backlog and see
if this fixes any other reported issues.</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/netbsd" term="netbsd" label="NetBSD" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[terminfo numeric parameters promoted from short to int]]></title>
            <link href="https://roy.marples.name/blog/posts/terminfo_int_paramters/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/terminfo_int_paramters/</id>
            
            <published>2020-03-15T07:55:00+00:00</published>
            <updated>2020-03-15T07:55:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p><a href="https://pubs.opengroup.org/onlinepubs/007908799/xcurses/terminfo.html">POSIX mandates implementations must support upto a short but may exceed it</a>.
When NetBSD terminfo was implemented, no terminfo description used over
a short, but because ncurses has supported ints for some time, some now do.</p>
<p>Infact, such a terminfo description was imported where colour pairs for
screen-256color went up to 65536 which exposed a bug in the existing
implementation where it was set to zero. Because the number might mean
something more than a range, we need to be able to store it accurately.</p>
<p>This requires a version bump because whilst the API hasn&rsquo;t changed thanks
to <a href="https://www.geeksforgeeks.org/integer-promotions-in-c/">C int promotion</a>,
the ABI has. Also the underlying database structure
has changed as well- we now store the numeric parameter inside a uint32_t
field rather than a uint16_t one.
Whilst this change can still read the old style database, the old one
cannot read the new one and thus we now maintain the database as
terminfo2.cdb, leaving the old library and database alone so old programs
still work fine.</p>
<p>libcurses, libfrom, libmenu and libpanel have also been bumped to
accomoate this change.</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/netbsd" term="netbsd" label="NetBSD" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[structure padding in C]]></title>
            <link href="https://roy.marples.name/blog/posts/structure_padding_in_c/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/structure_padding_in_c/</id>
            
            <published>2020-01-09T01:06:00+00:00</published>
            <updated>2020-01-09T01:06:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p>Whilst developing <a href="https://en.wikipedia.org/wiki/Privilege_separation">Privilege Separation</a> in <a href="/projects/dhcpcd">dhcpcd</a>, I had to come up with an <a href="https://en.wikipedia.org/wiki/Inter-process_communication">IPC</a> design for it.
Of course, that involves creating <a href="https://en.wikipedia.org/wiki/Struct_(C_programming_language)">structures</a>.</p>
<p>So far, my structures in dhcpcd are long lived- or rather the scope is design to live outside of where it was created.
As such they are created on the <a href="https://en.wikipedia.org/wiki/Heap_(data_structure)">heap</a> and are at the <a href="https://cpp4arduino.com/2018/11/06/what-is-heap-fragmentation.html">mercy of malloc</a>.
Generally I use <a href="https://pubs.opengroup.org/onlinepubs/009695399/functions/calloc.html">calloc</a> so that the whole area is inited to zero as <a href="https://en.wikipedia.org/wiki/Uninitialized_variable">uninitialised memory is bad</a>.</p>
<p>So I decided to start out and see if I can just create the structures I need on the stack.
Turns out I could! Yay!
Now, how to you initialise a structure on the stack to all zeros?
First let us consider this structure:</p>
<div class="highlight"><pre style="background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-c" data-lang="c"><span style="color:#069;font-weight:bold">struct</span> ps_addr {
	sa_family_t psa_family;
	<span style="color:#069;font-weight:bold">union</span> {
		<span style="color:#069;font-weight:bold">struct</span> in_addr psau_in_addr;
		<span style="color:#069;font-weight:bold">struct</span> in6_addr psau_in6_addr;
	} psa_u;
<span style="color:#099">#define	psa_in_addr		psa_u.psau_in_addr
</span><span style="color:#099">#define	psa_in6_addr	psa_u.psau_in6_addr
</span><span style="color:#099"></span>};
</code></pre></div><p>The first way is memset:</p>
<div class="highlight"><pre style="background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-c" data-lang="c"><span style="color:#069;font-weight:bold">struct</span> ps_addr psa;

memset(<span style="color:#555">&amp;</span>psa, <span style="color:#f60">0</span>, <span style="color:#069;font-weight:bold">sizeof</span>(psa));
psa.psa_family <span style="color:#555">=</span> AF_INET;
</code></pre></div><p>But what if you could avoid memset?
Luckily the <a href="https://www.dribin.org/dave/blog/archives/2010/05/15/c99_syntax/">C standard allows setting any member and will zero all other members</a>.
So we can do this:</p>
<div class="highlight"><pre style="background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-c" data-lang="c"><span style="color:#069;font-weight:bold">struct</span> ps_addr psa <span style="color:#555">=</span> { .psa_family <span style="color:#555">=</span> AF_INET };
</code></pre></div><p>Wow!!! So simple. This reduces binary size a fair bit.
But <strong>then</strong> I turned on the <a href="https://github.com/google/sanitizers/wiki/MemorySanitizer">Memory Sanitiser</a> and boom, it crashed hard.
Why?</p>
<p>The answer is simple- padding.
<a href="http://www.catb.org/esr/structure-packing/">Eric S Raymond gives a very good writeup</a> about the problem.
Basically, the standard will initialise any unintialised members to zero- but padding added for alignent isn&rsquo;t a member!
So we need to ensure that our structure requires zero padding.</p>
<p>Here is the new struct:</p>
<div class="highlight"><pre style="background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-c" data-lang="c"><span style="color:#069;font-weight:bold">struct</span> ps_addr {
	sa_family_t psa_family;
	uint8_t psa_pad[<span style="color:#f60">4</span><span style="color:#555">-</span> <span style="color:#069;font-weight:bold">sizeof</span>(sa_family_t)];
	<span style="color:#069;font-weight:bold">union</span> {
		<span style="color:#069;font-weight:bold">struct</span> in_addr psau_in_addr;
		<span style="color:#069;font-weight:bold">struct</span> in6_addr psau_in6_addr;
	} psa_u;
<span style="color:#099">#define	psa_in_addr		psa_u.psau_in_addr
</span><span style="color:#099">#define	psa_in6_addr	psa_u.psau_in6_addr
</span><span style="color:#099"></span>};
</code></pre></div><p>And it allows the former structure initialisation to work and memory sanitisers are happy- so happy days :)
Now, if anyone can tell me what I can use instead of the magic number 4 in the above I&rsquo;d be even happier!</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/dhcpcd" term="dhcpcd" label="dhcpcd" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[open_memstream]]></title>
            <link href="https://roy.marples.name/blog/posts/open_memstream/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/open_memstream/</id>
            
            <published>2019-07-20T13:52:00+00:00</published>
            <updated>2019-07-20T13:52:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p><a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/open_memstream.html">open_memstream</a> is one of the more important functions added to POSIX libc of late. It&rsquo;s so important because it makes the generation of strings really easy- you no longer need to care about allocating the right amount of memory as the library will do it for you.
Now, there&rsquo;s many functions that already help with this, such as <a href="https://netbsd.gw.com/cgi-bin/man-cgi?asprintf">asprintf</a> but that&rsquo;s not standard and if you want to create many strings in one area you still need to care about the size of the area. You want to create an area if you have many strings, because it&rsquo;s more efficient for malloc and if you keep the area around and re-use it then it avoids <a href="https://stackoverflow.com/questions/3770457/what-is-memory-fragmentation">memory fragmentation</a>.</p>
<p>Now, to be clear, <em>you have been able to do this since forever</em> using <a href="https://pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html">fopen</a>, writing to the file and then allocating your area based on the final file size. Still, it requires some memory management still but more importantly <em>it writes to a file</em>. Writing to a file is slow and reduces the life span of the disk you&rsquo;re writing to. It&rsquo;s only been fairly recently that <a href="https://en.wikipedia.org/wiki/Tmpfs">tmpfs</a> was a thing, but even today not all OS&rsquo;s have /tmp mounted as tmpfs. Requiring this isn&rsquo;t exactly ideal for a generic program to do- the setup and install should be easy.
Because of all these reasons, most programs worked the string length needed and either allocated an area or string and then finally write the string. However, while saving the disk, it&rsquo;s also a lot more error prone because you need to work out the length of everything and that&rsquo;s not always trivial, especially for things like a DHCP client which is always building strings based on the information given by the DHCP server.</p>
<p>Here&rsquo;s an example of <code>open_memstream</code> in action:</p>
<div class="highlight"><pre style="background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-c" data-lang="c"><span style="color:#09f;font-style:italic">/*
</span><span style="color:#09f;font-style:italic"> * Example program which manages an area of environment strings
</span><span style="color:#09f;font-style:italic"> * to send to child programs.
</span><span style="color:#09f;font-style:italic"> */</span>

<span style="color:#099">#include</span> <span style="color:#099">&lt;stdio.h&gt;</span><span style="color:#099">
</span><span style="color:#099">#include</span> <span style="color:#099">&lt;stdlib.h&gt;</span><span style="color:#099">
</span><span style="color:#099">#include</span> <span style="color:#099">&lt;unistd.h&gt;</span><span style="color:#099">
</span><span style="color:#099"></span>
<span style="color:#069;font-weight:bold">static</span> <span style="color:#069;font-weight:bold">const</span> <span style="color:#078;font-weight:bold">char</span> <span style="color:#555">*</span>foo <span style="color:#555">=</span> <span style="color:#c30">&#34;foo&#34;</span>;
<span style="color:#069;font-weight:bold">static</span> <span style="color:#069;font-weight:bold">const</span> <span style="color:#078;font-weight:bold">char</span> <span style="color:#555">*</span>bar <span style="color:#555">=</span> <span style="color:#c30">&#34;bar&#34;</span>;

<span style="color:#078;font-weight:bold">int</span> <span style="color:#c0f">main</span>(<span style="color:#078;font-weight:bold">void</span>)
{
        <span style="color:#078;font-weight:bold">char</span> <span style="color:#555">*</span>argv[] <span style="color:#555">=</span> { <span style="color:#c30">&#34;/usr/bin/env&#34;</span>, <span style="color:#366">NULL</span> };
        <span style="color:#078;font-weight:bold">char</span> <span style="color:#555">*</span>buf, <span style="color:#555">*</span>ep, <span style="color:#555">*</span>p, <span style="color:#555">**</span>env, <span style="color:#555">**</span>envp;
        size_t buflen, nenv, i;
        FILE <span style="color:#555">*</span>fp <span style="color:#555">=</span> open_memstream(<span style="color:#555">&amp;</span>buf, <span style="color:#555">&amp;</span>buflen);

        fprintf(fp, <span style="color:#c30">&#34;FOO=%s&#34;</span>, foo);
        fputc(<span style="color:#c30">&#39;\0&#39;</span>, fp);
        fprintf(fp, <span style="color:#c30">&#34;BAR=%s&#34;</span>, bar);
        fputc(<span style="color:#c30">&#39;\0&#39;</span>, fp);

        <span style="color:#09f;font-style:italic">/* We could keep fp around as our area and just rewind it. */</span>
        fclose(fp);

        <span style="color:#09f;font-style:italic">/* execve relies on a trailing NULL */</span>
        nenv <span style="color:#555">=</span> <span style="color:#f60">1</span>;
        <span style="color:#069;font-weight:bold">for</span> (p <span style="color:#555">=</span> buf, ep <span style="color:#555">=</span> p <span style="color:#555">+</span> buflen; p <span style="color:#555">&lt;</span> ep; p<span style="color:#555">++</span>) {
                <span style="color:#069;font-weight:bold">if</span> (<span style="color:#555">*</span>p <span style="color:#555">==</span> <span style="color:#c30">&#39;\0&#39;</span>)
                        nenv<span style="color:#555">++</span>;
        }

        <span style="color:#09f;font-style:italic">/* reallocarray(3) should be standard really */</span>
        envp <span style="color:#555">=</span> env <span style="color:#555">=</span> malloc(nenv <span style="color:#555">*</span> <span style="color:#069;font-weight:bold">sizeof</span>(<span style="color:#078;font-weight:bold">char</span> <span style="color:#555">*</span>));
        <span style="color:#555">*</span>envp<span style="color:#555">++</span> <span style="color:#555">=</span> buf;
        <span style="color:#069;font-weight:bold">for</span> (p <span style="color:#555">=</span> buf, ep<span style="color:#555">--</span>; p <span style="color:#555">&lt;</span> ep; p<span style="color:#555">++</span>) {
                <span style="color:#069;font-weight:bold">if</span> (<span style="color:#555">*</span>p <span style="color:#555">==</span> <span style="color:#c30">&#39;\0&#39;</span>)
                        <span style="color:#555">*</span>envp<span style="color:#555">++</span> <span style="color:#555">=</span> p <span style="color:#555">+</span> <span style="color:#f60">1</span>;
        }
        <span style="color:#555">*</span>envp <span style="color:#555">=</span> <span style="color:#366">NULL</span>;

        execve(argv[<span style="color:#f60">0</span>], argv, env);
}
</code></pre></div><p>As you can see, we only manage the environment array handed to to <code>execve</code>.
<code>open_memstream</code> is managing our string area and <code>fprintf</code> is working out the
length each string needs to be for us.
This vastly reduces the complexity and increases the security and reliabilty
of creating large environment strings, which most DHCP clients do.
We could also write a helper function to write the string AND the trailing
NULL terminator for the string to be more efficient.
You&rsquo;ll get to see this in dhcpcd-8 which should be released later this year.</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/tech" term="tech" label="tech" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/dhcpcd" term="dhcpcd" label="dhcpcd" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[Red-Black Tree]]></title>
            <link href="https://roy.marples.name/blog/posts/red_black_tree/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/red_black_tree/</id>
            
            <published>2019-07-04T13:43:00+00:00</published>
            <updated>2019-07-04T13:43:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p>Pretty much every piece of software I&rsquo;ve seen uses a list of objects. When you need to easily grow and shrink this list easily you then need something like a <a href="https://en.wikipedia.org/wiki/Linked_list">Linked List</a>.
dhcpcd has used very popular and widely available BSD based <a href="https://netbsd.gw.com/cgi-bin/man-cgi?queue+3+NetBSD-current">queue(3), specifically a tailq</a>. The main advantages of this type of list are:</p>
<ul>
<li>Very low extra memory needed for it&rsquo;s implementation</li>
<li>Fast at insertion and removal operation- both are O(1)</li>
</ul>
<p>However, it&rsquo;s just a list. And like any list, to find something we need to pick a starting point and then search in a single direction and match each item until we find it.
This is described as O(N) and it&rsquo;s performance roughly corrolates to the Number of objects in the list. If you need to insert at an arbitary point <em>(for example to order the list)</em> you need to search it, so this is O(N) also.</p>
<p>But is this slow?</p>
<p>Typically for dhcpcd, the answer is no because on a desktop, tablet, phone or SOHO router you only have a handful of objects in all the lists.
However, <a href="https://roy.marples.name/archives/dhcpcd-discuss/0002332.html">someone ran dhcpcd on a switch with millions of routes</a> and dhcpcd was taking minutes of CPU time for routing table modifications. So in this corner case &hellip; yes! dhcpcd is slow!
A suggestion to improve matters was given in that report- use a <a href="https://en.wikipedia.org/wiki/Red%E2%80%93black_tree">Red-Black Tree</a> instead of a Linked List. A RB tree guarantees O(log N) performance for searching. A patch was even submitted based on OpenBSD&rsquo;s tree implementation!
This reduced the dhcpcd runtime from minutes to seconds in his situation.</p>
<p>Now you can&rsquo;t just swap in a RB Tree for a Linked List. Each object within an RB Tree has to have a unique key. Also, you need to have comparison function to define an order to the objects within the tree.
Only then can you start to implement it. To find an object within the tree, you just need to know it&rsquo;s key and off you go.
I settled on using NetBSD&rsquo;s <a href="https://netbsd.gw.com/cgi-bin/man-cgi?rbtree+3+NetBSD-current">rbtree(3)</a> implementation instead of the initial suggestion to use the generic BSD <a href="https://netbsd.gw.com/cgi-bin/man-cgi?tree+3+NetBSD-current">tree(3)</a>.
This mainly to reduce the binary size of dhcpcd because it&rsquo;s in libc on NetBSD and on other systems it will creates a smaller binary due to the complexity of the tree(3) macros.
Testing also showed it was slightly faster and also easier to actually develop with.</p>
<p>So should you replace all LinkedLists with RB Trees? No! That would be silly :)
After all, sometimes you don&rsquo;t actually need to search or order a list- a lot of the time, lists are used for push/pop operations and thus gain nothing from RB Tree.</p>
<p>You&rsquo;ll get to see this in dhcpcd-8 which should be released later this year.</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/tech" term="tech" label="tech" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/dhcpcd" term="dhcpcd" label="dhcpcd" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[IP address sharing]]></title>
            <link href="https://roy.marples.name/blog/posts/ip_address_sharing/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/ip_address_sharing/</id>
            
            <published>2017-07-05T16:25:00+00:00</published>
            <updated>2017-07-05T16:25:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p>So dhcpcd has supported a shared IP address for a long time. It did this by removing the address from the non preferrred interface and then adding it to the preferred interface.<br>
Easy!</p>
<p>But this came with some issues:</p>
<ul>
<li>There is a window where the IP address doesn&rsquo;t exist, and the kernel may wipe out the subnet route at that point also.</li>
<li>DHCP renews didn&rsquo;t come through to the right interface.</li>
<li>Some kernels didn&rsquo;t like the address moving interfaces.</li>
</ul>
<p>Still, to the best of my knowledge, no other product has this feature and for the most part, it did work well allowing almost seamless switching of wired-&gt; wireless and back again with both using the same IP address. But that wasn&rsquo;t good enough - <a href="https://roy.marples.name/archives/dhcpcd-discuss/0001706.html">I was challenged to do better!</a></p>
<p>So I took up the bat and changed the behaviour to this:</p>
<ul>
<li>Each applicable interface will have the shared ip address.</li>
<li>Whenever the address is added, the most preferred address will be ARP announced.</li>
</ul>
<p>And lo - <strong>IT WORKS!!!</strong>  The changeover when plugging/removing the wired interface is 100% seamless for me. ssh, ping, etc get zero interuption. Of course, YMMV ;)<br>
But there are some costs:</p>
<ul>
<li>Thanks to ARP, only the primary interface will receive DHCP unicast messages for other interfaces.<br>
As such we need to re-direct them to the correct interface by examining <code>xid</code> and <code>chaddr</code>.<br>
This means we have to relax the BPF filters to allow more through.</li>
<li>Kernels supporting <a href="https://tools.ietf.org/html/rfc5227">RFC5227</a> will double ARP announce the address.</li>
<li>NetBSD-8 kernels needed some love to get it to work and there&rsquo;s still an issue with it not working when an address is deleted from the interface.</li>
</ul>
<p>Only the last bullet is really important, which is mainly why the changeset hasn&rsquo;t hit the master branch yet. But that should be fixed soon.
The other points can be fixed as and when.</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/tech" term="tech" label="tech" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[dhcpcd-7 finally enters beta]]></title>
            <link href="https://roy.marples.name/blog/posts/dhcpcd-7_finally_enters_beta/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/dhcpcd-7_finally_enters_beta/</id>
            
            <published>2017-03-31T21:25:00+00:00</published>
            <updated>2017-03-31T21:25:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p>It&rsquo;s been a while in the making, but dhcpcd-7.0.0-beta1 is finally here!
I have been using this a <em>lot</em> on all supported platforms bar Solaris
and it&rsquo;s been very trouble free, so hopefully not many changes (if any?
famous last words!) before a RC and final release.</p>
<p>Summary of changes since dhcpcd-6.11.5:</p>
<ul>
<li>source file locations reworked:
dhcpcd source is in src
dhcpcd hooks are in hooks
compat is in compat</li>
<li>README split into README.md and BUILDING.md</li>
<li>internal routing is now protocol agnostic</li>
<li>avoid using <code>__packed</code> and use compile time asserts instead</li>
<li>addresses some alignment issues</li>
<li>disable some ARP code on kernels which support RFC5227</li>
<li>BSD IPv6 kernel settings are now updated to reflect dhcpcd config</li>
<li>custom logger has been removed, syslog handles everything
as such, the <code>--logfile</code> option has been removed as well.
If you need better/earlier logging, get a better syslogger!</li>
<li>distinfo and signed distinfo files are now available alongside
release taraballs from this point onwards</li>
<li>default DBDIR has changed from <code>/var/db</code> to <code>/var/db/dhcpcd</code></li>
<li><code>/etc/dhcpcd.duid</code> moves to <code>DBDIR/duid</code></li>
<li><code>/etc/dhcpcd.secret</code> moves to <code>DBDIR/secret</code></li>
<li>lease file names have dhcpcd removed from them as they are now
inside a directory of the same name</li>
<li>fixed issues with reject routes not working on some platforms</li>
<li>improved nl80211 support on Linux for working out the SSID</li>
<li>no longer request NTP by default in dhcpcd.conf</li>
<li>fix detecting IPv6 DAD on OpenBSD</li>
<li>remove custom Solaris DLPI filtering in favour of BPF
(note there seems to be a kernel issue where the DHCP
fd receives ARP&rsquo;s as well, the only side effect is
a noisy syslog)</li>
<li>BPF filtering vastly improved so dhcpcd only wake up on
ARP or DHCP packets destined for it</li>
<li>support for MUD URL (draft-ietf-opsawg-mud-05)</li>
<li>if the kernel isn&rsquo;t doing DAD, don&rsquo;t insist on waiting for it
to actually do it</li>
<li>fix a potential crash where the DHCP or ARP states could be
freed before the packet processing loop naturally breaks</li>
<li>removed gateway and nogateway options
(these can be controlled by the nooption directive which
works for more than just gateways)</li>
<li>removed ipv6ra_own and ipv6ra_own_default options
(these can be controled by the ipv6rs/noipv6rs directive)</li>
<li>fix a memory leak on systems where posix_spawnattr_init
allocates memory by calling posix_spawnattr_destroy afterwards</li>
<li>fix a crash receiving SIGUSR1</li>
</ul>
<p>I&rsquo;ve not done everything I&rsquo;ve wanted to, but I feel that many issues
have now been addressed and on the whole dhcpcd is in a very good state
right now.</p>
<p>Let me know of any issues you find!</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[Fossil <-> Git bridge]]></title>
            <link href="https://roy.marples.name/blog/posts/fossil_git_bridge/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/fossil_git_bridge/</id>
            
            <published>2017-02-22T03:10:00+00:00</published>
            <updated>2017-02-22T03:10:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p>I&rsquo;ve been using <a href="http://fossil-scm.org/index.html/doc/trunk/www/index.wiki">Fossil</a> for quite a while now as my <a href="https://en.wikipedia.org/wiki/Version_control">SCM</a>.
I like Fossil.
But Fossil is not <a href="https://git-scm.com/">Git</a>, and most people seem to like Git.
It could be better to say that most people like <a href="https://github.com/">GitHub</a> because it&rsquo;s the first hosted SCM that&rsquo;s free for open source with good social interaction I&rsquo;m aware of.
And GitHub is <strong>huge</strong>.
Some might say that if you&rsquo;re not on GitHub, you don&rsquo;t exist as a project. Well this obviously isn&rsquo;t true, but you get the idea.
You <em>can</em> get free Fossil hosting at <a href="http://chiselapp.com/">Chisel</a>, which is nice, but it&rsquo;s also not GitHub.
Plus I like to be 100% self hosted.</p>
<p>So, to get myself on GitHub <em>(as a mirror only)</em>, there needs to be a bridge between Fossil and Git.
<a href="http://fossil-scm.org/xfer/doc/trunk/www/inout.wiki">Fossil documentation</a> implies this is quite easy. Sadly, this isn&rsquo;t the case as the &lt;=Fossil-1.37 releases <em>(note there is no guaranntee that future versions of follow will not have these flaws- my branch may not be comitted to trunk)</em> have the following flaws:</p>
<ul>
<li>Branch and Tag name mangling (dhcpcd-6 becomes dhcpcd_6)</li>
<li>Silent master branch renaming into trunk on inport, but not on export</li>
<li>No tag comments (Fossil lacks the feature) which means syncing tags back and forth results in tag conflict due to signature change</li>
</ul>
<p>I submitted some initial patches the the <a href="http://www.mail-archive.com/fossil-users@lists.fossil-scm.org/msg24586.html">Fossil mailing list</a> and I now have a Fossil commit bit!
You can <a href="https://www.fossil-scm.org/xfer/timeline?r=roy-export&amp;nd">find my branch here to fix the Fossil Git bridge</a>.</p>
<p>But that&rsquo;s not the end of the story.
A bridge has two ends.
With my initial setup, the Git end was bare bones repository which I pushed to GitHub.
This is no longer the case- I now need a staging repository to pull both ends.
And this requires a script because Git needs a little more hand-holding to completely track a remote.
The below script is tailored for my needs, yours may differ. It also reflects the above initial design and the subsequent change- as such it it may need editing if you need to create a git clone from fossil.
This comes with no support, just as an idea of how you might implement such a bridge.</p>
<div class="highlight"><pre style="background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh"><span style="color:#099">#!/bin/sh
</span><span style="color:#099"></span>
<span style="color:#033">fossildir</span><span style="color:#555">=</span>/var/fossil
<span style="color:#09f;font-style:italic"># Cannot be a bare directory for git as we cannot write to the host directly.</span>
<span style="color:#09f;font-style:italic"># So we have a staging directory instead.</span>
<span style="color:#09f;font-style:italic"># This requires a bit of hand-holding to track all the branches.</span>
<span style="color:#033">gitdir</span><span style="color:#555">=</span>/var/git-staging

<span style="color:#033">marksdir</span><span style="color:#555">=</span>/var/scm-marks

<span style="color:#09f;font-style:italic"># Respect default naming at either end</span>
<span style="color:#033">fossil_export_opts</span><span style="color:#555">=</span><span style="color:#c30">&#34;--rename-trunk master&#34;</span>
<span style="color:#033">fossil_import_opts</span><span style="color:#555">=</span><span style="color:#c30">&#34;--rename-master trunk&#34;</span>

<span style="color:#09f;font-style:italic"># Only used when creating a git bare bones repo from Fossil.</span>
export_fossil_to_git_new<span style="color:#555">()</span>
<span style="color:#555">{</span>

        rm-f <span style="color:#c30">&#34;</span><span style="color:#033">$fossilmarks</span><span style="color:#c30">&#34;</span> <span style="color:#c30">&#34;</span><span style="color:#033">$gitmarks</span><span style="color:#c30">&#34;</span>
        git init
        fossil export--git <span style="color:#c30;font-weight:bold">\
</span><span style="color:#c30;font-weight:bold"></span>--export-marks <span style="color:#c30">&#34;</span><span style="color:#033">$fossilmarks</span><span style="color:#c30">&#34;</span> <span style="color:#c30;font-weight:bold">\
</span><span style="color:#c30;font-weight:bold"></span>                <span style="color:#033">$fossil_export_opts</span> <span style="color:#c30">&#34;</span><span style="color:#033">$fossildir</span><span style="color:#c30">/</span><span style="color:#033">$fossilrepo</span><span style="color:#c30">&#34;</span> | <span style="color:#c30;font-weight:bold">\
</span><span style="color:#c30;font-weight:bold"></span>                git fast-import <span style="color:#c30;font-weight:bold">\
</span><span style="color:#c30;font-weight:bold"></span>--export-marks<span style="color:#555">=</span><span style="color:#c30">&#34;</span><span style="color:#033">$gitmarks</span><span style="color:#c30">&#34;</span>
<span style="color:#555">}</span>

export_fossil_to_git<span style="color:#555">()</span>
<span style="color:#555">{</span>

        fossil export--git <span style="color:#c30;font-weight:bold">\
</span><span style="color:#c30;font-weight:bold"></span>--import-marks <span style="color:#c30">&#34;</span><span style="color:#033">$fossilmarks</span><span style="color:#c30">&#34;</span>--export-marks <span style="color:#c30">&#34;</span><span style="color:#033">$fossilmarks</span><span style="color:#c30">&#34;</span> <span style="color:#c30;font-weight:bold">\
</span><span style="color:#c30;font-weight:bold"></span>                <span style="color:#033">$fossil_export_opts</span> <span style="color:#c30">&#34;</span><span style="color:#033">$fossildir</span><span style="color:#c30">/</span><span style="color:#033">$fossilrepo</span><span style="color:#c30">&#34;</span> | <span style="color:#c30;font-weight:bold">\
</span><span style="color:#c30;font-weight:bold"></span>                git fast-import <span style="color:#c30;font-weight:bold">\
</span><span style="color:#c30;font-weight:bold"></span>--import-marks<span style="color:#555">=</span><span style="color:#c30">&#34;</span><span style="color:#033">$gitmarks</span><span style="color:#c30">&#34;</span>--export-marks<span style="color:#555">=</span><span style="color:#c30">&#34;</span><span style="color:#033">$gitmarks</span><span style="color:#c30">&#34;</span>
<span style="color:#555">}</span>

export_git_to_fossil<span style="color:#555">()</span>
<span style="color:#555">{</span>

        git fast-export--all <span style="color:#c30;font-weight:bold">\
</span><span style="color:#c30;font-weight:bold"></span>--import-marks<span style="color:#555">=</span><span style="color:#c30">&#34;</span><span style="color:#033">$gitmarks</span><span style="color:#c30">&#34;</span>--export-marks<span style="color:#555">=</span><span style="color:#c30">&#34;</span><span style="color:#033">$gitmarks</span><span style="color:#c30">&#34;</span> | <span style="color:#c30;font-weight:bold">\
</span><span style="color:#c30;font-weight:bold"></span>                fossil import--git--incremental <span style="color:#c30;font-weight:bold">\
</span><span style="color:#c30;font-weight:bold"></span>--import-marks <span style="color:#c30">&#34;</span><span style="color:#033">$fossilmarks</span><span style="color:#c30">&#34;</span>--export-marks <span style="color:#c30">&#34;</span><span style="color:#033">$fossilmarks</span><span style="color:#c30">&#34;</span> <span style="color:#c30;font-weight:bold">\
</span><span style="color:#c30;font-weight:bold"></span>                <span style="color:#033">$fossil_import_opts</span> <span style="color:#c30">&#34;</span><span style="color:#033">$fossildir</span><span style="color:#c30">/</span><span style="color:#033">$fossilrepo</span><span style="color:#c30">&#34;</span>
<span style="color:#555">}</span>

pull_git<span style="color:#555">()</span>
<span style="color:#555">{</span>
        <span style="color:#366">local</span> remote

        git fetch--all
        <span style="color:#09f;font-style:italic"># Track all remote branches</span>
        git branch-r | grep-v <span style="color:#c30">&#39;\-&gt;&#39;</span> | <span style="color:#069;font-weight:bold">while</span> <span style="color:#366">read</span> remote; <span style="color:#069;font-weight:bold">do</span>
                <span style="color:#069;font-weight:bold">if</span> <span style="color:#555">[</span>-z <span style="color:#c30">&#34;</span><span style="color:#069;font-weight:bold">$(</span>git branch--list <span style="color:#c30">&#34;</span><span style="color:#a00">${</span><span style="color:#033">remote</span>#origin/<span style="color:#a00">}</span><span style="color:#c30">&#34;</span><span style="color:#069;font-weight:bold">)</span><span style="color:#c30">&#34;</span> <span style="color:#555">]</span>; <span style="color:#069;font-weight:bold">then</span>
                        git branch--track <span style="color:#c30">&#34;</span><span style="color:#a00">${</span><span style="color:#033">remote</span>#origin/<span style="color:#a00">}</span><span style="color:#c30">&#34;</span> <span style="color:#c30">&#34;</span><span style="color:#033">$remote</span><span style="color:#c30">&#34;</span>
                <span style="color:#069;font-weight:bold">fi</span>
        <span style="color:#069;font-weight:bold">done</span>
        git branch--list | sed-e <span style="color:#c30">&#39;s/^\* //&#39;</span> | <span style="color:#069;font-weight:bold">while</span> <span style="color:#366">read</span> branch; <span style="color:#069;font-weight:bold">do</span>
                git checkout <span style="color:#c30">&#34;</span><span style="color:#033">$branch</span><span style="color:#c30">&#34;</span>
                git merge--ff-only
        <span style="color:#069;font-weight:bold">done</span>
<span style="color:#555">}</span>

push_git<span style="color:#555">()</span>
<span style="color:#555">{</span>

        git push--all
        git push--tags
        <span style="color:#09f;font-style:italic"># Reset the current branch checkout.</span>
        <span style="color:#09f;font-style:italic"># If we don&#39;t, the next run will complain about unstashed changes.</span>
        <span style="color:#09f;font-style:italic"># This maybe a bug in git, but maybe not because the live checkout</span>
        <span style="color:#09f;font-style:italic"># *is* behind at this point as we just fast-imported.</span>
        git reset--hard
<span style="color:#555">}</span>

<span style="color:#366">echo</span> <span style="color:#c30">&#34;Syncing git and fossil.&#34;</span>
<span style="color:#069;font-weight:bold">for</span> repo in <span style="color:#c30">&#34;</span><span style="color:#033">$fossildir</span><span style="color:#c30">&#34;</span>/*.fossil; <span style="color:#069;font-weight:bold">do</span>
        <span style="color:#033">fossilrepo</span><span style="color:#555">=</span><span style="color:#a00">${</span><span style="color:#033">repo</span>#<span style="color:#a00">${</span><span style="color:#033">fossildir</span><span style="color:#a00">}</span>/*<span style="color:#a00">}</span>
        <span style="color:#033">repo</span><span style="color:#555">=</span><span style="color:#a00">${</span><span style="color:#033">fossilrepo</span>%.fossil<span style="color:#a00">}</span>
        <span style="color:#033">gitrepo</span><span style="color:#555">=</span><span style="color:#c30">&#34;</span><span style="color:#033">$repo</span><span style="color:#c30">&#34;</span>
        <span style="color:#033">fossilmarks</span><span style="color:#555">=</span><span style="color:#c30">&#34;</span><span style="color:#033">$marksdir</span><span style="color:#c30">/</span><span style="color:#033">$repo</span><span style="color:#c30">.fossil.marks&#34;</span>
        <span style="color:#033">gitmarks</span><span style="color:#555">=</span><span style="color:#c30">&#34;</span><span style="color:#033">$marksdir</span><span style="color:#c30">/</span><span style="color:#033">$repo</span><span style="color:#c30">.git.marks&#34;</span>

        <span style="color:#09f;font-style:italic"># We just sync old fossil repos to new phab clones</span>
        <span style="color:#069;font-weight:bold">if</span> <span style="color:#555">[</span>-d <span style="color:#c30">&#34;</span><span style="color:#033">$gitdir</span><span style="color:#c30">/</span><span style="color:#033">$gitrepo</span><span style="color:#c30">&#34;</span> <span style="color:#555">]</span>; <span style="color:#069;font-weight:bold">then</span>
                <span style="color:#366">cd</span> <span style="color:#c30">&#34;</span><span style="color:#033">$gitdir</span><span style="color:#c30">/</span><span style="color:#033">$gitrepo</span><span style="color:#c30">&#34;</span>
                pull_git <span style="color:#09f;font-style:italic"># staging only</span>
                export_git_to_fossil
                export_fossil_to_git
                push_git <span style="color:#09f;font-style:italic"># staging only</span>
<span style="color:#09f;font-style:italic"># Enable the below if pusing to a bare git repo from fossil</span>
<span style="color:#09f;font-style:italic">#       else</span>
<span style="color:#09f;font-style:italic">#               export_fossil_to_git_new</span>
        <span style="color:#069;font-weight:bold">fi</span>
<span style="color:#069;font-weight:bold">done</span>
</code></pre></div><p><a href="http://roy.marples.name/downloads/reposync">Direct download to script</a></p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/site" term="site" label="site" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[A New Start]]></title>
            <link href="https://roy.marples.name/blog/posts/a_new_start/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/a_new_start/</id>
            
            <published>2016-12-01T00:00:00+00:00</published>
            <updated>2016-12-01T00:00:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p>So, I&rsquo;ve not blogged for a long long long time.
The last time was over 2 years ago.
There are various reasons for this, involving Tech, Code and Life.</p>
<h2 id="tech">Tech</h2>
<p>My old blog was powered by <a href="http://www.s9y">Serendipity</a>.
Before that, it was <a href="http://trac.edgewall.org/">Trac</a> and before that it was <a href="http://www.drupal.org">Drupal</a></p>
<p>Now, Drupal was very &hellip;&hellip; well, blocky. It worked, and worked well to start. But my poor server at the time could not cope with the resource demands it had, alongside my existing Trac instances to host my project&rsquo;s wiki and ticketing systems. So I migrated it to the <a href="http://trac-hacks.org/wiki/FullBlogPlugin">Trac FullBlog Plugin</a>.
This was amazing! Where Drupal was complex, Trac was simplicity. Life was good.</p>
<p>But slow. As it turns out Trac itself was getting slower and slower.
So I changed from <a href="http://httpd.apache.org/docs/2.4/mod/prefork.html">Apache Pre-Fork</a> to <a href="https://www.lighttpd.net/">Lighttpd</a>.
This didn&rsquo;t work too great for me. Too complex, too crash. So I changed to <a href="https://www.nginx.com/solutions/web-server/">nginx</a>.
and used <a href="http://projects.unbit.it/uwsgi">uWSGI</a> to bridge my fcgi&rsquo;s. Wow, my multi-purpose server had free memory!
Amazing! I used this setup for about 5 years, maybe longer.
However, Trac still got slower and slower.</p>
<p>So I migrated it all to Serendipity (the blog that is).
I was also getting fed up with using <a href="http://git-scm.com/">git</a> as my source code repo alongside Trac so I changed that to <a href="http://www.fossil-scm.org">Fossil</a>.
No more Trac? And nginx and uwsgi working great! Life was good, my server now had over 1G free memory &hellip; which did slowly get used up as a cache I guess. But swap was never ever hit.
Even when compiling the server software.
Tech did not get this good.</p>
<p>But then it stopped.
Serendipity refused to let me log in to the admin panel.
But Life got in the way at this point. So I didn&rsquo;t blog.</p>
<p>Fast forward to now and my <a href="http://nuclearelephant.com/">DSPAM filter</a> stopped working.
Full stop.
No-one knew why, myself and a few NetBSD devs spent a few hours looking at the problem.
It only worked outside of my <a href="http://www.procmail.org/">procmail</a> filter, but my setup required it to work inside as I have email lists on the same box that required unfiltered mail to hit their informational funcions.
And I hate <a href="https://en.wikipedia.org/wiki/Email_spam">SPAM</a>.
So I installed <a href="http://spamassassin.apache.org/">SpamAssassin</a> as a replacement.
It turned out the <a href="http://www.pkgsrc.org/">pkgsrc</a> package needed a small bit of love, but now it&rsquo;s working as well as DSPAM ever did, but more importantly working.
As a result of this, I had to prune spam from my hosted mailing list archives and it turns out <a href="http://www.hypermail-project.org/">hypermail</a> doesn&rsquo;t allow you to do this, short of manually rebuilding the archive.
So I ditched that and rebuilt <a href="/archives">my mail archives</a> around <a href="http://www.mhonarc.org/">mhonarc</a>. I also took the time to theme it like my Fossil projects for consistency, which is fine.</p>
<p>Now, a lot of mail archives have a nice search function too so I decided to brush off my <a href="http://www.php.net">PHP</a> skills which I&rsquo;ve not used since the 1990&rsquo;s.
It turned out my skills weren&rsquo;t that great as I thought and my first attempt failed. But no error was posted OR logged.
It turned out that I couldn&rsquo;t get uWSGI or NGINX to actually log my PHP errors! I&rsquo;m sure there was a way, but frankly the setup was hard to manage so instead of bashing my head, I looked to find an easier solution.</p>
<p>Apache had gained a new <a href="https://httpd.apache.org/docs/2.4/mod/event.html">event MPM</a> which promised the same low memory use as NGINX.
It also had really improved <a href="https://httpd.apache.org/mod_fcgid/">mod_fcgid</a> and <a href="https://httpd.apache.org/docs/current/mod/mod_proxy.html">mod_proxy</a> so it&rsquo;s very useable easily.
PHP had <a href="http://php.net/manual/en/install.fpm.php">integrated PHP-FPM</a>.
As I no longer needed Trac, NGINX or uWSGI i said <a href="https://twitter.com/rsmarples/status/802230704985751552">bye bye</a> to them all and installed Apache.
So full circle on the web server, but I now had easy to find PHP error reporting, so my <a href="/archives/search.php">archives search page</a> worked fine after a quick fix!</p>
<p>In summary everything on my server was back to normal, fully working nicely, easily and well reported and diagnosed.
Except my blog. I spent more time looking at it, didn&rsquo;t like it, nor the hard upgrade I was looking at the to latest version.
So, after changing all my software, why not my Blog?</p>
<p>After migrating a few times, I know the score.
<strong>It&rsquo;s Tricky (TM).</strong>
So how to make life better? After a lot of research, I have settled on using <a href="http://getgrav.org/">GRAV</a> for a few reasons listed here:</p>
<ul>
<li>Does not force MySQL database (I prefer PostgreSQL)</li>
<li>No SQL database requirement, uses folders and Markdown files with embedded meta data</li>
<li>The default theme already looks good</li>
<li>Can self upgrade</li>
<li>Because everthing is in markdown files it should be easier to manage and migrate away from later</li>
<li>I want to self host- this is my data, not someone else&rsquo;s</li>
<li>It&rsquo;s in PHP <em>(so no need to install Node.JS, Ruby or whatever flavour of the month is)</em></li>
<li>MIT license (close enough to my favoured 2 clause BSD)</li>
</ul>
<p>So, this is the first post in a new blog, a new start where my Tech is currently &hellip;.. working without issue!
This has got to be a first for me :)</p>
<h2 id="code">Code</h2>
<p>I write code. I like to think I&rsquo;m quite good at it :) And like most people, I have an opinion on what makes good code and bad code &hellip;. I hate bad code, even my own!
So how did code get in the way?</p>
<p>I mentioned earlier that for some reason I my Serendipity admin login stopped working. Well, I looked at the code &hellip;. and it was not nice.
<em>(My install was an old version compared to their current 2.0 so this may have changed)</em>
There were little comments, there was poor seperation between Model, Controller and View.
Now, the actual code in question looked like it should be working &hellip;. it hashed my paswsword, compared the hash to the saved DB entry.
I even went as far as adding debug code.
It all looked perfect, yet it did not work. No-one knew where the error was.</p>
<p>I was also pretty annoyed with Serendipity for other reasons I discovered only after using it, so I decided to ditch it entirely and move on.
As you can tell above, I have no problem changing out software I no longer believe in, or fares poorly compared to others. I also enjoy when the software I originally chose makes great strides to tempt me back in the fold, like Apache.
I don&rsquo;t claim to understand web server code, but I did peruse their codebase a while ago and it looks cleaner compared to when I did in the early 90&rsquo;s trying to make it work on Windows for $DAYJOB.</p>
<p>I&rsquo;ve also spent a lot of time on my pet coding projects, dhcpcd, dhcpcd-ui, resovlconf and NetBSD.</p>
<p>Anyway, enough ramblings about code. There will be a lot more about that in the future anyway now that I have a working blog again.
Well, almost working.
I need to write some code to import from Serendipity to here, which will be nice as I enjoy coding and want to preserve the content I&rsquo;ve lovingly created- alongwith you in the comments- over the years and I would hate to lose that!
Speaking of comments, there is currently no comment system on this blog. <a href="https://twitter.com/intent/tweet?screen_name=rsmarples" class="twitter-mention-button" data-show-count="false">So Tweet me about it</a><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script> for the time being until I integrate something like <a href="https://posativ.org/isso/">ISSO commenting</a> or maybe find a Grav plugin.
I also need to find a way of providing top links to my project pages.</p>
<h2 id="life">Life</h2>
<p>So in the past few years, my Family has been very stable and loving :)
But a new child got in the way! Ethan Thomas Marples was born 2nd December 2015, so he&rsquo;s one year old tomorrow!
That has taken a lot of my time, and all my children still take a lot of my time, so it&rsquo;s a very enjoyable getting in the way :D</p>
<p>There&rsquo;s also been some changes at work. My old company <a href="http://www.instem.com/news/articles/1305-instem-enters-early-phase-clinical-market.php">Logos Technologies was bought by Instem</a>.
I&rsquo;m still doing the same job, working on the same product, but the inner dealings of the buy out, company politics and day to day integration have certainly been eye opening.</p>
<p>Playing games got in the way. Far too much time playing MMO&rsquo;s &hellip;. I&rsquo;m now off that bandwagon. But I don&rsquo;t regret it, it was a lot of fun :)</p>
<p>I&rsquo;ve also been on a health roller coaster. I&rsquo;ve taken the nice Doctors Orders and have invested in a <a href="https://www.fitbit.com/uk/chargehr">FitBit Charge</a> and <a href="https://www.fitbit.com/uk/aria">FitBit Aria Scales</a> which keep track of my steps, calories burned, sleep and weight. There is no more hiding.
The good news is that I&rsquo;m a lot fitter- I now enjoy walking and take a 40 minute walk each day minimum <strong>as well as walking the kids too and from school</strong>.
I&rsquo;m drinking a lot lot less, but still enjoy <em>(probably a little too much still)</em> a weekend tipple.</p>
<p>I&rsquo;ve lost over a stone <strong>(21 pounds to be precise)</strong> as a result!
My resting BPM as dropped from a <em>$HIGHNUMBER</em> to 58, which is healthy :D
I <em>should</em> keep track of my blood pressure more, but maybe in the new year &hellip;.. but</p>
<p>** GO ME!! **</p>
<p>I&rsquo;m fitter, stronger, more alert and ready to blog!
Although probably shorter blogs next time ;)</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/tech" term="tech" label="tech" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/life" term="life" label="life" />
                            
                        
                    
                
            
        </entry>
    
</feed>
