Merge pull request #180 from Arnavion/fix-filename-encoding
Fix filename encoding error for DCC transfers of files with non-ASCII characters in their name
This commit is contained in:
commit
ac9bbc6d99
|
@ -57,6 +57,8 @@
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
#include "xchatc.h"
|
#include "xchatc.h"
|
||||||
|
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
#ifdef USE_DCC64
|
#ifdef USE_DCC64
|
||||||
#define BIG_STR_TO_INT(x) strtoull(x,NULL,10)
|
#define BIG_STR_TO_INT(x) strtoull(x,NULL,10)
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -388,8 +390,7 @@ dcc_close (struct DCC *dcc, int dccstat, int destroy)
|
||||||
/* completed file to the completed directory */
|
/* completed file to the completed directory */
|
||||||
if(dcc->type == TYPE_RECV)
|
if(dcc->type == TYPE_RECV)
|
||||||
{
|
{
|
||||||
/* mgl: change this to use destfile_fs for correctness and to */
|
/* mgl: change this to handle the case where dccwithnick is set */
|
||||||
/* handle the case where hex_dcc_save_nick is set */
|
|
||||||
move_file_utf8 (prefs.hex_dcc_dir, prefs.hex_dcc_completed_dir,
|
move_file_utf8 (prefs.hex_dcc_dir, prefs.hex_dcc_completed_dir,
|
||||||
file_part (dcc->destfile), prefs.hex_dcc_permissions);
|
file_part (dcc->destfile), prefs.hex_dcc_permissions);
|
||||||
}
|
}
|
||||||
|
@ -414,8 +415,6 @@ dcc_close (struct DCC *dcc, int dccstat, int destroy)
|
||||||
free (dcc->file);
|
free (dcc->file);
|
||||||
if (dcc->destfile)
|
if (dcc->destfile)
|
||||||
g_free (dcc->destfile);
|
g_free (dcc->destfile);
|
||||||
if (dcc->destfile_fs)
|
|
||||||
g_free (dcc->destfile_fs);
|
|
||||||
free (dcc->nick);
|
free (dcc->nick);
|
||||||
free (dcc);
|
free (dcc);
|
||||||
return;
|
return;
|
||||||
|
@ -691,33 +690,30 @@ dcc_read (GIOChannel *source, GIOCondition condition, struct DCC *dcc)
|
||||||
|
|
||||||
if (dcc->resumable)
|
if (dcc->resumable)
|
||||||
{
|
{
|
||||||
dcc->fp = open (dcc->destfile_fs, O_WRONLY | O_APPEND | OFLAGS);
|
dcc->fp = g_open (dcc->destfile, O_WRONLY | O_APPEND | OFLAGS, 0);
|
||||||
dcc->pos = dcc->resumable;
|
dcc->pos = dcc->resumable;
|
||||||
dcc->ack = dcc->resumable;
|
dcc->ack = dcc->resumable;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
if (access (dcc->destfile_fs, F_OK) == 0)
|
if (g_access (dcc->destfile, F_OK) == 0)
|
||||||
{
|
{
|
||||||
n = 0;
|
n = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
n++;
|
n++;
|
||||||
snprintf (buf, sizeof (buf), "%s.%d", dcc->destfile_fs, n);
|
snprintf (buf, sizeof (buf), "%s.%d", dcc->destfile, n);
|
||||||
}
|
}
|
||||||
while (access (buf, F_OK) == 0);
|
while (access (buf, F_OK) == 0);
|
||||||
|
|
||||||
g_free (dcc->destfile_fs);
|
|
||||||
dcc->destfile_fs = g_strdup (buf);
|
|
||||||
|
|
||||||
old = dcc->destfile;
|
old = dcc->destfile;
|
||||||
dcc->destfile = xchat_filename_to_utf8 (buf, -1, 0, 0, 0);
|
dcc->destfile = g_strdup (buf);
|
||||||
|
|
||||||
EMIT_SIGNAL (XP_TE_DCCRENAME, dcc->serv->front_session,
|
EMIT_SIGNAL (XP_TE_DCCRENAME, dcc->serv->front_session,
|
||||||
old, dcc->destfile, NULL, NULL, 0);
|
old, dcc->destfile, NULL, NULL, 0);
|
||||||
g_free (old);
|
g_free (old);
|
||||||
}
|
}
|
||||||
dcc->fp =
|
dcc->fp =
|
||||||
open (dcc->destfile_fs, OFLAGS | O_TRUNC | O_WRONLY | O_CREAT,
|
g_open (dcc->destfile, OFLAGS | O_TRUNC | O_WRONLY | O_CREAT,
|
||||||
prefs.hex_dcc_permissions);
|
prefs.hex_dcc_permissions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1835,7 +1831,7 @@ dcc_send (struct session *sess, char *to, char *file, int maxcps, int passive)
|
||||||
dcc->dccstat = STAT_QUEUED;
|
dcc->dccstat = STAT_QUEUED;
|
||||||
dcc->size = st.st_size;
|
dcc->size = st.st_size;
|
||||||
dcc->type = TYPE_SEND;
|
dcc->type = TYPE_SEND;
|
||||||
dcc->fp = open (file_fs, OFLAGS | O_RDONLY);
|
dcc->fp = g_open (file_fs, OFLAGS | O_RDONLY, 0);
|
||||||
if (dcc->fp != -1)
|
if (dcc->fp != -1)
|
||||||
{
|
{
|
||||||
g_free (file_fs);
|
g_free (file_fs);
|
||||||
|
@ -1983,7 +1979,7 @@ static int
|
||||||
is_same_file (struct DCC *dcc, struct DCC *new_dcc)
|
is_same_file (struct DCC *dcc, struct DCC *new_dcc)
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
struct stat st_a, st_b;
|
GStatBuf st_a, st_b;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* if it's the same filename, must be same */
|
/* if it's the same filename, must be same */
|
||||||
|
@ -1995,9 +1991,9 @@ is_same_file (struct DCC *dcc, struct DCC *new_dcc)
|
||||||
/* warning no win32 implementation - behaviour may be unreliable */
|
/* warning no win32 implementation - behaviour may be unreliable */
|
||||||
#else
|
#else
|
||||||
/* this fstat() shouldn't really fail */
|
/* this fstat() shouldn't really fail */
|
||||||
if ((dcc->fp == -1 ? stat (dcc->destfile_fs, &st_a) : fstat (dcc->fp, &st_a)) == -1)
|
if ((dcc->fp == -1 ? g_stat (dcc->destfile, &st_a) : fstat (dcc->fp, &st_a)) == -1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (stat (new_dcc->destfile_fs, &st_b) == -1)
|
if (g_stat (new_dcc->destfile, &st_b) == -1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* same inode, same device, same file! */
|
/* same inode, same device, same file! */
|
||||||
|
@ -2015,11 +2011,11 @@ is_resumable (struct DCC *dcc)
|
||||||
dcc->resumable = 0;
|
dcc->resumable = 0;
|
||||||
|
|
||||||
/* Check the file size */
|
/* Check the file size */
|
||||||
if (access (dcc->destfile_fs, W_OK) == 0)
|
if (g_access (dcc->destfile, W_OK) == 0)
|
||||||
{
|
{
|
||||||
struct stat st;
|
GStatBuf st;
|
||||||
|
|
||||||
if (stat (dcc->destfile_fs, &st) != -1)
|
if (g_stat (dcc->destfile, &st) != -1)
|
||||||
{
|
{
|
||||||
if (st.st_size < dcc->size)
|
if (st.st_size < dcc->size)
|
||||||
{
|
{
|
||||||
|
@ -2102,10 +2098,6 @@ dcc_get_with_destfile (struct DCC *dcc, char *file)
|
||||||
g_free (dcc->destfile);
|
g_free (dcc->destfile);
|
||||||
dcc->destfile = g_strdup (file); /* utf-8 */
|
dcc->destfile = g_strdup (file); /* utf-8 */
|
||||||
|
|
||||||
/* get the local filesystem encoding */
|
|
||||||
g_free (dcc->destfile_fs);
|
|
||||||
dcc->destfile_fs = xchat_filename_from_utf8 (dcc->destfile, -1, 0, 0, 0);
|
|
||||||
|
|
||||||
/* since destfile changed, must check resumability again */
|
/* since destfile changed, must check resumability again */
|
||||||
is_resumable (dcc);
|
is_resumable (dcc);
|
||||||
|
|
||||||
|
@ -2337,8 +2329,8 @@ dcc_add_file (session *sess, char *file, DCC_SIZE size, int port, char *nick, gu
|
||||||
strlen (file) + 4);
|
strlen (file) + 4);
|
||||||
|
|
||||||
strcpy (dcc->destfile, prefs.hex_dcc_dir);
|
strcpy (dcc->destfile, prefs.hex_dcc_dir);
|
||||||
if (prefs.hex_dcc_dir[strlen (prefs.hex_dcc_dir) - 1] != '/')
|
if (prefs.hex_dcc_dir[strlen (prefs.hex_dcc_dir) - 1] != G_DIR_SEPARATOR)
|
||||||
strcat (dcc->destfile, "/");
|
strcat (dcc->destfile, G_DIR_SEPARATOR_S);
|
||||||
if (prefs.hex_dcc_save_nick)
|
if (prefs.hex_dcc_save_nick)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -2357,9 +2349,6 @@ dcc_add_file (session *sess, char *file, DCC_SIZE size, int port, char *nick, gu
|
||||||
}
|
}
|
||||||
strcat (dcc->destfile, file);
|
strcat (dcc->destfile, file);
|
||||||
|
|
||||||
/* get the local filesystem encoding */
|
|
||||||
dcc->destfile_fs = xchat_filename_from_utf8 (dcc->destfile, -1, 0, 0, 0);
|
|
||||||
|
|
||||||
dcc->resumable = 0;
|
dcc->resumable = 0;
|
||||||
dcc->pos = 0;
|
dcc->pos = 0;
|
||||||
dcc->serv = sess->server;
|
dcc->serv = sess->server;
|
||||||
|
|
|
@ -62,7 +62,6 @@ struct DCC
|
||||||
time_t lasttime;
|
time_t lasttime;
|
||||||
char *file; /* utf8 */
|
char *file; /* utf8 */
|
||||||
char *destfile; /* utf8 */
|
char *destfile; /* utf8 */
|
||||||
char *destfile_fs; /* local filesystem encoding */
|
|
||||||
char *nick;
|
char *nick;
|
||||||
unsigned char type; /* 0 = SEND 1 = RECV 2 = CHAT */
|
unsigned char type; /* 0 = SEND 1 = RECV 2 = CHAT */
|
||||||
unsigned char dccstat; /* 0 = QUEUED 1 = ACTIVE 2 = FAILED 3 = DONE */
|
unsigned char dccstat; /* 0 = QUEUED 1 = ACTIVE 2 = FAILED 3 = DONE */
|
||||||
|
|
|
@ -254,10 +254,7 @@ file_part (char *file)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return (filepart);
|
return (filepart);
|
||||||
case '/':
|
case G_DIR_SEPARATOR:
|
||||||
#ifdef WIN32
|
|
||||||
case '\\':
|
|
||||||
#endif
|
|
||||||
filepart = file + 1;
|
filepart = file + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -589,12 +589,7 @@ struct popup
|
||||||
/* CL: get a random int in the range [0..n-1]. DON'T use rand() % n, it gives terrible results. */
|
/* CL: get a random int in the range [0..n-1]. DON'T use rand() % n, it gives terrible results. */
|
||||||
#define RAND_INT(n) ((int)(rand() / (RAND_MAX + 1.0) * (n)))
|
#define RAND_INT(n) ((int)(rand() / (RAND_MAX + 1.0) * (n)))
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#define xchat_filename_from_utf8 g_locale_from_utf8
|
|
||||||
#define xchat_filename_to_utf8 g_locale_to_utf8
|
|
||||||
#else
|
|
||||||
#define xchat_filename_from_utf8 g_filename_from_utf8
|
#define xchat_filename_from_utf8 g_filename_from_utf8
|
||||||
#define xchat_filename_to_utf8 g_filename_to_utf8
|
#define xchat_filename_to_utf8 g_filename_to_utf8
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue