Search Results: "ed"

15 November 2013

Paul Tagliamonte: Now introducing: Snitch!

Snitch is the first DSL I ve written in Hy. It may be the first Hy DSL ever, but I have nothing to prove that. Since I ve had a bit of time while the hard-working Alioth maintainers hack on getting vasks alive, I wrote Snitch (and set up the Debian view to be shown on fraked.debian.net - more to come!) Snitch's DSL looks like:
(rules "personal"
  (rule "pault.ag" pingable httpable)
  (rule "lucifer.pault.ag" pingable httpable))
Which expands out to quite a few lines that query the server s status using Snitch s informants, and insert the result into MongoDB. More to come!

Rudy Godoy: New GPG Key 65F80A4D

A bit late but I ve created a new 4096 RSA GPG key. I ve published a transition document as well. I hope I can meet fellow Debian developers soon to get my new key signed. So, if you are in town (Arequipa, Peru) drop me an email!

14 November 2013

Steve Kemp: Meanwhile, behind the facade of this innocent book store

In brief:

Russ Allbery: rra-c-util 4.11

This is my collection of helper libraries and utilities that I use for most of my C-based software (and some Perl bits as well). Most of the changes in this release are improvements to the Autoconf macros, primarily based on feedback from Julien LIE and reconciliation with the macros used in INN. The major backward-incompatible change is that RRA_LIB_KRB5 and friends now define HAVE_KRB5 (to match the name) and set rra_use_KRB5, and similarly RRA_LIB_OPENSSL and friends define HAVE_OPENSSL and set rra_use_OPENSSL. Any packages that use these macros will probably need some updates. There are also a couple other fixes for RRA_LIB_KRB5 and RRA_LIB_KRB5_OPTIONAL: both now work for packages that do not use Automake, and the optional version does not fail if com_err couldn't be found. Similarly, RRA_LIB_OPENSSL_OPTIONAL no longer aborts if libcrypto couldn't be found and both OpenSSL macros probe for libdl first unless --enable-reduced-depends is used. Finally, RRA_LIB_OPENSSL properly restores the default CPPFLAGS, LDFLAGS, and LIBS after the library probes. Also in this release, all uses of asprintf, snprintf, and related functions check the return status, since POSIX allows these functions to fail for reasons other than memory allocation failure. xasprintf and xvasprintf distinguish between memory allocation failure and other failures and report better error messages, and the vasprintf replacement properly preserves errno if snprintf fails. portable/socket.h also defines EAI_ADDRFAMILY, which is obsolete but which some software needs to check, to EAI_FAMILY if it's not defined so that the check can be done unconditionally. You can get the latest version from the rra-c-util distribution page.

Jan Wagner: Upgrade RAM of your QNAP TS-459 Pro+ to 2GB

After running a QNAP TS-459 Pro+ for the last 3 or 4 years at home, my monitoring was alerting me about memory warnings cause I upgraded my SqueezeBox Server to the latest nightly version. So I looked into how to upgrade the shipped Adata SU3S1333B1G9-B.

It seems that the KVR1333D3S8S9/2G should work, so I ordered one. After plugin it in, it revealed that the module wasn't working while it worked for others. After digging around, it seems essentially that the modul has a 8-chip design. Indeed, my modul just has only 8 memory chips, but the design is a 16 chip. So I thought it would be a nice try to order the one from amazon that worked for others. And like expected it's not the same module but has the same Kingston Part Number.

As you can see, the 16 chip design module has printed '9905428-189.A00lf' on and the 8 chip design '9931712-009.A00G'. It's something like in the Wireless LAN USB dongle business where they sell totally different hardware with the same Part Number but different Revisions.
I also ordered a Samsung M471B5773DH0-CH9 cause that's also a 8 chip design.

To make it short, both 8 chips design modules worked like a charm, the M471B5773DH0-CH9 and the KVR1333D3S8S9/2G (9931712-009.A00G). - Please avoid the Adolf one from Kingston! ;)

Tanguy Ortolo: Using Wine with sound under Debian testing (Jessie)

If you are using Wine under Debian testing with PulseAudio, you probably noticed that you cannot get sound playback any more. This is because: Loudspeaker icon
  1. Wine uses ALSA, which uses a plugin to play through PulseAudio;
  2. Wine being in 32 bits, all that has to be installed in i386 versions;
  3. recent versions of libasound2-plugins depend on libavcodec54 which depends on libopus0 which is not multiarch-capable and thus cannot be installed in both i386 and amd64 versions;
  4. libopus0:amd64 cannot be reasonably removed to install only libopus0:i386 because many multimedia software depend on it (in other words: try that and you will end removing VLC and everything similar too).
No need to despair though, as there are several ways to work around that problem until the maintainer of libasound2-plugins has converted it to multiarch.Use ALSA directly Since the problem is that Wine tries to use the ALSA PulseAudio plugin which is not available in 32 bits, the most direct solution is to configure it not to use it. Run winecfg, go to the audio tab and manually select your audio devices, which will then be used directly with ALSA without trying to use the PulseAudio plugin.
Screenshot of winecfg

Wine configuration

Downgrade ALSA plugins Since the problem is caused by a dependency chain that only exists with the testing (Jessie) version of the libasound2-plugins package, another solution is to downgrade it to a previous version. To do that, make sure you have enabled the Debian repositories for both the stable (Wheezy) and testing (Jessie) in /etc/apt/sources.list: deb http://ftp.fr.debian.org/debian/ jessie main deb http://security.debian.org/ jessie/updates main contrib non-free deb http://ftp.fr.debian.org/debian/ wheezy main deb http://security.debian.org/ wheezy/updates main contrib non-free Then, forcefully install the stable version of libasound2-plugins for both i386 and amd64: # apt-get install libasound2-plugins:i386/stable \ libasound2-plugins:amd64/stable

Russ Allbery: Review: Water Logic

