Ejemplo n.º 1
0
static const char *
getOldConfigDir( void )
{
    static char * path = NULL;

    if( !path )
    {
#ifdef __BEOS__
        char buf[MAX_PATH_LENGTH];
        find_directory( B_USER_SETTINGS_DIRECTORY,
                       dev_for_path( "/boot" ), true,
                       buf, sizeof( buf ) );
        path = tr_buildPath( buf, "Transmission", NULL );
#elif defined( SYS_DARWIN )
        path = tr_buildPath( getHomeDir( ), "Library",
                              "Application Support",
                              "Transmission", NULL );
#elif defined( __AMIGAOS4__ )
        path = tr_strdup( "PROGDIR:.transmission" );
#elif defined( WIN32 )
        char appdata[MAX_PATH]; /* SHGetFolderPath() requires MAX_PATH */
        SHGetFolderPath( NULL, CSIDL_APPDATA, NULL, 0, appdata );
        path = tr_buildPath( appdata, "Transmission", NULL );
#else
        path = tr_buildPath( getHomeDir( ), ".transmission", NULL );
#endif
    }

    return path;
}
Ejemplo n.º 2
0
static int
test_path_exists (void)
{
  char * const test_dir = create_test_dir (__FUNCTION__);
  tr_error * err = NULL;
  char * path1, * path2;

  path1 = tr_buildPath (test_dir, "a", NULL);
  path2 = tr_buildPath (test_dir, "b", NULL);

  /* Non-existent file does not exist */
  check (!tr_sys_path_exists (path1, &err));
  check (err == NULL);

  /* Create file and see that it exists */
  libtest_create_file_with_string_contents (path1, "test");
  check (tr_sys_path_exists (path1, &err));
  check (err == NULL);

  tr_sys_path_remove (path1, NULL);

  /* Create directory and see that it exists */
  tr_sys_dir_create (path1, 0, 0777, NULL);
  check (tr_sys_path_exists (path1, &err));
  check (err == NULL);

  tr_sys_path_remove (path1, NULL);

  if (create_symlink (path1, path2, false))
    {
      /* Non-existent file does not exist (via symlink) */
      check (!tr_sys_path_exists (path1, &err));
      check (err == NULL);

      /* Create file and see that it exists (via symlink) */
      libtest_create_file_with_string_contents (path2, "test");
      check (tr_sys_path_exists (path1, &err));
      check (err == NULL);

      tr_sys_path_remove (path2, NULL);

      /* Create directory and see that it exists (via symlink) */
      tr_sys_dir_create (path2, 0, 0777, NULL);
      check (tr_sys_path_exists (path1, &err));
      check (err == NULL);

      tr_sys_path_remove (path2, NULL);
      tr_sys_path_remove (path1, NULL);
    }
  else
    {
      fprintf (stderr, "WARNING: [%s] unable to run symlink tests\n", __FUNCTION__);
    }

  tr_free (path2);
  tr_free (path1);

  tr_free (test_dir);
  return 0;
}
Ejemplo n.º 3
0
static void
moveFiles( const char * oldDir,
           const char * newDir )
{
    if( oldDir && newDir && strcmp( oldDir, newDir ) )
    {
        DIR * dirh = opendir( oldDir );
        if( dirh )
        {
            int             count = 0;
            struct dirent * dirp;
            while( ( dirp = readdir( dirh ) ) )
            {
                if( strcmp( dirp->d_name,
                            "." ) && strcmp( dirp->d_name, ".." ) )
                {
                    char * o = tr_buildPath( oldDir, dirp->d_name, NULL );
                    char * n = tr_buildPath( newDir, dirp->d_name, NULL );
                    rename( o, n );
                    ++count;
                    tr_free( n );
                    tr_free( o );
                }
            }

            if( count )
                tr_inf( _( "Migrated %1$d files from \"%2$s\" to \"%3$s\"" ),
                        count, oldDir, newDir );
            closedir( dirh );
        }
    }
}
Ejemplo n.º 4
0
static const char *
getOldConfigDir( void )
{
    static char * path = NULL;

    if( !path )
    {
#ifdef SYS_DARWIN
        path = tr_buildPath( getHomeDir( ), "Library",
                              "Application Support",
                              "Transmission", NULL );
#elif defined( WIN32 )
        char appdata[MAX_PATH]; /* SHGetFolderPath() requires MAX_PATH */
        SHGetFolderPath( NULL, CSIDL_APPDATA, NULL, 0, appdata );
        path = tr_buildPath( appdata, "Transmission", NULL );
#elif defined( __HAIKU__ )
        char buf[TR_PATH_MAX];
        find_directory( B_USER_SETTINGS_DIRECTORY, -1, true, buf, sizeof(buf) );
        path = tr_buildPath( buf, "Transmission", NULL );
#else
        path = tr_buildPath( getHomeDir( ), ".transmission", NULL );
#endif
    }

    return path;
}
Ejemplo n.º 5
0
const char*
tr_getDefaultConfigDir( void )
{
    static char * s = NULL;

    if( !s )
    {
        if( ( s = getenv( "TRANSMISSION_HOME" ) ) )
        {
            s = tr_strdup( s );
        }
        else
        {
#ifdef SYS_DARWIN
            s = tr_buildPath( getHomeDir( ), "Library",
                              "Application Support", "Transmission", NULL );
#elif defined( WIN32 )
            char appdata[MAX_PATH]; /* SHGetFolderPath() requires MAX_PATH */
            SHGetFolderPath( NULL, CSIDL_APPDATA, NULL, 0, appdata );
            s = tr_buildPath( appdata, "Transmission", NULL );
#else
            if( ( s = getenv( "XDG_CONFIG_HOME" ) ) )
                s = tr_buildPath( s, "transmission", NULL );
            else
                s = tr_buildPath( getHomeDir( ), ".config", "transmission", NULL );
#endif
        }
    }

    return s;
}
Ejemplo n.º 6
0
const char*
tr_getDefaultDownloadDir (void)
{
    static char * user_dir = NULL;

    if (user_dir == NULL)
    {
        const char * config_home;
        char * config_file;
        char * content;
        size_t content_len;

        /* figure out where to look for user-dirs.dirs */
        config_home = getenv ("XDG_CONFIG_HOME");
        if (config_home && *config_home)
            config_file = tr_buildPath (config_home, "user-dirs.dirs", NULL);
        else
            config_file = tr_buildPath (getHomeDir (), ".config", "user-dirs.dirs", NULL);

        /* read in user-dirs.dirs and look for the download dir entry */
        content = (char *) tr_loadFile (config_file, &content_len);
        if (content && content_len>0)
        {
            const char * key = "XDG_DOWNLOAD_DIR=\"";
            char * line = strstr (content, key);
            if (line != NULL)
            {
                char * value = line + strlen (key);
                char * end = strchr (value, '"');

                if (end)
                {
                    *end = '\0';

                    if (!memcmp (value, "$HOME/", 6))
                        user_dir = tr_buildPath (getHomeDir (), value+6, NULL);
                    else if (!strcmp (value, "$HOME"))
                        user_dir = tr_strdup (getHomeDir ());
                    else
                        user_dir = tr_strdup (value);
                }
            }
        }

        if (user_dir == NULL)
#ifdef __HAIKU__
            user_dir = tr_buildPath (getHomeDir (), "Desktop", NULL);
#else
            user_dir = tr_buildPath (getHomeDir (), "Downloads", NULL);
#endif

        tr_free (content);
        tr_free (config_file);
    }

    return user_dir;
}
Ejemplo n.º 7
0
static int
test_buildpath (void)
{
  char * out;

  out = tr_buildPath ("foo", "bar", NULL);
  check_streq ("foo" TR_PATH_DELIMITER_STR "bar", out);
  tr_free (out);

  out = tr_buildPath ("", "foo", "bar", NULL);
  check_streq (TR_PATH_DELIMITER_STR "foo" TR_PATH_DELIMITER_STR "bar", out);
  tr_free (out);

  return 0;
}
Ejemplo n.º 8
0
static void
rm_rf (const char * killme)
{
  struct stat sb;

  if (!stat (killme, &sb))
    {
      DIR * odir;

      if (S_ISDIR (sb.st_mode) && ((odir = opendir (killme))))
        {
          struct dirent *d;
          for (d = readdir(odir); d != NULL; d=readdir(odir))
            {
              if (d->d_name && strcmp(d->d_name,".") && strcmp(d->d_name,".."))
                {
                  char * tmp = tr_buildPath (killme, d->d_name, NULL);
                  rm_rf (tmp);
                  tr_free (tmp);
                }
            }
          closedir (odir);
        }

      if (verbose)
        fprintf (stderr, "cleanup: removing %s\n", killme);

      tr_remove (killme);
    }
}
Ejemplo n.º 9
0
static char*
getOldTorrentFilename( const tr_session * session, const tr_info * inf )
{
    int i;
    char * path;
    struct stat sb;
    const int tagCount = 5;
    const char * tags[] = { "beos", "cli", "daemon", "macosx", "wx" };

    /* test the beos, cli, daemon, macosx, wx tags */
    for( i=0; i<tagCount; ++i ) {
        path = tr_strdup_printf( "%s%c%s-%s", tr_getTorrentDir( session ), '/', inf->hashString, tags[i] );
        if( !stat( path, &sb ) && ( ( sb.st_mode & S_IFMT ) == S_IFREG ) )
            return path;
        tr_free( path );
    }

    /* test a non-tagged file */
    path = tr_buildPath( tr_getTorrentDir( session ), inf->hashString, NULL );
    if( !stat( path, &sb ) && ( ( sb.st_mode & S_IFMT ) == S_IFREG ) )
        return path;
    tr_free( path );

    /* return the -gtk form by default, since that's the most common case.
       don't bother testing stat() on it since this is the last candidate
       and we don't want to return NULL anyway */
    return tr_strdup_printf( "%s%c%s-%s", tr_getTorrentDir( session ), '/', inf->hashString, "gtk" );
}
Ejemplo n.º 10
0
static tr_time_t*
getMTimes( const tr_torrent * tor,
           int *              setme_n )
{
    int         i;
    const int   n = tor->info.fileCount;
    tr_time_t * m = calloc( n, sizeof( tr_time_t ) );

    for( i = 0; i < n; ++i )
    {
        struct stat sb;
        char * fname = tr_buildPath( tor->downloadDir, tor->info.files[i].name, NULL );
        if( !stat( fname, &sb ) && S_ISREG( sb.st_mode ) )
        {
#ifdef SYS_DARWIN
            m[i] = sb.st_mtimespec.tv_sec;
#else
            m[i] = sb.st_mtime;
#endif
        }
        tr_free( fname );
    }

    *setme_n = n;
    return m;
}
Ejemplo n.º 11
0
int
tr_blocklistSetContent( tr_session * session,
                        const char * contentFilename )
{
    tr_list *      l;
    tr_blocklist * b;
    const char *   defaultName = "level1.bin";

    assert( tr_isSession( session ) );

    for( b = NULL, l = session->blocklists; !b && l; l = l->next )
        if( tr_stringEndsWith( _tr_blocklistGetFilename( l->data ),
                               defaultName ) )
            b = l->data;

    if( !b )
    {
        char * path = tr_buildPath( session->configDir, "blocklists", defaultName, NULL );
        b = _tr_blocklistNew( path, session->isBlocklistEnabled );
        tr_list_append( &session->blocklists, b );
        tr_free( path );
    }

    return _tr_blocklistSetContent( b, contentFilename );
}
Ejemplo n.º 12
0
void
tr_sessionLoadSettings( tr_benc * d, const char * configDir, const char * appName )
{
    char * filename;
    tr_benc fileSettings;
    tr_benc sessionDefaults;
    tr_benc tmp;

    assert( tr_bencIsDict( d ) );

    /* initializing the defaults: caller may have passed in some app-level defaults.
     * preserve those and use the session defaults to fill in any missing gaps. */
    tr_bencInitDict( &sessionDefaults, 0 );
    tr_sessionGetDefaultSettings( &sessionDefaults );
    tr_bencMergeDicts( &sessionDefaults, d );
    tmp = *d; *d = sessionDefaults; sessionDefaults = tmp;

    /* if caller didn't specify a config dir, use the default */
    if( !configDir || !*configDir )
        configDir = tr_getDefaultConfigDir( appName );

    /* file settings override the defaults */
    filename = tr_buildPath( configDir, "settings.json", NULL );
    if( !tr_bencLoadJSONFile( filename, &fileSettings ) ) {
        tr_bencMergeDicts( d, &fileSettings );
        tr_bencFree( &fileSettings );
    }

    /* cleanup */
    tr_bencFree( &sessionDefaults );
    tr_free( filename );
}
Ejemplo n.º 13
0
static void
rm_rf (const char * killme)
{
  tr_sys_path_info info;

  if (tr_sys_path_get_info (killme, 0, &info, NULL))
    {
      tr_sys_dir_t odir;

      if (info.type == TR_SYS_PATH_IS_DIRECTORY &&
          (odir = tr_sys_dir_open (killme, 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 * tmp = tr_buildPath (killme, name, NULL);
                  rm_rf (tmp);
                  tr_free (tmp);
                }
            }
          tr_sys_dir_close (odir, NULL);
        }

      if (verbose)
        fprintf (stderr, "cleanup: removing %s\n", killme);

      tr_sys_path_remove (killme, NULL);
    }
}
Ejemplo n.º 14
0
static char *
create_test_dir (const char * name)
{
  char * const test_dir = tr_buildPath (tr_sessionGetConfigDir (session), name, NULL);
  tr_sys_dir_create (test_dir, 0, 0777, NULL);
  return test_dir;
}
Ejemplo n.º 15
0
void
tr_setConfigDir( tr_session * session, const char * configDir )
{
    char * path;

    session->configDir = tr_strdup( configDir );

    path = tr_buildPath( configDir, RESUME_SUBDIR, NULL );
    tr_mkdirp( path, 0777 );
    session->resumeDir = path;

    path = tr_buildPath( configDir, TORRENT_SUBDIR, NULL );
    tr_mkdirp( path, 0777 );
    session->torrentDir = path;

    migrateFiles( session );
}
Ejemplo n.º 16
0
void
tr_dhtUninit (tr_session *ss)
{
    if (session != ss)
        return;

    tr_logAddNamedDbg ("DHT", "Uninitializing DHT");

    if (dht_timer != NULL) {
        event_free (dht_timer);
        dht_timer = NULL;
    }

    /* Since we only save known good nodes, avoid erasing older data if we
       don't know enough nodes. */
    if ((tr_dhtStatus (ss, AF_INET, NULL) < TR_DHT_FIREWALLED) &&
      (tr_dhtStatus (ss, AF_INET6, NULL) < TR_DHT_FIREWALLED)) {
        tr_logAddNamedInfo ("DHT", "Not saving nodes, DHT not ready");
    } else {
        tr_variant benc;
        struct sockaddr_in sins[300];
        struct sockaddr_in6 sins6[300];
        char compact[300 * 6], compact6[300 * 18];
        char *dat_file;
        int i, j, num = 300, num6 = 300;
        int n = dht_get_nodes (sins, &num, sins6, &num6);

        tr_logAddNamedInfo ("DHT", "Saving %d (%d + %d) nodes", n, num, num6);

        j = 0;
        for (i=0; i<num; ++i) {
            memcpy (compact + j, &sins[i].sin_addr, 4);
            memcpy (compact + j + 4, &sins[i].sin_port, 2);
            j += 6;
        }
        j = 0;
        for (i=0; i<num6; ++i) {
            memcpy (compact6 + j, &sins6[i].sin6_addr, 16);
            memcpy (compact6 + j + 16, &sins6[i].sin6_port, 2);
            j += 18;
        }
        tr_variantInitDict (&benc, 3);
        tr_variantDictAddRaw (&benc, TR_KEY_id, myid, 20);
        if (num > 0)
            tr_variantDictAddRaw (&benc, TR_KEY_nodes, compact, num * 6);
        if (num6 > 0)
            tr_variantDictAddRaw (&benc, TR_KEY_nodes6, compact6, num6 * 18);
        dat_file = tr_buildPath (ss->configDir, "dht.dat", NULL);
        tr_variantToFile (&benc, TR_VARIANT_FMT_BENC, dat_file);
        tr_variantFree (&benc);
        tr_free (dat_file);
    }

    dht_uninit ();
    tr_logAddNamedDbg ("DHT", "Done uninitializing DHT");

    session = NULL;
}
Ejemplo n.º 17
0
static tr_watchdir_status onFileAdded(tr_watchdir_t dir, char const* name, void* context)
{
    tr_session* session = context;

    if (!tr_str_has_suffix(name, ".torrent"))
    {
        return TR_WATCHDIR_IGNORE;
    }

    char* filename = tr_buildPath(tr_watchdir_get_path(dir), name, NULL);
    tr_ctor* ctor = tr_ctorNew(session);
    int err = tr_ctorSetMetainfoFromFile(ctor, filename);

    if (err == 0)
    {
        tr_torrentNew(ctor, &err, NULL);

        if (err == TR_PARSE_ERR)
        {
            tr_logAddError("Error parsing .torrent file \"%s\"", name);
        }
        else
        {
            bool trash = false;
            bool const test = tr_ctorGetDeleteSource(ctor, &trash);

            tr_logAddInfo("Parsing .torrent file successful \"%s\"", name);

            if (test && trash)
            {
                tr_error* error = NULL;

                tr_logAddInfo("Deleting input .torrent file \"%s\"", name);

                if (!tr_sys_path_remove(filename, &error))
                {
                    tr_logAddError("Error deleting .torrent file: %s", error->message);
                    tr_error_free(error);
                }
            }
            else
            {
                char* new_filename = tr_strdup_printf("%s.added", filename);
                tr_sys_path_rename(filename, new_filename, NULL);
                tr_free(new_filename);
            }
        }
    }
    else
    {
        err = TR_PARSE_ERR;
    }

    tr_ctorFree(ctor);
    tr_free(filename);

    return err == TR_PARSE_ERR ? TR_WATCHDIR_RETRY : TR_WATCHDIR_ACCEPT;
}
Ejemplo n.º 18
0
/**
 * returns 0 on success, or an errno value on failure.
 * errno values include ENOENT if the parent folder doesn't exist,
 * plus the errno values set by tr_mkdirp() and open().
 */
