Initial commit of rfkilld. - rfkilld - An rfkill daemon, which runs scripts according to rfkill events.
       
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit cb0a601f08208245331447ec00db5de4b447ce50
 (DIR) parent 3e475d9f0d2322e6a31dd70f4c1416e79a41aa76
 (HTM) Author: Christoph Lohmann <20h@r-36.net>
       Date:   Sat, 26 Feb 2011 21:31:38 +0100
       
       Initial commit of rfkilld.
       
       Diffstat:
         Makefile                            |      68 +++++++++++++++++++++----------
         README.md                           |      20 ++++++++++++++++++++
         arg.h                               |      19 +++++++++++++++++++
         bin/rfkilld                         |      96 -------------------------------
         config.mk                           |      16 +++++++++++++++-
         etc/conf.d/rfkilld                  |       5 +++++
         etc/rc.d/rfkilld                    |      37 +++++++++++++++++++++++++++++++
         etc/rfkilld/bluetooth.sh            |      15 +++++++++++++++
         etc/rfkilld/wlan.sh                 |      16 ++++++++++++++++
         etc/rfkilld/wwan.sh                 |      15 +++++++++++++++
         rfkilld.c                           |     170 +++++++++++++++++++++++++++++++
       
       11 files changed, 359 insertions(+), 118 deletions(-)
       ---
 (DIR) diff --git a/Makefile b/Makefile
       @@ -1,29 +1,55 @@
       -# rfkilld - rfkill daemon 
       +# rfkilld - rfkill daemon
        # See LICENSE file for copyright and license details.
        
        include config.mk
        
       -dist:
       +SRC = ${NAME}.c
       +OBJ = ${SRC:.c=.o}
       +
       +all: options ${NAME}
       +
       +options:
       +        @echo ${NAME} build options:
       +        @echo "CFLAGS   = ${CFLAGS}"
       +        @echo "LDFLAGS  = ${LDFLAGS}"
       +        @echo "CC       = ${CC}"
       +
       +.c.o:
       +        @echo CC $<
       +        @${CC} -c ${CFLAGS} $<
       +
       +${OBJ}: config.mk
       +
       +${NAME}: ${OBJ}
       +        @echo CC -o $@
       +        @${CC} -o $@ ${OBJ} ${LDFLAGS}
       +
       +clean:
       +        @echo cleaning
       +        @rm -f ${NAME} ${OBJ} ${NAME}-${VERSION}.tar.gz
       +
       +dist: clean
                @echo creating dist tarball
       -        @mkdir -p rfkilld-${VERSION}
       -        @cp -R LICENSE README.md Makefile config.mk \
       -                bin etc rfkilld-${VERSION}
       -        @tar -cf rfkilld-${VERSION}.tar rfkilld-${VERSION}
       -        @gzip rfkilld-${VERSION}.tar
       -        @rm -rf rfkilld-${VERSION}
       -
       -install:
       -        @echo installing rfkilld script to ${DESTDIR}${PREFIX}/bin
       -        @cp bin/rfkilld ${DESTDIR}${PREFIX}/bin
       -        @chmod 755 ${DESTDIR}${PREFIX}/bin/rfkilld
       -        @echo installing etc files into ${DESTDIR}/etc/rfkilld
       -        @mkdir -p ${DESTDIR}/etc/rfkilld
       -        @cp -R etc/rfkilld ${DESTDIR}/etc/rfkilld
       +        @mkdir -p ${NAME}-${VERSION}
       +        @cp -R LICENSE Makefile README.md config.mk \
       +                etc ${SRC} *.h ${NAME}-${VERSION}
       +        @tar -cf ${NAME}-${VERSION}.tar ${NAME}-${VERSION}
       +        @gzip ${NAME}-${VERSION}.tar
       +        @rm -rf ${NAME}-${VERSION}
       +
       +install: all
       +        @echo installing executable file to ${DESTDIR}${PREFIX}/bin
       +        @mkdir -p ${DESTDIR}${PREFIX}/bin
       +        @cp -f ${NAME} ${DESTDIR}${PREFIX}/bin
       +        @chmod 755 ${DESTDIR}${PREFIX}/bin/${NAME}
       +        @echo installing etc files into ${DESTDIR}/etc/${NAME}
       +        @mkdir -p ${DESTDIR}/etc/${NAME}
       +        @cp -R etc/${NAME} ${DESTDIR}/etc/${NAME}
        
        uninstall:
       -        @echo removing rfkilld script from ${DESTDIR}${PREFIX}/bin
       -        @rm -f ${DESTDIR}${PREFIX}/bin/rfkilld
       -        @echo removing etc files from ${DESTDIR}/etc/rfkilld
       -        @rm -rf ${DESTDIR}/etc/rfkilld
       +        @echo removing executable file from ${DESTDIR}${PREFIX}/bin
       +        @rm -f ${DESTDIR}${PREFIX}/bin/${NAME}
       +        @echo removing etc files from ${DESTDIR}/etc/${NAME}
       +        @rm -rf ${DESTDIR}/etc/${NAME}
        
       -.PHONY: dist install uninstall
       +.PHONY: all options clean dist install uninstall
 (DIR) diff --git a/README.md b/README.md
       @@ -0,0 +1,20 @@
       +# rfkilld - a rfkill daemon
       +
       +This daemon listens for rfkill events from the kernel, over a netlink,
       +for the »rfkill« subsystem. When an event occurs, the specific proper-
       +tties (NAME, TYPE, STATE) are taken and the files
       +
       +        /etc/rfkilld/$name $state $type
       +        /etc/rfkilld/$type $state $name
       +
       +are run using the shown arguments.
       +
       +Included are rc.d and conf.d files for being used in Archlinux.
       +
       +It is recommended to run this in conjunction with conn [0].
       +
       +
       +Have fun!
       +
       +t[0] http://git.r-36.net/conn/
       +
 (DIR) diff --git a/arg.h b/arg.h
       @@ -0,0 +1,19 @@
       +#ifndef ARG_H
       +#define ARG_H
       +
       +#define USED(x) ((void)(x))        
       +
       +extern char *argv0;
       +
       +#define        ARGBEGIN        for(argv0 = *argv, argv++, argc--;\
       +                            argv[0] && argv[0][0]=='-' && argv[0][1];\
       +                            argc--, argv++) {\
       +                                char _argc;\
       +                                _argc = argv[0][1];\
       +                                switch(_argc)
       +#define        ARGEND                USED(_argc);} USED(argv);USED(argc);
       +#define        EARGF(x)        ((argv[1] == NULL)? ((x), abort(), (char *)0) :\
       +                        (argc--, argv++, argv[0]))
       +
       +#endif
       +
 (DIR) diff --git a/bin/rfkilld b/bin/rfkilld
       @@ -1,96 +0,0 @@
       -#!/bin/sh
       -
       -usage() {
       -        echo "usage: `basename $1` [-hbl] [-p pidfile] [-e etcdir] [-b]"
       -}
       -
       -UDEVMONITORCMD="/usr/bin/nlmon -p -k"
       -ETCDIR="/etc/rfkilld"
       -PIDFILE="/var/run/rfkilld.pid"
       -dobackground=0
       -dodebug=0
       -dolog=0
       -
       -while getopts "ldp:e:" opt;
       -do
       -        case $opt in
       -                d)
       -                        dodebug=1
       -                        ;;
       -                p)
       -                        PIDFILE="$OPTARG"
       -                        ;;
       -                e)
       -                        ETCDIR="$OPTARG"
       -                        ;;
       -                l)
       -                        dolog=1
       -                        ;;
       -                *)
       -                        usage $0
       -                        exit 1
       -                        ;;
       -        esac
       -done
       -shift $(($OPTIND - 1))
       -
       -debugcmd=""
       -if [ $dodebug -eq 1 ];
       -tthen
       -        debugcmd="-d"
       -        set -x
       -fi
       -
       -echo $$ > $PIDFILE 2>&1 >/dev/null
       -ttrap "[ -e $PIDFILE ] && rm $PIDFILE; exit 0;" 2 3 6 9 15
       -
       -name=
       -ttype=
       -state=
       -
       -$UDEVMONITORCMD | \
       -while read status
       -do
       -        [[ "$status" =~ ^RFKILL_NAME=(.*)$ ]] \
       -                && name="${BASH_REMATCH[1]}"
       -        [[ "$status" =~ ^RFKILL_TYPE=(.*)$ ]] \
       -                && type="${BASH_REMATCH[1]}"
       -        [[ "$status" =~ ^RFKILL_STATE=(.*)$ ]] \
       -                && state="${BASH_REMATCH[1]}"
       -
       -        if [ "$status" == "" ];
       -        then
       -                if [ "$name" == "" ] || [ "$type" == "" ] \
       -                        || [ "$state" == "" ];
       -                then
       -                        continue
       -                fi
       -
       -                [ $dodebug -eq 1 ] \
       -                        && logger -t rfkilld "req $name $type $state"
       -
       -                if [ -x $ETCDIR/$name.sh ];
       -                then
       -                        $ETCDIR/$name.sh $state 2>&1 >/dev/null &        
       -                        
       -                        [ $dolog -eq 1 ] \
       -                                && logger -t rfkilld "ran $name.sh $state"
       -                fi
       -
       -                if [ -x $ETCDIR/$type.sh ];
       -                then
       -                        $ETCDIR/$type.sh $state $name 2>&1 >/dev/null &
       -
       -                        [ $dolog -eq 1 ] \
       -                                && logger -t rfkilld \
       -                                "ran $type.sh $state $name"
       -                fi
       -
       -                name=
       -                type=
       -                state=
       -        fi
       -done
       -
       -exit 0
       -
 (DIR) diff --git a/config.mk b/config.mk
       @@ -1,4 +1,5 @@
       -# rfkilld version
       +# rfkilld metadata
       +NAME = rfkilld
        VERSION = 0.2
        
        # Customize below to fit your system
       @@ -7,3 +8,16 @@ VERSION = 0.2
        PREFIX = /usr
        MANPREFIX = ${PREFIX}/share/man
        
       +# includes and libs
       +INCS = -I. -I/usr/include
       +LIBS = -L/usr/lib -lc -ludev
       +
       +# flags
       +CPPFLAGS = -DVERSION=\"${VERSION}\"
       +CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
       +LDFLAGS = -g ${LIBS}
       +#LDFLAGS = -s ${LIBS}
       +
       +# compiler and linker
       +CC = cc
       +
 (DIR) diff --git a/etc/conf.d/rfkilld b/etc/conf.d/rfkilld
       @@ -0,0 +1,5 @@
       +#
       +# Parameters to be passed to rfkilld. 
       +#
       +RFKILLD_ARGS="-l -b"
       +
 (DIR) diff --git a/etc/rc.d/rfkilld b/etc/rc.d/rfkilld
       @@ -0,0 +1,37 @@
       +#!/bin/bash
       +
       +. /etc/rc.conf
       +. /etc/rc.d/functions
       +. /etc/conf.d/rfkilld
       +
       +PID=`pidof -o %PPID /usr/bin/rfkilld`
       +case "$1" in
       +  start)
       +    stat_busy "Starting rfkilld"
       +    [ -z "$PID" ] && /usr/bin/rfkilld $RFKILLD_ARGS 2>&1
       +    if [ $? -gt 0 ]; then
       +      stat_fail
       +    else
       +      PID=`pidof -o %PPID /usr/bin/rfkilld`
       +      add_daemon rfkilld
       +      stat_done
       +    fi
       +    ;;
       +  stop)
       +    stat_busy "Stopping rfkilld"
       +    [ ! -z "$PID" ]  && kill -KILL $PID &>/dev/null
       +    if [ $? -gt 0 ]; then
       +      stat_fail
       +    else
       +      rm_daemon rfkilld 
       +      stat_done
       +    fi
       +    ;;
       +  restart)
       +    $0 stop
       +    $0 start
       +    ;;
       +  *)
       +    echo "usage: $0 {start|stop|restart}"  
       +esac
       +exit 0
 (DIR) diff --git a/etc/rfkilld/bluetooth.sh b/etc/rfkilld/bluetooth.sh
       @@ -0,0 +1,15 @@
       +#!/bin/sh
       +
       +case $1 in
       +        0)
       +                ;;
       +        1)
       +                rfkill block bluetooth
       +                ;;
       +        *)
       +                exit 1
       +                ;;
       +esac
       +
       +exit 0
       +
 (DIR) diff --git a/etc/rfkilld/wlan.sh b/etc/rfkilld/wlan.sh
       @@ -0,0 +1,16 @@
       +#!/bin/sh
       +
       +case $1 in
       +        0)
       +                conn -k wifi
       +                ;;
       +        1)
       +                conn -s wifi
       +                ;;
       +        *)
       +                exit 1
       +                ;;
       +esac
       +
       +exit 0
       +
 (DIR) diff --git a/etc/rfkilld/wwan.sh b/etc/rfkilld/wwan.sh
       @@ -0,0 +1,15 @@
       +#!/bin/sh
       +
       +case $1 in
       +        0)
       +                ;;
       +        1|2)
       +                # conn -s wwan
       +                ;;
       +        *)
       +                exit 1
       +                ;;
       +esac
       +
       +exit 0
       +
 (DIR) diff --git a/rfkilld.c b/rfkilld.c
       @@ -0,0 +1,170 @@
       +/*
       + * Copy me if you can.
       + * by 20h
       + */
       +
       +#define _XOPEN_SOURCE
       +#include <unistd.h>
       +#include <stdio.h>
       +#include <stdlib.h>
       +#include <libudev.h>
       +#include <poll.h>
       +#include <ctype.h>
       +#include <string.h>
       +#include <stdarg.h>
       +#include <syslog.h>
       +#include <signal.h>
       +#include <strings.h>
       +#include <sys/wait.h>
       +#include <sys/types.h>
       +#include <sys/stat.h>
       +
       +#include "arg.h"
       +
       +char *argv0;
       +char *etcdir = "/etc/rfkilld";
       +int running = 1;
       +int dolog = 0;
       +
       +void
       +runifexecutable(char *file, char *oname, char *ostate)
       +{
       +        char cmd[512], name[64], state[16]; 
       +        int pid;
       +
       +        strncpy(name, oname, sizeof(name));
       +        strncpy(state, ostate, sizeof(state));
       +
       +        snprintf(cmd, sizeof(cmd), "%s/%s.sh", etcdir, file);
       +        if (!access(cmd, X_OK)) {
       +                if (!(pid = fork())) {
       +                        if (!fork())
       +                                if(execl(cmd, name, state, NULL) < 0)
       +                                        perror("execl");
       +                        exit(EXIT_SUCCESS);
       +                }
       +                waitpid(pid, NULL, 0);
       +        }
       +}
       +
       +void
       +runscripts(struct udev_device *dev)
       +{
       +        struct udev_list_entry *props;
       +        char *type, *name, *state;
       +
       +        props = udev_device_get_properties_list_entry(dev);
       +        type = (char *)udev_device_get_property_value(dev, "RFKILL_NAME");
       +        name = (char *)udev_device_get_property_value(dev, "RFKILL_TYPE");
       +        state = (char *)udev_device_get_property_value(dev, "RFKILL_STATE");
       +
       +        if (dolog)
       +                syslog(LOG_NOTICE, "name: %s; type: %s; state: %s;\n",
       +                                name, type, state);
       +
       +        runifexecutable(name, type, state);
       +        runifexecutable(type, name, state);
       +}
       +
       +void
       +sighandler(int sig)
       +{
       +        switch(sig) {
       +        case SIGCHLD:
       +                while(waitpid(-1, NULL, WNOHANG) > 0);
       +                break;
       +        case SIGHUP:
       +        case SIGINT:
       +        case SIGQUIT:
       +        case SIGABRT:
       +        case SIGTERM:
       +                closelog();
       +                running = 0;
       +                break;
       +        default:
       +                break;
       +        }
       +}
       +
       +void
       +initsignals(void)
       +{
       +        signal(SIGCHLD, sighandler);
       +        signal(SIGHUP, sighandler);
       +        signal(SIGINT, sighandler);
       +        signal(SIGQUIT, sighandler);
       +        signal(SIGABRT, sighandler);
       +        signal(SIGTERM, sighandler);
       +        signal(SIGKILL, sighandler);
       +}
       +
       +void
       +usage(void)
       +{
       +        fprintf(stderr, "usage: %s [-hbl] [-e etcdir]\n", argv0);
       +        fflush(stderr);
       +        exit(EXIT_FAILURE);
       +}
       +
       +int
       +main(int argc, char *argv[])
       +{
       +        struct udev *udev;
       +        struct udev_monitor *mon;
       +        struct udev_device *dev;
       +        struct pollfd fds[1];
       +        int ret, dodaemonize;
       +
       +        dodaemonize = 0;
       +
       +        ARGBEGIN {
       +        case 'b':
       +                dodaemonize = 1;
       +                break;
       +        case 'l':
       +                dolog = 1;
       +                break;
       +        case 'e':
       +                etcdir = EARGF(usage());
       +                break;
       +        default:
       +                usage();
       +        } ARGEND;
       +
       +        if(dodaemonize)
       +                daemon(0, 0);
       +
       +        if(dolog)
       +                openlog("rfkilld", 0, LOG_DAEMON);
       +
       +        initsignals();
       +
       +        udev = udev_new();
       +        if (!udev) {
       +                perror("udev_new");
       +                exit(EXIT_FAILURE);
       +        }
       +
       +        mon = udev_monitor_new_from_netlink(udev, "kernel");
       +        udev_monitor_filter_add_match_subsystem_devtype(mon, "rfkill", NULL);
       +        udev_monitor_enable_receiving(mon);
       +        
       +        fds[0].fd = udev_monitor_get_fd(mon);
       +        fds[0].events = POLLIN|POLLPRI;
       +        while(running) {
       +                ret = poll(fds, 1, 500);        
       +                if (ret > 0) {
       +                        if ((fds[0].revents & POLLIN) \
       +                                        || (fds[0].revents & POLLPRI)) {
       +                                dev = udev_monitor_receive_device(mon);
       +                                if (dev) {
       +                                        runscripts(dev);
       +                                        udev_device_unref(dev);
       +                                }
       +                        }
       +                }
       +        }
       +
       +        exit(EXIT_SUCCESS);
       +}
       +