Transmission copies files when asked to delete them!?

Ask for help and report issues not specific to either the Mac OS X or GTK+ versions of Transmission
Post Reply
maki.ato
Posts: 66
Joined: Fri Apr 15, 2011 10:20 pm

Transmission copies files when asked to delete them!?

Post by maki.ato » Thu Oct 09, 2014 12:25 am

This is a weird one.
I asked Transmission Daemon to delete a torrent and its data, a folder with ~30G of files.
I know that transmission doesn't have permissions to delete the files: I'm cross seeding them. They were downloaded on my PC and copied over to the NAS.

What's going on is somewhat baffling. Lets say the torrent folder's name is Tor_Folder. Transmission is copying that folder with its content (reminder ~30G of files) to a sub folder it just created named Tor_Folder_eWIKCL, so the full folder structure is: /base_complete_torrents_folder/Tor_Folder/Tor_Folder_eWIKCL/Tor_Folder/

While that's going on, the contents of /base_complete_torrents_folder/Tor_Folder doesn't change.

What's going on? Why the seemingly redundant file copy?

Edit: Now that it's ended (actually, it ran out of HDD space) that temp folder and it's content were deleted and the torrent files was deleted.

x190
Posts: 5094
Joined: Sun Nov 30, 2008 4:59 am

Re: Transmission copies files when asked to delete them!?

Post by x190 » Thu Oct 09, 2014 2:54 am

Edit: Now that it's ended (actually, it ran out of HDD space) that temp folder and it's content were deleted and the torrent files was deleted.
Yeah, that's how the code works. Basically you need 30 GBs to delete 30 GBs. There's a reason behind it, but it's a long boring story.
The stone age didn’t end because we ran out of stones.
---The Great Disruption - by Paul Gilding
https://paulgilding.com/
-------------------------------------------------

maki.ato
Posts: 66
Joined: Fri Apr 15, 2011 10:20 pm

Re: Transmission copies files when asked to delete them!?

Post by maki.ato » Thu Oct 09, 2014 12:19 pm

x190 wrote:
Edit: Now that it's ended (actually, it ran out of HDD space) that temp folder and it's content were deleted and the torrent files was deleted.
Yeah, that's how the code works. Basically you need 30 GBs to delete 30 GBs. There's a reason behind it, but it's a long boring story.
Now I'm curious. If you've got the time to share it (shorthand, or point me in the right direction) I'm more than willing to listen and learn.

x190
Posts: 5094
Joined: Sun Nov 30, 2008 4:59 am

Re: Transmission copies files when asked to delete them!?

Post by x190 » Fri Oct 10, 2014 2:36 am

Code: Select all

/**
 * This convoluted code does something (seemingly) simple:
 * remove the torrent's local files.
 *
 * Fun complications:
 * 1. Try to preserve the directory hierarchy in the recycle bin.
 * 2. If there are nontorrent files, don't delete them...
 * 3. ...unless the other files are "junk", such as .DS_Store
 */
