Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
f5ba1c21
Commit
f5ba1c21
authored
Mar 10, 2008
by
Lei Zhang
Committed by
Alexandre Julliard
Mar 12, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shell32: Add xdg-user-dirs lookup code.
parent
371afffd
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
256 additions
and
0 deletions
+256
-0
xdg.c
dlls/shell32/xdg.c
+255
-0
xdg.h
dlls/shell32/xdg.h
+1
-0
No files found.
dlls/shell32/xdg.c
View file @
f5ba1c21
...
...
@@ -16,10 +16,38 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
*
* XDG_UserDirLookup() and helper functions are based on code from:
* http://www.freedesktop.org/wiki/Software/xdg-user-dirs
*
* Copyright (c) 2007 Red Hat, inc
*
* From the xdg-user-dirs license:
* 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.
*/
#include "config.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
...
...
@@ -712,3 +740,230 @@ char *XDG_GetStringValue(XDG_PARSED_FILE *file, const char *group_name, const ch
return
NULL
;
}
/* Get the name of the xdg configuration file.
*
* [in] home_dir - $HOME
* [out] config_file - the name of the configuration file
*/
static
HRESULT
get_xdg_config_file
(
char
*
home_dir
,
char
**
config_file
)
{
char
*
config_home
;
config_home
=
getenv
(
"XDG_CONFIG_HOME"
);
if
(
!
config_home
||
!
config_home
[
0
])
{
*
config_file
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strlen
(
home_dir
)
+
strlen
(
"/.config/user-dirs.dirs"
)
+
1
);
if
(
!*
config_file
)
return
E_OUTOFMEMORY
;
strcpy
(
*
config_file
,
home_dir
);
strcat
(
*
config_file
,
"/.config/user-dirs.dirs"
);
}
else
{
*
config_file
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strlen
(
config_home
)
+
strlen
(
"/user-dirs.dirs"
)
+
1
);
if
(
!*
config_file
)
return
E_OUTOFMEMORY
;
strcpy
(
*
config_file
,
config_home
);
strcat
(
*
config_file
,
"/user-dirs.dirs"
);
}
return
S_OK
;
}
/* Parse the key in a line in the xdg-user-dir config file.
* i.e. XDG_PICTURES_DIR="$HOME/Pictures"
* ^ ^
*
* [in] xdg_dirs - array of xdg directories to look for
* [in] num_dirs - number of elements in xdg_dirs
* [in/out] p_ptr - pointer to where we are in the buffer
* Returns the index to xdg_dirs if we find the key, or -1 on error.
*/
static
int
parse_config1
(
const
char
**
xdg_dirs
,
const
unsigned
int
num_dirs
,
char
**
p_ptr
)
{
char
*
p
;
int
i
;
p
=
*
p_ptr
;
while
(
*
p
==
' '
||
*
p
==
'\t'
)
p
++
;
if
(
strncmp
(
p
,
"XDG_"
,
4
))
return
-
1
;
p
+=
4
;
for
(
i
=
0
;
i
<
num_dirs
;
i
++
)
{
if
(
!
strncmp
(
p
,
xdg_dirs
[
i
],
strlen
(
xdg_dirs
[
i
])))
{
p
+=
strlen
(
xdg_dirs
[
i
]);
break
;
}
}
if
(
i
==
num_dirs
)
return
-
1
;
if
(
strncmp
(
p
,
"_DIR"
,
4
))
return
-
1
;
p
+=
4
;
while
(
*
p
==
' '
||
*
p
==
'\t'
)
p
++
;
if
(
*
p
!=
'='
)
return
-
1
;
p
++
;
while
(
*
p
==
' '
||
*
p
==
'\t'
)
p
++
;
if
(
*
p
!=
'"'
)
return
-
1
;
p
++
;
*
p_ptr
=
p
;
return
i
;
}
/* Parse the value in a line in the xdg-user-dir config file.
* i.e. XDG_PICTURES_DIR="$HOME/Pictures"
* ^ ^
*
* [in] p - pointer to the buffer
* [in] home_dir - $HOME
* [out] out_ptr - the directory name
*/
static
HRESULT
parse_config2
(
char
*
p
,
const
char
*
home_dir
,
char
**
out_ptr
)
{
BOOL
relative
;
char
*
out
,
*
d
;
relative
=
FALSE
;
if
(
!
strncmp
(
p
,
"$HOME/"
,
6
))
{
p
+=
6
;
relative
=
TRUE
;
}
else
if
(
*
p
!=
'/'
)
return
E_FAIL
;
if
(
relative
)
{
out
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strlen
(
home_dir
)
+
strlen
(
p
)
+
2
);
if
(
!
out
)
return
E_OUTOFMEMORY
;
strcpy
(
out
,
home_dir
);
strcat
(
out
,
"/"
);
}
else
{
out
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strlen
(
p
)
+
1
);
if
(
!
out
)
return
E_OUTOFMEMORY
;
*
out
=
0
;
}
d
=
out
+
strlen
(
out
);
while
(
*
p
&&
*
p
!=
'"'
)
{
if
((
*
p
==
'\\'
)
&&
(
*
(
p
+
1
)
!=
0
))
p
++
;
*
d
++
=
*
p
++
;
}
*
d
=
0
;
*
out_ptr
=
out
;
return
S_OK
;
}
/* Parse part of a line in the xdg-user-dir config file.
* i.e. XDG_PICTURES_DIR="$HOME/Pictures"
* ^ ^
*
* The calling function is responsible for freeing all elements of out_ptr as
* well as out_ptr itself.
*
* [in] xdg_dirs - array of xdg directories to look for
* [in] num_dirs - number of elements in xdg_dirs
* [out] out_ptr - an array of the xdg directories names
*/
HRESULT
XDG_UserDirLookup
(
const
char
**
xdg_dirs
,
const
unsigned
int
num_dirs
,
char
***
out_ptr
)
{
FILE
*
file
;
char
**
out
;
char
*
home_dir
,
*
config_file
;
char
buffer
[
512
];
int
i
,
len
;
HRESULT
hr
;
*
out_ptr
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
num_dirs
*
sizeof
(
char
*
));
out
=
*
out_ptr
;
if
(
!
out
)
return
E_OUTOFMEMORY
;
home_dir
=
getenv
(
"HOME"
);
if
(
!
home_dir
)
{
hr
=
E_FAIL
;
goto
xdg_user_dir_lookup_error
;
}
hr
=
get_xdg_config_file
(
home_dir
,
&
config_file
);
if
(
FAILED
(
hr
))
goto
xdg_user_dir_lookup_error
;
file
=
fopen
(
config_file
,
"r"
);
HeapFree
(
GetProcessHeap
(),
0
,
config_file
);
if
(
!
file
)
{
hr
=
E_HANDLE
;
goto
xdg_user_dir_lookup_error
;
}
while
(
fgets
(
buffer
,
sizeof
(
buffer
),
file
))
{
int
idx
;
char
*
p
;
/* Remove newline at end */
len
=
strlen
(
buffer
);
if
(
len
>
0
&&
buffer
[
len
-
1
]
==
'\n'
)
buffer
[
len
-
1
]
=
0
;
/* Parse the key */
p
=
buffer
;
idx
=
parse_config1
(
xdg_dirs
,
num_dirs
,
&
p
);
if
(
idx
<
0
)
continue
;
if
(
out
[
idx
])
continue
;
/* Parse the value */
hr
=
parse_config2
(
p
,
home_dir
,
&
out
[
idx
]);
if
(
FAILED
(
hr
))
{
if
(
hr
==
E_OUTOFMEMORY
)
goto
xdg_user_dir_lookup_error
;
continue
;
}
}
hr
=
S_OK
;
/* Remove entries for directories that do no exist */
for
(
i
=
0
;
i
<
num_dirs
;
i
++
)
{
struct
stat
statFolder
;
if
(
!
out
[
i
])
continue
;
if
(
!
stat
(
out
[
i
],
&
statFolder
)
&&
S_ISDIR
(
statFolder
.
st_mode
))
continue
;
HeapFree
(
GetProcessHeap
(),
0
,
out
[
i
]);
out
[
i
]
=
NULL
;
}
xdg_user_dir_lookup_error:
if
(
FAILED
(
hr
))
{
for
(
i
=
0
;
i
<
num_dirs
;
i
++
)
HeapFree
(
GetProcessHeap
(),
0
,
out
[
i
]);
HeapFree
(
GetProcessHeap
(),
0
,
out_ptr
);
}
return
hr
;
}
dlls/shell32/xdg.h
View file @
f5ba1c21
...
...
@@ -47,5 +47,6 @@ HRESULT TRASH_UnpackItemID(LPCSHITEMID id, TRASH_ELEMENT *element, WIN32_FIND_DA
HRESULT
TRASH_EnumItems
(
LPITEMIDLIST
**
pidls
,
int
*
count
);
void
TRASH_DisposeElement
(
TRASH_ELEMENT
*
element
);
HRESULT
XDG_UserDirLookup
(
const
char
**
xdg_dirs
,
const
unsigned
int
num_dirs
,
char
***
out_ptr
);
#endif
/* ndef __XDG_H__ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment