Subversion Repositories public

Rev

Rev 108 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
45 luk 1
 
2
/// inotify cron table manipulator classes implementation
3
/**
4
 * \file incrontab.cpp
5
 *
6
 * inotify cron system
7
 *
108 luk 8
 * Copyright (C) 2006, 2007, 2008, 2012 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
 *  
108 luk 14
 * Credits:
15
 *   Christian Ruppert (new include to build with GCC 4.4+)
16
 *
45 luk 17
 */
18
 
19
 
20
#include <sstream>
108 luk 21
#include <cstdio>
45 luk 22
#include <errno.h>
23
 
24
#include "inotify-cxx.h"
25
 
26
#include "incrontab.h"
69 luk 27
#include "incroncfg.h"
45 luk 28
 
69 luk 29
/*
47 luk 30
/// Allowed users
31
#define INCRON_ALLOW_PATH "/etc/incron.allow"
45 luk 32
 
47 luk 33
/// Denied users
45 luk 34
#define INCRON_DENY_PATH "/etc/incron.deny"
69 luk 35
*/
45 luk 36
 
57 luk 37
/*
38
 * ALLOW/DENY SEMANTICS
39
 *
40
 * If /etc/incron.allow exists ONLY users contained here
41
 * are allowed to use incron.
42
 *
43
 * Otherwise, if /etc/incron.deny exists only user NOT
44
 * contained here are allowed to use incron.
45
 *
46
 * Otherwise all users may use incron.
47
 *
48
 */
45 luk 49
 
50
 
51
 
69 luk 52
IncronTabEntry::IncronTabEntry()
47 luk 53
: m_uMask(0),
54
  m_fNoLoop(false)
45 luk 55
{
56
 
57
}
58
 
69 luk 59
IncronTabEntry::IncronTabEntry(const std::string& rPath, uint32_t uMask, const std::string& rCmd)
45 luk 60
: m_path(rPath),
61
  m_uMask(uMask),
62
  m_cmd(rCmd)
63
{
64
 
65
}
66
 
69 luk 67
std::string IncronTabEntry::ToString() const
45 luk 68
{
69
  std::ostringstream ss;
70
 
71
  std::string m;
72
 
73
  InotifyEvent::DumpTypes(m_uMask, m);
47 luk 74
  if (m.empty()) {
75
    m = m_fNoLoop ? "IN_NO_LOOP" : "0";
76
  }
77
  else {
78
    if (m_fNoLoop)
79
      m.append(",IN_NO_LOOP");
80
  }
45 luk 81
 
55 luk 82
  ss << GetSafePath(m_path) << " " << m << " " << m_cmd;
45 luk 83
  return ss.str();
84
}
85
 
69 luk 86
bool IncronTabEntry::Parse(const std::string& rStr, IncronTabEntry& rEntry)
45 luk 87
{
88
  unsigned long u;
55 luk 89
  std::string s1, s2, s3;
45 luk 90
 
55 luk 91
  StringTokenizer tok(rStr, ' ', '\\');
92
  if (!tok.HasMoreTokens())
45 luk 93
    return false;
55 luk 94
 
95
  s1 = tok.GetNextToken(true);
96
  if (!tok.HasMoreTokens())
97
    return false;
98
 
99
  s2 = tok.GetNextToken(true);
100
  if (!tok.HasMoreTokens())
101
    return false;
45 luk 102
 
55 luk 103
  tok.SetNoPrefix();
104
  s3 = tok.GetRemainder();
105
  SIZE len = s3.length();
106
  if (len > 0 && s3[len-1] == '\n')
107
    s3.resize(len-1);
108
 
45 luk 109
  rEntry.m_path = s1;
110
  rEntry.m_cmd = s3;
53 luk 111
  rEntry.m_uMask = 0;
112
  rEntry.m_fNoLoop = false;
45 luk 113
 
55 luk 114
  if (sscanf(s2.c_str(), "%lu", &u) == 1) {
45 luk 115
    rEntry.m_uMask = (uint32_t) u;
116
  }
117
  else {
118
    StringTokenizer tok(s2);
119
    while (tok.HasMoreTokens()) {
47 luk 120
      std::string s(tok.GetNextToken());
121
      if (s == "IN_NO_LOOP")
122
        rEntry.m_fNoLoop = true;
123
      else
124
        rEntry.m_uMask |= InotifyEvent::GetMaskByName(s);
45 luk 125
    }
126
  }
127
 
128
  return true;
129
}
130
 
