initial commit

This commit is contained in:
Nico 2021-01-27 11:02:15 +00:00
commit 92dc248455
8 changed files with 298 additions and 0 deletions

10
Makefile Normal file
View File

@ -0,0 +1,10 @@
INSTALLDIR=/run/media/nico/KOBOeReader/.adds/gemini
all: kobo-gemini update
kobo-gemini:
CGO_ENABLED=1 GOARCH=arm CC=arm-kobo-linux-gnueabihf-gcc CXX=arm-kobo-linux-gnueabihf-g++ go build
update: kobo-gemini run.sh nickel.sh
cp kobo-gemini run.sh nickel.sh ${INSTALLDIR}
chmod a+x ${INSTALLDIR}/*

2
build.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
CGO_ENABLED=1 GOARCH=arm CC=arm-kobo-linux-gnueabihf-gcc CXX=arm-kobo-linux-gnueabihf-g++ go build

13
go.mod Normal file
View File

@ -0,0 +1,13 @@
module tildegit.org/nihilazo/kobo-gemini
go 1.15
require (
git.sr.ht/~adnano/go-gemini v0.1.13
github.com/fogleman/gg v1.3.0
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/shermp/go-fbink-v2 v1.20.2
github.com/shermp/go-fbink-v2/v2 v2.21.0
github.com/shermp/go-kobo-input v0.0.0-20180928074949-be0734a2dcc6
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 // indirect
)

16
go.sum Normal file
View File

@ -0,0 +1,16 @@
git.sr.ht/~adnano/go-gemini v0.1.13 h1:vzKkkVrOzMpfJ1AAeE/PChg0Rw5Zf+9HrnwsgVxXUT4=
git.sr.ht/~adnano/go-gemini v0.1.13/go.mod h1:If1VxEWcZDrRt5FeAFnGTcM2Ud1E3BXs3VJ5rnZWKq0=
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/shermp/go-fbink-v2 v1.20.2 h1:EtRKDZwrc8fkNGDZppsYB2nxcMosYU7hqYLovMP78/4=
github.com/shermp/go-fbink-v2 v1.20.2/go.mod h1:88bOAwruwze/4JB/KW8uoyPtWm5OPa1BZEraFMHJgpQ=
github.com/shermp/go-fbink-v2/v2 v2.21.0 h1:S2Q8B5zLGo7xTGILpqkVNZB94YwkehvTmECIYkxKH04=
github.com/shermp/go-fbink-v2/v2 v2.21.0/go.mod h1:QPZ+LtEGpr7FkAwfS1AuCHXUrTJWg57PKRl4SmnzKak=
github.com/shermp/go-kobo-input v0.0.0-20180928074949-be0734a2dcc6 h1:Tf6xr3SyROl/gYEbLVVRoASIuehPrjzq1y3P7krVqlo=
github.com/shermp/go-kobo-input v0.0.0-20180928074949-be0734a2dcc6/go.mod h1:DuK6sbQLR5V3MLqWS8y+wYaFj4KIyPeNMe5HrOgRH2w=
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 h1:nfeHNc1nAqecKCy2FCy4HY+soOOe5sDLJ/gZLbx6GYI=
golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
tildegit.org/nihilazo/go-kobo-input v0.0.0-20210121201215-df5621661ac7 h1:7VnVnqyc+wmztFdkwujdIdjAEEmpAta2xGv/bvLZMXQ=

BIN
kobo-gemini Executable file

Binary file not shown.

149
main.go Normal file
View File

@ -0,0 +1,149 @@
package main
import (
//"github.com/fogleman/gg"
"github.com/shermp/go-fbink-v2/gofbink"
"github.com/shermp/go-kobo-input/koboin"
//"image"
"git.sr.ht/~adnano/go-gemini"
"git.sr.ht/~adnano/go-gemini/tofu"
"crypto/x509"
// "time"
// "bytes"
"errors"
"net/url"
"bufio"
"io/ioutil"
"fmt"
"time"
)
var (
hosts tofu.KnownHosts
hostsfile *tofu.HostWriter
scanner *bufio.Scanner
)
var height int = 1080
var width int = 1440 // TODO get from device instead of hardcoding
func trustCertificate(hostname string, cert *x509.Certificate) error { // TODO actually check certs
/*host := tofu.NewHost(hostname, cert.Raw, cert.NotAfter)
knownHost, ok := hosts.Lookup(hostname)
if ok && time.Now().Before(knownHost.Expires) {
// Check fingerprint
if bytes.Equal(knownHost.Fingerprint, host.Fingerprint) {
return nil
}
return errors.New("error: fingerprint does not match!")
}
return errors.New("error: fingerprint does not match!")*/
return nil
}
func do(req *gemini.Request, via []*gemini.Request) (*gemini.Response, error) {
client := gemini.Client{
TrustCertificate: trustCertificate,
}
resp, err := client.Do(req)
if err != nil {
return resp, err
}
switch resp.Status.Class() {
case gemini.StatusClassInput: // TODO implement input
/* input, ok := getInput(resp.Meta, resp.Status == gemini.StatusSensitiveInput)
if !ok {
break
}
req.URL.ForceQuery = true
req.URL.RawQuery = gemini.QueryEscape(input)
return do(req, via) */
case gemini.StatusClassRedirect:
via = append(via, req)
if len(via) > 5 {
return resp, errors.New("too many redirects")
}
target, err := url.Parse(resp.Meta)
if err != nil {
return resp, err
}
target = req.URL.ResolveReference(target)
redirect := *req
redirect.URL = target
return do(&redirect, via)
}
return resp, err
}
func main() {
// Framebuffer setup
fbinkOpts := gofbink.FBInkConfig{}
rOpts := gofbink.RestrictedConfig{}
fb := gofbink.New(&fbinkOpts, &rOpts)
fb.Open()
defer fb.Close()
fb.Init(&fbinkOpts)
fb.ClearScreen(&fbinkOpts)
fb.Refresh(0,0,0,0, gofbink.DitherPassthrough, &fbinkOpts)
// Touchscreen setup
touchPath := "/dev/input/event1"
t := koboin.New(touchPath, height, width)
if t == nil {
return
}
defer t.Close()
// Load known hosts file
path := "/mnt/onboard/.adds/gemini/known-hosts"
err := hosts.Load(path)
if err != nil {
fb.Println(err)
time.Sleep(1000)
}
hostsfile, err = tofu.NewHostsFile(path)
if err != nil {
fb.Println(err)
time.Sleep(1000)
}
url := "gemini://breadpunk.club/~bagel"
req, err := gemini.NewRequest(url)
if err != nil {
fb.Println(err)
time.Sleep(1000)
}
resp, err := do(req, nil)
if err != nil {
fb.Println(err)
time.Sleep(1000)
}
defer resp.Body.Close()
// Handle response
if resp.Status.Class() == gemini.StatusClassSuccess {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fb.Println(err)
}
fb.Println(string(body))
} else {
fb.Println(fmt.Sprintf("%d %s\n", resp.Status, resp.Meta))
}
for {
x, y, err := t.GetInput()
if err != nil {
continue
}
if x < 100 && y < 100 {
break
}
}
}

