Initial support for automatically creating the ~/.wine directory on
startup.
This commit is contained in:
parent
d053539f7d
commit
04869eb658
|
@ -23,9 +23,11 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -48,7 +50,6 @@
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#include "ntstatus.h"
|
#include "ntstatus.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
@ -622,6 +623,116 @@ static int server_connect( const char *oldcwd, const char *serverdir )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* rm_rf
|
||||||
|
*
|
||||||
|
* Remove a directory and all its contents; helper for create_config_dir.
|
||||||
|
*/
|
||||||
|
static void rm_rf( const char *path )
|
||||||
|
{
|
||||||
|
int err = errno; /* preserve errno */
|
||||||
|
DIR *dir;
|
||||||
|
char *buffer, *p;
|
||||||
|
struct stat st;
|
||||||
|
struct dirent *de;
|
||||||
|
|
||||||
|
if (!(buffer = malloc( strlen(path) + 256 + 1 ))) goto done;
|
||||||
|
strcpy( buffer, path );
|
||||||
|
p = buffer + strlen(buffer);
|
||||||
|
*p++ = '/';
|
||||||
|
|
||||||
|
if ((dir = opendir( path )))
|
||||||
|
{
|
||||||
|
while ((de = readdir( dir )))
|
||||||
|
{
|
||||||
|
if (!strcmp( de->d_name, "." ) || !strcmp( de->d_name, ".." )) continue;
|
||||||
|
strcpy( p, de->d_name );
|
||||||
|
if (unlink( buffer ) != -1) continue;
|
||||||
|
if (errno == EISDIR ||
|
||||||
|
(errno == EPERM && !lstat( buffer, &st ) && S_ISDIR(st.st_mode)))
|
||||||
|
{
|
||||||
|
/* recurse in the sub-directory */
|
||||||
|
rm_rf( buffer );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir( dir );
|
||||||
|
}
|
||||||
|
free( buffer );
|
||||||
|
rmdir( path );
|
||||||
|
done:
|
||||||
|
errno = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* create_config_dir
|
||||||
|
*
|
||||||
|
* Create the wine configuration dir (~/.wine).
|
||||||
|
*/
|
||||||
|
static void create_config_dir(void)
|
||||||
|
{
|
||||||
|
const char *config_dir = wine_get_config_dir();
|
||||||
|
char *tmp_dir;
|
||||||
|
int fd;
|
||||||
|
pid_t pid, wret;
|
||||||
|
|
||||||
|
if (!(tmp_dir = malloc( strlen(config_dir) + sizeof("-XXXXXX") )))
|
||||||
|
fatal_error( "out of memory\n" );
|
||||||
|
strcpy( tmp_dir, config_dir );
|
||||||
|
strcat( tmp_dir, "-XXXXXX" );
|
||||||
|
if ((fd = mkstemps( tmp_dir, 0 )) == -1)
|
||||||
|
fatal_perror( "can't get temp file name for %s", config_dir );
|
||||||
|
close( fd );
|
||||||
|
unlink( tmp_dir );
|
||||||
|
if (mkdir( tmp_dir, 0777 ) == -1)
|
||||||
|
fatal_perror( "cannot create temp dir %s", tmp_dir );
|
||||||
|
|
||||||
|
MESSAGE( "wine: creating configuration directory '%s'...\n", config_dir );
|
||||||
|
pid = fork();
|
||||||
|
if (pid == -1)
|
||||||
|
{
|
||||||
|
rmdir( tmp_dir );
|
||||||
|
fatal_perror( "fork" );
|
||||||
|
}
|
||||||
|
if (!pid)
|
||||||
|
{
|
||||||
|
const char *argv[5];
|
||||||
|
|
||||||
|
argv[0] = "wineprefixcreate";
|
||||||
|
argv[1] = "--quiet";
|
||||||
|
argv[2] = "--prefix";
|
||||||
|
argv[3] = tmp_dir;
|
||||||
|
argv[4] = NULL;
|
||||||
|
wine_exec_wine_binary( argv[0], (char **)argv, NULL );
|
||||||
|
rmdir( tmp_dir );
|
||||||
|
fatal_perror( "could not exec wineprefixcreate" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
while ((wret = waitpid( pid, &status, 0 )) != pid)
|
||||||
|
{
|
||||||
|
if (wret == -1 && errno != EINTR) fatal_perror( "wait4" );
|
||||||
|
}
|
||||||
|
if (!WIFEXITED(status) || WEXITSTATUS(status))
|
||||||
|
{
|
||||||
|
rm_rf( tmp_dir );
|
||||||
|
fatal_error( "wineprefixcreate failed while creating '%s'.\n", config_dir );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rename( tmp_dir, config_dir ) == -1)
|
||||||
|
{
|
||||||
|
rm_rf( tmp_dir );
|
||||||
|
if (errno != EEXIST && errno != ENOTEMPTY)
|
||||||
|
fatal_perror( "rename '%s' to '%s'", tmp_dir, config_dir );
|
||||||
|
/* else it was probably created by a concurrent wine process */
|
||||||
|
}
|
||||||
|
free( tmp_dir );
|
||||||
|
MESSAGE( "wine: '%s' created successfully.\n", config_dir );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* server_init_process
|
* server_init_process
|
||||||
*
|
*
|
||||||
|
@ -632,6 +743,13 @@ void server_init_process(void)
|
||||||
int size;
|
int size;
|
||||||
char *oldcwd;
|
char *oldcwd;
|
||||||
obj_handle_t dummy_handle;
|
obj_handle_t dummy_handle;
|
||||||
|
const char *server_dir = wine_get_server_dir();
|
||||||
|
|
||||||
|
if (!server_dir) /* this means the config dir doesn't exist */
|
||||||
|
{
|
||||||
|
create_config_dir();
|
||||||
|
server_dir = wine_get_server_dir();
|
||||||
|
}
|
||||||
|
|
||||||
/* retrieve the current directory */
|
/* retrieve the current directory */
|
||||||
for (size = 512; ; size *= 2)
|
for (size = 512; ; size *= 2)
|
||||||
|
@ -645,7 +763,7 @@ void server_init_process(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* connect to the server */
|
/* connect to the server */
|
||||||
fd_socket = server_connect( oldcwd, wine_get_server_dir() );
|
fd_socket = server_connect( oldcwd, server_dir );
|
||||||
|
|
||||||
/* switch back to the starting directory */
|
/* switch back to the starting directory */
|
||||||
if (oldcwd)
|
if (oldcwd)
|
||||||
|
|
|
@ -33,10 +33,11 @@
|
||||||
#ifdef HAVE_PWD_H
|
#ifdef HAVE_PWD_H
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "wine/library.h"
|
||||||
|
|
||||||
static const char * const server_config_dir = "/.wine"; /* config dir relative to $HOME */
|
static const char server_config_dir[] = "/.wine"; /* config dir relative to $HOME */
|
||||||
static const char * const server_root_prefix = "/tmp/.wine-"; /* prefix for server root dir */
|
static const char server_root_prefix[] = "/tmp/.wine-"; /* prefix for server root dir */
|
||||||
static const char * const server_dir_prefix = "/server-"; /* prefix for server dir */
|
static const char server_dir_prefix[] = "/server-"; /* prefix for server dir */
|
||||||
|
|
||||||
static char *config_dir;
|
static char *config_dir;
|
||||||
static char *server_dir;
|
static char *server_dir;
|
||||||
|
@ -100,11 +101,40 @@ inline static void remove_trailing_slashes( char *path )
|
||||||
while (len > 1 && path[len-1] == '/') path[--len] = 0;
|
while (len > 1 && path[len-1] == '/') path[--len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* initialize the server directory value */
|
||||||
|
static void init_server_dir( dev_t dev, ino_t ino )
|
||||||
|
{
|
||||||
|
const char *user = wine_get_user_name();
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
server_dir = xmalloc( sizeof(server_root_prefix) + strlen(user) + sizeof(server_dir_prefix) +
|
||||||
|
2*sizeof(dev) + 2*sizeof(ino) );
|
||||||
|
strcpy( server_dir, server_root_prefix );
|
||||||
|
p = server_dir + sizeof(server_root_prefix) - 1;
|
||||||
|
strcpy( p, user );
|
||||||
|
while (*p)
|
||||||
|
{
|
||||||
|
if (*p == '/') *p = '!';
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
strcpy( p, server_dir_prefix );
|
||||||
|
p += sizeof(server_dir_prefix) - 1;
|
||||||
|
|
||||||
|
if (sizeof(dev) > sizeof(unsigned long) && dev > ~0UL)
|
||||||
|
sprintf( p, "%lx%08lx-", (unsigned long)(dev >> 32), (unsigned long)dev );
|
||||||
|
else
|
||||||
|
sprintf( p, "%lx-", (unsigned long)dev );
|
||||||
|
|
||||||
|
if (sizeof(ino) > sizeof(unsigned long) && ino > ~0UL)
|
||||||
|
sprintf( p, "%lx%08lx", (unsigned long)(ino >> 32), (unsigned long)ino );
|
||||||
|
else
|
||||||
|
sprintf( p, "%lx", (unsigned long)ino );
|
||||||
|
}
|
||||||
|
|
||||||
/* initialize all the paths values */
|
/* initialize all the paths values */
|
||||||
static void init_paths(void)
|
static void init_paths(void)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *p;
|
|
||||||
|
|
||||||
const char *home = getenv( "HOME" );
|
const char *home = getenv( "HOME" );
|
||||||
const char *user = NULL;
|
const char *user = NULL;
|
||||||
|
@ -139,46 +169,30 @@ static void init_paths(void)
|
||||||
if (config_dir[0] != '/')
|
if (config_dir[0] != '/')
|
||||||
fatal_error( "invalid directory %s in WINEPREFIX: not an absolute path\n", prefix );
|
fatal_error( "invalid directory %s in WINEPREFIX: not an absolute path\n", prefix );
|
||||||
if (stat( config_dir, &st ) == -1)
|
if (stat( config_dir, &st ) == -1)
|
||||||
fatal_perror( "cannot open %s as specified in WINEPREFIX", config_dir );
|
{
|
||||||
|
if (errno != ENOENT)
|
||||||
|
fatal_perror( "cannot open %s as specified in WINEPREFIX", config_dir );
|
||||||
|
fatal_error( "the '%s' directory specified in WINEPREFIX doesn't exist.\n"
|
||||||
|
"You may want to create it by running 'wineprefixcreate'.\n", config_dir );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!home) fatal_error( "could not determine your home directory\n" );
|
if (!home) fatal_error( "could not determine your home directory\n" );
|
||||||
if (home[0] != '/') fatal_error( "your home directory %s is not an absolute path\n", home );
|
if (home[0] != '/') fatal_error( "your home directory %s is not an absolute path\n", home );
|
||||||
config_dir = xmalloc( strlen(home) + strlen(server_config_dir) + 1 );
|
config_dir = xmalloc( strlen(home) + sizeof(server_config_dir) );
|
||||||
strcpy( config_dir, home );
|
strcpy( config_dir, home );
|
||||||
remove_trailing_slashes( config_dir );
|
remove_trailing_slashes( config_dir );
|
||||||
strcat( config_dir, server_config_dir );
|
strcat( config_dir, server_config_dir );
|
||||||
if (stat( config_dir, &st ) == -1)
|
if (stat( config_dir, &st ) == -1)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT) return; /* will be created later on */
|
||||||
fatal_perror( "cannot open %s", config_dir );
|
fatal_perror( "cannot open %s", config_dir );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!S_ISDIR(st.st_mode)) fatal_error( "%s is not a directory\n", config_dir );
|
if (!S_ISDIR(st.st_mode)) fatal_error( "%s is not a directory\n", config_dir );
|
||||||
|
|
||||||
/* build server_dir */
|
init_server_dir( st.st_dev, st.st_ino );
|
||||||
|
|
||||||
server_dir = xmalloc( strlen(server_root_prefix) + strlen(user) + strlen( server_dir_prefix ) +
|
|
||||||
2*sizeof(st.st_dev) + 2*sizeof(st.st_ino) + 2 );
|
|
||||||
strcpy( server_dir, server_root_prefix );
|
|
||||||
p = server_dir + strlen(server_dir);
|
|
||||||
strcpy( p, user );
|
|
||||||
while (*p)
|
|
||||||
{
|
|
||||||
if (*p == '/') *p = '!';
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
strcpy( p, server_dir_prefix );
|
|
||||||
|
|
||||||
if (sizeof(st.st_dev) > sizeof(unsigned long) && st.st_dev > ~0UL)
|
|
||||||
sprintf( server_dir + strlen(server_dir), "%lx%08lx-",
|
|
||||||
(unsigned long)(st.st_dev >> 32), (unsigned long)st.st_dev );
|
|
||||||
else
|
|
||||||
sprintf( server_dir + strlen(server_dir), "%lx-", (unsigned long)st.st_dev );
|
|
||||||
|
|
||||||
if (sizeof(st.st_ino) > sizeof(unsigned long) && st.st_ino > ~0UL)
|
|
||||||
sprintf( server_dir + strlen(server_dir), "%lx%08lx",
|
|
||||||
(unsigned long)(st.st_ino >> 32), (unsigned long)st.st_ino );
|
|
||||||
else
|
|
||||||
sprintf( server_dir + strlen(server_dir), "%lx", (unsigned long)st.st_ino );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize the argv0 path */
|
/* initialize the argv0 path */
|
||||||
|
@ -232,7 +246,21 @@ const char *wine_get_config_dir(void)
|
||||||
/* return the full name of the server directory (the one containing the socket) */
|
/* return the full name of the server directory (the one containing the socket) */
|
||||||
const char *wine_get_server_dir(void)
|
const char *wine_get_server_dir(void)
|
||||||
{
|
{
|
||||||
if (!server_dir) init_paths();
|
if (!server_dir)
|
||||||
|
{
|
||||||
|
if (!config_dir) init_paths();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat( config_dir, &st ) == -1)
|
||||||
|
{
|
||||||
|
if (errno != ENOENT) fatal_error( "cannot stat %s\n", config_dir );
|
||||||
|
return NULL; /* will have to try again once config_dir has been created */
|
||||||
|
}
|
||||||
|
init_server_dir( st.st_dev, st.st_ino );
|
||||||
|
}
|
||||||
|
}
|
||||||
return server_dir;
|
return server_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,11 @@ usage()
|
||||||
echo "Usage: $0 [options]"
|
echo "Usage: $0 [options]"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " --help Display this message"
|
echo " -h, --help Display this message"
|
||||||
echo " --prefix <dir> Prefix directory to create (defaults to \$WINEPREFIX or ~/.wine)"
|
echo " --prefix <dir> Directory to create (default: \$WINEPREFIX or ~/.wine)"
|
||||||
echo " --update Update the prefix directory if it already exists"
|
echo " -q, --quiet Don't print status messages"
|
||||||
echo " --use-wine-tree <dir> Run from the Wine source tree <dir>"
|
echo " -u, --update Update the prefix directory if it already exists"
|
||||||
|
echo " --use-wine-tree <dir> Run from the Wine source tree <dir>"
|
||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,11 +40,12 @@ dlldir="@dlldir@"
|
||||||
datadir="@datadir@/wine"
|
datadir="@datadir@/wine"
|
||||||
|
|
||||||
do_update=0
|
do_update=0
|
||||||
|
quiet=0
|
||||||
|
|
||||||
while [ $# -gt 0 ]
|
while [ $# -gt 0 ]
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--help)
|
-h|--help)
|
||||||
usage
|
usage
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
@ -51,10 +53,14 @@ do
|
||||||
WINEPREFIX="$2"
|
WINEPREFIX="$2"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
--update)
|
-u|--update)
|
||||||
do_update=1
|
do_update=1
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
-q|--quiet)
|
||||||
|
quiet=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--use-wine-tree)
|
--use-wine-tree)
|
||||||
topdir=`cd "$2" && pwd`
|
topdir=`cd "$2" && pwd`
|
||||||
if [ -x "$topdir/server/wineserver" ]
|
if [ -x "$topdir/server/wineserver" ]
|
||||||
|
@ -69,6 +75,7 @@ do
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
echo "Unknown option $1"
|
||||||
usage
|
usage
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
|
@ -77,19 +84,10 @@ done
|
||||||
|
|
||||||
WINEPREFIX="${WINEPREFIX:-$HOME/.wine}"
|
WINEPREFIX="${WINEPREFIX:-$HOME/.wine}"
|
||||||
|
|
||||||
if [ -d "$WINEPREFIX" ]
|
if [ -d "$WINEPREFIX" ] || mkdir "$WINEPREFIX"; then :
|
||||||
then
|
|
||||||
if [ $do_update = 0 ]
|
|
||||||
then
|
|
||||||
echo "The $WINEPREFIX directory already exists, aborting"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
if mkdir "$WINEPREFIX"; then :
|
echo "Could not create $WINEPREFIX, aborting"
|
||||||
else
|
exit 1
|
||||||
echo "Could not create $WINEPREFIX, aborting"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
WINEPREFIX=`cd "$WINEPREFIX" && pwd`
|
WINEPREFIX=`cd "$WINEPREFIX" && pwd`
|
||||||
|
@ -160,7 +158,13 @@ ${WINELOADER:-wine} rundll32.exe setupapi.dll,InstallHinfSection DefaultInstall
|
||||||
if [ $do_update = 0 ]
|
if [ $do_update = 0 ]
|
||||||
then
|
then
|
||||||
${WINESERVER:-wineserver} -w
|
${WINESERVER:-wineserver} -w
|
||||||
echo "$WINEPREFIX created successfully."
|
if [ $quiet = 0 ]
|
||||||
|
then
|
||||||
|
echo "$WINEPREFIX created successfully."
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
echo "$WINEPREFIX updated successfully."
|
if [ $quiet = 0 ]
|
||||||
|
then
|
||||||
|
echo "$WINEPREFIX updated successfully."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
Loading…
Reference in New Issue