зеркало из https://github.com/mozilla/pjs.git
Bug 399500 - "support XDG user dirs in the directory service" [p=chpe@gnome.org (Christian Persch) r=caillon sr=bsmedberg a1.9=damons]
This commit is contained in:
Родитель
1a0b827211
Коммит
bd2f12ba01
|
@ -238,6 +238,222 @@ GetUnixHomeDir(nsILocalFile** aFile)
|
|||
PR_TRUE, aFile);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
The following licence applies to the xdg_user_dir_lookup function:
|
||||
|
||||
Copyright (c) 2007 Red Hat, inc
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
static char *
|
||||
xdg_user_dir_lookup (const char *type)
|
||||
{
|
||||
FILE *file;
|
||||
char *home_dir, *config_home, *config_file;
|
||||
char buffer[512];
|
||||
char *user_dir;
|
||||
char *p, *d;
|
||||
int len;
|
||||
int relative;
|
||||
|
||||
home_dir = getenv ("HOME");
|
||||
|
||||
if (home_dir == NULL)
|
||||
goto error;
|
||||
|
||||
config_home = getenv ("XDG_CONFIG_HOME");
|
||||
if (config_home == NULL || config_home[0] == 0)
|
||||
{
|
||||
config_file = (char*) malloc (strlen (home_dir) + strlen ("/.config/user-dirs.dirs") + 1);
|
||||
if (config_file == NULL)
|
||||
goto error;
|
||||
|
||||
strcpy (config_file, home_dir);
|
||||
strcat (config_file, "/.config/user-dirs.dirs");
|
||||
}
|
||||
else
|
||||
{
|
||||
config_file = (char*) malloc (strlen (config_home) + strlen ("/user-dirs.dirs") + 1);
|
||||
if (config_file == NULL)
|
||||
goto error;
|
||||
|
||||
strcpy (config_file, config_home);
|
||||
strcat (config_file, "/user-dirs.dirs");
|
||||
}
|
||||
|
||||
file = fopen (config_file, "r");
|
||||
free (config_file);
|
||||
if (file == NULL)
|
||||
goto error;
|
||||
|
||||
user_dir = NULL;
|
||||
while (fgets (buffer, sizeof (buffer), file))
|
||||
{
|
||||
/* Remove newline at end */
|
||||
len = strlen (buffer);
|
||||
if (len > 0 && buffer[len-1] == '\n')
|
||||
buffer[len-1] = 0;
|
||||
|
||||
p = buffer;
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
|
||||
if (strncmp (p, "XDG_", 4) != 0)
|
||||
continue;
|
||||
p += 4;
|
||||
if (strncmp (p, type, strlen (type)) != 0)
|
||||
continue;
|
||||
p += strlen (type);
|
||||
if (strncmp (p, "_DIR", 4) != 0)
|
||||
continue;
|
||||
p += 4;
|
||||
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
|
||||
if (*p != '=')
|
||||
continue;
|
||||
p++;
|
||||
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
|
||||
if (*p != '"')
|
||||
continue;
|
||||
p++;
|
||||
|
||||
relative = 0;
|
||||
if (strncmp (p, "$HOME/", 6) == 0)
|
||||
{
|
||||
p += 6;
|
||||
relative = 1;
|
||||
}
|
||||
else if (*p != '/')
|
||||
continue;
|
||||
|
||||
if (relative)
|
||||
{
|
||||
user_dir = (char*) malloc (strlen (home_dir) + 1 + strlen (p) + 1);
|
||||
if (user_dir == NULL)
|
||||
goto error2;
|
||||
|
||||
strcpy (user_dir, home_dir);
|
||||
strcat (user_dir, "/");
|
||||
}
|
||||
else
|
||||
{
|
||||
user_dir = (char*) malloc (strlen (p) + 1);
|
||||
if (user_dir == NULL)
|
||||
goto error2;
|
||||
|
||||
*user_dir = 0;
|
||||
}
|
||||
|
||||
d = user_dir + strlen (user_dir);
|
||||
while (*p && *p != '"')
|
||||
{
|
||||
if ((*p == '\\') && (*(p+1) != 0))
|
||||
p++;
|
||||
*d++ = *p++;
|
||||
}
|
||||
*d = 0;
|
||||
}
|
||||
error2:
|
||||
fclose (file);
|
||||
|
||||
if (user_dir)
|
||||
return user_dir;
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char xdg_user_dirs[] =
|
||||
"DESKTOP\0"
|
||||
"DOCUMENTS\0"
|
||||
"DOWNLOAD\0"
|
||||
"MUSIC\0"
|
||||
"PICTURES\0"
|
||||
"PUBLICSHARE\0"
|
||||
"TEMPLATES\0"
|
||||
"VIDEOS";
|
||||
|
||||
static const PRUint8 xdg_user_dir_offsets[] = {
|
||||
0,
|
||||
8,
|
||||
18,
|
||||
27,
|
||||
33,
|
||||
42,
|
||||
54,
|
||||
64
|
||||
};
|
||||
|
||||
static nsresult
|
||||
GetUnixXDGUserDirectory(SystemDirectories aSystemDirectory,
|
||||
nsILocalFile** aFile)
|
||||
{
|
||||
char *dir = xdg_user_dir_lookup
|
||||
(xdg_user_dirs + xdg_user_dir_offsets[aSystemDirectory -
|
||||
Unix_XDG_Desktop]);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsILocalFile> file;
|
||||
if (dir) {
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(dir), PR_TRUE,
|
||||
getter_AddRefs(file));
|
||||
free(dir);
|
||||
} else if (Unix_XDG_Desktop == aSystemDirectory) {
|
||||
// for the XDG desktop dir, fall back to HOME/Desktop
|
||||
// (for historical compatibility)
|
||||
rv = GetUnixHomeDir(getter_AddRefs(file));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = file->AppendNative(NS_LITERAL_CSTRING("Desktop"));
|
||||
} else {
|
||||
// no fallback for the other XDG dirs
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
PRBool exists;
|
||||
rv = file->Exists(&exists);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (!exists) {
|
||||
rv = file->Create(nsIFile::DIRECTORY_TYPE, 0755);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
*aFile = nsnull;
|
||||
file.swap(*aFile);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
|
@ -575,25 +791,15 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|||
case Unix_HomeDirectory:
|
||||
return GetUnixHomeDir(aFile);
|
||||
|
||||
case Unix_DesktopDirectory:
|
||||
{
|
||||
nsCOMPtr<nsILocalFile> home;
|
||||
nsresult rv = GetUnixHomeDir(getter_AddRefs(home));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = home->AppendNative(NS_LITERAL_CSTRING("Desktop"));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
PRBool exists;
|
||||
rv = home->Exists(&exists);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (!exists)
|
||||
return GetUnixHomeDir(aFile);
|
||||
|
||||
NS_ADDREF(*aFile = home);
|
||||
return NS_OK;
|
||||
}
|
||||
case Unix_XDG_Desktop:
|
||||
case Unix_XDG_Documents:
|
||||
case Unix_XDG_Download:
|
||||
case Unix_XDG_Music:
|
||||
case Unix_XDG_Pictures:
|
||||
case Unix_XDG_PublicShare:
|
||||
case Unix_XDG_Templates:
|
||||
case Unix_XDG_Videos:
|
||||
return GetUnixXDGUserDirectory(aSystemSystemDirectory, aFile);
|
||||
#endif
|
||||
|
||||
#ifdef XP_BEOS
|
||||
|
|
|
@ -114,8 +114,15 @@ enum SystemDirectories {
|
|||
Unix_LocalDirectory = 301,
|
||||
Unix_LibDirectory = 302,
|
||||
Unix_HomeDirectory = 303,
|
||||
Unix_DesktopDirectory = 304,
|
||||
|
||||
Unix_XDG_Desktop = 304,
|
||||
Unix_XDG_Documents = 305,
|
||||
Unix_XDG_Download = 306,
|
||||
Unix_XDG_Music = 307,
|
||||
Unix_XDG_Pictures = 308,
|
||||
Unix_XDG_PublicShare = 309,
|
||||
Unix_XDG_Templates = 310,
|
||||
Unix_XDG_Videos = 311,
|
||||
|
||||
BeOS_SettingsDirectory = 401,
|
||||
BeOS_HomeDirectory = 402,
|
||||
BeOS_DesktopDirectory = 403,
|
||||
|
|
|
@ -358,6 +358,15 @@ nsIAtom* nsDirectoryService::sDefaultDownloadDirectory = nsnull;
|
|||
#elif defined (XP_UNIX)
|
||||
nsIAtom* nsDirectoryService::sLocalDirectory = nsnull;
|
||||
nsIAtom* nsDirectoryService::sLibDirectory = nsnull;
|
||||
nsIAtom* nsDirectoryService::sDefaultDownloadDirectory = nsnull;
|
||||
nsIAtom* nsDirectoryService::sXDGDesktop = nsnull;
|
||||
nsIAtom* nsDirectoryService::sXDGDocuments = nsnull;
|
||||
nsIAtom* nsDirectoryService::sXDGDownload = nsnull;
|
||||
nsIAtom* nsDirectoryService::sXDGMusic = nsnull;
|
||||
nsIAtom* nsDirectoryService::sXDGPictures = nsnull;
|
||||
nsIAtom* nsDirectoryService::sXDGPublicShare = nsnull;
|
||||
nsIAtom* nsDirectoryService::sXDGTemplates = nsnull;
|
||||
nsIAtom* nsDirectoryService::sXDGVideos = nsnull;
|
||||
#elif defined (XP_OS2)
|
||||
nsIAtom* nsDirectoryService::sSystemDirectory = nsnull;
|
||||
nsIAtom* nsDirectoryService::sOS2Directory = nsnull;
|
||||
|
@ -465,6 +474,15 @@ static const nsStaticAtom directory_atoms[] = {
|
|||
#elif defined (XP_UNIX)
|
||||
{ NS_UNIX_LOCAL_DIR, &nsDirectoryService::sLocalDirectory },
|
||||
{ NS_UNIX_LIB_DIR, &nsDirectoryService::sLibDirectory },
|
||||
{ NS_UNIX_DEFAULT_DOWNLOAD_DIR, &nsDirectoryService::sDefaultDownloadDirectory },
|
||||
{ NS_UNIX_XDG_DESKTOP_DIR, &nsDirectoryService::sXDGDesktop },
|
||||
{ NS_UNIX_XDG_DOCUMENTS_DIR, &nsDirectoryService::sXDGDocuments },
|
||||
{ NS_UNIX_XDG_DOWNLOAD_DIR, &nsDirectoryService::sXDGDownload },
|
||||
{ NS_UNIX_XDG_MUSIC_DIR, &nsDirectoryService::sXDGMusic },
|
||||
{ NS_UNIX_XDG_PICTURES_DIR, &nsDirectoryService::sXDGPictures },
|
||||
{ NS_UNIX_XDG_PUBLIC_SHARE_DIR, &nsDirectoryService::sXDGPublicShare },
|
||||
{ NS_UNIX_XDG_TEMPLATES_DIR, &nsDirectoryService::sXDGTemplates },
|
||||
{ NS_UNIX_XDG_VIDEOS_DIR, &nsDirectoryService::sXDGVideos },
|
||||
#elif defined (XP_OS2)
|
||||
{ NS_OS_SYSTEM_DIR, &nsDirectoryService::sSystemDirectory },
|
||||
{ NS_OS2_DIR, &nsDirectoryService::sOS2Directory },
|
||||
|
@ -1150,9 +1168,47 @@ nsDirectoryService::GetFile(const char *prop, PRBool *persistent, nsIFile **_ret
|
|||
{
|
||||
rv = GetSpecialSystemDirectory(Unix_HomeDirectory, getter_AddRefs(localFile));
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sOS_DesktopDirectory)
|
||||
else if (inAtom == nsDirectoryService::sXDGDesktop ||
|
||||
inAtom == nsDirectoryService::sOS_DesktopDirectory)
|
||||
{
|
||||
rv = GetSpecialSystemDirectory(Unix_DesktopDirectory, getter_AddRefs(localFile));
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Desktop, getter_AddRefs(localFile));
|
||||
*persistent = PR_FALSE;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGDocuments)
|
||||
{
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Documents, getter_AddRefs(localFile));
|
||||
*persistent = PR_FALSE;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGDownload ||
|
||||
inAtom == nsDirectoryService::sDefaultDownloadDirectory)
|
||||
{
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Download, getter_AddRefs(localFile));
|
||||
*persistent = PR_FALSE;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGMusic)
|
||||
{
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Music, getter_AddRefs(localFile));
|
||||
*persistent = PR_FALSE;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGPictures)
|
||||
{
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Pictures, getter_AddRefs(localFile));
|
||||
*persistent = PR_FALSE;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGPublicShare)
|
||||
{
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_PublicShare, getter_AddRefs(localFile));
|
||||
*persistent = PR_FALSE;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGTemplates)
|
||||
{
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Templates, getter_AddRefs(localFile));
|
||||
*persistent = PR_FALSE;
|
||||
}
|
||||
else if (inAtom == nsDirectoryService::sXDGVideos)
|
||||
{
|
||||
rv = GetSpecialSystemDirectory(Unix_XDG_Videos, getter_AddRefs(localFile));
|
||||
*persistent = PR_FALSE;
|
||||
}
|
||||
#elif defined (XP_OS2)
|
||||
else if (inAtom == nsDirectoryService::sSystemDirectory)
|
||||
|
|
|
@ -160,6 +160,15 @@ public:
|
|||
#elif defined (XP_UNIX)
|
||||
static nsIAtom *sLocalDirectory;
|
||||
static nsIAtom *sLibDirectory;
|
||||
static nsIAtom *sXDGDesktop;
|
||||
static nsIAtom *sXDGDocuments;
|
||||
static nsIAtom *sXDGDownload;
|
||||
static nsIAtom *sXDGMusic;
|
||||
static nsIAtom *sXDGPictures;
|
||||
static nsIAtom *sXDGPublicShare;
|
||||
static nsIAtom *sXDGTemplates;
|
||||
static nsIAtom *sXDGVideos;
|
||||
static nsIAtom *sDefaultDownloadDirectory;
|
||||
#elif defined (XP_OS2)
|
||||
static nsIAtom *sSystemDirectory;
|
||||
static nsIAtom *sOS2Directory;
|
||||
|
|
|
@ -186,6 +186,14 @@
|
|||
#define NS_UNIX_LOCAL_DIR "Locl"
|
||||
#define NS_UNIX_LIB_DIR "LibD"
|
||||
#define NS_UNIX_HOME_DIR NS_OS_HOME_DIR
|
||||
#define NS_UNIX_XDG_DESKTOP_DIR "XDGDesk"
|
||||
#define NS_UNIX_XDG_DOCUMENTS_DIR "XDGDocs"
|
||||
#define NS_UNIX_XDG_DOWNLOAD_DIR "XDGDwnld"
|
||||
#define NS_UNIX_XDG_MUSIC_DIR "XDGMusic"
|
||||
#define NS_UNIX_XDG_PICTURES_DIR "XDGPict"
|
||||
#define NS_UNIX_XDG_PUBLIC_SHARE_DIR "XDGPubSh"
|
||||
#define NS_UNIX_XDG_TEMPLATES_DIR "XDGTempl"
|
||||
#define NS_UNIX_XDG_VIDEOS_DIR "XDGVids"
|
||||
#elif defined (XP_OS2)
|
||||
#define NS_OS2_DIR "OS2Dir"
|
||||
#define NS_OS2_HOME_DIR NS_OS_HOME_DIR
|
||||
|
|
Загрузка…
Ссылка в новой задаче