Subversion Repositories public

Rev

Rev 77 | 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
 *
100 luk 8
 * Copyright (C) 2006, 2007, 2008 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
 
75 luk 106
  /// Rebuilds the poll array data.
107
  void Rebuild();
67 luk 108
 
75 luk 109
  /// Removes all registered user tables.
110
  /**
111
   * It doesn't cause poll data rebuilding.
112
   */
113
  inline void Clear()
114
  {
115
    m_maps.clear();
116
  }
117
 
45 luk 118
private:
67 luk 119
  int m_iPipeFd;    ///< pipe file descriptor
120
  int m_iMgmtFd;    ///< table management file descriptor
121
  Inotify* m_pIn;   ///< table management inotify object 
122
  InotifyWatch* m_pSys;   ///< watch for system tables
123
  InotifyWatch* m_pUser;  ///< watch for user tables 
124
  FDUT_MAP m_maps;  ///< watch-to-usertable mapping
125
  size_t m_size;    ///< poll data size
126
  struct pollfd* m_pPoll; ///< poll data array
45 luk 127
 
67 luk 128
  /// Processes events on the table management inotify object. 
129
  void ProcessMgmtEvents();
45 luk 130
};
131
 
132
 
47 luk 133
/// User table class.
134
/**
135
 * This class processes inotify events for an user. It creates
136
 * child processes which do appropriate actions as defined
137
 * in the user table file.
138
 */
45 luk 139
class UserTable
140
{
141
public:
47 luk 142
  /// Constructor.
143
  /**
144
   * \param[in] pEd event dispatcher
145
   * \param[in] rUser user name
67 luk 146
   * \param[in] fSysTable system table yes/no
47 luk 147
   */
67 luk 148
        UserTable(EventDispatcher* pEd, const std::string& rUser, bool fSysTable);
47 luk 149
 
150
  /// Destructor.
45 luk 151
        virtual ~UserTable();
152
 
47 luk 153
  /// Loads the table.
154
  /**
155
   * All loaded entries have their inotify watches and are
156
   * registered for event dispatching.
157
   * If loading fails the table remains empty.
158
   */
45 luk 159
  void Load();
160
 
47 luk 161
  /// Removes all entries from the table.
162
  /**
163
   * All entries are unregistered from the event dispatcher and
164
   * their watches are destroyed.
165
   */
45 luk 166
  void Dispose();
167
 
47 luk 168
  /// Processes an inotify event.
169
  /**
170
   * \param[in] rEvt inotify event
171
   */
45 luk 172
  void OnEvent(InotifyEvent& rEvt);
47 luk 173
 
174
  /// Cleans-up all zombie child processes and enables disabled watches.
175
  /**
176
   * \attention This method must be called AFTER processing all events
177
   *            which has been caused by the processes.
178
   */
179
  static void FinishDone();
65 luk 180
 
181
  /// Checks whether the user may access a file.
182
  /**
183
   * Any access right (RWX) is sufficient.
184
   *
185
   * \param[in] rPath absolute file path
186
   * \param[in] fNoFollow don't follow a symbolic link
187
   * \return true = access granted, false = otherwise
188
   */
189
  bool MayAccess(const std::string& rPath, bool fNoFollow) const;
190
 
67 luk 191
  /// Checks whether it is a system table.
192
  /**
193
   * \return true = system table, false = user table
194
   */
195
  bool IsSystem() const;
196
 
197
  /// Returns the related inotify object.
198
  /**
199
   * \return related inotify object
200
   */
201
  Inotify* GetInotify()
202
  {
203
    return &m_in;
204
  }
205
 
206
  /// Checks whether an user exists and has permission to use incron.
207
  /**
208
   * It searches for the given user name in the user database.
209
   * If it failes it returns 'false'. Otherwise it checks
210
   * permission files for this user (see InCronTab::CheckUser()).
211
   *
212
   * \param[in] user user name
213
   * \return true = user has permission to use incron, false = otherwise
214
   *
215
   * \sa InCronTab::CheckUser()
216
   */
217
  inline static bool CheckUser(const char* user)
218
  {
219
    struct passwd* pw = getpwnam(user);
220
    if (pw == NULL)
221
      return false;
222
 
69 luk 223
    return IncronTab::CheckUser(user);
67 luk 224
  }
225
 
77 luk 226
  /// Runs a program as the table's user.
227
  /**
228
   * \attention Don't call from the main process (before forking)!
229
   */
230
  void RunAsUser(char* const* argv) const;
231
 
45 luk 232
private:
67 luk 233
  Inotify m_in;           ///< inotify object
47 luk 234
  EventDispatcher* m_pEd; ///< event dispatcher
235
  std::string m_user;     ///< user name
67 luk 236
  bool m_fSysTable;       ///< system table yes/no
69 luk 237
  IncronTab m_tab;        ///< incron table
47 luk 238
  IWCE_MAP m_map;         ///< watch-to-entry mapping
239
 
69 luk 240
  static PROC_MAP s_procMap;  ///< child process mapping
45 luk 241
 
47 luk 242
  /// Finds an entry for a watch.
243
  /**
244
   * \param[in] pWatch inotify watch
245
   * \return pointer to the appropriate entry; NULL if no such entry exists
246
   */
69 luk 247
  IncronTabEntry* FindEntry(InotifyWatch* pWatch);
45 luk 248
 
47 luk 249
  /// Prepares arguments for creating a child process.
250
  /**
251
   * \param[in] rCmd command string
252
   * \param[out] argc argument count
253
   * \param[out] argv argument array
254
   * \return true = success, false = failure
255
   */
45 luk 256
  bool PrepareArgs(const std::string& rCmd, int& argc, char**& argv);
47 luk 257
 
51 luk 258
  /// Frees memory allocated for arguments.
259
  /**
260
   * \param[in] argc argument count
261
   * \param[in] argv argument array
262
   */
263
  void CleanupArgs(int argc, char** argv);
264
 
45 luk 265
};
266
 
267
#endif //_USERTABLE_H_