Implement logging and remove wlroots dependency
This implements a simpler version of the wlroots logger for swaylock. With this logger, the dependency on wlroots can be dropped. This also adds a debug flag and disables debugging output by default
This commit is contained in:
parent
fcf1bd4ebe
commit
e3935ad143
@ -33,7 +33,6 @@ channel or shoot an email to sir@cmpwn.com for advice.
|
|||||||
Install dependencies:
|
Install dependencies:
|
||||||
|
|
||||||
* meson \*
|
* meson \*
|
||||||
* [wlroots](https://github.com/swaywm/wlroots)
|
|
||||||
* wayland
|
* wayland
|
||||||
* wayland-protocols \*
|
* wayland-protocols \*
|
||||||
* pango
|
* pango
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <wlr/util/log.h>
|
|
||||||
#include "background-image.h"
|
#include "background-image.h"
|
||||||
#include "cairo.h"
|
#include "cairo.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
enum background_mode parse_background_mode(const char *mode) {
|
enum background_mode parse_background_mode(const char *mode) {
|
||||||
if (strcmp(mode, "stretch") == 0) {
|
if (strcmp(mode, "stretch") == 0) {
|
||||||
@ -18,7 +18,7 @@ enum background_mode parse_background_mode(const char *mode) {
|
|||||||
} else if (strcmp(mode, "solid_color") == 0) {
|
} else if (strcmp(mode, "solid_color") == 0) {
|
||||||
return BACKGROUND_MODE_SOLID_COLOR;
|
return BACKGROUND_MODE_SOLID_COLOR;
|
||||||
}
|
}
|
||||||
wlr_log(WLR_ERROR, "Unsupported background mode: %s", mode);
|
swaylock_log(LOG_ERROR, "Unsupported background mode: %s", mode);
|
||||||
return BACKGROUND_MODE_INVALID;
|
return BACKGROUND_MODE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ cairo_surface_t *load_background_image(const char *path) {
|
|||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &err);
|
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &err);
|
||||||
if (!pixbuf) {
|
if (!pixbuf) {
|
||||||
wlr_log(WLR_ERROR, "Failed to load background image (%s).",
|
swaylock_log(LOG_ERROR, "Failed to load background image (%s).",
|
||||||
err->message);
|
err->message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -38,11 +38,11 @@ cairo_surface_t *load_background_image(const char *path) {
|
|||||||
image = cairo_image_surface_create_from_png(path);
|
image = cairo_image_surface_create_from_png(path);
|
||||||
#endif // HAVE_GDK_PIXBUF
|
#endif // HAVE_GDK_PIXBUF
|
||||||
if (!image) {
|
if (!image) {
|
||||||
wlr_log(WLR_ERROR, "Failed to read background image.");
|
swaylock_log(LOG_ERROR, "Failed to read background image.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (cairo_surface_status(image) != CAIRO_STATUS_SUCCESS) {
|
if (cairo_surface_status(image) != CAIRO_STATUS_SUCCESS) {
|
||||||
wlr_log(WLR_ERROR, "Failed to read background image: %s."
|
swaylock_log(LOG_ERROR, "Failed to read background image: %s."
|
||||||
#if !HAVE_GDK_PIXBUF
|
#if !HAVE_GDK_PIXBUF
|
||||||
"\nSway was compiled without gdk_pixbuf support, so only"
|
"\nSway was compiled without gdk_pixbuf support, so only"
|
||||||
"\nPNG images can be loaded. This is the likely cause."
|
"\nPNG images can be loaded. This is the likely cause."
|
||||||
|
36
include/log.h
Normal file
36
include/log.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef _SWAYLOCK_LOG_H
|
||||||
|
#define _SWAYLOCK_LOG_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
enum log_importance {
|
||||||
|
LOG_SILENT = 0,
|
||||||
|
LOG_ERROR = 1,
|
||||||
|
LOG_INFO = 2,
|
||||||
|
LOG_DEBUG = 3,
|
||||||
|
LOG_IMPORTANCE_LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
void swaylock_log_init(enum log_importance verbosity);
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define _ATTRIB_PRINTF(start, end) __attribute__((format(printf, start, end)))
|
||||||
|
#else
|
||||||
|
#define _ATTRIB_PRINTF(start, end)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void _swaylock_log(enum log_importance verbosity, const char *format, ...)
|
||||||
|
_ATTRIB_PRINTF(2, 3);
|
||||||
|
|
||||||
|
const char *_swaylock_strip_path(const char *filepath);
|
||||||
|
|
||||||
|
#define swaylock_log(verb, fmt, ...) \
|
||||||
|
_swaylock_log(verb, "[%s:%d] " fmt, _swaylock_strip_path(__FILE__), \
|
||||||
|
__LINE__, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define swaylock_log_errno(verb, fmt, ...) \
|
||||||
|
swaylock_log(verb, fmt ": %s", ##__VA_ARGS__, strerror(errno))
|
||||||
|
|
||||||
|
#endif
|
68
log.c
Normal file
68
log.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#define _POSIX_C_SOURCE 199506L
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
static enum log_importance log_importance = LOG_ERROR;
|
||||||
|
|
||||||
|
static const char *verbosity_colors[] = {
|
||||||
|
[LOG_SILENT] = "",
|
||||||
|
[LOG_ERROR ] = "\x1B[1;31m",
|
||||||
|
[LOG_INFO ] = "\x1B[1;34m",
|
||||||
|
[LOG_DEBUG ] = "\x1B[1;30m",
|
||||||
|
};
|
||||||
|
|
||||||
|
void swaylock_log_init(enum log_importance verbosity) {
|
||||||
|
if (verbosity < LOG_IMPORTANCE_LAST) {
|
||||||
|
log_importance = verbosity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _swaylock_log(enum log_importance verbosity, const char *fmt, ...) {
|
||||||
|
if (verbosity > log_importance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
// prefix the time to the log message
|
||||||
|
struct tm result;
|
||||||
|
time_t t = time(NULL);
|
||||||
|
struct tm *tm_info = localtime_r(&t, &result);
|
||||||
|
char buffer[26];
|
||||||
|
|
||||||
|
// generate time prefix
|
||||||
|
strftime(buffer, sizeof(buffer), "%F %T - ", tm_info);
|
||||||
|
fprintf(stderr, "%s", buffer);
|
||||||
|
|
||||||
|
unsigned c = (verbosity < LOG_IMPORTANCE_LAST)
|
||||||
|
? verbosity : LOG_IMPORTANCE_LAST - 1;
|
||||||
|
|
||||||
|
if (isatty(STDERR_FILENO)) {
|
||||||
|
fprintf(stderr, "%s", verbosity_colors[c]);
|
||||||
|
}
|
||||||
|
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
|
||||||
|
if (isatty(STDERR_FILENO)) {
|
||||||
|
fprintf(stderr, "\x1B[0m");
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *_swaylock_strip_path(const char *filepath) {
|
||||||
|
if (*filepath == '.') {
|
||||||
|
while (*filepath == '.' || *filepath == '/') {
|
||||||
|
++filepath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filepath;
|
||||||
|
}
|
8
loop.c
8
loop.c
@ -7,8 +7,8 @@
|
|||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wlr/util/log.h>
|
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
#include "log.h"
|
||||||
#include "loop.h"
|
#include "loop.h"
|
||||||
|
|
||||||
struct loop_fd_event {
|
struct loop_fd_event {
|
||||||
@ -34,7 +34,7 @@ struct loop {
|
|||||||
struct loop *loop_create(void) {
|
struct loop *loop_create(void) {
|
||||||
struct loop *loop = calloc(1, sizeof(struct loop));
|
struct loop *loop = calloc(1, sizeof(struct loop));
|
||||||
if (!loop) {
|
if (!loop) {
|
||||||
wlr_log(WLR_ERROR, "Unable to allocate memory for loop");
|
swaylock_log(LOG_ERROR, "Unable to allocate memory for loop");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
loop->fd_capacity = 10;
|
loop->fd_capacity = 10;
|
||||||
@ -107,7 +107,7 @@ void loop_add_fd(struct loop *loop, int fd, short mask,
|
|||||||
void (*callback)(int fd, short mask, void *data), void *data) {
|
void (*callback)(int fd, short mask, void *data), void *data) {
|
||||||
struct loop_fd_event *event = calloc(1, sizeof(struct loop_fd_event));
|
struct loop_fd_event *event = calloc(1, sizeof(struct loop_fd_event));
|
||||||
if (!event) {
|
if (!event) {
|
||||||
wlr_log(WLR_ERROR, "Unable to allocate memory for event");
|
swaylock_log(LOG_ERROR, "Unable to allocate memory for event");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
event->callback = callback;
|
event->callback = callback;
|
||||||
@ -129,7 +129,7 @@ struct loop_timer *loop_add_timer(struct loop *loop, int ms,
|
|||||||
void (*callback)(void *data), void *data) {
|
void (*callback)(void *data), void *data) {
|
||||||
struct loop_timer *timer = calloc(1, sizeof(struct loop_timer));
|
struct loop_timer *timer = calloc(1, sizeof(struct loop_timer));
|
||||||
if (!timer) {
|
if (!timer) {
|
||||||
wlr_log(WLR_ERROR, "Unable to allocate memory for timer");
|
swaylock_log(LOG_ERROR, "Unable to allocate memory for timer");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
timer->callback = callback;
|
timer->callback = callback;
|
||||||
|
84
main.c
84
main.c
@ -15,29 +15,17 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include <wordexp.h>
|
#include <wordexp.h>
|
||||||
#include <wlr/util/log.h>
|
|
||||||
#include "background-image.h"
|
#include "background-image.h"
|
||||||
|
#include "cairo.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "loop.h"
|
||||||
|
#include "pool-buffer.h"
|
||||||
#include "seat.h"
|
#include "seat.h"
|
||||||
#include "swaylock.h"
|
#include "swaylock.h"
|
||||||
#include "pool-buffer.h"
|
|
||||||
#include "cairo.h"
|
|
||||||
#include "loop.h"
|
|
||||||
#include "wlr-input-inhibitor-unstable-v1-client-protocol.h"
|
#include "wlr-input-inhibitor-unstable-v1-client-protocol.h"
|
||||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
void sway_terminate(int exit_code) {
|
|
||||||
exit(exit_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sway_abort(const char *format, ...) {
|
|
||||||
va_list args;
|
|
||||||
va_start(args, format);
|
|
||||||
_wlr_vlog(WLR_ERROR, format, args);
|
|
||||||
va_end(args);
|
|
||||||
sway_terminate(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t parse_color(const char *color) {
|
static uint32_t parse_color(const char *color) {
|
||||||
if (color[0] == '#') {
|
if (color[0] == '#') {
|
||||||
++color;
|
++color;
|
||||||
@ -45,7 +33,8 @@ static uint32_t parse_color(const char *color) {
|
|||||||
|
|
||||||
int len = strlen(color);
|
int len = strlen(color);
|
||||||
if (len != 6 && len != 8) {
|
if (len != 6 && len != 8) {
|
||||||
wlr_log(WLR_DEBUG, "Invalid color %s, defaulting to color 0xFFFFFFFF", color);
|
swaylock_log(LOG_DEBUG, "Invalid color %s, defaulting to 0xFFFFFFFF",
|
||||||
|
color);
|
||||||
return 0xFFFFFFFF;
|
return 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
uint32_t res = (uint32_t)strtoul(color, NULL, 16);
|
uint32_t res = (uint32_t)strtoul(color, NULL, 16);
|
||||||
@ -70,7 +59,7 @@ int lenient_strcmp(char *a, char *b) {
|
|||||||
static void daemonize(void) {
|
static void daemonize(void) {
|
||||||
int fds[2];
|
int fds[2];
|
||||||
if (pipe(fds) != 0) {
|
if (pipe(fds) != 0) {
|
||||||
wlr_log(WLR_ERROR, "Failed to pipe");
|
swaylock_log(LOG_ERROR, "Failed to pipe");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (fork() == 0) {
|
if (fork() == 0) {
|
||||||
@ -94,7 +83,7 @@ static void daemonize(void) {
|
|||||||
close(fds[1]);
|
close(fds[1]);
|
||||||
uint8_t success;
|
uint8_t success;
|
||||||
if (read(fds[0], &success, 1) != 1 || !success) {
|
if (read(fds[0], &success, 1) != 1 || !success) {
|
||||||
wlr_log(WLR_ERROR, "Failed to daemonize");
|
swaylock_log(LOG_ERROR, "Failed to daemonize");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
close(fds[0]);
|
close(fds[0]);
|
||||||
@ -278,7 +267,7 @@ static void handle_xdg_output_logical_position(void *data,
|
|||||||
|
|
||||||
static void handle_xdg_output_name(void *data, struct zxdg_output_v1 *output,
|
static void handle_xdg_output_name(void *data, struct zxdg_output_v1 *output,
|
||||||
const char *name) {
|
const char *name) {
|
||||||
wlr_log(WLR_DEBUG, "output name is %s", name);
|
swaylock_log(LOG_DEBUG, "output name is %s", name);
|
||||||
struct swaylock_surface *surface = data;
|
struct swaylock_surface *surface = data;
|
||||||
surface->xdg_output = output;
|
surface->xdg_output = output;
|
||||||
surface->output_name = strdup(name);
|
surface->output_name = strdup(name);
|
||||||
@ -391,11 +380,11 @@ static void load_image(char *arg, struct swaylock_state *state) {
|
|||||||
wl_list_for_each_safe(iter_image, temp, &state->images, link) {
|
wl_list_for_each_safe(iter_image, temp, &state->images, link) {
|
||||||
if (lenient_strcmp(iter_image->output_name, image->output_name) == 0) {
|
if (lenient_strcmp(iter_image->output_name, image->output_name) == 0) {
|
||||||
if (image->output_name) {
|
if (image->output_name) {
|
||||||
wlr_log(WLR_DEBUG,
|
swaylock_log(LOG_DEBUG,
|
||||||
"Replacing image defined for output %s with %s",
|
"Replacing image defined for output %s with %s",
|
||||||
image->output_name, image->path);
|
image->output_name, image->path);
|
||||||
} else {
|
} else {
|
||||||
wlr_log(WLR_DEBUG, "Replacing default image with %s",
|
swaylock_log(LOG_DEBUG, "Replacing default image with %s",
|
||||||
image->path);
|
image->path);
|
||||||
}
|
}
|
||||||
wl_list_remove(&iter_image->link);
|
wl_list_remove(&iter_image->link);
|
||||||
@ -422,8 +411,8 @@ static void load_image(char *arg, struct swaylock_state *state) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wl_list_insert(&state->images, &image->link);
|
wl_list_insert(&state->images, &image->link);
|
||||||
wlr_log(WLR_DEBUG, "Loaded image %s for output %s",
|
swaylock_log(LOG_DEBUG, "Loaded image %s for output %s", image->path,
|
||||||
image->path, image->output_name ? image->output_name : "*");
|
image->output_name ? image->output_name : "*");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_default_colors(struct swaylock_colors *colors) {
|
static void set_default_colors(struct swaylock_colors *colors) {
|
||||||
@ -505,6 +494,7 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
|
|||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"config", required_argument, NULL, 'C'},
|
{"config", required_argument, NULL, 'C'},
|
||||||
{"color", required_argument, NULL, 'c'},
|
{"color", required_argument, NULL, 'c'},
|
||||||
|
{"debug", no_argument, NULL, 'd'},
|
||||||
{"ignore-empty-password", no_argument, NULL, 'e'},
|
{"ignore-empty-password", no_argument, NULL, 'e'},
|
||||||
{"daemonize", no_argument, NULL, 'f'},
|
{"daemonize", no_argument, NULL, 'f'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
@ -556,6 +546,8 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
|
|||||||
"Path to the config file.\n"
|
"Path to the config file.\n"
|
||||||
" -c, --color <color> "
|
" -c, --color <color> "
|
||||||
"Turn the screen into the given color instead of white.\n"
|
"Turn the screen into the given color instead of white.\n"
|
||||||
|
" -d, --debug "
|
||||||
|
"Enable debugging output.\n"
|
||||||
" -e, --ignore-empty-password "
|
" -e, --ignore-empty-password "
|
||||||
"When an empty password is provided, do not validate it.\n"
|
"When an empty password is provided, do not validate it.\n"
|
||||||
" -f, --daemonize "
|
" -f, --daemonize "
|
||||||
@ -651,7 +643,8 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
|
|||||||
optind = 1;
|
optind = 1;
|
||||||
while (1) {
|
while (1) {
|
||||||
int opt_idx = 0;
|
int opt_idx = 0;
|
||||||
c = getopt_long(argc, argv, "c:efhi:Llnrs:tuvC:", long_options, &opt_idx);
|
c = getopt_long(argc, argv, "c:defhi:Llnrs:tuvC:", long_options,
|
||||||
|
&opt_idx);
|
||||||
if (c == -1) {
|
if (c == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -667,6 +660,9 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state,
|
|||||||
state->args.mode = BACKGROUND_MODE_SOLID_COLOR;
|
state->args.mode = BACKGROUND_MODE_SOLID_COLOR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
swaylock_log_init(LOG_DEBUG);
|
||||||
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if (state) {
|
if (state) {
|
||||||
state->args.ignore_empty = true;
|
state->args.ignore_empty = true;
|
||||||
@ -889,12 +885,12 @@ static char *get_config_path(void) {
|
|||||||
char *home = getenv("HOME");
|
char *home = getenv("HOME");
|
||||||
char *config_home = malloc(strlen(home) + strlen("/.config") + 1);
|
char *config_home = malloc(strlen(home) + strlen("/.config") + 1);
|
||||||
if (!config_home) {
|
if (!config_home) {
|
||||||
wlr_log(WLR_ERROR, "Unable to allocate $HOME/.config");
|
swaylock_log(LOG_ERROR, "Unable to allocate $HOME/.config");
|
||||||
} else {
|
} else {
|
||||||
strcpy(config_home, home);
|
strcpy(config_home, home);
|
||||||
strcat(config_home, "/.config");
|
strcat(config_home, "/.config");
|
||||||
setenv("XDG_CONFIG_HOME", config_home, 1);
|
setenv("XDG_CONFIG_HOME", config_home, 1);
|
||||||
wlr_log(WLR_DEBUG, "Set XDG_CONFIG_HOME to %s", config_home);
|
swaylock_log(LOG_DEBUG, "Set XDG_CONFIG_HOME to %s", config_home);
|
||||||
free(config_home);
|
free(config_home);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -919,7 +915,7 @@ static int load_config(char *path, struct swaylock_state *state,
|
|||||||
enum line_mode *line_mode) {
|
enum line_mode *line_mode) {
|
||||||
FILE *config = fopen(path, "r");
|
FILE *config = fopen(path, "r");
|
||||||
if (!config) {
|
if (!config) {
|
||||||
wlr_log(WLR_ERROR, "Failed to read config. Running without it.");
|
swaylock_log(LOG_ERROR, "Failed to read config. Running without it.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
@ -938,7 +934,7 @@ static int load_config(char *path, struct swaylock_state *state,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_log(WLR_DEBUG, "Config Line #%d: %s", line_number, line);
|
swaylock_log(LOG_DEBUG, "Config Line #%d: %s", line_number, line);
|
||||||
char flag[nread + 3];
|
char flag[nread + 3];
|
||||||
sprintf(flag, "--%s", line);
|
sprintf(flag, "--%s", line);
|
||||||
char *argv[] = {"swaylock", flag};
|
char *argv[] = {"swaylock", flag};
|
||||||
@ -961,7 +957,7 @@ static void display_in(int fd, short mask, void *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
wlr_log_init(WLR_DEBUG, NULL);
|
swaylock_log_init(LOG_ERROR);
|
||||||
initialize_pw_backend();
|
initialize_pw_backend();
|
||||||
|
|
||||||
enum line_mode line_mode = LM_LINE;
|
enum line_mode line_mode = LM_LINE;
|
||||||
@ -989,18 +985,20 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (config_path) {
|
if (config_path) {
|
||||||
wlr_log(WLR_DEBUG, "Found config at %s", config_path);
|
swaylock_log(LOG_DEBUG, "Found config at %s", config_path);
|
||||||
int config_status = load_config(config_path, &state, &line_mode);
|
int config_status = load_config(config_path, &state, &line_mode);
|
||||||
free(config_path);
|
free(config_path);
|
||||||
if (config_status != 0) {
|
if (config_status != 0) {
|
||||||
|
free(state.args.font);
|
||||||
return config_status;
|
return config_status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
wlr_log(WLR_DEBUG, "Parsing CLI Args");
|
swaylock_log(LOG_DEBUG, "Parsing CLI Args");
|
||||||
int result = parse_options(argc, argv, &state, &line_mode, NULL);
|
int result = parse_options(argc, argv, &state, &line_mode, NULL);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
|
free(state.args.font);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1014,7 +1012,8 @@ int main(int argc, char **argv) {
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
// Most non-linux platforms require root to mlock()
|
// Most non-linux platforms require root to mlock()
|
||||||
if (mlock(state.password.buffer, sizeof(state.password.buffer)) != 0) {
|
if (mlock(state.password.buffer, sizeof(state.password.buffer)) != 0) {
|
||||||
sway_abort("Unable to mlock() password memory.");
|
swaylock_log(LOG_ERROR, "Unable to mlock() password memory.");
|
||||||
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1022,9 +1021,11 @@ int main(int argc, char **argv) {
|
|||||||
state.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
state.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
state.display = wl_display_connect(NULL);
|
state.display = wl_display_connect(NULL);
|
||||||
if (!state.display) {
|
if (!state.display) {
|
||||||
sway_abort("Unable to connect to the compositor. "
|
free(state.args.font);
|
||||||
|
swaylock_log(LOG_ERROR, "Unable to connect to the compositor. "
|
||||||
"If your compositor is running, check or set the "
|
"If your compositor is running, check or set the "
|
||||||
"WAYLAND_DISPLAY environment variable.");
|
"WAYLAND_DISPLAY environment variable.");
|
||||||
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wl_registry *registry = wl_display_get_registry(state.display);
|
struct wl_registry *registry = wl_display_get_registry(state.display);
|
||||||
@ -1032,19 +1033,22 @@ int main(int argc, char **argv) {
|
|||||||
wl_display_roundtrip(state.display);
|
wl_display_roundtrip(state.display);
|
||||||
assert(state.compositor && state.layer_shell && state.shm);
|
assert(state.compositor && state.layer_shell && state.shm);
|
||||||
if (!state.input_inhibit_manager) {
|
if (!state.input_inhibit_manager) {
|
||||||
wlr_log(WLR_ERROR, "Compositor does not support the input inhibitor "
|
free(state.args.font);
|
||||||
"protocol, refusing to run insecurely");
|
swaylock_log(LOG_ERROR, "Compositor does not support the input "
|
||||||
|
"inhibitor protocol, refusing to run insecurely");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wl_list_empty(&state.surfaces)) {
|
if (wl_list_empty(&state.surfaces)) {
|
||||||
wlr_log(WLR_DEBUG, "Exiting - no outputs to show on.");
|
free(state.args.font);
|
||||||
|
swaylock_log(LOG_ERROR, "Exiting - no outputs to show on.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
zwlr_input_inhibit_manager_v1_get_inhibitor(state.input_inhibit_manager);
|
zwlr_input_inhibit_manager_v1_get_inhibitor(state.input_inhibit_manager);
|
||||||
if (wl_display_roundtrip(state.display) == -1) {
|
if (wl_display_roundtrip(state.display) == -1) {
|
||||||
wlr_log(WLR_ERROR, "Exiting - failed to inhibit input:"
|
free(state.args.font);
|
||||||
|
swaylock_log(LOG_ERROR, "Exiting - failed to inhibit input:"
|
||||||
" is another lockscreen already running?");
|
" is another lockscreen already running?");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@ -1059,8 +1063,8 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
wl_display_roundtrip(state.display);
|
wl_display_roundtrip(state.display);
|
||||||
} else {
|
} else {
|
||||||
wlr_log(WLR_INFO, "Compositor does not support zxdg output manager, "
|
swaylock_log(LOG_INFO, "Compositor does not support zxdg output "
|
||||||
"images assigned to named outputs will not work");
|
"manager, images assigned to named outputs will not work");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct swaylock_surface *surface;
|
struct swaylock_surface *surface;
|
||||||
|
@ -32,7 +32,6 @@ if is_freebsd
|
|||||||
add_project_arguments('-D_C11_SOURCE', language: 'c')
|
add_project_arguments('-D_C11_SOURCE', language: 'c')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
wlroots = dependency('wlroots', fallback: ['wlroots', 'wlroots'])
|
|
||||||
wayland_client = dependency('wayland-client')
|
wayland_client = dependency('wayland-client')
|
||||||
wayland_protos = dependency('wayland-protocols', version: '>=1.14')
|
wayland_protos = dependency('wayland-protocols', version: '>=1.14')
|
||||||
xkbcommon = dependency('xkbcommon')
|
xkbcommon = dependency('xkbcommon')
|
||||||
@ -123,13 +122,13 @@ dependencies = [
|
|||||||
pangocairo,
|
pangocairo,
|
||||||
xkbcommon,
|
xkbcommon,
|
||||||
wayland_client,
|
wayland_client,
|
||||||
wlroots,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
'background-image.c',
|
'background-image.c',
|
||||||
'cairo.c',
|
'cairo.c',
|
||||||
'list.c',
|
'list.c',
|
||||||
|
'log.c',
|
||||||
'loop.c',
|
'loop.c',
|
||||||
'main.c',
|
'main.c',
|
||||||
'pango.c',
|
'pango.c',
|
||||||
|
8
pam.c
8
pam.c
@ -5,7 +5,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wlr/util/log.h>
|
#include "log.h"
|
||||||
#include "swaylock.h"
|
#include "swaylock.h"
|
||||||
|
|
||||||
void initialize_pw_backend(void) {
|
void initialize_pw_backend(void) {
|
||||||
@ -43,15 +43,15 @@ bool attempt_password(struct swaylock_password *pw) {
|
|||||||
int pam_err;
|
int pam_err;
|
||||||
if ((pam_err = pam_start("swaylock", username,
|
if ((pam_err = pam_start("swaylock", username,
|
||||||
&local_conversation, &local_auth_handle)) != PAM_SUCCESS) {
|
&local_conversation, &local_auth_handle)) != PAM_SUCCESS) {
|
||||||
wlr_log(WLR_ERROR, "PAM returned error %d", pam_err);
|
swaylock_log(LOG_ERROR, "PAM returned error %d", pam_err);
|
||||||
}
|
}
|
||||||
if ((pam_err = pam_authenticate(local_auth_handle, 0)) != PAM_SUCCESS) {
|
if ((pam_err = pam_authenticate(local_auth_handle, 0)) != PAM_SUCCESS) {
|
||||||
wlr_log(WLR_ERROR, "pam_authenticate failed");
|
swaylock_log(LOG_ERROR, "pam_authenticate failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
// TODO: only call pam_end once we succeed at authing. refresh tokens beforehand
|
// TODO: only call pam_end once we succeed at authing. refresh tokens beforehand
|
||||||
if ((pam_err = pam_end(local_auth_handle, pam_err)) != PAM_SUCCESS) {
|
if ((pam_err = pam_end(local_auth_handle, pam_err)) != PAM_SUCCESS) {
|
||||||
wlr_log(WLR_ERROR, "pam_end failed");
|
swaylock_log(LOG_ERROR, "pam_end failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
clear_password_buffer(pw);
|
clear_password_buffer(pw);
|
||||||
|
6
pango.c
6
pango.c
@ -6,8 +6,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wlr/util/log.h>
|
|
||||||
#include "cairo.h"
|
#include "cairo.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
static const char overflow[] = "[buffer overflow]";
|
static const char overflow[] = "[buffer overflow]";
|
||||||
static const int max_chars = 16384;
|
static const int max_chars = 16384;
|
||||||
@ -70,8 +70,8 @@ PangoLayout *get_pango_layout(cairo_t *cairo, const char *font,
|
|||||||
pango_layout_set_text(layout, buf, -1);
|
pango_layout_set_text(layout, buf, -1);
|
||||||
free(buf);
|
free(buf);
|
||||||
} else {
|
} else {
|
||||||
wlr_log(WLR_ERROR, "pango_parse_markup '%s' -> error %s", text,
|
swaylock_log(LOG_ERROR, "pango_parse_markup '%s' -> error %s",
|
||||||
error->message);
|
text, error->message);
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
markup = false; // fallback to plain text
|
markup = false; // fallback to plain text
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wlr/util/log.h>
|
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include "swaylock.h"
|
#include "log.h"
|
||||||
#include "seat.h"
|
|
||||||
#include "loop.h"
|
#include "loop.h"
|
||||||
|
#include "seat.h"
|
||||||
|
#include "swaylock.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
|
|
||||||
void clear_password_buffer(struct swaylock_password *pw) {
|
void clear_password_buffer(struct swaylock_password *pw) {
|
||||||
|
6
seat.c
6
seat.c
@ -2,8 +2,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wlr/util/log.h>
|
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
#include "log.h"
|
||||||
#include "swaylock.h"
|
#include "swaylock.h"
|
||||||
#include "seat.h"
|
#include "seat.h"
|
||||||
|
|
||||||
@ -12,13 +12,13 @@ static void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
|||||||
struct swaylock_state *state = data;
|
struct swaylock_state *state = data;
|
||||||
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
|
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
wlr_log(WLR_ERROR, "Unknown keymap format %d, aborting", format);
|
swaylock_log(LOG_ERROR, "Unknown keymap format %d, aborting", format);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
if (map_shm == MAP_FAILED) {
|
if (map_shm == MAP_FAILED) {
|
||||||
close(fd);
|
close(fd);
|
||||||
wlr_log(WLR_ERROR, "Unable to initialize keymap shm, aborting");
|
swaylock_log(LOG_ERROR, "Unable to initialize keymap shm, aborting");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
struct xkb_keymap *keymap = xkb_keymap_new_from_string(
|
struct xkb_keymap *keymap = xkb_keymap_new_from_string(
|
||||||
|
41
shadow.c
41
shadow.c
@ -4,7 +4,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wlr/util/log.h>
|
#include "log.h"
|
||||||
#include "swaylock/swaylock.h"
|
#include "swaylock/swaylock.h"
|
||||||
#ifdef __GLIBC__
|
#ifdef __GLIBC__
|
||||||
// GNU, you damn slimy bastard
|
// GNU, you damn slimy bastard
|
||||||
@ -25,14 +25,14 @@ void run_child(void) {
|
|||||||
/* This code runs as root */
|
/* This code runs as root */
|
||||||
struct passwd *pwent = getpwuid(getuid());
|
struct passwd *pwent = getpwuid(getuid());
|
||||||
if (!pwent) {
|
if (!pwent) {
|
||||||
wlr_log_errno(WLR_ERROR, "failed to getpwuid");
|
swaylock_log_errno(LOG_ERROR, "failed to getpwuid");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
char *encpw = pwent->pw_passwd;
|
char *encpw = pwent->pw_passwd;
|
||||||
if (strcmp(encpw, "x") == 0) {
|
if (strcmp(encpw, "x") == 0) {
|
||||||
struct spwd *swent = getspnam(pwent->pw_name);
|
struct spwd *swent = getspnam(pwent->pw_name);
|
||||||
if (!swent) {
|
if (!swent) {
|
||||||
wlr_log_errno(WLR_ERROR, "failed to getspnam");
|
swaylock_log_errno(LOG_ERROR, "failed to getspnam");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
encpw = swent->sp_pwdp;
|
encpw = swent->sp_pwdp;
|
||||||
@ -48,7 +48,7 @@ void run_child(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This code does not run as root */
|
/* This code does not run as root */
|
||||||
wlr_log(WLR_DEBUG, "prepared to authorize user %s", pwent->pw_name);
|
swaylock_log(LOG_DEBUG, "prepared to authorize user %s", pwent->pw_name);
|
||||||
|
|
||||||
size_t size;
|
size_t size;
|
||||||
char *buf;
|
char *buf;
|
||||||
@ -58,19 +58,19 @@ void run_child(void) {
|
|||||||
if (amt == 0) {
|
if (amt == 0) {
|
||||||
break;
|
break;
|
||||||
} else if (amt < 0) {
|
} else if (amt < 0) {
|
||||||
wlr_log_errno(WLR_ERROR, "read pw request");
|
swaylock_log_errno(LOG_ERROR, "read pw request");
|
||||||
}
|
}
|
||||||
wlr_log(WLR_DEBUG, "received pw check request");
|
swaylock_log(LOG_DEBUG, "received pw check request");
|
||||||
buf = malloc(size);
|
buf = malloc(size);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
wlr_log_errno(WLR_ERROR, "failed to malloc pw buffer");
|
swaylock_log_errno(LOG_ERROR, "failed to malloc pw buffer");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
size_t offs = 0;
|
size_t offs = 0;
|
||||||
do {
|
do {
|
||||||
amt = read(comm[0][0], &buf[offs], size - offs);
|
amt = read(comm[0][0], &buf[offs], size - offs);
|
||||||
if (amt <= 0) {
|
if (amt <= 0) {
|
||||||
wlr_log_errno(WLR_ERROR, "failed to read pw");
|
swaylock_log_errno(LOG_ERROR, "failed to read pw");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
offs += (size_t)amt;
|
offs += (size_t)amt;
|
||||||
@ -78,11 +78,11 @@ void run_child(void) {
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
char *c = crypt(buf, encpw);
|
char *c = crypt(buf, encpw);
|
||||||
if (c == NULL) {
|
if (c == NULL) {
|
||||||
wlr_log_errno(WLR_ERROR, "crypt");
|
swaylock_log_errno(LOG_ERROR, "crypt");
|
||||||
}
|
}
|
||||||
result = strcmp(c, encpw) == 0;
|
result = strcmp(c, encpw) == 0;
|
||||||
if (write(comm[1][1], &result, sizeof(result)) != sizeof(result)) {
|
if (write(comm[1][1], &result, sizeof(result)) != sizeof(result)) {
|
||||||
wlr_log_errno(WLR_ERROR, "failed to write pw check result");
|
swaylock_log_errno(LOG_ERROR, "failed to write pw check result");
|
||||||
clear_buffer(buf, size);
|
clear_buffer(buf, size);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@ -96,15 +96,16 @@ void run_child(void) {
|
|||||||
|
|
||||||
void initialize_pw_backend(void) {
|
void initialize_pw_backend(void) {
|
||||||
if (geteuid() != 0) {
|
if (geteuid() != 0) {
|
||||||
wlr_log(WLR_ERROR, "swaylock needs to be setuid to read /etc/shadow");
|
swaylock_log(LOG_ERROR,
|
||||||
|
"swaylock needs to be setuid to read /etc/shadow");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (pipe(comm[0]) != 0) {
|
if (pipe(comm[0]) != 0) {
|
||||||
wlr_log_errno(WLR_ERROR, "failed to create pipe");
|
swaylock_log_errno(LOG_ERROR, "failed to create pipe");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (pipe(comm[1]) != 0) {
|
if (pipe(comm[1]) != 0) {
|
||||||
wlr_log_errno(WLR_ERROR, "failed to create pipe");
|
swaylock_log_errno(LOG_ERROR, "failed to create pipe");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
pid_t child = fork();
|
pid_t child = fork();
|
||||||
@ -113,17 +114,17 @@ void initialize_pw_backend(void) {
|
|||||||
close(comm[1][0]);
|
close(comm[1][0]);
|
||||||
run_child();
|
run_child();
|
||||||
} else if (child < 0) {
|
} else if (child < 0) {
|
||||||
wlr_log_errno(WLR_ERROR, "failed to fork");
|
swaylock_log_errno(LOG_ERROR, "failed to fork");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
close(comm[0][0]);
|
close(comm[0][0]);
|
||||||
close(comm[1][1]);
|
close(comm[1][1]);
|
||||||
if (setgid(getgid()) != 0) {
|
if (setgid(getgid()) != 0) {
|
||||||
wlr_log_errno(WLR_ERROR, "Unable to drop root");
|
swaylock_log_errno(LOG_ERROR, "Unable to drop root");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (setuid(getuid()) != 0) {
|
if (setuid(getuid()) != 0) {
|
||||||
wlr_log_errno(WLR_ERROR, "Unable to drop root");
|
swaylock_log_errno(LOG_ERROR, "Unable to drop root");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,22 +134,22 @@ bool attempt_password(struct swaylock_password *pw) {
|
|||||||
size_t len = pw->len + 1;
|
size_t len = pw->len + 1;
|
||||||
size_t offs = 0;
|
size_t offs = 0;
|
||||||
if (write(comm[0][1], &len, sizeof(len)) < 0) {
|
if (write(comm[0][1], &len, sizeof(len)) < 0) {
|
||||||
wlr_log_errno(WLR_ERROR, "Failed to request pw check");
|
swaylock_log_errno(LOG_ERROR, "Failed to request pw check");
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
ssize_t amt = write(comm[0][1], &pw->buffer[offs], len - offs);
|
ssize_t amt = write(comm[0][1], &pw->buffer[offs], len - offs);
|
||||||
if (amt < 0) {
|
if (amt < 0) {
|
||||||
wlr_log_errno(WLR_ERROR, "Failed to write pw buffer");
|
swaylock_log_errno(LOG_ERROR, "Failed to write pw buffer");
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
offs += amt;
|
offs += amt;
|
||||||
} while (offs < len);
|
} while (offs < len);
|
||||||
if (read(comm[1][0], &result, sizeof(result)) != sizeof(result)) {
|
if (read(comm[1][0], &result, sizeof(result)) != sizeof(result)) {
|
||||||
wlr_log_errno(WLR_ERROR, "Failed to read pw result");
|
swaylock_log_errno(LOG_ERROR, "Failed to read pw result");
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
wlr_log(WLR_DEBUG, "pw result: %d", result);
|
swaylock_log(LOG_DEBUG, "pw result: %d", result);
|
||||||
ret:
|
ret:
|
||||||
clear_password_buffer(pw);
|
clear_password_buffer(pw);
|
||||||
return result;
|
return result;
|
||||||
|
@ -21,6 +21,9 @@ Locks your Wayland session.
|
|||||||
All leading dashes should be omitted and the equals sign is required for
|
All leading dashes should be omitted and the equals sign is required for
|
||||||
flags that take an argument.
|
flags that take an argument.
|
||||||
|
|
||||||
|
*-d, --debug*
|
||||||
|
Enable debugging output.
|
||||||
|
|
||||||
*-e, --ignore-empty-password*
|
*-e, --ignore-empty-password*
|
||||||
When an empty password is provided by the user, do not validate it.
|
When an empty password is provided by the user, do not validate it.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user