Esempio n. 1
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;
}
Esempio n. 2
0
static void
gotsig (int sig)
{
    switch (sig)
    {
        case SIGHUP:
        {
            if (!mySession)
            {
                tr_logAddInfo ("Deferring reload until session is fully started.");
                seenHUP = true;
            }
            else
            {
                tr_variant settings;
                const char * configDir;

                /* reopen the logfile to allow for log rotation */
                if (logfileName) {
                    logfile = freopen (logfileName, LOGFILE_MODE_STR, logfile);
                    if (!logfile)
                        fprintf (stderr, "Couldn't reopen \"%s\": %s\n", logfileName, tr_strerror (errno));
                }

                configDir = tr_sessionGetConfigDir (mySession);
                tr_logAddInfo ("Reloading settings from \"%s\"", configDir);
                tr_variantInitDict (&settings, 0);
                tr_variantDictAddBool (&settings, TR_KEY_rpc_enabled, true);
                tr_sessionLoadSettings (&settings, configDir, MY_NAME);
                tr_sessionSet (mySession, &settings);
                tr_variantFree (&settings);
                tr_sessionReloadBlocklists (mySession);
            }
            break;
        }

        default:
            tr_logAddError ("Unexpected signal (%d) in daemon, closing.", sig);
            /* no break */

        case SIGINT:
        case SIGTERM:
            event_base_loopexit(ev_base, NULL);
            break;
    }
}
Esempio n. 3
0
static void
watchdir_new_impl (dtr_watchdir * w)
{
    int i;
    DIR * odir;
    w->inotify_fd = inotify_init ();

    if (w->inotify_fd < 0)
    {
        i = -1;
    }
    else
    {
        tr_logAddInfo ("Using inotify to watch directory \"%s\"", w->dir);
        i = inotify_add_watch (w->inotify_fd, w->dir, DTR_INOTIFY_MASK);
    }

    if (i < 0)
    {
        tr_logAddError ("Unable to watch \"%s\": %s", w->dir, tr_strerror (errno));
    }
    else if ((odir = opendir (w->dir)))
    {
        struct dirent * d;

        while ((d = readdir (odir)))
        {
            const char * name = d->d_name;

            if (!tr_str_has_suffix (name, ".torrent")) /* skip non-torrents */
                continue;

            tr_logAddInfo ("Found new .torrent file \"%s\" in watchdir \"%s\"", name, w->dir);
            w->callback (w->session, w->dir, name);
        }

        closedir (odir);
    }

}
Esempio n. 4
0
static void
onFileAdded (tr_session * session, const char * dir, const char * file)
{
    char * filename = tr_buildPath (dir, file, NULL);
    tr_ctor * ctor = tr_ctorNew (session);
    int err = tr_ctorSetMetainfoFromFile (ctor, filename);

    if (!err)
    {
        tr_torrentNew (ctor, &err, NULL);

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

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

            if (!test && trash)
            {
                tr_logAddInfo ("Deleting input .torrent file \"%s\"", file);
                if (tr_remove (filename))
                    tr_logAddError ("Error deleting .torrent file: %s", tr_strerror (errno));
            }
            else
            {
                char * new_filename = tr_strdup_printf ("%s.added", filename);
                tr_rename (filename, new_filename);
                tr_free (new_filename);
            }
        }
    }

    tr_ctorFree (ctor);
    tr_free (filename);
}
Esempio n. 5
0
static void blocklistLoad(tr_blocklistFile* b)
{
    tr_sys_file_t fd;
    uint64_t byteCount;
    tr_sys_path_info info;
    char* base;
    tr_error* error = NULL;
    char const* err_fmt = _("Couldn't read \"%1$s\": %2$s");

    blocklistClose(b);

    if (!tr_sys_path_get_info(b->filename, 0, &info, NULL))
    {
        return;
    }

    byteCount = info.size;

    if (byteCount == 0)
    {
        return;
    }

    fd = tr_sys_file_open(b->filename, TR_SYS_FILE_READ, 0, &error);

    if (fd == TR_BAD_SYS_FILE)
    {
        tr_logAddError(err_fmt, b->filename, error->message);
        tr_error_free(error);
        return;
    }

    b->rules = tr_sys_file_map_for_reading(fd, 0, byteCount, &error);

    if (b->rules == NULL)
    {
        tr_logAddError(err_fmt, b->filename, error->message);
        tr_sys_file_close(fd, NULL);
        tr_error_free(error);
        return;
    }

    b->fd = fd;
    b->byteCount = byteCount;
    b->ruleCount = byteCount / sizeof(struct tr_ipv4_range);

    base = tr_sys_path_basename(b->filename, NULL);
    tr_logAddInfo(_("Blocklist \"%s\" contains %zu entries"), base, b->ruleCount);
    tr_free(base);
}
Esempio n. 6
0
static void
watchdir_new_impl (dtr_watchdir * w)
{
    int i;
    tr_sys_dir_t odir;
    w->inotify_fd = inotify_init ();

    if (w->inotify_fd < 0)
    {
        i = -1;
    }
    else
    {
        tr_logAddInfo ("Using inotify to watch directory \"%s\"", w->dir);
        i = inotify_add_watch (w->inotify_fd, w->dir, DTR_INOTIFY_MASK);
    }

    if (i < 0)
    {
        tr_logAddError ("Unable to watch \"%s\": %s", w->dir, tr_strerror (errno));
    }
    else if ((odir = tr_sys_dir_open (w->dir, NULL)) != TR_BAD_SYS_DIR)
    {
        const char * name;
        while ((name = tr_sys_dir_read_name (odir, NULL)) != NULL)
        {
            if (!tr_str_has_suffix (name, ".torrent")) /* skip non-torrents */
                continue;

            tr_logAddInfo ("Found new .torrent file \"%s\" in watchdir \"%s\"", name, w->dir);
            w->callback (w->session, w->dir, name);
        }

        tr_sys_dir_close (odir, NULL);
    }

}
Esempio n. 7
0
static void
blocklistLoad (tr_blocklistFile * b)
{
  int fd;
  size_t byteCount;
  struct stat st;
  char * base;
  const char * err_fmt = _("Couldn't read \"%1$s\": %2$s");

  blocklistClose (b);

  if (stat (b->filename, &st) == -1)
    return;

  fd = open (b->filename, O_RDONLY | O_BINARY);
  if (fd == -1)
    {
      tr_logAddError (err_fmt, b->filename, tr_strerror (errno));
      return;
    }

  byteCount = (size_t) st.st_size;
  b->rules = mmap (NULL, byteCount, PROT_READ, MAP_PRIVATE, fd, 0);
  if (!b->rules)
    {
      tr_logAddError (err_fmt, b->filename, tr_strerror (errno));
      close (fd);
      return;
    }

  b->fd = fd;
  b->byteCount = byteCount;
  b->ruleCount = byteCount / sizeof (struct tr_ipv4_range);

  base = tr_basename (b->filename);
  tr_logAddInfo (_("Blocklist \"%s\" contains %zu entries"), base, b->ruleCount);
  tr_free (base);
}
Esempio n. 8
0
static void
watchdir_update_impl (dtr_watchdir * w)
{
    int ret;
    fd_set rfds;
    struct timeval time;
    const int fd = w->inotify_fd;

    /* timeout after one second */
    time.tv_sec = 1;
    time.tv_usec = 0;

    /* make the fd_set hold the inotify fd */
    FD_ZERO (&rfds);
    FD_SET (fd, &rfds);

    /* check for added files */
    ret = select (fd+1, &rfds, NULL, NULL, &time);
    if (ret < 0) {
        perror ("select");
    } else if (!ret) {
        /* timed out! */
    } else if (FD_ISSET (fd, &rfds)) {
        int i = 0;
        char buf[BUF_LEN];
        int len = read (fd, buf, sizeof (buf));
        while (i < len) {
            struct inotify_event * event = (struct inotify_event *) &buf[i];
            const char * name = event->name;
            if (tr_str_has_suffix (name, ".torrent"))
            {
                tr_logAddInfo ("Found new .torrent file \"%s\" in watchdir \"%s\"", name, w->dir);
                w->callback (w->session, w->dir, name);
            }
            i += EVENT_SIZE +  event->len;
        }
    }
}
Esempio n. 9
0
struct tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_address const* addr, tr_port port, bool clientIsSeed)
{
    TR_ASSERT(tr_address_is_valid(addr));

