LINUX.ORG.RU

Сообщения Spoofing

 

Как утилизировать 4 сетевых порта 1000Mbps (+3 фото)

Статьи — Администрирование

Эффективное использование нескольких сетевых портов для виртуальных машин, запущенных на сервере

( читать дальше... )

 , ,

Spoofing
()

Безмятежность

Галерея — Скриншоты

У нас в Красноярске в это время года пасмурно, погода портится, льют осенние дожди, серые тучи закрывают небо, отчего не хватает солнца, и вместе с ним нет и настроения. В Москве прохладно, но осенью, как у нас в Сибири, совсем не пахнет, а вместо этого светит солнце, днём даже пригревает. В общем, надо привыкать к новому климату.

Погода должна радовать, но старые привычки, что осенью всё серое и хочется чего-то светлого — не отпускают. Захотелось вернуться к светлым тонам в интерфейсе. На скриншоте закос под ACME (Plan9).

CRUX, FVWM с закосом под классику, — классику, по которой я уверен, уже тоскуют даже самые матёрые линуксоиды. URxvt, vim как IDE.

>>> Пустой рабочий стол

>>> Firefox, Telegram

Для разнообразия были выбраны чуть разные оттенки жёлтого в urxvt и vim. И, как можно увидеть, к использованию предлагается как тёмный (dark), так и светлый (light) стиль оформления.

~/.Xresources

URxvt.cursorColor: #a6dcf8
URxvt.scrollBar: true
URxvt.scrollBar_right: true
URxvt.scrollstyle: plain
URxvt.scrollColor: #999957

!URxvt.background: #ffffec
!URxvt.foreground: #424242

URxvt.background: #1a1a1a
URxvt.foreground: #ffffec

URxvt.color0: #424242
URxvt.color1: #b8261e
URxvt.color2: #3e8630
URxvt.color3: #7f8f29
URxvt.color4: #2a8dc5
URxvt.color5: #8888c7
URxvt.color6: #6aa7a8
URxvt.color7: #999957
URxvt.color8: #eeeea7
URxvt.color9: #f2acaa
URxvt.color10: #98ce8f
URxvt.color11: #b6b79c
URxvt.color12: #a6dcf8
URxvt.color13: #d0d1f7
URxvt.color14: #b0eced
URxvt.color15: #ffffec

~/.vim/colors/acme.vim

highlight clear 

highlight! Normal guibg=#ffffea guifg=#000000 ctermbg=230 ctermfg=232 
highlight! NonText guibg=bg guifg=#ffffea ctermbg=bg ctermfg=230
highlight! StatusLine guibg=#aeeeee guifg=#000000 gui=NONE ctermbg=159 ctermfg=232 cterm=NONE
highlight! StatusLineNC guibg=#eaffff guifg=#000000 gui=NONE ctermbg=194 ctermfg=232 cterm=NONE
highlight! WildMenu guibg=#000000 guifg=#eaffff gui=NONE ctermbg=black ctermfg=159 cterm=NONE
highlight! VertSplit guibg=#ffffea guifg=#000000 gui=NONE ctermbg=159 ctermfg=232 cterm=NONE
highlight! Folded guibg=#cccc7c guifg=fg gui=italic ctermbg=187 ctermfg=fg cterm=italic
highlight! FoldColumn guibg=#fcfcce guifg=fg ctermbg=229 ctermfg=fg
highlight! Conceal guibg=bg guifg=fg gui=NONE ctermbg=bg ctermfg=fg cterm=NONE
highlight! LineNr guibg=bg guifg=#505050 gui=italic ctermbg=bg ctermfg=239 cterm=italic
highlight! Visual guibg=fg guifg=bg ctermbg=fg ctermfg=bg
highlight! CursorLine guibg=#ffffca guifg=fg ctermbg=230 ctermfg=fg
highlight! Pmenu guibg=bg guifg=fg ctermbg=bg ctermfg=fg
highlight! PmenuSel guibg=fg guifg=bg ctermbg=fg ctermfg=bg

highlight! Statement guibg=bg guifg=fg gui=italic ctermbg=bg ctermfg=fg cterm=italic
highlight! Identifier guibg=bg guifg=fg gui=bold ctermbg=bg ctermfg=fg cterm=bold
highlight! Type guibg=bg guifg=fg gui=bold ctermbg=bg ctermfg=fg cterm=bold
highlight! PreProc guibg=bg guifg=fg gui=bold ctermbg=bg ctermfg=fg cterm=bold
highlight! Constant guibg=bg guifg=#101010 gui=bold ctermbg=bg ctermfg=233 cterm=italic
highlight! Comment guibg=bg guifg=#303030 gui=italic ctermbg=bg ctermfg=236 cterm=italic
highlight! Special guibg=bg guifg=fg gui=bold ctermbg=bg ctermfg=fg cterm=bold
highlight! SpecialKey guibg=bg guifg=fg gui=bold ctermbg=bg ctermfg=fg cterm=bold
highlight! NonText guibg=bg guifg=fg gui=bold ctermbg=bg ctermfg=fg cterm=bold
highlight! Directory guibg=bg guifg=fg gui=bold ctermbg=bg ctermfg=fg cterm=bold
highlight! link Title Directory
highlight! link MoreMsg Comment
highlight! link Question Comment

hi link vimFunction Identifier

let g:colors_name = "acme"

~/.fvwm/config

DestroyModuleConfig FvwmIconMan:*
*FvwmIconMan: UseWinList true
*FvwmIconMan: Resolution global
*FvwmIconMan: Sort id
*FvwmIconMan: Shape true
*FvwmIconMan: Tips always
*FvwmIconMan: TipsDelays 0
*FvwmIconMan: TipsFont "xft:Sans:size=8"
*FvwmIconMan: TipsFormat "%t"
*FvwmIconMan: ManagerGeometry 1x1
*FvwmIconMan: ButtonGeometry 180x25
*FvwmIconMan: MaxButtonWidth 180
*FvwmIconMan: DrawIcons always
*FvwmIconMan: ReliefThickness 1
*FvwmIconMan: Format "%t"
*FvwmIconMan: Font "xft:Sans:size=10"
*FvwmIconMan: Action Mouse 0 A ret
*FvwmIconMan: Action Mouse 1 A sendcommand IconManClick
*FvwmIconMan: Action Mouse 3 A sendcommand "Menu MenuIconOps"
*FvwmIconMan: Title ""

DestroyModuleConfig TaskBar:*
*TaskBar: Geometry $[vp.width]x32+0-0
*TaskBar: Font "xft:Sans:size=10:antialias=True"
*TaskBar: (Container)
*TaskBar: (Container(Rows 1 Columns $[vp.width]), Padding 2 2, Frame 2)
PipeRead 'echo "*TaskBar: ($(($[vp.width] - 50))x1, Container, Frame 0)"'
*TaskBar: (Swallow FvwmIconMan 'Module FvwmIconMan', Frame 0)
*TaskBar: (End)
*TaskBar: (50x1, Container, Frame 0)
*TaskBar: (Container, Frame -1)
*TaskBar: (Swallow DateTime 'Module FvwmScript FvwmScript-DateTime', Frame 0)
*TaskBar: (End)
*TaskBar: (End)
*TaskBar: (End)

>>> Просмотр (3440x1440, 145 Kb)

 , ,

Spoofing
()

rc.local через http, ftp, rsync, git?

Форум — General

хотелось бы реализовать автозапуск приложений а-ля rc.local, только получаемый из внешнего источника а-ля git.

ну казалось бы три строчки кода в тот-же rc.local добавить:

wait_inet_connection

git clone https://...

cd /project.git && ./autorun.inf

но думаю должно быть решение более изящное и интересное.

кто-нибудь сталкивался с такой задачей?

 , ,

Spoofing
()

Как ограничить количество одновременно загружаемых файлов?

Форум — Security

VDS с диском на 20гб, возможность загружать файлы размером пусть 100мб, возможность количества одновременных подключений 1000 клиентов.

А что если все они одновременно начнут загружать файл? Ну выполнять большой POST-запрос. nginx сохраняет его во временный файл, а дисковое пространство ограничено.

Пока POST-запрос не отправлен до конца, nginx не передаст его php-fpm, т.е. по сути мы имеем 1000 активных подключений, которые смеху ради поставились на паузу (ограничили скорость в 1кб) и потихоньку льют тебе файл на сервер.

И с точки зрения php ты ничего с этим сделать не сможешь, пока файл (POST) не придёт целиком, nginx не передаст его в работу на php-fpm, иначе было бы достаточно например сделать искусственное ограничение (на уровне приложения) в 10 пользователей, которые одновременно могут загружать файл.

Т.е. бэкед в этой ситуации вообще лох и ничего не может.

Поэтому такое ограничение необходимо установить на уровне nginx.

Как?

Смонтировать отдельную директорию, в виде отдельного файла (дискового образа) и когда там закончится место чтобы nginx выкидывал 50х ошибку клиенту? Чтобы место не закончилось на VDS, а в файле, клиенты всё равно будут страдать, а щито поделать...

 ,

Spoofing
()

Wayland без X?

Форум — General

Я всё могу понять, технология новая, требует обката, свежа, юна, под неё ещё ничего толком не написали, нету выбора WM на вкус и цвет, терминал какой дают, но в принципе, браузер запускается, а вся работа в терминале, в консольных приложениях, я готов пойти неудобства ради...

(chroot) /tmp/tmp.D80f2xWrcR: # prt-get depinst --test sway | grep -c xorg
28

мммм...

А зачем мне сырой Wayland с недоиксами в системе? Я уж тогда поставлю сотню пакетов xorg и не буду терпеть никаких неудобств.

Правильно понимаю, что на текущий момент невозможно иметь чистое Wayland окружение без иксовых зависимостей?

Изменится ли эта ситуация в будущем?

В тонкости-нюансы, что иксовые пакеты требует mesa, которую требует wayland, я не вдаюсь, я смотрю на итоговый результат, что Wayland это шляпа полностью зависимая от иксов.

 

Spoofing
()

Microsoft ограничила для россиян возможность обновления компьютеров до Windows 11

Форум — Talks

Собственно, сабж.

 

Spoofing
()

Я тупой, что делать?

Форум — Talks

Не могу осилить ничего сложнее bash и php, просто не понимаю ЗАЧЕМ!?

Создаю функцию, которая будет дёргать другие функции, дергаю динамические данные из массивов или базы данных, этого хватает для перекладывания файликов с места на место и создания образов и загрузки линуксов по сети, для записи и вывода статей на сайте, ну норм же.

