N4626 – Working Draft, C++ Extensions for Networking (2017)

N4626Working Draft, C++ Extensions for Networking, a.k.a. Networking Technical Specification, Networking TS, Jonathan Wakely, 2017-03-17.

Background

  • at cppreference.com
  • Section 4.2 <quote>The design of this specification is based, in part, on the Asio library written by Christopher Kohlhoff.</quote>
  • N4480C++ Extensions for Library Fundamentals, Version 2, 2015-11-25.

Composition

Physical

Everything
#include <experimental/net>

Buys everything.

In Phases && Slices
#include <experimental/netfwd>
#include <experimental/buffer>
#include <experimental/executor>
#include <experimental/internet>
#include <experimental/io_context>
#include <experimental/socket>
#include <experimental/timer>

Incorporates subcomponentry in stages.

Namespaces

std::net
Finally, once standardized, someday; after the year “202a.”
std::experimental::net
(inlined) std::experimental::net::v1
Currently, under draft, during trials, maybe now; prior to the year “202a.”
std::net::ip
a.k.a. std::experimental::net::v1::ip.
The Internet Protocol Subsystem

Components

As elaborated in <net>, a.k.a. <experimental/net>.
Using the "post-standardized" naming conventions:

std::net::associated_allocator
std::net::associated_executor
std::net::async_completion
std::net::async_result
std::net::bad_executor
std::net::basic_datagram_socket
std::net::basic_socket
std::net::basic_socket_acceptor
std::net::basic_socket_iostream
std::net::basic_socket_streambuf
std::net::basic_stream_socket
std::net::basic_waitable_timer
std::net::bind_executor
std::net::buffer_copy
std::net::buffer_size
std::net::const_buffer
std::net::defer
std::net::dispatch
std::net::dynamic_string_buffer
std::net::dynamic_vector_buffer
std::net::execution_context
std::net::execution_context;
std::net::execution_context::service
std::net::executor
std::net::executor_binder
std::net::executor_work_guard
std::net::get_associated_allocator
std::net::get_associated_executor
std::net::high_resolution_timer
std::net::io_context
std::net::io_context::executor_type
std::net::ip::address
std::net::ip::address_v4
std::net::ip::address_v4_iterator
std::net::ip::address_v4_range
std::net::ip::address_v6
std::net::ip::address_v6_iterator
std::net::ip::address_v6_range
std::net::ip::bad_address_cast
std::net::ip::basic_address_iterator
std::net::ip::basic_address_range
std::net::ip::basic_endpoint
std::net::ip::basic_resolver
std::net::ip::basic_resolver_entry
std::net::ip::basic_resolver_results
std::net::ip::network_v4
std::net::ip::network_v6
std::net::ip::resolver_base
std::net::ip::tcp
std::net::ip::udp
std::net::is_executor
std::net::make_work_guard
std::net::mutable_buffer
std::net::packaged_task
std::net::post
std::net::socket_base
std::net::steady_timer
std::net::strand
std::net::system_context
std::net::system_executor
std::net::system_timer
std::net::transfer_all
std::net::transfer_at_least
std::net::transfer_exactly
std::net::use_future_t
std::net::uses_executor
std::net::wait_traits

Referenced

Contents

  • Contents (this list)
  • List of Tables
  1. Scope
  2. Normative references
  3. Terms and definitions
  4. General Principles
    1. Conformance
    2. Acknowledgments
  5. Namespaces and headers
  6. Future plans (Informative)
  7. Feature test macros (Informative)
  8. Method of description (Informative)
    1. Structure of each clause
    2. Other conventions
  9. Error reporting
    1. Synchronous operations
    2. Asynchronous operations
    3. Error conditions
    4. Suppression of signals
  10. Library summary
  11. Convenience header
    • Header <experimental/net> synopsis
  12. Forward declarations
    • Header <experimental/netfwd> synopsis
  13. Asynchronous model
    • Header <experimental/executor> synopsis
    • Requirements
    • Class template async_result
    • Class template async_completion
    • Class template associated_allocator
    • Function get_associated_allocator
    • Class execution_context
    • Class execution_context::service
    • Class template is_executor
    • Executor argument tag
    • uses_executor
    • Class template associated_executor
    • Function get_associated_executor
    • Class template executor_binder
    • Function bind_executor
    • Class template executor_work_guard
    • Function make_work_guard
    • Class system_executor
    • Class system_context
    • Class bad_executor
    • Class executor
    • Function dispatch
    • Function post
    • Function defer
    • Class template strand
    • Class template use_future_t
    • Partial specialization of async_result for packaged_task
  14. I/O services
    • Header <experimental/io_context> synopsis
    • Class io_context
    • Class io_context::executor_type
  15. Timers
    • Header <experimental/timer> synopsis
    • Requirements
    • Class template wait_traits
    • Class template basic_waitable_timer
  16. Buffers
    • Header <experimental/buffer> synopsis
    • Requirements
    • Error codes
    • Class mutable_buffer
    • Class const_buffer
    • Buffer type traits
    • Buffer sequence access
    • Function buffer_size
    • Function buffer_copy
    • Buffer arithmetic
    • Buffer creation functions
    • Class template dynamic_vector_buffer
    • Class template dynamic_string_buffer
    • Dynamic buffer creation functions
  17. Buffer-oriented streams
    • Requirements
    • Class transfer_all
    • Class transfer_at_least
    • Class transfer_exactly
    • Synchronous read operations
    • Asynchronous read operations
    • Synchronous write operations
    • Asynchronous write operations
    • Synchronous delimited read operations
    • Asynchronous delimited read operations
  18. Sockets
    • Header <experimental/socket> synopsis
    • Requirements
    • Error codes
    • Class socket_base
    • Socket options
    • Class template basic_socket
    • Class template basic_datagram_socket
    • Class template basic_stream_socket
    • Class template basic_socket_acceptor
  19. Socket iostreams
    • Class template basic_socket_streambuf
    • Class template basic_socket_iostream
  20. Socket algorithms
    • Synchronous connect operations
    • Asynchronous connect operations
  21. Internet protocol
    • Header <experimental/internet> synopsis
    • Requirements
    • Error codes
    • Class ip::address
    • Class ip::address_v4
    • Class ip::address_v6
    • Class ip::bad_address_cast
    • Hash support
    • Class template ip::basic_address_iterator specializations
    • Class template ip::basic_address_range specializations
    • Class template ip::network_v4
    • Class template ip::network_v6
    • Class template ip::basic_endpoint
    • Class template ip::basic_resolver_entry
    • Class template ip::basic_resolver_results
    • Class ip::resolver_base
    • Class template ip::basic_resolver
    • Host name functions
    • Class ip::tcp
    • Class ip::udp
    • Internet socket options
  • Index
  • Index of library names
  • Index of implementation-defined behavior

Previously filled.