static int
TrOpenFile( int          i,
            const char * folder,
            const char * torrentFile,
            int          doWrite,
            int          doPreallocate,
            uint64_t     desiredFileSize )
{
    struct tr_openfile * file = &gFd->open[i];
    int                  flags;
    char               * filename;
    struct stat          sb;
    int                  alreadyExisted;

    /* confirm the parent folder exists */
    if( stat( folder, &sb ) || !S_ISDIR( sb.st_mode ) )
        return ENOENT;

    /* create subfolders, if any */
    filename = tr_buildPath( folder, torrentFile, NULL );
    if( doWrite )
    {
        char * tmp = tr_dirname( filename );
        const int err = tr_mkdirp( tmp, 0777 ) ? errno : 0;
        tr_free( tmp );
        if( err ) {
            tr_free( filename );
            return err;
        }
    }

    alreadyExisted = !stat( filename, &sb ) && S_ISREG( sb.st_mode );

    if( doWrite && !alreadyExisted && doPreallocate )
        if( preallocateFile( filename, desiredFileSize ) )
            tr_inf( _( "Preallocated file \"%s\"" ), filename );
    
    /* open the file */
    flags = doWrite ? ( O_RDWR | O_CREAT ) : O_RDONLY;
#ifdef O_LARGEFILE
    flags |= O_LARGEFILE;
#endif
#ifdef WIN32
    flags |= O_BINARY;
#endif
    file->fd = open( filename, flags, 0666 );
    if( file->fd == -1 )
    {
        const int err = errno;
        tr_err( _( "Couldn't open \"%1$s\": %2$s" ), filename,
               tr_strerror( err ) );
        tr_free( filename );
        return err;
    }

    tr_free( filename );
    return 0;
}
Ejemplo n.º 19
0
void
tr_setConfigDir( tr_handle *  handle,
                 const char * configDir )
{
    char * path;

    handle->configDir = tr_strdup( configDir );

    path = tr_buildPath( configDir, RESUME_SUBDIR, NULL );
    tr_mkdirp( path, 0777 );
    handle->resumeDir = path;

    path = tr_buildPath( configDir, TORRENT_SUBDIR, NULL );
    tr_mkdirp( path, 0777 );
    handle->torrentDir = path;

    migrateFiles( handle );
}
Ejemplo n.º 20
0
static const char *
getOldCacheDir( void )
{
    static char * path = NULL;

    if( !path )
    {
#if defined( __BEOS__ ) || defined( WIN32 )
        path = tr_buildPath( getOldConfigDir( ), "Cache", NULL );
#elif defined( SYS_DARWIN )
        path = tr_buildPath( getHomeDir( ), "Library", "Caches", "Transmission", NULL );
#else
        path = tr_buildPath( getOldConfigDir( ), "cache", NULL );
#endif
    }

    return path;
}
Ejemplo n.º 21
0
char *
libtest_sandbox_create (void)
{
  char * path = tr_getcwd ();
  char * sandbox = tr_buildPath (path, "sandbox-XXXXXX", NULL);
  tr_free (path);
  tr_mkdtemp (sandbox);
  return sandbox;
}
Ejemplo n.º 22
0
static void
metainfoLookupRescan( tr_session * session )
{
    int          i;
    int          n;
    struct stat  sb;
    const char * dirname = tr_getTorrentDir( session );
    DIR *        odir = NULL;
    tr_ctor *    ctor = NULL;
    tr_list *    list = NULL;

    assert( tr_isSession( session ) );

    /* walk through the directory and find the mappings */
    ctor = tr_ctorNew( session );
    tr_ctorSetSave( ctor, FALSE ); /* since we already have them */
    if( !stat( dirname, &sb ) && S_ISDIR( sb.st_mode ) && ( ( odir = opendir( dirname ) ) ) )
    {
        struct dirent *d;
        for( d = readdir( odir ); d != NULL; d = readdir( odir ) )
        {
            if( d->d_name && d->d_name[0] != '.' ) /* skip dotfiles, ., and ..
                                                     */
            {
                tr_info inf;
                char * path = tr_buildPath( dirname, d->d_name, NULL );
                tr_ctorSetMetainfoFromFile( ctor, path );
                if( !tr_torrentParse( session, ctor, &inf ) )
                {
                    tr_list_append( &list, tr_strdup( inf.hashString ) );
                    tr_list_append( &list, tr_strdup( path ) );
                    tr_metainfoFree( &inf );
                }
                tr_free( path );
            }
        }
        closedir( odir );
    }
    tr_ctorFree( ctor );

    n = tr_list_size( list ) / 2;
    session->metainfoLookup = tr_new0( struct tr_metainfo_lookup, n );
    session->metainfoLookupCount = n;
    for( i = 0; i < n; ++i )
    {
        char * hashString = tr_list_pop_front( &list );
        char * filename = tr_list_pop_front( &list );

        memcpy( session->metainfoLookup[i].hashString, hashString,
                2 * SHA_DIGEST_LENGTH + 1 );
        tr_free( hashString );
        session->metainfoLookup[i].filename = filename;
    }

    metainfoLookupResort( session );
    tr_dbg( "Found %d torrents in \"%s\"", n, dirname );
}
Ejemplo n.º 23
0
static int
test_path_resolve (void)
{
  char * const test_dir = create_test_dir (__FUNCTION__);
  tr_error * err = NULL;
  char * path1, * path2;

  path1 = tr_buildPath (test_dir, "a", NULL);
  path2 = tr_buildPath (test_dir, "b", NULL);

  libtest_create_file_with_string_contents (path1, "test");
  if (create_symlink (path2, path1, false))
    {
      char * tmp;

      tmp = tr_sys_path_resolve (path2, &err);
      check (tmp != NULL);
      check (err == NULL);
      check (path_contains_no_symlinks (tmp));
      tr_free (tmp);

      tr_sys_path_remove (path1, NULL);
      tr_sys_dir_create (path1, 0, 0755, NULL);

      tmp = tr_sys_path_resolve (path2, &err);
      check (tmp != NULL);
      check (err == NULL);
      check (path_contains_no_symlinks (tmp));
      tr_free (tmp);
    }
  else
    {
      fprintf (stderr, "WARNING: [%s] unable to run symlink tests\n", __FUNCTION__);
    }

  tr_sys_path_remove (path2, NULL);
  tr_sys_path_remove (path1, NULL);

  tr_free (path2);
  tr_free (path1);

  tr_free (test_dir);
  return 0;
}
Ejemplo n.º 24
0
static int
checkFile( tr_torrent *    tor,
           tr_file_index_t fileIndex,
           int *           abortFlag )
{
    tr_piece_index_t i;
    int              changed = FALSE;
    int              nofile;
    struct stat      sb;
    char           * path;
    const tr_file  * file = &tor->info.files[fileIndex];

    path = tr_buildPath( tor->downloadDir, file->name, NULL );
    nofile = stat( path, &sb ) || !S_ISREG( sb.st_mode );

    for( i = file->firstPiece;
         i <= file->lastPiece && i < tor->info.pieceCount && ( !*abortFlag );
         ++i )
    {
        if( nofile )
        {
            tr_torrentSetHasPiece( tor, i, 0 );
        }
        else if( !tr_torrentIsPieceChecked( tor, i ) )
        {
            const int      wasComplete = tr_cpPieceIsComplete(
                tor->completion, i );

            if( tr_ioTestPiece( tor, i ) ) /* yay */
            {
                tr_torrentSetHasPiece( tor, i, TRUE );
                if( !wasComplete )
                    changed = TRUE;
            }
            else
            {
                /* if we were wrong about it being complete,
                 * reset and start again.  if we were right about
                 * it being incomplete, do nothing -- we don't
                 * want to lose blocks in those incomplete pieces */

                if( wasComplete )
                {
                    tr_torrentSetHasPiece( tor, i, FALSE );
                    changed = TRUE;
                }
            }
        }

        tr_torrentSetPieceChecked( tor, i, TRUE );
    }

    tr_free( path );

    return changed;
}
Ejemplo n.º 25
0
static const char *
getOldTorrentsDir( void )
{
    static char * path = NULL;

    if( !path )
        path = tr_buildPath( getOldConfigDir( ), TORRENT_SUBDIR, NULL );

    return path;
}
Ejemplo n.º 26
0
static int
isClutchDir( const char * path )
{
    struct stat sb;
    char * tmp = tr_buildPath( path, "javascript", "transmission.js", NULL );
    const int ret = !stat( tmp, &sb );
    tr_inf( _( "Searching for web interface file \"%s\"" ), tmp );
    tr_free( tmp );
    return ret;
}
Ejemplo n.º 27
0
static int
isWebClientDir( const char * path )
{
    struct stat sb;
    char * tmp = tr_buildPath( path, "index.html", NULL );
    const int ret = !stat( tmp, &sb );
    tr_inf( _( "Searching for web interface file \"%s\"" ), tmp );
    tr_free( tmp );
    return ret;
}
Ejemplo n.º 28
0
/* returns 0 on success, or an errno on failure */
static int
readOrWriteBytes( const tr_torrent * tor,
                  int                ioMode,
                  tr_file_index_t    fileIndex,
                  uint64_t           fileOffset,
                  void *             buf,
                  size_t             buflen )
{
    const tr_info * info = &tor->info;
    const tr_file * file = &info->files[fileIndex];

    typedef size_t ( *iofunc )( int, void *, size_t );
    iofunc          func = ioMode ==
                           TR_IO_READ ? (iofunc)read : (iofunc)write;
    char          * path;
    struct stat     sb;
    int             fd = -1;
    int             err;
    int             fileExists;

    assert( tor->downloadDir && *tor->downloadDir );
    assert( fileIndex < info->fileCount );
    assert( !file->length || ( fileOffset < file->length ) );
    assert( fileOffset + buflen <= file->length );

    path = tr_buildPath( tor->downloadDir, file->name, NULL );
    fileExists = !stat( path, &sb );
    tr_free( path );

    if( !file->length )
        return 0;

    if( ( ioMode == TR_IO_READ ) && !fileExists ) /* does file exist? */
        err = errno;
    else if( ( fd = tr_fdFileCheckout ( tor->downloadDir, file->name, ioMode == TR_IO_WRITE, !file->dnd, file->length ) ) < 0 )
        err = errno;
    else if( tr_lseek( fd, (int64_t)fileOffset, SEEK_SET ) == -1 )
        err = errno;
    else if( func( fd, buf, buflen ) != buflen )
        err = errno;
    else
        err = 0;

    if( ( !err ) && ( !fileExists ) && ( ioMode == TR_IO_WRITE ) )
        tr_statsFileCreated( tor->session );

    if( fd >= 0 )
        tr_fdFileReturn( fd );

    return err;
}
Ejemplo n.º 29
0
const char*
tr_getDefaultConfigDir( const char * appname )
{
    static char * s = NULL;

    if( !appname || !*appname )
        appname = "Transmission";

    if( !s )
    {
        if( ( s = getenv( "TRANSMISSION_HOME" ) ) )
        {
            s = tr_strdup( s );
        }
        else
        {
#ifdef SYS_DARWIN
            s = tr_buildPath( getHomeDir( ), "Library", "Application Support",
                              appname, NULL );
#elif defined( WIN32 )
            char appdata[MAX_PATH]; /* SHGetFolderPath() requires MAX_PATH */
            SHGetFolderPath( NULL, CSIDL_APPDATA, NULL, 0, appdata );
            s = tr_buildPath( appdata, appname, NULL );
#elif defined( __HAIKU__ )
            char buf[MAX_PATH_LENGTH];
            find_directory( B_USER_SETTINGS_DIRECTORY, -1, true, buf, sizeof(buf) );
            s = tr_buildPath( buf, appname, NULL );
#else
            if( ( s = getenv( "XDG_CONFIG_HOME" ) ) )
                s = tr_buildPath( s, appname, NULL );
            else
                s = tr_buildPath( getHomeDir( ), ".config", appname, NULL );
#endif
        }
    }

    return s;
}
Ejemplo n.º 30
0
static CURL *
createEasy( tr_session * s, struct tr_web_task * task )
{
    const tr_address * addr;
    tr_bool is_default_value;
    CURL * e = curl_easy_init( );
    const long verbose = getenv( "TR_CURL_VERBOSE" ) != NULL;
    char * cookie_filename = tr_buildPath( s->configDir, "cookies.txt", NULL );

    task->timeout_secs = getTimeoutFromURL( task );

    curl_easy_setopt( e, CURLOPT_AUTOREFERER, 1L );
    curl_easy_setopt( e, CURLOPT_COOKIEFILE, cookie_filename );
    curl_easy_setopt( e, CURLOPT_ENCODING, "gzip;q=1.0, deflate, identity" );
    curl_easy_setopt( e, CURLOPT_FOLLOWLOCATION, 1L );
    curl_easy_setopt( e, CURLOPT_MAXREDIRS, -1L );
    curl_easy_setopt( e, CURLOPT_NOSIGNAL, 1L );
    curl_easy_setopt( e, CURLOPT_PRIVATE, task );
#ifdef USE_LIBCURL_SOCKOPT
    curl_easy_setopt( e, CURLOPT_SOCKOPTFUNCTION, sockoptfunction );
    curl_easy_setopt( e, CURLOPT_SOCKOPTDATA, task );
#endif
    curl_easy_setopt( e, CURLOPT_SSL_VERIFYHOST, 0L );
    curl_easy_setopt( e, CURLOPT_SSL_VERIFYPEER, 0L );
    curl_easy_setopt( e, CURLOPT_TIMEOUT, task->timeout_secs );
    curl_easy_setopt( e, CURLOPT_URL, task->url );
    curl_easy_setopt( e, CURLOPT_USERAGENT, TR_NAME "/" SHORT_VERSION_STRING );
    curl_easy_setopt( e, CURLOPT_VERBOSE, verbose );
    curl_easy_setopt( e, CURLOPT_WRITEDATA, task );
    curl_easy_setopt( e, CURLOPT_WRITEFUNCTION, writeFunc );

    if((( addr = tr_sessionGetPublicAddress( s, TR_AF_INET, &is_default_value ))) && !is_default_value )
        curl_easy_setopt( e, CURLOPT_INTERFACE, tr_ntop_non_ts( addr ) );
    else if ((( addr = tr_sessionGetPublicAddress( s, TR_AF_INET6, &is_default_value ))) && !is_default_value )
        curl_easy_setopt( e, CURLOPT_INTERFACE, tr_ntop_non_ts( addr ) );

    if( task->range )
        curl_easy_setopt( e, CURLOPT_RANGE, task->range );

    if( s->curl_easy_config_func != NULL )
        s->curl_easy_config_func( s, e, task->url );

    tr_free( cookie_filename );
    return e;
}