Subversion Repositories public

Rev

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