C++17 in details: Parallel Algorithms | Bartłomiej Filipek

Bartłomiej Filipek <noreply@blogger.com>; C++17 in details: Parallel Algorithms; In His Blog; 2017-08-17.

Contents

Mentioned

  • C++11
  • C++14
  • C++17
  • “map reduce” is “transform reduce” in C++17.
  • execution policy.

Scheme

std::algorithm_name(policy, arguments...);

Components

#include <execution>
namespace std::execution
std::execution::ExecutionPolicy

Configuration
Sequential
The algorithm may not be parallelized.

  • (type) std::execution::sequenced_policy
  • (constant) std::execution::seq
Parallel
The algorithm may be parallelized; each individual ith can be scheduled concurrently, but within a stripe, serialization occurs.

  • (type) std::execution::parallel_policy
  • (constant) std::execution::par
Unsequenced (Vectorizable)
The algorithm can be vectorized; the workload as a whole is to be considered.

  • (type) std::execution::parallel_unsequenced_policy
  • (constant) std::execution::par_unseq

Catalog

Via Experimental Parallel Algorithms, at cppreference.com.

Generally…

  • adjacent difference
  • adjacent find.
  • all_of
  • any_of
  • none_of
  • copy
  • count
  • equal
  • fill
  • find
  • generate
  • includes
  • inner product
  • in place merge
  • merge
  • is heap
  • is partitioned
  • is sorted
  • lexicographical_compare
  • min element
  • minmax element
  • mismatch
  • move
  • n-th element
  • partial sort
  • sort copy
  • partition
  • remove & variations
  • replace & variations
  • reverse
  • rotate
  • search
  • set difference
  • intersection
  • union
  • symmetric difference
  • sort
  • stable partition
  • swap ranges
  • transform
  • unique
More New…
  • for_each
  • for_each_n
  • reduce
  • exclusive_scan
  • inclusive_scan
  • std::partial_sum
The Map/Reduce Idom
  • transform_reduce – applies a functor, then reduces out of order
  • transform_exclusive_scan – applies a functor, then calculates exclusive scan
  • transform_inclusive_scan – applies a functor, then calculates inclusive scan

Filler

  • GPU
  • Vectorization (SIMD)
  • Packages
    • CUDA
    • OpenCL
    • OpenGL
    • SYCL
    • Intel TBB
    • “other” vectorized libraries
  • Amdahl’s law; In Jimi Wales’ Wiki

Referenced

There are many resources referenced

Papers

isocpp.org
  • N4659Draft, Standard for Programming Language C++, 2017-03-21.
  • P0024R2Parallelism
    a.k.a. “the original paper for the spec”
  • P0636r0Changes between C++14 and C++17 DIS
  • N3554PDF: A Parallel Algorithms Library, 2013.
    a.k.a. “the initial Parallelism TS”

Popularization

In Modern C++ (Magazine)‖

Books

  • Jacek Galowicz; C++17 STL Cookbook; amzn.to
  • Marius Bancila; Modern C++ Programming Cookbook; amzn.to

YouTube

  • Bryce Adelstein; A Talk; On YouTube; WHEN?
    tl;dr → something about the distinction between std::execution::par, and std::execution::par_unseq.
  • Bryce Lelbach: C++Now 2017: C++17 Features; On YouTube; 2017.
  • Sean Parent; A Talk; At code::dive (Conference), hosted on YouTube; 2016; same material(?) was the subject of a keynote address at CppNow 2012 <rly?>
  • Jason Turner: C++ Weekly channel; On YouTube.
    tl;dr → covers C++17 features in a linear read-the-news-at-you-over-visual-media type format.

Implementations

Previously

In His Blog

Series

  1. Fixes and deprecation
  2. Language clarification
  3. Templates
  4. Attributes
  5. Simplification
  6. Library changes – Filesystem
  7. Library changes – Parallel STL
  8. Library changes – Utils
  9. Wrap up, Bonus

Previously filled.

Trip report: Summer ISO C++ standards meeting (Toronto) | Sutter’s Mill

Herb Sutter; Trip report: Summer ISO C++ standards meeting (Toronto); In His Blog entitled Sutter’s Mill; 2017-07-15.

Mentions

  • Concepts TS
    • “introducer syntax”
    • “terse/natural syntax”
  • Draft C++20
  • C++17
  • Modules TS
  • Coroutines TS
  • Networking TS
  • atomic_shared_ptr<T>
  • Latches
  • Barriers
  • Reflection
  • Library Evolution [Working Group]
  • SG1
  • CppCon

Something About…

  • several new containers
  • compile-time programming
  • metaclass programming

and…

  • modules
  • contracts

Definitions

“IS”
The “international standard” is core [of the] C++ standard.
a.k.a. “trunk.”
“TS”
The “technical specification” is a document separate from the main standard. Experimental features can start here before being put into the IS.
a.k.a. “beta branches.”
Current Status
See the actualities, below.

Who

  • Bjarne Stroustrup
  • Gabriel Dos Reis
  • Andrew Sutton

Referenced

Proposals
  • P0194compile-time reflection
  • P0244Unicode support
  • P0355date library
  • P0329Add designated initializers.
    e.g. struct A { int x; int y; int z; }; A b{.x = 1, .z = 2};
  • P0409Allow lambda capture [=, this].
  • P0428Allow template parameter lists on lambdas.
    e.g. auto f = []<typename T>(std::vector<T> vector) { /*…*/ };
Issues
  • BUG 311remove deprecated features

Previously

In His Blog

Actualities

Previously filled

Roundup of miscellaneous notes, captured and organized

Blockchain Culture

The Seven(Hundred) Dwarves

  • Blockstack(.org)- The New Decentralized Internet
    • blockstack, at GitHub
    • Union Square Ventures (USV)
    • Promotion
      • Staff (USV); The Blockchain App Stack; In Their Blog; 2016-08-08.
      • Blockstack Unveils A Browser For The Decentralized Web; Laura Shin; In Forbes; 2017-05-15.
        tl;dr → <quote>Tuesday, at the main blockchain industry conference, Consensus, one of the companies working on this new decentralized web, Blockstack, which has $5.5 million in funding from Union Square Ventures and AngelList cofounder Naval Ravikant, released a browser add-on that enables that and more.<snip/>The add-on enables a browser to store the user’s identity information by a local key on the consumer’s device.</quote>; Ryan Shea, cofounder.
  • Everyone has something here.

Bluetooth Culture

Bluetooth LE (BLE)

  • and?

Bluetooth 5

  • Something about mesh networking
  • Something about the standard being released “summer 2017.”

C++ Culture

C++20

  • The roadmap onto the twenties.

Application

  • MapReduce, from ETL or EU somewhere.
  • Kyoto Cabinet, Typhoon, Tycoon
  • Virtual Reality packages
  • Ctemplate, Olafud Spek (?)
  • Robot Operating System (ROS)
  • libgraphqlparser – A GraphQL query parser in C++ with C and C++ APIs

