source: trunk/scripts/check-attachments @ 1184

Revision 1170, 6.8 KB checked in by bogdan2412, 3 months ago (diff)

Some more fixes from live.

  • Made finfo only return the mime type (no charset information), since most of our code expects this behaviour. Changed check-attachments script so that it optionally checks that the stored mimetypes agree with the stored files. This helped discover a bug in the attach-endline-fix which was skiping files that were small enough that mime was not recognizing them as plain text.
  • Fixed a bug with the textblock edit button not displaying the correct edit link for pages with round or task security.
  • Replaced deprecated functions from mailing code base.
  • Added an 'admin' tab to the top navigation bar.
  • Fixed random unwanted characters in common/round.php
  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1#! /usr/bin/env php
2<?php
3
4require_once(dirname($argv[0]) . "/utilities.php");
5require_once(IA_ROOT_DIR . "common/attachment.php");
6require_once(IA_ROOT_DIR . "common/db/attachment.php");
7db_connect();
8
9log_print("Checking attachment dir...");
10log_warn("This script consumes tons of memory so errors might occur");
11
12$res = db_query("SELECT `id`, `name`, `page`, `size` FROM ia_file");
13
14$extra_files = array_flip(glob(IA_ROOT_DIR . "attach/*"));
15$extra_atts = array();
16$total_files = count($extra_files);
17$total_atts = 0;
18$mismatched_sizes = array();
19
20// Check attachments.
21while ($att = db_next_row($res)) {
22    ++$total_atts;
23    $fname = attachment_get_filepath($att);
24    if (array_key_exists($fname, $extra_files)) {
25        unset($extra_files[$fname]);
26    } else {
27        $extra_atts[] = $att;
28        continue;
29    }
30    if (filesize($fname) != $att['size']) {
31        $att['file_size'] = filesize($fname);
32        $mismatched_sizes[] = $att;
33    }
34}
35
36// FIXME: check cache.
37$extra_files = array_keys($extra_files);
38
39if (count($extra_files) == 0 && count($extra_atts) == 0) {
40    log_print("Database and attach dir are in perfect sync, $total_files total files.");
41} else {
42    log_print("There are ".count($extra_files)." out of ".$total_files." disk files with no db entry.");
43    if (count($extra_files)) {
44        if (read_bool("Do you want to see a list?", false)) {
45            foreach ($extra_files as $file) {
46                log_print($file);
47            }
48        }
49        if (read_bool("Want to delete them?", false)) {
50            foreach ($extra_files as $file) {
51                unlink($file);
52            }
53        }
54    }
55
56    log_print("There are ".count($extra_atts)." out of ".$total_atts." db files with no disk file.");
57    if (count($extra_atts)) {
58        if (read_bool("Do you want to see a list?", false)) {
59            foreach ($extra_atts as $att) {
60                log_print("page ".$att['page']." name ".$att['name']);
61            }
62        }
63        if (read_bool("Want to delete them?", false)) {
64            foreach ($extra_atts as $att) {
65                attachment_delete_by_id($att['id']);
66            }
67        }
68    }
69}
70
71unset($extra_atts);
72unset($extra_files);
73
74if (count($mismatched_sizes) != 0) {
75    log_print('There are ' . count($mismatched_sizes) . ' files with ' .
76              'mismatching sizes on disk and in the db');
77    if (read_bool('Do you want to see a list?', false)) {
78        foreach ($mismatched_sizes as $att) {
79            log_print(sprintf('page %s name %s file_size %s db_size %s',
80                              $att['page'], $att['name'],
81                              $att['file_size'], $att['size']));
82        }
83    }
84    if (read_bool('Do you want to try to fix this?', false)) {
85        foreach ($mismatched_sizes as $att) {
86            if ($att['file_size'] == 0 && $att['size'] != 0) {
87                // File was likely uploaded when disk was out of space.
88                // Nothing we can do, delete it.
89                log_print(sprintf('Deleting attachment page %s name %s',
90                                  $att['page'], $att['name']));
91                attachment_delete_by_id($att['id']);
92                continue;
93            }
94
95            $safe_update = false;
96            if (starts_with($att['name'], 'grader_test') &&
97                $att['file_size'] == $att['size'] + 1) {
98                // A script was run that added missing trailing endlines
99                // to grader tests.
100                $safe_update = true;
101            }
102            if ($att['file_size'] != 0 && $att['size'] == 0) {
103                $safe_update = true;
104            }
105
106            if ($safe_update) {
107                $new_att = attachment_get_by_id($att['id']);
108                $new_att['size'] = $att['file_size'];
109                attachment_update($new_att['id'], $new_att['name'],
110                                  $new_att['size'], $new_att['mime_type'],
111                                  $new_att['page'], $new_att['user_id'],
112                                  $new_att['remote_ip_info']);
113                continue;
114            }
115            log_print(sprintf('I don\'t know how to handle attachment page ' .
116                              $att['page'] . ' name ' . $att['name']));
117        }
118    }
119} else {
120    log_print('Stored file sizes match those of the files on disk.');
121}
122
123if (read_bool("Check mimetypes (could take a long time)?", false)) {
124    $res = db_query("SELECT `id`, `name`, `page`, `mime_type` FROM ia_file");
125    $mismatched_mimetypes = array();
126    while ($att = db_next_row($res)) {
127        $fname = attachment_get_filepath($att);
128        if (!is_file($fname)) {
129            continue;
130        }
131        if (get_mime_type($fname) != $att['mime_type']) {
132            $att['file_mime_type'] = get_mime_type($fname);
133            $mismatched_mimetypes[] = $att;
134        }
135    }
136
137    if (count($mismatched_mimetypes) != 0) {
138        log_print('There are ' . count($mismatched_mimetypes) . ' files with ' .
139                  'mismatching mimetypes on disk and in the db');
140        if (read_bool('Do you want to see a list?', false)) {
141            foreach ($mismatched_mimetypes as $att) {
142                log_print(
143                    sprintf('page %s name %s file_mime_type %s db_mime_type %s',
144                            $att['page'], $att['name'],
145                            $att['file_mime_type'], $att['mime_type']));
146            }
147        }
148        if (read_bool('Do you want to update them?', false)) {
149            foreach ($mismatched_mimetypes as $att) {
150                $new_att = attachment_get_by_id($att['id']);
151                $new_att['mime_type'] = $att['file_mime_type'];
152                attachment_update($new_att['id'], $new_att['name'],
153                                  $new_att['size'], $new_att['mime_type'],
154                                  $new_att['page'], $new_att['user_id'],
155                                  $new_att['remote_ip_info']);
156            }
157        }
158    } else {
159        log_print('Stored mime_types match those of the files on disk.');
160    }
161}
162
163if (read_bool("Enforce permissions?", false)) {
164    $defowner = null;
165    if (preg_match('/\/home\/([^\/]*)/', IA_ROOT_DIR, $matches)) {
166        $defowner = $matches[1];
167    }
168    $userown = read_line("Owning user?", $defowner);
169    $groupown = read_line("Owning group?", $defowner);
170    $errs = false;
171    $files = glob(IA_ROOT_DIR . "attach/*");
172    foreach ($files as $file) {
173        $err = array();
174        if (@chmod($file, 0640) == false) {
175            $err[] = "chmod";
176        }
177        if (@chown($file, $userown) == false) {
178            $err[] = "chown";
179        }
180        if (@chgrp($file, $groupown) == false) {
181            $err[] = "chgrp";
182        }
183        $errs |= $err;
184        if ($err) {
185            log_print("Failed ".implode(', ', $err)." on $file");
186        }
187    }
188    if ($errs) {
189        log_print("There were some errors. You should run this as root.");
190    }
191}
192
193?>
Note: See TracBrowser for help on using the repository browser.