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 |