#include <signal.h>
#include <libtransmission/transmission.h>
+#include <libtransmission/file.h>
#include <libtransmission/tr-getopt.h>
#include <libtransmission/utils.h> /* tr_wait_msec */
#include <libtransmission/variant.h>
if (tr_variantDictFindStr (&settings, TR_KEY_download_dir, &str, NULL))
{
- if (!tr_fileExists (str, NULL))
+ if (!tr_sys_path_exists (str, NULL))
{
tr_mkdirp (str, 0700);
- if (!tr_fileExists (str, NULL))
+ if (!tr_sys_path_exists (str, NULL))
{
fprintf (stderr, "Unable to create download directory \"%s\"!\n", str);
return EXIT_FAILURE;
#include <event2/event.h>
#include <libtransmission/transmission.h>
+#include <libtransmission/error.h>
+#include <libtransmission/file.h>
#include <libtransmission/tr-getopt.h>
#include <libtransmission/log.h>
#include <libtransmission/utils.h>
if (!test && trash)
{
+ tr_error * error = NULL;
+
tr_logAddInfo ("Deleting input .torrent file \"%s\"", file);
- if (tr_remove (filename))
- tr_logAddError ("Error deleting .torrent file: %s", tr_strerror (errno));
+ 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_rename (filename, new_filename);
+ tr_sys_path_rename (filename, new_filename, NULL);
tr_free (new_filename);
}
}
/* cleanup */
if (pidfile_created)
- tr_remove (pid_filename);
+ tr_sys_path_remove (pid_filename, NULL);
tr_variantFree (&settings);
sd_notify (0, "STATUS=\n");
return 0;
#include <sys/select.h>
#include <unistd.h> /* close */
#else
- #include <sys/types.h> /* stat */
- #include <sys/stat.h> /* stat */
#include <event2/buffer.h> /* evbuffer */
#endif
#include <dirent.h> /* readdir */
#include <libtransmission/transmission.h>
+#include <libtransmission/file.h>
#include <libtransmission/log.h>
#include <libtransmission/utils.h> /* tr_buildPath (), tr_logAddInfo () */
#include "watch.h"
static void
watchdir_update_impl (dtr_watchdir * w)
{
- struct stat sb;
+ tr_sys_path_info info;
DIR * odir;
const time_t oldTime = w->lastTimeChecked;
const char * dirname = w->dir;
struct evbuffer * curFiles = evbuffer_new ();
if ((oldTime + WATCHDIR_POLL_INTERVAL_SECS < time (NULL))
- && !stat (dirname, &sb)
- && S_ISDIR (sb.st_mode)
+ && tr_sys_path_get_info (dirname, 0, &info, NULL)
+ && info.type == TR_SYS_PATH_IS_DIRECTORY
&& ((odir = opendir (dirname))))
{
struct dirent * d;
#include <string.h>
#include <libtransmission/transmission.h>
-#include <libtransmission/utils.h> /* tr_is_same_file () */
+#include <libtransmission/file.h> /* tr_sys_path_is_same () */
#include "conf.h"
#include "file-list.h"
int duplicate_id = 0;
tr_torrent * torrent;
- if (filename && (!o->filename || !tr_is_same_file (filename, o->filename)))
+ if (filename && (!o->filename || !tr_sys_path_is_same (filename, o->filename, NULL)))
{
g_free (o->filename);
o->filename = g_strdup (filename);
struct OpenData * data = gdata;
char * fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (b));
- if (fname && (!data->downloadDir || !tr_is_same_file (fname, data->downloadDir)))
+ if (fname && (!data->downloadDir || !tr_sys_path_is_same (fname, data->downloadDir, NULL)))
{
g_free (data->downloadDir);
data->downloadDir = g_strdup (fname);
#include "transmission.h"
#include "blocklist.h"
+#include "file.h"
#include "net.h"
#include "session.h" /* tr_sessionIsAddressBlocked() */
#include "utils.h"
FILE * fp;
char * dir;
- dir = tr_dirname (path);
+ dir = tr_sys_path_dirname (path, NULL);
tr_mkdirp (dir, 0700);
tr_free (dir);
- tr_remove (path);
+ tr_sys_path_remove (path, NULL);
fp = fopen (path, "w+");
fprintf (fp, "%s", contents);
fclose (fp);
#ifndef _WIN32
#include <sys/mman.h>
#endif
-#include <sys/types.h>
-#include <sys/stat.h>
#include <fcntl.h>
#include "transmission.h"
#include "blocklist.h"
+#include "file.h"
#include "log.h"
#include "net.h"
#include "utils.h"
{
int fd;
size_t byteCount;
- struct stat st;
+ tr_sys_path_info info;
char * base;
const char * err_fmt = _("Couldn't read \"%1$s\": %2$s");
blocklistClose (b);
- if (stat (b->filename, &st) == -1)
+ if (!tr_sys_path_get_info (b->filename, 0, &info, NULL))
+ return;
+
+ byteCount = (size_t) info.size;
+ if (byteCount == 0)
return;
fd = open (b->filename, O_RDONLY | O_BINARY);
return;
}
- byteCount = (size_t) st.st_size;
b->rules = mmap (NULL, byteCount, PROT_READ, MAP_PRIVATE, fd, 0);
if (!b->rules)
{
b->byteCount = byteCount;
b->ruleCount = byteCount / sizeof (struct tr_ipv4_range);
- base = tr_basename (b->filename);
+ base = tr_sys_path_basename (b->filename, NULL);
tr_logAddInfo (_("Blocklist \"%s\" contains %"TR_PRIuSIZE" entries"), base, b->ruleCount);
tr_free (base);
}
blocklistDelete (tr_blocklistFile * b)
{
blocklistClose (b);
- tr_remove (b->filename);
+ tr_sys_path_remove (b->filename, NULL);
}
/***
bool
tr_blocklistFileExists (const tr_blocklistFile * b)
{
- return tr_fileExists (b->filename, NULL);
+ return tr_sys_path_exists (b->filename, NULL);
}
int
}
else
{
- char * base = tr_basename (b->filename);
+ char * base = tr_sys_path_basename (b->filename, NULL);
tr_logAddInfo (_("Blocklist \"%s\" updated with %"TR_PRIuSIZE" entries"), base, ranges_count);
tr_free (base);
}
#include "transmission.h"
#include "fdlimit.h"
+#include "file.h"
#include "log.h"
#include "session.h"
#include "torrent.h" /* tr_isTorrent () */
uint64_t file_size)
{
int flags;
- struct stat sb;
+ tr_sys_path_info info;
bool already_existed;
bool resize_needed;
/* create subfolders, if any */
if (writable)
{
- char * dir = tr_dirname (filename);
+ char * dir = tr_sys_path_dirname (filename, NULL);
const int err = tr_mkdirp (dir, 0777) ? errno : 0;
if (err)
{
tr_free (dir);
}
- already_existed = !stat (filename, &sb) && S_ISREG (sb.st_mode);
+ already_existed = tr_sys_path_get_info (filename, 0, &info, NULL) && info.type == TR_SYS_PATH_IS_FILE;
if (writable && !already_existed && (allocation == TR_PREALLOCATE_FULL))
if (preallocate_file_full (filename, file_size))
tr_logAddDebug ("Preallocated file \"%s\"", filename);
/* we can't resize the file w/o write permissions */
- resize_needed = already_existed && (file_size < (uint64_t)sb.st_size);
+ resize_needed = already_existed && (file_size < info.size);
writable |= resize_needed;
/* open the file */
#include <unistd.h>
#include "transmission.h"
+#include "file.h"
#include "platform.h" /* TR_PATH_DELIMETER */
#include "torrent.h"
#include "trevent.h"
****
***/
-#include <sys/types.h> /* stat(), opendir() */
-#include <sys/stat.h> /* stat() */
+#include <sys/types.h> /* opendir() */
#include <dirent.h> /* opendir() */
#include <unistd.h> /* getcwd() */
static void
rm_rf (const char * killme)
{
- struct stat sb;
+ tr_sys_path_info info;
- if (!stat (killme, &sb))
+ if (tr_sys_path_get_info (killme, 0, &info, NULL))
{
DIR * odir;
- if (S_ISDIR (sb.st_mode) && ((odir = opendir (killme))))
+ if (info.type == TR_SYS_PATH_IS_DIRECTORY && ((odir = opendir (killme))))
{
struct dirent *d;
for (d = readdir(odir); d != NULL; d=readdir(odir))
if (verbose)
fprintf (stderr, "cleanup: removing %s\n", killme);
- tr_remove (killme);
+ tr_sys_path_remove (killme, NULL);
}
}
char * path;
char * dirname;
const tr_file * file = &tor->info.files[i];
- struct stat sb;
if (!complete && (i==0))
path = tr_strdup_printf ("%s%c%s.part", tor->currentDir, TR_PATH_DELIMITER, file->name);
else
path = tr_strdup_printf ("%s%c%s", tor->currentDir, TR_PATH_DELIMITER, file->name);
- dirname = tr_dirname (path);
+ dirname = tr_sys_path_dirname (path, NULL);
tr_mkdirp (dirname, 0700);
fp = fopen (path, "wb+");
for (j=0; j<file->length; ++j)
path = tr_torrentFindFile (tor, i);
assert (path != NULL);
err = errno;
- errno = 0;
- stat (path, &sb);
- assert (errno == 0);
+ assert (tr_sys_path_exists (path, NULL));
errno = err;
tr_free (path);
}
char * dir;
const int tmperr = errno;
- dir = tr_dirname (path);
+ dir = tr_sys_path_dirname (path, NULL);
errno = 0;
tr_mkdirp (dir, 0700);
assert (errno == 0);
build_parent_dir (path);
- tr_remove (path);
+ tr_sys_path_remove (path, NULL);
fp = fopen (path, "wb");
fwrite (payload, 1, n, fp);
fclose (fp);
#include <event2/buffer.h>
#include "transmission.h"
+#include "file.h"
#include "log.h"
#include "platform.h" /* tr_lock */
#include "utils.h"
char timestr[64];
char * message;
struct evbuffer * buf = evbuffer_new ();
- char * base = tr_basename (file);
+ char * base = tr_sys_path_basename (file, NULL);
evbuffer_add_printf (buf, "[%s] ",
tr_logGetTimeStr (timestr, sizeof (timestr)));
#include "transmission.h"
#include "crypto.h"
+#include "file.h"
#include "makemeta.h"
#include <unistd.h> /* sync() */
/* quick check of some of the parsed metainfo */
check_int_eq (payloadSize, inf.totalSize);
- tmpstr = tr_basename(input_file);
+ tmpstr = tr_sys_path_basename (input_file, NULL);
check_streq (tmpstr, inf.name);
tr_free (tmpstr);
check_streq (comment, inf.comment);
/* quick check of some of the parsed metainfo */
check_int_eq (totalSize, inf.totalSize);
- tmpstr = tr_basename(top);
+ tmpstr = tr_sys_path_basename (top, NULL);
check_streq (tmpstr, inf.name);
tr_free (tmpstr);
check_streq (comment, inf.comment);
#include <stdlib.h> /* qsort */
#include <string.h> /* strcmp, strlen */
-#include <sys/types.h>
-#include <sys/stat.h>
#include <unistd.h> /* read () */
#include <dirent.h>
#include "transmission.h"
#include "crypto.h" /* tr_sha1 */
+#include "error.h"
#include "fdlimit.h" /* tr_open_file_for_scanning () */
+#include "file.h"
#include "log.h"
#include "session.h"
#include "makemeta.h"
const char * base,
struct FileList * list)
{
- int i;
DIR * odir;
char * buf;
- struct stat sb;
-
- sb.st_size = 0;
+ tr_sys_path_info info;
+ tr_error * error = NULL;
buf = tr_buildPath (dir, base, NULL);
- i = stat (buf, &sb);
- if (i)
+ if (!tr_sys_path_get_info (buf, 0, &info, &error))
{
tr_logAddError (_("Torrent Creator is skipping file \"%s\": %s"),
- buf, tr_strerror (errno));
+ buf, error->message);
tr_free (buf);
+ tr_error_free (error);
return list;
}
- if (S_ISDIR (sb.st_mode) && ((odir = opendir (buf))))
+ if (info.type == TR_SYS_PATH_IS_DIRECTORY && ((odir = opendir (buf))))
{
struct dirent *d;
for (d = readdir (odir); d != NULL; d = readdir (odir))
list = getFiles (buf, d->d_name, list);
closedir (odir);
}
- else if (S_ISREG (sb.st_mode) && (sb.st_size > 0))
+ else if (info.type == TR_SYS_PATH_IS_FILE && info.size > 0)
{
struct FileList * node = tr_new (struct FileList, 1);
- node->size = sb.st_size;
+ node->size = info.size;
node->filename = tr_strdup (buf);
node->next = list;
list = node;
int i;
struct FileList * files;
struct FileList * walk;
- char topFile[TR_PATH_MAX];
tr_metainfo_builder * ret = tr_new0 (tr_metainfo_builder, 1);
- tr_realpath (topFileArg, topFile);
-
- ret->top = tr_strdup (topFile);
+ ret->top = tr_sys_path_resolve (topFileArg, NULL);
{
- struct stat sb;
- stat (topFile, &sb);
- ret->isFolder = S_ISDIR (sb.st_mode);
+ tr_sys_path_info info;
+ ret->isFolder = tr_sys_path_get_info (ret->top, 0, &info, NULL) &&
+ info.type == TR_SYS_PATH_IS_DIRECTORY;
}
- /* build a list of files containing topFile and,
+ /* build a list of files containing top file and,
if it's a directory, all of its children */
{
- char * dir = tr_dirname (topFile);
- char * base = tr_basename (topFile);
+ char * dir = tr_sys_path_dirname (ret->top, NULL);
+ char * base = tr_sys_path_basename (ret->top, NULL);
files = getFiles (dir, base, NULL);
tr_free (base);
tr_free (dir);
tr_variantDictAddInt (dict, TR_KEY_length, builder->files[0].size);
}
- base = tr_basename (builder->top);
+ base = tr_sys_path_basename (builder->top, NULL);
tr_variantDictAddStr (dict, TR_KEY_name, base);
tr_free (base);
*/
#include <assert.h>
-#include <errno.h>
-#include <stdio.h> /* fopen (), fwrite (), fclose () */
#include <string.h> /* strlen () */
-#include <sys/types.h>
-#include <unistd.h> /* stat */
-
#include <event2/buffer.h>
#include "transmission.h"
-#include "session.h"
#include "crypto.h" /* tr_sha1 */
+#include "file.h"
#include "log.h"
#include "metainfo.h"
#include "platform.h" /* tr_getTorrentDir () */
+#include "session.h"
#include "utils.h"
#include "variant.h"
char * filename;
filename = getTorrentFilename (session, inf);
- tr_remove (filename);
+ tr_sys_path_remove (filename, NULL);
tr_free (filename);
}
#include "cache.h"
#include "completion.h"
#include "crypto.h" /* tr_sha1 () */
+#include "file.h"
#include "log.h"
#include "peer-io.h"
#include "peer-mgr.h"
va_list args;
char timestr[64];
struct evbuffer * buf = evbuffer_new ();
- char * base = tr_basename (file);
+ char * base = tr_sys_path_basename (file, NULL);
char * message;
evbuffer_add_printf (buf, "[%s] %s - %s [%s]: ",
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /* getuid(), close() */
-#include <sys/stat.h>
#ifdef _WIN32
#include <w32api.h>
#endif
#include "transmission.h"
-#include "session.h"
+#include "file.h"
#include "list.h"
#include "log.h"
#include "platform.h"
+#include "session.h"
/***
**** THREADS
static int
isWebClientDir (const char * path)
{
- struct stat sb;
char * tmp = tr_buildPath (path, "index.html", NULL);
- const int ret = !stat (tmp, &sb);
+ const bool ret = tr_sys_path_exists (tmp, NULL);
tr_logAddInfo (_("Searching for web interface file \"%s\""), tmp);
tr_free (tmp);
if (s == NULL) /* check calling module place */
{
+ char * tmp;
GetModuleFileName (GetModuleHandle (NULL), dir, sizeof (dir));
- s = tr_buildPath (dirname (dir), "Web", NULL);
+ tmp = tr_sys_path_dirname (dir, NULL);
+ s = tr_buildPath (tmp, "Web", NULL);
+ tr_free (tmp);
if (!isWebClientDir (s))
{
tr_free (s);
#include <errno.h>
#include <stdio.h> /* fopen() */
#include <string.h> /* strcmp() */
-#include <stdio.h>
-#include <sys/types.h> /* stat() */
-#include <sys/stat.h> /* stat() */
-#include <unistd.h> /* stat(), sync() */
+#include <unistd.h> /* sync() */
#include "transmission.h"
+#include "file.h"
#include "resume.h"
#include "torrent.h" /* tr_isTorrent() */
-#include "utils.h" /* tr_mkdirp() */
#include "variant.h"
#include "libtransmission-test.h"
uint8_t * contents;
size_t contents_len;
- assert (tr_fileExists (path, NULL));
+ assert (tr_sys_path_exists (path, NULL));
contents = tr_loadFile (path, &contents_len);
***/
tmpstr = tr_buildPath (tor->currentDir, "hello-world.txt", NULL);
- check (tr_fileExists (tmpstr, NULL));
+ check (tr_sys_path_exists (tmpstr, NULL));
check_streq ("hello-world.txt", tr_torrentName(tor));
check_int_eq (0, torrentRenameAndWait (tor, tor->info.name, "foobar"));
- check (!tr_fileExists (tmpstr, NULL)); /* confirm the old filename can't be found */
+ check (!tr_sys_path_exists (tmpstr, NULL)); /* confirm the old filename can't be found */
tr_free (tmpstr);
check (tor->info.files[0].is_renamed); /* confirm the file's 'renamed' flag is set */
check_streq ("foobar", tr_torrentName(tor)); /* confirm the torrent's name is now 'foobar' */
check_streq ("foobar", tor->info.files[0].name); /* confirm the file's name is now 'foobar' in our struct */
check (strstr (tor->info.torrent, "foobar") == NULL); /* confirm the name in the .torrent file hasn't changed */
tmpstr = tr_buildPath (tor->currentDir, "foobar", NULL);
- check (tr_fileExists (tmpstr, NULL)); /* confirm the file's name is now 'foobar' on the disk */
+ check (tr_sys_path_exists (tmpstr, NULL)); /* confirm the file's name is now 'foobar' on the disk */
tr_free (tmpstr);
check (testFileExistsAndConsistsOfThisString (tor, 0, "hello, world!\n")); /* confirm the contents are right */
***/
tmpstr = tr_buildPath (tor->currentDir, "foobar", NULL);
- check (tr_fileExists (tmpstr, NULL));
+ check (tr_sys_path_exists (tmpstr, NULL));
check_int_eq (0, torrentRenameAndWait (tor, "foobar", "hello-world.txt"));
- check (!tr_fileExists (tmpstr, NULL));
+ check (!tr_sys_path_exists (tmpstr, NULL));
check (tor->info.files[0].is_renamed);
check_streq ("hello-world.txt", tor->info.files[0].name);
check_streq ("hello-world.txt", tr_torrentName(tor));
/* remove the directory Felidae/Felinae/Felis/catus */
str = tr_torrentFindFile (tor, 1);
check (str != NULL);
- tr_remove (str);
+ tr_sys_path_remove (str, NULL);
tr_free (str);
str = tr_torrentFindFile (tor, 2);
check (str != NULL);
- tr_remove (str);
- tmp = tr_dirname (str);
- tr_remove (tmp);
+ tr_sys_path_remove (str, NULL);
+ tmp = tr_sys_path_dirname (str, NULL);
+ tr_sys_path_remove (tmp, NULL);
tr_free (tmp);
tr_free (str);
sync ();
#include "transmission.h"
#include "completion.h"
+#include "file.h"
#include "log.h"
#include "metainfo.h" /* tr_metainfoGetBasename () */
#include "peer-mgr.h" /* pex */
tr_torrentRemoveResume (const tr_torrent * tor)
{
char * filename = getResumeFilename (tor);
- tr_remove (filename);
+ tr_sys_path_remove (filename, NULL);
tr_free (filename);
}
#include "transmission.h"
#include "completion.h"
#include "fdlimit.h"
+#include "file.h"
#include "log.h"
#include "platform-quota.h" /* tr_device_info_get_free_space() */
#include "rpcimpl.h"
tr_snprintf (result, sizeof (result), "success");
}
- tr_remove (filename);
+ tr_sys_path_remove (filename, NULL);
tr_free (filename);
tr_free (buf);
}
#include <string.h> /* memcpy */
#include <signal.h>
-#include <sys/types.h> /* stat (), umask () */
-#include <sys/stat.h> /* stat (), umask () */
-#include <unistd.h> /* stat */
+#include <sys/types.h> /* umask () */
+#include <sys/stat.h> /* umask () */
#include <dirent.h> /* opendir */
#include <event2/dns.h> /* evdns_base_free () */
#include "cache.h"
#include "crypto.h"
#include "fdlimit.h"
+#include "file.h"
#include "list.h"
#include "log.h"
#include "net.h"
{
int i;
int n = 0;
- struct stat sb;
+ tr_sys_path_info info;
DIR * odir = NULL;
tr_list * l = NULL;
tr_list * list = NULL;
tr_ctorSetSave (data->ctor, false); /* since we already have them */
- if (!stat (dirname, &sb)
- && S_ISDIR (sb.st_mode)
+ if (tr_sys_path_get_info (dirname, 0, &info, NULL)
+ && info.type == TR_SYS_PATH_IS_DIRECTORY
&& ((odir = opendir (dirname))))
{
struct dirent *d;
{
char * binname;
char * basename;
- time_t path_mtime = 0;
- time_t binname_mtime = 0;
+ tr_sys_path_info path_info;
+ tr_sys_path_info binname_info;
- basename = tr_basename (d->d_name);
+ basename = tr_sys_path_basename (d->d_name, NULL);
binname = tr_strdup_printf ("%s" TR_PATH_DELIMITER_STR "%s.bin", dirname, basename);
- if (!tr_fileExists (binname, &binname_mtime)) /* create it */
+ if (!tr_sys_path_get_info (binname, 0, &binname_info, NULL)) /* create it */
{
tr_blocklistFile * b = tr_blocklistFileNew (binname, isEnabled);
const int n = tr_blocklistFileSetContent (b, path);
tr_blocklistFileFree (b);
}
- else if (tr_fileExists(path,&path_mtime) && (path_mtime>=binname_mtime)) /* update it */
+ else if (tr_sys_path_get_info (path, 0, &path_info, NULL) &&
+ path_info.last_modified_at >= binname_info.last_modified_at) /* update it */
{
char * old;
tr_blocklistFile * b;
old = tr_strdup_printf ("%s.old", binname);
- tr_remove (old);
- tr_rename (binname, old);
+ tr_sys_path_remove (old, NULL);
+ tr_sys_path_rename (binname, old, NULL);
b = tr_blocklistFileNew (binname, isEnabled);
if (tr_blocklistFileSetContent (b, path) > 0)
{
- tr_remove (old);
+ tr_sys_path_remove (old, NULL);
}
else
{
- tr_remove (binname);
- tr_rename (old, binname);
+ tr_sys_path_remove (binname, NULL);
+ tr_sys_path_rename (old, binname, NULL);
}
tr_blocklistFileFree (b);
static void
metainfoLookupInit (tr_session * session)
{
- struct stat sb;
+ tr_sys_path_info info;
const char * dirname = tr_getTorrentDir (session);
DIR * odir = NULL;
tr_ctor * ctor = NULL;
tr_variantInitDict (lookup, 0);
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))))
+ if (tr_sys_path_get_info (dirname, 0, &info, NULL)
+ && info.type == TR_SYS_PATH_IS_DIRECTORY
+ && ((odir = opendir (dirname))))
{
struct dirent *d;
while ((d = readdir (odir)))
*/
#include <errno.h> /* EINVAL */
+
#include "transmission.h"
+#include "file.h"
#include "magnet.h"
#include "session.h" /* tr_sessionFindTorrentFile () */
#include "torrent.h" /* tr_ctorGetSave () */
name = NULL;
if (!name || !*name)
{
- char * base = tr_basename (filename);
+ char * base = tr_sys_path_basename (filename, NULL);
tr_variantDictAddStr (info, TR_KEY_name, base);
tr_free (base);
}
#include "transmission.h"
#include "crypto.h" /* tr_sha1 () */
+#include "file.h"
#include "log.h"
#include "magnet.h"
#include "metainfo.h"
int infoDictLength;
/* remove any old .torrent and .resume files */
- tr_remove (path);
+ tr_sys_path_remove (path, NULL);
tr_torrentRemoveResume (tor);
dbgmsg (tor, "Saving completed metadata to \"%s\"", path);
* $Id$
*/
+#include <errno.h> /* EINVAL */
#include <signal.h> /* signal () */
-#include <sys/types.h> /* stat */
-#include <sys/stat.h> /* stat */
#ifndef _WIN32
#include <sys/wait.h> /* wait () */
#else
#include <process.h>
#endif
-#include <unistd.h> /* stat */
+#include <unistd.h> /* fork (), execvp (), _exit () */
#include <dirent.h>
#include <assert.h>
#include "cache.h"
#include "completion.h"
#include "crypto.h" /* for tr_sha1 */
-#include "resume.h"
+#include "error.h"
#include "fdlimit.h" /* tr_fdTorrentClose */
+#include "file.h"
#include "inout.h" /* tr_ioTestPiece () */
#include "log.h"
#include "magnet.h"
#include "peer-mgr.h"
#include "platform.h" /* TR_PATH_DELIMITER_STR */
#include "ptrarray.h"
+#include "resume.h"
#include "session.h"
#include "torrent.h"
#include "torrent-magnet.h"
uint64_t loaded;
const char * dir;
bool isNewTorrent;
- struct stat st;
tr_session * session = tr_ctorGetSession (ctor);
static int nextUniqueId = 1;
}
/* if we don't have a local .torrent file already, assume the torrent is new */
- isNewTorrent = stat (tor->info.torrent, &st);
+ isNewTorrent = !tr_sys_path_exists (tor->info.torrent, NULL);
/* maybe save our own copy of the metainfo */
if (tr_ctorGetSave (ctor))
for (i=0; i<n; ++i)
{
- struct stat sb;
+ tr_sys_path_info info;
char * filename = tr_torrentFindFile (tor, i);
- sb.st_size = 0;
- if (filename && !stat (filename, &sb))
- byte_count += sb.st_size;
+ if (filename != NULL && tr_sys_path_get_info (filename, 0, &info, NULL))
+ byte_count += info.size;
tr_free (filename);
}
{
if (!tor->info.files[i].dnd)
{
- struct stat sb;
+ tr_sys_path_info info;
const uint64_t length = tor->info.files[i].length;
char * path = tr_torrentFindFile (tor, i);
bytesLeft += length;
- if ((path != NULL) && !stat (path, &sb)
- && S_ISREG (sb.st_mode)
- && ((uint64_t)sb.st_size <= length))
- bytesLeft -= sb.st_size;
+ if (path != NULL &&
+ tr_sys_path_get_info (path, 0, &info, NULL) &&
+ info.type == TR_SYS_PATH_IS_FILE &&
+ info.size <= length)
+ bytesLeft -= info.size;
tr_free (path);
}
{
if (strcmp (d->d_name, ".") && strcmp (d->d_name, ".."))
{
- struct stat sb;
+ tr_sys_path_info info;
char * filename = tr_buildPath (folder, d->d_name, NULL);
- if (!stat (filename, &sb) && S_ISDIR (sb.st_mode))
+ if (tr_sys_path_get_info (filename, 0, &info, NULL) &&
+ info.type == TR_SYS_PATH_IS_DIRECTORY)
removeEmptyFoldersAndJunkFiles (filename);
else if (isJunkFile (d->d_name))
- tr_remove (filename);
+ tr_sys_path_remove (filename, NULL);
tr_free (filename);
}
}
- tr_remove (folder);
+ tr_sys_path_remove (folder, NULL);
closedir (odir);
}
}
/* try to find the file, looking in the partial and download dirs */
filename = tr_buildPath (top, tor->info.files[f].name, NULL);
- if (!tr_fileExists (filename, 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_fileExists (filename, NULL))
+ if (!tr_sys_path_exists (filename, NULL))
{
tr_free (filename);
filename = NULL;
for (i=0, n=tr_ptrArraySize (&files); i<n; ++i)
{
char * walk = tr_strdup (tr_ptrArrayNth (&files, i));
- while (tr_fileExists (walk, NULL) && !tr_is_same_file (tmpdir, walk))
+ while (tr_sys_path_exists (walk, NULL) && !tr_sys_path_is_same (tmpdir, walk, NULL))
{
- char * tmp = tr_dirname (walk);
+ char * tmp = tr_sys_path_dirname (walk, NULL);
func (walk);
tr_free (walk);
walk = tmp;
/* get the directory that this file goes in... */
filename = tr_buildPath (top, tor->info.files[f].name, NULL);
- dir = tr_dirname (filename);
+ dir = tr_sys_path_dirname (filename, NULL);
tr_free (filename);
/* walk up the directory tree until we reach 'top' */
- if (!tr_is_same_file (top, dir) && strcmp (top, dir))
+ if (!tr_sys_path_is_same (top, dir, NULL) && strcmp (top, dir) != 0)
{
for (;;)
{
- char * parent = tr_dirname (dir);
- if (tr_is_same_file (top, parent) || !strcmp (top, parent))
+ 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);
removeEmptyFoldersAndJunkFiles (tr_ptrArrayNth (&folders, i));
/* cleanup */
- tr_remove (tmpdir);
+ tr_sys_path_remove (tmpdir, NULL);
tr_free (tmpdir);
tr_ptrArrayDestruct (&folders, tr_free);
tr_ptrArrayDestruct (&files, tr_free);
tr_mkdirp (location, 0777);
- if (!tr_is_same_file (location, tor->currentDir))
+ if (!tr_sys_path_is_same (location, tor->currentDir, NULL))
{
tr_file_index_t i;
tr_logAddDebug ("Found file #%d: %s", (int)i, oldpath);
- if (do_move && !tr_is_same_file (oldpath, newpath))
+ if (do_move && !tr_sys_path_is_same (oldpath, newpath, NULL))
{
bool renamed = false;
errno = 0;
{
char * oldpath = tr_buildPath (base, sub, NULL);
char * newpath = tr_buildPath (base, f->name, NULL);
+ tr_error * error = NULL;
- if (tr_rename (oldpath, newpath))
- tr_logAddTorErr (tor, "Error moving \"%s\" to \"%s\": %s", oldpath, newpath, tr_strerror (errno));
+ if (!tr_sys_path_rename (oldpath, newpath, &error))
+ {
+ tr_logAddTorErr (tor, "Error moving \"%s\" to \"%s\": %s", oldpath, newpath, error->message);
+ tr_error_free (error);
+ }
tr_free (newpath);
tr_free (oldpath);
const tr_file * file;
const char * b = NULL;
const char * s = NULL;
+ tr_sys_path_info file_info;
assert (tr_isTorrent (tor));
assert (fileNum < tor->info.fileCount);
if (b == NULL)
{
char * filename = tr_buildPath (tor->downloadDir, file->name, NULL);
- if (tr_fileExists (filename, mtime))
+ if (tr_sys_path_get_info (filename, 0, &file_info, NULL))
{
b = tor->downloadDir;
s = file->name;
if ((b == NULL) && (tor->incompleteDir != NULL))
{
char * filename = tr_buildPath (tor->incompleteDir, file->name, NULL);
- if (tr_fileExists (filename, mtime))
+ if (tr_sys_path_get_info (filename, 0, &file_info, NULL))
{
b = tor->incompleteDir;
s = file->name;
if ((b == NULL) && (tor->incompleteDir != NULL))
{
char * filename = tr_buildPath (tor->incompleteDir, part, NULL);
- if (tr_fileExists (filename, mtime))
+ if (tr_sys_path_get_info (filename, 0, &file_info, NULL))
{
b = tor->incompleteDir;
s = part;
if (b == NULL)
{
char * filename = tr_buildPath (tor->downloadDir, part, NULL);
- if (tr_fileExists (filename, mtime))
+ if (tr_sys_path_get_info (filename, 0, &file_info, NULL))
{
b = tor->downloadDir;
s = part;
*base = b;
if (subpath != NULL)
*subpath = tr_strdup (s);
+ if (mtime != NULL)
+ *mtime = file_info.last_modified_at;
+
/* cleanup */
tr_free (part);
{
char * src;
const char * base;
- int error = 0;
+ int err = 0;
if (!tr_torrentIsSeed(tor) && (tor->incompleteDir != NULL))
base = tor->incompleteDir;
base = tor->downloadDir;
src = tr_buildPath (base, oldpath, NULL);
- if (!tr_fileExists (src, NULL)) /* check for it as a partial */
+ if (!tr_sys_path_exists (src, NULL)) /* check for it as a partial */
{
char * tmp = tr_strdup_printf ("%s.part", src);
tr_free (src);
src = tmp;
}
- if (tr_fileExists (src, NULL))
+ if (tr_sys_path_exists (src, NULL))
{
int tmp;
bool tgt_exists;
- char * parent = tr_dirname (src);
+ char * parent = tr_sys_path_dirname (src, NULL);
char * tgt;
if (tr_str_has_suffix (src, ".part"))
tgt = tr_buildPath (parent, newname, NULL);
tmp = errno;
- tgt_exists = tr_fileExists (tgt, NULL);
+ tgt_exists = tr_sys_path_exists (tgt, NULL);
errno = tmp;
if (!tgt_exists)
{
- int rv;
+ tr_error * error = NULL;
tmp = errno;
- rv = tr_rename (src, tgt);
- if (rv != 0)
- error = errno;
+ if (!tr_sys_path_rename (src, tgt, &error))
+ {
+ err = error->code;
+ tr_error_free (error);
+ }
errno = tmp;
}
tr_free (src);
- return error;
+ return err;
}
static void
}
else
{
- char * tmp = tr_dirname (oldpath);
+ char * tmp = tr_sys_path_dirname (oldpath, NULL);
if (oldpath_len >= strlen(file->name))
name = tr_buildPath (tmp, newname, NULL);
#ifdef HAVE_ICONV_OPEN
#include <iconv.h>
#endif
-#include <libgen.h> /* basename () */
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <unistd.h> /* stat (), getcwd (), getpagesize () */
+#include <unistd.h> /* stat (), getpagesize () */
#include <event2/buffer.h>
#include <event2/event.h>
#ifdef _WIN32
#include <w32api.h>
#define WINVER WindowsXP /* freeaddrinfo (), getaddrinfo (), getnameinfo () */
- #include <direct.h> /* _getcwd () */
#include <windows.h> /* Sleep (), GetSystemTimeAsFileTime () */
#endif
#include "transmission.h"
+#include "error.h"
#include "fdlimit.h"
+#include "file.h"
#include "ConvertUTF.h"
#include "list.h"
#include "log.h"
+#include "net.h"
#include "utils.h"
-#include "platform.h" /* tr_lockLock (), TR_PATH_MAX */
+#include "platform.h" /* tr_lockLock () */
#include "platform-quota.h" /* tr_device_info_create(), tr_device_info_get_free_space(), tr_device_info_free() */
#include "variant.h"
#include "version.h"
size_t * size)
{
uint8_t * buf;
- struct stat sb;
+ tr_sys_path_info info;
int fd;
ssize_t n;
+ tr_error * error = NULL;
const char * const err_fmt = _("Couldn't read \"%1$s\": %2$s");
/* try to stat the file */
- errno = 0;
- if (stat (path, &sb))
+ if (!tr_sys_path_get_info (path, 0, &info, &error))
{
- const int err = errno;
- tr_logAddDebug (err_fmt, path, tr_strerror (errno));
+ const int err = error->code;
+ tr_logAddDebug (err_fmt, path, error->message);
+ tr_error_free (error);
errno = err;
return NULL;
}
- if ((sb.st_mode & S_IFMT) != S_IFREG)
+ if (info.type != TR_SYS_PATH_IS_FILE)
{
tr_logAddError (err_fmt, path, _("Not a regular file"));
errno = EISDIR;
return NULL;
}
+ /* file size should be able to fit into size_t */
+ if (sizeof(info.size) > sizeof(*size))
+ assert (info.size <= SIZE_MAX);
+
/* Load the torrent file into our buffer */
fd = tr_open_file_for_scanning (path);
if (fd < 0)
errno = err;
return NULL;
}
- buf = tr_malloc (sb.st_size + 1);
+ buf = tr_malloc (info.size + 1);
if (!buf)
{
const int err = errno;
errno = err;
return NULL;
}
- n = read (fd, buf, (size_t)sb.st_size);
+ n = read (fd, buf, (size_t)info.size);
if (n == -1)
{
const int err = errno;
}
tr_close_file (fd);
- buf[ sb.st_size ] = '\0';
- *size = sb.st_size;
+ buf[info.size] = '\0';
+ *size = info.size;
return buf;
}
-char*
-tr_basename (const char * path)
-{
-#ifdef _MSC_VER
-
- char fname[_MAX_FNAME], ext[_MAX_EXT];
- if (_splitpath_s (path, NULL, 0, NULL, 0, fname, sizeof (fname), ext, sizeof (ext)) == 0)
- {
- const size_t tmpLen = strlen(fname) + strlen(ext) + 2;
- char * const tmp = tr_malloc (tmpLen);
- if (tmp != NULL)
- {
- if (_makepath_s (tmp, tmpLen, NULL, NULL, fname, ext) == 0)
- return tmp;
-
- tr_free (tmp);
- }
- }
-
- return tr_strdup (".");
-
-#else
-
- char * tmp = tr_strdup (path);
- char * ret = tr_strdup (basename (tmp));
- tr_free (tmp);
- return ret;
-
-#endif
-}
-
-char*
-tr_dirname (const char * path)
-{
-#ifdef _MSC_VER
-
- char drive[_MAX_DRIVE], dir[_MAX_DIR];
- if (_splitpath_s (path, drive, sizeof (drive), dir, sizeof (dir), NULL, 0, NULL, 0) == 0)
- {
- const size_t tmpLen = strlen(drive) + strlen(dir) + 2;
- char * const tmp = tr_malloc (tmpLen);
- if (tmp != NULL)
- {
- if (_makepath_s (tmp, tmpLen, drive, dir, NULL, NULL) == 0)
- {
- size_t len = strlen(tmp);
- while (len > 0 && (tmp[len - 1] == '/' || tmp[len - 1] == '\\'))
- tmp[--len] = '\0';
-
- return tmp;
- }
-
- tr_free (tmp);
- }
- }
-
- return tr_strdup (".");
-
-#else
-
- char * tmp = tr_strdup (path);
- char * ret = tr_strdup (dirname (tmp));
- tr_free (tmp);
- return ret;
-
-#endif
-}
-
char*
tr_mkdtemp (char * template)
{
return buf;
}
-#ifdef __APPLE__
- #define TR_STAT_MTIME(sb)((sb).st_mtimespec.tv_sec)
-#else
- #define TR_STAT_MTIME(sb)((sb).st_mtime)
-#endif
-
-bool
-tr_fileExists (const char * filename, time_t * mtime)
-{
- struct stat sb;
- const bool ok = !stat (filename, &sb);
-
- if (ok && (mtime != NULL))
- *mtime = TR_STAT_MTIME (sb);
-
- return ok;
-}
-
int64_t
tr_getDirFreeSpace (const char * dir)
{
int in;
int out;
char * buf;
- struct stat st;
+ tr_sys_path_info info;
off_t bytesLeft;
const size_t buflen = 1024 * 128; /* 128 KiB buffer */
+ tr_error * error = NULL;
/* make sure the old file exists */
- if (stat (oldpath, &st))
+ if (!tr_sys_path_get_info (oldpath, 0, &info, &error))
{
- const int err = errno;
+ const int err = error->code;
+ tr_error_free (error);
errno = err;
return -1;
}
- if (!S_ISREG (st.st_mode))
+ if (info.type != TR_SYS_PATH_IS_FILE)
{
errno = ENOENT;
return -1;
}
- bytesLeft = st.st_size;
+ bytesLeft = info.size;
/* make sure the target directory exists */
{
- char * newdir = tr_dirname (newpath);
+ char * newdir = tr_sys_path_dirname (newpath, NULL);
int i = tr_mkdirp (newdir, 0777);
tr_free (newdir);
if (i)
/* they might be on the same filesystem... */
{
- const int i = tr_rename (oldpath, newpath);
+ const bool i = tr_sys_path_rename (oldpath, newpath, NULL);
if (renamed != NULL)
- *renamed = i == 0;
- if (!i)
+ *renamed = i;
+ if (i)
return 0;
}
if (bytesLeft != 0)
return -1;
- tr_remove (oldpath);
+ tr_sys_path_remove (oldpath, NULL);
return 0;
}
-int
-tr_rename (const char * oldpath, const char * newpath)
-{
- /* FIXME: needs win32 utf-16 support */
-
- return rename (oldpath, newpath);
-}
-
-int
-tr_remove (const char * pathname)
-{
- /* FIXME: needs win32 utf-16 support */
-
- return remove (pathname);
-}
-
-bool
-tr_is_same_file (const char * filename1, const char * filename2)
-{
-#ifdef _WIN32
-
- bool res;
- HANDLE fh1, fh2;
- BY_HANDLE_FILE_INFORMATION fi1, fi2;
- int n = strlen (filename1) + 1;
- int m = strlen (filename2) + 1;
- wchar_t f1nameUTF16[n];
- wchar_t f2nameUTF16[m];
-
- MultiByteToWideChar (CP_UTF8, 0, filename1, -1, f1nameUTF16, n);
- MultiByteToWideChar (CP_UTF8, 0, filename2, -1, f2nameUTF16, m);
- fh1 = CreateFileW (chkFilename (f1nameUTF16), 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
- fh2 = CreateFileW (chkFilename (f2nameUTF16), 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
- res = GetFileInformationByHandle (fh1, &fi1)
- && GetFileInformationByHandle (fh2, &fi2)
- && (fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber)
- && (fi1.nFileIndexHigh == fi2.nFileIndexHigh)
- && (fi1.nFileIndexLow == fi2.nFileIndexLow);
- CloseHandle (fh1);
- CloseHandle (fh2);
- return res;
-
-#else
-
- struct stat sb1, sb2;
-
- return !stat (filename1, &sb1)
- && !stat (filename2, &sb2)
- && (sb1.st_dev == sb2.st_dev)
- && (sb1.st_ino == sb2.st_ino);
-
-#endif
-}
-
/***
****
***/
return buf;
}
-char *
-tr_realpath (const char * path, char * resolved_path)
-{
-#ifdef _WIN32
- /* From a message to the Mingw-msys list, Jun 2, 2005 by Mark Junker. */
- if (GetFullPathNameA (path, TR_PATH_MAX, resolved_path, NULL) == 0)
- return NULL;
- return resolved_path;
-#else
- return realpath (path, resolved_path);
-#endif
-}
-
/***
****
***/
*/
bool tr_wildmat (const char * text, const char * pattern) TR_GNUC_NONNULL (1,2);
-/** @brief Portability wrapper for basename () that uses the system implementation if available */
-char* tr_basename (const char * path) TR_GNUC_MALLOC;
-
-/** @brief Portability wrapper for dirname () that uses the system implementation if available */
-char* tr_dirname (const char * path) TR_GNUC_MALLOC;
/**
* Like mkdir, but makes parent directories as needed.
char* tr_buildPath (const char * first_element, ...) TR_GNUC_NULL_TERMINATED
TR_GNUC_MALLOC;
-bool tr_fileExists (const char * filename, time_t * mtime);
-
/**
* @brief Get available disk space (in bytes) for the specified folder.
* @return zero or positive integer on success, -1 in case of error.
int tr_moveFile (const char * oldpath, const char * newpath,
bool * renamed) TR_GNUC_NONNULL (1,2);
-/** @brief Portability wrapper for rename () */
-int tr_rename (const char * oldpath_utf8, const char * newpath_utf8);
-
-/** @brief Portability wrapper for remove () */
-int tr_remove (const char * pathname_utf8);
-
-/** @brief Test to see if the two filenames point to the same file. */
-bool tr_is_same_file (const char * filename1, const char * filename2);
-
/** @brief convenience function to remove an item from an array */
void tr_removeElementFromArray (void * array,
unsigned int index_to_remove,
/** @brief Private libtransmission function to update tr_time ()'s counter */
static inline void tr_timeUpdate (time_t now) { __tr_current_time = now; }
-#ifdef _WIN32
- #include <windef.h> /* MAX_PATH */
- #define TR_PATH_MAX (MAX_PATH + 1)
-#else
- #include <limits.h> /* PATH_MAX */
- #ifdef PATH_MAX
- #define TR_PATH_MAX PATH_MAX
- #else
- #define TR_PATH_MAX 4096
- #endif
-#endif
-
-/** @brief Portability wrapper for realpath () that uses the system implementation if available.
- @param resolved_path should be TR_PATH_MAX or larger */
-char* tr_realpath (const char *path, char * resolved_path);
-
/** @brief Portability wrapper for htonll () that uses the system implementation if available */
uint64_t tr_htonll (uint64_t);
#include <assert.h>
#include <errno.h>
-#include <stdio.h> /* rename() */
#include <stdlib.h> /* strtod(), realloc(), qsort(), mkstemp() */
#include <string.h>
#include "transmission.h"
#include "ConvertUTF.h"
#include "fdlimit.h" /* tr_close_file() */
+#include "error.h"
+#include "file.h"
#include "log.h"
-#include "platform.h" /* TR_PATH_MAX */
#include "utils.h" /* tr_new(), tr_free() */
#include "variant.h"
#include "variant-common.h"
char * tmp;
int fd;
int err = 0;
- char buf[TR_PATH_MAX];
+ char * real_filename;
/* follow symlinks to find the "real" file, to make sure the temporary
* we build with tr_mkstemp() is created on the right partition */
- if (tr_realpath (filename, buf) != NULL)
- filename = buf;
+ if ((real_filename = tr_sys_path_resolve (filename, NULL)) != NULL)
+ filename = real_filename;
/* if the file already exists, try to move it out of the way & keep it as a backup */
tmp = tr_strdup_printf ("%s.tmp.XXXXXX", filename);
{
tr_logAddError (_("Couldn't save temporary file \"%1$s\": %2$s"), tmp, tr_strerror (err));
tr_close_file (fd);
- tr_remove (tmp);
+ tr_sys_path_remove (tmp, NULL);
}
else
{
+ tr_error * error = NULL;
+
tr_close_file (fd);
- if (!tr_rename (tmp, filename))
+ if (tr_sys_path_rename (tmp, filename, &error))
{
tr_logAddInfo (_("Saved \"%s\""), filename);
}
else
{
- err = errno;
- tr_logAddError (_("Couldn't save file \"%1$s\": %2$s"), filename, tr_strerror (err));
- tr_remove (tmp);
+ err = error->code;
+ tr_logAddError (_("Couldn't save file \"%1$s\": %2$s"), filename, error->message);
+ tr_sys_path_remove (tmp, NULL);
+ tr_error_free (error);
}
}
}
}
tr_free (tmp);
+ tr_free (real_filename);
return err;
}
#include <event2/buffer.h>
#include "transmission.h"
+#include "file.h"
#include "list.h"
#include "log.h"
#include "net.h" /* tr_address */
}
str = tr_buildPath (session->configDir, "cookies.txt", NULL);
- if (tr_fileExists (str, NULL))
+ if (tr_sys_path_exists (str, NULL))
web->cookie_filename = tr_strdup (str);
tr_free (str);
#include <unistd.h> /* getcwd() */
#include <libtransmission/transmission.h>
+#include <libtransmission/file.h>
#include <libtransmission/makemeta.h>
#include <libtransmission/tr-getopt.h>
#include <libtransmission/utils.h>
if (outfile == NULL)
{
- char * base = tr_basename (infile);
+ char * base = tr_sys_path_basename (infile, NULL);
char * end = tr_strdup_printf ("%s.torrent", base);
char * cwd = tr_getcwd ();
outfile = out2 = tr_buildPath (cwd, end, NULL);