Review: Water Logic, by Laurie J. Marks
Series: Elemental Logic #3
Publisher: Small Beer Press
Copyright: 2007
ISBN: 1-931520-23-2
Format: Trade paperback
Pages: 332
Water Logic is the third book in the Elemental Logic series, starting with Fire Logic. As with Earth Logic, it's best to read all three books in close temporal proximity, since Water Logic offers little recap of what happened in the previous books and relies on a large cast of characters who are not reintroduced. It's also hard to review without spoilers for the previous books. Earth Logic ended with a monumental shift in Shaftal politics, and half of Water Logic is deeply concerned with the implications of that shift and where Shaftal should go from here. Karis and Zanja are, of course, deeply involved, but much of the political story is told from the perspective of the character introduced in Earth Logic, and from the perspective of another earth blood, Meriseth. Water bloods haven't been seen much so far in the series. Water magic is about repeated patterns and the malleability of time, and the plot of Water Logic eventually entangles Zanja in events far in the past of Shaftal. This proceeds in parallel with more of Marks's excellent analysis of the meaning of war and peace, diplomacy, cooperation, multiculturalism, adaptation, and empathy. The two sides of the book do to some extent reinforce each other, but the connections are tricky and less obvious. Parts of this book are excellent. Wars are complicated and powerful, and don't end easily. The mutual incomprehension and mutual (if intermittant) struggle for understanding between the natives of Shaftal and the Sainnites is beautifully presented. I particularly loved Mariseth's approach throughout the book. Earth bloods are perhaps Marks's best invention, and seeing another (besides Karis) at work, with the same stubborn patience but with different tactics and different levels of power, was a delight. I feel like reading, and thinking about, Seth's decisions makes me a better person. As with the previous books, though, parts of Water Logic are a bit boring, or at least don't seem to coherently move in a conclusive direction. Zanja has long journeys across the landscape as well as several adventures after she's grabbed by water logic that seem only distantly connected to the rest of the story. Marks does pull this mostly together in the end, and I could detect other thematic linkages while mulling the book over after finishing it, but the book feels a bit disjointed while reading it. And there are some elements, such as the cowdogs, that are neat bits of world-building but that seem tossed in just because they're neat and don't feel strongly connected to the plot. The other complaint I have, which would probably have been lessened by reading the books closer together, is that the cast is a bit too large. All of Karis's extended family are, of course, still around, which I found more confusing than helpful. Named and important characters keep popping in and then disappearing, with no introduction and no help for the reader who doesn't remember the exact details of their roles from previous books. It's a bit frustrating, and it makes the book feel a bit cluttered, although it does a great job of showing the dynamics of a large and comfortable family. (Marks shows the dynamics of family webs with multiple adults better than any other fantasy author I know.) Karis is a bit more sidelined in this book, casting her in the role of force of nature, and I think that works well. It took me a bit to warm to Zanja again, but by the end of the book I was greatly enjoying her sections. But the star, for me, is Seth. Even though some of her segments should have been the boring parts of the book, since they were mostly concerned with quitodian issues, they were the parts I wanted to read about. I was very touched by the ending, even if I think a bit too much authorial hand-waving was required. There is material left for a sequel at the end of Water Logic, including a villain who has yet to fully appear, but it's currently not clear whether Air Logic will ever materialize. But, as with Earth Logic, Water Logic provides a satisfying ending and leaves the world in a stable enough place that I didn't feel cheated out of the end of the story. I think Fire Logic remains the strongest book of this series, but Water Logic is very much worth reading if you've read the previous books. Unfortunately, the books apparently didn't sell well, so this book is from a small press instead of Tor. You may have to order it on-line instead of finding it a local bookstore. But the whole series is very much worth reading. It's a refreshingly original take on fantasy and is much more thoughtful about human relationships and politics than most fantasy works. Rating: 7 out of 10

Russ Allbery: Small random haul

Paul Lockhart A Mathematician's Lament (non-fiction)
Alastair Reynolds Blue Remembered Earth (sff)
Donna Tartt The Goldfinch (mainstream)
Tor.com (ed.) Some of the Best from Tor.com 2013 (sff) Not very much in this set, but I wanted to post it before I forgot about it. The Reynolds was the only book I picked up on vacation this year, since I'm being good about not buying too many new books until I get back on the reading bandwagon. That said, I did just place another order since several new books came out that I want to have right now, most notably Nicola Griffith's Hild.

Russ Allbery: C TAP Harness 2.3

This release pushes out some improvements to my TAP library and test harness that I found time to do a while back. I have some other plans, but not much time, so I'm not sure when I'll get to them. Now included in the C TAP library is a test_cleanup_register function that registers a cleanup function called during exit from the test. This function will be passed a boolean argument indicating whether the test succeeded or failed. It was already possible to do this with simple atexit, but now callers can decide whether to delete possibly-interesting trace files based on whether the test was successful. As part of this change, I also refactored and improved everything that happens during test exit, and in the process fixed a bug where lazy plans and test summaries were still displayed even when a test aborted with bail. This release also adds the gcc warn_unused_result attribute to the various TAP library functions (mostly the malloc variations that call bail on failure) where the return value really shouldn't be ignored. You can get the latest release from the C TAP Harness distribution page.

Benjamin Drung: Wanted: Most secure unencrypted email solution

Dear lazy web, Thanks to the global surveillance disclosures, I am searching for a secure email solution. Using end-to-end encryption seems to be the only secure solution to keep the email content private, but it does not protect your email header. End-to-end encryption has the big drawback that the communication partner has to use it, which is rarely the case. I want to communicate as secure as possible even with people that do not use end-to-end encryption. What is the most secure unencrypted email solution? Should I rent a (virtual) server in my country (Germany) and run my own email server on it? Do you know any reliable, inexpensive server host for such use case?

13 November 2013

Petter Reinholdtsen: Lets make a wireless community network in Oslo!

Today NUUG and Hackeriet announced our plans to join forces and create a wireless community network in Oslo. The workshop to help people get started will take place Thursday 2013-11-28, but we already are collecting the geolocation of people joining forces to make this happen. We have 9 locations plotted on the map, but we will need more before we have a connected mesh spread across Oslo. If this sound interesting to you, please join us at the workshop. If you are too impatient to wait 15 days, please join us on the IRC channel #nuug on irc.freenode.net right away. :)

Hideki Yamane: latest freetype package (2.5.0.1)


During MiniDebConf in Taiwan, I've heard about freetype package is not updated for a while. I'm not sure why freetype maintainers haven't update it but anyway I've made an updated package (freetype 2.5.0.1 - it has a feature "new Adobe CFF rasterizer", see Google's blog post and Adobe's).

