diff options
author | Timo Sirainen <cras@irssi.org> | 2002-01-17 22:51:28 +0000 |
---|---|---|
committer | cras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 2002-01-17 22:51:28 +0000 |
commit | 103d66897418625386f7ee3af676b3456353477a (patch) | |
tree | 5bd1f8d38e1914465c7cbce650ddf560e16e0b5a /src/irc | |
parent | ab19c70aa16411619f2a2490eb8366426a057aed (diff) | |
download | irssi-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.c | 29 |
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); |