Module: wine Branch: master Commit: 161160f05ae2340ab5bb35307ca02056cbca68e9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=161160f05ae2340ab5bb35307c...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Apr 17 12:41:34 2008 +0200
server: Keep a file descriptor open to the config directory to make sure we don't write the registry in the wrong place.
---
server/registry.c | 57 +++++++++++++++++++--------------------------------- server/request.c | 11 ++++++++- server/request.h | 1 + 3 files changed, 31 insertions(+), 38 deletions(-)
diff --git a/server/registry.c b/server/registry.c index 5084892..d2c0b23 100644 --- a/server/registry.c +++ b/server/registry.c @@ -112,7 +112,7 @@ static void set_periodic_save_timer(void); struct save_branch_info { struct key *key; - char *path; + const char *path; };
#define MAX_SAVE_BRANCH_INFO 3 @@ -1396,11 +1396,9 @@ static void load_init_registry_from_file( const char *filename, struct key *key
assert( save_branch_count < MAX_SAVE_BRANCH_INFO );
- if ((save_branch_info[save_branch_count].path = strdup( filename ))) - { - save_branch_info[save_branch_count++].key = (struct key *)grab_object( key ); - make_object_static( &key->obj ); - } + save_branch_info[save_branch_count].path = filename; + save_branch_info[save_branch_count++].key = (struct key *)grab_object( key ); + make_object_static( &key->obj ); }
static WCHAR *format_user_registry_path( const SID *sid, struct unicode_str *path ) @@ -1438,27 +1436,24 @@ void init_registry(void) WCHAR *current_user_path; struct unicode_str current_user_str;
- const char *config = wine_get_config_dir(); - char *p, *filename; struct key *key; int dummy;
+ /* switch to the config dir */ + + if (fchdir( config_dir_fd ) == -1) fatal_perror( "chdir to config dir" ); + /* create the root key */ root_key = alloc_key( &root_name, time(NULL) ); assert( root_key ); make_object_static( &root_key->obj );
- if (!(filename = malloc( strlen(config) + 16 ))) fatal_error( "out of memory\n" ); - strcpy( filename, config ); - p = filename + strlen(filename); - /* load system.reg into Registry\Machine */
if (!(key = create_key( root_key, &HKLM_name, NULL, 0, time(NULL), &dummy ))) fatal_error( "could not create Machine registry key\n" );
- strcpy( p, "/system.reg" ); - load_init_registry_from_file( filename, key ); + load_init_registry_from_file( "system.reg", key ); release_object( key );
/* load userdef.reg into Registry\User.Default */ @@ -1466,8 +1461,7 @@ void init_registry(void) if (!(key = create_key( root_key, &HKU_name, NULL, 0, time(NULL), &dummy ))) fatal_error( "could not create User\.Default registry key\n" );
- strcpy( p, "/userdef.reg" ); - load_init_registry_from_file( filename, key ); + load_init_registry_from_file( "userdef.reg", key ); release_object( key );
/* load user.reg into HKEY_CURRENT_USER */ @@ -1478,14 +1472,14 @@ void init_registry(void) !(key = create_key( root_key, ¤t_user_str, NULL, 0, time(NULL), &dummy ))) fatal_error( "could not create HKEY_CURRENT_USER registry key\n" ); free( current_user_path ); - strcpy( p, "/user.reg" ); - load_init_registry_from_file( filename, key ); + load_init_registry_from_file( "user.reg", key ); release_object( key );
- free( filename ); - /* start the periodic save timer */ set_periodic_save_timer(); + + /* go back to the server dir */ + if (fchdir( server_dir_fd ) == -1) fatal_perror( "chdir to server dir" ); }
/* save a registry branch to a file */ @@ -1532,8 +1526,8 @@ static void save_registry( struct key *key, obj_handle_t handle ) static int save_branch( struct key *key, const char *path ) { struct stat st; - char *p, *real, *tmp = NULL; - int fd, count = 0, ret = 0, by_symlink; + char *p, *tmp = NULL; + int fd, count = 0, ret = 0; FILE *f;
if (!(key->flags & KEY_DIRTY)) @@ -1542,25 +1536,13 @@ static int save_branch( struct key *key, const char *path ) return 1; }
- /* get the real path */ - - by_symlink = (!lstat(path, &st) && S_ISLNK (st.st_mode)); - if (!(real = malloc( PATH_MAX ))) return 0; - if (!realpath( path, real )) - { - free( real ); - real = NULL; - } - else path = real; - /* test the file type */
if ((fd = open( path, O_WRONLY )) != -1) { /* if file is not a regular file or has multiple links or is accessed * via symbolic links, write directly into it; otherwise use a temp file */ - if (by_symlink || - (!fstat( fd, &st ) && (!S_ISREG(st.st_mode) || st.st_nlink > 1))) + if (!lstat( path, &st ) && (!S_ISREG(st.st_mode) || st.st_nlink > 1)) { ftruncate( fd, 0 ); goto save; @@ -1610,7 +1592,6 @@ static int save_branch( struct key *key, const char *path )
done: free( tmp ); - free( real ); if (ret) make_clean( key ); return ret; } @@ -1620,9 +1601,11 @@ static void periodic_save( void *arg ) { int i;
+ if (fchdir( config_dir_fd ) == -1) return; save_timeout_user = NULL; for (i = 0; i < save_branch_count; i++) save_branch( save_branch_info[i].key, save_branch_info[i].path ); + if (fchdir( server_dir_fd ) == -1) fatal_perror( "chdir to server dir" ); set_periodic_save_timer(); }
@@ -1638,6 +1621,7 @@ void flush_registry(void) { int i;
+ if (fchdir( config_dir_fd ) == -1) return; for (i = 0; i < save_branch_count; i++) { if (!save_branch( save_branch_info[i].key, save_branch_info[i].path )) @@ -1647,6 +1631,7 @@ void flush_registry(void) perror( " " ); } } + if (fchdir( server_dir_fd ) == -1) fatal_perror( "chdir to server dir" ); }
diff --git a/server/request.c b/server/request.c index 9a2c7b1..8726e1c 100644 --- a/server/request.c +++ b/server/request.c @@ -120,6 +120,8 @@ static const struct fd_ops master_socket_fd_ops = struct thread *current = NULL; /* thread handling the current request */ unsigned int global_error = 0; /* global error code for when no thread is current */ timeout_t server_start_time = 0; /* server startup time */ +int server_dir_fd = -1; /* file descriptor for the server dir */ +int config_dir_fd = -1; /* file descriptor for the config dir */
static struct master_socket *master_socket; /* the master socket object */ static struct timeout_user *master_timeout; @@ -553,7 +555,8 @@ static void create_server_dir( const char *dir ) create_dir( server_dir, &st );
if (chdir( server_dir ) == -1) fatal_perror( "chdir %s", server_dir ); - if (stat( ".", &st2 ) == -1) fatal_perror( "stat %s", server_dir ); + if ((server_dir_fd = open( ".", O_RDONLY )) == -1) fatal_perror( "open %s", server_dir ); + if (fstat( server_dir_fd, &st2 ) == -1) fatal_perror( "stat %s", server_dir ); if (st.st_dev != st2.st_dev || st.st_ino != st2.st_ino) fatal_error( "chdir did not end up in %s\n", server_dir );
@@ -733,6 +736,7 @@ static void acquire_lock(void) void open_master_socket(void) { const char *server_dir = wine_get_server_dir(); + const char *config_dir = wine_get_config_dir(); int fd, pid, status, sync_pipe[2]; char dummy;
@@ -740,7 +744,10 @@ void open_master_socket(void) assert( sizeof(union generic_request) == sizeof(struct request_max_size) ); assert( sizeof(union generic_reply) == sizeof(struct request_max_size) );
- if (!server_dir) fatal_error( "directory %s cannot be accessed\n", wine_get_config_dir() ); + if (!server_dir) fatal_error( "directory %s cannot be accessed\n", config_dir ); + if (chdir( config_dir ) == -1) fatal_perror( "chdir to %s", config_dir ); + if ((config_dir_fd = open( ".", O_RDONLY )) == -1) fatal_perror( "open %s", config_dir ); + create_server_dir( server_dir );
if (!foreground) diff --git a/server/request.h b/server/request.h index 283ad97..496c5ff 100644 --- a/server/request.h +++ b/server/request.h @@ -61,6 +61,7 @@ extern void close_master_socket( timeout_t timeout ); extern void shutdown_master_socket(void); extern int wait_for_lock(void); extern int kill_lock_owner( int sig ); +extern int server_dir_fd, config_dir_fd;
extern void trace_request(void); extern void trace_reply( enum request req, const union generic_reply *reply );