Subversion Repositories public

Compare Revisions

Ignore whitespace Rev 61 → Rev 63

/incron/trunk/incrontab.5
1,4 → 1,4
.TH "incrontab" "5" "0.3.3" "Lukas Jelinek" "incron documentation"
.TH "incrontab" "5" "0.3.4" "Lukas Jelinek" "incron documentation"
.SH "NAME"
incrontab \- tables for driving inotify cron (incron)
.SH "DESCRIPTION"
/incron/trunk/ict-main.cpp
5,7 → 5,7
*
* inotify cron system
*
* Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz>
* Copyright (C) 2006, 2007 Lukas Jelinek, <lukas@aiken.cz>
*
* This program is free software; you can use it, redistribute
* it and/or modify it under the terms of the GNU General Public
33,7 → 33,7
const char* argp_program_version = INCRON_TAB_NAME " " INCRON_VERSION;
const char* argp_program_bug_address = INCRON_BUG_ADDRESS;
 
static char doc[] = "incrontab - incron table manipulator";
static char doc[] = "incrontab - incron table manipulator\n(c) Lukas Jelinek, 2006, 2007";
 
static char args_doc[] = "FILE";
 
203,7 → 203,7
uid_t iu = geteuid();
uid_t ig = getegid();
 
if (seteuid(uid) != 0 || setegid(gid) != 0) {
if (setegid(gid) != 0 || seteuid(uid) != 0) {
fprintf(stderr, "cannot change effective UID/GID for user %s: %s\n", user, strerror(errno));
return false;
}
220,13 → 220,7
time_t mt = (time_t) 0;
const char* e = NULL;
if (fchmod(fd, 0644) != 0) {
fprintf(stderr, "cannot change mode of temporary file: %s\n", strerror(errno));
close(fd);
goto end;
}
if (seteuid(iu) != 0 || setegid(ig) != 0) {
if (setegid(ig) != 0 || seteuid(iu) != 0) {
fprintf(stderr, "cannot change effective UID/GID: %s\n", strerror(errno));
close(fd);
goto end;
278,7 → 272,7
{
pid_t pid = fork();
if (pid == 0) {
if (setuid(uid) != 0 || setgid(gid) != 0) {
if (setgid(gid) != 0 || setuid(uid) != 0) {
fprintf(stderr, "cannot set user %s: %s\n", user, strerror(errno));
goto end;
}
316,10 → 310,16
{
InCronTab ict;
if (!ict.Load(s) || !ict.Save(tp)) {
if (ict.Load(s) && ict.Save(tp)) {
if (chmod(tp.c_str(), S_IRUSR | S_IWUSR) != 0) {
fprintf(stderr, "cannot change mode of temporary file: %s\n", strerror(errno));
}
}
else {
fprintf(stderr, "cannot move temporary table: %s\n", strerror(errno));
goto end;
}
}
ok = true;
/incron/trunk/CHANGELOG
1,3 → 1,9
0.3.4 2007-01-03
* based on inotify-cxx 0.6.2
* problems with wrong ordered setting of UID/GID fixed (#0000115, #0000117)
* user tables have 0600 permission now
 
 
0.3.3 2006-12-15
* based on inotify-cxx 0.5.3
* "GID ignorance" bug fixed (#0000109)
/incron/trunk/LICENSE-X11
1,4 → 1,4
Copyright (c) 2006 Lukas Jelinek
Copyright (c) 2006,2007 Lukas Jelinek
 
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
/incron/trunk/README
1,7 → 1,7
 
inotify cron system
 
(c) Lukas Jelinek, 2006
(c) Lukas Jelinek, 2006, 2007
 
1. About
2. Requirements
/incron/trunk/incrontab.cpp
5,7 → 5,7
*
* inotify cron system
*
* Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz>
* Copyright (C) 2006, 2007 Lukas Jelinek, <lukas@aiken.cz>
*
* This program is free software; you can use it, redistribute
* it and/or modify it under the terms of the GNU General Public
/incron/trunk/incrond.8
1,4 → 1,4
.TH "incrond" "8" "0.3.3" "Lukas Jelinek" "incron documentation"
.TH "incrond" "8" "0.3.4" "Lukas Jelinek" "incron documentation"
.SH "NAME"
incrond \- inotify cron (incron) daemon
 
/incron/trunk/icd-main.cpp
5,7 → 5,7
*
* inotify cron system
*
* Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz>
* Copyright (C) 2006, 2007 Lukas Jelinek, <lukas@aiken.cz>
*
* This program is free software; you can use it, redistribute
* it and/or modify it under the terms of the GNU General Public
/incron/trunk/inotify-cxx.cpp
5,7 → 5,7
*
* inotify C++ interface
*
* Copyright (C) 2006 Lukas Jelinek <lukas@aiken.cz>
* Copyright (C) 2006, 2007 Lukas Jelinek <lukas@aiken.cz>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of one of the following licenses:
26,6 → 26,9
 
#include "inotify-cxx.h"
 
/// procfs inotify base path
#define PROCFS_INOTIFY_BASE "/proc/sys/fs/inotify/"
 
/// dump separator (between particular entries)
#define DUMP_SEP \
({ \
93,6 → 96,11
else if (rName == "IN_ONLYDIR")
return IN_ONLYDIR;
#endif // IN_ONLYDIR
 
#ifdef IN_MOVE_SELF
else if (rName == "IN_MOVE_SELF")
return IN_MOVE_SELF;
#endif // IN_MOVE_SELF
return (uint32_t) 0;
}
137,6 → 145,14
DUMP_SEP;
rStr.append("IN_CLOSE");
}
 
#ifdef IN_MOVE_SELF
if (IsType(uValue, IN_MOVE_SELF)) {
DUMP_SEP;
rStr.append("IN_MOVE_SELF");
}
#endif // IN_MOVE_SELF
else {
if (IsType(uValue, IN_CLOSE_WRITE)) {
DUMP_SEP;
254,7 → 270,26
IN_WRITE_END
}
 
void InotifyWatch::OnOneshotEvent()
{
IN_WRITE_BEGIN
if (!m_fEnabled) {
IN_WRITE_END_NOTHROW
throw InotifyException(IN_EXC_MSG("event cannot occur on disabled watch"), EINVAL, this);
}
if (m_pInotify != NULL) {
m_pInotify->m_watches.erase(m_wd);
m_wd = -1;
}
m_fEnabled = false;
IN_WRITE_END
}
 
 
Inotify::Inotify() throw (InotifyException)
{
IN_LOCK_INIT
411,6 → 446,8
InotifyWatch* pW = FindWatch(pEvt->wd);
if (pW != NULL) {
InotifyEvent evt(pEvt, pW);
if (InotifyEvent::IsType(pW->GetMask(), IN_ONESHOT))
pW->OnOneshotEvent();
m_events.push_back(evt);
}
i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
506,5 → 543,57
}
IN_WRITE_END
}
}
 
uint32_t Inotify::GetCapability(InotifyCapability_t cap) throw (InotifyException)
{
FILE* f = fopen(GetCapabilityPath(cap).c_str(), "r");
if (f == NULL)
throw InotifyException(IN_EXC_MSG("cannot get capability"), errno, NULL);
unsigned int val = 0;
if (fscanf(f, "%u", &val) != 1) {
fclose(f);
throw InotifyException(IN_EXC_MSG("cannot get capability"), EIO, NULL);
}
fclose(f);
return (uint32_t) val;
}
 
void Inotify::SetCapability(InotifyCapability_t cap, uint32_t val) throw (InotifyException)
{
FILE* f = fopen(GetCapabilityPath(cap).c_str(), "w");
if (f == NULL)
throw InotifyException(IN_EXC_MSG("cannot set capability"), errno, NULL);
if (fprintf(f, "%u", (unsigned int) val) <= 0) {
fclose(f);
throw InotifyException(IN_EXC_MSG("cannot set capability"), EIO, NULL);
}
fclose(f);
}
 
std::string Inotify::GetCapabilityPath(InotifyCapability_t cap) throw (InotifyException)
{
std::string path(PROCFS_INOTIFY_BASE);
switch (cap) {
case IN_MAX_EVENTS:
path.append("max_queued_events");
break;
case IN_MAX_INSTANCES:
path.append("max_user_instances");
break;
case IN_MAX_WATCHES:
path.append("max_user_watches");
break;
default:
throw InotifyException(IN_EXC_MSG("unknown capability type"), EINVAL, NULL);
}
return path;
}
 
/incron/trunk/incrontab.h
5,7 → 5,7
*
* inotify cron system
*
* Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz>
* Copyright (C) 2006, 2007 Lukas Jelinek, <lukas@aiken.cz>
*
* This program is free software; you can use it, redistribute
* it and/or modify it under the terms of the GNU General Public
/incron/trunk/TODO
1,3 → 1,3
Currently pending tasks:
 
*** nothing to do ***
* recursive monitoring (whole subtrees)
/incron/trunk/inotify-cxx.h
5,7 → 5,7
*
* inotify C++ interface
*
* Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz>
* Copyright (C) 2006, 2007 Lukas Jelinek, <lukas@aiken.cz>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of one of the following licenses:
51,6 → 51,14
*/
#define IN_EXC_MSG(msg) (std::string(__PRETTY_FUNCTION__) + ": " + msg)
 
/// inotify capability/limit identifiers
typedef enum
{
IN_MAX_EVENTS = 0, ///< max. events in the kernel queue
IN_MAX_INSTANCES = 1, ///< max. inotify file descriptors per process
IN_MAX_WATCHES = 2 ///< max. watches per file descriptor
} InotifyCapability_t;
 
/// inotify-cxx thread safety
/**
* If this symbol is defined you can use this interface safely
469,6 → 477,21
return m_fEnabled;
}
/// Checks whether the watch is recursive.
/**
* A recursive watch monitors a directory itself and all
* its subdirectories. This watch is a logical object
* which may have many underlying kernel watches.
*
* \return currently always false (recursive watches not yet supported)
* \attention Recursive watches are currently NOT supported.
* They are planned for future versions.
*/
inline bool IsRecursive() const
{
return false;
}
private:
friend class Inotify;
 
479,6 → 502,14
bool m_fEnabled; ///< events enabled yes/no
IN_LOCK_DECL
/// Disables the watch (if it has the one-shot flag).
/**
* This method must be called after receiving an event.
* It ensures the watch object is consistent with the kernel
* data.
*/
void OnOneshotEvent();
};
 
 
719,6 → 750,103
* \sa GetDescriptor()
*/
void SetNonBlock(bool fNonBlock) throw (InotifyException);
/// Acquires a particular inotify capability/limit.
/**
* \param[in] cap capability/limit identifier
* \return capability/limit value
* \throw InotifyException thrown if the given value cannot be acquired
*/
static uint32_t GetCapability(InotifyCapability_t cap) throw (InotifyException);
/// Modifies a particular inotify capability/limit.
/**
* \param[in] cap capability/limit identifier
* \param[in] val new capability/limit value
* \throw InotifyException thrown if the given value cannot be set
* \attention Using this function requires root privileges.
* Beware of setting extensive values - it may seriously
* affect system performance and/or stability.
*/
static void SetCapability(InotifyCapability_t cap, uint32_t val) throw (InotifyException);
/// Returns the maximum number of events in the kernel queue.
/**
* \return maximum number of events in the kernel queue
* \throw InotifyException thrown if the given value cannot be acquired
*/
inline static uint32_t GetMaxEvents() throw (InotifyException)
{
return GetCapability(IN_MAX_EVENTS);
}
/// Sets the maximum number of events in the kernel queue.
/**
* \param[in] val new value
* \throw InotifyException thrown if the given value cannot be set
* \attention Using this function requires root privileges.
* Beware of setting extensive values - the greater value
* is set here the more physical memory may be used for the inotify
* infrastructure.
*/
inline static void SetMaxEvents(uint32_t val) throw (InotifyException)
{
SetCapability(IN_MAX_EVENTS, val);
}
/// Returns the maximum number of inotify instances per process.
/**
* It means the maximum number of open inotify file descriptors
* per running process.
*
* \return maximum number of inotify instances
* \throw InotifyException thrown if the given value cannot be acquired
*/
inline static uint32_t GetMaxInstances() throw (InotifyException)
{
return GetCapability(IN_MAX_INSTANCES);
}
/// Sets the maximum number of inotify instances per process.
/**
* \param[in] val new value
* \throw InotifyException thrown if the given value cannot be set
* \attention Using this function requires root privileges.
* Beware of setting extensive values - the greater value
* is set here the more physical memory may be used for the inotify
* infrastructure.
*/
inline static void SetMaxInstances(uint32_t val) throw (InotifyException)
{
SetCapability(IN_MAX_INSTANCES, val);
}
/// Returns the maximum number of inotify watches per instance.
/**
* It means the maximum number of inotify watches per inotify
* file descriptor.
*
* \return maximum number of inotify watches
* \throw InotifyException thrown if the given value cannot be acquired
*/
inline static uint32_t GetMaxWatches() throw (InotifyException)
{
return GetCapability(IN_MAX_WATCHES);
}
/// Sets the maximum number of inotify watches per instance.
/**
* \param[in] val new value
* \throw InotifyException thrown if the given value cannot be set
* \attention Using this function requires root privileges.
* Beware of setting extensive values - the greater value
* is set here the more physical memory may be used for the inotify
* infrastructure.
*/
inline static void SetMaxWatches(uint32_t val) throw (InotifyException)
{
SetCapability(IN_MAX_WATCHES, val);
}
 
private:
int m_fd; ///< file descriptor
730,6 → 858,8
IN_LOCK_DECL
friend class InotifyWatch;
static std::string GetCapabilityPath(InotifyCapability_t cap) throw (InotifyException);
};
 
 
/incron/trunk/usertable.cpp
5,7 → 5,7
*
* inotify cron system
*
* Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz>
* Copyright (C) 2006, 2007 Lukas Jelinek, <lukas@aiken.cz>
*
* This program is free software; you can use it, redistribute
* it and/or modify it under the terms of the GNU General Public
210,10 → 210,11
struct passwd* pwd = getpwnam(m_user.c_str());
if ( pwd == NULL // user not found
|| setgid(pwd->pw_gid) != 0 // setting GID failed
|| setuid(pwd->pw_uid) != 0 // setting UID failed
|| setgid(pwd->pw_gid) != 0 // setting GID failed
|| execvp(argv[0], argv) != 0) // exec failed
{
syslog(LOG_ERR, "cannot exec process: %s", strerror(errno));
_exit(1);
}
}
/incron/trunk/COPYING
1,6 → 1,6
inotify cron system
Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz>
Copyright (C) 2006,2007 Lukas Jelinek, <lukas@aiken.cz>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License,
/incron/trunk/usertable.h
5,7 → 5,7
*
* inotify cron system
*
* Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz>
* Copyright (C) 2006, 2007 Lukas Jelinek, <lukas@aiken.cz>
*
* This program is free software; you can use it, redistribute
* it and/or modify it under the terms of the GNU General Public
/incron/trunk/incrontab.1
1,4 → 1,4
.TH "incrontab" "1" "0.3.3" "Lukas Jelinek" "incron documentation"
.TH "incrontab" "1" "0.3.4" "Lukas Jelinek" "incron documentation"
.SH "NAME"
incrontab \- table manipulator for inotify cron (incron)
.SH "SYNOPSIS"
/incron/trunk/incron.h
5,7 → 5,7
*
* inotify cron system
*
* Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz>
* Copyright (C) 2006, 2007 Lukas Jelinek, <lukas@aiken.cz>
*
* This program is free software; you can use it, redistribute
* it and/or modify it under the terms of the GNU General Public
27,7 → 27,7
#define INCRON_TAB_NAME "incrontab"
 
/// Application version (release)
#define INCRON_VERSION "0.3.3"
#define INCRON_VERSION "0.3.4"
 
/// Address for sending bugs
#define INCRON_BUG_ADDRESS "<bugs@aiken.cz>"