Почитал новость о том, что в Linux приходит Rust, подумал, ну вот время для изучения C упущено, но сейчас начинается новая эпоха с Rust в ядре, чем чёрт не шутит, может стоит попробовать, авось, для ядра какие-нибудь приколюхи тоже смогу писать? НЕТ НЕ СМОГУ ПОТОМУ ЧТО Я ТУПОЙ(((((

https://doc.rust-lang.ru/book/ch03-01-variables-and-mutability.html#Затенение...

Затенение (переменных)

Я не понимаю что это и зачем это нужно.

fn main() {
    let x = 5;

    let x = x + 1;

    {
        let x = x * 2;
        println!("The value of x in the inner scope is: {x}");
    }

    println!("The value of x is: {x}");
}

Почему нельзя из main вызвать функцию, которая сделает это самое x * 2 и напишет строчку, зачем было усложнять и придумывать какое-то { }.

fn main() {
    let x = 5;

    let x = x + 1;

    x_multiple(x);

    println!("The value of x is: {x}");
}

fn x_multiple(x: i32) {
      let x = x * 2;

      println!("The value of x in the inner scope is: {x}");
}

За достоверность синтаксиса не ручаюсь.

Я ещё могу как-то понять типы данных, ну там, один байтик 255 максимальное число, два байтика уже 255 * 255 = 65025 максимальное число, четыре байтика 255 * 255 * 255 * 255... Прикольно конечно, да, что 4 байтами можно кодировать большие числа, как это делают во всяких JPEG, PNG и т.д. бинарных форматах, что можно одним символом " " (пробел) описать число 32 т.к. это 32 символ в ASCII таблице.

Структуры в расте ещё какие-то, почему нельзя обойтись обычными массивами для хранения данных.

Классы в PHP не осилил, Rust похоже тоже не осилю.

Ну и что теперь, обратно в дворники идти?

 

Spoofing
()

Почему BIGDATA это плохо

Форум — Admin

Сервер HP DL380 Gen9, RAID-контроллер P440ar, 6 SAS HDD по 18TB в массиве RAID-0, файловая система ext4, картинка.

Просто «на холодную» смонтировал диск и просто вы только посмотрите:

# time find /mnt/disk2/
/mnt/disk2/
/mnt/disk2/lost+found
/mnt/disk2/vm
/mnt/disk2/vm/CRUX-WebServer-RootServer.img
/mnt/disk2/vm/CRUX-CorePorts.img
/mnt/disk2/vm/CRUX-DocumentsAndSettings.img
/mnt/disk2/vm/old
/mnt/disk2/vm/old/CRUX-WebServer-RootServer.img
/mnt/disk2/vm/old/CRUX-Worker2.img
/mnt/disk2/vm/old/CRUX-WebServer-RootServer-www_XXXXXXXX_ru.img
/mnt/disk2/vm/old/CRUX-Worker1.img
/mnt/disk2/vm/old/CRUX-WebServer-RootServer-www_XXXXXXXX_ru.img
/mnt/disk2/vm/old/CRUX-KVM-Host-XXXXXXXX_ru.img
/mnt/disk2/vm/old/CRUX-OneGigabyte.img
/mnt/disk2/vm/old/CRUX-KVM-Host-XXXXXXXX_ru.img
/mnt/disk2/vm/old/CRUX-WebServer-RootServer-www_XXXXXXXX_ru.img

real    0m8.957s
user    0m0.002s
sys     0m0.000s

Это оставило мне глубокую душевную рану, с такими результатами, я не ожидал.

С такими результатами этот сервер не то, что под торренты или условную файлопомойку, его под просмотр аниме через DLNA использовать сомнительно, его разве что для архивных бэкапов раз в год запускать... Чувствуется, что данные находились где-то на другом континенте.

С такими результатами, приходит понимание, что существует некий предел объёма данных в принципе, который допустимо использовать в рамках одной железки. Пусть это будет 10тб. Вместо одного LFF сервера взять несколько SFF, набить их дисками и распределять хранение данных между ними по сети, использовать какой-нибудь Ceph, да даже самописанный костыль, который будет проксировать файлики с разных серверов глядя на URL: /srv1/filename, /srv2/filename, /srv3/filename — будет быстрее и лучше.

Чем тупо взять много больших дисков и всё в RAID-0, и ожидать каких-то адекватных скоростей и отклика.

Какой самый большой объём данных вы щупали? Как считаете, не лучше ли такой объём данных распределить между несколькими железками, чем всё на одной хранить?

 ,

Spoofing
()

CRUX 3.7 RC4, $USER

Форум — Talks
Index of /tmp/

../
crux-3.7-rc4.iso                                   06-Sep-2022 20:24          1171259392
crux-3.7-rc4.md5                                   06-Sep-2022 20:24                  51
crux-3.7-rc4.sha256                                06-Sep-2022 20:24                  83
rpi-newinstall.txt                                 12-Jan-2020 21:44                2374
rust#1.63.0-1.pkg.tar.xz                           02-Sep-2022 20:46           101515068

>>> Тык

 

Spoofing
()

Железячные рейд-контроллеры — всё?

Форум — Talks

Приехала, значится, корзина, на 8 (восемь) 2.5" NVMe дисков. Вы не ослышались. NVMe диски в форм-факторе обычных 2.5" твердотельных накопителей. Ещё U.2 называется разъём.

https://www.netboot.ru/20220902_164630.jpg

https://www.netboot.ru/20220902_164639.jpg

https://www.netboot.ru/20220902_164650.jpg

Прикрутил корзину, а подключается она... Подключается она... Прямиком в рейзер! И разъём сильно отличается от обычного SAS-кабеля. И цвет кабелей, не сининький, а серенький. Такие дела.

https://www.netboot.ru/20220902_165313.jpg

https://www.netboot.ru/20220902_172005.jpg

https://www.netboot.ru/20220902_172016.jpg

Вместо обычных SATA/SAS-дисков у нас теперь подключаются NVMe-диски, и подключаются напрямую к линиям PCI, минуя какой-либо хардварный рейд-контроллер.

Получается что рейд-контроллеры — всё? В скором будущем их не станет, когда основная масса перейдёт с серверных SAS-дисков на NVMe U.2 диски?

А как же резервирование, зеркалирование дисков, вот это вот всё? Это получается же только софтварным путём только решается, т.е. будущее за mdadm?

Или NVMe диски будут существовать параллельно с SAS-дисками? И если кому-то надо аниме хранить, то тот будет использовать дисковые массивы с хардварными рейдами? А новые U.2 корзины для дисков они предназначены совсем для других задач?

Что вы думаете по этому поводу?

На чём лучше собирать CRUX?

 ,

Spoofing
()

А ты уже обновил ядро Linux до 5.19.5, $USER?

Форум — Talks

 

Spoofing
()

Безлимитные мессенджеры на тарифах ОпСоСов

Форум — Talks

Здравствуйте, кто пользуется тарифами операторов сотовой связи, на которых заявлен безлимит на мессенджеры, в частности интересует Telegram — он действительно безлимитный?

Есть идея поднять торрентокачалку на VDS, а затем скриптом отправлять самому себе файлы в Telegram, и получается на тарифе с безлимитными мессенджерами такие загрузки файлов не должны тарифицироваться.

Всё верно?

Для разбиения файлов по 2Гб есть split.

 ,

Spoofing
()

Возможно ли запустить горячую копию виртуальной машины?

Форум — Admin

Инструмент значения не имеет, proxmox, libvirt или что-то ещё.

Запущена виртуальная машина, нужно запустить её уже запущенную копию.

Никаких виртуальных дисков, файлов копировать не нужно т.к. ОС загружена в памяти.

Такое возможно?

 

Spoofing
()

CRUX 3.7 RC2

Форум — Talks

УРА! УРА! УРА!

ДРУЗЬЯ! Новый релиз CRUX 3.7 вышел из стадии глубокого тестирования, пакетная база заморожена, а это значит... Это значит, что мы теперь можем более точно увидеть diff нового выпуска этого замурррчательного дистрибутива CRUX 3.7! УРА!

>>> CRUX 3.7 RC2 (1.1GB) — Скачать официальную сборку CRUX 3.7 RC2 с сайта автора.

Но у нас свой, особый путь, за что мы все так любим CRUX — за сорц-базед и красоту дистрибутива в своей простоте, в том числе за счёт элементарной пересборки пакетной базы. prt-get update -fr `prt-get listinst`

Поэтому... Поэтому прямо сейчас.

https://www.netboot.ru/Screenshot_2022-07-28_08-45-28.png — Прямо сейчас я с пылу-жару собираю новенькую пакетную базу на двух AMD EPYC 7742 [128 / 256] загрузившись в tmpfs!

>>> Скачать LIVE ISO (260MB) — Загрузочный ISO собранный при помощи моего booty, на последнем ядре Linux 5.18.14, который загрузит свеженький CRUX 3.7 прямо в tmpfs или overlayfs+squashfs на ваш выбор!

На секундочку, у меня есть последний CRUX 3.6 который мы хотим обновить до CRUX 3.7, какие различия версий пакетов?

# ports -d
Collection  Name                Port      Installed
core        bash                5.1.16-2  5.1.16-1
core        binutils            2.38-1    2.35.2-1
core        dhcpcd              9.4.1-2   9.4.1-1
core        exim                4.96-1    4.95-1
core        filesystem          3.7-2     3.6-2
core        gcc                 12.1.0-1  10.4.0-1
core        glibc               2.35-2    2.32-7
core        glibc-32            2.35-1    2.32-7
core        less                608-1     590-1
core        libffi              3.4.2-1   3.3-1
core        libnsl              2.0.0-1   1.3.0-1
core        libtirpc            1.3.2-2   1.3.2-1
core        mlocate             0.26-3    0.26-2
core        openssl             3.0.5-1   1.1.1q-1
core        perl                5.36.0-1  5.32.1-1
core        pkgutils            5.40.9-1  5.40.7-1
core        ports               1.6-3     1.6-2
core        procps              4.0.0-1   3.3.17-1
core        prt-get             5.19.6-1  5.19.5-2
core        python3             3.10.5-1  3.9.13-1
core        python3-setuptools  63.1.0-1  63.2.0-1
core        rc                  2.32-2    2.31-3
core        rdate               0.10-1    0.9-1
core        signify             0.10-1    20200707-1
opt         wget                1.21.2-1  1.21.3-1

Более детально посмотрим различия CRUX 3.6 и грядущего CRUX 3.7!

# ls /tmp/tmp.O3X39q7qQf/usr/ports/core/ > /tmp/3.7
# ls ports-3.6.1/core/ > /tmp/3.6
# diff /tmp/3.6 /tmp/3.7 
12a13
> cmake
20a22
> dumb_runtime_dir
46a49,50
> jansson
> jsoncpp
52a57
> libedit
54a60
> libmnl
56a63,64
> libnftnl
> libnghttp2
58a67
> libpcre2
62a72
> libuv
63a74
> lzlib
68a80
> meson
72a85,86
> nftables
> ninja
78c92
< pkg-config
---
> pkgconf
84a99
> python3-setuptools
87a103
> rhash

Добавлено в core:

  • cmake
  • dumb_runtime_dir
  • jansson
  • jsoncpp
  • libedit
  • libmnl
  • libnftnl
  • libnghttp2
  • libpcre2
  • libuv
  • lzlib
  • meson
  • nftables
  • ninja
  • pkgconf
  • python3-setuptools
  • rhash

Удалено из core:

  • pkg-config
  • wget

Насколько же новый CRUX 3.7 стал жирнее в сравнении с предыдущим CRUX 3.6?

Установим оба!

Правила следующие: установки одного core недостаточно для работы CRUX, если речь не идёт об chroot, мы же хотим загружаться в установленную систему? Поэтому ставить мы будем не только core, а дополнительно возьмём загрузчик grub2 в качестве обязательного к установке пакета.

CRUX 3.6

# mkdir /tmp/crux36 ; mount -t tmpfs tmpfs /tmp/crux36 ; mkdir -p /tmp/crux36/var/lib/pkg ; touch /tmp/crux36/var/lib/pkg/db ; for pkg in ports-3.6.1/*/*/*.pkg.tar.xz ; do echo Install $pkg ... ; pkgadd --root /tmp/crux36 $pkg ; done
Install ports-3.6.1/core/acl/acl#2.3.1-1.pkg.tar.xz ...         
Install ports-3.6.1/core/attr/attr#2.5.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/autoconf/autoconf#2.71-1.pkg.tar.xz ...
Install ports-3.6.1/core/automake/automake#1.16.5-1.pkg.tar.xz ...
Install ports-3.6.1/core/bash/bash#5.1.16-1.pkg.tar.xz ... 
Install ports-3.6.1/core/bc/bc#1.07.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/binutils/binutils#2.35.2-1.pkg.tar.xz ...
Install ports-3.6.1/core/bison/bison#3.8.2-1.pkg.tar.xz ...       
Install ports-3.6.1/core/bzip2/bzip2#1.0.8-3.pkg.tar.xz ...     
Install ports-3.6.1/core/ca-certificates/ca-certificates#20220719-1.pkg.tar.xz ...    
Install ports-3.6.1/core/coreutils/coreutils#9.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/cpio/cpio#2.13-2.pkg.tar.xz ...             
Install ports-3.6.1/core/curl/curl#7.84.0-1.pkg.tar.xz ...       
Install ports-3.6.1/core/dash/dash#0.5.11.5-1.pkg.tar.xz ...    
Install ports-3.6.1/core/db/db#5.3.28-2.pkg.tar.xz ...
Install ports-3.6.1/core/dcron/dcron#4.5-3.pkg.tar.xz ...
Install ports-3.6.1/core/dhcpcd/dhcpcd#9.4.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/diffutils/diffutils#3.8-1.pkg.tar.xz ...
Install ports-3.6.1/core/e2fsprogs/e2fsprogs#1.46.5-1.pkg.tar.xz ...
Install ports-3.6.1/core/ed/ed#1.18-1.pkg.tar.xz ...      
Install ports-3.6.1/core/elfutils/elfutils#0.187-1.pkg.tar.xz ...
Install ports-3.6.1/core/eudev/eudev#3.2.11-1.pkg.tar.xz ...
Install ports-3.6.1/core/exim/exim#4.95-1.pkg.tar.xz ...
Install ports-3.6.1/core/expat/expat#2.4.8-1.pkg.tar.xz ...
Install ports-3.6.1/core/file/file#5.42-1.pkg.tar.xz ... 
Install ports-3.6.1/core/filesystem/filesystem#3.6-2.pkg.tar.xz ...
Install ports-3.6.1/core/findutils/findutils#4.9.0-1.pkg.tar.xz ...
Install ports-3.6.1/core/flex/flex#2.6.4-2.pkg.tar.xz ...        
Install ports-3.6.1/core/gawk/gawk#5.1.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/gcc/gcc#10.4.0-1.pkg.tar.xz ...         
Install ports-3.6.1/core/gdbm/gdbm#1.23-1.pkg.tar.xz ...     
Install ports-3.6.1/core/gettext/gettext#0.21-1.pkg.tar.xz ...
Install ports-3.6.1/core/glibc-32/glibc-32#2.32-7.pkg.tar.xz ...
Install ports-3.6.1/core/glibc/glibc#2.32-7.pkg.tar.xz ...                           
Install ports-3.6.1/core/gperf/gperf#3.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/grep/grep#3.7-1.pkg.tar.xz ...
Install ports-3.6.1/core/groff/groff#1.22.4-1.pkg.tar.xz ...
Install ports-3.6.1/core/gzip/gzip#1.12-1.pkg.tar.xz ...
Install ports-3.6.1/core/hdparm/hdparm#9.64-1.pkg.tar.xz ...
Install ports-3.6.1/core/httpup/httpup#0.5.0-1.pkg.tar.xz ...
Install ports-3.6.1/core/iana-etc/iana-etc#20220719-1.pkg.tar.xz ...
Install ports-3.6.1/core/inetutils/inetutils#2.3-1.pkg.tar.xz ...
Install ports-3.6.1/core/iproute2/iproute2#5.18.0-1.pkg.tar.xz ...
Install ports-3.6.1/core/iptables/iptables#1.8.8-1.pkg.tar.xz ...
Install ports-3.6.1/core/kbd/kbd#2.5.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/kmod/kmod#30-1.pkg.tar.xz ...
Install ports-3.6.1/core/less/less#590-1.pkg.tar.xz ...
Install ports-3.6.1/core/libarchive/libarchive#3.6.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/libcap/libcap#2.65-1.pkg.tar.xz ...
Install ports-3.6.1/core/libdevmapper/libdevmapper#1.02.185-1.pkg.tar.xz ...
Install ports-3.6.1/core/libffi/libffi#3.3-1.pkg.tar.xz ...
Install ports-3.6.1/core/libgmp/libgmp#6.2.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/libmpc/libmpc#1.2.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/libmpfr/libmpfr#4.1.0-1.pkg.tar.xz ...
Install ports-3.6.1/core/libnsl/libnsl#1.3.0-1.pkg.tar.xz ...
Install ports-3.6.1/core/libpcre/libpcre#8.45-1.pkg.tar.xz ...
Install ports-3.6.1/core/libpipeline/libpipeline#1.5.6-1.pkg.tar.xz ...
Install ports-3.6.1/core/libtirpc/libtirpc#1.3.2-1.pkg.tar.xz ...
Install ports-3.6.1/core/libtool/libtool#2.4.7-1.pkg.tar.xz ...
Install ports-3.6.1/core/libusb/libusb#1.0.26-1.pkg.tar.xz ...
Install ports-3.6.1/core/linux-pam/linux-pam#1.5.2-3.pkg.tar.xz ...
Install ports-3.6.1/core/lzo/lzo#2.10-1.pkg.tar.xz ...
Install ports-3.6.1/core/m4/m4#1.4.19-1.pkg.tar.xz ...
Install ports-3.6.1/core/make/make#4.3-1.pkg.tar.xz ...
Install ports-3.6.1/core/man-db/man-db#2.10.2-1.pkg.tar.xz ...
Install ports-3.6.1/core/man-pages/man-pages#5.13-1.pkg.tar.xz ...
Install ports-3.6.1/core/mlocate/mlocate#0.26-2.pkg.tar.xz ...
Install ports-3.6.1/core/mpdecimal/mpdecimal#2.5.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/nasm/nasm#2.15.05-1.pkg.tar.xz ...
Install ports-3.6.1/core/ncurses/ncurses#6.3-1.pkg.tar.xz ...
Install ports-3.6.1/core/openssh/openssh#9.0p1-1.pkg.tar.xz ...
Install ports-3.6.1/core/openssl/openssl#1.1.1q-1.pkg.tar.xz ...
Install ports-3.6.1/core/patch/patch#2.7.6.17-9c98-1.pkg.tar.xz ...
Install ports-3.6.1/core/pciutils/pciutils#3.8.0-1.pkg.tar.xz ...
Install ports-3.6.1/core/perl/perl#5.32.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/pkg-config/pkg-config#0.29.2-1.pkg.tar.xz ...
Install ports-3.6.1/core/pkgutils/pkgutils#5.40.7-1.pkg.tar.xz ...
Install ports-3.6.1/core/ports/ports#1.6-2.pkg.tar.xz ...
Install ports-3.6.1/core/procps/procps#3.3.17-1.pkg.tar.xz ...
Install ports-3.6.1/core/prt-get/prt-get#5.19.5-2.pkg.tar.xz ...
Install ports-3.6.1/core/psmisc/psmisc#23.5-1.pkg.tar.xz ...
Install ports-3.6.1/core/python3/python3#3.9.13-1.pkg.tar.xz ...
Install ports-3.6.1/core/rc/rc#2.31-3.pkg.tar.xz ...
Install ports-3.6.1/core/rdate/rdate#0.9-1.pkg.tar.xz ...
Install ports-3.6.1/core/readline/readline#8.1.2-1.pkg.tar.xz ...
Install ports-3.6.1/core/rsync/rsync#3.2.4-1.pkg.tar.xz ...
Install ports-3.6.1/core/sed/sed#4.8-1.pkg.tar.xz ...
Install ports-3.6.1/core/shadow/shadow#4.11.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/signify/signify#20200707-1.pkg.tar.xz ...
Install ports-3.6.1/core/sqlite3/sqlite3#3.39.2-1.pkg.tar.xz ...
Install ports-3.6.1/core/start-stop-daemon/start-stop-daemon#20210417-1.pkg.tar.xz ...
Install ports-3.6.1/core/sudo/sudo#1.9.11p3-1.pkg.tar.xz ...
Install ports-3.6.1/core/sysfsutils/sysfsutils#2.1.1-1.pkg.tar.xz ...
Install ports-3.6.1/core/sysklogd/sysklogd#2.4.0-1.pkg.tar.xz ...
Install ports-3.6.1/core/sysvinit/sysvinit#3.04-1.pkg.tar.xz ...
Install ports-3.6.1/core/tar/tar#1.34-1.pkg.tar.xz ...
Install ports-3.6.1/core/time/time#1.9-1.pkg.tar.xz ...
Install ports-3.6.1/core/tzdata/tzdata#2022a-1.pkg.tar.xz ...
Install ports-3.6.1/core/usbutils/usbutils#014-1.pkg.tar.xz ...
Install ports-3.6.1/core/util-linux/util-linux#2.38-1.pkg.tar.xz ...
Install ports-3.6.1/core/vim/vim#9.0.0054-1.pkg.tar.xz ...
Install ports-3.6.1/core/wget/wget#1.21.3-1.pkg.tar.xz ...
Install ports-3.6.1/core/which/which#2.21-2.pkg.tar.xz ...
Install ports-3.6.1/core/xz/xz#5.2.5-1.pkg.tar.xz ...
Install ports-3.6.1/core/zlib/zlib#1.2.12-1.pkg.tar.xz ...
Install ports-3.6.1/core/zstd/zstd#1.5.2-1.pkg.tar.xz ...
Install ports-3.6.1/opt/fakeroot/fakeroot#1.29-1.pkg.tar.xz ...
Install ports-3.6.1/opt/freetype/freetype#2.12.1-1.pkg.tar.xz ...
Install ports-3.6.1/opt/grub2-efi/grub2-efi#2.06-1.pkg.tar.xz ...
Install ports-3.6.1/opt/grub2/grub2#2.06-2.pkg.tar.xz ...
Install ports-3.6.1/opt/iputils/iputils#20211215-1.pkg.tar.xz ...
Install ports-3.6.1/opt/libpng/libpng#1.6.37-1.pkg.tar.xz ...
Install ports-3.6.1/opt/meson/meson#0.63.0-1.pkg.tar.xz ...
Install ports-3.6.1/opt/ninja/ninja#1.11.0-1.pkg.tar.xz ...
Install ports-3.6.1/opt/python3-setuptools/python3-setuptools#63.2.0-1.pkg.tar.xz ...
# df -h /tmp/crux36
Filesystem      Size  Used Avail Use% Mounted on
tmpfs            40G  761M   39G   2% /tmp/crux36

761МБ занимает обновлённый CRUX 3.6 в установленном виде!

CRUX 3.7

# mkdir /tmp/crux37 ; mount -t tmpfs tmpfs /tmp/crux37 ; mkdir -p /tmp/crux37/var/lib/pkg ; touch /tmp/crux37/var/lib/pkg/db ; for pkg in ports-3.7/*/*/*.pkg.tar.xz ; do echo Install $pkg ... ; pkgadd --root /tmp/crux37 $pkg ; done

Install ports-3.7/core/acl/acl#2.3.1-1.pkg.tar.xz ...      
Install ports-3.7/core/attr/attr#2.5.1-1.pkg.tar.xz ...        
Install ports-3.7/core/autoconf/autoconf#2.71-1.pkg.tar.xz ...
Install ports-3.7/core/automake/automake#1.16.5-1.pkg.tar.xz ...
Install ports-3.7/core/bash/bash#5.1.16-2.pkg.tar.xz ...     
Install ports-3.7/core/bc/bc#1.07.1-1.pkg.tar.xz ...             
Install ports-3.7/core/binutils/binutils#2.38-1.pkg.tar.xz ... 
Install ports-3.7/core/bison/bison#3.8.2-1.pkg.tar.xz ...
Install ports-3.7/core/bzip2/bzip2#1.0.8-3.pkg.tar.xz ...    
Install ports-3.7/core/ca-certificates/ca-certificates#20220719-1.pkg.tar.xz ...
Install ports-3.7/core/cmake/cmake#3.23.2-1.pkg.tar.xz ...
Install ports-3.7/core/coreutils/coreutils#9.1-1.pkg.tar.xz ...
Install ports-3.7/core/cpio/cpio#2.13-2.pkg.tar.xz ...        
Install ports-3.7/core/curl/curl#7.84.0-1.pkg.tar.xz ...  
Install ports-3.7/core/dash/dash#0.5.11.5-1.pkg.tar.xz ...                          
Install ports-3.7/core/db/db#5.3.28-2.pkg.tar.xz ...          
Install ports-3.7/core/dcron/dcron#4.5-3.pkg.tar.xz ...
Install ports-3.7/core/dhcpcd/dhcpcd#9.4.1-2.pkg.tar.xz ...
Install ports-3.7/core/diffutils/diffutils#3.8-1.pkg.tar.xz ...
Install ports-3.7/core/dumb_runtime_dir/dumb_runtime_dir#1.0.4-1.pkg.tar.xz ...
Install ports-3.7/core/e2fsprogs/e2fsprogs#1.46.5-1.pkg.tar.xz ...
Install ports-3.7/core/ed/ed#1.18-1.pkg.tar.xz ...
Install ports-3.7/core/elfutils/elfutils#0.187-1.pkg.tar.xz ...
Install ports-3.7/core/eudev/eudev#3.2.11-1.pkg.tar.xz ...
Install ports-3.7/core/exim/exim#4.96-1.pkg.tar.xz ...
Install ports-3.7/core/expat/expat#2.4.8-1.pkg.tar.xz ...
Install ports-3.7/core/file/file#5.42-1.pkg.tar.xz ...
Install ports-3.7/core/filesystem/filesystem#3.7-2.pkg.tar.xz ...
Install ports-3.7/core/findutils/findutils#4.9.0-1.pkg.tar.xz ...
Install ports-3.7/core/flex/flex#2.6.4-2.pkg.tar.xz ...
Install ports-3.7/core/gawk/gawk#5.1.1-1.pkg.tar.xz ...
Install ports-3.7/core/gcc/gcc#12.1.0-1.pkg.tar.xz ...
Install ports-3.7/core/gdbm/gdbm#1.23-1.pkg.tar.xz ...
Install ports-3.7/core/gettext/gettext#0.21-1.pkg.tar.xz ...
Install ports-3.7/core/glibc-32/glibc-32#2.35-1.pkg.tar.xz ...
Install ports-3.7/core/glibc/glibc#2.35-2.pkg.tar.xz ...
Install ports-3.7/core/gperf/gperf#3.1-1.pkg.tar.xz ...
Install ports-3.7/core/grep/grep#3.7-1.pkg.tar.xz ...
Install ports-3.7/core/groff/groff#1.22.4-1.pkg.tar.xz ...
Install ports-3.7/core/gzip/gzip#1.12-1.pkg.tar.xz ...
Install ports-3.7/core/hdparm/hdparm#9.64-1.pkg.tar.xz ...
Install ports-3.7/core/httpup/httpup#0.5.0-1.pkg.tar.xz ...
Install ports-3.7/core/iana-etc/iana-etc#20220719-1.pkg.tar.xz ...
Install ports-3.7/core/inetutils/inetutils#2.3-1.pkg.tar.xz ...
Install ports-3.7/core/iproute2/iproute2#5.18.0-1.pkg.tar.xz ...
Install ports-3.7/core/iptables/iptables#1.8.8-1.pkg.tar.xz ...
Install ports-3.7/core/jansson/jansson#2.14-1.pkg.tar.xz ...
Install ports-3.7/core/jsoncpp/jsoncpp#1.9.5-1.pkg.tar.xz ...
Install ports-3.7/core/kbd/kbd#2.5.1-1.pkg.tar.xz ...
Install ports-3.7/core/kmod/kmod#30-1.pkg.tar.xz ...
Install ports-3.7/core/less/less#608-1.pkg.tar.xz ...
Install ports-3.7/core/libarchive/libarchive#3.6.1-1.pkg.tar.xz ...
Install ports-3.7/core/libcap/libcap#2.65-1.pkg.tar.xz ...
Install ports-3.7/core/libdevmapper/libdevmapper#1.02.185-1.pkg.tar.xz ...
Install ports-3.7/core/libedit/libedit#20210910_3.1-1.pkg.tar.xz ...
Install ports-3.7/core/libffi/libffi#3.4.2-1.pkg.tar.xz ...
Install ports-3.7/core/libgmp/libgmp#6.2.1-1.pkg.tar.xz ...
Install ports-3.7/core/libmnl/libmnl#1.0.5-1.pkg.tar.xz ...
Install ports-3.7/core/libmpc/libmpc#1.2.1-1.pkg.tar.xz ...
Install ports-3.7/core/libmpfr/libmpfr#4.1.0-1.pkg.tar.xz ...
Install ports-3.7/core/libnftnl/libnftnl#1.2.2-1.pkg.tar.xz ...
Install ports-3.7/core/libnghttp2/libnghttp2#1.48.0-1.pkg.tar.xz ...
Install ports-3.7/core/libnsl/libnsl#2.0.0-1.pkg.tar.xz ...
Install ports-3.7/core/libpcre/libpcre#8.45-1.pkg.tar.xz ...
Install ports-3.7/core/libpcre2/libpcre2#10.40-1.pkg.tar.xz ...
Install ports-3.7/core/libpipeline/libpipeline#1.5.6-1.pkg.tar.xz ...
Install ports-3.7/core/libtirpc/libtirpc#1.3.2-2.pkg.tar.xz ...
Install ports-3.7/core/libtool/libtool#2.4.7-1.pkg.tar.xz ...
Install ports-3.7/core/libusb/libusb#1.0.26-1.pkg.tar.xz ...
Install ports-3.7/core/libuv/libuv#1.44.1-1.pkg.tar.xz ...
Install ports-3.7/core/linux-pam/linux-pam#1.5.2-3.pkg.tar.xz ...
Install ports-3.7/core/lzlib/lzlib#1.12-1.pkg.tar.xz ...
Install ports-3.7/core/lzo/lzo#2.10-1.pkg.tar.xz ...
Install ports-3.7/core/m4/m4#1.4.19-1.pkg.tar.xz ...
Install ports-3.7/core/make/make#4.3-1.pkg.tar.xz ...
Install ports-3.7/core/man-db/man-db#2.10.2-1.pkg.tar.xz ...
Install ports-3.7/core/man-pages/man-pages#5.13-1.pkg.tar.xz ...
Install ports-3.7/core/meson/meson#0.63.0-1.pkg.tar.xz ...
Install ports-3.7/core/mlocate/mlocate#0.26-3.pkg.tar.xz ...
Install ports-3.7/core/mpdecimal/mpdecimal#2.5.1-1.pkg.tar.xz ...
Install ports-3.7/core/nasm/nasm#2.15.05-1.pkg.tar.xz ...
Install ports-3.7/core/ncurses/ncurses#6.3-1.pkg.tar.xz ...
Install ports-3.7/core/nftables/nftables#1.0.4-1.pkg.tar.xz ...
Install ports-3.7/core/ninja/ninja#1.11.0-1.pkg.tar.xz ...
Install ports-3.7/core/openssh/openssh#9.0p1-1.pkg.tar.xz ...
Install ports-3.7/core/openssl/openssl#3.0.5-1.pkg.tar.xz ...
Install ports-3.7/core/patch/patch#2.7.6.17-9c98-1.pkg.tar.xz ...
Install ports-3.7/core/pciutils/pciutils#3.8.0-1.pkg.tar.xz ...
Install ports-3.7/core/perl/perl#5.36.0-1.pkg.tar.xz ...
Install ports-3.7/core/pkgconf/pkgconf#1.8.0-1.pkg.tar.xz ...
Install ports-3.7/core/pkgutils/pkgutils#5.40.9-1.pkg.tar.xz ...
Install ports-3.7/core/ports/ports#1.6-3.pkg.tar.xz ...
Install ports-3.7/core/procps/procps#4.0.0-1.pkg.tar.xz ...
Install ports-3.7/core/prt-get/prt-get#5.19.6-1.pkg.tar.xz ...
Install ports-3.7/core/psmisc/psmisc#23.5-1.pkg.tar.xz ...
Install ports-3.7/core/python3-setuptools/python3-setuptools#63.1.0-1.pkg.tar.xz ...
Install ports-3.7/core/python3/python3#3.10.5-1.pkg.tar.xz ...
Install ports-3.7/core/rc/rc#2.32-2.pkg.tar.xz ...
Install ports-3.7/core/rdate/rdate#0.10-1.pkg.tar.xz ...
Install ports-3.7/core/readline/readline#8.1.2-1.pkg.tar.xz ...
Install ports-3.7/core/rhash/rhash#1.4.3-1.pkg.tar.xz ...
Install ports-3.7/core/rsync/rsync#3.2.4-1.pkg.tar.xz ...
Install ports-3.7/core/sed/sed#4.8-1.pkg.tar.xz ...
Install ports-3.7/core/shadow/shadow#4.11.1-1.pkg.tar.xz ...
Install ports-3.7/core/signify/signify#0.10-1.pkg.tar.xz ...
Install ports-3.7/core/sqlite3/sqlite3#3.39.2-1.pkg.tar.xz ...
Install ports-3.7/core/start-stop-daemon/start-stop-daemon#20210417-1.pkg.tar.xz ...
Install ports-3.7/core/sudo/sudo#1.9.11p3-1.pkg.tar.xz ...
Install ports-3.7/core/sysfsutils/sysfsutils#2.1.1-1.pkg.tar.xz ...
Install ports-3.7/core/sysklogd/sysklogd#2.4.0-1.pkg.tar.xz ...
Install ports-3.7/core/sysvinit/sysvinit#3.04-1.pkg.tar.xz ...
Install ports-3.7/core/tar/tar#1.34-1.pkg.tar.xz ...
Install ports-3.7/core/time/time#1.9-1.pkg.tar.xz ...
Install ports-3.7/core/tzdata/tzdata#2022a-1.pkg.tar.xz ...
Install ports-3.7/core/usbutils/usbutils#014-1.pkg.tar.xz ...
Install ports-3.7/core/util-linux/util-linux#2.38-1.pkg.tar.xz ...
Install ports-3.7/core/vim/vim#9.0.0054-1.pkg.tar.xz ...
Install ports-3.7/core/which/which#2.21-2.pkg.tar.xz ...
Install ports-3.7/core/xz/xz#5.2.5-1.pkg.tar.xz ...
Install ports-3.7/core/zlib/zlib#1.2.12-1.pkg.tar.xz ...
Install ports-3.7/core/zstd/zstd#1.5.2-1.pkg.tar.xz ...
Install ports-3.7/opt/fakeroot/fakeroot#1.29-1.pkg.tar.xz ...
Install ports-3.7/opt/freetype/freetype#2.12.1-1.pkg.tar.xz ...
Install ports-3.7/opt/grub2-efi/grub2-efi#2.06-1.pkg.tar.xz ...
Install ports-3.7/opt/grub2/grub2#2.06-2.pkg.tar.xz ...
Install ports-3.7/opt/libpng/libpng#1.6.37-1.pkg.tar.xz ...
# df -h /tmp/crux37
Filesystem      Size  Used Avail Use% Mounted on
tmpfs            40G  833M   39G   3% /tmp/crux37

833M занимает последний CRUX 3.7 в установленном виде!

Даже не смотря на то, что часть ключевых пакетов из opt была перемещена в core, форы новому CRUX 3.7 это не дало.

Факт! CRUX 3.7 стал жирнее на 72 мегабайта!

Но это ещё не всё, давайте проведём другой более интересный эксперимент, всё таки нам нужно установить CRUX как операционную систему.

Для этого мы создадим образ виртуальной машины размером ровно 1,000,000,000 Байт == 1 ГБайт! Поместится ли наш жирненький пингвин в ней?

Почему выбран именно такой размер файла образа? Да всё просто. Для установки системы на VDS намного проще сперва развернуть систему локально в виртуальной машине, настроить её, а затем этот образ с системой целиком залить по сети на диск VDS, используя команду wget -qO - site/raw_image | dd of=/dev/vda status=progress, поэтому в наших интересах получить оптимальный размер для такого образа диска.

Почему жирненький пингвин может не поместиться? Потому что 1 Гбайт будет занимать не столько сам пингвин, сколько мета-информация о разделах диска, файловая система и тому подобное. Может и не влезть. Да.

И так, погнали!

# qemu-img create -f raw vm/CRUX-3-6.img 1000000000
Formatting 'vm/CRUX-3-6.img', fmt=raw size=1000000000
# qemu-img create -f raw vm/CRUX-3-7.img 1000000000
Formatting 'vm/CRUX-3-7.img', fmt=raw size=1000000000
# ls -la vm/
total 81261288
drwxr-xr-x 3 root root        4096 Jul 28 06:40 .
drwxr-x--- 9 root root        4096 Jul 27 13:24 ..
-rw-r--r-- 1 root root  1000000000 Jul 28 06:41 CRUX-3-6.img
-rw-r--r-- 1 root root  1000000000 Jul 28 06:41 CRUX-3-7.img
-rw-r--r-- 1 root root 30000000000 Jul 28 06:41 CRUX-CorePorts.img
-rw-r--r-- 1 root root 50000000000 Jul 28 06:35 CRUX-DocumentsAndSettings.img
-rw-r--r-- 1 root root 10000000000 Jul 19 08:37 CRUX-WebServer-RootServer.img
drwxr-xr-x 2 root root        4096 Jul 18 14:37 old

Абсолютно все те же самые пакеты будут установлены в виртуальных машинах.

Произведём установку CRUX 3.6 и CRUX 3.7 на образы виртуалок как в chroot, а затем установим загрузчик grub2 и подготовим образы дисков к загрузке внутри уже собственных виртуальных машин!

# qemu-system-x86_64                           \
  -enable-kvm                                  \
  -smp $(nproc)                                \
  -m 12G                                       \
  -nic tap,ifname=tap1,mac=52:54:00:00:00:01   \
  -daemonize                                   \
  -vnc :0,to=99,id=default                     \
  -drive file=vm/CRUX-CorePorts.img,format=raw \
  -drive file=vm/CRUX-3-6.img,format=raw       \
  -drive file=vm/CRUX-3-7.img,format=raw
VNC server running on 0.0.0.0:5900

Для этого я запускаю свою основную виртуалку с CRUX, куда подключаю диски, на которые будут установлены другие системы.

Зайдём на виртуалку, разметим диски, создадим один корневой раздел под ext4.

# fdisk -l /dev/sdb /dev/sdc
Disk /dev/sdb: 953.67 MiB, 1000000000 bytes, 1953125 sectors

Device     Boot Start     End Sectors   Size Id Type
/dev/sdb1  *     2048 1953124 1951077 952.7M 83 Linux


Disk /dev/sdc: 953.67 MiB, 1000000000 bytes, 1953125 sectors

Device     Boot Start     End Sectors   Size Id Type
/dev/sdc1  *     2048 1953124 1951077 952.7M 83 Linux

Обратите внимание! В реальности 952M нам доступно, а мы ещё даже не создали файловую систему.

# mke2fs -t ext4 /dev/sdb1
# mount /dev/sdb1 /mnt
# df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1       920M   24K  856M   1% /mnt

Уже 856M нам осталось доступно!

# mkdir -p /mnt/var/lib/pkg ; touch /mnt/var/lib/pkg/db ; for pkg in ports-3.6.1/*/*/*.pkg.tar.xz ; do pkgadd -r /mnt $pkg ; done
# df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1       920M  766M   91M  90% /mnt

Вот и приехали!

CRUX 3.6, из одного гигабайта (1,000,000,000 байт) образа диска у нас осталось 91 мегабайт свободного пространства, это пока ещё без ядра.

Проделаем тоже самое с CRUX 3.7.

# mke2fs -t ext4 /dev/sdc1
# mount /dev/sdc1 /mnt
# mkdir -p /mnt/var/lib/pkg ; touch /mnt/var/lib/pkg/db ; for pkg in ports-3.7/*/*/*.pkg.tar.xz ; do pkgadd -r /mnt $pkg ; done
# df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdc1       920M  838M   18M  98% /mnt

Установленный CRUX 3.7 на диск размером 1,000,000,000 байт оставил нам всего 18 мегабайт свободного пространства!

Для обеих систем соберём последнее ванильное ядро Linux 5.18.14

# wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.18.14.tar.xz
# tar xf linux-5.18.14.tar.xz
# cd linux-5.18.14
# make mrproper
# make defconfig
# make kvm_guest.config
# scripts/config -e CONFIG_CRYPTO_ECDSA
# scripts/config -e CONFIG_WIREGUARD
# make olddefconfig

kvm_guest.config включает все необходимые драйверы для системы, которая будет работать в виртуальной машине. Для себя включил Wireguard.

# make -j$(nproc)
# make tarxz-pkg
# tar tvf linux-5.18.14-x86.tar.xz 
drwxr-xr-x root/root         0 2022-07-28 07:36 boot/
-rw-r--r-- root/root    133768 2022-07-28 07:36 boot/config-5.18.14
-rw-r--r-- root/root  11202432 2022-07-28 07:36 boot/vmlinuz-5.18.14
-rwxr-xr-x root/root  73921096 2022-07-28 07:36 boot/vmlinux-5.18.14
-rw-r--r-- root/root   5670638 2022-07-28 07:36 boot/System.map-5.18.14
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/modules/
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/modules/5.18.14/
-rw-r--r-- root/root       331 2022-07-28 07:36 lib/modules/5.18.14/modules.order
-rw-r--r-- root/root       862 2022-07-28 07:36 lib/modules/5.18.14/modules.alias
-rw-r--r-- root/root     11704 2022-07-28 07:36 lib/modules/5.18.14/modules.builtin
-rw-r--r-- root/root        12 2022-07-28 07:36 lib/modules/5.18.14/modules.symbols.bin
-rw-r--r-- root/root    106167 2022-07-28 07:36 lib/modules/5.18.14/modules.builtin.modinfo
-rw-r--r-- root/root      1528 2022-07-28 07:36 lib/modules/5.18.14/modules.alias.bin
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/modules/5.18.14/kernel/
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/modules/5.18.14/kernel/net/
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/modules/5.18.14/kernel/net/netfilter/
-rw-r--r-- root/root     11256 2022-07-28 07:36 lib/modules/5.18.14/kernel/net/netfilter/xt_nat.ko
-rw-r--r-- root/root      7200 2022-07-28 07:36 lib/modules/5.18.14/kernel/net/netfilter/xt_LOG.ko
-rw-r--r-- root/root     31152 2022-07-28 07:36 lib/modules/5.18.14/kernel/net/netfilter/nf_log_syslog.ko
-rw-r--r-- root/root      6216 2022-07-28 07:36 lib/modules/5.18.14/kernel/net/netfilter/xt_mark.ko
-rw-r--r-- root/root     11440 2022-07-28 07:36 lib/modules/5.18.14/kernel/net/netfilter/xt_addrtype.ko
-rw-r--r-- root/root      7360 2022-07-28 07:36 lib/modules/5.18.14/kernel/net/netfilter/xt_MASQUERADE.ko
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/modules/5.18.14/kernel/net/ipv4/
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/modules/5.18.14/kernel/net/ipv4/netfilter/
-rw-r--r-- root/root      9264 2022-07-28 07:36 lib/modules/5.18.14/kernel/net/ipv4/netfilter/iptable_nat.ko
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/modules/5.18.14/kernel/fs/
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/modules/5.18.14/kernel/fs/efivarfs/
-rw-r--r-- root/root     20504 2022-07-28 07:36 lib/modules/5.18.14/kernel/fs/efivarfs/efivarfs.ko
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/modules/5.18.14/kernel/drivers/
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/modules/5.18.14/kernel/drivers/thermal/
drwxr-xr-x root/root         0 2022-07-28 07:36 lib/modules/5.18.14/kernel/drivers/thermal/intel/
-rw-r--r-- root/root     20984 2022-07-28 07:36 lib/modules/5.18.14/kernel/drivers/thermal/intel/x86_pkg_temp_thermal.ko
-rw-r--r-- root/root         0 2022-07-28 07:36 lib/modules/5.18.14/modules.devname
-rw-r--r-- root/root     10944 2022-07-28 07:36 lib/modules/5.18.14/modules.builtin.alias.bin
-rw-r--r-- root/root        49 2022-07-28 07:36 lib/modules/5.18.14/modules.symbols
-rw-r--r-- root/root       975 2022-07-28 07:36 lib/modules/5.18.14/modules.dep.bin
-rw-r--r-- root/root       340 2022-07-28 07:36 lib/modules/5.18.14/modules.dep
lrwxrwxrwx root/root         0 2022-07-28 07:36 lib/modules/5.18.14/build -> /usr/src/linux-5.18.14
-rw-r--r-- root/root        89 2022-07-28 07:36 lib/modules/5.18.14/modules.softdep
lrwxrwxrwx root/root         0 2022-07-28 07:36 lib/modules/5.18.14/source -> /usr/src/linux-5.18.14
-rw-r--r-- root/root     14623 2022-07-28 07:36 lib/modules/5.18.14/modules.builtin.bin

Мдя...

Вот и всё.

Больше нельзя установить CRUX 3.7 в чистом виде на диск размером 1,000,000,000 байт чтобы запускать его на VDS.

Придётся делать обрезание пингвину! Например, мы можем выиграть немного свободного места, если затюним файловую систему, ну хотя бы tune2fs -m 1 /dev/sdb1 — зарезервируем для root'а 1% свободного пространства, вместо 5%.

Отключать насовсем этот резерв нельзя, иначе вы не сможете даже зайти по ssh, когда логи в /var/log съедят всё оставшееся место на диске.

# umount /mnt
# tune2fs -m 1 /dev/sdb1
# tune2fs -m 1 /dev/sdc1

CRUX 3.6

mount /dev/sdb1 /mnt
# df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1       920M  766M  129M  86% /mnt

CRUX 3.7

# mount /dev/sdc1 /mnt/
# df -h /mnt/
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdc1       920M  838M   57M  94% /mnt

Иии... Ядро по-прежнему нельзя установить, недостаточно места.

Другой вариант, немного покромсать файлы ядра, ведь на самом деле для работы системы нам нужно только само ядро vmlinuz и папка /lib.

Давайте сделаем так и извлечём только эти файлы.

# tar xvf linux-5.18.14-x86.tar.xz -C /mnt boot/vmlinuz-5.18.14 lib/

После установки ядра, оставшееся место для CRUX 3.6

# df -h /mnt/
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1       920M  777M   80M  91% /mnt

И оставшееся место для CRUX 3.7

# df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdc1       920M  849M  6.9M 100% /mnt

Загрузчик, финальная настройка системы!

# mount /dev/sdb1 /mnt/
# mount --bind /dev /mnt/dev
# mount -t proc proc /mnt/proc
# mount -t sysfs none /mnt/sys
# chroot /mnt/ /bin/bash
# localedef -i en_US -f UTF-8 en_US.UTF-8
# passwd
# grub-install /dev/sdb
# grub-mkconfig -o /boot/grub/grub.cfg
# umount -R /mnt

Аналогично делаем с /dev/sdc1, где у нас установлен CRUX 3.7

# mount /dev/sdc1 /mnt
# mount --bind /dev /mnt/dev
# mount -t proc proc /mnt/proc
# mount -t sysfs none /mnt/sys
# chroot /mnt/ /bin/bash
# localedef -i en_US -f UTF-8 en_US.UTF-8
# passwd
New password: 
Retype new password: 
passwd: password updated successfully
# grub-install /dev/sdc
Installing for i386-pc platform.
Installation finished. No error reported.
# grub-mkconfig -o /boot/grub/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.18.14
Warning: os-prober will not be executed to detect other bootable partitions.
Systems on them will not be added to the GRUB boot configuration.
Check GRUB_DISABLE_OS_PROBER documentation entry.
done

Не забудьте в grub.cfg заменить все /dev/sdb и /dev/sdc устройства на /dev/sda т.к. загрузка будет происходить именно с /dev/sda.

В финале, у нас осталось 1.6 мегабайт свободного пространства после установки CRUX 3.7 на 1,000,000,000-байтный диск!

# df -h /mnt/
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdc1       920M  855M  1.6M 100% /mnt

Для работы системы это не критично, всё свободное место съедят логи в /var/log, а система продолжит работу.

И в завершении всего, я выложил образы виртуальных машин обновлённых версий CRUX 3.6 и CRUX 3.7

>>> Скачать CRUX 3.6 IMG (1,000,000,000b)

>>> Скачать CRUX 3.7 IMG (1,000,000,000b)

Логин root пароль toor, чтобы вы могли просто скачать образы и пощупать систему CRUX GNU/Linux вживую!

https://www.netboot.ru/Screenshot_2022-07-28_11-29-11.png

 

Spoofing
()

Дефолт95

Галерея — Скриншоты

Раз в несколько лет я пытаюсь осилить нормальный дистрибутив, но в итоге всегда возвращаюсь к CRUX.

Забавно, как на моём ноутбуке, i7-11-чего-то-там, 40GB RAM и 512GB NVMe, самый обычный терминал запускается секунду-две, дело было на Fedora/Gnome42. Пробовал дефолтную Ubuntu, но никак не могу привыкнуть к интерфейсу...

О! https://github.com/grassmunk/Chicago95

То, что доктор прописал. Настроив хоткеи под себя, этим наконец можно пользоваться. Посмотрим, как скоро я вернусь обратно на CRUX/FVWM, но пока остаюсь на Ubuntu/XFCE+Chicago95. Так!

>>> Просмотр (3440x1440, 696 Kb)

 , , ,

Spoofing
()

Каминг аут

Форум — Talks

Не знаю какой чёрт меня дёрнул, но решил обмазаться мейнстримом, установил последнюю Fedora + Gnome 3 на свой ноутбук.

10 из 10, господи, 10 из 10!!!

Последний раз когда я ставил гном с момента его появления на свет, выглядил он весьма кринжово, когда слева надо триггернуть панель быстрого запуска приложений, а справа надо было триггернуть список рабочих столов, т.е. помимо того, что надо жмякнуть в «Обзор», потом надо было знатно ещё помышевозить, а переключение между приложениями вообще было непонятно как организовано.

А что сейчас? Я просто вожу по тачпаду тремя пальцами вниз-вверх чтобы запустить приложение, а влево-право переключаюсь между рабочими столами. При этом я могу вниз провести пальцами один раз, а затем начать печатать имя приложения чтобы его запустить, всё упрощено донельзя, и для домохозяек и для профессиональных пользователей.

У меня возникло ощущение как будто бы я этот гном делал, он настолько стал интуитивно понятный и простой... Потому что если бы я этот гном делал, я бы его сделал именно таким, какой он есть сейчас, это гениально, это просто нечто, слов нет какая федора с дефолтным гномом классная!

Даже если сейчас в процессе использования всплывут какие-то огрехи, всё равно все плюсы интерфейса перекрывают любые недостатки, я готов простить гному даже если его плазма будет падать каждые 10 минут. Вот так вот!

Я закончил.

 ,

Spoofing
()

Как ограничивать доступ по IP, когда IPv6 раздают /64 подсетями?

Форум — Security

Ну вот как, когда даже такой параметр как IP, злодей может менять «на лету». В данном случае конечно же имеется ввиду IPv6, но всё же. Так же, подсетями блочить? Ну нет, там же этими же подсетями и раздают эти адреса направо и налево.

По сути, вообще вариантов не остаётся, кроме как создавать свой внутренний идентификатор (логин) пользователя и фильтровать пользователей по нему. Я бы очень хотел оставить анонимусов, но похоже их эпоха прошла.

 ,

Spoofing
()

Открытое тестирование сайта

Форум — Talks

Здравствуйте, мои маленькие психологически зрелые личности!

В свободное от работы время, в своё удовольствие, когда никому ничего не должен, когда нет кредитов и долгов, никаких обязательств перед кем-либо, когда приходишь домой, а дома тишина, чистота, покой и умиротворение, и никто слова тебе поперёк не скажет, — я занимаюсь разработкой своего проекта, сайта, на базе которого можно создавать другие сайты и управлять ими.

Исходный код вы можете скачать по ссылке http://www.netboot.ru/latest.tar, сейчас это сугубо-черновой вариант только чтобы продемонстировать рабочий прототип, оценить качество кода и может быть внести своё предложение по развитию.

Проверить как оно работает вживую вы можете на сайте http://www.netboot.ru/blog/, где пока на время тестирования вы можете свободно добавлять и редактировать любые сообщения.

Как я писал ранее, я не осилил ООП, поэтому проект написан в олдскульном стиле (или депрекейтед, уж кому как), с использованием исключительно простых функций, но при этом без использования глобальных переменных! Я большой перфекционист и строг прежде всего к самому себе в плане качества работы и кода, поэтому старался писать правильно.

Так например, у меня заведено в правилах, что каждая, подчёркиваю, _каждая_ функция возращает false, всегда! Чтобы функция вернула нужный нам результат, мы должны сами, подчёркиваю, _сами_, через условия добывать этот результат. Только так. В противном случае всегда будет false, и функции, которые друг-друга вызывают, получают false и отвечают тоже false, и клиент получает ошибку. С этим у меня очень строго.

Но не смотря на это, функции всё ещё поделены логически на отдельные пространства имён, то есть, все функции, которые работают с базой данных, начинаются с префикса db_, все функции, которые работают с сессиями, начинаются с префикса session_ и т.д. Соответсвенно такие списки функций я выделил в отдельные файлы, которые назвал не-классами, в ./src/noclasses лежат .noclass.php файлики.

Весь, целиком и полностью весь проект написан на функциях и ничего нигде «случайно» не происходит. Так, если вызвать php-файл напрямую из браузера, то ничего не произойдёт, т.к. там просто объявляются функции!

Проект состоит из /index.php файлика, ./src/noclasses/*.noclass.php функций и ./src/contollers/*.php контроллеров.

В /index.php самой первой вызывается функция:

run($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']);

То есть, по-сути, чтобы сэмулировать какой-то запрос и получить на него ответ, вы можете дёргать эту функцию руками.

Далее в main.noclass.php эта функция обрабатывает запрос и выдаёт ответ.

function run($request_uri, $request_method) {

    $route = route($request_uri, $request_method);

    $buffer = process($route);

    $output = output($buffer);

    return false;

}

route() смотрит какой документ запросили и выдаёт контроллер, который должен обработать запрос.

process() запускает заданный контроллер на выполнение, контроллер возвращает ответ, сгенерированную страничку например.

output() просто отдаёт ответ клиенту.

Функция route() требует доработки, т.к. каждый запрашиваемый документ проверяется вручную, а нам нужно реализовать динамический роутинг, который будет по списку смотреть маршрут и выдавать контроллер. //TODO в общем.

function route($request_uri, $request_method) {

    $request_path = strtok($request_uri, '?');
    $request = explode('/', $request_path);
    $require = false;

    if (end($request) == '') {

        if ($request[1] == '') {
            $require = 'index.php';

            return $require;
        }

    }

    return false;

}

Функция process() занимается вызовом котроллера.

function process($route) {

    if ($route == false) {
        echo 'kernel panic: controller not found';
        return false;
    }

    $request = $route['request'];
    $require = $route['require'];

    ob_start();
    $exec = (@include($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'controllers' . DIRECTORY_SEPARATOR . $require));
    $ob_buffer_length = ob_get_length();
    $ob_buffer = ob_get_contents();
    ob_end_clean();

    if ($ob_buffer_length > 0) {
        echo 'kernel panic: buffer overflow outside of request() function in ' . $require;
        return false;
    }

    if ($exec == false) {
        echo 'kernel panic: failed to execute ' . $require;
        return false;
    }

    if (function_exists('request')) {
        $exec = request($request['request_uri'], $request['request_method'], $request['request']);

        if ($exec == false) {
            echo 'kernel panic: request() function returned false in ' . $require;
            return false;
        }

        return $exec;
    }
    else {
        echo 'kernel panic: request() function is not defined in ' . $require;
        return false;
    }

    return false;

}

Вы видите, что, если php-скрипт что-то выводит вне вызываемой функции, это приводит к «панике»: kernel panic: buffer overflow outside of request()

Каждый контроллер обязан содержать функцию request(), которая уже обрабатывает запрос и выдаёт ответ.

Вот пример такого контроллера, который обрабатывает GET и POST запросы и выводит ответ.

function request($request_uri, $request_method, $request) {

    if ($request_method == 'GET') {
        return get_index();
    }

    if ($request_method == 'POST') {
        return post_index();
    }

    return false;

}

function get_index() {

    return 'Hello World!';

}

function post_index() {

    return 'Hello World!';

}

Например, мы хотим отрисовать шаблон, тогда функция get_index будет выглядить так.

function get_index() {

    $var = array(
        'title' => 'Welcome!',
        'body' => 'Hello world!'
    );

    $view = view('index.view-get-request', $var);

    return $view;

}

И шаблон будет загружен из файла ./themes/localhost.localdomain/index.view-get-request.php

Как вы видите, не смотря на то, что код полностью написан на функциях, я бы сказал, что он напоминает чем-то ООП: на функциях тоже можно писать хорошо!

 

Spoofing
()

Выдержит ли SQLite нагрузку уровня linux.org.ru?

Форум — Talks

всем привет я пишу сайт на пхп четыре (из-за pdo это пока не получается, поэтому если есть замена pdo для работы с различными бд — подскажите)

главная фича моего движка в простой кодовой базе, в которой разберётся любой начинающий программист на html, css и php

есть поддержка виртуальных хостов. один движок может обслуживать сколько угодно сайтов, у каждого сайта может быть свой индивидуальный дизайн, при этом у них единая база данных с сообщениями и пользователями. например, на одном движке можно вести несколько сайтов, а затем «на лету» их смержить в один, объеденив область видимости нескольских сайтов в один, либо же наоборот, если проект разрастается и условная тема про собачек на сайте котиков набирает популярность — сайт можно раздробить на два, один про кошечек, второй про собачек, при этом пользователям не придётся создавать новые аккаунты на втором сайте.

как уже сказал, у каждого хоста может быть свой индивидуальный дизайн, то есть пользователь вообще не будет знать, что сайт про кошечек и сайт про собачек — это один и тот-же сайт. он увидит перед собой два разных сайта, у каждого своя область видимости в базе данных и дизайн.

все сообщения на сайте — как статьи на википедии, или как сообщения на ЛОРе, могут редактироваться сколько угодно раз и хранить всю историю изменений. весь ключевой вопрос лишь в том, способен ли выдержать SQLite такую нагрузку, или же придётся смотреть в сторону другой базы данных???

пользователи могут создавать сколько угодно аккаунтов и логиниться под разными аккаунтами, а затем переключаться между ними. считаю это прикольным.

у меня своя собственная реализация сессий, которая никак не связана со встроенными сессиями на пхп и никак их не использует. то есть session_*(); и $_SESSION не задействуются. моя реализация позволяет более тонко контролировать все нюансы, например, не создавать пустую сессию «в холостую», или например точно определить, что в папке на диске достаточно места для хранения данных сессии.

вот пример базы данных для сообщений. они хранят всю историю изменений.

CREATE TABLE IF NOT EXISTS 'post'
(
	'id' INTEGER PRIMARY KEY,
	'domain' NVARCHAR(255) DEFAULT NULL,
	'sub_reply' INTEGER DEFAULT NULL,
	'date_created' DATETIME DEFAULT CURRENT_TIMESTAMP,
	'date_modified' DATETIME DEFAULT NULL,
	'flags' NVARCHAR(200) DEFAULT NULL
);

CREATE TABLE IF NOT EXISTS 'post_history'
(
	'id' INTEGER PRIMARY KEY,
	'sub_post' INTEGER NOT NULL,
	'ref_text' INTEGER NOT NULL,
	'date_created' DATETIME DEFAULT CURRENT_TIMESTAMP,
	'date_modified' DATETIME DEFAULT NULL
);

CREATE TABLE IF NOT EXISTS 'post_text'
(
	'id' INTEGER PRIMARY KEY,
	'text' TEXT DEFAULT NULL,
	'text_headers' TEXT DEFAULT NULL
);

сам текст сообщений хранится отдельно в третьей таблице, это сделано потому, что у каждой базы данных (конкретно у MySQL и PostgreSQL) на этот счёт разное мнение. кто-то хранит TEXT и BLOB далеко за пределами основной таблицы, чтобы минимизировать нагрузку при выборке из базы, а кто-то хранит там же рядышком. правильнее будет хранить TEXT отдельно. поэтому храню.

я не осилил ООП и не смог написать на классах, поэтому я писал на функциях, и я их назвал неклассами.

в папочке ./src/noclass/ у меня лежат следующие неклассы.

database.noclass.php:

<?php

function db_directory_sqlite() {
    return dirname($_SERVER['DOCUMENT_ROOT']) . '/db';
}

function db_connect($db_dsn = null, $db_username = null, $db_password = null, $db_attributes = null) {

    $db = false;

    if (strpos($db_dsn, 'sqlite:') == 0) {
        $db_file = substr($db_dsn, strlen('sqlite:'));
        if ($db_file == ':memory:') {
            $db = true;
        }
        elseif (is_writeable(db_directory_sqlite())) {
            $db = true;
        }
    }

    if ($db == false) {
        return false;
    }

    $db = db_connect_retry($db_dsn, $db_username, $db_password, $db_attributes);

    return $db;

}

function db_connect_retry($db_dsn, $db_username, $db_password, $db_attributes) {

    $db = false;

    while ($db == false) {
        try {
            $db = new PDO($db_dsn, $db_username, $db_password, $db_attributes);
        }
        catch (Exception $e) {
            if (stripos($e->getMessage(), 'DATABASE IS LOCKED')) {
                usleep(50000);
                continue;
            }

            return false;
        }
    }

    return $db;

}

function db_open_sqlite_in_memory() {
    $db_file = false;
    $db_dsn = 'sqlite::memory:';

    $db = db_connect($db_dsn);

    return $db;
}

function db_open_sqlite($db_file) {

    if ($db_file == ':memory:') {
        $db = db_open_sqlite_in_memory();

        return $db;
    }

    $db_dsn = 'sqlite:' . $db_file;

    $db = db_connect($db_dsn);

    return $db;
}

function db_open($db_dsn) {
    $db = db_open_sqlite($db_dsn);

    return $db;
}

function db_exec($db, $query_string) {
    $query = $db->exec($query_string);

    return $query;
}

function db_query($db, $query_string) {
    $query = $db->query($query_string);

    return $query;
}

function db_run($db, $query_string, $query_args = false) {
    if ($query_args == false) {
        $query = db_query($db, $query_string);

        return $query;
    }

    $query = $db->prepare($query_string);
    $query->execute($query_args);

    return $query;
}

function db_begin_transaction($db) {
    $query = $db->beginTransaction();

    return $query;
}

function db_is_transaction($db) {
    $query = $db->inTransaction();

    return $query;
}

function db_rollback($db) {
    $query = $db->rollBack();

    return $query;
}

function db_commit($db) {
    $query = $db->commit();

    return $query;
}

function db_last_id($db) {
    $query = $db->lastInsertId();

    return $query;
}

function db_insert($db, $table, $values) {

    $keys = array_keys($values);

    $values = array_values($values);

    $columns = array();
    foreach ($keys as $item) {
        $columns[] = "'$item'";
    }
    $columns = implode(',', $columns);

    $placeholders = array();
    foreach ($keys as $item) {
        $placeholders[] = "?";
    }
    $placeholders = implode(',', $placeholders);

    $query = "INSERT INTO $table ($columns) VALUES ($placeholders);";

    $query = db_run($db, $query, $values);

    return $query;

}

function db_update($db, $table, $value, $where) {

    $collection = array_merge($value, $where);
    $collection = array_values($collection);

    $fields = array();
    foreach ($value as $item => $data) {
        $fields[] = "$item = ?";
    }
    $fields = implode(',', $fields);

    $places = array();
    foreach ($where as $item => $data) {
        $places[] = "$item = ?";
    }
    $places = implode(' AND ', $places);

    $query = "UPDATE $table SET $fields WHERE $places;";

    $query = db_run($db, $query, $collection);

    return $query;

}

function db($db_name) {
    $db_file = db_directory_sqlite() . DIRECTORY_SEPARATOR . $db_name;

    $db = db_open($db_file);

    return $db;
}

post.noclass.php:

<?php

function post_insert($text_headers, $text, $replyto = false) {

    $db = db('example.db');

    if ($db == false) {
        return false;
    }

    db_begin_transaction($db);

    if (db_post_insert($db, $text_headers, $text, $replyto)) {

        db_commit($db);

        return true;

    }

    db_rollback($db);

    return false;

}

function db_post_insert($db, $text_headers, $text, $replyto = false) {

    if ($replyto == false) {

        $id = db_post_insert_id($db);

        if ($id == false) {
            return false;
        }

    }
    else {

        $replyto = db_post_select_id_single($db, $replyto);

        if ($replyto == false) {
            return false;
        }
        else {

            $id = db_post_insert_id($db);

            if ($id == false) {
                return false;
            }

        }
 
    }

    if (db_post_insert_post($db, $id, $replyto)) {

        $ref_text = db_post_insert_post_text($db, $text_headers, $text);

        if ($ref_text == false) {
            return false;
        }

        if (db_post_insert_post_history($db, $id, $ref_text)) {
            return $id;
        }

    }

    return false;

}

function db_post_insert_id($db) {

    $value = array(
        'id' => null
    );
    
    db_insert($db, 'post', $value);

    return db_last_id($db);

}

function db_post_select_id_single($db, $id) {

    $value = array(
        'id' => $id
    );
    
    $query = 'SELECT id FROM post WHERE id = :id;';

    $query = db_run($db, $query, $value);

    $row = $query->fetch();

    return ($row == false) ? false : $row['id'];

}

function db_post_insert_post($db, $id, $replyto = false) {

    $date_created = date('Y-m-d H:i:s', time());
    $date_modified = null;

    $search = array(
        'id' => $id
    );
    
    $entry = array(
        'id' => null,
        'domain' => null,
        'sub_reply' => $replyto,
        'date_created' => $date_created,
        'date_modified' => $date_modified,
        'flags' => null
    );

    // remove false, null and other zero-values from entry
    $entry = array_filter($entry);

    if (db_update($db, 'post', $entry, $search)) {
        return $id;
    }

    return false;

}

function db_post_insert_post_text($db, $text_headers, $text) {

    if ($text_headers == false) {
        //nothing to do -- skip headers
    }
    else {
        $text_headers = serialize($text_headers);
    }

    $entry = array(
        'id' => null,
        'text' => $text,
        'text_headers' => $text_headers
    );

    // remove false, null and other zero-values from entry
    $entry = array_filter($entry);

    if (db_insert($db, 'post_text', $entry)) {
        return db_last_id($db);
    }

    return false;

}

function db_post_insert_post_history($db, $sub_post, $ref_text) {

    $date_created = date('Y-m-d H:i:s', time());
    $date_modified = null;

    $entry = array(
        'id' => null,
        'sub_post' => $sub_post,
        'ref_text' => $ref_text,
        'date_created' => $date_created,
        'date_modified' => $date_modified
    );

    // remove false, null and other zero-values from entry
    $entry = array_filter($entry);

    if (db_insert($db, 'post_history', $entry)) {
        return db_last_id($db);
    }

    return false;

}

function db_post_select_count($db) {

    $query = db_query($db, 'SELECT COUNT(*) as sizeof FROM post;');

    $row = $query->fetch();

    return $row['sizeof'];

}

function post_update($id, $text_headers, $text) {

    $db = db('example.db');

    if ($db == false) {
        return false;
    }

    db_begin_transaction($db);

    if (db_post_update($db, $id, $text_headers, $text)) {

        db_commit($db);

        return true;

    }

    db_rollback($db);

    return false;

}

function db_post_update($db, $id, $text_headers, $text) {

    $id = db_post_select_id_single($db, $id);

    if ($id == false) {
        return false;
    }

    if (db_post_update_post($db, $id)) {

        $ref_text = db_post_insert_post_text($db, $text_headers, $text);

        if ($ref_text == false) {
            return false;
        }

        if (db_post_insert_post_history($db, $id, $ref_text)) {
            return $id;
        }

    }

    return false;

}

function db_post_update_post($db, $id) {

    $date_created = null;
    $date_modified = date('Y-m-d H:i:s', time());

    $search = array(
        'id' => $id
    );
    
    $entry = array(
        'id' => null,
        'domain' => null,
        'sub_reply' => null,
        'date_created' => $date_created,
        'date_modified' => $date_modified,
        'flags' => null
    );

    // remove false, null and other zero-values from entry
    $entry = array_filter($entry);

    if (db_update($db, 'post', $entry, $search)) {
        return $id;
    }

    return false;

}

function db_post_select_id($db, $id = false) {

    if ($id == false) {
        return false;
    }

    $value = array(
        'id' => $id
    );

    $query = '
SELECT * FROM post
INNER JOIN post_history AS initial ON (initial.sub_post = post.id AND initial.id = (SELECT id FROM post_history WHERE sub_post = post.id ORDER BY id ASC LIMIT 1))
INNER JOIN post_history AS current ON (current.sub_post = post.id AND current.id = (SELECT id FROM post_history WHERE sub_post = post.id ORDER BY id DESC LIMIT 1))
INNER JOIN post_text ON post_text.id = current.ref_text
WHERE post.id = :id
';

    $query = db_run($db, $query, $value);

    $row = $query->fetch();

    $row = post_row($row);

    return $row;

}

function db_post_select_page($db, $page = false, $limit = 10) {

    $pages = (db_post_select_count($db) / $limit);
    $pages = ceil($pages);

    if ($page == false) {
        $page = $pages;
    }
    elseif ($page > $pages) {
        $page = $pages;
    }
    elseif ($page < 1) {
        $page = $pages;
    }

    $offset = ($page - 1) * $limit;

    // should I make it more stronger?
    // escape offset and limit
    $query = '
SELECT * FROM post
INNER JOIN post_history AS initial ON (initial.sub_post = post.id AND initial.id = (SELECT id FROM post_history WHERE sub_post = post.id ORDER BY id ASC LIMIT 1))
INNER JOIN post_history AS current ON (current.sub_post = post.id AND current.id = (SELECT id FROM post_history WHERE sub_post = post.id ORDER BY id DESC LIMIT 1))
INNER JOIN post_text ON post_text.id = current.ref_text
ORDER BY id DESC LIMIT ' . $limit . ' OFFSET ' . $offset . ';
';

    $query = db_query($db, $query);

    $array = array();

    while ($row = $query->fetch()) {

        $array[] = post_row($row);

    }

    return $array;

}

function post_row($row) {

    if ($row == false) {
        return false;
    }

    if ($row['date_created'] == null) {
        $row['date_created'] = '(unavailable)';
    }

    if ($row['date_modified'] == null) {
        $row['date_modified'] = '(unavailable)';
    }

    if (empty($row['text_headers'])) {
        $row['text_headers'] = array();
    }
    else {
        $row['text_headers'] = unserialize($row['text_headers']);
    }

    if (empty($row['text_headers']['title'])) {
        $row['text_headers']['title'] = '';
    }

    return $row;

}

function post_escape($text) {

    $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
    $text = nl2br($text);

    return $text;

}

function post_input_filtered($text) {

    $text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');

    return $text;

}

function post_text_filtered($text) {

    $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');

    return $text;

}

session.noclass.php

<?php

function session_directory() {
    return dirname($_SERVER['DOCUMENT_ROOT']) . DIRECTORY_SEPARATOR . 'db' . DIRECTORY_SEPARATOR . 'sess';
}

function session_open($session_name = 'ident') {

    $session_id = session_open_if_cookie_is_set($session_name);

    if ($session_id == false) {
        $session_id = session_new($session_name);
    }

    return $session_id;

}

function session_open_if_cookie_is_set($session_name = 'ident') {

    if (isset($_COOKIE[$session_name])) {
        $session_id = $_COOKIE[$session_name];

        if (strlen(str_replace(array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'), '', $session_id)) > 0) {
            $session_id = session_new($session_name);
        }

        return $session_id;
    }

    return false;

}

function session_load($session_id) {

    $session_file = session_directory() . DIRECTORY_SEPARATOR . $session_id;
    $session_data = false;

    if ($fp = @fopen($session_file, 'r')) {
        flock($fp, LOCK_SH);
        $session_data = fread($fp, filesize($session_file));
        $session_data = unserialize($session_data);
        flock($fp, LOCK_UN);
        fclose($fp);
    }

    if (is_array($session_data)) {
        return $session_data;
    }

    return array();

}

function session_save($session_id, $session_data = array()) {

    $session_file = session_directory() . DIRECTORY_SEPARATOR . $session_id;
    $session_data = serialize($session_data);

    if ($fp = @fopen($session_file, 'w+')) {
        flock($fp, LOCK_EX);
        $bytes_written = fwrite($fp, $session_data);
        flock($fp, LOCK_UN);
        fclose($fp);
    }

    return $bytes_written;

}

function session_new($session_name) {

    if (headers_sent()) {
        return false;
    }

    $session_id = bin2hex(session_random_bytes(8));

    $cookie_lifetime = 0;
    $cookie_path = '/';
    $cookie_domain = '';
    $cookie_secure = false;
    $cookie_httponly = false;

    if (setcookie($session_name, $session_id, $cookie_lifetime, $cookie_path, $cookie_domain, $cookie_secure, $cookie_httponly) == false) {
        return false;
    }

    return $session_id;

}

function session_random_bytes($length = 32) {
    
    $random_bytes = '';

    for ($i = 0; $i < $length; $i++) {
        $random_bytes .= chr(rand(0, 255));
    }

    return $random_bytes;

}

function session() {

    $id = session_open();

    if ($id == false) {
        return false;
    }

    $session = session_load($id);

    return $session;

}

вот вам небольшая инструкция как использовать сессии

вы просто делаете $session = session(); и создаётся новая сессия и в переменную $session загружается массив со всеми данными сессии.

если вы хотите что-то сохранить в сессию, то вы должны проделать все действия вручую:

// создаём новую сессию
// в $id помещается идентификатор сессии, ну типа PHPSESSID
$id = session_open();

// загружаем данные сессии в переменную $session
// можно для этого использовать $_SESSION но я не хочу и не буду
$session = session_load($id);

// создаём в $session приветствие
$session = array('greeting' => 'hello world!');

// сохраняем данные сессии, за вас это никто не сделает
session_save($id, $session);

есть такой забавный момент, когда мы не хотим создавать сессию, если у пользователя её нету. для этого есть функция session_open_if_cookie_is_set();, которая запускает сессию только при наличии куки.

в целом моя реализация сессий лучше пхпшной т.к. она не создаёт пустых файлов!!! каждый момент вы контролируете сами!!!

теперь давайте я вам расскажу про сообщения а-ля википедия или лор.

для отправки сообщения я делаю так:

$headers = array(
    'title' => 'заголовок письма'
);

$content = 'текст письма';

post_insert($headers, $content);

как вы знаете у сообщения есть не только его содержимое, не только сам текст сообщения. у сообщения есть мета-данные, такие как заголовок, тэги, ну ещё что-нибудь может быть. поэтому все эти мета-данные помещаются в отдельный массив.

затем при выборке сообщения из базы мы можем сравить, сделать diff не только на сам текст сообщения, но и на все заголовки тоже сделать diff и увидеть различия между двумя версиями сообщения включая всю мета-информацию, — заголовки, теги. теперь вы понимаете почему я решил так сделать.

функция post_insert(); вернёт просто true в случае узбека. иначе false.

для того, чтобы отредактировать сообщение, есть функция post_update();, но первым параметром ещё нужно указать ID сообщения.

например мы только что добавили сообщение, его ID 1, теперь мы хотим его отредактировать.

$id = '1';

$headers = array(
    'title' => 'заголовок письма (отредактировано)'
);

$content = 'исправленный текст письма';

post_update($id, $headers, $content);

и теперь в базу будет сохранена новая версия сообщения.

выполняем sqlite example.db .dump и смотрим

INSERT INTO post VALUES(1,NULL,NULL,'2022-07-17 06:24:55','2022-07-17 06:25:26',NULL);

INSERT INTO post_history VALUES(1,1,1,'2022-07-17 06:24:55',NULL);
INSERT INTO post_history VALUES(2,1,2,'2022-07-17 06:25:26',NULL);

INSERT INTO post_text VALUES(1,'текст письма','a:1:{s:5:"title";s:31:"заголовок письма";}');
INSERT INTO post_text VALUES(2,'исправленный текст письма','a:1:{s:5:"title";s:64:"заголовок письма (отредактировано)";}');

по факту сообщение одно, а ревизии у него две! так-то!

для того, чтобы прочитать сообщение в массив мы подключаемся к базе данных и выполняем одну функцию, указав ID сообщения

$db = db('example.db');

if ($db == false) {
    return false;
}

$post = db_post_select_id($db, $_GET['id']);

var_dump($post);

для того, чтобы вывести страницу со списком сообщений есть функция db_post_select_page($db, $_GET['page']);

в целом мой код будет очень хорошо документирован, но это чуть попозже, пока только реализация.

мой код написан очень качественно на совесть, писал для себя.

очень скоро будет релиз и я создаю отдельный сайт посвящённый своей цмс на пхп четыре. оцените качество кода, насколько он красив и хорош, и очень строгий!

главный вопрос — выдержит ли такая структура базы данных на SQLite нагрузку с бесконечным редактированием сообщений???

 ,

Spoofing
()

Что за суета вокруг LT?

Форум — Linux-org-ru

На сайте название которого нельзя произносить вслух люди массово жалуются на сброс URL.

Вот я сейчас если сделаю сайт, там зарегистрируются все мои друзья с ЛОРа, мой сайт тоже окажется «вне закона»?

Или любой кто будет использовать опен-сорц(!) движок ЛОРа окажется вне закона?

Может тогда стоит добавить новое правило?

9999.1) Нельзя форкать ЛОР

А опен-сорц, он для кого надо опен-сорц.

Я просто хочу разобраться в политике администрации ЛОРа. Где проходит граница? Ну просто уточнили бы, чтобы люди не мучались, за что их собственно минусуют.

 

Spoofing
()

RSS подписка на новые темы