    struct tr_peer_socket ret = TR_PEER_SOCKET_INIT;

    static int const domains[NUM_TR_AF_INET_TYPES] = { AF_INET, AF_INET6 };
    tr_socket_t s;
    struct sockaddr_storage sock;
    socklen_t addrlen;
    tr_address const* source_addr;
    socklen_t sourcelen;
    struct sockaddr_storage source_sock;
    char err_buf[512];

    if (!tr_address_is_valid_for_peers(addr, port))
    {
        return ret;
    }

    s = tr_fdSocketCreate(session, domains[addr->type], SOCK_STREAM);

    if (s == TR_BAD_SOCKET)
    {
        return ret;
    }

    /* seeds don't need much of a read buffer... */
    if (clientIsSeed)
    {
        int n = 8192;

        if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (void const*)&n, sizeof(n)) == -1)
        {
            tr_logAddInfo("Unable to set SO_RCVBUF on socket %" PRIdMAX ": %s", (intmax_t)s,
                tr_net_strerror(err_buf, sizeof(err_buf), sockerrno));
        }
    }

    if (evutil_make_socket_nonblocking(s) == -1)
    {
        tr_netClose(session, s);
        return ret;
    }

    addrlen = setup_sockaddr(addr, port, &sock);

    /* set source address */
    source_addr = tr_sessionGetPublicAddress(session, addr->type, NULL);
    TR_ASSERT(source_addr != NULL);
    sourcelen = setup_sockaddr(source_addr, 0, &source_sock);

    if (bind(s, (struct sockaddr*)&source_sock, sourcelen) == -1)
    {
        tr_logAddError(_("Couldn't set source address %s on %" PRIdMAX ": %s"), tr_address_to_string(source_addr), (intmax_t)s,
            tr_net_strerror(err_buf, sizeof(err_buf), sockerrno));
        tr_netClose(session, s);
        return ret;
    }

    if (connect(s, (struct sockaddr*)&sock, addrlen) == -1 &&
#ifdef _WIN32
        sockerrno != WSAEWOULDBLOCK &&
#endif
        sockerrno != EINPROGRESS)
    {
        int const tmperrno = sockerrno;

        if ((tmperrno != ENETUNREACH && tmperrno != EHOSTUNREACH) || addr->type == TR_AF_INET)
        {
            tr_logAddError(_("Couldn't connect socket %" PRIdMAX " to %s, port %d (errno %d - %s)"), (intmax_t)s,
                tr_address_to_string(addr), (int)ntohs(port), tmperrno, tr_net_strerror(err_buf, sizeof(err_buf), tmperrno));
        }

        tr_netClose(session, s);
    }
    else
    {
        ret = tr_peer_socket_tcp_create(s);
    }

    tr_logAddDeep(__FILE__, __LINE__, NULL, "New OUTGOING connection %" PRIdMAX " (%s)", (intmax_t)s,
        tr_peerIoAddrStr(addr, port));

    return ret;
}