Computing Culture

Ubicomp, <ahem>Pervicomp</ahem>

  • Rich Gold
  • Mark Weiser

Dev(Ops) Culture

Futures Cult(ure)

Advocacy

  • Cory Doctorow, the coming war against general purpose computing, an article; WHERE?
  • Cory Doctorow, dystopia contra utopia, an article; WHERE?

Fiction

  • Cory Doctorow, various works

Imagine a World In Which…

  • Stocks vs Flows
  • Chaos vs Stability
  • Permission vs Permissionless
  • Civil Society ↔ Crony Society
    • Transparency
    • Deals
    • Priorities
  • Predictive Technology “just works”
    • is trusted
    • is eventual
    • is law
    • “is” equates with “ought”

Fedora Culture

  • Flatpak

Fedora 26 Notes

  • nmcli reload con down $i
  • nm cli reload con up $i
  • eui64 must be manually configured

Internet of (unpatchable) Thingies (IoT)

  • MQTT
  • mosquito

Language Lifestyles

Go Lang

  • Go for it.
  • A package manager

LangSec

  • theory
  • implementation?

Rust Lang

  • Was there a NoStarch book?

SCOLD Lang

  • C++20?
    hey, surely someone has modules working by now, eh?

Projects

Generally

  • Repig, in C++, with threads, in an NVMe

mod_profile

  • sure, what?

mod_proliphix

  • Interface to the (discontinued) Proliphix thermostats

mod_resting

  • CDN Store
  • Picture Store
  • Document Cache (store & forward)

mod_files

  • Firefox Tiles

SCOLD Experiences

SCOLD near-syntax, common errors

  • #import <hpp>
  • missing #divert
  • #using, a declaration
  • #origin
  • #namespace
  • $@

Suggestions

Build System
  • –with-std-scold or maybe –with-scold
module-c-string
  • vecdup, like strdup
  • vectree, like strfree→free
module-json
  • json::check::Failure or json::Cast.
  • namespace json::is
    • is_array
    • is_null
    • is_object
  • json::as<…>(…)
module-path
  • pathify(…)
module-sqlite
  • column result
  • concept guarding the template parameter, from C++17
module-string
  • typed strings
    • location
    • path
    • etc.
  • and

Surveillance Culture

Concepts

  • Eigenpeople
  • Eigenpersonas
  • Personality modeling

Literature

Yves-Alexandre de Montjoye, Jordi Quoidbach, Florent Robic, Alex (Sandy) Pentland; Predicting Personality Using Novel Mobile Phone-Based Metrics; In: A.M. Greenberg, W.G. Kennedy, N.D. Bos (editors) Social Computing, Behavioral-Cultural Modeling and Prediction as Proceedings of Social Computing, Behavioral (SBP 2013), Lecture Notes in Computer Science, vol 7812; 2013; paywalls: Springer, ACM. Previously filled.

Theory

  • POSS (Post Open Source Software)
    defined as: if everything is on GitHub, then who needs licenses?
    Was this ever amplified?
    Certainly it is facially incorrect and facile.

Psychology

  • Rob Horning; Sock of Myself, an essay; In Real Life Magazine; 2017-05-17
    tl;dr → riffing on happiness, Facebook. Is. Bad. Q.E.D. R.D. Laing , The Divided Self,; John Cheney-Lippold’s We Are Data; Donald Mackenzie.
  • Michael Nelson; University of California, Riverside.

Purposive directionality

  • increase
    • predictability
  • reduce
    • uncertainty
    • variability

Various

Uncomprehensible, Unknown, Unpossible

  • Sunlight, a package? FOSS?

Roundup of unnoted & unfilled items for C++ & SCOLD

Within “Major” C++ Components

  • Kyoto Cabinet
  • Kyoto Tycoon
  • lstio (of Google)
  • ros (Robot Operating System)
  • GraphQL, for C++
  • and

Within Demonstration Projects

  • Wall of Sheep
  • iptables emulator (simulator, exhibition)
  • Reboot the Sun Microsystems Network Architecture
    but with json, avro, etc.

    • portmapper
    • xdr
    • the yp thingy?
      feels like LDAP
  • Conversational Request-Response Daemon
    • NNTP
    • SMTP
  • Pig in C++
    • with threading
      • std::future
      • std::promise
    • with UDFs
  • and

Within C++ SCOLD

  • for module-sqlite
    • connect & open
      • sqlite::open::Result
      • the exception contains the filename
    • errors use the std::error_code std::error_category system
      • status::Code
      • std::error:code
    • insert_last_rowid
    • step(…) as an ADL function
    • row(…) and done(…) are not errors
      they are legitimate flavors of success.
    • function as<…>(…)
    • use concepts to guard the return types
      • as<std::string>(…)
      • as<std::string_view>(…)
      • as<c::stringz>(…) and consty
      • as<c::stringn>(…) and consty
  • ideas for top-level namespaces
    • rest
    • more
    • want
    • have
  • exception taxonomization
    • std::length_error
      • for resizing
      • for sizing
      • because it really is a “programmer’s error”
      • because it isn’t a resource exhaustion error (that is something else)
    • std::out_of_range
      • for indexing-type access violations
      • not std::invalid_argument
  • something about an object iterator
    • a:b, c:d
  • rename module-file-slurp → module-slurp
  • slurp::Failure
    • descends from std::ios::failure
    • rethrow ios::failure
  • promote 1-arg copy
    • std::copy(…3-arguments…)
    • want::copy(1-argument)
      • is like std::move(…)
      • can be elided, or must not be elided?
  • for module-sys-time, namespace sys::time
    • from when milliseconds were good enough
    • ftime and timeb
      but is labeled as “deprecated” nowadays
  • for module-sys-posix
    • sleep
    • usleep
    • returns the time remaining
  • The variants of the syscalls with timeouts.
    • run the syscall in a separate thread
  • module-ish
  • the grab bag, the collection
  • recollect module-mvr in there
  • and

Within Cloud

  • C++ MapReduce & Pig thingy, out of some EU Uni.
  • Apache Beam
    • Uses a dataflow-like language specification
    • Runtimes (“Runners”)
      • Java
      • Python
    • beam.apache.org
    • nifi.apache.org
Posted in C++

Modern MySQL++, MySQL++ v3.2.3

TangentSoft

Forks

… of unknown currency or quality.

Abandoned

Alternatives

On using SSL Certificates for auth in MySQL and LAMP in general

Context

mariadb-10.0.20-1.fc21.x86_64
php-5.6.10-1.fc21.x86_64
php-pdo-5.6.10-1.fc21.x86_64

Complaints

On the use MariaDB v10.0 (MySQL)

