This repository has been archived on 2024-06-12. You can view files and clone it, but cannot push or open issues or pull requests.
MPortLink/src/mpl-core.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);
}