Commit 85aa460b authored by amnesia's avatar amnesia

Compile Liberté Linux's udev-watchdog at build time.

This is aimed at helping solve
https://amnesia.boum.org/todo/erase_memory_when_the_USB_stick_is_removed/

This commit is not in master because libudev-dev does not exist in Lenny.
parent 42af5a2e
#!/bin/sh
# Compile and install a custom udev-watchdog program
# Including common functions
. "${LH_BASE:-/usr/share/live-helper}"/scripts/build.sh
# Setting static variables
DESCRIPTION="$(Echo 'compile and install a custom udev-watchdog program')"
HELP=""
USAGE="${PROGRAM}"
# Get LH_DISTRIBUTION from config/bootstrap
Read_conffiles config/all config/common config/chroot config/bootstrap
Set_defaults
Echo_message "compiling a custom udev-watchdog program"
apt-get install --yes gcc binutils libudev-dev
SRC="/usr/src/udev-watchdog.c"
DST="/usr/local/sbin/udev-watchdog"
gcc -o "$DST" "$SRC" -static -Wall -ludev
strip --strip-all "$DST"
aptitude --assume-yes purge libudev-dev
/*
* Copyright (C) 2004-2009 Kay Sievers <kay.sievers@vrfy.org>
*
* + Trimmed from udev-149. Fixed passing of devtype parameter.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <getopt.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/select.h>
#include <linux/types.h>
#include <linux/netlink.h>
#include <libudev.h>
static volatile sig_atomic_t udev_exit;
static void sig_handler(int signum)
{
if (signum == SIGINT || signum == SIGTERM)
udev_exit = 2;
}
static int print_device(struct udev_device *device, const char *f_action, const char *f_devsuffix)
{
struct timeval tv;
struct timezone tz;
const char *action = udev_device_get_action(device);
const char *devpath = udev_device_get_devpath(device);
size_t f_len, d_len;
gettimeofday(&tv, &tz);
printf("%llu.%06u %s %s\n",
(unsigned long long) tv.tv_sec, (unsigned int) tv.tv_usec,
action, devpath);
if (! strcmp(f_action, action)) {
f_len = strlen(f_devsuffix);
d_len = strlen(devpath);
if (d_len >= f_len && !strcmp(devpath+(d_len-f_len), f_devsuffix))
return 1;
}
return 0;
}
int main(int argc, char *argv[])
{
int rc = 0;
struct udev *udev = udev_new();
if (udev == NULL)
goto out2;
if (argc != 2)
goto out2;
struct sigaction act;
sigset_t mask;
struct udev_monitor *kernel_monitor = NULL;
fd_set readfds;
const char *filter_subsys = "block";
const char *filter_devtype = "partition";
const char *filter_action = "remove";
const char *filter_devsuffix = argv[1];
/* set signal handlers */
memset(&act, 0x00, sizeof(struct sigaction));
act.sa_handler = sig_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART;
sigaction(SIGINT, &act, NULL);
sigaction(SIGTERM, &act, NULL);
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGTERM);
sigprocmask(SIG_UNBLOCK, &mask, NULL);
kernel_monitor = udev_monitor_new_from_netlink(udev, "kernel");
if (kernel_monitor == NULL) {
fprintf(stderr, "error: unable to create netlink socket\n");
rc = 3;
goto out;
}
if (udev_monitor_filter_add_match_subsystem_devtype(kernel_monitor, filter_subsys, filter_devtype) < 0)
fprintf(stderr, "error: unable to apply subsystem filter '%s:%s'\n", filter_subsys, filter_devtype);
if (udev_monitor_enable_receiving(kernel_monitor) < 0) {
fprintf(stderr, "error: unable to subscribe to kernel events\n");
rc = 4;
goto out;
}
while (!udev_exit) {
int fdcount;
FD_ZERO(&readfds);
if (kernel_monitor != NULL)
FD_SET(udev_monitor_get_fd(kernel_monitor), &readfds);
fdcount = select(udev_monitor_get_fd(kernel_monitor)+1,
&readfds, NULL, NULL, NULL);
if (fdcount < 0) {
if (errno != EINTR)
fprintf(stderr, "error receiving uevent message: %m\n");
continue;
}
if ((kernel_monitor != NULL) && FD_ISSET(udev_monitor_get_fd(kernel_monitor), &readfds)) {
struct udev_device *device;
device = udev_monitor_receive_device(kernel_monitor);
if (device == NULL)
continue;
if (print_device(device, filter_action, filter_devsuffix))
udev_exit = 1;
udev_device_unref(device);
}
}
out:
udev_monitor_unref(kernel_monitor);
out2:
udev_unref(udev);
if (udev_exit == 2)
rc = 1;
return rc;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment