mirror of https://github.com/edeproject/ede.git
Applying patches from Michael to fix openbsd buils. Fixing notification daemon to properly read 'replaces' property.
This commit is contained in:
parent
29475da925
commit
3042413e36
|
@ -10,4 +10,4 @@
|
||||||
|
|
||||||
SubDir TOP data pekwm scripts ;
|
SubDir TOP data pekwm scripts ;
|
||||||
|
|
||||||
InstallProgram "$(PEKWM_DATA_DIR)/scripts" : pekwm_themeset.sh pekwm_ws_menu.sh ;
|
# InstallProgram "$(PEKWM_DATA_DIR)/scripts" : pekwm_themeset.sh pekwm_ws_menu.sh ;
|
||||||
|
|
|
@ -102,11 +102,11 @@ const char* bold_keywords[] = {
|
||||||
|
|
||||||
#define BOLD_KEYWORDS_LEN 8
|
#define BOLD_KEYWORDS_LEN 8
|
||||||
|
|
||||||
void close_cb(Fl_Widget*, void*) {
|
static void close_cb(Fl_Widget*, void*) {
|
||||||
win->hide();
|
win->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
char* prepare_style(char* txt, int len) {
|
static char* prepare_style(char* txt, int len) {
|
||||||
// paint all with 'A' style at startup
|
// paint all with 'A' style at startup
|
||||||
char* style = new char[len + 1];
|
char* style = new char[len + 1];
|
||||||
memset(style, 'A', len - 1);
|
memset(style, 'A', len - 1);
|
||||||
|
@ -114,12 +114,13 @@ char* prepare_style(char* txt, int len) {
|
||||||
|
|
||||||
// find bold keywords and paint them
|
// find bold keywords and paint them
|
||||||
char* p = 0;
|
char* p = 0;
|
||||||
|
unsigned int ln;
|
||||||
for(int i = 0; i < BOLD_KEYWORDS_LEN; i++) {
|
for(int i = 0; i < BOLD_KEYWORDS_LEN; i++) {
|
||||||
p = strstr(txt, bold_keywords[i]);
|
p = strstr(txt, bold_keywords[i]);
|
||||||
if(!p)
|
if(!p) continue;
|
||||||
continue;
|
|
||||||
unsigned int len = strlen(bold_keywords[i]);
|
ln = strlen(bold_keywords[i]);
|
||||||
memset(&style[p - txt], 'B', len);
|
memset(&style[p - txt], 'B', ln);
|
||||||
}
|
}
|
||||||
|
|
||||||
return style;
|
return style;
|
||||||
|
|
|
@ -99,7 +99,7 @@ if $(CURL_CFLAGS) || $(CURL_LIBS) {
|
||||||
curlmulti.c
|
curlmulti.c
|
||||||
lock_pthread.c ;
|
lock_pthread.c ;
|
||||||
|
|
||||||
ObjectCcFlags $(CURL_TRANSPORT_SRC) : $(CURL_CFLAGS) ;
|
ObjectCcFlags $(CURL_TRANSPORT_SRC) : $(XMLRPC_C_FLAGS) $(CURL_CFLAGS) ;
|
||||||
|
|
||||||
UTIL_SRC =
|
UTIL_SRC =
|
||||||
casprintf.c
|
casprintf.c
|
||||||
|
|
|
@ -421,7 +421,6 @@ DesktopIcon *Desktop::read_desktop_file(const char *path, const char *base, Desk
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Desktop::arrange_icons(void) {
|
void Desktop::arrange_icons(void) {
|
||||||
int lw = icon_opts ? icon_opts->label_maxwidth : 75;
|
int lw = icon_opts ? icon_opts->label_maxwidth : 75;
|
||||||
int X = (lw / 5) + 10;
|
int X = (lw / 5) + 10;
|
||||||
|
|
|
@ -31,4 +31,4 @@ SOURCE = ede-desktop.cpp
|
||||||
|
|
||||||
ObjectC++Flags $(SOURCE) : $(EDELIB_DBUS_INCLUDE) ;
|
ObjectC++Flags $(SOURCE) : $(EDELIB_DBUS_INCLUDE) ;
|
||||||
EdeProgram ede-desktop : $(SOURCE) ;
|
EdeProgram ede-desktop : $(SOURCE) ;
|
||||||
LinkAgainst ede-desktop : $(EDELIB_DBUS_LIB) $(XSHAPE_LIBS) ;
|
LinkAgainst ede-desktop : $(EDELIB_DBUS_LIB) $(XSHAPE_LIBS) $(PTHREAD_LIBS) ;
|
|
@ -13,7 +13,7 @@ SubDir TOP ede-notify-daemon ;
|
||||||
SOURCE = ede-notify-daemon.cpp NotifyWindow.cpp ;
|
SOURCE = ede-notify-daemon.cpp NotifyWindow.cpp ;
|
||||||
|
|
||||||
EdeProgram ede-notify-daemon : $(SOURCE) ;
|
EdeProgram ede-notify-daemon : $(SOURCE) ;
|
||||||
LinkAgainst ede-notify-daemon : $(EDELIB_DBUS_LIB) ;
|
LinkAgainst ede-notify-daemon : $(EDELIB_DBUS_LIB) $(PTHREAD_LIBS) ;
|
||||||
|
|
||||||
TranslationStrings locale : $(SOURCE) ;
|
TranslationStrings locale : $(SOURCE) ;
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,8 @@ void NotifyWindow::set_icon(const char *img) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifyWindow::set_body(const char *s) {
|
void NotifyWindow::set_body(const char *s) {
|
||||||
summary->resize(summary->x(), summary->y() - (summary->h() / 2), summary->w(), summary->h());
|
summary->resize(65, 10, 185, 25);
|
||||||
|
//summary->resize(summary->x(), summary->y() - (summary->h() / 2), summary->w(), summary->h());
|
||||||
|
|
||||||
body->value(s);
|
body->value(s);
|
||||||
body->show();
|
body->show();
|
||||||
|
@ -137,7 +138,7 @@ void NotifyWindow::resize(int X, int Y, int W, int H) {
|
||||||
* do not call further if window is shown: different strategy is needed as every time
|
* do not call further if window is shown: different strategy is needed as every time
|
||||||
* window is re-configured, this will be called
|
* window is re-configured, this will be called
|
||||||
*/
|
*/
|
||||||
if(shown()) return;
|
//if(shown()) return;
|
||||||
|
|
||||||
/* resize summary if needed */
|
/* resize summary if needed */
|
||||||
if(summary->size() > 0) {
|
if(summary->size() > 0) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* $Id: ede-panel.cpp 3330 2012-05-28 10:57:50Z karijes $
|
* $Id: ede-panel.cpp 3330 2012-05-28 10:57:50Z karijes $
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Sanel Zukan
|
* Copyright (C) 2012-2014 Sanel Zukan
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -31,7 +31,8 @@
|
||||||
|
|
||||||
class NotifyWindow : public Fl_Window {
|
class NotifyWindow : public Fl_Window {
|
||||||
private:
|
private:
|
||||||
int id, exp, timer_set;
|
unsigned int id;
|
||||||
|
int exp, timer_set;
|
||||||
Fl_Button *closeb;
|
Fl_Button *closeb;
|
||||||
Fl_Box *imgbox;
|
Fl_Box *imgbox;
|
||||||
Fl_Multiline_Output *summary, *body;
|
Fl_Multiline_Output *summary, *body;
|
||||||
|
@ -41,8 +42,8 @@ private:
|
||||||
public:
|
public:
|
||||||
NotifyWindow();
|
NotifyWindow();
|
||||||
|
|
||||||
void set_id(int i) { id = i; }
|
void set_id(unsigned int i) { id = i; }
|
||||||
int get_id(void) { return id; }
|
unsigned int get_id(void) { return id; }
|
||||||
|
|
||||||
void set_icon(const char *img);
|
void set_icon(const char *img);
|
||||||
void set_summary(const char *s) { summary->value(s); }
|
void set_summary(const char *s) { summary->value(s); }
|
||||||
|
@ -52,7 +53,14 @@ public:
|
||||||
* match to spec: if is -1, then we handle it, if is 0, then window will not be closed and
|
* match to spec: if is -1, then we handle it, if is 0, then window will not be closed and
|
||||||
* the rest is sender specific
|
* the rest is sender specific
|
||||||
*/
|
*/
|
||||||
void set_expire(int t) { exp = t; }
|
void set_expire(int t, bool update_timer) {
|
||||||
|
exp = t;
|
||||||
|
// if(update_timer) {
|
||||||
|
// remove_timeout();
|
||||||
|
// add_timeout();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
void show(void);
|
void show(void);
|
||||||
|
|
||||||
virtual void resize(int X, int Y, int W, int H);
|
virtual void resize(int X, int Y, int W, int H);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* $Id: ede-panel.cpp 3330 2012-05-28 10:57:50Z karijes $
|
* $Id: ede-panel.cpp 3330 2012-05-28 10:57:50Z karijes $
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Sanel Zukan
|
* Copyright (C) 2012-2014 Sanel Zukan
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -83,7 +83,8 @@ static bool server_running;
|
||||||
* list of server capabilities
|
* list of server capabilities
|
||||||
* check all available on: http://people.gnome.org/~mccann/docs/notification-spec/notification-spec-latest.html
|
* check all available on: http://people.gnome.org/~mccann/docs/notification-spec/notification-spec-latest.html
|
||||||
*/
|
*/
|
||||||
static const char *server_caps[] = {"actions", "body", "icon-static", 0};
|
// static const char *server_caps[] = {"actions", "body", "icon-static", 0};
|
||||||
|
static const char *server_caps[] = {"body", "icon-static", 0};
|
||||||
|
|
||||||
/* increased every time new notification window is shown; must be less than UINT_MAX */
|
/* increased every time new notification window is shown; must be less than UINT_MAX */
|
||||||
static unsigned int notify_id;
|
static unsigned int notify_id;
|
||||||
|
@ -128,22 +129,40 @@ static bool get_int_coordinate(const char *n, EdbusDict &hints, int &c) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_window(unsigned int id,
|
static void show_or_update_window(bool update_only,
|
||||||
const char *app_name,
|
unsigned int id,
|
||||||
const char *app_icon,
|
const char *app_name,
|
||||||
const char *summary,
|
const char *app_icon,
|
||||||
const char *body,
|
const char *summary,
|
||||||
int expire_timeout,
|
const char *body,
|
||||||
EdbusDict &hints)
|
int expire_timeout,
|
||||||
|
EdbusDict &hints)
|
||||||
{
|
{
|
||||||
byte_t u = get_urgency_level(hints);
|
byte_t u = get_urgency_level(hints);
|
||||||
|
NotifyWindow *win = NULL;
|
||||||
|
|
||||||
NotifyWindow *win = new NotifyWindow();
|
if(update_only) {
|
||||||
|
E_DEBUG(E_STRLOC ": Requesting update\n");
|
||||||
|
/* try to find existing window with given id */
|
||||||
|
Fl_Window *wi;
|
||||||
|
NotifyWindow *tmp;
|
||||||
|
|
||||||
if(!empty_str(summary))
|
for(wi = Fl::first_window(); wi; wi = Fl::next_window(wi)) {
|
||||||
win->set_summary(summary);
|
if(wi->type() != NOTIFYWINDOW_TYPE) continue;
|
||||||
if(!empty_str(body))
|
tmp = (NotifyWindow*)wi;
|
||||||
win->set_body(body);
|
if(tmp->get_id() == id) {
|
||||||
|
E_DEBUG(E_STRLOC ": Requesting update - win found\n");
|
||||||
|
win = tmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* window not found or new window requested */
|
||||||
|
if(!win) win = new NotifyWindow();
|
||||||
|
|
||||||
|
if(!empty_str(summary)) win->set_summary(summary);
|
||||||
|
if(!empty_str(body)) win->set_body(body);
|
||||||
if(empty_str(app_icon)) {
|
if(empty_str(app_icon)) {
|
||||||
switch(u) {
|
switch(u) {
|
||||||
case URGENCY_CRITICAL:
|
case URGENCY_CRITICAL:
|
||||||
|
@ -158,7 +177,7 @@ static void show_window(unsigned int id,
|
||||||
|
|
||||||
win->set_icon(app_icon);
|
win->set_icon(app_icon);
|
||||||
win->set_id(id);
|
win->set_id(id);
|
||||||
win->set_expire(expire_timeout);
|
win->set_expire(expire_timeout, update_only);
|
||||||
|
|
||||||
/* according to spec, both coordinates must exist so window can be positioned as desired */
|
/* according to spec, both coordinates must exist so window can be positioned as desired */
|
||||||
int X, Y;
|
int X, Y;
|
||||||
|
@ -198,7 +217,8 @@ static void show_window(unsigned int id,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we are already running loop, so window will handle events */
|
/* we are already running loop, so window will handle events */
|
||||||
win->show();
|
if(!win->shown())
|
||||||
|
win->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_notify(EdbusConnection *dbus, const EdbusMessage *m) {
|
static int handle_notify(EdbusConnection *dbus, const EdbusMessage *m) {
|
||||||
|
@ -209,7 +229,7 @@ static int handle_notify(EdbusConnection *dbus, const EdbusMessage *m) {
|
||||||
|
|
||||||
const char *app_name, *app_icon, *summary, *body;
|
const char *app_name, *app_icon, *summary, *body;
|
||||||
app_name = app_icon = summary = body = NULL;
|
app_name = app_icon = summary = body = NULL;
|
||||||
unsigned int replaces_id;
|
unsigned int replaces_id, id;
|
||||||
int expire_timeout;
|
int expire_timeout;
|
||||||
|
|
||||||
EdbusMessage::const_iterator it = m->begin();
|
EdbusMessage::const_iterator it = m->begin();
|
||||||
|
@ -246,19 +266,33 @@ static int handle_notify(EdbusConnection *dbus, const EdbusMessage *m) {
|
||||||
E_RETURN_VAL_IF_FAIL(it->is_int32(), 0);
|
E_RETURN_VAL_IF_FAIL(it->is_int32(), 0);
|
||||||
expire_timeout = it->to_int32();
|
expire_timeout = it->to_int32();
|
||||||
|
|
||||||
/* specification dumb stuff: what if we got UINT_MAX?? here we will reverse to first ID */
|
if(replaces_id > 0) {
|
||||||
if(++notify_id == UINT_MAX) notify_id = 1;
|
id = replaces_id;
|
||||||
|
|
||||||
if(replaces_id) {
|
|
||||||
//replaces_id == notify_id;
|
|
||||||
} else {
|
} else {
|
||||||
show_window(notify_id, app_name, app_icon, summary, body, expire_timeout, hints);
|
/* by the spec, if we got MAX, reversing will be just fine */
|
||||||
|
if(++notify_id == UINT_MAX) notify_id = 1;
|
||||||
|
id = notify_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reply sent to client */
|
/* this should never happen */
|
||||||
|
E_RETURN_VAL_IF_FAIL(id != 0, 0);
|
||||||
|
|
||||||
|
show_or_update_window(replaces_id > 0, id,
|
||||||
|
app_name, app_icon, summary, body, expire_timeout, hints);
|
||||||
|
#if 0
|
||||||
|
if(replaces_id) {
|
||||||
|
update_window(replaces_id, app_name, app_icon, summary, body, expire_timeout, hints);
|
||||||
|
sent_id = replaces_id;
|
||||||
|
} else {
|
||||||
|
show_window(notify_id, app_name, app_icon, summary, body, expire_timeout, hints);
|
||||||
|
sent_id = notify_id;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* reply sent to client, with used window id */
|
||||||
EdbusMessage reply;
|
EdbusMessage reply;
|
||||||
reply.create_reply(*m);
|
reply.create_reply(*m);
|
||||||
reply << EdbusData::from_uint32(replaces_id);
|
reply << EdbusData::from_uint32(id);
|
||||||
dbus->send(reply);
|
dbus->send(reply);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -357,7 +391,6 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
dbus.register_object(NOTIFICATIONS_DBUS_PATH);
|
dbus.register_object(NOTIFICATIONS_DBUS_PATH);
|
||||||
dbus.method_callback(notifications_dbus_method_cb, &dbus);
|
dbus.method_callback(notifications_dbus_method_cb, &dbus);
|
||||||
//dbus.signal_callback(notifications_dbus_signal_cb, &dbus);
|
|
||||||
dbus.setup_listener_with_fltk();
|
dbus.setup_listener_with_fltk();
|
||||||
server_running = true;
|
server_running = true;
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,64 @@
|
||||||
|
|
||||||
N_EVENTS=5
|
N_EVENTS=5
|
||||||
|
|
||||||
notify_cmd="notify-send --expire-time=10000"
|
#notify_cmd="notify-send --expire-time=3000"
|
||||||
|
#
|
||||||
|
#for((i=0;i<$N_EVENTS;i++)) do
|
||||||
|
# $notify_cmd "title $i" "this is content"
|
||||||
|
#done
|
||||||
|
|
||||||
for((i=0;i<$N_EVENTS;i++)) do
|
#method call sender=:1.798 -> dest=org.freedesktop.Notifications serial=116 path=/org/freedesktop/Notifications; interface=org.freedesktop.Notifications; member=Notify
|
||||||
$notify_cmd "title $i" "this is content"
|
# string "Mumble"
|
||||||
done
|
# uint32 1
|
||||||
|
# string "gtk-dialog-info"
|
||||||
|
# string "User Joined Channel"
|
||||||
|
# string "<a href='clientid://df93eabe004245bd18dd38cf9a07bd5242b2f522' class='log-user log-target'>madamova</a> entered channel."
|
||||||
|
# array [
|
||||||
|
# ]
|
||||||
|
# array [
|
||||||
|
# dict entry(
|
||||||
|
# string "desktop-entry"
|
||||||
|
# variant string "mumble"
|
||||||
|
# )
|
||||||
|
# ]
|
||||||
|
# int32 -1
|
||||||
|
|
||||||
|
dbus-send --type=method_call \
|
||||||
|
--dest=org.freedesktop.Notifications \
|
||||||
|
/org/freedesktop/Notifications org.freedesktop.Notifications.Notify \
|
||||||
|
string:"Mumble" \
|
||||||
|
uint32:1 \
|
||||||
|
string:"gtk-dialog-info" \
|
||||||
|
string:"User Joined Channel" \
|
||||||
|
string:"<a href='clientid://df93eabe004245bd18dd38cf9a07bd5242b2f522' class='log-user log-target'>madamova</a> entered channel." \
|
||||||
|
array:string:'' \
|
||||||
|
dict:string:string:'','' \
|
||||||
|
int32:-1
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
dbus-send --type=method_call \
|
||||||
|
--dest=org.freedesktop.Notifications \
|
||||||
|
/org/freedesktop/Notifications org.freedesktop.Notifications.Notify \
|
||||||
|
string:"Mumble 2" \
|
||||||
|
uint32:1 \
|
||||||
|
string:"gtk-dialog-info" \
|
||||||
|
string:"User Joined Channel #2" \
|
||||||
|
string:"<a href='clientid://df93eabe004245bd18dd38cf9a07bd5242b2f522' class='log-user log-target'>madamova</a> entered channel. asdasd asdasdsa asdasd asdasd asdasdsa" \
|
||||||
|
array:string:'' \
|
||||||
|
dict:string:string:'','' \
|
||||||
|
int32:-1
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
dbus-send --type=method_call \
|
||||||
|
--dest=org.freedesktop.Notifications \
|
||||||
|
/org/freedesktop/Notifications org.freedesktop.Notifications.Notify \
|
||||||
|
string:"Mumble 2" \
|
||||||
|
uint32:1 \
|
||||||
|
string:"gtk-dialog-info" \
|
||||||
|
string:"User Joined Channel #2 dasdasd asdasfdsa fsdfsdfa sdfsdfasdf asdfsdfasdfasdfasdfa asdfasdfdsafasdfasdfdsafdsaf sadfsdafds" \
|
||||||
|
string:"doh!" \
|
||||||
|
array:string:'' \
|
||||||
|
dict:string:string:'','' \
|
||||||
|
int32:-1
|
||||||
|
|
|
@ -36,13 +36,17 @@
|
||||||
# include <string.h> /* strncmp */
|
# include <string.h> /* strncmp */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||||
# include <sys/param.h>
|
# include <sys/param.h>
|
||||||
# include <sys/sysctl.h>
|
# include <sys/sysctl.h>
|
||||||
# if __FreeBSD_version < 500101
|
# if defined(__OpenBSD__)
|
||||||
# include <sys/dkstat.h>
|
# include <sys/sched.h>
|
||||||
# else
|
# else
|
||||||
# include <sys/resource.h>
|
# if __FreeBSD_version < 500101
|
||||||
|
# include <sys/dkstat.h>
|
||||||
|
# else
|
||||||
|
# include <sys/resource.h>
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# include <sys/stat.h>
|
# include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -66,9 +66,12 @@ EDELIB_NS_USING(EDBUS_SYSTEM)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* stolen from xfce's xfsm-shutdown-helper */
|
/* stolen from xfce's xfsm-shutdown-helper */
|
||||||
#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||||
# define POWEROFF_CMD "/sbin/shutdown -p now"
|
# define POWEROFF_CMD "/sbin/shutdown -p now"
|
||||||
# define REBOOT_CMD "/sbin/shutdown -r now"
|
# define REBOOT_CMD "/sbin/shutdown -r now"
|
||||||
|
#elif defined(__OpenBSD__)
|
||||||
|
# define POWEROFF_CMD "/sbin/shutdown -hp now"
|
||||||
|
# define REBOOT_CMD "/sbin/shutdown -r now"
|
||||||
#elif defined(sun) || defined(__sun)
|
#elif defined(sun) || defined(__sun)
|
||||||
# define POWEROFF_CMD "/usr/sbin/shutdown -i 5 -g 0 -y"
|
# define POWEROFF_CMD "/usr/sbin/shutdown -i 5 -g 0 -y"
|
||||||
# define REBOOT_CMD "/usr/sbin/shutdown -i 6 -g 0 -y"
|
# define REBOOT_CMD "/usr/sbin/shutdown -i 6 -g 0 -y"
|
||||||
|
|
Loading…
Reference in New Issue