static void
deleteLocalData (tr_torrent * tor, tr_fileFunc func)
{
  int i, n;
  tr_file_index_t f;
  char * base;
  tr_sys_dir_t odir;
  char * tmpdir = NULL;
  tr_ptrArray files = TR_PTR_ARRAY_INIT;
  tr_ptrArray folders = TR_PTR_ARRAY_INIT;
  PtrArrayCompareFunc vstrcmp = (PtrArrayCompareFunc)strcmp;
  const char * const top = tor->currentDir;

  /* if it's a magnet link, there's nothing to move... */
  if (!tr_torrentHasMetadata (tor))
    return;

  /***
  ****  Move the local data to a new tmpdir
  ***/

  base = tr_strdup_printf ("%s__XXXXXX", tr_torrentName (tor));
  tmpdir = tr_buildPath (top, base, NULL);
  tr_sys_dir_create_temp (tmpdir, NULL);
  tr_free (base);

  for (f=0; f<tor->info.fileCount; ++f)
    {
      char * filename;

      /* try to find the file, looking in the partial and download dirs */
      filename = tr_buildPath (top, tor->info.files[f].name, NULL);
      if (!tr_sys_path_exists (filename, NULL))
        {
          char * partial = tr_torrentBuildPartial (tor, f);
          tr_free (filename);
          filename = tr_buildPath (top, partial, NULL);
          tr_free (partial);
          if (!tr_sys_path_exists (filename, NULL))
            {
              tr_free (filename);
              filename = NULL;
            }
        }

      /* if we found the file, move it */
      if (filename != NULL)
        {
          char * target = tr_buildPath (tmpdir, tor->info.files[f].name, NULL);
          tr_moveFile (filename, target, NULL);
          tr_ptrArrayAppend (&files, target);
          tr_free (filename);
        }
    }

  /***
  ****  Remove tmpdir.
  ****
  ****  Try deleting the top-level files & folders to preserve
  ****  the directory hierarchy in the recycle bin.
  ****  If case that fails -- for example, rmdir () doesn't
  ****  delete nonempty folders -- go from the bottom up too.
  ***/

  /* try deleting the local data's top-level files & folders */
  if ((odir = tr_sys_dir_open (tmpdir, NULL)) != TR_BAD_SYS_DIR)
    {
      const char * name;
      while ((name = tr_sys_dir_read_name (odir, NULL)) != NULL)
        {
          if (strcmp (name, ".") != 0 && strcmp (name, "..") != 0)
            {
              char * file = tr_buildPath (tmpdir, name, NULL);
              func (file);
              tr_free (file);
            }
        }
      tr_sys_dir_close (odir, NULL);
    }

  /* go from the bottom up */
  for (i=0, n=tr_ptrArraySize (&files); i<n; ++i)
    {
      char * walk = tr_strdup (tr_ptrArrayNth (&files, i));
      while (tr_sys_path_exists (walk, NULL) && !tr_sys_path_is_same (tmpdir, walk, NULL))
        {
          char * tmp = tr_sys_path_dirname (walk, NULL);
          func (walk);
          tr_free (walk);
          walk = tmp;
        }
      tr_free (walk);
    }

  /***
  ****  The local data has been removed.
  ****  What's left in top are empty folders, junk, and user-generated files.
  ****  Remove the first two categories and leave the third.
  ***/

  /* build a list of 'top's child directories that belong to this torrent */
  for (f=0; f<tor->info.fileCount; ++f)
    {
      char * dir;
      char * filename;

      /* get the directory that this file goes in... */
      filename = tr_buildPath (top, tor->info.files[f].name, NULL);
      dir = tr_sys_path_dirname (filename, NULL);
      tr_free (filename);

      /* walk up the directory tree until we reach 'top' */
      if (!tr_sys_path_is_same (top, dir, NULL) && strcmp (top, dir) != 0)
        {
          for (;;)
            {
              char * parent = tr_sys_path_dirname (dir, NULL);
              if (tr_sys_path_is_same (top, parent, NULL) || strcmp (top, parent) == 0)
                {
                  if (tr_ptrArrayFindSorted (&folders, dir, vstrcmp) == NULL)
                    tr_ptrArrayInsertSorted (&folders, tr_strdup(dir), vstrcmp);
                  tr_free (parent);
                  break;
                }

              /* walk upwards to parent */
              tr_free (dir);
              dir = parent;
            }
        }

      tr_free (dir);
    }

  for (i=0, n=tr_ptrArraySize (&folders); i<n; ++i)
    removeEmptyFoldersAndJunkFiles (tr_ptrArrayNth (&folders, i));

  /* cleanup */
  tr_sys_path_remove (tmpdir, NULL);
  tr_free (tmpdir);
  tr_ptrArrayDestruct (&folders, tr_free);
  tr_ptrArrayDestruct (&files, tr_free);
}
IMO, it's a case of doing dumb things in a futile effort to keep everybody happy. Well, is everybody HAPPY? :)
The stone age didn’t end because we ran out of stones.
---The Great Disruption - by Paul Gilding
https://paulgilding.com/
-------------------------------------------------

maki.ato
Posts: 66
Joined: Fri Apr 15, 2011 10:20 pm

Re: Transmission copies files when asked to delete them!?

Post by maki.ato » Fri Oct 10, 2014 7:04 am

Holy crap, what a convoluted piece of code.

freddy96
Posts: 1
Joined: Sun Jan 04, 2015 9:30 pm

Re: Transmission copies files when asked to delete them!?

Post by freddy96 » Sun Jan 04, 2015 9:32 pm

Try LongPathTool for transmission file name too long error.. :)

Post Reply