feat(profile): add more dbus interface base abs & improve dbus integration.
This commit is contained in:
parent
a724af9ded
commit
4210db4faa
23 changed files with 128 additions and 13 deletions
|
|
@ -33,6 +33,11 @@
|
||||||
|
|
||||||
# Session bus
|
# Session bus
|
||||||
|
|
||||||
|
dbus send bus=session path=/org/a11y/bus
|
||||||
|
interface=org.freedesktop.DBus.Properties
|
||||||
|
member=GetAll
|
||||||
|
peer=(name=@{busname}, label="@{p_dbus_accessibility}"),
|
||||||
|
|
||||||
dbus send bus=session path=/org/a11y/bus
|
dbus send bus=session path=/org/a11y/bus
|
||||||
interface=org.a11y.Bus
|
interface=org.a11y.Bus
|
||||||
member=Get
|
member=Get
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
dbus receive bus=system path=/
|
dbus receive bus=system path=/
|
||||||
interface=org.freedesktop.DBus.ObjectManager
|
interface=org.freedesktop.DBus.ObjectManager
|
||||||
member=InterfacesRemoved
|
member={InterfacesAdded,InterfacesRemoved}
|
||||||
peer=(name="{@{busname},org.bluez}", label="@{p_bluetoothd}"),
|
peer=(name="{@{busname},org.bluez}", label="@{p_bluetoothd}"),
|
||||||
|
|
||||||
dbus send bus=system path=/
|
dbus send bus=system path=/
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,16 @@
|
||||||
member=StateChanged
|
member=StateChanged
|
||||||
peer=(name=@{busname}, label="@{p_avahi_daemon}"),
|
peer=(name=@{busname}, label="@{p_avahi_daemon}"),
|
||||||
|
|
||||||
|
dbus receive bus=system path=/Client@{int}/ServiceResolver@{int}
|
||||||
|
interface=org.freedesktop.Avahi.ServiceResolver
|
||||||
|
member=Found
|
||||||
|
peer=(name=@{busname}, label="@{p_avahi_daemon}"),
|
||||||
|
|
||||||
|
dbus send bus=system path=/Client@{int}/ServiceResolver@{int}
|
||||||
|
interface=org.freedesktop.Avahi.ServiceResolver
|
||||||
|
member=Free
|
||||||
|
peer=(name=org.freedesktop.Avahi, label="@{p_avahi_daemon}"),
|
||||||
|
|
||||||
include if exists <abstractions/bus/org.freedesktop.Avahi.d>
|
include if exists <abstractions/bus/org.freedesktop.Avahi.d>
|
||||||
|
|
||||||
# vim:syntax=apparmor
|
# vim:syntax=apparmor
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
dbus receive bus=system path=/org/freedesktop
|
dbus receive bus=system path=/org/freedesktop
|
||||||
interface=org.freedesktop.DBus.ObjectManager
|
interface=org.freedesktop.DBus.ObjectManager
|
||||||
member=InterfacesAdded
|
member={InterfacesAdded,InterfacesRemoved}
|
||||||
peer=(name="{@{busname},org.freedesktop.NetworkManager}", label=NetworkManager),
|
peer=(name="{@{busname},org.freedesktop.NetworkManager}", label=NetworkManager),
|
||||||
|
|
||||||
dbus receive bus=system path=/org/freedesktop/NetworkManager
|
dbus receive bus=system path=/org/freedesktop/NetworkManager
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
dbus receive bus=system path=/org/freedesktop/UPower
|
dbus receive bus=system path=/org/freedesktop/UPower
|
||||||
interface=org.freedesktop.UPower
|
interface=org.freedesktop.UPower
|
||||||
member=DeviceAdded
|
member={DeviceAdded,DeviceRemoved}
|
||||||
peer=(name="{@{busname},org.freedesktop.UPower}", label="@{p_upowerd}"),
|
peer=(name="{@{busname},org.freedesktop.UPower}", label="@{p_upowerd}"),
|
||||||
|
|
||||||
include if exists <abstractions/bus/org.freedesktop.UPower.d>
|
include if exists <abstractions/bus/org.freedesktop.UPower.d>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@
|
||||||
member=Lookup
|
member=Lookup
|
||||||
peer=(name="@{busname}", label=xdg-permission-store),
|
peer=(name="@{busname}", label=xdg-permission-store),
|
||||||
|
|
||||||
|
dbus send bus=session path=/org/freedesktop/impl/portal/PermissionStore
|
||||||
|
interface=org.freedesktop.impl.portal.PermissionStore
|
||||||
|
member=Lookup
|
||||||
|
peer=(name=org.freedesktop.impl.portal.PermissionStore, label=xdg-permission-store),
|
||||||
|
|
||||||
include if exists <abstractions/bus/org.freedesktop.impl.portal.PermissionStore.d>
|
include if exists <abstractions/bus/org.freedesktop.impl.portal.PermissionStore.d>
|
||||||
|
|
||||||
# vim:syntax=apparmor
|
# vim:syntax=apparmor
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,7 @@
|
||||||
|
|
||||||
abi <abi/4.0>,
|
abi <abi/4.0>,
|
||||||
|
|
||||||
#aa:dbus common bus=session name=org.freedesktop.portal.Desktop label=xdg-desktop-portal
|
#aa:dbus common bus=session name=org.freedesktop.portal.{d,D}esktop label=xdg-desktop-portal
|
||||||
dbus send bus=session path=/org/freedesktop/portal/desktop
|
|
||||||
interface=org.freedesktop.DBus.Properties
|
|
||||||
member=GetAll
|
|
||||||
peer=(name=@{busname}, label=xdg-desktop-portal),
|
|
||||||
|
|
||||||
dbus send bus=session path=/org/freedesktop/portal/desktop
|
dbus send bus=session path=/org/freedesktop/portal/desktop
|
||||||
interface=org.freedesktop.DBus.Properties
|
interface=org.freedesktop.DBus.Properties
|
||||||
|
|
@ -35,6 +31,11 @@
|
||||||
member={Read,ReadAll}
|
member={Read,ReadAll}
|
||||||
peer=(name="@{busname}", label=xdg-desktop-portal),
|
peer=(name="@{busname}", label=xdg-desktop-portal),
|
||||||
|
|
||||||
|
dbus send bus=session path=/org/freedesktop/portal/desktop
|
||||||
|
interface=org.freedesktop.host.portal.Registry
|
||||||
|
member=Register
|
||||||
|
peer=(name=org.freedesktop.portal.Desktop, label=xdg-desktop-portal),
|
||||||
|
|
||||||
include if exists <abstractions/bus/org.freedesktop.portal.Desktop.d>
|
include if exists <abstractions/bus/org.freedesktop.portal.Desktop.d>
|
||||||
|
|
||||||
# vim:syntax=apparmor
|
# vim:syntax=apparmor
|
||||||
|
|
|
||||||
16
apparmor.d/abstractions/bus/org.gtk.Notifications
Normal file
16
apparmor.d/abstractions/bus/org.gtk.Notifications
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
# apparmor.d - Full set of apparmor profiles
|
||||||
|
# Copyright (C) 2023-2024 Alexandre Pujol <alexandre@pujol.io>
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
|
abi <abi/4.0>,
|
||||||
|
|
||||||
|
#aa:dbus common bus=session name=org.gtk.Notifications label=gnome-shell
|
||||||
|
|
||||||
|
dbus send bus=session path=/org/gtk/Notifications
|
||||||
|
interface=org.gtk.Notifications
|
||||||
|
member=RemoveNotification
|
||||||
|
peer=(name=org.gtk.Notifications, label=gnome-shell),
|
||||||
|
|
||||||
|
include if exists <abstractions/bus/org.gtk.Notifications.d>
|
||||||
|
|
||||||
|
# vim:syntax=apparmor
|
||||||
31
apparmor.d/abstractions/bus/org.mpris.MediaPlayer2.Player
Normal file
31
apparmor.d/abstractions/bus/org.mpris.MediaPlayer2.Player
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
# apparmor.d - Full set of apparmor profiles
|
||||||
|
# Copyright (C) 2023-2024 Alexandre Pujol <alexandre@pujol.io>
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
|
abi <abi/4.0>,
|
||||||
|
|
||||||
|
#aa-dbus common bus=session name=org.mpris.MediaPlayer2.Player label=unconfined
|
||||||
|
|
||||||
|
dbus receive bus=session path=/org/mpris/MediaPlayer2
|
||||||
|
interface=org.freedesktop.DBus.Properties
|
||||||
|
member=PropertiesChanged
|
||||||
|
peer=(name=@{busname}),
|
||||||
|
|
||||||
|
dbus receive bus=session path=/org/mpris/MediaPlayer2
|
||||||
|
interface=org.mpris.MediaPlayer2.Player
|
||||||
|
member=Seeked
|
||||||
|
peer=(name=@{busname}),
|
||||||
|
|
||||||
|
dbus send bus=session path=/org/mpris/MediaPlayer2
|
||||||
|
interface=org.freedesktop.DBus.Properties
|
||||||
|
member=Get
|
||||||
|
peer=(name=@{busname}),
|
||||||
|
|
||||||
|
dbus send bus=session path=/org/mpris/MediaPlayer2
|
||||||
|
interface=org.freedesktop.DBus.Properties
|
||||||
|
member=GetAll
|
||||||
|
peer=(name=@{busname}),
|
||||||
|
|
||||||
|
include if exists <abstractions/bus/org.mpris.MediaPlayer2.Player.d>
|
||||||
|
|
||||||
|
# vim:syntax=apparmor
|
||||||
|
|
@ -36,6 +36,11 @@ profile cups-browsed @{exec_path} {
|
||||||
member=CheckPermissions
|
member=CheckPermissions
|
||||||
peer=(name=:*, label=NetworkManager),
|
peer=(name=:*, label=NetworkManager),
|
||||||
|
|
||||||
|
dbus receive bus=system path=/org/cups/cupsd/Notifier
|
||||||
|
interface=org.cups.cupsd.Notifier
|
||||||
|
member=PrinterDeleted
|
||||||
|
peer=(name=@{busname}, label=cups-notifier-dbus),
|
||||||
|
|
||||||
@{exec_path} mr,
|
@{exec_path} mr,
|
||||||
|
|
||||||
/usr/share/cups/locale/{,**} r,
|
/usr/share/cups/locale/{,**} r,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ profile cups-notifier-dbus @{exec_path} {
|
||||||
|
|
||||||
signal (receive) set=(term) peer=cupsd,
|
signal (receive) set=(term) peer=cupsd,
|
||||||
|
|
||||||
|
#aa:dbus own bus=system name=org.cups.cupsd.Notifier
|
||||||
|
|
||||||
@{exec_path} mr,
|
@{exec_path} mr,
|
||||||
|
|
||||||
owner /var/spool/cups/tmp/cups-dbus-notifier-lockfile rw,
|
owner /var/spool/cups/tmp/cups-dbus-notifier-lockfile rw,
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,15 @@ profile cupsd @{exec_path} flags=(attach_disconnected) {
|
||||||
|
|
||||||
signal (send) set=(term) peer=cups-notifier-dbus,
|
signal (send) set=(term) peer=cups-notifier-dbus,
|
||||||
|
|
||||||
|
dbus send bus=system path=/org/freedesktop/ColorManager
|
||||||
|
interface=org.freedesktop.ColorManager
|
||||||
|
member=DeleteDevice
|
||||||
|
peer=(name=org.freedesktop.ColorManager, label="@{p_colord}"),
|
||||||
|
dbus send bus=system path=/org/freedesktop/ColorManager
|
||||||
|
interface=org.freedesktop.ColorManager
|
||||||
|
member=FindDeviceById
|
||||||
|
peer=(name=org.freedesktop.ColorManager, label="@{p_colord}"),
|
||||||
|
|
||||||
@{exec_path} mr,
|
@{exec_path} mr,
|
||||||
|
|
||||||
@{sh_path} rix,
|
@{sh_path} rix,
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ profile xdg-desktop-portal-gnome @{exec_path} flags=(attach_disconnected) {
|
||||||
#aa:dbus own bus=session name=org.freedesktop.impl.portal.desktop.gnome
|
#aa:dbus own bus=session name=org.freedesktop.impl.portal.desktop.gnome
|
||||||
#aa:dbus talk bus=session name=org.freedesktop.impl.portal path=/org/freedesktop/portal/desktop label=xdg-desktop-portal
|
#aa:dbus talk bus=session name=org.freedesktop.impl.portal path=/org/freedesktop/portal/desktop label=xdg-desktop-portal
|
||||||
#aa:dbus talk bus=session name=org.gnome.Mutter label=gnome-shell
|
#aa:dbus talk bus=session name=org.gnome.Mutter label=gnome-shell
|
||||||
|
#aa:dbus talk bus=session name=org.gnome.Settings.GlobalShortcutsProvider label=gnome-control-center-global-shortcuts-provider
|
||||||
#aa:dbus talk bus=session name=org.gnome.Shell.Screenshot label=gnome-shell
|
#aa:dbus talk bus=session name=org.gnome.Shell.Screenshot label=gnome-shell
|
||||||
|
|
||||||
dbus send bus=session path=/org/freedesktop/portal/desktop
|
dbus send bus=session path=/org/freedesktop/portal/desktop
|
||||||
|
|
@ -46,6 +47,11 @@ profile xdg-desktop-portal-gnome @{exec_path} flags=(attach_disconnected) {
|
||||||
member=GetAll
|
member=GetAll
|
||||||
peer=(name=:*, label=gnome-shell),
|
peer=(name=:*, label=gnome-shell),
|
||||||
|
|
||||||
|
dbus receive bus=session path=/org/gnome/Shell
|
||||||
|
interface=org.freedesktop.DBus.Properties
|
||||||
|
member=PropertiesChanged
|
||||||
|
peer=(name=@{busname}, label=gnome-shell),
|
||||||
|
|
||||||
@{exec_path} mr,
|
@{exec_path} mr,
|
||||||
|
|
||||||
/ r,
|
/ r,
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ include <tunables/global>
|
||||||
profile evolution-source-registry @{exec_path} {
|
profile evolution-source-registry @{exec_path} {
|
||||||
include <abstractions/base>
|
include <abstractions/base>
|
||||||
include <abstractions/bus-session>
|
include <abstractions/bus-session>
|
||||||
|
include <abstractions/bus/org.freedesktop.secrets>
|
||||||
include <abstractions/bus/org.gtk.vfs.MountTracker>
|
include <abstractions/bus/org.gtk.vfs.MountTracker>
|
||||||
include <abstractions/dconf-write>
|
include <abstractions/dconf-write>
|
||||||
include <abstractions/nameservice-strict>
|
include <abstractions/nameservice-strict>
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ include <tunables/global>
|
||||||
profile gio-launch-desktop @{exec_path} flags=(attach_disconnected) {
|
profile gio-launch-desktop @{exec_path} flags=(attach_disconnected) {
|
||||||
include <abstractions/base>
|
include <abstractions/base>
|
||||||
include <abstractions/app-launcher-user>
|
include <abstractions/app-launcher-user>
|
||||||
|
include <abstractions/bus-session>
|
||||||
include <abstractions/bus/org.gtk.vfs.Metadata>
|
include <abstractions/bus/org.gtk.vfs.Metadata>
|
||||||
include <abstractions/bus/org.gtk.vfs.MountTracker>
|
include <abstractions/bus/org.gtk.vfs.MountTracker>
|
||||||
include <abstractions/consoles>
|
include <abstractions/consoles>
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ profile gnome-characters @{exec_path} {
|
||||||
include <abstractions/nameservice-strict>
|
include <abstractions/nameservice-strict>
|
||||||
|
|
||||||
#aa:dbus own bus=session name=org.gnome.Characters
|
#aa:dbus own bus=session name=org.gnome.Characters
|
||||||
#aa-dbus own bus=session name=org.gnome.Characters.SearchProvider interface+=org.gnome.Shell.SearchProvider2
|
#aa-dbus talk bus=session name=org.gnome.Shell.SearchProvider2 label=gnome-shell
|
||||||
|
|
||||||
@{exec_path} mr,
|
@{exec_path} mr,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,12 @@ profile gnome-extension-gsconnect @{exec_path} {
|
||||||
include <abstractions/bus-session>
|
include <abstractions/bus-session>
|
||||||
include <abstractions/bus-system>
|
include <abstractions/bus-system>
|
||||||
include <abstractions/bus/org.a11y>
|
include <abstractions/bus/org.a11y>
|
||||||
|
include <abstractions/bus/org.freedesktop.NetworkManager>
|
||||||
|
include <abstractions/bus/org.gtk.Notifications>
|
||||||
|
include <abstractions/bus/org.gtk.Private.RemoteVolumeMonitor>
|
||||||
|
include <abstractions/bus/org.gtk.vfs.Daemon>
|
||||||
|
include <abstractions/bus/org.gtk.vfs.MountTracker>
|
||||||
|
include <abstractions/bus/org.mpris.MediaPlayer2.Player>
|
||||||
include <abstractions/dconf-write>
|
include <abstractions/dconf-write>
|
||||||
include <abstractions/gnome-strict>
|
include <abstractions/gnome-strict>
|
||||||
include <abstractions/nameservice-strict>
|
include <abstractions/nameservice-strict>
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ profile gnome-keyring-daemon @{exec_path} flags=(attach_disconnected) {
|
||||||
|
|
||||||
#aa:dbus own bus=session name=org.gnome.keyring
|
#aa:dbus own bus=session name=org.gnome.keyring
|
||||||
#aa:dbus own bus=session name=org.freedesktop.{S,s}ecret{,s}
|
#aa:dbus own bus=session name=org.freedesktop.{S,s}ecret{,s}
|
||||||
|
#aa:dbus own bus=session name=org.freedesktop.impl.portal.Secret
|
||||||
|
|
||||||
dbus receive bus=session
|
dbus receive bus=session
|
||||||
interface=org.freedesktop.DBus.Introspectable
|
interface=org.freedesktop.DBus.Introspectable
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,11 @@ profile gsd-print-notifications @{exec_path} flags=(attach_disconnected) {
|
||||||
# dbus receive bus=system path=/org/cups/cupsd/Notifier
|
# dbus receive bus=system path=/org/cups/cupsd/Notifier
|
||||||
# interface=org.cups.cupsd.Notifier,
|
# interface=org.cups.cupsd.Notifier,
|
||||||
|
|
||||||
|
dbus receive bus=system path=/org/cups/cupsd/Notifier
|
||||||
|
interface=org.cups.cupsd.Notifier
|
||||||
|
member=ServerStarted
|
||||||
|
peer=(name=@{busname}, label=cups-notifier-dbus),
|
||||||
|
|
||||||
dbus receive bus=session
|
dbus receive bus=session
|
||||||
interface=org.freedesktop.DBus.Introspectable
|
interface=org.freedesktop.DBus.Introspectable
|
||||||
member=Introspect
|
member=Introspect
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,8 @@ profile NetworkManager @{exec_path} flags=(attach_disconnected) {
|
||||||
|
|
||||||
dbus send bus=system path=/org/freedesktop
|
dbus send bus=system path=/org/freedesktop
|
||||||
interface=org.freedesktop.DBus.ObjectManager
|
interface=org.freedesktop.DBus.ObjectManager
|
||||||
member=InterfacesAdded
|
member={InterfacesAdded,InterfacesRemoved}
|
||||||
peer=(name=org.freedesktop.DBus, label=nm-online),
|
peer=(name=org.freedesktop.DBus),
|
||||||
|
|
||||||
@{exec_path} mr,
|
@{exec_path} mr,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ profile fwupd @{exec_path} flags=(attach_disconnected,complain) {
|
||||||
include <abstractions/bus/org.bluez>
|
include <abstractions/bus/org.bluez>
|
||||||
include <abstractions/bus/org.freedesktop.ModemManager1>
|
include <abstractions/bus/org.freedesktop.ModemManager1>
|
||||||
include <abstractions/bus/org.freedesktop.PolicyKit1>
|
include <abstractions/bus/org.freedesktop.PolicyKit1>
|
||||||
include <abstractions/bus/org.freedesktop.UDisks2>
|
|
||||||
include <abstractions/bus/org.freedesktop.UPower>
|
|
||||||
include <abstractions/consoles>
|
include <abstractions/consoles>
|
||||||
include <abstractions/disks-write>
|
include <abstractions/disks-write>
|
||||||
include <abstractions/fonts>
|
include <abstractions/fonts>
|
||||||
|
|
@ -38,7 +36,9 @@ profile fwupd @{exec_path} flags=(attach_disconnected,complain) {
|
||||||
network netlink raw,
|
network netlink raw,
|
||||||
|
|
||||||
#aa:dbus own bus=system name=org.freedesktop.fwupd path=/
|
#aa:dbus own bus=system name=org.freedesktop.fwupd path=/
|
||||||
|
#aa:dbus talk bus=system name=org.bluez.GattCharacteristic1 label=bluetoothd
|
||||||
#aa:dbus talk bus=system name=org.freedesktop.UDisks2 label=udisksd
|
#aa:dbus talk bus=system name=org.freedesktop.UDisks2 label=udisksd
|
||||||
|
#aa:dbus talk bus=system name=org.freedesktop.UPower label=upowerd
|
||||||
|
|
||||||
dbus receive bus=system path=/
|
dbus receive bus=system path=/
|
||||||
interface=org.freedesktop.DBus.ObjectManager
|
interface=org.freedesktop.DBus.ObjectManager
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,14 @@ include <tunables/global>
|
||||||
profile spotify @{exec_path} flags=(attach_disconnected) {
|
profile spotify @{exec_path} flags=(attach_disconnected) {
|
||||||
include <abstractions/base>
|
include <abstractions/base>
|
||||||
include <abstractions/audio-client>
|
include <abstractions/audio-client>
|
||||||
|
include <abstractions/bus-accessibility>
|
||||||
|
include <abstractions/bus-session>
|
||||||
|
include <abstractions/bus/org.a11y>
|
||||||
|
include <abstractions/bus/org.freedesktop.Notifications>
|
||||||
|
include <abstractions/bus/org.freedesktop.ScreenSaver>
|
||||||
|
include <abstractions/bus/org.freedesktop.secrets>
|
||||||
|
include <abstractions/bus/org.gtk.vfs.MountTracker>
|
||||||
|
include <abstractions/bus/org.kde.StatusNotifierWatcher>
|
||||||
include <abstractions/common/electron>
|
include <abstractions/common/electron>
|
||||||
include <abstractions/devices-usb-read>
|
include <abstractions/devices-usb-read>
|
||||||
|
|
||||||
|
|
@ -25,6 +33,9 @@ profile spotify @{exec_path} flags=(attach_disconnected) {
|
||||||
network inet6 stream,
|
network inet6 stream,
|
||||||
network netlink raw,
|
network netlink raw,
|
||||||
|
|
||||||
|
#aa:dbus own bus=session name=org.mpris.MediaPlayer2.spotify
|
||||||
|
#aa:dbus talk bus=session name=org.ayatana.NotificationItem label=gnome-shell
|
||||||
|
|
||||||
@{exec_path} mrix,
|
@{exec_path} mrix,
|
||||||
|
|
||||||
@{sh_path} mr,
|
@{sh_path} mr,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue