/* * mpl-core.c * * by Alexander Zhirov (alexander@zhirov.kz) * Telegram @alexanderzhirov */ #include "mpl-core.h" #include #include #include #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); }