summaryrefslogtreecommitdiff
path: root/src/irc
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2002-01-17 22:51:28 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2002-01-17 22:51:28 +0000
commit103d66897418625386f7ee3af676b3456353477a (patch)
tree5bd1f8d38e1914465c7cbce650ddf560e16e0b5a /src/irc
parentab19c70aa16411619f2a2490eb8366426a057aed (diff)
downloadirssi-103d66897418625386f7ee3af676b3456353477a.zip
When creating a file for DCC download, make sure we won't run into any race
conditions if /SET dcc_download_path was set to some directory where other users could write files as well. Also, the created file mode is always 0600 now. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@2318 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/irc')
-rw-r--r--src/irc/dcc/dcc-get.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/src/irc/dcc/dcc-get.c b/src/irc/dcc/dcc-get.c
index 39b368f6..b04cab40 100644
--- a/src/irc/dcc/dcc-get.c
+++ b/src/irc/dcc/dcc-get.c
@@ -169,7 +169,8 @@ static void sig_dccget_receive(GET_DCC_REC *dcc)
static void sig_dccget_connected(GET_DCC_REC *dcc)
{
struct stat statbuf;
- char *fname;
+ char *fname, *tempfname;
+ int temphandle, old_umask;
if (net_geterror(dcc->handle) != 0) {
/* error connecting */
@@ -195,8 +196,30 @@ static void sig_dccget_connected(GET_DCC_REC *dcc)
}
if (dcc->get_type != DCC_GET_RESUME) {
- dcc->fhandle = open(dcc->file, O_WRONLY | O_TRUNC | O_CREAT,
- dcc_file_create_mode);
+ /* we want to overwrite the file, remove it here.
+ if it gets created after this, we'll fail. */
+ unlink(dcc->file);
+
+ /* just to make sure we won't run into race conditions
+ if download_path is in some global temp directory */
+ tempfname = g_strconcat(dcc->file, ".XXXXXX", NULL);
+
+ old_umask = umask(066);
+ temphandle = mkstemp(tempfname);
+ umask(old_umask);
+
+ dcc->fhandle = -1;
+ if (link(tempfname, dcc->file) == 0) {
+ /* ok, we're the file owner now */
+ dcc->fhandle = open(dcc->file, O_WRONLY | O_TRUNC | O_CREAT,
+ dcc_file_create_mode);
+ }
+
+ /* close/remove the temp file */
+ close(temphandle);
+ unlink(tempfname);
+ g_free(tempfname);
+
if (dcc->fhandle == -1) {
signal_emit("dcc error file create", 2,
dcc, dcc->file);