2006-08-13 00:26:52 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* $Id$
|
|
|
|
*
|
2007-02-19 22:09:05 +00:00
|
|
|
* Copyright (c) 2005-2007 Transmission authors and contributors
|
2006-08-13 00:26:52 +00:00
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
*****************************************************************************/
|
2006-07-16 19:39:23 +00:00
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
#include <glib/gi18n.h>
|
2007-09-28 00:46:22 +00:00
|
|
|
#include <glib/gstdio.h>
|
2006-07-16 19:39:23 +00:00
|
|
|
|
2007-09-27 20:57:58 +00:00
|
|
|
#include <libtransmission/transmission.h>
|
|
|
|
#include <libtransmission/bencode.h>
|
|
|
|
|
2006-07-16 19:39:23 +00:00
|
|
|
#include "conf.h"
|
|
|
|
#include "util.h"
|
|
|
|
|
2007-10-12 20:50:03 +00:00
|
|
|
#define CONF_SUBDIR "gtk"
|
|
|
|
#define FILE_SOCKET "socket"
|
2006-07-16 19:39:23 +00:00
|
|
|
|
|
|
|
static char *gl_confdir = NULL;
|
|
|
|
static char *gl_lockpath = NULL;
|
2007-10-12 20:50:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* errstr may be NULL, this might be called before GTK is initialized */
|
|
|
|
gboolean
|
|
|
|
cf_init(const char *dir, char **errstr) {
|
|
|
|
if(NULL != errstr)
|
|
|
|
*errstr = NULL;
|
|
|
|
gl_confdir = g_build_filename(dir, CONF_SUBDIR, NULL);
|
|
|
|
|
|
|
|
if(mkdir_p(gl_confdir, 0755 ))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if(NULL != errstr)
|
|
|
|
*errstr = g_strdup_printf(_("Failed to create the directory %s:\n%s"),
|
|
|
|
gl_confdir, strerror(errno));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***
|
|
|
|
****
|
|
|
|
**** Lockfile
|
|
|
|
****
|
|
|
|
***/
|
2006-07-16 19:39:23 +00:00
|
|
|
|
|
|
|
/* errstr may be NULL, this might be called before GTK is initialized */
|
|
|
|
static int
|
|
|
|
lockfile(const char *file, char **errstr) {
|
|
|
|
int fd, savederr;
|
|
|
|
struct flock lk;
|
|
|
|
|
|
|
|
if(NULL != errstr)
|
|
|
|
*errstr = NULL;
|
|
|
|
|
|
|
|
if(0 > (fd = open(file, O_RDWR | O_CREAT, 0666))) {
|
|
|
|
savederr = errno;
|
|
|
|
if(NULL != errstr)
|
|
|
|
*errstr = g_strdup_printf(_("Failed to open the file %s for writing:\n%s"),
|
|
|
|
file, strerror(errno));
|
|
|
|
errno = savederr;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-07-18 17:28:25 +00:00
|
|
|
memset(&lk, 0, sizeof(lk));
|
2006-07-16 19:39:23 +00:00
|
|
|
lk.l_start = 0;
|
|
|
|
lk.l_len = 0;
|
|
|
|
lk.l_type = F_WRLCK;
|
|
|
|
lk.l_whence = SEEK_SET;
|
|
|
|
if(-1 == fcntl(fd, F_SETLK, &lk)) {
|
|
|
|
savederr = errno;
|
|
|
|
if(NULL != errstr) {
|
|
|
|
if(EAGAIN == errno)
|
|
|
|
*errstr = g_strdup_printf(_("Another copy of %s is already running."),
|
|
|
|
g_get_application_name());
|
|
|
|
else
|
|
|
|
*errstr = g_strdup_printf(_("Failed to lock the file %s:\n%s"),
|
|
|
|
file, strerror(errno));
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
errno = savederr;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
2007-10-12 20:50:03 +00:00
|
|
|
static char*
|
|
|
|
getLockFilename( void )
|
|
|
|
{
|
|
|
|
return g_build_filename( tr_getPrefsDirectory(),
|
|
|
|
CONF_SUBDIR, "lock", NULL );
|
2006-07-16 19:39:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-09-28 00:46:22 +00:00
|
|
|
cf_removelocks( void )
|
|
|
|
{
|
|
|
|
g_unlink( gl_lockpath );
|
|
|
|
g_free( gl_lockpath );
|
2006-07-16 19:39:23 +00:00
|
|
|
}
|
|
|
|
|
2007-10-12 20:50:03 +00:00
|
|
|
/* errstr may be NULL, this might be called before GTK is initialized */
|
|
|
|
gboolean
|
|
|
|
cf_lock( char ** errstr )
|
|
|
|
{
|
|
|
|
const char * path = getLockFilename( );
|
|
|
|
int fd = lockfile( path, errstr );
|
|
|
|
if( fd >= 0 )
|
|
|
|
gl_lockpath = g_strdup( path );
|
|
|
|
g_atexit( cf_removelocks );
|
|
|
|
return fd >= 0;
|
2006-07-16 19:39:23 +00:00
|
|
|
}
|
|
|
|
|
2007-10-12 20:50:03 +00:00
|
|
|
char*
|
|
|
|
cf_sockname( void )
|
|
|
|
{
|
|
|
|
return g_build_filename( gl_confdir, FILE_SOCKET, NULL );
|
2006-07-16 19:39:23 +00:00
|
|
|
}
|
|
|
|
|
2007-10-12 20:50:03 +00:00
|
|
|
/***
|
|
|
|
****
|
|
|
|
**** Preferences
|
|
|
|
****
|
|
|
|
***/
|
2006-07-16 19:39:23 +00:00
|
|
|
|
2007-10-03 21:02:30 +00:00
|
|
|
#define GROUP "general"
|
2006-07-16 19:39:23 +00:00
|
|
|
|
2007-09-27 20:57:58 +00:00
|
|
|
static char*
|
|
|
|
getPrefsFilename( void )
|
|
|
|
{
|
2007-09-28 00:46:22 +00:00
|
|
|
return g_build_filename( tr_getPrefsDirectory(),
|
|
|
|
CONF_SUBDIR, "prefs.ini", NULL );
|
2007-09-27 20:57:58 +00:00
|
|
|
}
|
2006-07-16 19:39:23 +00:00
|
|
|
|
2007-09-27 20:57:58 +00:00
|
|
|
static GKeyFile*
|
|
|
|
getPrefsKeyFile( void )
|
|
|
|
{
|
|
|
|
static GKeyFile * myKeyFile = NULL;
|
|
|
|
|
|
|
|
if( myKeyFile == NULL )
|
|
|
|
{
|
|
|
|
char * filename = getPrefsFilename( );
|
|
|
|
myKeyFile = g_key_file_new( );
|
|
|
|
g_key_file_load_from_file( myKeyFile, filename, 0, NULL );
|
|
|
|
g_free( filename );
|
|
|
|
}
|
2006-07-16 19:39:23 +00:00
|
|
|
|
2007-09-27 20:57:58 +00:00
|
|
|
return myKeyFile;
|
|
|
|
}
|
2006-07-16 19:39:23 +00:00
|
|
|
|
2007-09-27 20:57:58 +00:00
|
|
|
int
|
|
|
|
pref_int_get( const char * key )
|
|
|
|
{
|
2007-10-03 21:02:30 +00:00
|
|
|
return g_key_file_get_integer( getPrefsKeyFile( ), GROUP, key, NULL );
|
2007-09-27 20:57:58 +00:00
|
|
|
}
|
|
|
|
void
|
|
|
|
pref_int_set( const char * key, int value )
|
|
|
|
{
|
2007-10-03 21:02:30 +00:00
|
|
|
g_key_file_set_integer( getPrefsKeyFile( ), GROUP, key, value );
|
2007-09-27 20:57:58 +00:00
|
|
|
}
|
|
|
|
void
|
|
|
|
pref_int_set_default( const char * key, int value )
|
|
|
|
{
|
2007-10-03 21:02:30 +00:00
|
|
|
if( !g_key_file_has_key( getPrefsKeyFile( ), GROUP, key, NULL ) )
|
2007-09-27 20:57:58 +00:00
|
|
|
pref_int_set( key, value );
|
|
|
|
}
|
2006-07-16 19:39:23 +00:00
|
|
|
|
2007-09-27 20:57:58 +00:00
|
|
|
gboolean
|
|
|
|
pref_flag_get ( const char * key )
|
|
|
|
{
|
2007-10-03 21:02:30 +00:00
|
|
|
return g_key_file_get_boolean( getPrefsKeyFile( ), GROUP, key, NULL );
|
2007-09-27 20:57:58 +00:00
|
|
|
}
|
|
|
|
void
|
|
|
|
pref_flag_set( const char * key, gboolean value )
|
|
|
|
{
|
2007-10-03 21:02:30 +00:00
|
|
|
g_key_file_set_boolean( getPrefsKeyFile( ), GROUP, key, value );
|
2007-09-27 20:57:58 +00:00
|
|
|
}
|
|
|
|
void
|
|
|
|
pref_flag_set_default( const char * key, gboolean value )
|
|
|
|
{
|
2007-10-03 21:02:30 +00:00
|
|
|
if( !g_key_file_has_key( getPrefsKeyFile( ), GROUP, key, NULL ) )
|
2007-09-27 20:57:58 +00:00
|
|
|
pref_flag_set( key, value );
|
|
|
|
}
|
|
|
|
|
|
|
|
char*
|
|
|
|
pref_string_get( const char * key )
|
|
|
|
{
|
2007-10-03 21:02:30 +00:00
|
|
|
return g_key_file_get_string( getPrefsKeyFile( ), GROUP, key, NULL );
|
2007-09-27 20:57:58 +00:00
|
|
|
}
|
|
|
|
void
|
|
|
|
pref_string_set( const char * key, const char * value )
|
|
|
|
{
|
2007-10-03 21:02:30 +00:00
|
|
|
g_key_file_set_string( getPrefsKeyFile( ), GROUP, key, value );
|
2007-09-27 20:57:58 +00:00
|
|
|
}
|
|
|
|
void
|
|
|
|
pref_string_set_default( const char * key, const char * value )
|
|
|
|
{
|
2007-10-03 21:02:30 +00:00
|
|
|
if( !g_key_file_has_key( getPrefsKeyFile( ), GROUP, key, NULL ) )
|
2007-09-27 20:57:58 +00:00
|
|
|
pref_string_set( key, value );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
pref_save(char **errstr)
|
|
|
|
{
|
|
|
|
gsize datalen;
|
2007-09-28 00:46:22 +00:00
|
|
|
GError * err = NULL;
|
2007-09-27 20:57:58 +00:00
|
|
|
char * data;
|
2007-09-28 00:46:22 +00:00
|
|
|
char * filename;
|
|
|
|
char * path;
|
|
|
|
|
|
|
|
filename = getPrefsFilename( );
|
|
|
|
path = g_path_get_dirname( filename );
|
|
|
|
mkdir_p( path, 0755 );
|
2007-09-27 20:57:58 +00:00
|
|
|
|
|
|
|
data = g_key_file_to_data( getPrefsKeyFile(), &datalen, &err );
|
|
|
|
if( !err ) {
|
|
|
|
GIOChannel * out = g_io_channel_new_file( filename, "w+", &err );
|
|
|
|
g_io_channel_write_chars( out, data, datalen, NULL, &err );
|
|
|
|
g_io_channel_unref( out );
|
2006-07-16 19:39:23 +00:00
|
|
|
}
|
|
|
|
|
2007-09-27 20:57:58 +00:00
|
|
|
if( errstr != NULL )
|
|
|
|
*errstr = err ? g_strdup( err->message ) : NULL;
|
|
|
|
|
|
|
|
g_clear_error( &err );
|
2007-09-28 00:46:22 +00:00
|
|
|
g_free( data );
|
|
|
|
g_free( path );
|
|
|
|
g_free( filename );
|
2006-07-16 19:39:23 +00:00
|
|
|
}
|