Subversion Repositories public

Rev

Rev 67 | Rev 75 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
45 luk 1
 
2
/// inotify cron daemon user tables header
3
/**
4
 * \file usertable.h
5
 *
6
 * inotify cron system
7
 *
63 luk 8
 * Copyright (C) 2006, 2007 Lukas Jelinek, <lukas@aiken.cz>
45 luk 9
 *
10
 * This program is free software; you can use it, redistribute
11
 * it and/or modify it under the terms of the GNU General Public
12
 * License, version 2 (see LICENSE-GPL).
13
 *  
14
 */
15
 
16
#ifndef _USERTABLE_H_
17
#define _USERTABLE_H_
18
 
19
#include <map>
47 luk 20
#include <deque>
67 luk 21
#include <sys/poll.h>
45 luk 22
 
23
#include "inotify-cxx.h"
24
#include "incrontab.h"
25
 
26
 
27
class UserTable;
28
 
67 luk 29
/// User name to user table mapping definition
30
typedef std::map<std::string, UserTable*> SUT_MAP;
31
 
47 luk 32
/// Callback for calling after a process finishes.
33
typedef void (*proc_done_cb)(InotifyWatch*);
45 luk 34
 
47 luk 35
/// Child process data
36
typedef struct
37
{
38
  proc_done_cb onDone;  ///< function called after process finishes
39
  InotifyWatch* pWatch; ///< related watch
40
} ProcData_t;
41
 
67 luk 42
/// fd-to-usertable mapping
43
typedef std::map<int, UserTable*> FDUT_MAP;
47 luk 44
 
45
/// Watch-to-tableentry mapping
69 luk 46
typedef std::map<InotifyWatch*, IncronTabEntry*> IWCE_MAP;
45 luk 47
 
47 luk 48
/// Child process list
69 luk 49
typedef std::map<pid_t, ProcData_t> PROC_MAP;
47 luk 50
 
51
/// Event dispatcher class.
52
/**
67 luk 53
 * This class processes events and distributes them as needed.
47 luk 54
 */
45 luk 55
class EventDispatcher
56
{
57
public:
47 luk 58
  /// Constructor.
59
  /**
67 luk 60
   * \param[in] iPipeFd pipe descriptor
61
   * \param[in] pIn inotify object for table management
62
   * \param[in] pSys watch for system tables
63
   * \param[in] pUser watch for user tables
47 luk 64
   */
67 luk 65
  EventDispatcher(int iPipeFd, Inotify* pIn, InotifyWatch* pSys, InotifyWatch* pUser);
45 luk 66
 
47 luk 67
  /// Destructor.
67 luk 68
  ~EventDispatcher();
45 luk 69
 
67 luk 70
  /// Processes events.
47 luk 71
  /**
67 luk 72
   * \return pipe event occurred yes/no
47 luk 73
   */
67 luk 74
  bool ProcessEvents();
45 luk 75
 
67 luk 76
  /// Registers an user table.
47 luk 77
  /**
78
   * \param[in] pTab user table
79
   */
67 luk 80
  void Register(UserTable* pTab);
45 luk 81
 
67 luk 82
  /// Unregisters an user table.
47 luk 83
  /**
67 luk 84
   * \param[in] pTab user table
47 luk 85
   */
67 luk 86
  void Unregister(UserTable* pTab);
45 luk 87
 
67 luk 88
  /// Returns the poll data size.
47 luk 89
  /**
67 luk 90
   * \return poll data size
47 luk 91
   */
67 luk 92
  inline size_t GetSize() const
93
  {
94
    return m_size;
95
  }
45 luk 96
 
67 luk 97
  /// Returns the poll data.
98
  /**
99
   * \return poll data
100
   */
101
  inline struct pollfd* GetPollData()
102
  {
103
    return m_pPoll;
104
  }
105
 
106
 
45 luk 107
private:
67 luk 108
  int m_iPipeFd;    ///< pipe file descriptor
109
  int m_iMgmtFd;    ///< table management file descriptor
110
  Inotify* m_pIn;   ///< table management inotify object 
111
  InotifyWatch* m_pSys;   ///< watch for system tables
112
  InotifyWatch* m_pUser;  ///< watch for user tables 
113
  FDUT_MAP m_maps;  ///< watch-to-usertable mapping
114
  size_t m_size;    ///< poll data size
115
  struct pollfd* m_pPoll; ///< poll data array
45 luk 116
 
67 luk 117
  /// Rebuilds the poll array data.
118
  void Rebuild();
119
 
120
  /// Processes events on the table management inotify object. 
121
  void ProcessMgmtEvents();
45 luk 122
};
123
 
124
 
47 luk 125
/// User table class.
126
/**
127
 * This class processes inotify events for an user. It creates
128
 * child processes which do appropriate actions as defined
129
 * in the user table file.
130
 */
45 luk 131
class UserTable
132
{
133
public:
47 luk 134
  /// Constructor.
135
  /**
136
   * \param[in] pEd event dispatcher
137
   * \param[in] rUser user name
67 luk 138
   * \param[in] fSysTable system table yes/no
47 luk 139
   */
67 luk 140
        UserTable(EventDispatcher* pEd, const std::string& rUser, bool fSysTable);
47 luk 141
 
142
  /// Destructor.
45 luk 143
        virtual ~UserTable();
144
 
47 luk 145
  /// Loads the table.
146
  /**
147
   * All loaded entries have their inotify watches and are
148
   * registered for event dispatching.
149
   * If loading fails the table remains empty.
150
   */
45 luk 151
  void Load();
152
 
47 luk 153
  /// Removes all entries from the table.
154
  /**
155
   * All entries are unregistered from the event dispatcher and
156
   * their watches are destroyed.
157
   */
45 luk 158
  void Dispose();
159
 
47 luk 160
  /// Processes an inotify event.
161
  /**
162
   * \param[in] rEvt inotify event
163
   */
45 luk 164
  void OnEvent(InotifyEvent& rEvt);
47 luk 165
 
166
  /// Cleans-up all zombie child processes and enables disabled watches.
167
  /**
168
   * \attention This method must be called AFTER processing all events
169
   *            which has been caused by the processes.
170
   */
171
  static void FinishDone();
65 luk 172
 
173
  /// Checks whether the user may access a file.
174
  /**
175
   * Any access right (RWX) is sufficient.
176
   *
177
   * \param[in] rPath absolute file path
178
   * \param[in] fNoFollow don't follow a symbolic link
179
   * \return true = access granted, false = otherwise
180
   */
181
  bool MayAccess(const std::string& rPath, bool fNoFollow) const;
182
 
67 luk 183
  /// Checks whether it is a system table.
184
  /**
185
   * \return true = system table, false = user table
186
   */
187
  bool IsSystem() const;
188
 
189
  /// Returns the related inotify object.
190
  /**
191
   * \return related inotify object
192
   */
193
  Inotify* GetInotify()
194
  {
195
    return &m_in;
196
  }
197
 
198
  /// Checks whether an user exists and has permission to use incron.
199
  /**
200
   * It searches for the given user name in the user database.
201
   * If it failes it returns 'false'. Otherwise it checks
202
   * permission files for this user (see InCronTab::CheckUser()).
203
   *
204
   * \param[in] user user name
205
   * \return true = user has permission to use incron, false = otherwise
206
   *
207
   * \sa InCronTab::CheckUser()
208
   */
209
  inline static bool CheckUser(const char* user)
210
  {
211
    struct passwd* pw = getpwnam(user);
212
    if (pw == NULL)
213
      return false;
214
 
69 luk 215
    return IncronTab::CheckUser(user);
67 luk 216
  }
217
 
45 luk 218
private:
67 luk 219
  Inotify m_in;           ///< inotify object
47 luk 220
  EventDispatcher* m_pEd; ///< event dispatcher
221
  std::string m_user;     ///< user name
67 luk 222
  bool m_fSysTable;       ///< system table yes/no
69 luk 223
  IncronTab m_tab;        ///< incron table
47 luk 224
  IWCE_MAP m_map;         ///< watch-to-entry mapping
225
 
69 luk 226
  static PROC_MAP s_procMap;  ///< child process mapping
45 luk 227
 
47 luk 228
  /// Finds an entry for a watch.
229
  /**
230
   * \param[in] pWatch inotify watch
231
   * \return pointer to the appropriate entry; NULL if no such entry exists
232
   */
69 luk 233
  IncronTabEntry* FindEntry(InotifyWatch* pWatch);
45 luk 234
 
47 luk 235
  /// Prepares arguments for creating a child process.
236
  /**
237
   * \param[in] rCmd command string
238
   * \param[out] argc argument count
239
   * \param[out] argv argument array
240
   * \return true = success, false = failure
241
   */
45 luk 242
  bool PrepareArgs(const std::string& rCmd, int& argc, char**& argv);
47 luk 243
 
51 luk 244
  /// Frees memory allocated for arguments.
245
  /**
246
   * \param[in] argc argument count
247
   * \param[in] argv argument array
248
   */
249
  void CleanupArgs(int argc, char** argv);
250
 
45 luk 251
};
252
 
253
#endif //_USERTABLE_H_