Changeset 7473
- Timestamp:
- Dec 23, 2008, 4:04:11 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gtk/tr-torrent.c
r7199 r7473 319 319 tr_torrent_delete_files( TrTorrent * gtor ) 320 320 { 321 tr_file_index_t i; 322 const tr_info * info = tr_torrent_info( gtor ); 323 const char * stop = 324 tr_torrentGetDownloadDir( tr_torrent_handle( gtor ) ); 325 326 for( i = 0; info && i < info->fileCount; ++i ) 327 { 328 char * file = g_build_filename( stop, info->files[i].name, NULL ); 329 while( strcmp( stop, file ) && strlen( stop ) < strlen( file ) ) 330 { 331 char * swap = g_path_get_dirname( file ); 332 tr_file_trash_or_unlink( file ); 333 g_free( file ); 334 file = swap; 335 } 336 337 g_free( file ); 338 } 321 tr_torrentDeleteLocalData( tr_torrent_handle( gtor ), tr_file_trash_or_unlink ); 339 322 } 340 323 -
trunk/gtk/util.c
r7464 r7473 515 515 } 516 516 517 void 517 int 518 518 tr_file_trash_or_unlink( const char * filename ) 519 519 { … … 522 522 gboolean trashed = FALSE; 523 523 #ifdef HAVE_GIO 524 GError * err = NULL;525 524 GFile * file = g_file_new_for_path( filename ); 526 trashed = g_file_trash( file, NULL, &err);525 trashed = g_file_trash( file, NULL, NULL ); 527 526 g_object_unref( G_OBJECT( file ) ); 528 527 #endif … … 530 529 g_unlink( filename ); 531 530 } 531 532 return 0; 532 533 } 533 534 -
trunk/gtk/util.h
r7464 r7473 133 133 gpointer tr_object_ref_sink( gpointer object ); 134 134 135 voidtr_file_trash_or_unlink( const char * filename );135 int tr_file_trash_or_unlink( const char * filename ); 136 136 137 137 #endif /* GTK_MAJOR_VERSION */ -
trunk/libtransmission/rpcimpl.c
r7404 r7473 151 151 int64_t deleteFlag; 152 152 if( tr_bencDictFindInt( args_in, "delete-local-data", &deleteFlag ) && deleteFlag ) 153 tr_torrentDeleteLocalData( tor );153 tr_torrentDeleteLocalData( tor, NULL ); 154 154 if( !( status & TR_RPC_NOREMOVE ) ) 155 155 tr_torrentRemove( tor ); -
trunk/libtransmission/torrent.c
r7446 r7473 26 26 #include <sys/stat.h> /* stat */ 27 27 #include <unistd.h> /* stat */ 28 #include <dirent.h> 28 29 29 30 #include <assert.h> … … 41 42 #include "metainfo.h" 42 43 #include "peer-mgr.h" 44 #include "platform.h" /* TR_PATH_DELIMITER_STR */ 45 #include "ptrarray.h" 43 46 #include "ratecontrol.h" 44 47 #include "torrent.h" … … 1189 1192 1190 1193 void 1191 tr_torrentDeleteLocalData( tr_torrent * tor )1192 {1193 tr_file_index_t i;1194 1195 for( i=0; i<tor->info.fileCount; ++i )1196 {1197 const tr_file * file = &tor->info.files[i];1198 char * path = tr_buildPath( tor->downloadDir, file->name, NULL );1199 tr_fdFileClose( path );1200 unlink( path );1201 tr_free( path );1202 }1203 }1204 1205 void1206 1194 tr_torrentStop( tr_torrent * tor ) 1207 1195 { … … 1816 1804 return bytesLeft; 1817 1805 } 1806 1807 /**** 1808 ***** Removing the torrent's local data 1809 ****/ 1810 1811 static int 1812 vstrcmp( const void * a, const void * b ) 1813 { 1814 return strcmp( a, b ); 1815 } 1816 1817 static int 1818 compareLongestFirst( const void * a, const void * b ) 1819 { 1820 const size_t alen = strlen( a ); 1821 const size_t blen = strlen( b ); 1822 1823 if( alen != blen ) 1824 return alen > blen ? -1 : 1; 1825 1826 return vstrcmp( a, b ); 1827 } 1828 1829 static void 1830 addDirtyFile( const char * root, 1831 const char * filename, 1832 tr_ptrArray * dirtyFolders ) 1833 { 1834 char * dir = tr_dirname( filename ); 1835 1836 /* add the parent folders to dirtyFolders until we reach the root or a known-dirty */ 1837 while ( ( dir != NULL ) 1838 && ( strlen( root ) <= strlen( dir ) ) 1839 && ( tr_ptrArrayFindSorted( dirtyFolders, dir, vstrcmp ) == NULL ) ) 1840 { 1841 char * tmp; 1842 tr_ptrArrayInsertSorted( dirtyFolders, tr_strdup( dir ), vstrcmp ); 1843 tmp = tr_dirname( dir ); 1844 tr_free( dir ); 1845 dir = tmp; 1846 } 1847 1848 tr_free( dir ); 1849 } 1850 1851 static void 1852 walkLocalData( const tr_torrent * tor, 1853 const char * root, 1854 const char * dir, 1855 const char * base, 1856 tr_ptrArray * torrentFiles, 1857 tr_ptrArray * folders, 1858 tr_ptrArray * dirtyFolders ) 1859 { 1860 int i; 1861 struct stat sb; 1862 char * buf; 1863 1864 buf = tr_buildPath( dir, base, NULL ); 1865 i = stat( buf, &sb ); 1866 if( !i ) 1867 { 1868 DIR * odir = NULL; 1869 1870 if( S_ISDIR( sb.st_mode ) && ( ( odir = opendir ( buf ) ) ) ) 1871 { 1872 struct dirent *d; 1873 tr_ptrArrayInsertSorted( folders, tr_strdup( buf ), vstrcmp ); 1874 for( d = readdir( odir ); d != NULL; d = readdir( odir ) ) 1875 if( d->d_name && d->d_name[0] != '.' ) /* skip dotfiles */ 1876 walkLocalData( tor, root, buf, d->d_name, torrentFiles, folders, dirtyFolders ); 1877 closedir( odir ); 1878 } 1879 else if( S_ISREG( sb.st_mode ) && ( sb.st_size > 0 ) ) 1880 { 1881 const char * sub = buf + strlen( tor->downloadDir ) + strlen( TR_PATH_DELIMITER_STR ); 1882 const tr_bool isTorrentFile = tr_ptrArrayFindSorted( torrentFiles, sub, vstrcmp ) != NULL; 1883 if( !isTorrentFile ) 1884 addDirtyFile( root, buf, dirtyFolders ); 1885 } 1886 } 1887 1888 tr_free( buf ); 1889 } 1890 1891 static void 1892 deleteLocalData( tr_torrent * tor, tr_fileFunc fileFunc ) 1893 { 1894 int i, n; 1895 char ** s; 1896 tr_file_index_t f; 1897 tr_ptrArray * torrentFiles = tr_ptrArrayNew( ); 1898 tr_ptrArray * folders = tr_ptrArrayNew( ); 1899 tr_ptrArray * dirtyFolders = tr_ptrArrayNew( ); /* dirty == contains non-torrent files */ 1900 1901 const char * firstFile = tor->info.files[0].name; 1902 const char * cpch = strchr( firstFile, TR_PATH_DELIMITER ); 1903 char * tmp = cpch ? tr_strndup( firstFile, cpch - firstFile ) : NULL; 1904 char * root = tr_buildPath( tor->downloadDir, tmp, NULL ); 1905 1906 for( f=0; f<tor->info.fileCount; ++f ) 1907 tr_ptrArrayInsertSorted( torrentFiles, tor->info.files[f].name, vstrcmp ); 1908 1909 /* build the set of folders and dirtyFolders */ 1910 walkLocalData( tor, root, root, NULL, torrentFiles, folders, dirtyFolders ); 1911 1912 /* close all the files because we're about to delete them */ 1913 for( f=0; f<tor->info.fileCount; ++f ) { 1914 char * path = tr_buildPath( tor->downloadDir, tor->info.files[f].name, NULL ); 1915 tr_fdFileClose( path ); 1916 tr_free( path ); 1917 } 1918 1919 /* try to remove entire folders first, so that the recycle bin will be tidy */ 1920 s = (char**) tr_ptrArrayPeek( folders, &n ); 1921 for( i=0; i<n; ++i ) 1922 if( tr_ptrArrayFindSorted( dirtyFolders, s[i], vstrcmp ) == NULL ) 1923 fileFunc( s[i] ); 1924 1925 /* now blow away any remaining torrent files, such torrent files in dirty folders */ 1926 for( f=0; f<tor->info.fileCount; ++f ) { 1927 char * path = tr_buildPath( tor->downloadDir, tor->info.files[f].name, NULL ); 1928 fileFunc( path ); 1929 tr_free( path ); 1930 } 1931 1932 /* Now clean out the directories left empty from the previous step. 1933 * Work from deepest to shallowest s.t. lower folders 1934 * won't prevent the upper folders from being deleted */ 1935 { 1936 tr_ptrArray * cleanFolders = tr_ptrArrayNew( ); 1937 s = (char**) tr_ptrArrayPeek( folders, &n ); 1938 for( i=0; i<n; ++i ) 1939 if( tr_ptrArrayFindSorted( dirtyFolders, s[i], vstrcmp ) == NULL ) 1940 tr_ptrArrayInsertSorted( cleanFolders, s[i], compareLongestFirst ); 1941 s = (char**) tr_ptrArrayPeek( cleanFolders, &n ); 1942 for( i=0; i<n; ++i ) 1943 fileFunc( s[i] ); 1944 tr_ptrArrayFree( cleanFolders, NULL ); 1945 } 1946 1947 /* cleanup */ 1948 tr_ptrArrayFree( dirtyFolders, tr_free ); 1949 tr_ptrArrayFree( folders, tr_free ); 1950 tr_ptrArrayFree( torrentFiles, NULL ); 1951 tr_free( root ); 1952 tr_free( tmp ); 1953 } 1954 1955 void 1956 tr_torrentDeleteLocalData( tr_torrent * tor, tr_fileFunc fileFunc ) 1957 { 1958 if( fileFunc == NULL ) 1959 fileFunc = unlink; 1960 1961 if( tor->info.fileCount > 1 ) 1962 deleteLocalData( tor, fileFunc ); 1963 else { 1964 char * path = tr_buildPath( tor->downloadDir, tor->info.files[0].name, NULL ); 1965 fileFunc( path ); 1966 tr_free( path ); 1967 } 1968 } -
trunk/libtransmission/transmission.h
r7468 r7473 796 796 void tr_torrentStop( tr_torrent * torrent ); 797 797 798 /** @brief Deletes the torrent data stored on disk. */ 799 void tr_torrentDeleteLocalData( tr_torrent * torrent ); 798 typedef int tr_fileFunc( const char * filename ); 799 800 /** 801 * @brief Deletes the torrent's local data. 802 * @param torrent 803 * @param fileFunc Pass in "unlink" to destroy the files or, on platforms with 804 * recycle bins, pass in a function that uses it instead. 805 * tr_torrentDeleteLocalData() ignores fileFunc's return value. 806 */ 807 void tr_torrentDeleteLocalData( tr_torrent * torrent, tr_fileFunc fileFunc ); 800 808 801 809 /**
Note: See TracChangeset
for help on using the changeset viewer.