of localhost
  • MySQL treats localhost as meaning “use the Unix domain socket” rather than “use TCP on the loopback interface.”  This affects the use of SSL.
  • Arguably, one shouldn’t use SSL on the Unix domain socket since that neither more nor less secure than certificates and certificate keys lying around in the filesystem.
of SSL (OpenSSL)
  • MySQL allows SSL certificates to be in PEM format or in TXT format (!!!); the file suffix is irrelevant; contrast with PHP which requires PEM format

On the use of PHP v5.6

of PHP PDO
  • Doesn’t accept \PDO::MYSQL_ATTR_SSL_CAPATH
    • The warning is emitted
      PHP Warning:  no valid certs found cafile stream: filename
  • Does accept \PDO::MYSQL_ATTR_SSL_CA
    • so one must use a bundled certificate file for the certificate path
  • Seems like the issue is that PDO doesn’t communicate down to the openssl layer
of PHP OpenSSL
  • PHP requires SSL certificates to be in PEM format; contrast with MySQL which supports TXT data (!!!) even misnamed into a .pem suffix file)
  • PHP doesn’t support capath (ssl-capath), it only supports cafile (“ssl-ca”); see …/ext/openssl/xp_ssl.c
  • Added openssl_get_cert_locations() in v5.6
    and run php < dump.php (see below)
  • PHP doesn’t support Subject Alternative Name (SAN)
    <quote ref=”cite“>SAN support for PHP will be introduced in PHP 5.6.</quote>
  • PHP runs HTTP over CURL or its own PHP Socket & PHP Streams.

ArrestDB in PHP

  • Stock implementation is alixaxel/ArrestDB
    • does not support null or empty password.
    • does not support IPv6 address syntax.
    • has limited error reporting
      • does not return exception messaging in the REST output
      • returns 503 with no further logging or messaging.

OpenSSL

  • Differences in support levels between PHP and MySQL (MariaDB)

References

Actualities

<?php
try {
    $dbh = new PDO('mysql:host=ipv6-address;port=port;dbname=dbname', dbusername, dbpassword);
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "
";
    die();
}
?>
array(8) {
  ["default_cert_file"]=>
  string(21) "/etc/pki/tls/cert.pem"
  ["default_cert_file_env"]=>
  string(13) "SSL_CERT_FILE"
  ["default_cert_dir"]=>
  string(18) "/etc/pki/tls/certs"
  ["default_cert_dir_env"]=>
  string(12) "SSL_CERT_DIR"
  ["default_private_dir"]=>
  string(20) "/etc/pki/tls/private"
  ["default_default_cert_area"]=>
  string(12) "/etc/pki/tls"
  ["ini_cafile"]=>
  string(0) ""
  ["ini_capath"]=>
  string(0) ""
}

Emacs query-replace with textual transformation

Solution

M-x replace-regexp <RET> begin\(pattern\)end <RET> newbegin\,(downcase \1)newend

Inventory

  • capitalize
  • upcase
  • downcase

Concept

Use the Lisp macro comma operator to evaluate any elisp expression in the replacement text.

Signalling: backslash comma left-parenthesis elisp-expression right-parenthesis

References

Starting an autotools project

Start by creating some crude sketcy-of-a directory structure that you expect to have

$ mkdir src/driver
$ vi src/driver/main.cpp
$ autoscan

This gives you configure.scan which you need to manually rename to configure.ac.

$ autoscan
$ mv configure.scan configure.ac

You will need to add a mention of AM_INIT_AUTOMAKE to your configure.ac. Failng to do this and you will see errors

$ automake --add-missing --foreign
configure.ac: error: no proper invocation of AM_INIT_AUTOMAKE was found.
configure.ac: You should verify that configure.ac invokes AM_INIT_AUTOMAKE,
configure.ac: that aclocal.m4 is present in the top-level directory,
configure.ac: and that aclocal.m4 was recently regenerated (using aclocal)
automake: error: no 'Makefile.am' found for any configure output
automake: Did you forget AC_CONFIG_FILES([Makefile]) in configure.ac?

Create your Makefile.am mentioning what you want to build.  Also, mention

AUTOMAKE_OPTIONS = foreign

Create your Makefile.in from your Makefile.am.

$ aclocal
$ automake --add-missing --foreign

You will still see errors as follows

$ automake --add-missing --foreign
configure.ac:7: installing './install-sh'
configure.ac:7: installing './missing'
configure.ac:8: error: required file 'config.h.in' not found
Makefile.am: installing './depcomp'

Try running autoheader to generate the config.h.in and autoconf to generate the configure:

autoheader
automake --add-missing --foreign
autoconf

Then you configure and build

$ ./configure
$ make

And again, and again, and again:

aclocal && automake --add-missing --foreign &&./configure && make

configure.scan → configure.ac

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([src/driver/main.cpp])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CXX

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT

The automake tool is very particular about what it sees, and it gives very cryptic error messages if it sees inappropriateness (or incorrect ordering). You must to have AM_INIT_AUTOMAKE invoked as follows:

AC_PREREQ([2.69])
AC_INIT([frigtool-driver], [0.1], [wbaker@baker.org])
AC_CONFIG_SRCDIR([src/driver/main.cpp])
AM_INIT_AUTOMAKE([no-define])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])

Makefile.am

# -*- Makefile -*-
# Copyright (c) 2014-2015, Wendell Craig Baker, wbaker@baker.org
# See the LICENSE file nearby.

bin_PROGRAMS = \
  $(bin_driver) \
  $(end)

bin_driver = bin/driver
bin_driver_SOURCES = \
  src/driver/main.cpp \
  $(end)

buildconf

#!/bin/sh