Changes:
freetype (2.5.0.1-0.1) UNRELEASED; urgency=low
.
* Non-maintainer upload.
* Now make it "multiple upstream source" style instead of "tar-in-tar".
New style makes it easier to check source code with search engine like
sources.debian.net.
* use "3.0 (quilt)" in debian/source/format
- merge debian/patches-freetype and patches-ft2demos to debian/patches
- drop patches since merged to upstream
+ savannah-bug-37907.patch
+ savannah-bug-37906.patch
+ savannah-bug-37905.patch
+ savannah-bug-35847.patch
+ savannah-bug-35833.patch
+ ft2demos-2.1.7-no-rpath.patch (cannot be applied)
- refresh patches
+ fix compiler warning in compiler_hardening_fixes.patch
* simplify debian/rules and separate some thing to debian/* files
- don't install GPLv2.TXT (not GPL.TXT)
* debian/control
- add "Build-Depends: libpng12-dev libpng-dev"
* update debian/libfreetype6.symbols

You can get its source package by
$ dget http://www.mithril-linux.org/~henrich/debian/package/temp/freetype_2.5.0.1-0.1.dsc

and can get .deb package
$ wget http://www.mithril-linux.org/~henrich/debian/package/temp/libfreetype6_2.5.0.1-0.1_amd64.deb

I've tested it with sid in VirtualBox image and get no weird thing. Could you test it? After that, I'll post to BTS.

Andrea Veri: Configuring DNSSEC on your personal domain

Today I ll be working out how to properly configure DNSSEC on a BIND9 installation, I ll also make sure to give you all the needed instructions to properly verify if a specific domain is being correctly covered by DNSSEC itself. In addition to that a few more details will be provided about adding the relevant SSHFP s entries on your DNS zone files to be able to automatically verify the authenticity of your domain when connecting to it with SSH avoiding any possible MITM attack. First of all, let s create the Zone Signing Key (ZSK) which is the key that will be responsible to sign any other record on the zone file which is not a DNSKEY record itself:
dnssec-keygen -a RSASHA1 -b 1024 -n ZONE gnome.org


Note: the dnssec-keygen binary file should be part of bind97 (RHEL 5) or bind (RHEL6) package according to yum whatprovides: RHEL 5:
32:bind97-9.7.0-17.P2.el5_9.2.x86_64 : The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) server
Repo : rhel-x86_64-server-5
Matched from:
Filename : /usr/sbin/dnssec-keygen


RHEL 6:
32:bind-9.8.2-0.17.rc1.el6.3.x86_64 : The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) server
Repo : rhel-x86_64-server-6
Matched from:
Filename : /usr/sbin/dnssec-keygen


Then, create the Key Signing Key (KSK), which will be used to sign all the DNSKEY records:
dnssec-keygen -a RSASHA1 -b 2048 -n ZONE -f KSK gnome.org


Creating the above keys can take several minutes, when done copy the public keys to the zone file this way:
cat Kgnome.org*.key >> gnome.org


When done you can clean out the useless bits from the zone file and just leave the DNSKEY records (which are not commented out as you will notice) An additional and cleaner way of accomplishing the above is to use the INCLUDE rule on the zone file itself as follows:
$INCLUDE /srv/dnssec-keys/Kgnome.org+005+12345.key
$INCLUDE /srv/dnssec-keys/Kgnome.org+005+67890.key


Choosing which method to use is really up to you. Once that is done you can go ahead and sign the zone file. As of myself I m making use of the do-domain script taken from the Fedora Infrastructure Team s repositories. If you are going to use it yourself, make sure to adjust all the relevant variables to match your setup, especially keyspath, region_zones, template_zone, signed_zones and AREA. The do-domain script also checks your zone file through named-checkzone before signing it.
/me while editing the do-domains script with the preview of gnome-code-assistance!

/me while editing the do-domains script with the preview of gnome-code-assistance!

If instead you don t want to use the script above, you can sign the zone file manually in the following way:
dnssec-signzone -K /path/to/your/dnssec/keys -e +3024000 -N INCREMENT gnome.org


By default, the above command will append .signed to the file name, you can modify that behaviour by appending the -f flag to the dnssec-signzone call. The -N INCREMENT will increment the serial number automatically making use of the RFC 1982 arithmetics while the -e flag will extend the zone signature end date from the default 30 days to 35. (this way we can safely run a monthly cron job that will sign the zone file automatically) You can make use of the following script to achieve the above:
#!/bin/sh
SIGNZONE="/usr/sbin/dnssec-signzone"
DNSSEC_KEYS="/srv/dnssec-keys"
NAMEDCHROOT="/var/named/chroot"
ZONEFILES="gnome.org"
cd $NAMEDCHROOT
for ZONE in $ZONEFILES; do
$SIGNZONE -K $DNSSEC_KEYS -e +3024000 -f $ZONE.signed -N INCREMENT $ZONE
done
/sbin/service named reload


Once the zone file has been signed just make sure to include it on named.conf and restart named:
zone "gnome.org"  
file "gnome.org.signed";
 ;


When you re done with that we should be moving ahead adding a DS record for our domain at our domain registrar. My example is taken from the known gandi.net registrar.
gandi

Gandi s DNSSEC interface

Select KSK (257) and (RSA/SHA-1) on the dropdown list and paste your public key on the box. You will find the public key you need on one of the Kgnome.org*.key files, you should look for the DNSKEY 257 entry as dig DNSKEY gnome.org shows:
;; ANSWER SECTION:
gnome.org. 888 IN DNSKEY 257 3 5 AwEAAbRD7AymDFuKc2iXta7HXZMleMkUMwjOZTsn4f75ZUp0of8TJdlU DtFtqifEBnFcGJU5r+ZVvkBKQ0qDTTjayL54Nz56XGGoIBj6XxbG8Es+ VbZCg0RsetDk5EsxLst0egrvOXga27jbsJ+7Me3D5Xp1bkBnQMrXEXQ9 C43QfO2KUWJVljo1Bii3fTfnHSLRUsbRn8Puz+orK71qxs3G9mgGR6rm n91brkpfmHKr3S9Rbxq8iDRWDPiCaWkI7qfASdFk4TLV0gSVlA3OxyW9 TCkPZStZ5r/WRW2jhUY/kjHERQd4qX5dHAuYrjJSV99P6FfCFXoJ3ty5 s3fl1RZaTo8=


Once that is done you should have a fully covered DNSSEC domain, you can verify that this way:
dig . DNSKEY   grep -Ev '^($ ;)' > root.keys
dig +sigchase +trusted-key=./root.keys gnome.org. A   cat -n


The result:
105 ;; WE HAVE MATERIAL, WE NOW DO VALIDATION
106 ;; VERIFYING DS RRset for org. with DNSKEY:59085: success
107 ;; OK We found DNSKEY (or more) to validate the RRset
108 ;; Ok, find a Trusted Key in the DNSKEY RRset: 19036
109 ;; VERIFYING DNSKEY RRset for . with DNSKEY:19036: success
110
111 ;; Ok this DNSKEY is a Trusted Key, DNSSEC validation is ok: SUCCESS

Bonus content: Adding SSHFP entries for your domain and verifying them You can retrieve the SSHFP entries for a specific host with the following command:
ssh-keygen -r $(hostname --fqdn) -f /etc/ssh/ssh_host_rsa_key.pub


When retrieved just add the SSHFP entry on the zone file for your domain and verify it:
ssh -oVerifyHostKeyDNS=yes -v subdomain.gnome.org


Or directly add the above parameter into your /etc/ssh/ssh_config file this way:
VerifyHostKeyDNS=yes


And run ssh -v subdomain.gnome.org , the result you should receive:
debug1: Server host key: RSA 00:39:fd:1a:a4:2c:6b:28:b8:2e:95:31:c2:90:72:03
debug1: found 1 secure fingerprints in DNS
debug1: matching host key fingerprint found in DNS
debug1: ssh_rsa_verify: signature correct

That s it! Enjoy!

Julien Danjou: OpenStack Design Summit Icehouse, from a Ceilometer point of view

Last week was the OpenStack Design Summit Icehouse in Hong-Kong where we, OpenStack developers, discussed and designed the new OpenStack release (Icehouse) that is coming up. The week has been wonderful. It was my second OpenStack design summit, and I loved it. Bumping into various people I've never met so far and worked with online was a real pleasure. As it was to meet again with fellow OpenStack developers! The event organisation was great, as were the parties. :-) On the last day, I had the chance to present a talk with Eoghan Glynn and Nick Barcet how we built the auto-scaling feature in Heat, implementing the "alarming" feature needed in Ceilometer.
The slides and video of the talk is online on my talks page. Design sessions This time, Ceilometer design sessions were spread on 3 days. Everything we talked about has its Etherpad instance. The discussions were interesting, and the amount of feedback gathered is big and is going to be very useful. There's a lot of people and companies using Ceilometer now, and the project is getting more and more traction in general. There's a lot of different way to use it and to bend it to one's needs. Considering the amount of features and options that is provided, building functionality with a genericized approach it making Ceilometer useful for a lot of different and interesting use-cases. Icehouse roadmap The list of blueprints targeting Icehouse is available, but not yet complete. I expect people to start filling this list in the next days.If you want to propose blueprints, you're free to do so and inform us about it so we can validate it. The same applies if you wish to implement one of them! Thereafter, I try to guess what the roadmap will look like in the upcoming weeks for Ceilometer based on the discussion we had last week during the summit. Events management A lot of work is going to be put into event management. Ceilometer plans to store notifications sent using oslo.messaging by OpenStack projects. Some work already got merge for Havana, but the API part and future improvements and ideas will continue to flow into the Icehouse release. Agents and group management A lot has been discussed around the polling agents and around the alarm evaluator agent. The current state of the ceilometer-central-agent disallows any kind of high-availability and load-balancing, as the polling task are kept and scheduled on only one node. The high-availability part is already covered by a custom mechanism built into ceilometer-alarm-evaluator, but it came clear to us that a more generic approach is needed. A lot of other projects needs this kind of functionality, and a pattern have been pointed out. A blueprint about group membership has been discussed in an Oslo session, and will end into a new Python library written to solve this in Ceilometer and in other projects. TaskFlow will also probably be leveraged to solve the task distribution issue. Documentation Since a few weeks, Ceilometer auto-generates its API reference documentation using sphinxcontrib-docbookrestapi that parses our API code that uses WSME. We also want to start writing a user guide, and we'll do that inside our own repository. That way, I hope that we will be the first project in OpenStack to require documentation to be incorporated into every patch that's being sent to Ceilometer. This is the best way to assure that nothing can be changed nor added without being accompanied with a documentation update. Tempest testing Testing of Ceilometer already has been a subject during the previous design summit about testing. We already put a large effort on Tempest testing in this last cycle, but we encountered a lot of small issues that we had to tackle to achieve something. Some Ceilometer basic tests are already on their way into Tempest, so this is something that is going to be achieved very soon. Ultimately, I would also want Ceilometer moving towards providing its own set of Tempest tests as part of the code base. That way, it'd be as easy for core reviewers to refuse a patch if it doesn't provide functional tests as it is to refuse it if it doesn't provide unit tests. As we'll do for the documentation. API improvements Once again, a few API improvements will probably be implemented, like aggregation or the ability to specify multiple queries with OR and AND operators. Roll-up, archiving of data There seems to be interest in archiving and rolling-up the data stored by Ceilometer, so work in this area is to be expected. Supporting multiple data storage driver in parallel seems to be something that needs to be done for this and other aspects of Ceilometer feature set. Alarming The alarming feature set is already big, and the work that has been accomplished pretty amazing. A few improvements will be made, as retrieving better metrics and building better statistics (exclusion of low quality data points).

Joachim Breitner: Constructing a list in a Monad

In Haskell, lists are ubiquitous. In real-world Haskell, monads are ubiquitous. So it should be an easy task to fill a list with values obtained in a monad, i.e. a list of n random numbers (in the Rand monad), or getting some input from the user, and storing it in a list, until the user chooses to finish the input. The task For now, assume a function getInput :: IO Int; we want to run it 10000 and then have the list of the values returned. Sounds simple and straight forward, but it is actually really hard to get the run-time behaviour that we naively and optimistically expect. The expectation In an imperative setting, we would have a simple counting loop. In the loop, we run getInput, allocate a new cell for the linked list, and append it to the list. Clearly, this
  • consumes no stack space and
  • at the end of the loop, the list is already fully evaluated in memory, ready to be used.
Can we achieve that with Haskell? Let s look at a few alternatives (complete code available)
Attempt 1: The accumulator I ll start with the probably worst attempt. Unfortunately, from what I have seen from correcting Haskell exams, this is what beginners would write, especially if they have the above imperative algorithm in mind, and know about the convert loops to recursion with accumulators approach to solving Haskell problems:
accumAppend :: Int -> IO [Int]
accumAppend n = go n []
  where
    go 0 l = return l
    go n l = do  x <- getInput; go (n-1) (l++[x]) 
To check the space usage of this, I pass -Kn to the GHC runtime and see what limit is just enough to let this program calculate accumAppend 10000 and fully evaluate the resulting list. It turns out that we need 328336 bytes of stack space. So what about the second requirement; that the list is fully evaluated? Experienced Haskellers see it immediatelly: The accumulator is not used in the loop, so each iteration adds a thunk around the previous value, that would add the next entry to the end. Only when the list is actually used, these are run, each traversing the whole list, causing quadratic cost. We can verify this using ghc-vis:
Clearly (and not surprisingly) this is not the best solution. Attempt 2: The accumulator (forced) Lets try to fix the second issue, by making sure that the list is always fully evaluated. We import Control.DeepSeq and write
accumAppendSeq :: Int -> IO [Int]
accumAppendSeq n = go n []
  where
    go 0 l = return l
    go n l = do  x <- getInput ; go (n-1) $!! (l++[x]) 
As the accumulator gets fully evaluated before being passed to the next invocation of go, the result will not contain thunks. But note that this has also fixed the stack consumption: The code now runs the smallest setting for -K, 8 bytes. This works as both go and deepseq are tail-recursive. But this is still not the solution we are looking for, as the quadradic cost caused by using ++ is still there. Attempt 3: The accumulator (reversed) Since we know that l++[x] is expensive, but x:l is cheap, we can simply use this to update the accumulator. This has the slightly annoying consequence that the entries of the list are in the reverse order, but we can fix that in the base case:
accumReverse :: Int -> IO [Int]
accumReverse n = go n []
  where
    go 0 l = return (reverse l)
    go n l = do  x <- getInput ; go (n-1) (x:l) 
And indeed, we get noticably faster code that still runs in 8 bytes of stack. Unfortunately, we still don t construct the final list directly. Attempt 4: Naive recursion Maybe we can do without an accumulator. The most naive such code would be
listRecurse :: Int -> IO [Int]
listRecurse n = go n
  where
    go 0 = return []
    go n = do  x <- getInput; r <- go (n-1); return (x:r) 
and I d expect that most experienced Haskellers would write that code (if they are asked not to use a library function). And indeed, this code does create the final list directly. But it requires a large stack or 164616 bytes. The reason is that this is no longer tail recursive: After calling go again we need to take the result and prepend x Attempt 5: library functions Maybe we should simply not worry about the implementation, and use library functions? Clearly, the authors of such libraries have found the best solution. So how does
listReplicateM :: Int -> IO [Int]
listReplicateM n = Control.Monad.replicateM n getInput
fare? Unfortunately, not better than the naive recursion. In fact, the stack space requirement is the same 164616 bytes. The same holds when using special libraries for generating and consuming list, e.g. the Streams module from the vector package:
listStreams :: Int -> IO [Int]
listStreams n = MStream.toList $ MStream.replicateM n getInput
Attempt 6: Difference lists It is time to dig deeper into our box of tricks. What if we have lists with constant time Snoc (a.k.a. appending a new element)? Then Attempt 3 would not require reversing the list. Such lists are provided by difference lists; there are libraries for that, but we can simply implement them using lambdas:
accumDList :: Int -> IO [Int]
accumDList n = go n id
  where
    go 0 l = return (l [])
    go n l = do  x <- getInput; go (n-1) (l . (x:)) 
Indeed, no stack is required (8 bytes are enough). But we are cheating here: We are still not constructing the final list, but rather we combine functions that append elements to lists. So when accumDList returns, what we have in memory, is a thunk and sequence of partial function applications in the wrong order, and evaluating the thunk does basically the same thing as reverse in Attempt 3. It might be a bit faster, is still not satisfying enough:
Attempt 7: Unsafe functions Even deepter in the box of tricks, somewhere in the grit and dust where one usually should not reach, there is a function that can help us out here: unsafeInterleaveIO. This allow us to modify the naive recursion in a way that first creates the Cons-cell, and then continues the loop:
listUnsafeInterleave :: Int -> IO [Int]
listUnsafeInterleave n = do  l <- go n; return $!! l 
  where
    go 0 = return []
    go n = do x <- getInput
              r <- unsafeInterleaveIO (go (n-1))
              return (x:r)
The stack consumption is 8 bytes. It is worth noting that the all to deepseq (in $!!) will actually drive the evaluation of go. Also, it guarantees that the unsafe effects of unsafeInterleaveIO are confined to the execution of listUnsafeInterleave, i.e. are actually safe. Run time statistics I ran criterion over the functions (generating lists of length 1000), and found these results:
  • accumAppend: 6.5 ms
  • accumAppendSeq: 8.2 ms
  • accumReverse: 14.0 us
  • listRecurse: 8.0 us (same as listReplicateM and listStreams)
  • accumDList: 12.0 us
  • listUnsafeInterleave: 174.0 us
Conclusion There are many ways to write a list-constructing list in Haskell, none are perfect they either fill the heap, or do not construct the list directly (usually requiring a second pass through it), or rely on IO-specific unsafe functions. The naive recursion performs the best, but may cause a stack overflow (note, though that from GHC 7.8, the stack will be unlimited). The next best option seems to be the difference lists
I m still wondering: What would be required from Haskell, GHC or the monads in question to have a fully satisfactory solution here, i.e. one that is as fast as the naive recursion, as stack efficient as the difference list solution, and allocates no thunks, only list cells?

Raphael Geissert: A bashism a week: heredocs

One great feature of POSIX shells is the so-called heredoc. They are even available in languages such as Perl, PHP, and Ruby.

So where is the bashism?

It's in the implementation. What odd thing do you see below?


$ strace -fqe open bash -c 'cat <<EOF
foo
EOF' 2>&1 grep -v /lib
open("/etc/ld.so.cache", O_RDONLY O_CLOEXEC) = 3
open("/dev/tty", O_RDWR O_NONBLOCK O_LARGEFILE) = 3
open("/proc/meminfo", O_RDONLY O_CLOEXEC) = 3
[pid 6696] open("/tmp/sh-thd-1384296303", O_WRONLY O_CREAT O_EXCL O_TRUNC O_LARGEFILE, 0600) = 3
[pid 6696] open("/tmp/sh-thd-1384296303", O_RDONLY O_LARGEFILE) = 4
[pid 6696] open("/etc/ld.so.cache", O_RDONLY O_CLOEXEC) = 3
foo
--- SIGCHLD (Child exited) @ 0 (0) ---


Yes, it uses temporary files!

So do ksh, pdksh, mksh, posh and possible other shells. Busybox's sh and dash do not use temporary files, though:


$ strace -fqe open dash -c 'cat <<EOF
foo
EOF' 2>&1 grep -v /lib
open("/etc/ld.so.cache", O_RDONLY O_CLOEXEC) = 3
[pid 6767] open("/etc/ld.so.cache", O_RDONLY O_CLOEXEC) = 3
foo
--- SIGCHLD (Child exited) @ 0 (0) ---


Next time you want data to never hit a hard disk, beware that heredocuments and herestrings are best avoided.

12 November 2013

Russell Coker: Bad Advertising of Protoplast

Carpal Tunnel Syndrome In early 2010 I wrote about Carpal Tunnel Syndrome, I gave a picture of the wrist brace and a description of the process of creating it [1]. A few months later I wrote a follow-up about how the wrist brace had helped me, at the time I was anticipating wearing it at night for the rest of my life [2]. But my wrist has continued to improve. Nowadays I never wear the wrist brace and hardly even think of it. I am a little more careful about posture than I was before, but mostly it has no impact on my life. I think this counts as a full recovery. At the time I was mildly interested in buying some thermo-plastic of that type to make things, but the only source I found was Jaycar which sold 100 grams for $14.95, Jaycar prices have now dropped to $11.50 for 100 grams or $89.50 for a kilo but it s still expensive [3]. Protoplast When looking at the sites that link to my blog I saw a site advertising Protoplast which is a type of thermo-plastic that can be used for making things [4]. Protoplast have more reasonable prices, E30 ($AU42.75) for a kilo and their web site offers better prices for anyone who purchases 10kg or more (good for hackerspaces etc). As they post no further than Belgium they aren t an option for me but they do seem to make a good offer, better than Jaycar offers in Australia. Protoplast is probably a good product, but I think that their advert is misleading. While it is probably possible to make a wrist-brace similar to mine with Protoplast it s a fact that my wrist brace was not made with it. My wrist brace started out as a flat sheet of plastic which could be formed to the final product without being melted. Converting a packet of plastic granules (as sold by Protoplast or Jaycar) to a sheet to even start work on such a wrist brace would take some work. To make a sheet of plastic out of beads sold by Jaycar or Protoplast you would ideally completely melt the plastic, if you just softened the plastic then it wouldn t be as strong as using a pre-made sheet. During the time that I wore the wrist brace I probably repaired it more than 30 times, this wasn t particularly difficult to do, I poured boiling water over it to soften the part that cracked until it became tacky and then pushed it together again. But the result was significantly weaker than the original due to the difficulty in welding the broken sections together. I ended up cutting some strips from less important parts of the wrist brace (the part nearest to my elbow) to reinforce the weakest part which was between my thumb and fore-finger. That section ended up being about three times thicker than it was originally while also not being as strong as it was originally. I also had difficulty in making it flat so it wasn t nearly as comfortable as the original version. It seems rather misleading to include the picture of my wrist brace on a site advertising plastic which wasn t used to make it and which probably couldn t be used to make something that looks as good with the same ratio of strength to mass. But with a suitable disclaimer indicating that the user probably can t get the same result it would be OK to give it as an example of what could be done. I can imagine someone using a product like Protoplast to make a wrist brace that can hold a mobile phone, that can be worn with a watch, or has other features that aren t offered by medical staff. License Issues The license for my blog doesn t permit people to just copy pictures, it s a Creative Commons Attribution-Noncommercial-Share Alike based license [5]. I am interested in supporting companies that make interesting products and anything that can help people with medical issues is also of interest. So I wouldn t rule out the possibility of a free license for a picture from my blog to be used in the way that they used it (with a link back to the original blog post). But I would want a description that informs readers that it s not an item made with their product, merely something similar that can be used for inspiration.

11 November 2013

Simon Josefsson: Using Replicant on Samsung Galaxy S III

For the last half-year I have used CyanogenMod on an Nexus 4 as my main phone. Recently the touch functionality stopped working on parts of the display, and the glass on the back has started to crack. It seems modern phones are not built to last. For comparison, before the N4 I used a Nokia N900 for around 3 years without any hardware damages (in my drawer now, still working). A few weeks ago I started looking for a replacement. My experience with CyanogenMod had been good, but the number of proprietary blobs on the N4 concerned me. Finding something better wasn t easy though, so I m documenting my experience here. My requirements were, briefly, that I wanted a phone that I could buy locally that had a free software community around it that produced a stable environment. I have modest requirements for things I wouldn t give up on: telephony, data connection (3G), email (IMAP+SMTP), chat (XMPP), and a web browser. I like the philosophy and openness around the Firefox OS but the more I have read about it, it seems unlikely that it would deliver what I need today. In particular none of the devices capable of running Firefox OS appealed to me, and the state of email reading seemed unclear. I m sure I ll revisit Firefox OS as an alternative for me in the future.

As I had been happy with CyanogenMod, but concerned about its freeness, it felt natural to move on and test the more free software friendly project Replicant. Replicant only supports a small number of devices. After talking with people in the #replicant IRC channel, it seemed the Samsung S3 would be a decent choice for me. The Samsung S2 would have worked as well, but it cost almost as much as the S3 where I looked. Despite the large number of Samsung S3 devices out there, it seems the prices even for used devices are high (around 2500 SEK in Sweden, ~380 USD). I ended up buying a brand new one for 3200 SEK (~500 USD) which felt expensive, especially after recalling the recent $199 sale for Nexus 4. Noticing that brand new Nexus 4 devices are still over 3000 SEK in Sweden comforted me a bit. I would have preferred a more robust phone, like the CAT B15, but the state of free software OSes on them seem unclear and I wanted something stable. So, enough about the background, let s get started. Building and installing Replicant on the device was straight forward. I followed the Replicant Samsung S3 Build instructions to build my own images. The only issue I had was that I had not set JAVA_HOME and the defaults were bad; make sure to set JAVA_HOME before building. I built everything on my Lenovo X201 running Debian Wheezy, with OpenJDK 6 as the Java implementation. Installing the newly built firmware was easy, I just followed the installation process documentation. I made sure to take a clockworkmod backup to an external SD card before wiping the old system. To get a really clean new device, I also re-formated /sdcard inside clockworkmod; I noticed there were some traces left of the old system there. I spent about one week testing various configurations before settling on something I could use daily. A fair amount of time was spent looking into backup and restore options for Android devices. My idea was that I would take a backup of the apps I ran on the N4 and transfer them to the S3. The Android Debug Bridge (adb) has a backup/restore command, however it (intentionally) ignores apps marked as allowBackup=false which a number of apps has. It doesn t seem possible to override that settings so much for the freedom to backup your own device. I then discovered oandbackup. It can backup your entire system, saving each app (together with associated data) into a separate directory, for simple review and inspection before restore. You can do batch backups and batch restore. I couldn t get it to automatically restore things, though, which would be neat for really automated re-installations (there is an open issue about this feature). After noticing that some apps did not like being moved from the N4 (running Android 4.2) to the S3 (running 4.0), I ended up installing most apps from scratch on a freshly installed Replicant. I use oandbackup to the external SD card so that I can quickly restore my phone. For backup/restore of SMS/MMS and Call Log, I use SMS Backup+ against my own IMAP server. Camera pictures are synced manually using adb when I am connected to my laptop. There is a number of apps that deserve to be mentioned because they are what I use on a daily basis. All of them come via the free software market F-Droid. For email (IMAP/SMTP), I use K-9 Mail which is feature rich but still easy to use. For chat, I use Xabber. I use NewsBlur s free software app to read RSS flows. For two-factor authentication, I use Google Authenticator. I haven t evaluated different PDF viewers, but the first one I tried (APV PDF Viewer) has worked fine so far. Handling a a synchronized address book and calendar deserve its own blog post because it is a challenging topic, but briefly, I m currently using a combination of aCal and DAVdroid. Finally, since Replicant is still work in progress, some words about stability and notes on what doesn t work. This is probably the most interesting part if you are considering running Replicant on an S3 yourself. Overall system stability is flawless, I hadn t had any crash or problem with the fundamental functionality (telephony, 3G, Camera). People have said graphics feels a bit laggy, but I cannot compare with the stock ROM and it doesn t get in the way of daily use. First some notes about non-free aspects:
  • Bluetooth doesn t work by default. After installing /system/vendor/firmware/bcm4334.hcd (MD5 b6207104da0ca4a0b1da66448af7ed4c) pairing and testing with a Bluetooth headset worked fine.
  • Front camera doesn t work by default. After installing /system/vendor/firmware/fimc_is_fw.bin (MD5 52eeaf0889bc9206860075cd9b7f80b9and) and /system/vendor/firmware/setfile.bin (MD5 0e6fdeb378fb154c39fd508ae28eaf2a) it works. The extensions are *.bin but I don t believe this code is executed on the main CPU.
  • GPS doesn t work by default. After installing /system/bin/gpsd (MD5 6757ed2e2a283259e67c62e6b2b9cfef), /system/lib/libsecril-client.so (MD5 a836df0f947d2aa2ef20dcb213317517), /system/lib/hw/gps.exynos4.so (MD5 1ea1d67f297dd52d59d40dbad9b02a0a) it works. This is code that runs on the main CPU, and even more alarming, it embeds a copy of OpenSSL and talks to various online servers for A-GPS, and is thus a likely (and probably not too challenging) attack vector for anyone wanting to remotely exploit any phone.
  • Wifi doesn t work, and I haven t gotten this to work. There is a list of non-free S3 firmware on the Replicant wiki however my stock ROM did not ship with those files. I don t believe any of the blobs run on the main CPU.
  • NFC doesn t work, and I haven t gotten it to work. It seems the infrastructure for NFC is missing in Replicant 4.0, it doesn t even expose the NFC hardware permission capability. This is quite unfortunate for me, since I daily work with YubiKey NEO and would have preferred to replace Google Authenticator with the YubiOATH that uses the NEO for OATH secret storage.
Some other observations:
  • Panorama mode in the Camera crashes; see issue about it.
  • There is a number of smaller graphical issues. I believe these are related to the EGL but haven t understood the details. What I ve noticed are the following issues. The task switcher doesn t show mini screenshots of all running apps (the screenshots are just black). ZXing is not able to QR decode images (I m told this is because Replicant uses a RGB color plane instead of the required YUV color plane). Video playback in the gallery is laggy to the point of being unusable. Video playback on Youtube in the default web browser works in full screen (not laggy), but not embedded in the webpage.
  • MTP has been a bit unreliable, my main laptop is able to import photos, but another laptop (also running Debian Wheezy) just stalls when talking to it. This may be a host issue, I have experience similar issues with a Nexus 7 2nd generation device.
I am quite happy with the setup so far, and I will continue to use it as my primary phone. flattr this!

Daniel Pocock: Outreach Program for Women applications

The deadline for Outreach Program for Women applications is very imminent and a range of applications have now appeared on the OPW wiki It is great to see Debian has attracted a diverse range of women who all appear to have coding experience. Code samples have been submitted in Java, C++ and Python among other things and they come from a range of locations around the globe, including Brazil, the UK, Iran and India. Experience counts Looking through the records of some of these applications, it is interesting to see a range of experience and connections in industry and the wider open source family:
  • translator for O'Reilly
  • IBM internship
  • Linux module programming
  • Working alongside one of the Mercurial contributors in a previous role
Funding needed Recent emails from the OPW organisors and DPL have highlighted the need to raise more funding to ensure that Debian can offer OPW internships to the selected applicants. Solving the biggest problem of GSoC 2014 Many of these applicants are students and will be eligible for GSoC 2014. According to the Google FAQ, even students who graduate in 2014 are eligible as long as they are enrolled in a course on the cut-off date 21 April 2014 One of the biggest challenges facing GSoC mentors is the selection of students who are capable of completing good work and have a long term interest in open source. One of the best ways to overcome that challenge is to start forming relationships with potential GSoC students well in advance and get to know them as they make small contributions over an extended period of time. The interest that these candidates have expressed in Debian and OPW suggests that some of them may well be suitable for Debian to help them get onto this track for the next GSoC. Not only will this make the GSoC 2014 selection process easier but it may help us to select more GSoC candidates with a long term outlook. Women in science, engineering and the wider business world More news items have appeared recently about women in science and engineering and other leadership roles:

In the early 1950s, Morgan was the only female analyst among 900 rocket scientists at North American Aviation. She was also one of the few without a college degree.

"What I saw a thousand times during the downturn was, 'We'd like to give her that opportunity, but we need to go with the sure thing - we can't afford diversity right now,'" - Sallie Krawcheck, former chief executive at Merrill Lynch

Vincent Bernat: Snimpy: SNMP & Python

While quite old fashioned, SNMP is still an ubiquitous protocol supported by most network equipments. It comes handy to expose various metrics, like network interface counters, to be gathered for the purpose of monitoring. It can also be used to retrieve and modify equipments configuration. Variables exposed by SNMP agents (servers) are organized inside a Management Information Base (MIB) which is a hierarchical database1. Each entry is identified by an OID. Querying a specific OID allows a manager (client) to get the value of an associated variable. For example, one common MIB-module is IF-MIB defined in RFC 2863. It contains objects used to manage network interfaces. One of them is ifTable whose rows are representing agent s logical network interfaces. Each row will expose the interface name, characteristics and various associated counters.
ifIndex ifDescr ifPhysAddress ifOperStatus ifOutOctets
1 lo up 545721741
2 eth0 0:18:f3:3:4e:4 up 78875421
3 eth1 0:18:f3:3:4e:5 down 0
ifTable is indexed by its first column ifIndex. If you want to get the operational status of the second interface, you need to query IF-MIB::ifOperStatus.2 which is translated to OID .1.3.6.1.2.1.2.2.1.8.2 using information provided by the MIB definition.

Scripting SNMP An SNMP agent can deliver a lot of interesting information: You can gather those information manually with tools like snmpget and snmpwalk:
$ snmpwalk -v 2c -c public localhost IF-MIB::ifDescr      
IF-MIB::ifDescr.1 = STRING: lo
IF-MIB::ifDescr.2 = STRING: eth0
IF-MIB::ifDescr.3 = STRING: eth1
However, building robust scripts with them is quite challenging. For example, if you wanted to get the descriptions of all active interfaces as well as the total number of octets transmitted, you could do something like that:
#!/bin/sh
set -e
host="$ 1:-localhost "
community="$ 2:-public "
args="-v2c -c $community $host"
for idx in $(snmpwalk -Ov -OQ $args IF-MIB::ifIndex); do
    descr=$(snmpget -Ov -OQ $args IF-MIB::ifDescr.$idx)
    oper=$(snmpget -Ov -OQ $args IF-MIB::ifOperStatus.$idx)
    in=$(snmpget -Ov -OQ $args IF-MIB::ifInOctets.$idx)
    out=$(snmpget -Ov -OQ $args IF-MIB::ifOutOctets.$idx)
    [ x"$descr" != x"lo" ]   continue
    [ x"$oper" = x"up" ]   continue
    echo $descr $in $out
done
Hopefully, SNMP bindings in various languages are pretty common. For example, Net-SNMP ships with a Python binding:
import argparse
import netsnmp
parser = argparse.ArgumentParser()
parser.add_argument("host", default="localhost", nargs="?",
                    help="Agent to retrieve variables from")
parser.add_argument("community", default="public", nargs="?",
                    help="Community to query the agent")
options = parser.parse_args()
args =  
    "Version": 2,
    "DestHost": options.host,
    "Community": options.community
 
for idx in netsnmp.snmpwalk(netsnmp.Varbind("IF-MIB::ifIndex"),
                            **args):
    descr, oper, cin, cout = netsnmp.snmpget(
        netsnmp.Varbind("IF-MIB::ifDescr", idx),
        netsnmp.Varbind("IF-MIB::ifOperStatus", idx),
        netsnmp.Varbind("IF-MIB::ifInOctets", idx),
        netsnmp.Varbind("IF-MIB::ifOutOctets", idx),
        **args)
    assert(descr is not None and
           cin is not None and
           cout is not None) #  
    if descr == "lo":
        continue
    if oper != "1": #  
        continue
    print("     ".format(descr, cin, cout))
This binding is quite primitive and has several drawbacks:
  1. It exports everything as strings. See .
  2. Error handling is just deficient. If you mispell something, like a variable name, you ll get snmp_build: unknown failure on the standard error. No exception. If a variable does not exist, you ll get None instead. See .
This inability to sanely handle failures makes this binding quite dangerous to use in scripts. Imagine making important modifications on the basis of the returned values. If you forget to check against None, your script may cause havoc!

Snimpy Because I didn t find any reliable Python binding for SNMP, I decided to write Snimpy with two goals in mind:
  1. Leverage information contained in MIBs to provide a pythonic interface.
  2. Any error condition should raise an exception.
Here is how the previous script could be written:
#!/usr/bin/env snimpy
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("host", default="localhost", nargs="?",
                    help="Agent to retrieve variables from")
parser.add_argument("community", default="public", nargs="?",
                    help="Community to query the agent")
options = parser.parse_args()
m = M(options.host, options.community, 2)
load("IF-MIB")
for idx in m.ifDescr:
    if m.ifDescr[idx] == "lo":
        continue
    if m.ifOperStatus[idx] != "up":
        continue
    print("     ".format(m.ifDescr[idx],
                            m.ifInOctets[idx],
                            m.ifOutOctets[idx]))
You can also use a list comprehension:
load("IF-MIB")
print("\n".join([ "     ".format(m.ifDescr[idx],
                                    m.ifInOctets[idx],
                                    m.ifOutOctets[idx])
                  for idx in m.ifDescr
                  if m.ifDescr[idx] != "lo"
                  and m.ifOperStatus[idx] == "up" ]))
Here is another simple example to get the routing database from the agent:
load("IP-FORWARD-MIB")
m=M("localhost", "public", 2)
routes = m.ipCidrRouteNextHop
for x in routes:
    net, netmask, tos, src = x
    print(" :>15s / :<15s  via  :<15s  src  :<15s ".format(
        net, netmask, routes[x], src))
IP-FORWARD-MIB::ipCidrRouteNextHop is a more complex table with a compound index. Despite this, querying the table still seems natural. Have a look at Snimpy s documentation for more information. Behind the hood, SNMP requests are handled by PySNMP and MIB parsing is done with libsmi2. Snimpy supports both Python 2, Python 3 and Pypy.

  1. A MIB is defined using a subset of ASN.1 called SMI. However, it is not uncommon to refer to the definition as a MIB too.
  2. Unfortunately, there is currently no robust SMI parser written in pure Python. For example, PySNMP relies on smidump which comes with libsmi. Snimpy uses a custom CFFI wrapper around libsmi.

Next.

Previous.