master
cpp 142 lines 2.82 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 timezone.c
8
9 Abstract:
10
11 This file contains methods for configuring the timezone.
12
13 --*/
14
15 #include "common.h"
16 #include "util.h"
17 #include "WslDistributionConfig.h"
18
19 #define TIMEZONE_LOCALTIME_FILE ETC_FOLDER "localtime"
20 #define TIMEZONE_SETTING_FILE ETC_FOLDER "timezone"
21
22 void UpdateTimezone(std::string_view Timezone, const wsl::linux::WslDistributionConfig& Config)
23
24 /*++
25
26 Routine Description:
27
28 This routine updates the instance's timezone information by creating the
29 /etc/localtime symlink and writing /etc/timezone.
30
31 Arguments:
32
33 Timezone - Supplies the Linux timezone.
34
35 Config - Supplies the distribution configuration.
36
37 Return Value:
38
39 None.
40
41 --*/
42
43 try
44 {
45 //
46 // If automatic timezone translation is disabled, do nothing.
47 //
48
49 if (!Config.AutoUpdateTimezone)
50 {
51 return;
52 }
53
54 if (Timezone.empty())
55 {
56 LOG_WARNING("Windows to Linux timezone mapping was not possible.");
57 return;
58 }
59
60 //
61 // Construct the /etc/localtime symlink target and ensure it will exist.
62 //
63
64 std::string Target{"/usr/share/zoneinfo/"};
65 Target += Timezone;
66 if (access(Target.c_str(), F_OK) < 0)
67 {
68 LOG_WARNING("{} not found. Is the tzdata package installed?", Target.c_str());
69 return;
70 }
71
72 //
73 // Update the /etc/localtime symlink.
74 //
75
76 if ((unlink(TIMEZONE_LOCALTIME_FILE) < 0) && (errno != ENOENT))
77 {
78 LOG_ERROR("unlink failed {}", errno);
79 return;
80 }
81
82 if (symlink(Target.c_str(), TIMEZONE_LOCALTIME_FILE) < 0)
83 {
84 LOG_ERROR("symlink failed {}", errno);
85 return;
86 }
87
88 //
89 // Write the contents of /etc/timezone to contain the IANA identifier.
90 //
91
92 wil::unique_fd TimezoneFile{TEMP_FAILURE_RETRY(open(TIMEZONE_SETTING_FILE, (O_CREAT | O_TRUNC | O_RDWR), 0644))};
93
94 if (!TimezoneFile)
95 {
96 LOG_ERROR("open({}) failed {}", TIMEZONE_SETTING_FILE, errno);
97 return;
98 }
99
100 std::string FileContents(Timezone);
101 FileContents += '\n';
102 if (UtilWriteStringView(TimezoneFile.get(), FileContents) < 0)
103 {
104 LOG_ERROR("write failed {}", errno);
105 return;
106 }
107
108 return;
109 }
110 CATCH_LOG()
111
112 void UpdateTimezone(gsl::span<gsl::byte> Buffer, const wsl::linux::WslDistributionConfig& Config)
113
114 /*++
115
116 Routine Description:
117
118 This routine processes an update timezone message.
119
120 Arguments:
121
122 Buffer - Supplies the message.
123
124 Config - Supplies the distribution configuration.
125
126
127 Return Value:
128
129 None.
130
131 --*/
132
133 {
134 auto* TimezoneInfo = gslhelpers::try_get_struct<const LX_INIT_TIMEZONE_INFORMATION>(Buffer);
135 if (!TimezoneInfo)
136 {
137 LOG_ERROR("Unexpected message size {}", Buffer.size());
138 return;
139 }
140
141 UpdateTimezone(wsl::shared::string::FromSpan(Buffer, TimezoneInfo->TimezoneOffset), Config);
142 }