RSS – это формат для описания новостной ленты того или иного сайта. Позволяет подписаться на новости с разных источников и читать их в одном месте.
Это что-то вроде подписки на изменения сайта. Технология была задолго до того, как появилась кнопка “следить” в социальных сетях. Хоть эта штука довольно старая, но всё ещё продолжает пользоваться спросом у некоторой когорты пользователей. Не нужно создавать никаких аккаунтов, регистрироваться или что-то типа того. Добавил RSS фид к себе в читалку и радуешься обновлениям.
В последнее время я прям подсел на сёрфинг Интернета в поиске интересных сайтов. Нахожу как и простенькие минималистичные блоги, так и сложные очень красивые личные страницы.
Как же я рад, что благодаря RSS могу подписаться на обновления любого из сайтов, которые предлагают новостной фид.
На компьютере я настроил консольную читалку newsboat
На телефоне стоит NetNewsWire
Но с помощью RSS можно подписываться не только на блоги и новостные ленты. Умершие несколько раз раньше и очень популярные сейчас подкасты работают именно с помощью RSS. Автор подкаста сам решает, где разместить свой подкаст:
и как это сделать:
Приложения а-ля Гугл или Эпл Подкасты и являются RSS читалками, но только для одного типа контента. С помощью читалок, которые я упомянул выше (и многих других) , можно подписываться и на подкасты тоже.
Через Nitter
можно вытащить RSS ленту вашего любимого твиттерского.
Раньше это можно было сделать и через твиттера, но в какой-то момент из него исчезли RSS ленты.
Через Invidious
можно подписаться на ютюб канал и даже на отдельный плейлист.
На ютюбе пока ещё существуют RSS ленты, но не факт, что их не постигнет твиттерская участь.
Nitter
и Invidious
– это альтернативные фронт-енды,
которые убирают практически все трекеры и позволяют потреблять контент в куда
более удобном и минималистичном формате.
Мне, как человеку, который имел неосторожность назвать себя минималистом,
факт наличия таких сервисов очень приятен.
Да и Surveillance capitalism вот это всё
Не забываем и про Github
.
Здесь тоже можно подписаться на обновления коммитов и релизов, например.
Правда, я не нашёл явного способа это сделать.
Разве что в инструментах разработчика можно вбить в поиске .xml
и наткнуться на RSS фид в исходном коде страницы.
Такой хак работает и на других сайтах тоже.
Например, я не сразу понял, что генератор статических сайтов Hugo, который я использую, может собирать RSS ленты :D
К чему я всё это? Благодаря RSS меняется то, как человек потребляет контент и вообще пользуется интернетом. С RSS больше не нужно открывать сайты в надежде на обновления. Не нужно прогружать тяжелые медленные страницы. Достаточно просто вытянуть обновления ленты в RSS читалке и наслаждаться только контентом без мишуры вокруг.
Если что, newsboat
можно достать здесь https://newsboat.org
foxy написал:
Некоторые клиенты умеют искать ленты на сайте. Я пользуюсь FeedBro в браузере и там можно тыкнуть, чтобы само нашло. Не всегда, но часто находит. Недавно нашёл Livemarks он оказывается лучше находит.
Вчера, бродя по интернету, я наткнулся на https://lukesmith.xyz/updates/bringing-back-oldschool-web-pins-and-buttons/. В этом посте Luke Smith вспоминает про такую штуку, как анимированные пины, которые были популярны в старом Интернете.
Сегодня же я захотел потыкаться в GIMP и сделал анимированный пин для Микоризы.
Выглядит он так.
Нет.
Когда-то я наткнулся на статью от @bouncepaw про ортовремя.
Чтобы различать стандартную систему времени, использую приставку шайзе для текущей системы, орто для моей новой системы.
В ортовремени сутки начинаются в 0 часов. Сутки делятся на 24 часа для совместимости.
0 орточасов соответствуют 6 шайзечасам, то есть времени, когда просыпаются самые ранние жаворонки. Для сравнения, в день написания статьи я встал в 1 орточас, а за день до этого — в 2 орточаса._
У большинства людей работа начинается где-то в 3 орточаса, то есть в 9 шайзечасов. Допустим, работа длится 8 часов, до 11 орточасов. Час на дорогу, часы бьют 12 орточасов — вы дома. Прошла ровно половина суток. Всё остальное время — ваше. Делайте что хотите, можете поспать даже. А когда проснётесь, новые сутки только-только начнутся!
Я загорелся идеей и решил попробовать, да и недавно стал носить наручные
не смарт-часы со стрелками.
Сначала это выглядело примерно так:
Я постоянно считал, сколько сейчас шайзе-времени, вместо того, чтобы жить по орто-.
“Не тру, не канон”, - подумал я.
Решил эту проблему довольно просто. Перевёл время не только на наручных часах, но и вообще везде, где только можно, на 6 часов назад (в случае часов со стрелками + или - значения не имеют). Автоматически перенеслись все события в календаре в новые, теперь правильные, места. Стало удобно, ведь я уже не тратил усилия, чтобы переключиться с орто- на шайзе- и наоборот.
Единственное, что меня беспокоило – не все интернет-приложения работают по времени устройства (что логично из-за соображения безопасности и чего-то там ещё, но не укладывается в концепцию ортовремени). Когда ждал доставку, чуть не перепутал время и не подставил курьера, ведь: “Ну, я поменял время на телефоне, значит поменялось везде”.
прошло какое-то время спустя вышенаписанных строк
Ещё заметил, что мне, на самом деле, не так важно, сколько времени сейчас,
но сколько времени до какого-либо события.
Например:
Не “мне нужно выйти из дома в 10:00”,
а “мне нужно выйти из дома через 30 минут”.
И так со мной было всегда, я просто никогда об этом раньше не задумывался.
Тот, который я нашёл помимо тех, которые были упомянуты в статье Баунса.
Кажется, что концепция ортовремени не обязывает других ей придерживаться, чтобы перестать путаться и спокойно существовать в обществе.
А вот с концепцией самого удобного в мире календаря риски ошибиться сутками или даже неделей куда критичнее, чем перепутать орто- и шайзе-часы.
У меня было 2 сисколла, 40 свободных гигов для виртуалки, 12 потоков,
Linux Kernel 5.8.1 и множество статей, инструкций и документаций всех сортов и расцветок,
а также Ubuntu 20.04 LTS, vim и мои нервы.
Не то что бы это был необходимый запас для сборки. Но если начал собирать ядро, становится трудно остановиться.
Единственное что вызывало у меня опасение – это кернелспейс.
Нет ничего более беспомощного, безответственного и испорченного, чем студент, пытающийся разобраться в ядре Linux.
Я знал, что рано или поздно закончу собирать эту дрянь.
Копаться в ядре стоит прежде всего на виртуальной машине. Иначе, если что-то сломается, операционная система может просто не взлететь. Ставим образ Убунты на виртуальную машину. Я делал через Boxes, ибо так проще всего.
sudo apt update && sudo apt upgrade
sudo apt install build-essential libncurses-dev libssl-dev
libelf-dev bison flex
wget -P ~/Downloads/
https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.8.1.tar.xz
tar -xvf ~/Downloads/linux-5.8.1.tar.xz -C ~/
В системном вызове мне нужно достучаться до структуры pci_dev
,
достав любое pci-устройство, и вывести поля device и vendor в пространство пользователя.
cd ~/linux-5.8.1/
В моём случае нужно достать поля из структуры pci_dev
. Так и назовём директорию.
mkdir pci_dev
vim pci_dev/pci_dev.c
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/pci.h>
#include <linux/uaccess.h>
// Структура, которую будем передавать в пространство пользователя
struct pci_device_info {
unsigned short vendor_id;
unsigned short device_id;
};
/* Объявление системного вызова (запятые в аргументах правильные).
info: указатель на эту же структуру, но в пространстве пользователя.
*/
SYSCALL_DEFINE1(pci_dev, struct pci_device_info *, info)
{
struct pci_dev *dev = NULL;
struct pci_device_info dev_info;
dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
dev_info.device_id = dev->device;
dev_info.vendor_id = dev->vendor;
// Печатаем информацию о структуре в пространство ядра
printk(KERN_INFO "pci vendor id [%d]\n", dev_info.vendor_id);
printk(KERN_INFO "pci device id [%d]\n", dev_info.device_id);
// Передаём структуру в пространство пользователя
copy_to_user(info, &dev_info, sizeof(struct pci_device_info));
return 0;
}
Сохраняем изменения и выходим из vim`а.
vim pci_dev/Makefile
Пишем это в Makefile нашего системного вызова.
obj-y := pci_dev.o
vim Makefile
Здесь нам нужна строчка core-y
с перечислением директорий а-ля kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/
Дописываем здесь директорию с нашим системным вызовом.
Должно получиться так:
kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ pci_dev/
vim include/linux/syscalls.h
В самый конец над #endif
добавляем
struct pci_device_info;
asmlinkage long sys_pci_dev(struct pci_device_info *);
vim arch/x86/entry/syscalls/syscall_64.tbl
В самый конец таблицы с 64-битным системными вызовами пишем следующее.
440 common pci_dev sys_pci_dev
Важно соблюдать нумерацию и табы.
Здесь нам нужна стандартная конфигурация.
make menuconfig
Тыкаем в Save, а потом в Exit.
nproc
У меня их 12. Это нужно, чтобы задействовать все ядра процессора для сборки ядра операционной системы (беды с терминологией ).
make -j12
-j
- с помощью этого флага указываем, сколько задач будет исполняться одновременно
sudo make modules_install -j12
sudo make install -j12
sudo update-grub
reboot
Теперь напишем программу, которая будет делать системный вызов и выводить в стандартный поток информацию о структуре.
vim pci_dev_user.c
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
// Определяем системный вызов для простоты
#define __NR_pci_dev 440
// Наша пользовательская структура,
// которую будем заполнять с помощью системного вызова
struct pci_device_info {
unsigned short vendor_id;
unsigned short device_id;
};
// Определение функции для системного вызова
long pci_dev_syscall(struct pci_device_info *ptr)
{
return syscall(__NR_pci_dev, ptr);
}
int main()
{
// Инициализируем структуру для заполнения
struct pci_device_info result = { 0 };
// Исполняем системный вызов, в аргумент которого помещаем
// указатель на пользовательскую структуру
pci_dev_syscall(&result);
// Выводим поля структуры в стандартный поток
printf("vendor_id: %hu\n", result.vendor_id);
printf("device_id: %d\n", result.device_id);
return 0;
}
gcc -o pci_dev_user pci_dev_user.c
./pci_dev_user
> vendor_id: 32902
> device_id: 10688
dmesg
> [ 38.604541] pci vendor id [32902]
> [ 38.604544] pci device id [10688]
Работает!
syscall_info
Буду более краток, ибо процесс по сборке и написанию идентичный. Однако, чтобы достать структуру пришлось много потеть и прыгать от одной структуры к другой.
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/uaccess.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/sched/task_stack.h>
#include <linux/export.h>
#include <linux/types.h>
// Здесь структура очень маленькая,
// так что просто передаём её напрямую пользователю,
// используя определение из ptrace.h
SYSCALL_DEFINE2(syscall_info, int, pid_input,
struct syscall_info *, info)
{
printk(KERN_INFO "process's pid: %d\n", pid_input);
struct pid *pid_task = NULL;
pid_task = find_get_pid(pid_input);
struct task_struct *task = NULL;
task = get_pid_task(pid_task, PIDTYPE_PID);
struct syscall_info sys_info;
task_current_syscall(task, &sys_info);
printk(KERN_INFO "user_sp: %llu", sys_info.sp);
copy_to_user(info, &sys_info, sizeof (struct syscall_info));
return 0;
}
#include <linux/kernel.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define __NR_syscall_info 441
// Задаём описание структуры
struct seccomp_data {
int nr;
__u32 arch;
__u64 instruction_pointer;
__u64 args[6];
};
struct syscall_info {
__u64 sp;
struct seccomp_data data;
};
long syscall_info_syscall(int pid_input, struct syscall_info *ptr)
{
return syscall(__NR_syscall_info, pid_input, ptr);
}
int main(int argc, char **argv)
{
char *a = argv[1];
int pid_id = atoi(a);
printf("Pid_id: %d\n", pid_id);
struct syscall_info result;
syscall_info_syscall(pid_id, &result);
printf("Syscall_number: %d\n", result.data.nr);
printf("User Stack Pointer: %lld\n", result.sp);
return 0;
}
Pid_id: 958
Syscall_number: 7
User Stack Pointer: 140726335318048
[ 21.342638] user_sp: 140726335318048
Указатели стека идентичны, значит, структура передана верно!
Изменяем конфигурацию загрузчика, чтобы загрузиться с нужным ядром
vim /etc/default/grub
Строки ниже должны быть следующими:
GRUB_DEFAULT=0
GRUB_TIMEOUT=-1 # Чтобы была возможность выбрать нужную версию ядра
GRUB_HIDDEN_TIMEOUT=0
Изменяем конфигурацию ядра.
scripts/config --disable SYSTEM_TRUSTED_KEYS
или
scripts/config --set-str SYSTEM_TRUSTED_KEYS ""
sudo apt install dwarves