diff options
-rw-r--r-- | CMakeLists.txt | 12 | ||||
-rw-r--r-- | LICENSE | 2 | ||||
-rw-r--r-- | README.adoc | 3 | ||||
-rw-r--r-- | ddc-ci.c | 2 | ||||
-rw-r--r-- | genpass.c | 151 | ||||
-rw-r--r-- | wmstatus.c | 2 | ||||
-rw-r--r-- | wmstatus.conf.example | 3 |
7 files changed, 166 insertions, 9 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f1d4292..233ebde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ include_directories ( link_directories ( ${x_LIBRARY_DIRS} ${pulse_LIBRARY_DIRS} ${dbus_LIBRARY_DIRS}) -option (WITH_GDM "Compile with GDM support" ${gdm_FOUND}) +option (WITH_GDM "Compile with GDM utilities" ${gdm_FOUND}) # Generate a configuration file configure_file (${PROJECT_SOURCE_DIR}/config.h.in @@ -33,7 +33,7 @@ configure_file (${PROJECT_SOURCE_DIR}/config.h.in include_directories (${PROJECT_BINARY_DIR}) # Build -set (targets wmstatus paswitch siprandom) +set (targets wmstatus paswitch siprandom genpass) if ("${CMAKE_SYSTEM_NAME}" STREQUAL Linux) # These use Linux i2c APIs, but can be made to work on macOS list (APPEND targets brightness input-switch) @@ -58,9 +58,10 @@ target_link_libraries (wmstatus add_threads (wmstatus) if (WITH_GDM) - include_directories (${gdm_INCLUDE_DIRS}) - link_directories (${gdm_LIBRARY_DIRS}) + list (APPEND targets gdm-switch-user) add_executable (gdm-switch-user gdm-switch-user.c) + target_include_directories (gdm-switch-user PUBLIC ${gdm_INCLUDE_DIRS}) + target_link_directories (gdm-switch-user PUBLIC ${gdm_LIBRARY_DIRS}) target_link_libraries (gdm-switch-user ${gdm_LIBRARIES}) endif () @@ -95,6 +96,7 @@ endif () # These should be accessible by users, but need to touch system devices. # Use the setuid bit, for simplicity. +set (SETUID "SETUID" CACHE STRING "Set this empty on permission issues") foreach (target brightness input-switch) if (${target} IN_LIST targets) list (REMOVE_ITEM targets ${target}) @@ -103,7 +105,7 @@ foreach (target brightness input-switch) OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE - SETUID) + ${SETUID}) endif () endforeach () @@ -1,4 +1,4 @@ -Copyright (c) 2015 - 2024, Přemysl Eric Janouch <p@janouch.name> +Copyright (c) 2015 - 2025, Přemysl Eric Janouch <p@janouch.name> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. diff --git a/README.adoc b/README.adoc index 0bd0de4..9f2b5f4 100644 --- a/README.adoc +++ b/README.adoc @@ -37,7 +37,8 @@ Regular releases are sporadic. git master should be stable enough. Building -------- Build dependencies: CMake, pkg-config, liberty (included) + -Runtime dependencies: libpulse, libx11, dbus-1, libgdm (optional) +Runtime dependencies: libpulse, libx11, dbus-1 + +Optional runtime dependencies: libgdm (gdm-switch-user) $ git clone --recursive https://git.janouch.name/p/desktop-tools.git $ mkdir desktop-tools/build @@ -46,7 +46,7 @@ log_message_custom (void *user_data, const char *quote, const char *fmt, static void wait_ms (long ms) { - struct timespec ts = { 0, ms * 1000 * 1000 }; + struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; nanosleep (&ts, NULL); } diff --git a/genpass.c b/genpass.c new file mode 100644 index 0000000..623eecb --- /dev/null +++ b/genpass.c @@ -0,0 +1,151 @@ +/* + * genpass.c: password generator + * + * Copyright (c) 2025, Přemysl Eric Janouch <p@janouch.name> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "config.h" +#undef PROGRAM_NAME +#define PROGRAM_NAME "genpass" +#include "liberty/liberty.c" + +static struct str +parse_group (const char *group) +{ + bool present[0x100] = {}; + for (size_t i = 0; group[i]; i++) + { + unsigned char c = group[i]; + if (!i || c != '-' || !group[i + 1]) + present[c] = true; + else if (group[i + 1] < group[i - 1]) + exit_fatal ("character ranges must be increasing"); + else + for (c = group[i - 1]; ++c <= group[i + 1]; ) + present[c] = true; + } + + struct str alphabet = str_make (); + for (size_t i = 1; i < N_ELEMENTS (present); i++) + if (present[i]) + str_append_c (&alphabet, i); + if (!alphabet.len) + exit_fatal ("empty group"); + return alphabet; +} + +static void +parse_program_arguments (int argc, char **argv, + unsigned long *length, struct strv *groups, struct str *alphabet) +{ + static const struct opt opts[] = + { + { 'l', "length", "CHARACTERS", 0, "set password length" }, + { 'd', "debug", NULL, 0, "run in debug mode" }, + { 'h', "help", NULL, 0, "display this help and exit" }, + { 'V', "version", NULL, 0, "output version information and exit" }, + { 0, NULL, NULL, 0, NULL } + }; + + struct opt_handler oh = + opt_handler_make (argc, argv, opts, "GROUP...", "Password generator."); + + int c; + while ((c = opt_handler_get (&oh)) != -1) + switch (c) + { + case 'l': + if (!xstrtoul (length, optarg, 10) || *length <= 0) + print_fatal ("invalid length argument"); + break; + case 'd': + g_debug_mode = true; + break; + case 'h': + opt_handler_usage (&oh, stdout); + exit (EXIT_SUCCESS); + case 'V': + printf (PROGRAM_NAME " " PROGRAM_VERSION "\n"); + exit (EXIT_SUCCESS); + default: + print_error ("wrong options"); + opt_handler_usage (&oh, stderr); + exit (EXIT_FAILURE); + } + + argc -= optind; + argv += optind; + + for (int i = 0; i < argc; i++) + { + struct str alphabet = parse_group (argv[i]); + strv_append_owned (groups, str_steal (&alphabet)); + } + + bool present[0x100] = {}; + for (size_t i = 0; i < groups->len; i++) + for (size_t k = 0; groups->vector[i][k]; k++) + { + unsigned char c = groups->vector[i][k]; + if (present[c]) + exit_fatal ("groups are not disjunct"); + present[c] = true; + } + for (size_t i = 1; i < N_ELEMENTS (present); i++) + if (present[i]) + str_append_c (alphabet, i); + + if (groups->len > *length) + exit_fatal ("the requested length is less than the number of groups"); + if (!groups->len) + { + opt_handler_usage (&oh, stderr); + exit (EXIT_FAILURE); + } + + opt_handler_free (&oh); +} + +int +main (int argc, char *argv[]) +{ + unsigned long length = 8; + struct strv groups = strv_make (); + struct str alphabet = str_make (); + parse_program_arguments (argc, argv, &length, &groups, &alphabet); + + unsigned seed = 0; + if (!random_bytes (&seed, sizeof seed, NULL)) + exit_fatal ("failed to initialize random numbers"); + srand (seed); + + // Select from a joined alphabet, but make sure all groups are represented. + struct str candidate = str_make (); + while (true) + { +restart: + for (size_t i = length; i--; ) + str_append_c (&candidate, alphabet.str[rand () % alphabet.len]); + for (size_t i = 0; i < groups.len; i++) + if (!strpbrk (candidate.str, groups.vector[i])) + { + str_reset (&candidate); + goto restart; + } + + printf ("%s\n", candidate.str); + return 0; + } +} @@ -2249,7 +2249,7 @@ action_noise_adjust (struct app_context *ctx, const struct strv *args) long arg = strtol (args->vector[0], NULL, 10); ctx->noise_fadeout_samples = 0; ctx->noise_fadeout_iterator = 0; - if (!ctx->noise_end_time && (arg < 0 || !noise_start (ctx))) + if (!ctx->noise_end_time && (arg <= 0 || !noise_start (ctx))) return; time_t now = time (NULL); diff --git a/wmstatus.conf.example b/wmstatus.conf.example index 90b472f..8d6a7fb 100644 --- a/wmstatus.conf.example +++ b/wmstatus.conf.example @@ -57,4 +57,7 @@ keys = { "Control XF86AudioRaiseVolume" = "noise-adjust +1" "Control XF86AudioLowerVolume" = "noise-adjust -1" + + # Turns on or off Pioneer integrated amplifiers + "Mod4 Control Delete" = "exec elksmart-comm --nec A538" } |