102
nickel.sh Executable file
View File

@ -0,0 +1,102 @@
#!/bin/sh
# This script is from koreader under AGPL-v3
PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/lib:"
# We don't need to duplicate any of the env setup from rcS, since we will only ever run this to *restart* nickel, and not bootstrap it.
# Meaning we've already got most of the necessary env from nickel itself via both our launcher (fmon/KFMon) and our own startup script.
# NOTE: LD_LIBRARY_PATH is the only late export from rcS we don't siphon in koreader.sh, for obvious reasons ;).
export LD_LIBRARY_PATH="/usr/local/Kobo"
# Reset PWD, and clear up our own custom stuff from the env while we're there, otherwise, USBMS may become very wonky on newer FW...
# shellcheck disable=SC2164
cd /
unset OLDPWD
unset LC_ALL TESSDATA_PREFIX STARDICT_DATA_DIR EXT_FONT_DIR
unset KOREADER_DIR KO_DONT_GRAB_INPUT
# Ensures fmon will restart. Note that we don't have to worry about reaping this, nickel kills on-animator.sh on start.
(
if [ "${PLATFORM}" = "freescale" ] || [ "${PLATFORM}" = "mx50-ntx" ] || [ "${PLATFORM}" = "mx6sl-ntx" ]; then
usleep 400000
fi
/etc/init.d/on-animator.sh
) &
Make sure we kill the Wi-Fi first, because nickel apparently doesn't like it if it's up... (cf. #1520)
NOTE: That check is possibly wrong on PLATFORM == freescale (because I don't know if the sdio_wifi_pwr module exists there), but we don't terribly care about that.
if grep -q "sdio_wifi_pwr" "/proc/modules"; then
killall -q -TERM restore-wifi-async.sh enable-wifi.sh obtain-ip.sh
cp -a "/etc/resolv.conf" "/tmp/resolv.ko"
old_hash="$(md5sum "/etc/resolv.conf" | cut -f1 -d' ')"
if [ -x "/sbin/dhcpcd" ]; then
env -u LD_LIBRARY_PATH dhcpcd -d -k "${INTERFACE}"
killall -q -TERM udhcpc default.script
else
killall -q -TERM udhcpc default.script dhcpcd
fi
# NOTE: dhcpcd -k waits for the signalled process to die, but busybox's killall doesn't have a -w, --wait flag,
# so we have to wait for udhcpc to die ourselves...
# NOTE: But if all is well, there *isn't* any udhcpc process or script left to begin with...
kill_timeout=0
while pkill -0 udhcpc; do
# Stop waiting after 5s
if [ ${kill_timeout} -ge 20 ]; then
break
fi
usleep 250000
kill_timeout=$((kill_timeout + 1))
done
new_hash="$(md5sum "/etc/resolv.conf" | cut -f1 -d' ')"
# Restore our network-specific resolv.conf if the DHCP client wiped it when releasing the lease...
if [ "${new_hash}" != "${old_hash}" ]; then
mv -f "/tmp/resolv.ko" "/etc/resolv.conf"
else
rm -f "/tmp/resolv.ko"
fi
wpa_cli terminate
[ "${WIFI_MODULE}" != "8189fs" ] && [ "${WIFI_MODULE}" != "8192es" ] && wlarm_le -i "${INTERFACE}" down
ifconfig "${INTERFACE}" down
# NOTE: Kobo's busybox build is weird. rmmod appears to be modprobe in disguise, defaulting to the -r flag...
# But since there's currently no modules.dep file being shipped, nor do they include the depmod applet,
# go with what the FW is doing, which is rmmod.
# c.f., #2394?
usleep 250000
rmmod "${WIFI_MODULE}"
if [ -n "${CPUFREQ_DVFS}" ]; then
echo "0" >"/sys/devices/platform/mxc_dvfs_core.0/enable"
# Leave Nickel in its usual state, don't try to use conservative
echo "userspace" >"/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
cat "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq" >"/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed"
fi
usleep 250000
rmmod sdio_wifi_pwr
fi
unset CPUFREQ_DVFS CPUFREQ_CONSERVATIVE
# Recreate Nickel's FIFO ourselves, like rcS does, because udev *will* write to it!
# Plus, we actually *do* want the stuff udev writes in there to be processed by Nickel, anyway.
rm -f "/tmp/nickel-hardware-status"
mkfifo "/tmp/nickel-hardware-status"
# Flush buffers to disk, who knows.
sync
# Handle the sdcard:
# We need to unmount it ourselves, or Nickel wigs out and shows an "unrecognized FS" popup until the next fake sd add event.
# The following udev trigger should then ensure there's a single sd add event enqueued in the FIFO for it to process,
# ensuring it gets sanely detected and remounted RO.
if [ -e "/dev/mmcblk1p1" ]; then
umount /mnt/sd
fi
# And finally, simply restart nickel.
# We don't care about horribly legacy stuff, because if people switch between nickel and KOReader in the first place, I assume they're using a decently recent enough FW version.
# Last tested on an H2O & a Forma running FW 4.7.x - 4.25.x
/usr/local/Kobo/hindenburg &
LIBC_FATAL_STDERR_=1 /usr/local/Kobo/nickel -platform kobo -skipFontLoad &
[ "${PLATFORM}" != "freescale" ] && udevadm trigger &
return 0

6
run.sh Normal file
View File

@ -0,0 +1,6 @@
#!/bin/sh
export DBUS_SESSION_BUS_ADDRESS NICKEL_HOME WIFI_MODULE LANG WIFI_MODULE_PATH INTERFACE
sync
killall -TERM nickel hindenburg sickel fickel 2>/dev/null
/mnt/onboard/.adds/gemini/kobo-gemini
exec /mnt/onboard/.adds/gemini/nickel.sh