cd ${0%/*}
set -e
aclocal
autoheader
automake --add-missing
autoreconf
echo "./configure && make check"

Whither the mysterious rpmbuild warning ‘Could not canonicalize hostname devbox.example.com’?

tl;dr → The host in question is an IPv6-only host; rpm uses IPv4-only APIs.


Context

You are using rpmbuild.

Question

Whither the mysterious Could not canonicalize hostname: devbox.example.com?

Specimen

warning: Could not canonicalize hostname: devbox.example.com

Explanation

The code in question is at least a score years old. It uses the IPv4-only API. It does not take into account IPv6. If you are on an IPv6-only host, then you will get this message.

Exhibition

$ rpmbuild -ba example-package-1.1.0.spec
<snip/>
install -D --mode 444 LICENSE /local/fedora/build/workspace/BUILDROOT/example-package-1.2.0-1.fc19.x86_64/usr/local/share/doc/example-package-1.2.0/LICENSE
make[1]: Leaving directory `/local/fedora/build/workspace/BUILD/example-package-1.2.0'
+ /usr/lib/rpm/find-debuginfo.sh --strict-build-id -m --run-dwz --dwz-low-mem-die-limit 10000000 --dwz-max-die-limit 110000000 /local/fedora/build/workspace/BUILD/example-package-1.2.0
/usr/lib/rpm/sepdebugcrcfix: Updated 0 CRC32s, 0 CRC32s did match.
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-compress
+ /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1
+ /usr/lib/rpm/redhat/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-java-repack-jars
Processing files: example-package-1.2.0-1.fc19.noarch
Provides: config(example-package) = 1.2.0-1.fc19 example-package = 1.2.0-1.fc19
Requires(interp): /bin/sh /bin/sh /bin/sh /bin/sh
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires(pre): /bin/sh
Requires(post): /bin/sh
Requires(preun): /bin/sh
Requires(postun): /bin/sh
Requires: /bin/bash /bin/sh
Checking for unpackaged file(s): /usr/lib/rpm/check-files /local/fedora/build/workspace/BUILDROOT/example-package-1.2.0-1.fc19.x86_64
warning: Could not canonicalize hostname: devbox.example.com
Wrote: /local/fedora/build/workspace/SRPMS/example-package-1.2.0-1.fc19.src.rpm
Wrote: /local/fedora/build/workspace/RPMS/noarch/example-package-1.2.0-1.fc19.noarch.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.Vzsxv5
+ umask 022
+ cd /local/fedora/build/workspace/BUILD
+ cd example-package-1.2.0
+ exit 0

Background

Via: An Email Thread
Date: 2002-04-26
Jeff Johnson ARS N3NPQ
jbj@redhat.com (jbj@jbj.org)
Chapel Hill, NC

<quote>Here’s the code that returns the build host (build/names.c):</quote>

const char *const buildHost(void)
{
  static char hostname[1024];
  static int gotit = 0;
  struct hostent *hbn;

  if (! gotit) {
      (void) gethostname(hostname, sizeof(hostname));
      hbn = gethostbyname(hostname);
      if (hbn)
	  strcpy(hostname, hbn->h_name);
      else
	  rpmMessage(RPMMESS_WARNING,
		      _("Could not canonicalize hostname: %s\n"), hostname);
      gotit = 1;
  }
  return(hostname);
}

Also

The opposite of trenchant, misdirecting, even wrong: Setting up RPM Building for SME Server (undated).
<quote><snip/>If you get “warning: Could not canonicalize hostname:” it can be ignored. This is a DNS resolution error and the easy solution is to add your hostname to /etc/hosts</quote>

Complete

Nowadays we so things: use C++11, type safe, exception safe, thread safe. We can get three of the four easily. Thread safety has to wait for another day.

  auto get_canonical_build_hostname(void) -> std::string {
    static std::string hostname;
    static bool cached(false);
    if (cached) {
      return hostname;
    }
    auto gethostname = sys::gethostname();
    if ( ! std::get<0>(gethostname)) {
      throw std::get<2>(gethostname);
    }
    std::string const &best_hostname_estimate = std::get<3>(gethostname);
    std::array<sys::AF,2> const families{sys::AF::INET6, sys::AF::INET4};
    for (auto family : families) {
      auto gethostbyname2 = sys::gethostbyname2(best_hostname_estimate, family);
      if (std::get<0>(gethostbyname2)) {
	hostname.assign(std::get<3>(gethostbyname2).name);
	return hostname;
      }
    }
    throw std::get<2>(gethostbyname);
  }

Demonstration

g++ -o canonical -ggdb -std=c++11 main.cpp
#include <algorithm>
#include <array>
#include <cstdio>
#include <cstdarg>
#include <cstdint>
#include <cstring>
#include <exception>
#include <functional>
#include <iostream>
#include <string>
#include <system_error>
#include <tuple>
#include <typeinfo>
#include <vector>

#include <unistd.h>
#include <netdb.h>
#include <sys/param.h>
#include <sys/socket.h>

// no language translations
#define _(message) message

namespace rpm {

  std::size_t message_count;

  enum class Message { INFO, WARNING, ERROR };
  constexpr Message const MESS_WARNING = Message::WARNING;

  auto log(Message severity, char const *format, ...) -> void __attribute__ ((format (printf, 2, 3))) {
    message_count++;
    FILE *stream = severity == Message::INFO ? stdout : stderr;
    fputs("warning: ", stream);
    va_list ap;
    va_start(ap, format);
    vfprintf(stream, format, ap);
    va_end(ap);
  }

}

extern "C" {
  static const char *const buildHost(void) {
    static char hostname[1024];
    static int gotit = 0;
    if (! gotit) {
      // (sic) was in the original code
      (void) ::gethostname(hostname, sizeof(hostname));
      ::hostent *hbn = ::gethostbyname(hostname);
      if (hbn) {
	strcpy(hostname, hbn->h_name);
      } else {
	rpm::log(rpm::MESS_WARNING, _("Could not canonicalize hostname: %s\n"), hostname);
      }
      gotit = 1;
    }
    return hostname;
  }
}

namespace sys {
  enum class AF { INET4 = AF_INET, INET6 = AF_INET6 };
  struct hostent;
  enum class herrc {
    host_not_found = HOST_NOT_FOUND,
      try_again = TRY_AGAIN,
      no_recovery = NO_RECOVERY,
      no_address = NO_ADDRESS, // same as no_data
      no_data = NO_DATA
  };
  namespace detail {
    std::size_t const PRUDENT_MAXIMUM_HOSTNAME_LENGTH = (2*MAXHOSTNAMELEN); // haters wanna
    union addr;
    class netdb_category;
    using getcall = std::function<::hostent *(char const *)>;
  }
}

namespace std {
  template<> struct is_error_condition_enum<sys::herrc>;
}

namespace sys {
  template<typename CHAR, typename TRAITS> inline auto operator<<(std::basic_ostream<CHAR, TRAITS> &, AF) -> std::basic_ostream<CHAR, TRAITS> &;
  auto netdb_category() noexcept -> std::error_category const &;
  inline auto gethostname() -> std::tuple<bool, int, std::system_error, std::string>;
  inline auto gethostbyname(std::string const &) -> std::tuple<bool, ::hostent *, std::system_error, hostent>; 
  inline auto gethostbyname2(std::string const &, AF) -> std::tuple<bool, ::hostent *, std::system_error, hostent>; 
  namespace detail {
    // count the length of a nullptr-terminated argv
    inline auto count(char const *const *argv) -> std::size_t;
    // gethostname(...) and gethostname2(...) are basically the same thing
    template<typename FUNCTION> auto gethostbyname(FUNCTION const &, std::string const &query_name) -> std::tuple<bool, ::hostent *, std::system_error, hostent>;
  }    
}

template<> struct std::is_error_condition_enum<sys::herrc> : public std::true_type { };

// per the memory shenanigains of ::hostent::h_addr_list
union sys::detail::addr {
  using addr4_type = ::in_addr;
  addr4_type addr4;
  using addr6_type = ::in6_addr;
  addr6_type addr6;
};

struct sys::hostent {
  // like ::hostent, but has appropriate deep copy semantics
  std::string name;                         // was h_name (Official name of host)
  std::vector<std::string> aliases;         // was h_aliases (Alias list)
  AF type;                                  // was h_addrtype (Host address type)
  std::size_t size;                         // was h_length (The address size, in bytes)
  std::vector<detail::addr> addresses;      // was h_addr_list (List of addresses from name server)
};

struct sys::detail::netdb_category : public std::error_category {
  using ancestor = std::error_category;
  // returns "netdb"
  auto name() const noexcept -> char const * override final;
  // returns hstrerror(code)
  auto message(int code) const -> std::string override final;
  // converts h_errno into 
  auto default_error_condition(int code) const noexcept -> std::error_condition override final;
};

auto sys::detail::count(char const *const *argv) -> std::size_t {
  std::size_t count = 0;
  if (nullptr != argv) {
    while (nullptr != *argv++) {
      count++;
    }
  }
  return count;
}

template<typename CHAR, typename TRAITS> auto sys::operator<<(std::basic_ostream<CHAR, TRAITS> &o, AF family) -> std::basic_ostream<CHAR, TRAITS> & {
  char const *begin, *end;
  switch (family) {
  case AF::INET4:
    {
      static char const WORD[]{"inet4"};
      begin = &WORD[0];
      end = &WORD[sizeof (WORD)-1];
    }
    break;
  case AF::INET6:
    {
      static char const WORD[]{"inet6"};
      begin = &WORD[0];
      end = &WORD[sizeof (WORD)-1];
    }
    break;
  default:
    throw std::system_error(std::make_error_code(std::errc::address_family_not_supported), "sys::AF=" + std::to_string(int(family)));
  }
  std::for_each(begin, end, [&o](char c) {
      o << o.widen(c);
    });
  return o;
}

auto sys::detail::netdb_category::name() const noexcept -> char const * {
  return "netdb";
}

// returns hstrerror(code)
auto sys::detail::netdb_category::message(int code) const -> std::string {
  return hstrerror(code);
}

auto sys::detail::netdb_category::default_error_condition(int code) const noexcept -> std::error_condition {
  return std::error_condition(code, *this);
}

auto sys::netdb_category() noexcept -> std::error_category const & {
  static detail::netdb_category const singleton;
  return singleton;
}

auto sys::gethostname() -> std::tuple<bool, int, std::system_error, std::string> {
  using result_type = std::tuple<bool, int, std::system_error, std::string>;
  std::vector<char> buf; // because you can't use a std::string as a fill-buffer
  buf.resize(detail::PRUDENT_MAXIMUM_HOSTNAME_LENGTH);
  int r = ::gethostname(buf.data(), buf.size());
  bool b = 0 == r;
  auto n2 = std::tuple_element<2, result_type>::type();
  auto n3 = std::tuple_element<3, result_type>::type();
  result_type result(b, r, n2, n3);
  if ( ! b ) {
    std::get<2>(result) = std::system_error(h_errno, sys::netdb_category(), "gethostname");
  } else {
    std::get<3>(result).assign(buf.data());
  }
  return result;
}

auto sys::gethostbyname(std::string const &query_name) -> std::tuple<bool, ::hostent *, std::system_error, hostent> {
  detail::getcall syscall = ::gethostbyname;
  return detail::gethostbyname(syscall, query_name);
}

auto sys::gethostbyname2(std::string const &query_name, AF family) -> std::tuple<bool, ::hostent *, std::system_error, hostent> {
  using namespace std::placeholders;
  detail::getcall syscall = std::bind(::gethostbyname2, _1, int(family));
  return detail::gethostbyname(syscall, query_name);
}

template<typename FUNCTION> auto sys::detail::gethostbyname(FUNCTION const &funcall, std::string const &query_name) -> std::tuple<bool, ::hostent *, std::system_error, hostent> {
  using result_type = std::tuple<bool, ::hostent *, std::system_error, hostent>;
  std::vector<char> buf; // because you can't use a std::string as a fill-buffer
  // not threadsafe, returns a pointer to static data
  ::hostent *r = funcall(query_name.c_str());
  bool b = nullptr != r;
  auto n2 = std::tuple_element<2, result_type>::type();
  auto n3 = std::tuple_element<3, result_type>::type();
  result_type result(b, r, n2, n3);
  if ( ! b ) {
    std::get<2>(result) = std::system_error(h_errno, sys::netdb_category(), "gethostbyname " + query_name);
  } else {
    hostent &href = std::get<3>(result);
    href.name = r->h_name;
    href.aliases.assign(&r->h_aliases[0], &r->h_aliases[detail::count(r->h_aliases)]);
    href.type = AF(r->h_addrtype);
    href.size = r->h_length;
    auto push_back = [&href, query_name](char const *rhs) {
      detail::addr lhs;
      switch (href.type) {
      case AF::INET4:
	lhs.addr4 = *(detail::addr::addr4_type *)(rhs);
	break;
      case AF::INET6:
	lhs.addr6 = *(detail::addr::addr6_type *)(rhs);
	break;
      default:
	// unclear this is a good idea.  If the address family isn't known, then the whole hostname
	// is poisoned to us until this gets cleared up.  Maybe we should ignore it and move along?
	throw std::system_error(std::make_error_code(std::errc::address_family_not_supported), "gethostbyname " + query_name);
      }
      href.addresses.push_back(lhs);
    };
    std::for_each(&r->h_addr_list[0], &r->h_addr_list[detail::count(r->h_addr_list)], push_back);
  }
  return result;
}

namespace {

  auto get_canonical_build_hostname(void) -> std::string {
    static std::string hostname;
    static bool cached(false);
    if (cached) {
      return hostname;
    }
    static_assert(std::is_same<std::tuple<bool, int, std::system_error, std::string>, decltype(sys::gethostname())>::value,
		  "sys::gethostname() return type is surprising");
    auto gethostname = sys::gethostname();
    if ( ! std::get<0>(gethostname)) {
      throw std::get<2>(gethostname);
    }
    std::string const &best_hostname_estimate = std::get<3>(gethostname);
    static_assert(std::is_same<std::tuple<bool, ::hostent *, std::system_error, sys::hostent>, decltype(sys::gethostbyname(std::string()))>::value,
		  "sys::gethostbyname(...) return type is surprising");
    auto gethostbyname = sys::gethostbyname(best_hostname_estimate);
    if (std::get<0>(gethostbyname)) {
      hostname.assign(std::get<3>(gethostbyname).name);
      return hostname;
    }
    // recall: that gethostbyname(...) only checks IPv4 ... and we could have an IPv6-only host on our hands [this is the modern age buddy!]
    std::array<sys::AF,2> const families{sys::AF::INET6, sys::AF::INET4};
    static_assert(std::is_same<std::tuple<bool, ::hostent *, std::system_error, sys::hostent>, decltype(sys::gethostbyname2(std::string(), sys::AF()))>::value,
		  "sys::gethostbyname2(...) return type is surprising");
    for (auto family : families) {
      auto gethostbyname2 = sys::gethostbyname2(best_hostname_estimate, family);
      if (std::get<0>(gethostbyname2)) {
	hostname.assign(std::get<3>(gethostbyname2).name);
	return hostname;
      }
    }
    // Characterizing that first failure
    throw std::get<2>(gethostbyname);
  } 

}

auto main() -> int {
  try {
    {
      std::cout << "Trial #1. (Straight C, like you learned in the '80s)\n";
      std::string hostname = ::buildHost();
      std::cout << "canonical hostname: " << hostname;
      char const *const was = 1 == rpm::message_count ? "was" : "where";
      char const *const problem = 1 == rpm::message_count ? "problem": "problems";
      std::cout << ", there " << was << ' ' << rpm::message_count << ' ' << problem << " observed\n";
    } {
      std::cout << "Trial #2. (SCOLD C++ Techniques)\n";
      std::string hostname, problem; 
      try {
	hostname = get_canonical_build_hostname();
      } catch (std::exception const &e) {
	problem = e.what();
      }
      std::cout << "canonical hostname: " << hostname;
      if (hostname.empty()) {
	std::cout << "(empty)";
      }
      if (!problem.empty()) {
	std::cout << ", problems found as " << problem;
      } else {
	std::cout << ", no problems observed, the answer is unambiguous";
      }
      std::cout << '\n';
    }
    return 0;
  } catch (std::exception const &e) {
    std::clog << "FAIL: unexpected exception " << e.what() << '\n';
    return 1;
  }
}

Referenced

Forthcoming

Scalable C++ Original Location Disaggregation (SCOLD)

Recipe for subversion-to-git for rsa (of code.google.com)

Whereas

Google Code is now Dead Code Walking, it’s time to acquire copies of the necessary sources mastered there.

Specimen

rsaThe rsa project an implementation of the RSA cryptography algorithm in C++.

Recipe

$ cd /vault/git/svn/com.google.code
$ mkdir rsa
$ svnadmin create rsa
$ cat > rsa/hooks/pre-revprop-change <<EOF
#!/bin/sh
exit 0;
EOF
$ chmod +x rsa/hooks/pre-revprop-change

$ svnsync init file:///vault/git/svn/com.google.code/rsa  http://rsa.googlecode.com/svn
Copied properties for revision 0.
# (just the one line of output)

$ svnsync sync file:///vault/git/svn/com.google.code/rsa 
# ... lots and lots of output (very slow)
# (very slow)
$ cd /vault/git/clones
$ git svn clone file:///vault/git/svn/com.google.code/rsa/rsa -T trunk -b branches -t tags
Initialized empty Git repository in /vault/git/clones/rsa/.git/
Using higher level of URL: file:///vault/git/svn/com.google.code/rsa/rsa => file:///vault/git/svn/com.google.code/rsa
# (lots of output, very slow)
r70 = ec1f09d6cf45cb09d411cac386b76ade1b5da15d (refs/remotes/trunk)
Checked out HEAD:
  file:///vault/git/svn/com.google.code/rsa/rsa/trunk r70

# convert to the bare repository format
$ mv rsa/.git rsa.git
$ rm -rf rsa
$ cd rsa.git
$ git config --bool core.bare true

Also, -s or --stdlayout is the same as -T trunk -b branches -t tags

WATCHOUT – if you use --stdlayouton an inappropriate dubversion URL, then you’ll get an empty cloned git repository.  The case above has the “standard layout” occurring, not at the top level, but rather one level down; e.g. within rsa of file:///vault/git/svn/com.google.code/rsa, for a complete URL of file:///vault/git/svn/com.google.code/rsa/rsa.

Optionally

emacs rsa.git/description
touch rsa.git/git-daemon-export-ok

Previously

UNSOLVED: git Updates were rejected because a pushed branch tip is behind its remote

$ git push
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Host key fingerprint is ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff

To git@git.example.com:wbaker/project.git
 ! [rejected]        feature-v1 -> feature-v1 (non-fast-forward)
error: failed to push some refs to 'git@git.example.com:wbaker/project.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. If you did not intend to push that branch, you may want to
hint: specify branches to push or set the 'push.default' configuration variable
hint: to 'simple', 'current' or 'upstream' to push only the current branch.

Context

  • This is a “satellite” or “working” repository
  • Commits have already occurred into this repository; it is time to push them upstream, to get them “back home.”
  • Development is occurring on master
  • Development had occurred on feature-v1 but does so no longer.
  • Development is not occurring on feature-v1 which is old & deprectaed.  It is unused.  It is resting, It is a dead branch.
  • The invocation of git pull origin has already occurred.

Diagnosis

Seems like git is trying to indicate that the branch feature-v1 is someonow not synchronized between the two repositories.

Suggestions

None really apply to this situation.

MySQL++ v3.1.0 does not support SSL, but v3.2.2 does

Problem Statement

  • Contact a MySQL; c.f. MariaDB v5.5
  • Use mysql++ for C++
    mysql++-3.1.0-13.fc20.x86_64
  • Use SSL for client auth
  • Fedora 20

Indications

  • mysql++ is not built with SSL support.

Diagnosis

  • MySQL++ SSL Support on Linux; some dude using the self-asserted identity token Ryan; On Stack Overflow; 2011-10-17.
    tl;dr => The MySQL v3.1.0 configure fails to find mysql_ssl_set; the bug is fixed in MySQL++ 3.2.0, (claimed) to have been released 2011-10.

Background

Evidences

$ g++ -std=c++11 -o mysqlpp-ssl mysqlpp-ssl.cpp -DMYSQLPP_MYSQL_HEADERS_BURIED $(mysql_config --cflags --libs) -lmysqlpp
$ ./mysq2lpp-ssl
./mysq2lpp-ssl: error, bad option 'Option not supported by database driver v5.5.41-MariaDB'
#include "mysql++/mysql++.h"
#include <iostream>

namespace {
  char const *const NAME = "mysq2lpp-ssl";
}
auto main(int argc, char *argv[]) -> int {
  try {
    char const *const database = "mysql";
    char const *const hostname = "db.example.com";
    char const *const username = "wbaker";
    char const *const password = "password";
    char const *const key = "/etc/pki/myclient/key.pem";
    char const *const cert = "/etc/pki/myclient/cert.pem";
    char const *const ca = nullptr;
    char const *const capath = "/etc/pki/myclient/ca";
    char const *const cipher = nullptr;
    mysqlpp::Connection conn;
    conn.set_option(new mysqlpp::SslOption(key, cert, ca, capath, cipher));
    if ( !conn.connect(database, hostname, username, password) || !conn.connected()) {
      throw mysqlpp::ConnectionFailed("because");
    }
    std::cout << "OK!\n";
    return 0;
  } catch (mysqlpp::BadOption const &e) {
    std::cerr << NAME << ": error, bad option '" << e.what() << "'\n";
  }
  return 1;
}
$ mock --rebuild ~/Downloads/mysql++-3.2.2-1.src.rpm
...todo...

Using SSL with MariaDB (MySQL)


# Create clean environment
shell> rm -rf newcerts
shell> mkdir newcerts && cd newcerts

# Create CA certificate
shell> openssl genrsa 2048 > ca-key.pem
shell> openssl req -new -x509 -nodes -days 3600 \
         -key ca-key.pem -out ca.pem

# Create server certificate, remove passphrase, and sign it
# server-cert.pem = public key, server-key.pem = private key
shell> openssl req -newkey rsa:2048 -days 3600 \
         -nodes -keyout server-key.pem -out server-req.pem
shell> openssl rsa -in server-key.pem -out server-key.pem
shell> openssl x509 -req -in server-req.pem -days 3600 \
         -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem

# Create client certificate, remove passphrase, and sign it
# client-cert.pem = public key, client-key.pem = private key
shell> openssl req -newkey rsa:2048 -days 3600 \
         -nodes -keyout client-key.pem -out client-req.pem
shell> openssl rsa -in client-key.pem -out client-key.pem
shell> openssl x509 -req -in client-req.pem -days 3600 \
         -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem

mysql> show global variables like '%ssl%'; 
+---------------+---------------------------------------+
| Variable_name | Value                                 |
+---------------+---------------------------------------+
| have_openssl  | YES                                   |
| have_ssl      | YES                                   |
| ssl_ca        | /etc/pki/mysql/root/ca-bundle.pem     |
| ssl_capath    |                                       |
| ssl_cert      | /etc/pki/mysql/server/cert.pem        |
| ssl_cipher    |                                       |
| ssl_key       | /etc/pki/mysql/server/key.pem         |
+---------------+---------------------------------------+
7 rows in set (0.00 sec)

MariaDB [(none)]> status;
--------------
mysql  Ver 15.1 Distrib 5.5.41-MariaDB, for Linux (x86_64) using readline 5.1

Connection id:		5
Current database:	
Current user:		wbaker@devbox.example.com
SSL: Cipher in use is DHE-RSA-AES256-GCM-SHA384
Current pager:		stdout
Using outfile:		''
Using delimiter:	;
Server:			MariaDB
Server version:		5.5.41-MariaDB MariaDB Server
Protocol version:	10
Connection:		mysql.example.com via TCP/IP
Server characterset:	latin1
Db     characterset:	latin1
Client characterset:	utf8
Conn.  characterset:	utf8
TCP port:		3306
Uptime:			8 min 50 sec

Threads: 1  Questions: 10  Slow queries: 0  Opens: 0  Flush tables: 2  Open tables: 26  Queries per second avg: 0.018
--------------

GRANT ALL PRIVILEGES ON test.* TO 'someuser'@'somehost'
  REQUIRE
      ISSUER '/C=US/ST=RedState/L=Thistown/O=MySQL Trust Authority 99/CN=The Man/emailAddress=ca@example.com'
  AND SUBJECT '/C=US/ST=BlueState/L=Thattown/O=ACME Widgets/CN=John Doe/emailAddress=john.doe@example.com';

Estimote SDK

Standard

20 bytes 160 bits Estimote Identifier
16 bytes 128 bits Proximity UUID
2 bytes 16 bits Major
2 bytes 16 bit Minor
  • Proximity UUID: B9407F30-F5F8-466E-AFF9-25556B57FE6D
    • The demonstration app looks for these
  • Major: 16-bit random
  • Minor: 16-bit random

Folklore

Futures

Concepts

  • distance is RSSI

MySQL++ v3.2.2 User Manual

Documents

Mentions

  • Specialized SQL Structures (SSQLS)

Classes

SOLVED: Which MySQL users have access to the database?

show databases;
SELECT * FROM mysql.db WHERE db = 'database_name';
SHOW GRANTS;
SHOW GRANTS FOR CURRENT_USER;

Example

select * from mysql.db where db = 'specimen';
+---------------------------------+-----------+----------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+-----------------------+------------------+------------------+----------------+---------------------+--------------------+--------------+------------+--------------+
| Host                            | Db        | User     | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Grant_priv | References_priv | Index_priv | Alter_priv | Create_tmp_table_priv | Lock_tables_priv | Create_view_priv | Show_view_priv | Create_routine_priv | Alter_routine_priv | Execute_priv | Event_priv | Trigger_priv |
+---------------------------------+-----------+----------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+-----------------------+------------------+------------------+----------------+---------------------+--------------------+--------------+------------+--------------+
| localhost                       | specimen  | role     | Y           | Y           | Y           | Y           | Y           | Y         | Y          | Y               | Y          | Y          | Y                     | Y                | Y                | Y              | Y                   | Y                  | Y            | Y          | Y            |
| localhost                       | specimen  | wbaker   | Y           | Y           | Y           | Y           | Y           | Y         | N          | Y               | Y          | Y          | Y                     | Y                | Y                | Y              | Y                   | Y                  | Y            | Y          | Y            |
| host.emerson.baker.org          | specimen  | wbaker   | Y           | Y           | Y           | Y           | Y           | Y         | N          | Y               | Y          | Y          | Y                     | Y                | Y                | Y              | Y                   | Y                  | Y            | Y          | Y            |
+---------------------------------+-----------+----------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+-----------------------+------------------+------------------+----------------+---------------------+--------------------+--------------+------------+--------------+
3 rows in set (0.00 sec)

References

Recipe for subversion-to-git for mysqlpp

Whereas

mysql++ has some minor issues, it is time to develop & present the remediations.

Previously

For mod-ndb we had Recipe for subversion-to-git for mod-ndb
For dbd-modules we had git svn, svnsync | Git and Subversion

Current

mysql++ seems to be mastered at Gna!

Recipe

$ cd /vault/git/svn
$ svnadmin create mysqlpp
$ cat > mysqlpp/hooks/pre-revprop-change
#!/bin/sh
exit 0;
^D
$ chmod +x mysqlpp/hooks/pre-revprop-change
$ svnsync init file:///vault/git/svn/mysqlpp http://svn.gna.org/svn/mysqlpp
Copied properties for revision 0.

$ svnsync sync file:///vault/git/svn/mysqlpp 
... hundreds of lines ...

$ cd /vault/git/clones
$ git svn clone file:///vault/git/svn/mysqlpp -T trunk -b branches -t tags

Also, -s is the same as -T trunk -b branches -t tags