Serenity Operating System
1/*
2 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
3 * Copyright (c) 2023, Linus Groh <linusg@serenityos.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <AK/DeprecatedString.h>
9#include <AK/LexicalPath.h>
10#include <AK/Platform.h>
11#include <AK/String.h>
12#include <AK/StringBuilder.h>
13#include <LibCore/SessionManagement.h>
14#include <LibCore/StandardPaths.h>
15#include <pwd.h>
16#include <stdlib.h>
17#include <unistd.h>
18
19namespace Core {
20
21DeprecatedString StandardPaths::home_directory()
22{
23 if (auto* home_env = getenv("HOME"))
24 return LexicalPath::canonicalized_path(home_env);
25
26 auto* pwd = getpwuid(getuid());
27 DeprecatedString path = pwd ? pwd->pw_dir : "/";
28 endpwent();
29 return LexicalPath::canonicalized_path(path);
30}
31
32DeprecatedString StandardPaths::desktop_directory()
33{
34 StringBuilder builder;
35 builder.append(home_directory());
36 builder.append("/Desktop"sv);
37 return LexicalPath::canonicalized_path(builder.to_deprecated_string());
38}
39
40DeprecatedString StandardPaths::documents_directory()
41{
42 StringBuilder builder;
43 builder.append(home_directory());
44 builder.append("/Documents"sv);
45 return LexicalPath::canonicalized_path(builder.to_deprecated_string());
46}
47
48DeprecatedString StandardPaths::downloads_directory()
49{
50 StringBuilder builder;
51 builder.append(home_directory());
52 builder.append("/Downloads"sv);
53 return LexicalPath::canonicalized_path(builder.to_deprecated_string());
54}
55
56DeprecatedString StandardPaths::config_directory()
57{
58 if (auto* config_directory = getenv("XDG_CONFIG_HOME"))
59 return LexicalPath::canonicalized_path(config_directory);
60
61 StringBuilder builder;
62 builder.append(home_directory());
63#if defined(AK_OS_MACOS)
64 builder.append("/Library/Preferences"sv);
65#else
66 builder.append("/.config"sv);
67#endif
68 return LexicalPath::canonicalized_path(builder.to_deprecated_string());
69}
70
71DeprecatedString StandardPaths::data_directory()
72{
73 if (auto* data_directory = getenv("XDG_DATA_HOME"))
74 return LexicalPath::canonicalized_path(data_directory);
75
76 StringBuilder builder;
77 builder.append(home_directory());
78#if defined(AK_OS_SERENITY)
79 builder.append("/.data"sv);
80#elif defined(AK_OS_MACOS)
81 builder.append("/Library/Application Support"sv);
82#else
83 builder.append("/.local/share"sv);
84#endif
85
86 return LexicalPath::canonicalized_path(builder.to_deprecated_string());
87}
88
89ErrorOr<DeprecatedString> StandardPaths::runtime_directory()
90{
91 if (auto* data_directory = getenv("XDG_RUNTIME_DIR"))
92 return LexicalPath::canonicalized_path(data_directory);
93
94 StringBuilder builder;
95
96#if defined(AK_OS_SERENITY)
97 auto sid = TRY(Core::SessionManagement::root_session_id());
98 builder.appendff("/tmp/session/{}", sid);
99#elif defined(AK_OS_MACOS)
100 builder.append(home_directory());
101 builder.append("/Library/Application Support"sv);
102#else
103 auto uid = getuid();
104 builder.appendff("/run/user/{}", uid);
105#endif
106
107 return LexicalPath::canonicalized_path(builder.to_deprecated_string());
108}
109
110DeprecatedString StandardPaths::tempfile_directory()
111{
112 return "/tmp";
113}
114
115ErrorOr<Vector<String>> StandardPaths::font_directories()
116{
117 return Vector { {
118#if defined(AK_OS_SERENITY)
119 TRY("/res/fonts"_string),
120#elif defined(AK_OS_MACOS)
121 TRY("/System/Library/Fonts"_string),
122 TRY("/Library/Fonts"_string),
123 TRY(String::formatted("{}/Library/Fonts"sv, home_directory())),
124#else
125 TRY("/usr/share/fonts"_string),
126 TRY("/usr/local/share/fonts"_string),
127 TRY(String::formatted("{}/.local/share/fonts"sv, home_directory())),
128#endif
129 } };
130}
131
132}