This commit is contained in:
Alexander Zhirov 2023-12-25 00:06:56 +03:00
parent bb72f57776
commit cd5f9f7a12
10 changed files with 344 additions and 342 deletions

11
.vscode/settings.json vendored
View File

@ -30,10 +30,11 @@
"mpl-lib.h": "c", "mpl-lib.h": "c",
"mpl-core.h": "c", "mpl-core.h": "c",
"mpl.h": "c", "mpl.h": "c",
"mpl-udev.h": "c" "mpl-udev.h": "c",
"mpl-args.h": "c",
"*.in": "cpp",
"signal.h": "c",
"stdio.h": "c"
}, },
"cmake.configureOnOpen": false, "cmake.configureOnOpen": false
"editor.rulers": [
80
]
} }

View File

@ -1,6 +1,33 @@
cmake_minimum_required(VERSION 3.18.4) cmake_minimum_required(VERSION 3.18.4)
project(mportlink) project(mportlink)
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Os")
set(VERSION_MAJOR 0)
set(VERSION_MINOR 1)
set(VERSION_PATCH 0)
string(TIMESTAMP CURRENT_YEAR "%y" UTC)
string(TIMESTAMP DAY_OF_YEAR "%j" UTC)
string(CONCAT BASEVERSION "${VERSION_MAJOR}" "." "${VERSION_MINOR}" "." "${VERSION_PATCH}")
string(CONCAT BUILDVERSION "${BASEVERSION}" "." "${CURRENT_YEAR}" "${DAY_OF_YEAR}")
execute_process(
COMMAND git describe HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(GIT_SHORT_HASH STREQUAL "")
set(VERSION "${BUILDVERSION}")
else()
set(VERSION "${GIT_VERSION}")
endif()
add_definitions(-DVERSION="${VERSION}")
file(GLOB_RECURSE SRC_FILES_LIST src/*.c) file(GLOB_RECURSE SRC_FILES_LIST src/*.c)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)

BIN
mportlink Executable file

Binary file not shown.

View File

@ -5,304 +5,108 @@
* Telegram @alexanderzhirov * Telegram @alexanderzhirov
*/ */
#include "mpl-core.h"
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/file.h> #include <sys/file.h>
#include <unistd.h>
#include "mpl-core.h"
#define LOCKFILE "/run/lock/mportlink.lock" #define LOCKFILE "/run/lock/mportlink.lock"
#define DEV_PATH "/dev/" #define DEV_PATH "/dev/"
#define DONGLE_PATH (DEV_PATH "dongle/") #define DONGLE_PATH (DEV_PATH "dongle/")
static void mpl_create_dongle_dir() static int mpl_create_dongle_dir()
{ {
struct stat st; struct stat st;
if (stat(DONGLE_PATH, &st) == 0) { if (stat(DONGLE_PATH, &st) == 0)
if (!S_ISDIR(st.st_mode)) { {
MPLOG(LOG_WARNING, "%s exists and is not a directory", if (!S_ISDIR(st.st_mode))
DONGLE_PATH); {
exit(EXIT_FAILURE); MPLOG(LOG_WARNING, "%s exists and is not a directory", DONGLE_PATH);
return 1;
} }
} else if (mkdir(DONGLE_PATH, }
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1) { else if (mkdir(DONGLE_PATH, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
{
MPLOG(LOG_ERR, "unable to create a directory %s", DONGLE_PATH); MPLOG(LOG_ERR, "unable to create a directory %s", DONGLE_PATH);
exit(EXIT_FAILURE); return 1;
} }
return 0;
} }
int mpl_init() void static mpl_free(MPL *mpl)
{ {
openlog(MPL, LOG_PID, LOG_SYSLOG); if (mpl)
free(mpl);
int lock_fd = open(LOCKFILE, O_CREAT | O_RDWR, 0644);
if (lock_fd < 0) {
MPLOG(LOG_ERR, "Unable to create a lockfile");
exit(EXIT_FAILURE);
}
int rc = flock(lock_fd, LOCK_EX | LOCK_NB);
if (rc || errno == EWOULDBLOCK) {
MPLOG(LOG_ERR, "Only one instance of %s is allowed", MPL);
exit(EXIT_FAILURE);
}
mpl_create_dongle_dir();
MPLOG(LOG_NOTICE, "Starting the %s daemon", MPL);
return lock_fd;
} }
void mpl_stop(const int lock_fd) MPL *mpl_init(MPL_PARAMETERS *parameters)
{ {
flock(lock_fd, LOCK_UN); MPL *mpl = (MPL *)calloc(1, sizeof(MPL));
MPLOG(LOG_NOTICE, "Stopping the %s daemon", MPL); if (!mpl)
{
MPLOG(LOG_ERR, "error getting the MPL structure");
exit(1);
}
mpl->parameters.check_device = parameters->check_device;
mpl->cancellable.signal = 0;
mpl->cancellable.exit = 0;
mpl->fd = open(LOCKFILE, O_CREAT | O_RDWR, 0644);
if (mpl->fd < 0)
{
MPLOG(LOG_ERR, "unable to create a lockfile");
exit(1);
}
int rc = flock(mpl->fd, LOCK_EX | LOCK_NB);
if (rc || errno == EWOULDBLOCK)
{
MPLOG(LOG_ERR, "only one instance of %s is allowed", MPL_NAME);
exit(1);
}
if (mpl_create_dongle_dir())
{
MPLOG(LOG_ERR, "%s will be stopped", MPL_NAME);
exit(1);
}
if (mpl_udev_init(&mpl->udev))
{
MPLOG(LOG_ERR, "%s will be stopped", MPL_NAME);
mpl_free(mpl);
exit(1);
}
MPLOG(LOG_NOTICE, "starting the %s daemon", MPL_NAME);
return mpl;
}
void mpl_stop(MPL *mpl)
{
mpl_udev_free(&mpl->udev);
flock(mpl->fd, LOCK_UN);
mpl_free(mpl);
if (mpl->cancellable.exit)
MPLOG(LOG_NOTICE, "stopping the %s daemon", MPL_NAME);
else
MPLOG(LOG_NOTICE, "successful completion of the process %d", getpid());
closelog(); closelog();
} }
MPL_UDEV *mpl_new() void mpl_loop(MPL *mpl)
{ {
MPL_UDEV *mpl_udev = (MPL_UDEV *)calloc(1, sizeof(MPL_UDEV)); if (mpl->parameters.check_device)
mpl_udev_check_devices(&mpl->udev);
if (mpl_udev == NULL) { mpl_udev_loop(&mpl->udev, &mpl->cancellable);
MPLOG(LOG_ERR, "Error getting the udev structure");
exit(EXIT_FAILURE);
}
return mpl_udev;
} }
void mpl_loop(MPL_UDEV *mpl_udev)
{
}
// typedef struct
// {
// const gchar *manufacturer;
// const gchar *model;
// const gchar *imei;
// const gchar *device_identifier;
// MMModemPortInfo *ports;
// guint n_ports;
// } MPLmodem;
// MPLmodem *mpl_get_new_modem()
// {
// MPLmodem *modem = (MPLmodem *)calloc(1, sizeof(MPLmodem));
// if (modem == NULL)
// {
// syslog(LOG_ERR, "mpl_get_new_modem, modem: memory allocation error");
// raise(SIGINT);
// }
// return modem;
// }
// void mpl_free_modem(MPLmodem *modem)
// {
// if (modem->n_ports && modem->ports)
// mm_modem_port_info_array_free(modem->ports, modem->n_ports);
// free(modem);
// }
// void mpl_print_modem_info(MPLmodem *modem, bool connected)
// {
// gchar *status;
// status = connected ? "Connected" : "Disconnected";
// g_print("%s %s %s (%s)\n", status, modem->manufacturer, modem->model, modem->device_identifier);
// g_print("`-- Count ports: %d\n", modem->n_ports);
// for (guint i = 0; i < modem->n_ports; i++)
// {
// if (i + 1 < modem->n_ports)
// {
// g_print(" |-- Port %d:\n", i);
// g_print(" | |-- Name: %s\n", modem->ports[i].name);
// g_print(" | `-- Link: %s-%d\n", modem->imei, i);
// }
// else
// {
// g_print(" `-- Port %d:\n", i);
// g_print(" |-- Name: %s\n", modem->ports[i].name);
// g_print(" `-- Link: %s-%d\n", modem->imei, i);
// }
// }
// }
// MPLmodem *mpl_get_new_modem_info(MMObject *obj)
// {
// MPLmodem *mpl_modem = NULL;
// MMModem *mm_modem = mm_object_get_modem(obj);
// if (mm_modem == NULL)
// {
// syslog(LOG_ERR, "mpl_get_new_modem_info, mm_modem: modem does not implement the interface");
// return NULL;
// }
// mpl_modem = mpl_get_new_modem();
// mpl_modem->manufacturer = mm_modem_get_manufacturer(mm_modem);
// mpl_modem->model = mm_modem_get_model(mm_modem);
// mpl_modem->imei = mm_modem_get_equipment_identifier(mm_modem);
// mpl_modem->device_identifier = mm_modem_get_device_identifier(mm_modem);
// gboolean success = mm_modem_get_ports(mm_modem, &mpl_modem->ports, &mpl_modem->n_ports);
// g_object_unref(mm_modem);
// if (success)
// return mpl_modem;
// else
// syslog(LOG_WARNING, "mpl_get_new_modem_info, success: error receiving modem ports");
// mpl_free_modem(mpl_modem);
// return NULL;
// }
// char *mpl_get_dst_path(guint index, const gchar *imei)
// {
// char *dst_path = NULL;
// guint size_id = snprintf(NULL, 0, "-%d", index);
// char *id = (char *)calloc(size_id + 1, sizeof(char));
// if (id == NULL)
// {
// syslog(LOG_ERR, "mpl_get_dst_path, id: memory allocation error");
// raise(SIGINT);
// }
// sprintf(id, "-%d", index);
// guint dst_path_size = strlen(DONGLE_PATH) + strlen(imei) + size_id;
// dst_path = (char *)calloc(dst_path_size + 1, sizeof(char));
// if (dst_path == NULL)
// {
// syslog(LOG_ERR, "mpl_get_dst_path, dst_path: memory allocation error");
// raise(SIGINT);
// }
// strcpy(dst_path, DONGLE_PATH);
// strcat(dst_path, imei);
// strcat(dst_path, id);
// free(id);
// return dst_path;
// }
// char *mpl_get_src_path(const gchar *port_name)
// {
// char *src_path = NULL;
// guint src_path_size = strlen(DEV_PATH) + strlen(port_name);
// src_path = (char *)calloc(src_path_size + 1, sizeof(char));
// if (src_path == NULL)
// {
// syslog(LOG_ERR, "mpl_get_src_path, src_path: memory allocation error");
// raise(SIGINT);
// }
// strcpy(src_path, DEV_PATH);
// strcat(src_path, port_name);
// return src_path;
// }
// void mpl_symlink_ports(MPLmodem *modem)
// {
// for (guint i = 0; i < modem->n_ports; i++)
// {
// char *src_path = mpl_get_src_path(modem->ports[i].name);
// char *dst_path = mpl_get_dst_path(i, modem->imei);
// struct stat st;
// if (access(src_path, F_OK) == -1)
// {
// syslog(LOG_ERR, "mpl_symlink_ports, src_path: device file is not available [%s]", src_path);
// free(src_path);
// free(dst_path);
// continue;
// }
// if (lstat(dst_path, &st) == 0)
// {
// syslog(LOG_WARNING, "mpl_symlink_ports, dst_path: a symbolic link to the device already exists [%s]", dst_path);
// if (unlink(dst_path) == -1)
// {
// syslog(LOG_ERR, "mpl_symlink_ports, dst_path: link could not be deleted [%s]", dst_path);
// free(src_path);
// free(dst_path);
// continue;
// }
// }
// if (symlink(src_path, dst_path) == 0)
// syslog(LOG_NOTICE, "mpl_symlink_ports, dst_path: the symbolic link has been successfully created [%s -> %s]", dst_path, src_path);
// else
// syslog(LOG_ERR, "mpl_symlink_ports, dst_path: error creating a symbolic link [%s -> %s]", dst_path, src_path);
// free(src_path);
// free(dst_path);
// }
// }
// void mpl_unlink_ports(MPLmodem *modem)
// {
// for (guint i = 0; i < modem->n_ports; i++)
// {
// char *dst_path = mpl_get_dst_path(i, modem->imei);
// struct stat st;
// if (lstat(dst_path, &st) == -1)
// {
// syslog(LOG_WARNING, "mpl_unlink_ports, dst_path: a symbolic link to the device not exists [%s]", dst_path);
// free(dst_path);
// continue;
// }
// if (unlink(dst_path) == 0)
// syslog(LOG_NOTICE, "mpl_unlink_ports, dst_path: link was successfully deleted [%s]", dst_path);
// else
// syslog(LOG_ERR, "mpl_unlink_ports, dst_path: link could not be deleted [%s]", dst_path);
// free(dst_path);
// }
// }
// void mpl_device_added(MMManager *manager, MMObject *obj)
// {
// MPLmodem *modem = mpl_get_new_modem_info(obj);
// if (modem == NULL)
// return;
// // mpl_print_modem_info(modem, true);
// mpl_symlink_ports(modem);
// mpl_free_modem(modem);
// }
// void mpl_device_removed(MMManager *manager, MMObject *obj)
// {
// MPLmodem *modem = mpl_get_new_modem_info(obj);
// if (modem == NULL)
// return;
// // mpl_print_modem_info(modem, false);
// mpl_unlink_ports(modem);
// mpl_free_modem(modem);
// }

View File

@ -9,11 +9,23 @@
#define MPL_CORE_H_ #define MPL_CORE_H_
#include "mpl-lib.h" #include "mpl-lib.h"
#include "mpl-udev.h"
int mpl_init(); typedef struct
void mpl_stop(const int lock_fd); {
void mpl_loop(MPL_UDEV *mpl_udev); int check_device;
} MPL_PARAMETERS;
MPL_UDEV *mpl_new(); typedef struct
{
int fd;
MPL_PARAMETERS parameters;
MPL_CANCELLABLE cancellable;
MPL_UDEV udev;
} MPL;
MPL *mpl_init(MPL_PARAMETERS *parameters);
void mpl_stop(MPL *mpl);
void mpl_loop(MPL *mpl);
#endif #endif

View File

@ -15,24 +15,20 @@
#include <string.h> #include <string.h>
#include <syslog.h> #include <syslog.h>
#define MPL "mportlink" #define MPL_NAME "mportlink"
#define MPLOG(PRIORITY, fmt, ...) do { \ #define MPLOG(PRIORITY, fmt, ...) do { \
char buf[256]; \ char buf[256]; \
snprintf(buf, sizeof(buf), fmt __VA_OPT__(,) __VA_ARGS__); \ snprintf(buf, sizeof(buf), fmt __VA_OPT__(,) __VA_ARGS__); \
PRIORITY < LOG_WARNING ? \ PRIORITY < LOG_WARNING && errno ? \
syslog(PRIORITY, "%s(): %s (%s)", __func__, buf, \ syslog(PRIORITY, "%s(): %s (%s)", __func__, buf, strerror(errno)) : \
strerror(errno)) : \
syslog(PRIORITY, "%s(): %s", __func__, buf); \ syslog(PRIORITY, "%s(): %s", __func__, buf); \
} while(0) } while(0)
typedef struct _MPL_UDEV MPL_UDEV; typedef struct
struct _MPL_UDEV
{ {
struct udev *udev; int signal;
struct udev_monitor *monitor; int exit;
int udev_fd; } MPL_CANCELLABLE;
};
#endif #endif

View File

@ -5,48 +5,54 @@
* Telegram @alexanderzhirov * Telegram @alexanderzhirov
*/ */
#include "mpl-lib.h"
#include "mpl-udev.h" #include "mpl-udev.h"
#include <libudev.h>
void mpl_udev_init(MPL_UDEV *mpl_udev) #include <unistd.h>
#include <sys/wait.h>
int mpl_udev_init(MPL_UDEV *udev)
{ {
mpl_udev->udev = udev_new(); udev->context = udev_new();
if (mpl_udev->udev == NULL) { if (udev->context == NULL)
MPLOG(LOG_ERR, "Error creating udev context"); {
exit(EXIT_FAILURE); MPLOG(LOG_ERR, "error creating udev context");
return 1;
} }
mpl_udev->monitor = udev_monitor_new_from_netlink(mpl_udev->udev, "udev"); udev->monitor = udev_monitor_new_from_netlink(udev->context, "udev");
if (mpl_udev->monitor == NULL) { if (udev->monitor == NULL)
MPLOG(LOG_ERR, "Error creating udev monitor"); {
udev_unref(mpl_udev->udev); MPLOG(LOG_ERR, "error creating udev monitor");
exit(EXIT_FAILURE); mpl_udev_free(udev);
return 1;
} }
udev_monitor_filter_add_match_subsystem_devtype(mpl_udev->monitor, udev_monitor_filter_add_match_subsystem_devtype(udev->monitor, "usb", NULL);
"usb", NULL); udev_monitor_enable_receiving(udev->monitor);
udev_monitor_enable_receiving(mpl_udev->monitor);
mpl_udev->udev_fd = udev_monitor_get_fd(mpl_udev->monitor); udev->fd = udev_monitor_get_fd(udev->monitor);
if (mpl_udev->udev_fd < 0) { if (udev->fd < 0)
MPLOG(LOG_ERR, "Error creating udev monitor descriptor"); {
udev_unref(mpl_udev->udev); MPLOG(LOG_ERR, "error creating udev monitor descriptor");
exit(EXIT_FAILURE); mpl_udev_free(udev);
return 1;
} }
return 0;
} }
void mpl_udev_check_devices(MPL_UDEV *mpl_udev) int mpl_udev_check_devices(MPL_UDEV *udev)
{ {
struct udev_device *dev; struct udev_device *dev;
struct udev_enumerate *enumerate; struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *dev_list_entry; struct udev_list_entry *devices, *dev_list_entry;
enumerate = udev_enumerate_new(mpl_udev->udev); enumerate = udev_enumerate_new(udev->context);
if (enumerate == NULL) { if (enumerate == NULL)
MPLOG(LOG_ERR, "Error creating udev enumerate"); {
exit(EXIT_FAILURE); MPLOG(LOG_ERR, "error creating udev enumerate");
return 1;
} }
udev_enumerate_add_match_subsystem(enumerate, "usb"); udev_enumerate_add_match_subsystem(enumerate, "usb");
@ -54,14 +60,16 @@ void mpl_udev_check_devices(MPL_UDEV *mpl_udev)
devices = udev_enumerate_get_list_entry(enumerate); devices = udev_enumerate_get_list_entry(enumerate);
if (devices == NULL) { if (devices == NULL)
MPLOG(LOG_ERR, "Error get udev devices"); {
exit(EXIT_FAILURE); MPLOG(LOG_ERR, "error get udev devices");
return 1;
} }
udev_list_entry_foreach(dev_list_entry, devices) { udev_list_entry_foreach(dev_list_entry, devices)
{
const char *syspath = udev_list_entry_get_name(dev_list_entry); const char *syspath = udev_list_entry_get_name(dev_list_entry);
dev = udev_device_new_from_syspath(mpl_udev->udev, syspath); dev = udev_device_new_from_syspath(udev->context, syspath);
const char *devtype = udev_device_get_devtype(dev); const char *devtype = udev_device_get_devtype(dev);
if (!(strcmp(devtype, "usb_interface") == 0)) if (!(strcmp(devtype, "usb_interface") == 0))
@ -71,8 +79,7 @@ void mpl_udev_check_devices(MPL_UDEV *mpl_udev)
if (!(strcmp(driver, "option") == 0)) if (!(strcmp(driver, "option") == 0))
continue; continue;
const char *sysattr_value = udev_device_get_sysattr_value(dev, const char *sysattr_value = udev_device_get_sysattr_value(dev, "bInterfaceNumber");
"bInterfaceNumber");
printf("Номер порта: %s\n", sysattr_value); printf("Номер порта: %s\n", sysattr_value);
// int num = atoi(sysattr_value); // int num = atoi(sysattr_value);
@ -85,10 +92,98 @@ void mpl_udev_check_devices(MPL_UDEV *mpl_udev)
} }
udev_enumerate_unref(enumerate); udev_enumerate_unref(enumerate);
return 0;
} }
mpl_udev_free(MPL_UDEV *mpl_udev) void mpl_udev_free(MPL_UDEV *udev)
{ {
udev_monitor_unref(mpl_udev->monitor); if (udev->monitor)
udev_unref(mpl_udev->udev); {
udev_monitor_unref(udev->monitor);
udev->monitor = NULL;
}
if (udev->context)
{
udev_unref(udev->context);
udev->context = NULL;
}
}
void mpl_udev_loop(MPL_UDEV *udev, MPL_CANCELLABLE *cancellable)
{
const char *path_to_device = NULL;
int port_number = -1;
int status = -1;
pid_t pid = -1;
while (1)
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(udev->fd, &fds);
if (select(udev->fd + 1, &fds, NULL, NULL, NULL) <= 0)
{
if (cancellable->exit)
return;
MPLOG(LOG_ERR, "file selection error");
break;
}
struct udev_device *dev = udev_monitor_receive_device(udev->monitor);
if (dev)
{
const char *action = udev_device_get_property_value(dev, "ACTION");
if (!(strcmp(action, "bind") == 0))
{
udev_device_unref(dev);
continue;
}
const char *devtype = udev_device_get_devtype(dev);
if (!(strcmp(devtype, "usb_interface") == 0))
{
udev_device_unref(dev);
continue;
}
const char *driver = udev_device_get_driver(dev);
if (!(strcmp(driver, "option") == 0))
{
udev_device_unref(dev);
continue;
}
const char *sysattr_value = udev_device_get_sysattr_value(dev, "bInterfaceNumber");
if (sysattr_value == NULL)
{
udev_device_unref(dev);
continue;
}
port_number = atoi(sysattr_value);
path_to_device = udev_device_get_syspath(dev);
pid = fork();
if (pid == 0)
{
udev_device_unref(dev);
break;
}
else
wait(&status);
udev_device_unref(dev);
}
}
mpl_udev_free(udev);
if (cancellable->exit)
return;
sleep(5);
printf("exit");
} }

View File

@ -5,7 +5,22 @@
* Telegram @alexanderzhirov * Telegram @alexanderzhirov
*/ */
#ifndef MPL_UDEV_H_
#define MPL_UDEV_H_
#include <libudev.h>
#include "mpl-lib.h" #include "mpl-lib.h"
void mpl_udev_init(MPL_UDEV *mpl_udev); typedef struct
void mpl_udev_check_devices(MPL_UDEV *mpl_udev); {
struct udev *context;
struct udev_monitor *monitor;
int fd;
} MPL_UDEV;
int mpl_udev_init(MPL_UDEV *udev);
void mpl_udev_free(MPL_UDEV *udev);
int mpl_udev_check_devices(MPL_UDEV *udev);
void mpl_udev_loop(MPL_UDEV *udev, MPL_CANCELLABLE *cancellable);
#endif

View File

@ -5,25 +5,74 @@
* Telegram @alexanderzhirov * Telegram @alexanderzhirov
*/ */
#include <getopt.h>
#include "mpl.h" #include "mpl.h"
static MPL *mpl;
const char *const short_options = "hcv";
const struct option long_options[] = {
{"help", 0, NULL, 'h'},
{"check-devices", 0, NULL, 'c'},
{"version", 0, NULL, 'v'},
{NULL, 0, NULL, 0}};
[[noreturn]] void static print_usage_and_exit(int code)
{
printf("Usage: %s [OPTION]...\n\n", MPL_NAME);
puts(" -c, --check-devices checking connected devices at startup");
puts(" -h, --help display this help text and exit");
puts(" -v, --version display version information and exit\n");
exit(code);
}
[[noreturn]] void static print_version_and_exit()
{
printf("%s version %s\n", MPL_NAME, VERSION);
exit(0);
}
static void signals_handler(int signum) static void signals_handler(int signum)
{ {
MPLOG(LOG_WARNING, "cancelling the main loop (%d)", signum); MPLOG(LOG_WARNING, "cancelling the mportlink loop (%d)", signum);
mpl->cancellable.signal = signum;
mpl->cancellable.exit = 1;
} }
int main() int main(int argc, char *argv[])
{ {
int lock_fd = mpl_init(); int c;
MPL_UDEV *mpl = mpl_new(); MPL_PARAMETERS parameters =
mpl_udev_init(mpl); {
.check_device = 0
};
while ((c = getopt_long(argc, argv, short_options, long_options, NULL)) != -1)
switch (c)
{
case 'c':
parameters.check_device = 1;
break;
case 'v':
print_version_and_exit();
case 'h':
print_usage_and_exit(0);
case '?':
print_usage_and_exit(1);
}
mpl = mpl_init(&parameters);
signal(SIGINT, signals_handler);
signal(SIGHUP, signals_handler); signal(SIGHUP, signals_handler);
signal(SIGINT, signals_handler);
signal(SIGTERM, signals_handler); signal(SIGTERM, signals_handler);
mpl_stop(lock_fd); mpl_loop(mpl);
return EXIT_SUCCESS; mpl_stop(mpl);
return 0;
} }

View File

@ -8,8 +8,11 @@
#ifndef MPL_H_ #ifndef MPL_H_
#define MPL_H_ #define MPL_H_
#ifndef VERSION
#define VERSION "unrelease"
#endif
#include "mpl-lib.h" #include "mpl-lib.h"
#include "mpl-core.h" #include "mpl-core.h"
#include "mpl-udev.h"
#endif #endif