|
Lines 1-4
Link Here
|
| 1 |
#!/usr/bin/python |
1 |
#!/usr/bin/python |
|
|
2 |
from __future__ import print_function |
| 2 |
'''queue_repair.py - qmail tools in Python. |
3 |
'''queue_repair.py - qmail tools in Python. |
| 3 |
Copyright (C) 2001 Charles Cazabon <pqt @ discworld.dyndns.org> |
4 |
Copyright (C) 2001 Charles Cazabon <pqt @ discworld.dyndns.org> |
| 4 |
|
5 |
|
|
Lines 66-89
Link Here
|
| 66 |
# key: pathname - all paths are relative to conf-qmail |
67 |
# key: pathname - all paths are relative to conf-qmail |
| 67 |
# data: (user, group, mode, split) |
68 |
# data: (user, group, mode, split) |
| 68 |
# split is: 0 : no, 1 : yes, -1 : only with big-todo |
69 |
# split is: 0 : no, 1 : yes, -1 : only with big-todo |
| 69 |
'queue' : ('qmailq', 'qmail', 0750, 0), |
70 |
'queue' : ('qmailq', 'qmail', 0o750, 0), |
| 70 |
'queue/bounce' : ('qmails', 'qmail', 0700, 0), |
71 |
'queue/bounce' : ('qmails', 'qmail', 0o700, 0), |
| 71 |
'queue/info' : ('qmails', 'qmail', 0700, 1), |
72 |
'queue/info' : ('qmails', 'qmail', 0o700, 1), |
| 72 |
'queue/intd' : ('qmailq', 'qmail', 0700, -1), |
73 |
'queue/intd' : ('qmailq', 'qmail', 0o700, -1), |
| 73 |
'queue/local' : ('qmails', 'qmail', 0700, 1), |
74 |
'queue/local' : ('qmails', 'qmail', 0o700, 1), |
| 74 |
'queue/lock' : ('qmailq', 'qmail', 0750, 0), |
75 |
'queue/lock' : ('qmailq', 'qmail', 0o750, 0), |
| 75 |
'queue/mess' : ('qmailq', 'qmail', 0750, 1), |
76 |
'queue/mess' : ('qmailq', 'qmail', 0o750, 1), |
| 76 |
'queue/pid' : ('qmailq', 'qmail', 0700, 0), |
77 |
'queue/pid' : ('qmailq', 'qmail', 0o700, 0), |
| 77 |
'queue/remote' : ('qmails', 'qmail', 0700, 1), |
78 |
'queue/remote' : ('qmails', 'qmail', 0o700, 1), |
| 78 |
'queue/todo' : ('qmailq', 'qmail', 0750, -1), |
79 |
'queue/todo' : ('qmailq', 'qmail', 0o750, -1), |
| 79 |
} |
80 |
} |
| 80 |
|
81 |
|
| 81 |
nondirs = { |
82 |
nondirs = { |
| 82 |
# Files to check; format is: |
83 |
# Files to check; format is: |
| 83 |
# key: pathname - all paths are relative to conf-qmail |
84 |
# key: pathname - all paths are relative to conf-qmail |
| 84 |
# data: (user, group, mode) |
85 |
# data: (user, group, mode) |
| 85 |
'queue/lock/sendmutex' : ('qmails', 'qmail', 0600), |
86 |
'queue/lock/sendmutex' : ('qmails', 'qmail', 0o600), |
| 86 |
'queue/lock/tcpto' : ('qmailr', 'qmail', 0644), |
87 |
'queue/lock/tcpto' : ('qmailr', 'qmail', 0o644), |
| 87 |
} |
88 |
} |
| 88 |
|
89 |
|
| 89 |
|
90 |
|
|
Lines 105-111
Link Here
|
| 105 |
while i <= max: |
106 |
while i <= max: |
| 106 |
for p in primelist: |
107 |
for p in primelist: |
| 107 |
if (i % p == 0) or (p * p > i): break |
108 |
if (i % p == 0) or (p * p > i): break |
| 108 |
if (i % p <> 0): |
109 |
if (i % p != 0): |
| 109 |
primelist.append(i) |
110 |
primelist.append(i) |
| 110 |
if i >= min: |
111 |
if i >= min: |
| 111 |
result.append(i) |
112 |
result.append(i) |
|
Lines 151-159
Link Here
|
| 151 |
''' |
152 |
''' |
| 152 |
global users, groups |
153 |
global users, groups |
| 153 |
msg('finding qmail UIDs/GIDs...') |
154 |
msg('finding qmail UIDs/GIDs...') |
| 154 |
us = users.keys() |
155 |
for u in users: |
| 155 |
gs = groups.keys() |
|
|
| 156 |
for u in us: |
| 157 |
if users[u]: |
156 |
if users[u]: |
| 158 |
# Handle case of someone else determining UIDs for us |
157 |
# Handle case of someone else determining UIDs for us |
| 159 |
msg(' %-7s preset as UID %i' % (u, users[u])) |
158 |
msg(' %-7s preset as UID %i' % (u, users[u])) |
|
Lines 163-169
Link Here
|
| 163 |
except KeyError: |
162 |
except KeyError: |
| 164 |
err('no uid for %s' % u) |
163 |
err('no uid for %s' % u) |
| 165 |
msg(' %-7s : UID %i' % (u, users[u])) |
164 |
msg(' %-7s : UID %i' % (u, users[u])) |
| 166 |
for g in gs: |
165 |
for g in groups: |
| 167 |
if groups[g]: |
166 |
if groups[g]: |
| 168 |
# Handle case of someone else determining GIDs for us |
167 |
# Handle case of someone else determining GIDs for us |
| 169 |
msg(' %-7s preset as GID %i' % (g, groups[g])) |
168 |
msg(' %-7s preset as GID %i' % (g, groups[g])) |
|
Lines 182-188
Link Here
|
| 182 |
that it has octal mode mode. If testmode is set, create path if it |
181 |
that it has octal mode mode. If testmode is set, create path if it |
| 183 |
doesn't exist. |
182 |
doesn't exist. |
| 184 |
''' |
183 |
''' |
| 185 |
if checked_dir.has_key(path): |
184 |
if path in checked_dir: |
| 186 |
return |
185 |
return |
| 187 |
msg(' checking directory %s...' % path) |
186 |
msg(' checking directory %s...' % path) |
| 188 |
if not os.path.exists(path): |
187 |
if not os.path.exists(path): |
|
Lines 208-214
Link Here
|
| 208 |
|
207 |
|
| 209 |
Verify path is owned by user:group, and make it so if testmode is not set. |
208 |
Verify path is owned by user:group, and make it so if testmode is not set. |
| 210 |
''' |
209 |
''' |
| 211 |
if checked_owner.has_key(path): |
210 |
if path in checked_owner: |
| 212 |
return |
211 |
return |
| 213 |
uid = users[user] |
212 |
uid = users[user] |
| 214 |
gid = groups[group] |
213 |
gid = groups[group] |
|
Lines 223-229
Link Here
|
| 223 |
msg(' fixed, %s ownership %i:%i' % (path, s[ST_UID], s[ST_GID])) |
222 |
msg(' fixed, %s ownership %i:%i' % (path, s[ST_UID], s[ST_GID])) |
| 224 |
else: |
223 |
else: |
| 225 |
msg(' testmode, not fixing') |
224 |
msg(' testmode, not fixing') |
| 226 |
except OSError, o: |
225 |
except OSError as o: |
| 227 |
err(o or '[no error message]') |
226 |
err(o or '[no error message]') |
| 228 |
checked_owner[path] = None |
227 |
checked_owner[path] = None |
| 229 |
|
228 |
|
|
Lines 233-239
Link Here
|
| 233 |
|
232 |
|
| 234 |
Verify path has mode mode, and make it so if testmode is not set. |
233 |
Verify path has mode mode, and make it so if testmode is not set. |
| 235 |
''' |
234 |
''' |
| 236 |
if checked_mode.has_key(path): |
235 |
if path in checked_mode: |
| 237 |
return |
236 |
return |
| 238 |
try: |
237 |
try: |
| 239 |
s = os.stat(path) |
238 |
s = os.stat(path) |
|
Lines 247-253
Link Here
|
| 247 |
msg(' changed %s mode to %o' % (path, newmode)) |
246 |
msg(' changed %s mode to %o' % (path, newmode)) |
| 248 |
else: |
247 |
else: |
| 249 |
msg(' testmode, not fixing') |
248 |
msg(' testmode, not fixing') |
| 250 |
except OSError, o: |
249 |
except OSError as o: |
| 251 |
err(o or '[no error message]') |
250 |
err(o or '[no error message]') |
| 252 |
checked_mode[path] = None |
251 |
checked_mode[path] = None |
| 253 |
|
252 |
|
|
Lines 311-317
Link Here
|
| 311 |
else: |
310 |
else: |
| 312 |
msg(' found unexpected direntry %s' % p) |
311 |
msg(' found unexpected direntry %s' % p) |
| 313 |
|
312 |
|
| 314 |
if splits == range(split): |
313 |
if splits == list(range(split)): |
| 315 |
# big-todo apparently in use |
314 |
# big-todo apparently in use |
| 316 |
bigtodo = 1 |
315 |
bigtodo = 1 |
| 317 |
msg(' big-todo found') |
316 |
msg(' big-todo found') |
|
Lines 330-336
Link Here
|
| 330 |
Verify ownership, mode, and contents of each queue directory in paths. |
329 |
Verify ownership, mode, and contents of each queue directory in paths. |
| 331 |
''' |
330 |
''' |
| 332 |
msg('checking main queue directories...') |
331 |
msg('checking main queue directories...') |
| 333 |
_dirs = paths.keys() |
332 |
_dirs = list(paths.keys()) |
| 334 |
_dirs.sort() |
333 |
_dirs.sort() |
| 335 |
for path in _dirs: |
334 |
for path in _dirs: |
| 336 |
(user, group, mode, is_split) = paths[path] |
335 |
(user, group, mode, is_split) = paths[path] |
|
Lines 345-351
Link Here
|
| 345 |
if not this_split: |
344 |
if not this_split: |
| 346 |
splits = [] |
345 |
splits = [] |
| 347 |
else: |
346 |
else: |
| 348 |
splits = range(split) |
347 |
splits = list(range(split)) |
| 349 |
for i in splits: |
348 |
for i in splits: |
| 350 |
splitpath = os.path.join(path, str(i)) |
349 |
splitpath = os.path.join(path, str(i)) |
| 351 |
check_dir(splitpath, user, group, mode) |
350 |
check_dir(splitpath, user, group, mode) |
|
Lines 467-473
Link Here
|
| 467 |
if not os.path.exists(path) and not testmode: |
466 |
if not os.path.exists(path) and not testmode: |
| 468 |
os.mkfifo(path) |
467 |
os.mkfifo(path) |
| 469 |
chown(path, user, group) |
468 |
chown(path, user, group) |
| 470 |
chmod(path, 0622) |
469 |
chmod(path, 0o622) |
| 471 |
|
470 |
|
| 472 |
####################################### |
471 |
####################################### |
| 473 |
def check_messages(path, split): |
472 |
def check_messages(path, split): |
|
Lines 549-560
Link Here
|
| 549 |
# Nothing in these directories to check at this point |
548 |
# Nothing in these directories to check at this point |
| 550 |
continue |
549 |
continue |
| 551 |
elif path in ('queue/mess', 'queue/todo'): |
550 |
elif path in ('queue/mess', 'queue/todo'): |
| 552 |
mode = 0644 |
551 |
mode = 0o644 |
| 553 |
else: |
552 |
else: |
| 554 |
mode = 0600 |
553 |
mode = 0o600 |
| 555 |
this_split = is_splitdir(is_split, bigtodo) |
554 |
this_split = is_splitdir(is_split, bigtodo) |
| 556 |
if this_split: |
555 |
if this_split: |
| 557 |
splits = range(split) |
556 |
splits = list(range(split)) |
| 558 |
else: |
557 |
else: |
| 559 |
splits = [''] |
558 |
splits = [''] |
| 560 |
for splitval in splits: |
559 |
for splitval in splits: |
|
Lines 635-641
Link Here
|
| 635 |
wd = os.getcwd() |
634 |
wd = os.getcwd() |
| 636 |
try: |
635 |
try: |
| 637 |
os.chdir(qmaildir) |
636 |
os.chdir(qmaildir) |
| 638 |
except StandardError: |
637 |
except: |
| 639 |
err('failed to chdir to %s' % qmaildir) |
638 |
err('failed to chdir to %s' % qmaildir) |
| 640 |
|
639 |
|
| 641 |
if testmode: |
640 |
if testmode: |
|
Lines 747-753
Link Here
|
| 747 |
if force_split < 1: |
746 |
if force_split < 1: |
| 748 |
raise ValueError |
747 |
raise ValueError |
| 749 |
except ValueError: |
748 |
except ValueError: |
| 750 |
raise getopt.error, 'split value must be a positive integer (%s)' % value |
749 |
raise getopt.error('split value must be a positive integer (%s)' % value) |
| 751 |
elif option in ('-n', '--no-bigtodo'): |
750 |
elif option in ('-n', '--no-bigtodo'): |
| 752 |
force_bigtodo = -1 |
751 |
force_bigtodo = -1 |
| 753 |
elif option in ('-b', '--bigtodo'): |
752 |
elif option in ('-b', '--bigtodo'): |
|
Lines 765-774
Link Here
|
| 765 |
create = 1 |
764 |
create = 1 |
| 766 |
if args: |
765 |
if args: |
| 767 |
if len(args) > 1: |
766 |
if len(args) > 1: |
| 768 |
raise getopt.error, 'conf-qmail must be a single argument (%s)' % string.join(args) |
767 |
raise getopt.error('conf-qmail must be a single argument (%s)' % string.join(args)) |
| 769 |
qmaildir = args[0] |
768 |
qmaildir = args[0] |
| 770 |
|
769 |
|
| 771 |
except getopt.error, o: |
770 |
except getopt.error as o: |
| 772 |
err('Error: %s' % o, showhelp=1) |
771 |
err('Error: %s' % o, showhelp=1) |
| 773 |
|
772 |
|
| 774 |
check_queue(qmaildir, test, force_split, force_bigtodo, create, mathishard) |
773 |
check_queue(qmaildir, test, force_split, force_bigtodo, create, mathishard) |