Index: /trunk/sites/all/modules/file_translit/file_translit.module
===================================================================
--- /trunk/sites/all/modules/file_translit/file_translit.module (revision 1073)
+++ /trunk/sites/all/modules/file_translit/file_translit.module (revision 1089)
@@ -25,4 +25,104 @@
     }
   }
+
+  $items = array();
+  if ($may_cache) {
+
+    // Provide a callback for converting existing data and files.
+    $items[] = array(
+      'path' => 'admin/content/file_translit/transliterate_existing_files',
+      'title' => t('Transliterate Existing Files'),
+      'description' => t('Rename your files so that they don\'t contain any special characters.'),
+      'callback' => 'drupal_get_form',
+      'callback arguments' => 'file_translit_convert_confirm',
+      'type' => MENU_NORMAL_ITEM,
+      'access' => user_access('administer site configuration'),
+    );
+  }
+
+  return $items;
 }
 
+/**
+ * Create a form for transliterating existing files.
+ */
+function file_translit_convert_confirm() {
+
+  return confirm_form(
+    $form,
+    t("Are you sure that you want to transliterate your existing file names?  Make sure that you back up your database and your files directory first!!"),
+    '', NULL, t("Rename all affected files"), NULL
+  );
+}
+
+/**
+ * Process submission of file_translit_convert_form();
+ */
+function file_translit_convert_confirm_submit() {
+  require_once(drupal_get_path('module', 'file_translit').'/file_translit.inc');
+
+  // Get all of the files that need to be converted, that is those that
+  // contain characters other than alphanumerics, underscores, dots, or
+  // hyphens.
+  $results = db_query("
+    SELECT f.fid, f.nid, f.filepath, n.type FROM {files} f
+    INNER JOIN {node} n ON f.nid = n.nid
+    WHERE SUBSTRING_INDEX(filepath, '/', -1) RLIKE '[^0-9A-Za-z_.-]'
+  ");
+
+  // Process each one.
+  while ($db_object = db_fetch_object($results)) {
+
+    // Transliterate the file's path.
+    $basename_old = basename($db_object->filepath);
+    $filepath_new = dirname($db_object->filepath) . "/" .
+                    file_translit_clean(basename($db_object->filepath));
+
+    // Move the file to a new location.
+    $moved = file_move(
+      $db_object->filepath,
+      $filepath_new,
+      FILE_EXISTS_RENAME
+    ) ?  TRUE : FALSE;
+
+    // If the file was actually moved, update the DB record.
+    // It's probably better to not mess with records for missing files.
+    $rows_affected = 0;
+    if ($moved) {
+
+      // Get the file's new path; it may have changed.
+      $filepath_new = $db_object->filepath;
+
+      // Update the files table with the new path.
+      db_query("
+        UPDATE {files} SET filepath = '%s' WHERE fid = %d AND nid = %d
+      ", $filepath_new, $db_object->fid, $db_object->nid);
+      $rows_affected = db_affected_rows();
+    }
+
+    else /* the file was not moved */ {
+      $filepath_new = '';
+    }
+
+    // Report what happened.
+    drupal_set_message(t(
+      'NID: @nid(@type); FID: @fid; Moved: @moved; ' .
+      'Records affected: @records; [@old] -> @new',
+      array(
+        '@nid'     => $db_object->nid,
+        '@type'    => $db_object->type,
+        '@fid'     => $db_object->fid,
+        '@moved'   => $moved ? "Y" : "N",
+        '@records' => $rows_affected,
+        '@old'     => $basename_old,
+        '@new'     => $filepath_new ? basename($filepath_new) : "(N/A)",
+      )
+    ));
+  }
+
+  // Clear the cache tables if possible.
+  if (module_exists('devel')) {
+    devel_cache_clear();
+  }
+}
