113 lines
2.3 KiB
C
113 lines
2.3 KiB
C
/*
|
|
* mpl-core.c
|
|
*
|
|
* by Alexander Zhirov (alexander@zhirov.kz)
|
|
* Telegram @alexanderzhirov
|
|
*/
|
|
|
|
#include "mpl-core.h"
|
|
|
|
#include <sys/stat.h>
|
|
#include <sys/file.h>
|
|
#include <unistd.h>
|
|
|
|
#define LOCKFILE "/run/lock/mportlink.lock"
|
|
#define DEV_PATH "/dev/"
|
|
#define DONGLE_PATH (DEV_PATH "dongle/")
|
|
|
|
static int mpl_create_dongle_dir()
|
|
{
|
|
struct stat st;
|
|
|
|
if (stat(DONGLE_PATH, &st) == 0)
|
|
{
|
|
if (!S_ISDIR(st.st_mode))
|
|
{
|
|
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)
|
|
{
|
|
MPLOG(LOG_ERR, "unable to create a directory %s", DONGLE_PATH);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void static mpl_free(MPL *mpl)
|
|
{
|
|
if (mpl)
|
|
free(mpl);
|
|
}
|
|
|
|
MPL *mpl_init(MPL_PARAMETERS *parameters)
|
|
{
|
|
MPL *mpl = (MPL *)calloc(1, sizeof(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();
|
|
}
|
|
|
|
void mpl_loop(MPL *mpl)
|
|
{
|
|
if (mpl->parameters.check_device)
|
|
mpl_udev_check_devices(&mpl->udev);
|
|
|
|
mpl_udev_loop(&mpl->udev, &mpl->cancellable);
|
|
}
|