69 luk 131
std::string IncronTabEntry::GetSafePath(const std::string& rPath)
55 luk 132
{
133
  std::ostringstream stream;
134
 
135
  SIZE len = rPath.length();
136
  for (SIZE i = 0; i < len; i++) {
137
    if (rPath[i] == ' ') {
138
      stream << "\\ ";
139
    }
140
    else if (rPath[i] == '\\') {
141
      stream << "\\\\";
142
    }
143
    else {
144
      stream << rPath[i];
145
    }
146
  }
147
 
148
  return stream.str();
149
}
150
 
69 luk 151
bool IncronTab::Load(const std::string& rPath)
45 luk 152
{
153
  m_tab.clear();
154
 
155
  FILE* f = fopen(rPath.c_str(), "r");
156
  if (f == NULL)
157
    return false;
158
 
159
  char s[1000];
69 luk 160
  IncronTabEntry e;
45 luk 161
  while (fgets(s, 1000, f) != NULL) {
69 luk 162
    if (IncronTabEntry::Parse(s, e)) {
45 luk 163
      m_tab.push_back(e);
164
    }
165
  }
166
 
167
  fclose(f);
168
 
169
  return true;
170
}
171
 
69 luk 172
bool IncronTab::Save(const std::string& rPath)
45 luk 173
{
174
  FILE* f = fopen(rPath.c_str(), "w");
175
  if (f == NULL)
176
    return false;
177
 
69 luk 178
  std::deque<IncronTabEntry>::iterator it = m_tab.begin();
45 luk 179
  while (it != m_tab.end()) {
180
    fputs((*it).ToString().c_str(), f);
181
    fputs("\n", f);
182
    it++;
183
  }
184
 
185
  fclose(f);
186
 
187
  return true;
188
}
189
 
69 luk 190
bool IncronTab::CheckUser(const std::string& rUser)
45 luk 191
{
192
  char s[100], u[100];
193
 
69 luk 194
  std::string path;
195
  if (!IncronCfg::GetValue("allowed_users", path))
196
    throw InotifyException("configuration is corrupted", EINVAL);
197
 
198
  FILE* f = fopen(path.c_str(), "r");
45 luk 199
  if (f == NULL) {
200
    if (errno == ENOENT) {
69 luk 201
      if (!IncronCfg::GetValue("denied_users", path))
202
        throw InotifyException("configuration is corrupted", EINVAL);
203
 
204
      f = fopen(path.c_str(), "r");
45 luk 205
      if (f == NULL) {
206
        return errno == ENOENT;
207
      }
208
      while (fgets(s, 100, f) != NULL) {
209
        if (sscanf(s, "%s", u) == 1) {
210
          if (rUser == u) {
211
            fclose(f);
212
            return false;
213
          }
214
        }
215
      }
216
      fclose(f);
217
      return true;
218
    }
219
 
220
    return false;
221
  }
222
 
223
  while (fgets(s, 100, f) != NULL) {
224
    if (sscanf(s, "%s", u) == 1) {
225
      if (rUser == u) {
226
        fclose(f);
227
        return true;
228
      }
229
    }
230
  }
231
 
232
  fclose(f);
233
  return false;
234
}
235
 
69 luk 236
std::string IncronTab::GetUserTablePath(const std::string& rUser)
45 luk 237
{
69 luk 238
  std::string s;
239
  if (!IncronCfg::GetValue("user_table_dir", s))
240
    throw InotifyException("configuration is corrupted", EINVAL);
241
 
242
  return IncronCfg::BuildPath(s, rUser);
45 luk 243
}
244
 
69 luk 245
std::string IncronTab::GetSystemTablePath(const std::string& rName)
67 luk 246
{
69 luk 247
  std::string s;
248
  if (!IncronCfg::GetValue("system_table_dir", s))
249
    throw InotifyException("configuration is corrupted", EINVAL);
250
 
251
  return IncronCfg::BuildPath(s, rName);
67 luk 252
}
55 luk 253
 
254
 
67 luk 255