571 行
53 KiB
XML
571 行
53 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0">
|
||
<id>gemini://technicalsuwako.moe</id>
|
||
<title>テクニカル諏訪子</title>
|
||
|
||
<updated>2023-10-15T00:00:00Z</updated>
|
||
|
||
<author><name>テクニカル諏訪子</name></author>
|
||
<link href="gemini://technicalsuwako.moe" rel="alternate"></link>
|
||
|
||
|
||
|
||
<entry>
|
||
<id>blog/postmarketos-make-repository.gmi</id>
|
||
<author><name>凛</name></author>
|
||
<title type="html">【PostmarketOS】自分のレポジトリを作り方</title>
|
||
<published>2023-10-15T00:00:00Z</published>
|
||
|
||
<category term="jp"></category>
|
||
|
||
<category term="blog"></category>
|
||
|
||
<category term="linux"></category>
|
||
|
||
<category term="デジタル自主"></category>
|
||
|
||
<category term="スマホ"></category>
|
||
|
||
<category term="postmarketos"></category>
|
||
|
||
<category term="pinephone"></category>
|
||
|
||
<category term="alpine"></category>
|
||
|
||
<link href="gemini://technicalsuwako.moe/blog/postmarketos-make-repository.gmi" rel="alternate"></link>
|
||
<content type="html">
|
||
|
||
|
||
|
||
<p><a href="/blog/crux-make-port-repository/">半年前に言った通り、あたしのパソコンでのLinuxを使用歴が非常に長いですが、スマホでの使用歴はそれ程長くないのです。</a><br />
|
||
2020年にはMan(ko)jaroを使用していましたが、毎回パッケージの更新後に度々問題が生じた為、Mobian(PinePhone用Debian)に切り替えました。<br />
|
||
Mobianは2022年まで使用していましたが、2年経ってもLinuxスマホの進歩があんまなかった為、再びPixel 3でGrapheneOS(Google非依存のAndroid)に戻りました。<br />
|
||
しかし、2023年10月現在、ついに大きな進展が見られる様になった為、PinePhoneを処理して、PostmarketOSを試してみたところ、Androidを使用する意欲がなくなりました。</p>
|
||
<p>ちなみに、PostmarketOSはスマホ専用Alpine Linuxベースのディストリビューションです。</p>
|
||
<h2 id="heading">レポジトリの作り方</h2>
|
||
<h3 id="heading-1">初回のみ</h3>
|
||
<p>以下のステップは初回だけ実行して下さい。<br />
|
||
まず、必要なツールをインストールします。</p>
|
||
<pre><code lang="">doas apk update
|
||
doas apk add alpine-sdk
|
||
doas addgroup <span style="color:#a2f;font-weight:bold">$(</span>whoami<span style="color:#a2f;font-weight:bold">)</span> abuild
|
||
doas reboot
|
||
</code></pre><p>再起動後、新しいディレクトリと鍵ペアを生成して下さい。</p>
|
||
<pre><code lang="">mkdir -p ~/.local/src/repo
|
||
abuild-keygen -a -i
|
||
</code></pre><h3 id="heading-2">新しいパッケージを作成する</h3>
|
||
<p>次のステップは、APKBUILDファイルを作成する事です。</p>
|
||
<pre><code lang=""><span style="color:#a2f">cd</span> ~/.local/src/repo
|
||
mkdir urloli
|
||
<span style="color:#a2f">cd</span> urloli
|
||
nvim APKBUILD
|
||
</code></pre><p>例:</p>
|
||
<pre><code lang=""># Maintainer: Suwako Moriya &lt;suwako at 076 dot moe&gt;
|
||
pkgname=urloli
|
||
pkgver=2.2.0
|
||
pkgrel=1
|
||
pkgdesc=&#34;$pkgname&#34;
|
||
url=&#34;https://076.moe&#34;
|
||
arch=&#34;all&#34;
|
||
license=&#34;GPL&#34;
|
||
source=&#34;https://076.moe/repo/src/$pkgname/$pkgname-$pkgver.tar.gz&#34;
|
||
makedepends=&#34;go&#34;
|
||
options=&#34;!check !strip&#34;
|
||
|
||
package() {
|
||
mkdir -p $pkgdir/etc/urloli $pkgdir/usr/bin $pkgdir/etc/init.d $pkgdir/www/active/urlo.li
|
||
mv -i config.json $pkgdir/etc/urloli/config.json
|
||
make
|
||
mv urloli $pkgdir/usr/bin/urloli
|
||
curl https://076.moe/repo/init/openrc/init.d/urloli &gt; $pkgdir/etc/init.d/urloli
|
||
mv view $pkgdir/www/active/urlo.li
|
||
mv static $pkgdir/www/active/urlo.li
|
||
chmod +x $pkgdir/etc/init.d/urloli
|
||
chmod +x $pkgdir/usr/bin/urloli
|
||
echo &#34;Change the domain name in \&#34;/etc/$pkgname/config.json\&#34;.&#34;
|
||
}
|
||
</code></pre><p>URLロリはGo以外従属ソフトがありませんが、Goはコンパイル時だけで必要ですので、「makedepends」に追加しました。<br />
|
||
実行するには必要であれば、「depends」に追加して下さい。</p>
|
||
<p><strong>注意:PostmarketOSやAlpineで、「ninja」をインストールする場合、<code lang="">apk add ninja</code>ではなく<code lang="">apk add samurai</code>を使用して下さい。</strong></p>
|
||
<p>次は「sha512sum」を生成し、ビルドを行って下さい。</p>
|
||
<pre><code lang="">abuild checksum
|
||
abuild
|
||
</code></pre><p>Alpineではパッケージの署名が必要ですが、PostmarketOSでは自動で署名される為、これは不要です。</p>
|
||
<h2 id="heading-3">レポジトリサーバーの準備</h2>
|
||
<p>次のステップは、サーバーを準備です。<br />
|
||
サーバーはOpenBSDの場合:</p>
|
||
<pre><code lang="">doas nvim /etc/httpd.conf
|
||
</code></pre><pre><code lang="">...
|
||
server &#34;076.moe&#34; {
|
||
listen on * port 443
|
||
root &#34;/htdocs/076.moe/www&#34;
|
||
directory index &#34;index.html&#34;
|
||
location &#34;/repo/*&#34; {
|
||
directory auto index
|
||
}
|
||
location &#34;/.well-known/acme-challenge/*&#34; {
|
||
root &#34;/acme&#34;
|
||
request strip 2
|
||
}
|
||
}
|
||
|
||
server &#34;www.076.moe&#34; {
|
||
listen on * port 80
|
||
block return 301 &#34;https://076.moe$REQUEST_URI&#34;
|
||
}
|
||
|
||
server &#34;l3nbzyxgrkmd46nacmzf2sy6tpjrwh4iv3pgacbrbk72wcgxq5a.b32.i2p&#34; {
|
||
listen on * port 8450
|
||
root &#34;/htdocs/076.moe/www&#34;
|
||
directory index &#34;index.html&#34;
|
||
location &#34;/repo/*&#34; {
|
||
directory auto index
|
||
}
|
||
}
|
||
|
||
server &#34;7dt6irsmfvbrtgn4nuah56kky6mvr472fbwwaltuxpf26qdqkdhfvnqd.onion&#34; {
|
||
listen on * port 8500
|
||
root &#34;/htdocs/076.moe/www&#34;
|
||
directory index &#34;index.html&#34;
|
||
location &#34;/repo/*&#34; {
|
||
directory auto index
|
||
}
|
||
}
|
||
...
|
||
</code></pre><pre><code lang="">doas mkdir -p /var/www/htdocs/076.moe/www/repo/alpine
|
||
doas chown -R <span style="color:#a2f;font-weight:bold">$(</span>whoami<span style="color:#a2f;font-weight:bold">)</span>:<span style="color:#a2f;font-weight:bold">$(</span>whoami<span style="color:#a2f;font-weight:bold">)</span> /var/www/htdocs/076.moe
|
||
doas rcctl restart httpd
|
||
</code></pre><h3 id="heading-4">パッケージを公開</h3>
|
||
<p>公開鍵をアップロードした後、パッケージを公開して下さい。</p>
|
||
<pre><code lang="">rsync -rtvzP ~/.abuild/*.rsa.pub <span style="color:#666">(</span>君のIPアドレス<span style="color:#666">)</span>:/var/www/htdocs/076.moe/www/repo/alpine
|
||
<span style="color:#a2f">cd</span> ~/packages
|
||
rsync -rtvzP repo <span style="color:#666">(</span>君のIPアドレス<span style="color:#666">)</span>:/var/www/htdocs/076.moe/www/repo/alpine
|
||
</code></pre><h2 id="heading-5">レポジトリの確認</h2>
|
||
<p>最後のステップは、自分のパッケージをインストールする事です。</p>
|
||
<pre><code lang=""><span style="color:#a2f">cd</span> /etc/apk/keys
|
||
doas wget https://<span style="color:#666">(</span>ドメイン名<span style="color:#666">)</span>/repo/alpine/<span style="color:#666">(</span>.rsa.pubのファイル名<span style="color:#666">)</span>
|
||
<span style="color:#a2f">cd</span> ..
|
||
doas nvim repositories
|
||
</code></pre><pre><code lang="">http://mirror.postmarketos.org/postmarketos/v23.06
|
||
http://dl-cdn.alpinelinux.org/alpine/v3.18/main
|
||
http://dl-cdn.alpinelinux.org/alpine/v3.18/community
|
||
http://(ドメイン名)/repo/alpine/repo # これを追加して下さい
|
||
</code></pre><pre><code lang="">doas apk update
|
||
doas apk add urloli
|
||
</code></pre><p>以上</p>
|
||
|
||
|
||
</content>
|
||
</entry>
|
||
|
||
<entry>
|
||
<id>blog/spliti-111.gmi</id>
|
||
<author><name>凛</name></author>
|
||
<title type="html">【オワコンテック】spliti 1.1.1登場</title>
|
||
<published>2023-09-09T00:00:00Z</published>
|
||
|
||
<category term="jp"></category>
|
||
|
||
<category term="blog"></category>
|
||
|
||
<category term="ウエブ開発"></category>
|
||
|
||
<category term="オワコンテック"></category>
|
||
|
||
<category term="spliti"></category>
|
||
|
||
<link href="gemini://technicalsuwako.moe/blog/spliti-111.gmi" rel="alternate"></link>
|
||
<content type="html">
|
||
|
||
|
||
|
||
<h2 id="spliti">splitiって何?</h2>
|
||
<p>splitiはMixiのフェイクニュース部分向けプライバシーUIです。</p>
|
||
<h2 id="heading">変更</h2>
|
||
<ul>
|
||
<li>YouTube動画があれば、オワコンYouTubeに変更させる様に</li>
|
||
<li>サムネイルがなければ、getimg()関数をす部に終了する様に</li>
|
||
<li>もっと小さいバグを修正</li>
|
||
</ul>
|
||
<h2 id="heading-1">ソースコード</h2>
|
||
<p><a href="https://gitler.moe/suwako/spliti">Gitler</a></p>
|
||
<h2 id="heading-2">公式インスタンス</h2>
|
||
<p><a href="">https://mixi.owacon.moe/</a></p>
|
||
<p>以上</p>
|
||
|
||
|
||
</content>
|
||
</entry>
|
||
|
||
<entry>
|
||
<id>blog/fix-broken-contact-form.gmi</id>
|
||
<author><name>凛</name></author>
|
||
<title type="html">【PHP】正しい連絡フォームの作り方(クライアント側をぜったいに信用するな!!)</title>
|
||
<published>2023-08-04T00:00:00Z</published>
|
||
|
||
<category term="blog"></category>
|
||
|
||
<category term="jp"></category>
|
||
|
||
<category term="プログラミング"></category>
|
||
|
||
<category term="php"></category>
|
||
|
||
<category term="ウエブ開発"></category>
|
||
|
||
<category term="html"></category>
|
||
|
||
<category term="javascript"></category>
|
||
|
||
<link href="gemini://technicalsuwako.moe/blog/fix-broken-contact-form.gmi" rel="alternate"></link>
|
||
<content type="html">
|
||
|
||
|
||
|
||
<h2 id="heading">問題</h2>
|
||
<p>現在の「モダン」ウェブ開発で、連絡フォームはJavascriptで制御されていますが、これは大きなリスクがあります。<br />
|
||
その理由について、直ぐに説明します。</p>
|
||
<p>以下のスクショをご覧いただいたら、何が問題は何だと思いますか?<br />
|
||
<a href="https://ass.technicalsuwako.moe/fuanform1.png"><img src="https://ass.technicalsuwako.moe/fuanform1.png" alt="" /></a></p>
|
||
<p>正解は:送信ボタンは<code lang="">&lt;form&gt;</code>タグの外にある事です。<br />
|
||
これでは、Javascriptを無効にした場合、送信ボタンをクリックする事が出来ません。</p>
|
||
<p>このフォームを送信する為には、この送信ボタンをフォーム内に移動し、<code lang="">type=&quot;button&quot;</code>を<code lang="">type=&quot;submit&quot;</code>に変更する事で、Javascriptなしでもフォームを送信する事が可能になります。<br />
|
||
そんな感じ:<br />
|
||
<a href="https://ass.technicalsuwako.moe/fuanform2.png"><img src="https://ass.technicalsuwako.moe/fuanform2.png" alt="" /></a></p>
|
||
<p>そうして、入力画面で「required=&quot;&quot;」というパラメータがあり、これによりJavascriptが無効であってもフィールドが入力されているかどうかを確認できます。<br />
|
||
例:<br />
|
||
<a href="https://ass.technicalsuwako.moe/fuanform3.png"><img src="https://ass.technicalsuwako.moe/fuanform3.png" alt="" /></a></p>
|
||
<p>しかし、このパラメータを削除すると、どのような事態が起こると思いますか?<br />
|
||
正解はこちら:<br />
|
||
<a href="https://ass.technicalsuwako.moe/fuanform4.png"><img src="https://ass.technicalsuwako.moe/fuanform4.png" alt="" /></a></p>
|
||
<p>また、確認画面ではフォームが<code lang="">&lt;input type=&quot;hidden&quot; /&gt;</code>タグを沢山含んでいます。<br />
|
||
その中の「value=&quot;&quot;」部分を変更する事が可能です。<br />
|
||
これにより、MySQLインジェクションも可能となります。</p>
|
||
<h2 id="heading-1">解決策</h2>
|
||
<p>上述の問題を解決する為には、サーバー側でのチェックが必要です。<br />
|
||
勿論、クライアント側とサーバー側の両方でチェックを行う事も可能です。</p>
|
||
<p>例として、PHPの場合を紹介します(PHPを使用するフォームが多い為):</p>
|
||
<pre><code lang=""><span style="color:#666">&lt;?</span>php
|
||
session_name(<span style="color:#b44">&#34;formvals&#34;</span>);
|
||
session_start([
|
||
<span style="color:#b44">&#34;cookie_httponly&#34;</span> <span style="color:#666">=&gt;</span> <span style="color:#a2f;font-weight:bold">true</span>,
|
||
]);
|
||
|
||
<span style="color:#a2f;font-weight:bold">if</span> (<span style="color:#a2f;font-weight:bold">empty</span>(<span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;csrf_token&#34;</span>])) <span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;csrf_token&#34;</span>] <span style="color:#666">=</span> bin2hex(random_bytes(<span style="color:#666">32</span>));
|
||
<span style="color:#a2f;font-weight:bold">if</span> (<span style="color:#666">!</span>isset(<span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;step&#34;</span>])) <span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;step&#34;</span>] <span style="color:#666">=</span> <span style="color:#666">1</span>;
|
||
<span style="color:#b8860b">$errmes</span> <span style="color:#666">=</span> [];
|
||
<span style="color:#b8860b">$reqvals</span> <span style="color:#666">=</span> [
|
||
<span style="color:#b44">&#34;name&#34;</span> <span style="color:#666">=&gt;</span> <span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;name&#34;</span>] <span style="color:#666">??</span> <span style="color:#b44">&#34;&#34;</span>,
|
||
<span style="color:#b44">&#34;kana&#34;</span> <span style="color:#666">=&gt;</span> <span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;kana&#34;</span>] <span style="color:#666">??</span> <span style="color:#b44">&#34;&#34;</span>,
|
||
];
|
||
<span style="color:#b8860b">$optvals</span> <span style="color:#666">=</span> [
|
||
<span style="color:#b44">&#34;url&#34;</span> <span style="color:#666">=&gt;</span> <span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;url&#34;</span>] <span style="color:#666">??</span> <span style="color:#b44">&#34;&#34;</span>,
|
||
];
|
||
|
||
<span style="color:#a2f;font-weight:bold">if</span> (<span style="color:#b8860b">$_SERVER</span>[<span style="color:#b44">&#34;REQUEST_METHOD&#34;</span>] <span style="color:#666">==</span> <span style="color:#b44">&#34;POST&#34;</span>) {
|
||
<span style="color:#a2f;font-weight:bold">if</span> (<span style="color:#666">!</span>hash_equals(<span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;csrf_token&#34;</span>], <span style="color:#b8860b">$_POST</span>[<span style="color:#b44">&#34;csrf_token&#34;</span>])) {
|
||
<span style="color:#a2f;font-weight:bold">die</span>(<span style="color:#b44">&#34;不正なCSRFトークン&#34;</span>);
|
||
}
|
||
|
||
<span style="color:#a2f;font-weight:bold">if</span> (<span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;step&#34;</span>] <span style="color:#666">==</span> <span style="color:#666">1</span>) {
|
||
<span style="color:#a2f;font-weight:bold">foreach</span> (<span style="color:#b8860b">$reqvals</span> <span style="color:#a2f;font-weight:bold">as</span> <span style="color:#b8860b">$k</span> <span style="color:#666">=&gt;</span> <span style="color:#b8860b">$v</span>) {
|
||
<span style="color:#b8860b">$_SESSION</span>[<span style="color:#b8860b">$k</span>] <span style="color:#666">=</span> filter_input(INPUT_POST, <span style="color:#b8860b">$k</span>, FILTER_SANITIZE_STRING);
|
||
<span style="color:#a2f;font-weight:bold">if</span> (<span style="color:#b8860b">$_SESSION</span>[<span style="color:#b8860b">$k</span>]) <span style="color:#b8860b">$reqvals</span>[<span style="color:#b8860b">$k</span>] <span style="color:#666">=</span> <span style="color:#b8860b">$_SESSION</span>[<span style="color:#b8860b">$k</span>];
|
||
<span style="color:#a2f;font-weight:bold">else</span> <span style="color:#b8860b">$errmes</span>[] <span style="color:#666">=</span> <span style="color:#b8860b">$k</span><span style="color:#666">.</span><span style="color:#b44">&#34;をご入力下さい。&#34;</span>;
|
||
}
|
||
|
||
<span style="color:#a2f;font-weight:bold">foreach</span> (<span style="color:#b8860b">$optvals</span> <span style="color:#a2f;font-weight:bold">as</span> <span style="color:#b8860b">$k</span> <span style="color:#666">=&gt;</span> <span style="color:#b8860b">$v</span>) {
|
||
<span style="color:#b8860b">$_SESSION</span>[<span style="color:#b8860b">$k</span>] <span style="color:#666">=</span> filter_input(INPUT_POST, <span style="color:#b8860b">$k</span>, FILTER_SANITIZE_STRING);
|
||
<span style="color:#b8860b">$optvals</span>[<span style="color:#b8860b">$k</span>] <span style="color:#666">=</span> <span style="color:#b8860b">$_SESSION</span>[<span style="color:#b8860b">$k</span>];
|
||
}
|
||
|
||
<span style="color:#a2f;font-weight:bold">if</span> (<span style="color:#a2f;font-weight:bold">empty</span>(<span style="color:#b8860b">$errmes</span>)) <span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;step&#34;</span>] <span style="color:#666">=</span> <span style="color:#666">2</span>;
|
||
}
|
||
<span style="color:#a2f;font-weight:bold">else</span> <span style="color:#a2f;font-weight:bold">if</span> (<span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;step&#34;</span>] <span style="color:#666">==</span> <span style="color:#666">2</span>) {
|
||
<span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;step&#34;</span>] <span style="color:#666">=</span> <span style="color:#666">1</span>;
|
||
session_destroy();
|
||
header(<span style="color:#b44">&#34;Location: /success.html&#34;</span>);
|
||
<span style="color:#a2f;font-weight:bold">die</span>();
|
||
}
|
||
}
|
||
<span style="color:#a2f;font-weight:bold">else</span> {
|
||
<span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;csrf_token&#34;</span>] <span style="color:#666">=</span> bin2hex(random_bytes(<span style="color:#666">32</span>));
|
||
<span style="color:#b8860b">$_SESSION</span>[<span style="color:#b44">&#34;step&#34;</span>] <span style="color:#666">=</span> <span style="color:#666">1</span>;
|
||
}
|
||
<span style="color:#080">?&gt;</span><span style="">
|
||
</span><span style="">
|
||
</span><span style="">&lt;!DOCTYPE html&gt;
|
||
</span><span style="">&lt;html&gt;
|
||
</span><span style=""> &lt;head&gt;
|
||
</span><span style=""> &lt;meta charset=&#34;utf-8&#34; /&gt;
|
||
</span><span style=""> &lt;title&gt;連絡フォーム&lt;/title&gt;
|
||
</span><span style=""> &lt;/head&gt;
|
||
</span><span style=""> &lt;body&gt;
|
||
</span><span style="">&lt;?php
|
||
</span><span style=""> if ($_SESSION[&#34;step&#34;] == 1) {
|
||
</span><span style=""> if (count($errmes) != 0) {
|
||
</span><span style="">?&gt;
|
||
</span><span style=""> &lt;ul style=&#34;font-width: bolder; color: #f00; list-style: none;&#34;&gt;
|
||
</span><span style="">&lt;?php
|
||
</span><span style=""> foreach ($errmes as $e) {
|
||
</span><span style=""> echo &#34;&lt;li&gt;&#34;.$e.&#34;&lt;/li&gt;&#34;;
|
||
</span><span style=""> }
|
||
</span><span style="">?&gt;
|
||
</span><span style=""> &lt;/ul&gt;
|
||
</span><span style="">&lt;?php
|
||
</span><span style=""> }
|
||
</span><span style="">?&gt;
|
||
</span><span style=""> &lt;form method=&#34;POST&#34; action=&#34;/contact.php&#34;&gt;
|
||
</span><span style=""> &lt;input type=&#34;hidden&#34; name=&#34;csrf_token&#34; value=&#34;&lt;?= $_SESSION[&#39;csrf_token&#39;] ?&gt;&#34;&gt;
|
||
</span><span style=""> &lt;table&gt;
|
||
</span><span style=""> &lt;tbody&gt;
|
||
</span><span style=""> &lt;tr&gt;
|
||
</span><span style=""> &lt;td&gt;お名前 (必須):&lt;/td&gt;
|
||
</span><span style=""> &lt;td&gt;&lt;input placeholder=&#34;山田 太郎&#34; required=&#34;&#34; name=&#34;name&#34; type=&#34;text&#34; value=&#34;&lt;?= $reqvals[&#34;name&#34;] ?&gt;&#34; /&gt;&lt;/td&gt;
|
||
</span><span style=""> &lt;/tr&gt;
|
||
</span><span style=""> &lt;tr&gt;
|
||
</span><span style=""> &lt;td&gt;お名前 (かな) (必須):&lt;/td&gt;
|
||
</span><span style=""> &lt;td&gt;&lt;input placeholder=&#34;やまだ たろう&#34; required=&#34;&#34; name=&#34;kana&#34; type=&#34;text&#34; value=&#34;&lt;?= $reqvals[&#34;kana&#34;] ?&gt;&#34; /&gt;&lt;/td&gt;
|
||
</span><span style=""> &lt;/tr&gt;
|
||
</span><span style=""> &lt;tr&gt;
|
||
</span><span style=""> &lt;td&gt;御社又は関連サイトのURL:&lt;/td&gt;
|
||
</span><span style=""> &lt;td&gt;&lt;input placeholder=&#34;https://076.moe/&#34; name=&#34;url&#34; type=&#34;text&#34; value=&#34;&lt;?= $optvals[&#34;url&#34;] ?&gt;&#34; /&gt;&lt;/td&gt;
|
||
</span><span style=""> &lt;/tr&gt;
|
||
</span><span style=""> &lt;/tbody&gt;
|
||
</span><span style=""> &lt;/table&gt;
|
||
</span><span style=""> &lt;button&gt;確認画面へ&lt;/button&gt;
|
||
</span><span style=""> &lt;/form&gt;
|
||
</span><span style="">&lt;?php
|
||
</span><span style=""> } else if ($_SESSION[&#34;step&#34;] == 2) {
|
||
</span><span style="">?&gt;
|
||
</span><span style=""> &lt;form method=&#34;POST&#34; action=&#34;/contact.php&#34;&gt;
|
||
</span><span style=""> &lt;input type=&#34;hidden&#34; name=&#34;csrf_token&#34; value=&#34;&lt;?= $_SESSION[&#39;csrf_token&#39;] ?&gt;&#34;&gt;
|
||
</span><span style=""> お名前 (必須): &lt;?= $reqvals[&#34;name&#34;] ?&gt;&lt;br /&gt;
|
||
</span><span style=""> お名前 (かな) (必須): &lt;?= $reqvals[&#34;kana&#34;] ?&gt;&lt;br /&gt;
|
||
</span><span style=""> 御社又は関連サイトのURL: &lt;?= $optvals[&#34;url&#34;] ?&gt;&lt;br /&gt;&lt;br /&gt;
|
||
</span><span style=""> &lt;button&gt;送信する&lt;/button&gt;
|
||
</span><span style=""> &lt;/form&gt;
|
||
</span><span style="">&lt;?php
|
||
</span><span style=""> } else {
|
||
</span><span style="">?&gt;
|
||
</span><span style=""> &lt;p&gt;不明なエラー。&lt;/p&gt;
|
||
</span><span style="">&lt;?php
|
||
</span><span style=""> }
|
||
</span><span style="">?&gt;
|
||
</span><span style=""> &lt;/body&gt;
|
||
</span><span style="">&lt;/html&gt;
|
||
</span></code></pre><p>結果:<br />
|
||
<a href="https://ass.technicalsuwako.moe/anzenform1.png"><img src="https://ass.technicalsuwako.moe/anzenform1.png" alt="" /></a></p>
|
||
<p><a href="https://ass.technicalsuwako.moe/anzenform2.png"><img src="https://ass.technicalsuwako.moe/anzenform2.png" alt="" /></a></p>
|
||
<p><a href="https://ass.technicalsuwako.moe/anzenform3.png"><img src="https://ass.technicalsuwako.moe/anzenform3.png" alt="" /></a></p>
|
||
<p><a href="https://ass.technicalsuwako.moe/anzenform4.png"><img src="https://ass.technicalsuwako.moe/anzenform4.png" alt="" /></a></p>
|
||
<p><a href="https://ass.technicalsuwako.moe/anzenform5.png"><img src="https://ass.technicalsuwako.moe/anzenform5.png" alt="" /></a></p>
|
||
<p><a href="https://ass.technicalsuwako.moe/anzenform6.png"><img src="https://ass.technicalsuwako.moe/anzenform6.png" alt="" /></a></p>
|
||
<p>ねぇねぇー!<br />
|
||
簡単でしょー!</p>
|
||
<p>以上</p>
|
||
|
||
|
||
</content>
|
||
</entry>
|
||
|
||
<entry>
|
||
<id>blog/zig-gengo-1.gmi</id>
|
||
<author><name>凛</name></author>
|
||
<title type="html">【Zig言語】第1部~基本的な紹介・セットアップ・「こんにちは、世界」</title>
|
||
<published>2023-08-01T00:00:00Z</published>
|
||
|
||
<category term="blog"></category>
|
||
|
||
<category term="jp"></category>
|
||
|
||
<category term="プログラミング"></category>
|
||
|
||
<category term="zig"></category>
|
||
|
||
<category term="システム開発"></category>
|
||
|
||
<link href="gemini://technicalsuwako.moe/blog/zig-gengo-1.gmi" rel="alternate"></link>
|
||
<content type="html">
|
||
|
||
|
||
|
||
<h2 id="zig">Zig言語シリーズ</h2>
|
||
<p>このブログでは様々なプログラミング言語の使い方を紹介します。<br />
|
||
主にZig、PHP、Go言語、C言語について解説し、更にはFLTK、Raylib、OpenGL等も取り上げます。</p>
|
||
<h2 id="zig-1">Zig言語とは?</h2>
|
||
<p>Zigは非常に新しい言語です。<br />
|
||
Goが新しい形のPHP、Carbonが新しいC++、Kotlinが新しいJava、TypeScriptが新しいJavascript、Swiftが新しいObjective-Cのように、Zigは新しい形のC言語と考える事が出来ます。<br />
|
||
初めて見ると、Zig言語は難しそうに見えますが、約1週間使ってみれば、そう難しくは感じなくなります。<br />
|
||
現在、最新バージョンは0.10.1ですが、今週中には0.11.0のリリースが予定されています。<br />
|
||
このシリーズではそのバージョンを使用します。</p>
|
||
<h2 id="czig">C言語とZig言語の違いは?</h2>
|
||
<p>C言語は16ビットの世代で作られましたが、Zigは64ビットの世代で作られたため、Zigの方がモダンな言語といえます。<br />
|
||
Zig言語は、Rustのような安全性とGo言語のようなシンプルさを持っています。<br />
|
||
コードの違いを以下で示します:</p>
|
||
<h3 id="c">C</h3>
|
||
<pre><code lang=""><span style="color:#080">#include</span> <span style="color:#080">&lt;stdio.h&gt;</span><span style="color:#080">
|
||
</span><span style="color:#080"></span>
|
||
<span style="color:#0b0;font-weight:bold">int</span> <span style="color:#00a000">tuika</span> (<span style="color:#0b0;font-weight:bold">int</span> a, <span style="color:#0b0;font-weight:bold">int</span> b) {
|
||
<span style="color:#a2f;font-weight:bold">return</span> a <span style="color:#666">+</span> b;
|
||
}
|
||
|
||
<span style="color:#0b0;font-weight:bold">int</span> <span style="color:#00a000">main</span> () {
|
||
<span style="color:#0b0;font-weight:bold">int</span> a <span style="color:#666">=</span> <span style="color:#666">1</span>;
|
||
<span style="color:#0b0;font-weight:bold">int</span> b <span style="color:#666">=</span> <span style="color:#666">2</span>;
|
||
printf(<span style="color:#b44">&#34;%d</span><span style="color:#b62;font-weight:bold">\n</span><span style="color:#b44">&#34;</span>, tuika(a, b));
|
||
|
||
<span style="color:#a2f;font-weight:bold">return</span> <span style="color:#666">0</span>;
|
||
}
|
||
</code></pre><h3 id="zig-2">Zig</h3>
|
||
<pre><code lang=""><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>std<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#a2f">@import</span>(<span style="color:#b44">&#34;std&#34;</span>);<span style="color:#bbb">
|
||
</span><span style="color:#bbb">
|
||
</span><span style="color:#bbb"></span><span style="color:#a2f;font-weight:bold">fn</span><span style="color:#bbb"> </span>tuika(a<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">u8</span>,<span style="color:#bbb"> </span>b<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">u8</span>)<span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">u8</span><span style="color:#bbb"> </span>{<span style="color:#bbb">
|
||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">return</span><span style="color:#bbb"> </span>a<span style="color:#bbb"> </span><span style="color:#666">+</span><span style="color:#bbb"> </span>b;<span style="color:#bbb">
|
||
</span><span style="color:#bbb"></span>}<span style="color:#bbb">
|
||
</span><span style="color:#bbb">
|
||
</span><span style="color:#bbb"></span><span style="color:#a2f;font-weight:bold">pub</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">fn</span><span style="color:#bbb"> </span>main()<span style="color:#bbb"> </span><span style="color:#666">!</span><span style="color:#0b0;font-weight:bold">void</span><span style="color:#bbb"> </span>{<span style="color:#bbb">
|
||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>a<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">u8</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">1</span>;<span style="color:#bbb">
|
||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>b<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">u8</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">2</span>;<span style="color:#bbb">
|
||
</span><span style="color:#bbb"> </span>std.debug.print(<span style="color:#b44">&#34;{d}</span><span style="color:#b62;font-weight:bold">\n</span><span style="color:#b44">&#34;</span>,<span style="color:#bbb"> </span>.{tuika(a,<span style="color:#bbb"> </span>b)});<span style="color:#bbb">
|
||
</span><span style="color:#bbb"></span>}<span style="color:#bbb">
|
||
</span></code></pre><p>よく見ると、スタイルは殆ど同じです。<br />
|
||
ただし、main関数の戻り値はintではなくvoidになります。<br />
|
||
そして、Zigではintが一つの型ではなく、様々なサイズ(u8~u128、i8~i128)があります。<br />
|
||
また、C言語で「型名 変数名 = 値」や「戻り値の型名 関数名 (パラメータ)」と表現するところを、Zig言語では「変更可否 変数名: 型名 = 値」や「公開・非公開 fn 関数名(パラメータ) 戻り値の型名」と表現します。</p>
|
||
<h2 id="heading">セットアップ</h2>
|
||
<p>バージョン0.11.0がリリースされれば、パッケージマネージャからインストール出来る様になると思います。<br />
|
||
そうでない場合は、以下のコマンドを実行してください。<br />
|
||
まず、LLVM16以上が必要です。<br />
|
||
それをインストールしたら、Zigをコンパイルする方法は:</p>
|
||
<pre><code lang=""><span style="color:#a2f">cd</span> zig-*
|
||
mkdir build
|
||
<span style="color:#a2f">cd</span> build
|
||
cmake .. -DZIG_STATIC_LLVM<span style="color:#666">=</span>ON -DCMAKE_PREFIX_PATH<span style="color:#666">=</span>/usr
|
||
make install -DPREFIX<span style="color:#666">=</span>/usr
|
||
</code></pre><p>注意:あたしはCRUXでしかコンパイル出来ませんでした。<br />
|
||
Artix、OpenBSD、FreeBSDでは失敗しました。<br />
|
||
Devuanは確認していません。</p>
|
||
<p>インストール後、新しいフォルダを作り、新しいプロジェクトを作成しましょう:</p>
|
||
<pre><code lang="">mkdir hello
|
||
<span style="color:#a2f">cd</span> hello
|
||
zig init-exe
|
||
</code></pre><p>現在のファイルは以下の様になります:</p>
|
||
<pre><code lang="">.
|
||
├── build.zig
|
||
└── src
|
||
└── main.zig
|
||
</code></pre><p>そのまま<code lang="">zig build run</code>を実行すると:</p>
|
||
<pre><code lang=""># zig build run
|
||
All your codebase are belong to us.
|
||
Run `zig build test` to run the tests.
|
||
</code></pre><h2 id="heading-1">「こんにちは、世界!」</h2>
|
||
<p>build.zigについては次の記事で紹介します。<br />
|
||
まず、src/main.zigを開き、全て削除し、以下のコードを書いて下さい。</p>
|
||
<pre><code lang=""><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>std<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#a2f">@import</span>(<span style="color:#b44">&#34;std&#34;</span>);<span style="color:#bbb">
|
||
</span><span style="color:#bbb"></span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>std.io<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>io;<span style="color:#bbb">
|
||
</span><span style="color:#bbb">
|
||
</span><span style="color:#bbb"></span><span style="color:#a2f;font-weight:bold">pub</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">fn</span><span style="color:#bbb"> </span>main()<span style="color:#bbb"> </span><span style="color:#666">!</span><span style="color:#0b0;font-weight:bold">void</span><span style="color:#bbb"> </span>{<span style="color:#bbb">
|
||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>stdout_file<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>io.getStdOut().writer();<span style="color:#bbb">
|
||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">var</span><span style="color:#bbb"> </span>bw<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>io.bufferedWriter(stdout_file);<span style="color:#bbb">
|
||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>stdout<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>bw.writer();<span style="color:#bbb">
|
||
</span><span style="color:#bbb">
|
||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">try</span><span style="color:#bbb"> </span>stdout.print(<span style="color:#b44">&#34;こんにちは、世界!</span><span style="color:#b62;font-weight:bold">\n</span><span style="color:#b44">&#34;</span>,<span style="color:#bbb"> </span>.{});<span style="color:#bbb">
|
||
</span><span style="color:#bbb">
|
||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">try</span><span style="color:#bbb"> </span>bw.flush();<span style="color:#bbb">
|
||
</span><span style="color:#bbb"></span>}<span style="color:#bbb">
|
||
</span></code></pre><p>保存すると、以下のエラーが表示されます:</p>
|
||
<pre><code lang=""> 1 main.zig|2 col 10| : error: expected &#39;;&#39; after declaration
|
||
</code></pre><p>はい、エラーがあると、それを修正するまでテキストエディターを閉じる事が出来ません。<br />
|
||
エラーを直しましょう!</p>
|
||
<pre><code lang=""><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>io<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>std.io;<span style="color:#bbb"> </span><span style="color:#080;font-style:italic">// ioとstd.ioを交換しましょう。
|
||
</span></code></pre><h3 id="heading-2">ビルドと実行すると</h3>
|
||
<pre><code lang=""># zig build run
|
||
こんにちは、世界!
|
||
</code></pre><h3 id="heading-3">コードの解説</h3>
|
||
<pre><code lang=""><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>std<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#a2f">@import</span>(<span style="color:#b44">&#34;std&#34;</span>);<span style="color:#bbb">
|
||
</span></code></pre><p>これにより、Zigの公式標準ライブラリを使用出来る様になります。</p>
|
||
<pre><code lang=""><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>io<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>std.io;<span style="color:#bbb">
|
||
</span></code></pre><p>これにより、ioコマンドをより簡単に実行出来る様になります。<br />
|
||
例えば、「std.io.getStdOut().writer();」を「io.getStdOut().writer();」に短縮出来ます。<br />
|
||
勿論、「const writer = std.io.getStdOut().writer();」と書く事も可能ですが、一度しか実行しないならばそれはもったいないです。</p>
|
||
<pre><code lang=""><span style="color:#a2f;font-weight:bold">pub</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">fn</span><span style="color:#bbb"> </span>main()<span style="color:#bbb"> </span><span style="color:#666">!</span><span style="color:#0b0;font-weight:bold">void</span><span style="color:#bbb"> </span>{}<span style="color:#bbb">
|
||
</span></code></pre><p>pubは公開を意味し、fnは関数を意味します。<br />
|
||
JavaやC#を使った経験があれば、「public function」の様な物です。<br />
|
||
興味深い部分は「!void」です。<br />
|
||
この「!」は「anyerror」と同じ意味を持ちます。<br />
|
||
「void」だけであれば、戻り値の型はいつでもvoidですが、「!void」の場合は「エラーがあれば、そのエラーを返し、なければvoidになる」という意味になります。<br />
|
||
とても便利だわー!!</p>
|
||
<pre><code lang=""><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">try</span><span style="color:#bbb"> </span>stdout.print(<span style="color:#b44">&#34;こんにちは、世界!</span><span style="color:#b62;font-weight:bold">\n</span><span style="color:#b44">&#34;</span>,<span style="color:#bbb"> </span>.{});<span style="color:#bbb">
|
||
</span></code></pre><p>最後に、この「try」は「このコマンドがメモリ上で安全であれば、実行してください」という意味を持ちます。<br />
|
||
また、この「.{}」は常に必要です。<br />
|
||
値を使う場合は、それを「.{}」の中に入れましょう。<br />
|
||
例えば:</p>
|
||
<pre><code lang=""><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>age<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">u8</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">20</span>;<span style="color:#bbb">
|
||
</span><span style="color:#bbb"></span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>name<span style="color:#666">:</span><span style="color:#bbb"> </span>[]<span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">u8</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;田中&#34;</span>;<span style="color:#bbb">
|
||
</span><span style="color:#bbb">
|
||
</span><span style="color:#bbb"></span><span style="color:#a2f;font-weight:bold">try</span><span style="color:#bbb"> </span>stdout.print(<span style="color:#b44">&#34;{s}さん、{d}歳になったら、大人ですよ。</span><span style="color:#b62;font-weight:bold">\n</span><span style="color:#b44">&#34;</span>,<span style="color:#bbb"> </span>.{<span style="color:#bbb"> </span>name,<span style="color:#bbb"> </span>age<span style="color:#bbb"> </span>});<span style="color:#bbb">
|
||
</span></code></pre><pre><code lang="">田中さん、20歳になったら、大人ですよ。
|
||
</code></pre><p>生成されるバイナリはzig-out/binフォルダに格納されます。</p>
|
||
<p>続く</p>
|
||
|
||
|
||
</content>
|
||
</entry>
|
||
|
||
<entry>
|
||
<id>blog/urloli-220.gmi</id>
|
||
<author><name>凛</name></author>
|
||
<title type="html">【076】URLロリ 2.2.0登場</title>
|
||
<published>2023-07-17T02:40:00Z</published>
|
||
|
||
<category term="jp"></category>
|
||
|
||
<category term="blog"></category>
|
||
|
||
<category term="ウエブ開発"></category>
|
||
|
||
<category term="076"></category>
|
||
|
||
<category term="urloli"></category>
|
||
|
||
<category term="urlロリ"></category>
|
||
|
||
<link href="gemini://technicalsuwako.moe/blog/urloli-220.gmi" rel="alternate"></link>
|
||
<content type="html">
|
||
|
||
|
||
|
||
<p>URLロリ は2.2.0にバージョンアップしました!!</p>
|
||
<h2 id="url">URLロリって何?</h2>
|
||
<p>URLロリはクッソ小さいURL短縮作成ソフトだわ〜♡</p>
|
||
<h2 id="heading">変更</h2>
|
||
<ul>
|
||
<li>ポート番号の修正</li>
|
||
<li>言語は<a href="https://gitler.moe/suwako/goliblocale">liblocale</a>化</li>
|
||
<li>複数言語対応</li>
|
||
</ul>
|
||
<h2 id="heading-1">ソースコード</h2>
|
||
<p><a href="https://gitler.moe/suwako/urloli">Gitler</a><br />
|
||
<a href="https://codeberg.org/TechnicalSuwako/urloli">Codeberg</a><br />
|
||
<a href="https://notabug.org/TechnicalSuwako/urloli">Notabug</a><br />
|
||
<a href="https://git.disroot.org/TechnicalSuwako/urloli">Disroot</a></p>
|
||
<h2 id="heading-2">公式インスタンス</h2>
|
||
<p><a href="https://urlo.li/">https://urlo.li/</a></p>
|
||
<h2 id="heading-3">ダウンロード</h2>
|
||
<p><a href="https://076.moe/repo/bin/urloli/">https://076.moe/repo/bin/urloli/</a></p>
|
||
<h2 id="heading-4">会話</h2>
|
||
<h3 id="xmpp">XMPP</h3>
|
||
<p><a href="xmpp:urloli@chat.xmpp.076.ne.jp?join">xmpp:urloli@chat.xmpp.076.ne.jp?join</a></p>
|
||
<h3 id="irc">IRC</h3>
|
||
<p>irc.076.ne.jp/6697<br />
|
||
#urloli</p>
|
||
<p>以上</p>
|
||
|
||
|
||
</content>
|
||
</entry>
|
||
|
||
|
||
</feed>
|