Merge pull request #88603 from romildo/upd.enlightenment
enlightenment.enlightenment: 0.23.1 -> 0.24.0, cleanup and fixes
This commit is contained in:
		
						commit
						d4fc8a16a2
					
				@ -32,15 +32,14 @@ in
 | 
			
		||||
 | 
			
		||||
  config = mkIf cfg.enable {
 | 
			
		||||
 | 
			
		||||
    environment.systemPackages = [
 | 
			
		||||
      e.efl e.enlightenment
 | 
			
		||||
      e.terminology e.econnman
 | 
			
		||||
      pkgs.xorg.xauth # used by kdesu
 | 
			
		||||
      pkgs.gtk2 # To get GTK's themes.
 | 
			
		||||
      pkgs.tango-icon-theme
 | 
			
		||||
 | 
			
		||||
      pkgs.gnome-icon-theme
 | 
			
		||||
      pkgs.xorg.xcursorthemes
 | 
			
		||||
    environment.systemPackages = with pkgs; [
 | 
			
		||||
      enlightenment.econnman
 | 
			
		||||
      enlightenment.efl
 | 
			
		||||
      enlightenment.enlightenment
 | 
			
		||||
      enlightenment.ephoto
 | 
			
		||||
      enlightenment.rage
 | 
			
		||||
      enlightenment.terminology
 | 
			
		||||
      xorg.xcursorthemes
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    environment.pathsToLink = [
 | 
			
		||||
@ -50,11 +49,10 @@ in
 | 
			
		||||
      "/share/locale"
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    services.xserver.desktopManager.session = [
 | 
			
		||||
    { name = "Enlightenment";
 | 
			
		||||
      start = ''
 | 
			
		||||
        export XDG_MENU_PREFIX=e-
 | 
			
		||||
    services.xserver.displayManager.sessionPackages = [ pkgs.enlightenment.enlightenment ];
 | 
			
		||||
 | 
			
		||||
    services.xserver.displayManager.sessionCommands = ''
 | 
			
		||||
      if test "$XDG_CURRENT_DESKTOP" = "Enlightenment"; then
 | 
			
		||||
        export GST_PLUGIN_PATH="${GST_PLUGIN_PATH}"
 | 
			
		||||
 | 
			
		||||
        # make available for D-BUS user services
 | 
			
		||||
@ -62,12 +60,15 @@ in
 | 
			
		||||
 | 
			
		||||
        # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
 | 
			
		||||
        ${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update
 | 
			
		||||
      fi
 | 
			
		||||
    '';
 | 
			
		||||
 | 
			
		||||
        exec ${e.enlightenment}/bin/enlightenment_start
 | 
			
		||||
      '';
 | 
			
		||||
    }];
 | 
			
		||||
 | 
			
		||||
    security.wrappers = (import "${e.enlightenment}/e-wrappers.nix").security.wrappers;
 | 
			
		||||
    # Wrappers for programs installed by enlightenment that should be setuid
 | 
			
		||||
    security.wrappers = {
 | 
			
		||||
      enlightenment_ckpasswd.source = "${pkgs.enlightenment.enlightenment}/lib/enlightenment/utils/enlightenment_ckpasswd";
 | 
			
		||||
      enlightenment_sys.source = "${pkgs.enlightenment.enlightenment}/lib/enlightenment/utils/enlightenment_sys";
 | 
			
		||||
      enlightenment_system.source = "${pkgs.enlightenment.enlightenment}/lib/enlightenment/utils/enlightenment_system";
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    environment.etc."X11/xkb".source = xcfg.xkbDir;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -41,28 +41,24 @@ import ./make-test-python.nix ({ pkgs, ...} :
 | 
			
		||||
 | 
			
		||||
    with subtest("First time wizard"):
 | 
			
		||||
        machine.wait_for_text("Default")  # Language
 | 
			
		||||
        machine.succeed("xdotool mousemove 512 185 click 1")  # Default Language
 | 
			
		||||
        machine.screenshot("wizard1")
 | 
			
		||||
        machine.succeed("xdotool mousemove 512 740 click 1")  # Next
 | 
			
		||||
        machine.screenshot("wizard2")
 | 
			
		||||
 | 
			
		||||
        machine.wait_for_text("English")  # Keyboard (default)
 | 
			
		||||
        machine.screenshot("wizard2")
 | 
			
		||||
        machine.succeed("xdotool mousemove 512 740 click 1")  # Next
 | 
			
		||||
 | 
			
		||||
        machine.wait_for_text("Standard")  # Profile (default)
 | 
			
		||||
        machine.screenshot("wizard3")
 | 
			
		||||
        machine.succeed("xdotool mousemove 512 740 click 1")  # Next
 | 
			
		||||
 | 
			
		||||
        machine.wait_for_text("Title")  # Sizing (default)
 | 
			
		||||
        machine.wait_for_text("Standard")  # Profile (default)
 | 
			
		||||
        machine.screenshot("wizard4")
 | 
			
		||||
        machine.succeed("xdotool mousemove 512 740 click 1")  # Next
 | 
			
		||||
 | 
			
		||||
        machine.wait_for_text("clicked")  # Windows Phocus
 | 
			
		||||
        machine.succeed("xdotool mousemove 512 370 click 1")  # Click
 | 
			
		||||
        machine.wait_for_text("Title")  # Sizing (default)
 | 
			
		||||
        machine.screenshot("wizard5")
 | 
			
		||||
        machine.succeed("xdotool mousemove 512 740 click 1")  # Next
 | 
			
		||||
 | 
			
		||||
        machine.wait_for_text("bindings")  # Mouse Modifiers (default)
 | 
			
		||||
        machine.wait_for_text("clicked")  # Windows Focus
 | 
			
		||||
        machine.succeed("xdotool mousemove 512 370 click 1")  # Click
 | 
			
		||||
        machine.screenshot("wizard6")
 | 
			
		||||
        machine.succeed("xdotool mousemove 512 740 click 1")  # Next
 | 
			
		||||
 | 
			
		||||
@ -74,7 +70,7 @@ import ./make-test-python.nix ({ pkgs, ...} :
 | 
			
		||||
        machine.screenshot("wizard8")
 | 
			
		||||
        machine.succeed("xdotool mousemove 512 740 click 1")  # Next
 | 
			
		||||
 | 
			
		||||
        machine.wait_for_text("Compositing")  # Compositing (default)
 | 
			
		||||
        machine.wait_for_text("OpenGL")  # Compositing (default)
 | 
			
		||||
        machine.screenshot("wizard9")
 | 
			
		||||
        machine.succeed("xdotool mousemove 512 740 click 1")  # Next
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,114 @@
 | 
			
		||||
From a1e54ae0097a3b6a0dabf4639fe8bc594c4f602d Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Jos=C3=A9=20Romildo=20Malaquias?= <malaquias@gmail.com>
 | 
			
		||||
Date: Thu, 14 May 2020 16:36:34 -0300
 | 
			
		||||
Subject: [PATCH] wrapped setuid executables
 | 
			
		||||
 | 
			
		||||
Installing programs with root ownership and setuid/setgid permissions
 | 
			
		||||
in /nix/store is not allowed. They should be wrapped in the
 | 
			
		||||
enlightenment service module, and the wrapped ones should be used
 | 
			
		||||
instead.
 | 
			
		||||
---
 | 
			
		||||
 meson/meson_inst.sh           | 4 ++--
 | 
			
		||||
 src/bin/e_auth.c              | 6 ++----
 | 
			
		||||
 src/bin/e_fm/e_fm_main_eeze.c | 6 +++---
 | 
			
		||||
 src/bin/e_start_main.c        | 2 +-
 | 
			
		||||
 src/bin/e_system.c            | 2 +-
 | 
			
		||||
 5 files changed, 9 insertions(+), 11 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/meson/meson_inst.sh b/meson/meson_inst.sh
 | 
			
		||||
index 321143e40..cd2399306 100755
 | 
			
		||||
--- a/meson/meson_inst.sh
 | 
			
		||||
+++ b/meson/meson_inst.sh
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
 #!/bin/sh
 | 
			
		||||
 
 | 
			
		||||
 for x in "$@" ; do
 | 
			
		||||
-	chown root "$DESTDIR/$x"
 | 
			
		||||
-	chmod a=rx,u+xs "$DESTDIR/$x"
 | 
			
		||||
+	echo TODO: chown root "$DESTDIR/$x"
 | 
			
		||||
+	echo TODO: chmod a=rx,u+xs "$DESTDIR/$x"
 | 
			
		||||
 done
 | 
			
		||||
diff --git a/src/bin/e_auth.c b/src/bin/e_auth.c
 | 
			
		||||
index 8b0aa6641..63c68c4bc 100644
 | 
			
		||||
--- a/src/bin/e_auth.c
 | 
			
		||||
+++ b/src/bin/e_auth.c
 | 
			
		||||
@@ -12,8 +12,7 @@ e_auth_begin(char *passwd)
 | 
			
		||||
    if (pwlen == 0) goto out;
 | 
			
		||||
 
 | 
			
		||||
    snprintf(buf, sizeof(buf),
 | 
			
		||||
-            "%s/enlightenment/utils/enlightenment_ckpasswd pw",
 | 
			
		||||
-            e_prefix_lib_get());
 | 
			
		||||
+            "/run/wrappers/bin/enlightenment_ckpasswd pw");
 | 
			
		||||
    exe = ecore_exe_pipe_run(buf, ECORE_EXE_PIPE_WRITE, NULL);
 | 
			
		||||
    if (!exe) goto out;
 | 
			
		||||
    if (ecore_exe_send(exe, passwd, pwlen) != EINA_TRUE) goto out;
 | 
			
		||||
@@ -47,8 +46,7 @@ e_auth_polkit_begin(char *passwd, const char *cookie, unsigned int uid)
 | 
			
		||||
    if (pwlen == 0) goto out;
 | 
			
		||||
 
 | 
			
		||||
    snprintf(buf, sizeof(buf),
 | 
			
		||||
-            "%s/enlightenment/utils/enlightenment_ckpasswd pk",
 | 
			
		||||
-            e_prefix_lib_get());
 | 
			
		||||
+            "/run/wrappers/bin/enlightenment_ckpasswd pk");
 | 
			
		||||
    exe = ecore_exe_pipe_run(buf, ECORE_EXE_PIPE_WRITE, NULL);
 | 
			
		||||
    if (!exe) goto out;
 | 
			
		||||
    snprintf(buf, sizeof(buf), "%s %u %s", cookie, uid, passwd);
 | 
			
		||||
diff --git a/src/bin/e_fm/e_fm_main_eeze.c b/src/bin/e_fm/e_fm_main_eeze.c
 | 
			
		||||
index 9b10b3117..0f0aa5b53 100644
 | 
			
		||||
--- a/src/bin/e_fm/e_fm_main_eeze.c
 | 
			
		||||
+++ b/src/bin/e_fm/e_fm_main_eeze.c
 | 
			
		||||
@@ -318,7 +318,7 @@ _e_fm_main_eeze_volume_eject(E_Volume *v)
 | 
			
		||||
      {
 | 
			
		||||
         char buf[PATH_MAX];
 | 
			
		||||
 
 | 
			
		||||
-        snprintf(buf, sizeof(buf), "%s/enlightenment/utils/enlightenment_sys", eina_prefix_lib_get(pfx));
 | 
			
		||||
+        snprintf(buf, sizeof(buf), "/run/wrappers/bin/enlightenment_sys");
 | 
			
		||||
         eeze_disk_mount_wrapper_set(v->disk, buf);
 | 
			
		||||
      }
 | 
			
		||||
    v->guard = ecore_timer_loop_add(E_FM_EJECT_TIMEOUT, (Ecore_Task_Cb)_e_fm_main_eeze_vol_eject_timeout, v);
 | 
			
		||||
@@ -512,7 +512,7 @@ _e_fm_main_eeze_volume_unmount(E_Volume *v)
 | 
			
		||||
      {
 | 
			
		||||
         char buf[PATH_MAX];
 | 
			
		||||
 
 | 
			
		||||
-        snprintf(buf, sizeof(buf), "%s/enlightenment/utils/enlightenment_sys", eina_prefix_lib_get(pfx));
 | 
			
		||||
+        snprintf(buf, sizeof(buf), "/run/wrappers/bin/enlightenment_sys");
 | 
			
		||||
         eeze_disk_mount_wrapper_set(v->disk, buf);
 | 
			
		||||
      }
 | 
			
		||||
    v->guard = ecore_timer_loop_add(E_FM_UNMOUNT_TIMEOUT, (Ecore_Task_Cb)_e_fm_main_eeze_vol_unmount_timeout, v);
 | 
			
		||||
@@ -548,7 +548,7 @@ _e_fm_main_eeze_volume_mount(E_Volume *v)
 | 
			
		||||
      {
 | 
			
		||||
         char buf2[PATH_MAX];
 | 
			
		||||
 
 | 
			
		||||
-        snprintf(buf2, sizeof(buf2), "%s/enlightenment/utils/enlightenment_sys", eina_prefix_lib_get(pfx));
 | 
			
		||||
+        snprintf(buf2, sizeof(buf2), "/run/wrappers/bin/enlightenment_sys");
 | 
			
		||||
         eeze_disk_mount_wrapper_set(v->disk, buf2);
 | 
			
		||||
      }
 | 
			
		||||
    v->guard = ecore_timer_loop_add(E_FM_MOUNT_TIMEOUT, (Ecore_Task_Cb)_e_fm_main_eeze_vol_mount_timeout, v);
 | 
			
		||||
diff --git a/src/bin/e_start_main.c b/src/bin/e_start_main.c
 | 
			
		||||
index 8534a7a8e..f0f0061a4 100644
 | 
			
		||||
--- a/src/bin/e_start_main.c
 | 
			
		||||
+++ b/src/bin/e_start_main.c
 | 
			
		||||
@@ -709,7 +709,7 @@ main(int argc, char **argv)
 | 
			
		||||
             "E_ALERT_FONT_DIR=%s/data/fonts", eina_prefix_data_get(pfx));
 | 
			
		||||
    putenv(buf2);
 | 
			
		||||
    snprintf(buf3, sizeof(buf3),
 | 
			
		||||
-            "E_ALERT_SYSTEM_BIN=%s/enlightenment/utils/enlightenment_system", eina_prefix_lib_get(pfx));
 | 
			
		||||
+            "E_ALERT_SYSTEM_BIN=/run/wrappers/bin/enlightenment_system");
 | 
			
		||||
    putenv(buf3);
 | 
			
		||||
 
 | 
			
		||||
    if ((valgrind_mode || valgrind_tool) &&
 | 
			
		||||
diff --git a/src/bin/e_system.c b/src/bin/e_system.c
 | 
			
		||||
index 1e7aabb64..5084933a1 100644
 | 
			
		||||
--- a/src/bin/e_system.c
 | 
			
		||||
+++ b/src/bin/e_system.c
 | 
			
		||||
@@ -132,7 +132,7 @@ _system_spawn(void)
 | 
			
		||||
    else _respawn_count = 0;
 | 
			
		||||
    if (_respawn_count > 5) return;
 | 
			
		||||
    snprintf(buf, sizeof(buf),
 | 
			
		||||
-            "%s/enlightenment/utils/enlightenment_system", e_prefix_lib_get());
 | 
			
		||||
+            "/run/wrappers/bin/enlightenment_system");
 | 
			
		||||
    _system_exe = ecore_exe_pipe_run
 | 
			
		||||
      (buf, ECORE_EXE_NOT_LEADER | ECORE_EXE_TERM_WITH_PARENT |
 | 
			
		||||
       ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_WRITE, NULL);
 | 
			
		||||
-- 
 | 
			
		||||
2.26.2
 | 
			
		||||
 | 
			
		||||
@ -1,19 +1,29 @@
 | 
			
		||||
{ stdenv, fetchurl, meson, ninja, pkgconfig, gettext, alsaLib, bc,
 | 
			
		||||
  bzip2, efl, gdbm, libXdmcp, libXrandr, libcap, libffi,
 | 
			
		||||
  libpthreadstubs, libxcb, luajit, mesa, pam, pcre, xcbutilkeysyms,
 | 
			
		||||
  xkeyboard_config,
 | 
			
		||||
{ stdenv
 | 
			
		||||
, fetchurl
 | 
			
		||||
, meson
 | 
			
		||||
, ninja
 | 
			
		||||
, pkgconfig
 | 
			
		||||
, gettext
 | 
			
		||||
, alsaLib
 | 
			
		||||
, acpid
 | 
			
		||||
, bc
 | 
			
		||||
, ddcutil
 | 
			
		||||
, efl
 | 
			
		||||
, pam
 | 
			
		||||
, xkeyboard_config
 | 
			
		||||
, udisks2
 | 
			
		||||
 | 
			
		||||
  bluetoothSupport ? true, bluez5,
 | 
			
		||||
  pulseSupport ? !stdenv.isDarwin, libpulseaudio,
 | 
			
		||||
, bluetoothSupport ? true, bluez5
 | 
			
		||||
, pulseSupport ? !stdenv.isDarwin, libpulseaudio
 | 
			
		||||
}:
 | 
			
		||||
 | 
			
		||||
stdenv.mkDerivation rec {
 | 
			
		||||
  pname = "enlightenment";
 | 
			
		||||
  version = "0.23.1";
 | 
			
		||||
  version = "0.24.0";
 | 
			
		||||
 | 
			
		||||
  src = fetchurl {
 | 
			
		||||
    url = "http://download.enlightenment.org/rel/apps/${pname}/${pname}-${version}.tar.xz";
 | 
			
		||||
    sha256 = "0d1cyl07w9pvi2pf029kablazks2q9aislzl46b6fq5m1465jc75";
 | 
			
		||||
    sha256 = "01053hxdmyjfb6gmz1pqmw0llrgc4356np515h5vsqcn59mhvfz7";
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  nativeBuildInputs = [
 | 
			
		||||
@ -25,58 +35,35 @@ stdenv.mkDerivation rec {
 | 
			
		||||
 | 
			
		||||
  buildInputs = [
 | 
			
		||||
    alsaLib
 | 
			
		||||
    bc  # for the Everything module calculator mode
 | 
			
		||||
    bzip2
 | 
			
		||||
    acpid # for systems with ACPI for lid events, AC/Battery plug in/out etc
 | 
			
		||||
    bc # for the Everything module calculator mode
 | 
			
		||||
    ddcutil # specifically libddcutil.so.2 for backlight control
 | 
			
		||||
    efl
 | 
			
		||||
    gdbm
 | 
			
		||||
    libXdmcp
 | 
			
		||||
    libXrandr
 | 
			
		||||
    libffi
 | 
			
		||||
    libpthreadstubs
 | 
			
		||||
    libxcb
 | 
			
		||||
    luajit
 | 
			
		||||
    mesa
 | 
			
		||||
    pam
 | 
			
		||||
    pcre
 | 
			
		||||
    xcbutilkeysyms
 | 
			
		||||
    xkeyboard_config
 | 
			
		||||
    udisks2 # for removable storage mounting/unmounting
 | 
			
		||||
  ]
 | 
			
		||||
  ++ stdenv.lib.optional stdenv.isLinux libcap
 | 
			
		||||
  ++ stdenv.lib.optional bluetoothSupport bluez5
 | 
			
		||||
  ++ stdenv.lib.optional pulseSupport libpulseaudio
 | 
			
		||||
  ++ stdenv.lib.optional bluetoothSupport bluez5 # for bluetooth configuration and control
 | 
			
		||||
  ++ stdenv.lib.optional pulseSupport libpulseaudio # for proper audio device control and redirection
 | 
			
		||||
  ;
 | 
			
		||||
 | 
			
		||||
  patches = [
 | 
			
		||||
    # Some programs installed by enlightenment (to set the cpu frequency,
 | 
			
		||||
    # for instance) need root ownership and setuid/setgid permissions, which
 | 
			
		||||
    # are not allowed for files in /nix/store. Instead of allowing the
 | 
			
		||||
    # installer to try to do this, the file $out/e-wrappers.nix is created,
 | 
			
		||||
    # containing the needed configuration for wrapping those programs. It
 | 
			
		||||
    # can be used in the enlightenment module. The idea is:
 | 
			
		||||
    #
 | 
			
		||||
    #  1) rename the original binary adding the extension .orig
 | 
			
		||||
    #  2) wrap the renamed binary at /run/wrappers/bin/
 | 
			
		||||
    #  3) create a new symbolic link using the original binary name (in the
 | 
			
		||||
    #     original directory where enlightenment wants it) pointing to the
 | 
			
		||||
    #     wrapper
 | 
			
		||||
 | 
			
		||||
    ./enlightenment.suid-exes.patch
 | 
			
		||||
    # Executables cannot be made setuid in nix store. They should be
 | 
			
		||||
    # wrapped in the enlightenment service module, and the wrapped
 | 
			
		||||
    # executables should be used instead.
 | 
			
		||||
    ./0001-wrapped-setuid-executables.patch
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  postPatch = ''
 | 
			
		||||
    # edge_cc is a binary provided by efl and cannot be found at the directory
 | 
			
		||||
    # given by e_prefix_bin_get(), which is $out/bin
 | 
			
		||||
 | 
			
		||||
    substituteInPlace src/bin/e_import_config_dialog.c \
 | 
			
		||||
      --replace "e_prefix_bin_get()" "\"${efl}/bin\""
 | 
			
		||||
 | 
			
		||||
    substituteInPlace src/modules/everything/evry_plug_calc.c \
 | 
			
		||||
      --replace "ecore_exe_pipe_run(\"bc -l\"" "ecore_exe_pipe_run(\"${bc}/bin/bc -l\""
 | 
			
		||||
  '';
 | 
			
		||||
 | 
			
		||||
  mesonFlags = [ "-Dsystemdunitdir=lib/systemd/user" ];
 | 
			
		||||
  mesonFlags = [
 | 
			
		||||
    "-D systemdunitdir=lib/systemd/user"
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  enableParallelBuilding = true;
 | 
			
		||||
  passthru.providedSessions = [ "enlightenment" ];
 | 
			
		||||
 | 
			
		||||
  meta = with stdenv.lib; {
 | 
			
		||||
    description = "The Compositing Window Manager and Desktop Shell";
 | 
			
		||||
 | 
			
		||||
@ -1,25 +0,0 @@
 | 
			
		||||
--- enlightenment-0.22.0.orig/meson/meson_inst.sh	2017-09-25 10:55:43.000000000 -0300
 | 
			
		||||
+++ enlightenment-0.22.0/meson/meson_inst.sh	2017-11-15 08:31:03.336844920 -0200
 | 
			
		||||
@@ -1,6 +1,19 @@
 | 
			
		||||
-#!/bin/sh
 | 
			
		||||
+#!/bin/sh -x
 | 
			
		||||
+
 | 
			
		||||
+w="$out"/e-wrappers.nix
 | 
			
		||||
+
 | 
			
		||||
+echo "# Wrappers for programs installed by enlightenment that should be setuid" > $w
 | 
			
		||||
+echo "" >> $w
 | 
			
		||||
+echo "{" >> $w
 | 
			
		||||
+echo "  security.wrappers = {" >> $w
 | 
			
		||||
 
 | 
			
		||||
 for x in "$@" ; do
 | 
			
		||||
-	chown root "$DESTDIR/$x"
 | 
			
		||||
-	chmod a=rx,u+xs "$DESTDIR/$x"
 | 
			
		||||
+	f="$DESTDIR$x";
 | 
			
		||||
+	b=$(basename "$f".orig)
 | 
			
		||||
+	mv -v "$f" "$f".orig
 | 
			
		||||
+	ln -sv /run/wrappers/bin/"$b" "$f"
 | 
			
		||||
+	echo "    \"$b\".source = \"$f.orig\";" >> $w
 | 
			
		||||
 done
 | 
			
		||||
+
 | 
			
		||||
+echo "  };" >> $w
 | 
			
		||||
+echo "}" >> $w
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user