#!/usr/bin/env bash # # Yamada Hayao # Twitter: @Hayao0819 # Email : hayao@fascode.net # # (c) 2019-2021 Fascode Network. # # dmc # # LICENSE: THE SUSHI-WARE LICENSE # https://github.com/MakeNowJust/sushi-ware # # # 参考資料 # https://qiita.com/laikuaut/items/4bc07eabce56ee30812d # https://qiita.com/t_nakayama0714/items/80b4c94de43643f4be51 script_usage(){ echo "usage: dmc [options] [command]" echo echo "A simple tool for switching LightDM Greeters" echo echo " LightDM command:" echo " autologin [username] [session] Set up automatic login (with blank username to disable)" echo " greeter Run greeter setup wizard" echo " greeter-create [file] Set the specified executable file as Greeter" echo " greeter-change [greeter] Specify the greeter to use" echo " greeter-edit [greeter] Edit the greeter configs" echo " greeter-list Show a list of currently installed Greeters" echo " remove Removes all changes made by this command" echo " edit Edit lightdm config" echo " show-config Show current settings" echo echo " GDM command:" echo " autologin [username] [session] Set up automatic login (with blank username to disable)" echo " cursor Run cursor selection wizard" #echo " cursor-change [cursor] Specify the cursor theme" echo " cursor-list Show a list of cursor theme" echo " sound [true or false] Toggle the sound when an event occurs" echo " logo [image] Specify the logo of the login screen" echo " tap [true or false] Toggle whether to recognize the tap as a click" echo " accessibility [true or false] Toggle whether to show accessibility menu" echo " root-login [true or false] Toggle whether to enable root login" echo echo " Webkit2 command:" echo " theme Run theme selection wizard" echo " theme-change [theme] Specify the theme" echo echo " Qtquick command:" echo " back Specify the background image" echo echo " General option:" echo " -m | --mode Specifiy the target you want to set" echo " -e | --editer Specifiy the editor to use for editing" echo " -h | --help This help message and exit" echo " --non-interactive Run in non-interactive mode" echo " --noroot No check root permission" echo " --write-all-files Allows rewriting of all configuration files" echo echo " Supported modes:" echo " Display managers: lightdm, gdm" echo " LightDM greeters: webkit2, qtquick" echo } set -eu # エラー msg_error() { echo "${@}" 1>&2 } # 警告 msg_warn() { echo "${@}" 1>&2 } # rootチェック check_root(){ if [[ "${NOROOT}" = false ]] && (( "${UID}" != 0 )); then msg_error "You have to run as root" exit 1 fi } # 数値チェック check_int(){ set +e #if (( "$(expr "${1}" + 1 >/dev/null 2>&1; printf "${?}")" < 2 )); then if printf "%s" "${1}" | grep -E "^[0-9]+$" 1>/dev/null 2>&1; then set -e return 0 else set -e return 1 fi } check_bool(){ if [[ -n "${1}" ]] && { [[ "${1}" = "true" ]] ||[[ "${1}" = "false" ]]; }; then return 0 else return 1 fi } # crudini ラッパー wrapper(){ local _command="${1}" shift 1 if which "${_command}" >/dev/null 2>&1; then $(which "${_command}") "${@}" else msg_error "${_command} was not found" exit 1 fi } crudini(){ wrapper crudini "${@}" } jq(){ wrapper jq "${@}" } # カーソルテーマの一覧を取得 get_cursor_theme(){ # カーソルテーマの一覧を取得 # 参考: https://wiki.archlinux.jp/index.php/%E3%82%AB%E3%83%BC%E3%82%BD%E3%83%AB%E3%83%86%E3%83%BC%E3%83%9E # 参考: https://wiki.archlinux.jp/index.php/GDM #echo "Searching cursor themes..." 1>&2 local _dir _cursor_theme_dir_list _find_cursor_dir_list=("/usr/share/icons" "${HOME}/.local/share/icons" "${HOME}/.icons") for _dir in "${_find_cursor_dir_list[@]}"; do if [[ -d "${_dir}" ]]; then while read -r line; do _cursor_theme_dir_list+=("${line}") done < <(find "${_dir}" -type d -name "cursors" -print0 | xargs -0 -i dirname {} | sort) fi done unset _dir _find_cursor_dir_list local _cursor_theme _cursor_theme_name _name for _cursor_theme in "${_cursor_theme_dir_list[@]}"; do _name="$(grep -E "^Name=" "${_cursor_theme}/cursor.theme" 2> /dev/null | sed "s|^Name=||g")" if [[ -z "${_name}" ]]; then _name="$(basename "${_cursor_theme}")" fi _cursor_theme_name+=("${_name}") done echo "${_cursor_theme_name[@]}" } # GTKテーマの一覧を取得 get_gtk_theme(){ local _dir _find_theme_dir_list=("/usr/share/themes" "${HOME}/.local/share/themes" "${HOME}/.themes") for _dir in "${_find_theme_dir_list[@]}"; do if [[ -d "${_dir}" ]]; then while read -r line; do _gtk_theme_dir_list+=("${line}") done < <(find "${_dir}" -type d -name "gtk-*" -print0 | xargs -0 -i dirname {} | tr " " "\n" | sort | uniq) fi done local _theme_name for _dir in "${_gtk_theme_dir_list[@]}"; do _theme_name="$(crudini --get "${_dir}/index.theme" 'Desktop Entry' "Name" 2> /dev/null ;:)" if [[ -z "${_theme_name}" ]]; then continue else _gtk_theme_name_list+=("${_theme_name}") fi done printf "%s\n" "${_gtk_theme_name_list[@]}" | sort | uniq | tr "\n" " " } # 質問を行う関数 ask_question(){ local _choice=("${@}") } #== LightDM用の汎用関数 ==# # キーが設定されている設定ファイル lightdm_get_source_file(){ local key="${1}" local source_name="$(lightdm --show-config 2>&1 | grep -E "^[A-Z] ${key}=" | cut -d ' ' -f 1)" local source_path="$(lightdm --show-config 2>&1 | grep -x -A "$(lightdm --show-config 2>&1 | wc -l)" "Sources:" | grep -xv "Sources" | grep -E "^${source_name} " | sed "s|^${source_name} ||g")" if [[ -n "${source_path}" ]]; then echo -n "${source_path}" else echo -n "" fi } # 設定ファイルの値を変更する lightdm_set_config(){ local key="${1}" value="${2}" file=${3-${DISPLAY_MANAGER_CONFIG["lightdm"]}} if [[ "${WRITE_ALL_FILES}" = true ]] && [[ -n "$(lightdm_get_source_file "${1}")" ]]; then crudini --set "$(lightdm_get_source_file "${1}")" 'Seat:*' "${key}" "${value}" else crudini --set "${file}" 'Seat:*' "${key}" "${value}" fi if [[ ! "$(lightdm_get_value "${key}")" = "${value}" ]]; then msg_error "Failed to change the setting value. A value has already been set for $(lightdm_get_source_file "${1}")" msg_error "lightdm-config does not manipulate other configuration files for safety. Comment out the settings in that file." fi } # 設定ファイルのキーを削除する lightdm_remove_key(){ local key="${1}" _config if grep -E "^ ?${key}.+" "${DISPLAY_MANAGER_CONFIG["lightdm"]}" 1>/dev/null 2>&1; then sed -i -r "s|^ ?${key} ?=.+||g" "${DISPLAY_MANAGER_CONFIG["lightdm"]}" sed -i '/^$/d' "${DISPLAY_MANAGER_CONFIG["lightdm"]}" fi } # 設定ファイルを作成 lightdm_init_configs(){ check_root if [[ ! -f "${DISPLAY_MANAGER_CONFIG["lightdm"]}" ]]; then mkdir -p "$(dirname "${DISPLAY_MANAGER_CONFIG["lightdm"]}")" touch "${DISPLAY_MANAGER_CONFIG["lightdm"]}" echo "[Seat:*]" > "${DISPLAY_MANAGER_CONFIG["lightdm"]}" fi } # 現在設定されている値を取得する lightdm_get_value(){ local _current_value="$(lightdm --show-config 2>&1 | grep -E "^[A-Z] ${1}=" | sed "s|^[A-Z] ||g" | cut -d "=" -f "2")" if [[ "${_current_value}" ]]; then echo -n "${_current_value}" return 0 else echo -n "" return 0 fi } #== LightDM用コマンド ==# # greeter-changeコマンド command_lightdm_greeter_change() { # 引数チェック if [[ -z "${1}" ]] || [[ "${1}" = "" ]]; then msg_error "Please specify Greeter." script_usage exit 1 fi # 指定されたGreeterが正しいか確認 if ! printf "%s\n" "${LIGHTDM_GREETERS[@]}" | grep -x "${1}" > /dev/null 2>&2; then msg_error "The greeter (${1}) doesn't exist." exit 1 else lightdm_set_config "greeter-session" "${1}" fi } # greeter-createコマンド command_lightdm_greeter_create(){ if [[ -z "${1}" ]] || [[ "${1}" = "" ]]; then msg_error "Please specify Greeter." script_usage exit 1 fi if [[ ! -f "${1}" ]]; then msg_error "${1} does not exist." script_usage exit 1 fi if [[ ! -x "${1}" ]]; then msg_error "hoge is not an executable file." script_usage exit 1 fi local path="${1}" local filename="$(basename "${1}")" if [[ -f "/usr/share/xgreeters/${filename}.desktop" ]]; then msg_error "Greeter with the same name already exists." exit 1 fi cat > "/usr/share/xgreeters/${filename}.desktop" < " read -r _input local _recall _recall(){ echo "Please enter the correct value." run_greeter_wizard exit 0 } # 回答を解析 if check_int "${_input}"; then # 数字が入力された if (( 1 <= _input)) && (( _input <= ${#LIGHTDM_GREETERS[@]} )); then _greeter="${LIGHTDM_GREETERS[$(( _input - 1 ))]}" else _recall fi else # 文字が入力された if printf "%s\n" "${LIGHTDM_GREETERS[@]}" | grep -x "${_input}" 1>/dev/null 2>&1; then _greeter="${_input}" else _recall fi fi # 結果に応じて処理を実行 if [[ -n "${_greeter}" ]]; then command_lightdm_greeter_change "${_greeter}" else run_greeter_wizard exit 0 fi echo "Changed greeter to ${_greeter}" } # removeコマンド command_lightdm_remove(){ if [[ ! -f "${DISPLAY_MANAGER_CONFIG["lightdm"]}" ]]; then return 0 else local _yes_or_no echo -ne "Are you sure you want to delete all settings?\nThis change is irreversible.\n (y or n) > " read -r -n 1 _yes_or_no if [[ "${_yes_or_no}" = "y" ]]; then mv "${DISPLAY_MANAGER_CONFIG["lightdm"]}" "${DISPLAY_MANAGER_CONFIG["lightdm"]}.disabled" fi fi } # greeter-edit command_lightdm_greeter_edit(){ if [[ "${NON_INTERACTIVE}" = true ]]; then msg_error "You cannot use this command in non-interactive mode." exit 1 fi local _greeter="${1:-${LIGHTDM_CURRENT_GREETER}}" if [[ -z "${GREETER_CONFIG["${_greeter}"]+SET}" ]]; then msg_error "This Greeter is not currently supported." msg_error "Please report the problem here." msg_error "https://github.com/FascodeNet/lightdm-config/issues" exit 1 else if [[ -z "${1}" ]] || [[ "${1}" = "" ]]; then msg_warn "Greeter was not specified. Open the currently configured Greeter configuration file." echo -n "(Enter to continue) > " read -r fi set -u bash -c "${USE_EDITOR} ${GREETER_CONFIG["${_greeter}"]}" exit fi } # edit command_lightdm_edit(){ if [[ "${NON_INTERACTIVE}" = true ]]; then msg_error "You cannot use this command in non-interactive mode." exit 1 fi for _config in "${LIGHTDM_LOADED_CONFIG[@]}"; do echo -ne "Edit ${_config} ? (y or n)> " read -r -n 1 _yes_or_no echo if [[ "${_yes_or_no}" = "y" ]]; then bash -c "${USE_EDITOR} ${_config}" fi done } # autologin command_lightdm_auto_login(){ if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then # 既に自動ログインが設定されているかを確認 local autologin_user="$(lightdm_get_value autologin-user)" if [[ -n "${autologin_user}" ]]; then # autologinを無効化 for _autologin in "autologin-guest" "autologin-user" "autologin-user-timeout" "autologin-in-background" "autologin-session"; do remove_key "${_autologin}" done echo "Canceled automatic login of ${autologin_user}" fi else local autologin_user="${1}" autologin_session if [[ -v 2 ]]; then autologin_session="${2}" fi # ユーザーチェック if ! getent passwd "${autologin_user}" 1> /dev/null 2>&1; then echo "${autologin_user} is a non-existent user." exit 1 fi # セッションを設定 if [[ -z "${autologin_session+SET}" ]]; then if (( $(find "/usr/share/xsessions" -print0 -type f 2> /dev/null | xargs -0 -i basename {} | wc -l) <= 1 )); then autologin_session="$(find "/usr/share/xsessions" -print0 -type f 2> /dev/null | xargs -0 -i basename {} | sed 's|.desktop$||g')" elif [[ "${NON_INTERACTIVE}" = true ]]; then # 非対話モード # ~/.dmrcの値を設定します autologin_session="$(grep -E '^Session=' "${HOME}/.dmrc" 2> /dev/null | cut -d '=' -f 2)" if [[ -z "${autologin_session}" ]]; then msg_error "Failed to set the session." msg_error "Not specified and ~/.dmrc does not exist either." exit 1 fi else echo "Select the desktop session to autologin" local session for session in "/usr/share/xsessions/"*; do echo " ${session}" done echo -n "(session name) > " read -r session if [[ -f "/usr/share/xsessions/${session}.desktop" ]]; then autologin_session="${session}" else msg_error "Please enter the correct session name." exit 1 fi fi else # 既に値が設定済み if [[ ! -f "/usr/share/xsessions/${autologin_session}.desktop" ]]; then # 存在しないセッションが指定された場合 msg_error "This is a session (${autologin_session}) that does not exist." exit 1 fi fi # autologin グループを設定 if ! getent group "autologin" 1> /dev/null 2>&1; then LANG=C groupadd -r "autologin" fi LANG=C gpasswd -a "${autologin_user}" "autologin" # 設定を書き込み lightdm_set_config "autologin-guest" "false" lightdm_set_config "autologin-user" "${autologin_user}" lightdm_set_config "autologin-user-timeout" "0" lightdm_set_config "autologin-in-background" "false" lightdm_set_config "autologin-session" "${autologin_session}" echo "${autologin_user} will automatically log in with ${autologin_session}" fi } # show-config command_lightdm_show_config(){ lightdm --show-config 2>&1 } #== GDM用の汎用関数 ==# gdm_init_configs(){ check_root if [[ ! -f "/etc/dconf/profile/gdm" ]]; then mkdir -p "/etc/dconf/profile" touch "/etc/dconf/profile/gdm" echo -e "user-db:user\nsystem-db:gdm\nfile-db:/usr/share/gdm/greeter-dconf-defaults" > "/etc/dconf/profile/gdm" fi local _file for _file in "${DISPLAY_MANAGER_CONFIG["gdm-dconf"]}" "${DISPLAY_MANAGER_CONFIG["gdm-custom"]}"; do if [[ ! -f "${_file}" ]]; then mkdir -p "$(dirname "${_file}")" touch "${_file}" fi done } # gdm_dconf_set_config gdm_dconf_set_config(){ if check_int "${3}" || check_bool "${3}"; then crudini --set "${DISPLAY_MANAGER_CONFIG["gdm-dconf"]}" "${1}" "${2}" "${3}" else crudini --set "${DISPLAY_MANAGER_CONFIG["gdm-dconf"]}" "${1}" "${2}" "\"${3}\"" fi gdm_update } # gdm_dconf_get_value gdm_dconf_get_value(){ dconf dump / | crudini --get - "${1}" "${2}" } # gdm_custom_get_value
gdm_custom_get_value(){ crudini --get "${DISPLAY_MANAGER_CONFIG["gdm-custom"]}" "${1}" "${2}" } # gdm_custom_set_config
gdm_custom_set_config(){ if check_int "${3}" || check_bool "${3}"; then crudini --set "${DISPLAY_MANAGER_CONFIG["gdm-custom"]}" "${1}" "${2}" "${3}" else crudini --set "${DISPLAY_MANAGER_CONFIG["gdm-custom"]}" "${1}" "${2}" "\"${3}\"" fi gdm_update } gdm_update(){ dconf update } #== GDM用コマンド ==# command_gdm_logo(){ if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then msg_error "Please specify the image of background" exit 1 fi if [[ ! -f "${1}" ]]; then msg_error "${1} was not found." exit 1 fi local _backgrounf_file="/usr/share/backgrounds/gdm/background" mkdir -p "$(dirname "${_backgrounf_file}")" cp "${1}" "${_backgrounf_file}" chmod 644 "${_backgrounf_file}" gdm_dconf_set_config "org/gnome/login-screen" "logo" "${_backgrounf_file}" } command_gdm_cursor_wizard(){ # カーソル一覧を取得 local cursor_themes while read -r line; do cursor_themes+=("${line}"); done < <(get_cursor_theme) # 一覧を生成 local _c unset _cursor_theme echo "Please select the cursor theme to use." for (( _c=1; _c<=${#cursor_themes[@]}; _c++)); do _cursor_theme="${cursor_themes[$(( _c - 1 ))]}" echo " ${_c}: ${_cursor_theme}" unset _cursor_theme done # 質問する local _input echo -n "(1 ~ ${#cursor_themes[@]}) > " read -r _input local _recall _recall(){ echo "Please enter the correct value." command_gdm_cursor_wizard exit 0 } # 回答を解析 if check_int "${_input}"; then # 数字が入力された if (( 1 <= _input)) && (( _input <= ${#cursor_themes[@]} )); then _cursor_theme="${cursor_themes[$(( _input - 1 ))]}" else _recall fi else # 文字が入力された if printf "%s\n" "${cursor_themes[@]}" | grep -x "${_input}" 1>/dev/null 2>&1; then _cursor_theme="${_input}" else _recall fi fi if [[ -n "${_cursor_theme}" ]]; then command_gdm_cursor_change "${_cursor_theme}" else command_gdm_cursor_wizard exit 0 fi echo "Changed cursor to ${_cursor_theme}" } command_gdm_cursor_change(){ if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then msg_error "Please specify the cursor theme" exit 1 fi local cursor_themes while read -r line; do cursor_themes+=("${line}"); done < <(get_cursor_theme) if ! printf "%s\n" "${cursor_themes[@]}" | grep -x "${1}" 1>/dev/null 2>&1; then msg_error "The cursor theme (${1}) was not found" exit 1 fi gdm_dconf_set_config "org/gnome/desktop/interface" "cursor-theme" "${1}" } command_gdm_sound(){ local _arg="$(echo "${1-""}" | tr "[:upper:]" "[:lower:]")" if ! check_bool "${_arg}"; then msg_error "Please specify true or false" script_usage exit 1 fi gdm_dconf_set_config "org/gnome/desktop/sound" "event-sounds" "${_arg}" } command_gdm_tap(){ local _arg="$(echo "${1-""}" | tr "[:upper:]" "[:lower:]")" if ! check_bool "${_arg}"; then msg_error "Please specify true or false" script_usage exit 1 fi gdm_dconf_set_config "org/gnome/desktop/peripherals/touchpad" "tap-to-click" "${_arg}" } # autologin command_gdm_auto_login(){ if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then # 既に自動ログインが設定されているかを確認 local autologin="$(gdm_custom_get_value daemon AutomaticLoginEnable)" if [[ "${autologin}" = "True" ]]; then gdm_custom_set_config "daemon" "AutomaticLoginEnable" "False" echo "Canceled automatic login of $(gdm_custom_get_value "daemon" "AutomaticLogin")" fi else local autologin_user="${1}" autologin_session if [[ -v 2 ]]; then autologin_session="${2}" fi # ユーザーチェック if ! getent passwd "${autologin_user}" 1> /dev/null 2>&1; then echo "${autologin_user} is a non-existent user." exit 1 fi # セッションを設定 (WayLandのセッションは現在サポートされていません) if [[ -z "${autologin_session+SET}" ]]; then if (( $(find "/usr/share/xsessions" -print0 -type f 2> /dev/null | xargs -0 -i basename {} | wc -l) <= 1 )); then autologin_session="$(find "/usr/share/xsessions" -print0 -type f 2> /dev/null | xargs -0 -i basename {} | sed 's|.desktop$||g')" elif [[ "${NON_INTERACTIVE}" = true ]]; then # 非対話モード # ~/.dmrcの値を設定します autologin_session="$(grep -E '^Session=' "${HOME}/.dmrc" 2> /dev/null | cut -d '=' -f 2)" if [[ -z "${autologin_session}" ]]; then msg_error "Failed to set the session." msg_error "Not specified and ~/.dmrc does not exist either." exit 1 fi else echo "Select the desktop session to autologin" local session for session in "/usr/share/xsessions/"*; do echo " $(basename "${session}" | sed "s|.desktop$||g")" done echo -n "(session name) > " read -r session if [[ -f "/usr/share/xsessions/${session}.desktop" ]]; then autologin_session="${session}" else msg_error "Please enter the correct session name." exit 1 fi fi else # 既に値が設定済み if [[ ! -f "/usr/share/xsessions/${autologin_session}.desktop" ]]; then # 存在しないセッションが指定された場合 msg_error "This is a session (${autologin_session}) that does not exist." exit 1 fi fi # autologin グループを設定 if ! getent group "autologin" 1> /dev/null 2>&1; then LANG=C groupadd -r "autologin" fi LANG=C gpasswd -a "${autologin_user}" "autologin" # 設定を書き込み gdm_custom_set_config "daemon" "AutomaticLoginEnable" "True" gdm_custom_set_config "daemon" "AutomaticLogin" "${autologin_user}" # セッションを指定 crudini --set "/var/lib/AccountsService/users/${autologin_user}" "User" "Session" "${autologin_session}" crudini --set "/var/lib/AccountsService/users/${autologin_user}" "User" "XSession" "${autologin_session}" echo "${autologin_user} will automatically log in with ${autologin_session}" fi } # accessibility コマンド command_gdm_accessibility(){ local _arg="$(echo "${1-""}" | tr "[:upper:]" "[:lower:]")" if ! check_bool "${_arg}"; then msg_error "Please specify true or false" script_usage exit 1 fi gdm_dconf_set_config "org/gnome/desktop/interface" "toolkit-accessibility" "${_arg}" } # root-login コマンド command_gdm_root_login(){ local _arg="$(echo "${1-""}" | tr "[:upper:]" "[:lower:]")" if ! check_bool "${_arg}"; then msg_error "Please specify true or false" script_usage exit 1 fi gdm_custom_set_config "daemon" "AllowRoot" "${_arg}" } #== Webkit2用の汎用関数 ==# webkit2_init_configs(){ check_root if [[ ! -f "${GREETER_CONFIG["lightdm-webkit2-greeter"]}" ]]; then mkdir -p "$(dirname "${GREETER_CONFIG["lightdm-webkit2-greeter"]}")" touch "${GREETER_CONFIG["lightdm-webkit2-greeter"]}" fi } # webkit2_get_value
webkit2_get_value(){ crudini --get "${GREETER_CONFIG["lightdm-webkit2-greeter"]}" "${1}" "${2}" } # webkit2_set_config
webkit2_set_config(){ crudini --set "${GREETER_CONFIG["lightdm-webkit2-greeter"]}" "${1}" "${2}" "${3}" } #== webkit2用コマンド ==# command_webkit2_theme_wizard(){ local _theme_list while read -r line; do _theme_list+=("${line}") done < <(ls /usr/share/lightdm-webkit/themes) local _current_theme=$(webkit2_get_value greeter webkit_theme | sed "s|\"||g") local _theme _c echo "Please select the theme to use." for (( _c=1; _c<=${#_theme_list[@]}; _c++)); do _theme="${_theme_list[$(( _c - 1 ))]}" if [[ "${_theme}" = "${_current_theme}" ]]; then echo " * ${_c}: ${_theme}" else echo " ${_c}: ${_theme}" fi unset _theme done # 質問する local _input echo -n "(1 ~ ${#_theme_list[@]}) > " read -r _input # shellcheck disable=SC2034 local _recall _recall(){ echo "Please enter the correct value." command_webkit2_theme_wizard exit 0 } # 回答を解析 if check_int "${_input}"; then # 数字が入力された if (( 1 <= _input)) && (( _input <= ${#_theme_list[@]} )); then _theme="${_theme_list[$(( _input - 1 ))]}" else _recall fi else # 文字が入力された if printf "%s\n" "${_theme_list[@]}" | grep -x "${_input}" 1>/dev/null 2>&1; then _theme="${_input}" else _recall fi fi if [[ -n "${_theme}" ]]; then command_webkit2_theme_change "${_theme}" echo "Changed the theme to ${_theme}" else command_webkit2_theme_wizard exit 0 fi } command_webkit2_theme_change(){ if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then msg_error "Please specify the theme name" exit 1 fi if [[ ! -d "/usr/share/lightdm-webkit/themes/${1}" ]]; then msg_error "The specified theme (${1}) does not exist" exit 1 fi webkit2_set_config "greeter" "webkit_theme" "${1}" } #== Qtquick用の汎用関数 ==# qtquick_init_configs(){ check_root if [[ ! -f "${GREETER_CONFIG["lightdm-qtquick-greeter"]}" ]] || [[ -z "$(cat "${GREETER_CONFIG["lightdm-qtquick-greeter"]}")" ]]; then mkdir -p "$(dirname "${GREETER_CONFIG["lightdm-qtquick-greeter"]}")" touch "${GREETER_CONFIG["lightdm-qtquick-greeter"]}" #echo -e "{\n\n}\n" > "${GREETER_CONFIG["lightdm-qtquick-greeter"]}" qtquick_set_config background_path "file:///hoge/fuga.png" qtquick_set_config theme "qrc:/Login.qml" fi } #qtquick_get_value qtquick_get_value(){ jq ".${1}" < "${GREETER_CONFIG["lightdm-qtquick-greeter"]}" } # command_qtquick_back qtquick_set_config(){ local _tempfile="/tmp/$(basename "${GREETER_CONFIG["lightdm-qtquick-greeter"]}")-$(base64 < "/dev/urandom" | fold -w 10 | head -n 1)" cp "${GREETER_CONFIG["lightdm-qtquick-greeter"]}" "${_tempfile}" #cat "${_tempfile}" | jq -r ".${1}|=\"${2}\"" > "${GREETER_CONFIG["lightdm-qtquick-greeter"]}" jq -r ".${1}|=\"${2}\"" < "${_tempfile}" > "${GREETER_CONFIG["lightdm-qtquick-greeter"]}" chmod 644 "${GREETER_CONFIG["lightdm-qtquick-greeter"]}" } #== Qtquick用コマンド ==# command_qtquick_back(){ if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then msg_error "Please specify the image of background" exit 1 fi if [[ ! -f "${1}" ]]; then msg_error "${1} was not found." exit 1 fi local _backgrounf_file="/usr/share/backgrounds/lightdm/qtquick-greeter" mkdir -p "$(dirname "${_backgrounf_file}")" cp "${1}" "${_backgrounf_file}" chmod 644 "${_backgrounf_file}" qtquick_set_config "background_path" "file://${_backgrounf_file}" } #== slick用の汎用関数 ==# slick_get_value(){ crudini --get "${GREETER_CONFIG["slick"]}" "Greeter" "${1}" } slick_set_config(){ crudini --set "${GREETER_CONFIG["slick"]}" "Greeter" "${1}" "${2}" } slick_init_configs(){ check_root if [[ -f "${GREETER_CONFIG["slick"]}" ]]; then mkdir -p "$(dirname "${GREETER_CONFIG["slick"]}")" touch "${GREETER_CONFIG["slick"]}" echo "[Greeter]" > "${GREETER_CONFIG["slick"]}" fi } command_slick_grid(){ local _arg="$(echo "${1-""}" | tr "[:upper:]" "[:lower:]")" if ! check_bool "${_arg}"; then msg_error "Please specify true or false" script_usage exit 1 fi slick_set_config "draw-grid" "${_arg}" } command_slick_back(){ if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then msg_error "Please specify the image of background" exit 1 fi if [[ ! -f "${1}" ]]; then msg_error "${1} was not found." exit 1 fi local _backgrounf_file="/usr/share/backgrounds/lightdm/slick-greeter" mkdir -p "$(dirname "${_backgrounf_file}")" cp "${1}" "${_backgrounf_file}" chmod 644 "${_backgrounf_file}" slick_set_config "background" "${_backgrounf_file}" } command_slick_theme_wizard(){ local gtk_themes while read -r line; do gtk_themes+=("${line}"); done < <(get_gtk_theme) } # 変数を設定 declare -A GREETER_CONFIG=( ["lightdm-webkit2-greeter"]="/etc/lightdm/lightdm-webkit2-greeter.conf" ["lightdm-slick-greeter"]="/etc/lightdm/slick-greeter.conf" ["lightdm-gtk-greeter"]="/etc/lightdm/lightdm-gtk-greeter.conf" ["io.elementary.greeter"]="/etc/lightdm/io.elementary.greeter.conf" ["lightdm-mini-greeter"]="/etc/lightdm/lightdm-mini-greeter.conf" ["lightdm-qtquick-greeter"]="/etc/lightdm/lightdm-qtquick-greeter.json" ) declare -A DISPLAY_MANAGER_CONFIG=( ["lightdm"]="/etc/lightdm/lightdm.conf.d/00-dmc-lightdm.conf" ["gdm-dconf"]="/etc/dconf/db/gdm.d/00-dmc-gdm" ["gdm-custom"]="/etc/gdm/custom.conf" ) #== CONFIGS ==# # LightDM - Greeterのディレクトリ LIGHTDM_GREETERS_DIR="$(lightdm_get_value "greeters-directory")" : "${LIGHTDM_GREETERS_DIR:="/usr/share/xgreeters"}" # LightDM - Greeter一覧 #LIGHTDM_GREETERS=( $( ) while read -r line; do LIGHTDM_GREETERS+=("${line}") done < <( (find "${LIGHTDM_GREETERS_DIR}" -print0 -type f | xargs -0 -i basename {} | sed "s|.desktop$||g") 2> /dev/null ) # LightDM - 現在設定されているGreeter LIGHTDM_CURRENT_GREETER="$(lightdm --show-config 2>&1 | grep "greeter-session" | cut -d "=" -f 2)" : "${LIGHTDM_CURRENT_GREETER:="lightdm-gtk-greeter"}" # LightDM - 読み込まれた設定ファイルの一覧 while read -r line; do LIGHTDM_LOADED_CONFIG+=("${line}") done < <(printf "%s\n" "$(lightdm --show-config 2>&1 | grep -x -A "$(lightdm --show-config 2>&1 | wc -l)" "Sources:" | grep -v "Sources" | sed 's|^[A-Z] ||g')" | tr -d " ") # Global - エディタ USE_EDITOR="${EDITOR:-vi}" # モード DISPLAY_MANAGER="$(basename "$(readlink "/etc/systemd/system/display-manager.service")" | sed "s|.service$||g")" : "${DISPLAY_MANAGER:="lightdm"}" # dmc config NON_INTERACTIVE=false WRITE_ALL_FILES=false NOROOT=false #== 引数解析 ==# ARGUMENT="${*}" OPTS="m:e:h" OPTL="mode:,editor:,help,non-interactive,noroot,write-all-files" # shellcheck disable=SC2086 if ! OPT="$(getopt -o ${OPTS} -l ${OPTL} -- ${ARGUMENT})"; then exit 1 fi eval set -- "${OPT}" unset OPT OPTS OPTL while true; do case "${1}" in -m | --mode) DISPLAY_MANAGER="${2}" shift 2 ;; -e | --editor) USE_EDITOR="${2}" shift 2 ;; -h | --help) script_usage exit 0 ;; --non-interactive) NON_INTERACTIVE=true shift 1 ;; --noroot) NOROOT=true shift 1 ;; --write-all-files) WRITE_ALL_FILES=true shift 1 ;; --) shift 1 break ;; esac done COMMAND="${1:-null}" if (( "${#}" >= 1 )); then shift 1 fi COMMAND_ARGS="${*}" : "${COMMAND_ARGS-""}" # サブコマンドの引数が何も指定されなかった場合に空文字を代入 if [[ "${COMMAND}" = "null" ]]; then script_usage exit 1 fi case "${DISPLAY_MANAGER}" in "lightdm") case "${COMMAND}" in "autologin") lightdm_init_configs command_lightdm_auto_login "${COMMAND_ARGS}" ;; "greeter") lightdm_init_configs run_greeter_wizard ;; "greeter-change") lightdm_init_configs command_lightdm_greeter_change "${COMMAND_ARGS}" ;; "greeter-create") lightdm_init_configs command_lightdm_greeter_create "${COMMAND_ARGS}" ;; "greeter-list") command_lightdm_greeter_list ;; "greeter-edit") check_root command_lightdm_greeter_edit "${COMMAND_ARGS}" ;; "remove") check_root command_lightdm_remove ;; "edit") check_root command_lightdm_edit ;; "show-config") command_lightdm_show_config ;; *) msg_error "Undefined commnad(${COMMAND})" ;; esac ;; "gdm") case "${COMMAND}" in "autologin") gdm_init_configs command_gdm_auto_login "${COMMAND_ARGS}" ;; "cursor") gdm_init_configs command_gdm_cursor_wizard ;; "sound") gdm_init_configs command_gdm_sound "${COMMAND_ARGS}" ;; "logo") gdm_init_configs command_gdm_logo "${COMMAND_ARGS}" ;; "tap") gdm_init_configs command_gdm_tap "${COMMAND_ARGS}" ;; "accessibility") gdm_init_configs command_gdm_accessibility "${COMMAND_ARGS}" ;; "root-login") gdm_init_configs command_gdm_root_login "${COMMAND_ARGS}" ;; *) msg_error "Undefined commnad(${COMMAND})" ;; esac ;; "webkit2") case "${COMMAND}" in "theme") webkit2_init_configs command_webkit2_theme_wizard ;; "theme-change") webkit2_init_configs command_webkit2_theme_change "${COMMAND_ARGS}" ;; *) msg_error "Undefined commnad(${COMMAND})" ;; esac ;; "qtquick") case "${COMMAND}" in "back") qtquick_init_configs command_qtquick_back "${COMMAND_ARGS}" ;; esac ;; "slick") case "${COMMAND}" in "back") slick_init_configs command_slick_back "${COMMAND_ARGS}" ;; "grid") slick_init_configs command_slick_grid "${COMMAND_ARGS}" ;; "icon") slick_init_configs command_slick_icon_wizard ;; "theme") slick_init_configs command_slick_theme_wizard ;; "other-monitor") slick_init_configs command_slick_other_monitor "${COMMAND_ARGS}" ;; "logo") slick_init_configs command_slick_logo "${COMMAND_ARGS}" ;; esac ;; *) msg_error "A display manager that is not currently supported." exit 1 ;; esac exit 0