-/*-*- Mode: C; c-basic-offset: 8 -*-*/
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
#include <pwd.h>
#include <netinet/ip.h>
#include <linux/kd.h>
+#include <dlfcn.h>
#include "macro.h"
#include "util.h"
#include "log.h"
#include "strv.h"
#include "label.h"
+#include "exit-status.h"
bool streq_ptr(const char *a, const char *b) {
return buf;
}
+char *format_timestamp_pretty(char *buf, size_t l, usec_t t) {
+ usec_t n, d;
+
+ n = now(CLOCK_REALTIME);
+
+ if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t)
+ return NULL;
+
+ d = n - t;
+
+ if (d >= USEC_PER_YEAR)
+ snprintf(buf, l, "%llu years and %llu months ago",
+ (unsigned long long) (d / USEC_PER_YEAR),
+ (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH));
+ else if (d >= USEC_PER_MONTH)
+ snprintf(buf, l, "%llu months and %llu days ago",
+ (unsigned long long) (d / USEC_PER_MONTH),
+ (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY));
+ else if (d >= USEC_PER_WEEK)
+ snprintf(buf, l, "%llu weeks and %llu days ago",
+ (unsigned long long) (d / USEC_PER_WEEK),
+ (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY));
+ else if (d >= 2*USEC_PER_DAY)
+ snprintf(buf, l, "%llu days ago", (unsigned long long) (d / USEC_PER_DAY));
+ else if (d >= 25*USEC_PER_HOUR)
+ snprintf(buf, l, "1 day and %lluh ago",
+ (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR));
+ else if (d >= 6*USEC_PER_HOUR)
+ snprintf(buf, l, "%lluh ago",
+ (unsigned long long) (d / USEC_PER_HOUR));
+ else if (d >= USEC_PER_HOUR)
+ snprintf(buf, l, "%lluh %llumin ago",
+ (unsigned long long) (d / USEC_PER_HOUR),
+ (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE));
+ else if (d >= 5*USEC_PER_MINUTE)
+ snprintf(buf, l, "%llumin ago",
+ (unsigned long long) (d / USEC_PER_MINUTE));
+ else if (d >= USEC_PER_MINUTE)
+ snprintf(buf, l, "%llumin %llus ago",
+ (unsigned long long) (d / USEC_PER_MINUTE),
+ (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC));
+ else if (d >= USEC_PER_SEC)
+ snprintf(buf, l, "%llus ago",
+ (unsigned long long) (d / USEC_PER_SEC));
+ else if (d >= USEC_PER_MSEC)
+ snprintf(buf, l, "%llums ago",
+ (unsigned long long) (d / USEC_PER_MSEC));
+ else if (d > 0)
+ snprintf(buf, l, "%lluus ago",
+ (unsigned long long) d);
+ else
+ snprintf(buf, l, "now");
+
+ buf[l-1] = 0;
+ return buf;
+}
+
char *format_timespan(char *buf, size_t l, usec_t t) {
static const struct {
const char *suffix;
assert(fd >= 0);
- /* First, unlock termios */
- zero(termios);
- ioctl(fd, TIOCSLCKTRMIOS, &termios);
+ /* We leave locked terminal attributes untouched, so that
+ * Plymouth may set whatever it wants to set, and we don't
+ * interfere with that. */
/* Disable exclusive mode, just in case */
ioctl(fd, TIOCNXCL);
return false;
}
+bool is_clean_exit_lsb(int code, int status) {
+
+ if (is_clean_exit(code, status))
+ return true;
+
+ return
+ code == CLD_EXITED &&
+ (status == EXIT_NOTINSTALLED || status == EXIT_NOTCONFIGURED);
+}
+
bool is_device_path(const char *path) {
/* Returns true on paths that refer to a device, either in
int getttyname_malloc(char **r) {
char path[PATH_MAX], *p, *c;
+ int k;
assert(r);
- if (ttyname_r(STDIN_FILENO, path, sizeof(path)) < 0)
- return -errno;
+ if ((k = ttyname_r(STDIN_FILENO, path, sizeof(path))) != 0)
+ return -k;
char_array_0(path);
status_printf("Welcome to \x1B[0;32m%s\x1B[0m!\n", r); /* Green for SUSE */
free(r);
+
+#elif defined(TARGET_GENTOO)
+ char *r;
+
+ if (read_one_line_file("/etc/gentoo-release", &r) < 0)
+ return;
+
+ truncate_nl(r);
+
+ status_printf("Welcome to \x1B[1;34m%s\x1B[0m!\n", r); /* Light Blue for Gentoo */
+
+ free(r);
+
+#elif defined(TARGET_DEBIAN)
+ char *r;
+
+ if (read_one_line_file("/etc/debian_version", &r) < 0)
+ return;
+
+ truncate_nl(r);
+
+ status_printf("Welcome to Debian \x1B[1;31m%s\x1B[0m!\n", r); /* Light Red for Debian */
+
+ free(r);
+#elif defined(TARGET_ARCH)
+ status_printf("Welcome to \x1B[1;36mArch Linux\x1B[0m!\n"); /* Cyan for Arch */
#else
#warning "You probably should add a welcome text logic here."
#endif
struct winsize ws;
zero(ws);
- if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) >= 0)
parsed_columns = ws.ws_col;
}
return r;
}
+int touch(const char *path) {
+ int fd;
+
+ assert(path);
+
+ if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0666)) < 0)
+ return -errno;
+
+ close_nointr_nofail(fd);
+ return 0;
+}
+
+char *unquote(const char *s, const char quote) {
+ size_t l;
+ assert(s);
+
+ if ((l = strlen(s)) < 2)
+ return strdup(s);
+
+ if (s[0] == quote && s[l-1] == quote)
+ return strndup(s+1, l-2);
+
+ return strdup(s);
+}
+
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",