├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── META-INF
└── com
│ └── google
│ └── android
│ └── update-binary
├── README.md
└── change_os_version.c
/.gitignore:
--------------------------------------------------------------------------------
1 | CMakeLists.txt.user
2 | CMakeCache.txt
3 | CMakeFiles
4 | CMakeScripts
5 | Testing
6 | Makefile
7 | cmake_install.cmake
8 | install_manifest.txt
9 | compile_commands.json
10 | CTestTestfile.cmake
11 | _deps
12 | /build
13 | change_os_version
14 | *.zip
15 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.12)
2 |
3 | if (NOT DEFINED NDK_ROOT)
4 | if (DEFINED ENV{NDK_ROOT})
5 | set(NDK_ROOT "$ENV{NDK_ROOT}")
6 | else ()
7 | message(FATAL_ERROR "Please define NDK_ROOT to point to your NDK path!")
8 | endif ()
9 | endif ()
10 |
11 | find_program(ZIP NAMES zip)
12 |
13 | # Set the tool chain file
14 | set(CMAKE_TOOLCHAIN_FILE ${NDK_ROOT}/build/cmake/android.toolchain.cmake)
15 | set(ANDROID_ABI arm64-v8a)
16 | set(ANDROID_PLATFORM latest)
17 | set(ANDROID_STL none)
18 | set(ANDROID_LD lld)
19 |
20 | add_compile_options(-Wall -Wextra -pedantic -Werror)
21 |
22 | set(DEFAULT_FUTURE_DATE "2099-12" CACHE STRING "Select os_patch_level date.")
23 | option(SELF_PACK_EXECUTABLES "Self-pack executables." ON)
24 |
25 | set(UPDATE_ZIP "backtothefuture-${DEFAULT_FUTURE_DATE}.zip")
26 |
27 | project(BackToTheFuture)
28 |
29 | set(CMAKE_C_FLAGS_RELEASE "-O2 -flto")
30 | set(ANDROID_PIE FALSE)
31 | link_libraries("-static")
32 |
33 | add_executable(change_os_version change_os_version.c)
34 |
35 | if (CMAKE_BUILD_TYPE STREQUAL Release)
36 | add_custom_command(
37 | TARGET change_os_version
38 | POST_BUILD
39 | COMMAND "${ANDROID_TOOLCHAIN_PREFIX}strip" --strip-all change_os_version
40 | COMMENT "Stripping the executables"
41 | VERBATIM
42 | )
43 | if (SELF_PACK_EXECUTABLES)
44 | include("${CMAKE_ROOT}/Modules/FindSelfPackers.cmake")
45 | if (SELF_PACKER_FOR_EXECUTABLE)
46 | add_custom_command(
47 | TARGET change_os_version
48 | POST_BUILD
49 | COMMAND ${SELF_PACKER_FOR_EXECUTABLE} -9q ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} change_os_version
50 | COMMENT "Packing the executables"
51 | VERBATIM
52 | )
53 | endif ()
54 | endif ()
55 | endif ()
56 |
57 | if (NOT CMAKE_CURRENT_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
58 | add_custom_command(
59 | OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/META-INF/com/google/android/update-binary
60 | COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/META-INF/com/google/android/update-binary
61 | ${CMAKE_CURRENT_BINARY_DIR}/META-INF/com/google/android/update-binary
62 | DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/META-INF/com/google/android/update-binary
63 | )
64 | endif ()
65 |
66 | add_custom_target(zip
67 | DEPENDS change_os_version
68 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/META-INF/com/google/android/update-binary
69 | COMMAND ${ZIP} ${UPDATE_ZIP} change_os_version META-INF/com/google/android/update-binary
70 | COMMENT "Preparing ${UPDATE_ZIP}"
71 | VERBATIM
72 | )
73 |
74 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/META-INF/com/google/android/update-binary:
--------------------------------------------------------------------------------
1 | #!/sbin/sh
2 |
3 | ZIPFILE=$3
4 | ZIPNAME=${ZIPFILE##*/}
5 | OUTFD=$2
6 |
7 | screen_width=50
8 |
9 | # Detect real $OUTFD
10 | #
11 | if readlink /proc/$$/fd/$OUTFD 2>/dev/null | grep /tmp >/dev/null; then
12 | OUTFD=0
13 | for FD in $( ls /proc/$$/fd ); do
14 | if readlink /proc/$$/fd/$FD 2>/dev/null | grep pipe >/dev/null; then
15 | if ps | grep " 3 $FD " | grep -v grep >/dev/null; then
16 | OUTFD=$FD
17 | break
18 | fi
19 | fi
20 | done
21 | fi
22 |
23 | ui_print() {
24 | echo -ne "ui_print $1\n" >> /proc/self/fd/$OUTFD
25 | echo -ne "ui_print\n" >> /proc/self/fd/$OUTFD
26 | }
27 |
28 | print_full_bar() {
29 | ui_print "$(printf '%*s\n' $screen_width | tr ' ' '=')"
30 | }
31 |
32 | print_justified() {
33 | local str="$1"
34 | local str_len=${#str}
35 | local padding_len=$(( ($screen_width - $str_len - 2) / 2))
36 | local ljust="$(printf '%*s' $padding_len)"
37 | local rjust="$(printf '%*s' $(($padding_len + $str_len % 2)))"
38 |
39 | ui_print "=$ljust$str$rjust="
40 | }
41 |
42 |
43 | ui_print " "
44 | print_full_bar
45 | print_justified "Back to the Future"
46 | print_justified "OS Patch level changer v1.1"
47 | print_justified "of boot and recovery partitions"
48 | print_justified "for Samsung S10/Note10 devices."
49 | print_justified "https://github.com/CruelKernel/"
50 | print_full_bar
51 | ui_print " "
52 |
53 | bl=$(getprop ro.boot.bootloader)
54 |
55 | # Device is first 5 characters of bootloader string.
56 | #
57 | device=${bl:0:$((${#bl} - 8))}
58 |
59 | if echo $device | grep -Ev 'G97([035][FN0]|7[BN])|N97([05][FN0]|6[BN0]|1N)' >/dev/null; then
60 | ui_print " - Unsupported device detected. Installation aborted."
61 | ui_print " "
62 | exit 1
63 | fi
64 |
65 | date="$(echo $ZIPNAME | sed 's/^.*-\(2[0-9]\{3\}-[01][0-9]\).zip$/\1/')"
66 |
67 | if [ "$date" = "$ZIPNAME" ]; then
68 | date="2127-12"
69 | ui_print " - Can't determine os_patch_level date"
70 | ui_print " - from filename '$ZIPNAME'."
71 | ui_print " - Max possible date $date will be used."
72 | else
73 | ui_print " - Detected date from zip filename: $date."
74 | fi
75 |
76 | unzip -d /tmp -o $ZIPFILE change_os_version
77 | chmod +x /tmp/change_os_version
78 |
79 | ui_print " - Patching boot ..."
80 | /tmp/change_os_version /dev/block/by-name/boot same $date 2>&1 |
81 | sed 's/^\(.*\)$/ui_print - - \1\n/' >> /proc/self/fd/$OUTFD
82 | ui_print " "
83 | ui_print " - Patching recovery ..."
84 | /tmp/change_os_version /dev/block/by-name/recovery same $date 2>&1 |
85 | sed 's/^\(.*\)$/ui_print - - \1\n/' >> /proc/self/fd/$OUTFD
86 |
87 | rm -f /tmp/change_os_version
88 |
89 | ui_print " "
90 | ui_print " - Finished."
91 | ui_print " "
92 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Back to the Future
2 |
3 | OS Patch Level changer for boot and recovery partitions. Flash in TWRP. You can set desired date in filename. Date format: YYYY-MM. For example: backtothefuture-2021-12.zip If there will be no date in the filename, max possible date 2127-12 will be used. If you select a wrong date, then don't reboot, rename the zipfile and flash it again.
4 |
5 | Downloads: https://github.com/CruelKernel/backtothefuture/releases
6 |
7 | If someone wants to know more about why it's not possible to rollback to normal date, here is the official documentation: https://source.android.com/security/keystore/version-binding#hal-changes. Short answer: because all your security keys are cryptographically updated with new os_patch_level date once you boot with "new date" kernel.
8 |
9 | So, once you installed a kernel with os_patch_level in future you are doomed to use greater or equal os_patch_level date for all your next kernels. However, full wipe will help.
10 |
--------------------------------------------------------------------------------
/change_os_version.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | #define BOOT_MAGIC_SIZE 8
17 | #define BOOT_IMAGE_HEADER_V1_SIZE 1648
18 | #define BOOT_IMAGE_HEADER_V2_SIZE 1660
19 |
20 | #define HEADER_VERSION_OFFSET ( \
21 | sizeof(uint8_t) * BOOT_MAGIC_SIZE + \
22 | 8 * sizeof(uint32_t) \
23 | )
24 | #define OS_VERSION_OFFSET_V0 (HEADER_VERSION_OFFSET + sizeof(uint32_t))
25 | #define OS_VERSION_OFFSET_V1 OS_VERSION_OFFSET_V0
26 | #define OS_VERSION_OFFSET_V2 OS_VERSION_OFFSET_V0
27 | #define OS_VERSION_OFFSET_V3 (HEADER_VERSION_OFFSET - 6 * sizeof(uint32_t))
28 |
29 | typedef union __attribute__((packed)) {
30 | uint32_t version;
31 | struct {
32 | unsigned os_patch_level:11;
33 | unsigned os_version:21;
34 | };
35 | struct {
36 | unsigned month:4;
37 | unsigned year:7;
38 | unsigned c:7;
39 | unsigned b:7;
40 | unsigned a:7;
41 | };
42 | } os_version_t;
43 |
44 | static bool stop_on(bool print_errno, bool cond, const char *message, ...)
45 | {
46 | if (!cond)
47 | return false;
48 |
49 | va_list args;
50 | va_start(args, message);
51 | vfprintf(stderr, message, args);
52 | va_end(args);
53 | if (print_errno)
54 | fprintf(stderr, ": %s", strerror(errno));
55 | fprintf(stderr, "\n");
56 | exit(EXIT_FAILURE);
57 |
58 | return true;
59 | }
60 |
61 | #define stopx(cond, ...) stop_on(false, cond, __VA_ARGS__)
62 | #define stop(cond, ...) stop_on(true, cond, __VA_ARGS__)
63 |
64 | static bool check_cond(bool print_errno, bool cond, const char *message, ...)
65 | {
66 | if (!cond)
67 | return false;
68 |
69 | va_list args;
70 | va_start(args, message);
71 | vfprintf(stderr, message, args);
72 | va_end(args);
73 | if (print_errno)
74 | fprintf(stderr, ": %s", strerror(errno));
75 | fprintf(stderr, "\n");
76 |
77 | return true;
78 | }
79 |
80 | #define checkx(cond, ...) check_cond(false, cond, __VA_ARGS__)
81 | #define check(cond, ...) check_cond(true, cond, __VA_ARGS__)
82 |
83 |
84 | static inline uint32_t get_header_version(uint8_t *addr)
85 | {
86 | return *(uint32_t *)(addr + HEADER_VERSION_OFFSET);
87 | }
88 |
89 | static inline os_version_t get_os_version(uint8_t *addr)
90 | {
91 | os_version_t v;
92 | uint32_t hdr_ver = get_header_version(addr);
93 |
94 | switch (hdr_ver) {
95 | case 0:
96 | case 1:
97 | case 2:
98 | v.version = *(uint32_t *)(addr + OS_VERSION_OFFSET_V2);
99 | break;
100 | case 3:
101 | v.version = *(uint32_t *)(addr + OS_VERSION_OFFSET_V3);
102 | break;
103 | default:
104 | errx(1, "Unsupported header version %u", hdr_ver);
105 | break;
106 | }
107 | return v;
108 | }
109 |
110 | static inline void set_os_version(uint8_t *addr, os_version_t v)
111 | {
112 | uint32_t hdr_ver = get_header_version(addr);
113 |
114 | switch (hdr_ver) {
115 | case 0:
116 | case 1:
117 | case 2:
118 | *(uint32_t *)(addr + OS_VERSION_OFFSET_V2) = v.version;
119 | break;
120 | case 3:
121 | *(uint32_t *)(addr + OS_VERSION_OFFSET_V3) = v.version;
122 | break;
123 | default:
124 | errx(1, "Unsupported header version %u", hdr_ver);
125 | break;
126 | }
127 | }
128 |
129 | static uint8_t *mmap_boot_image(const char *file, int flags)
130 | {
131 | uint8_t *addr;
132 | uint32_t header_version;
133 | struct stat st;
134 | int mmap_flags = PROT_READ;
135 | size_t block_size;
136 |
137 | int fd = open(file, flags);
138 | stop(fd < 0, "open %s failed", file);
139 |
140 | if (flags == O_RDWR)
141 | mmap_flags |= PROT_WRITE;
142 |
143 | stop(fstat(fd, &st) < 0, "stat %s failed", file);
144 | stopx(!(S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) &&
145 | st.st_size < BOOT_IMAGE_HEADER_V2_SIZE,
146 | "%s is too small", file);
147 | stopx(S_ISCHR(st.st_mode), "%s is not a block device", file);
148 |
149 | if (S_ISBLK(st.st_mode)) {
150 | stop(ioctl(fd, BLKGETSIZE64, &block_size) < 0,
151 | "%s can't determine block device size", file);
152 | stopx(block_size < BOOT_IMAGE_HEADER_V2_SIZE,
153 | "%s is too small", file);
154 | }
155 |
156 | addr = mmap(NULL, BOOT_IMAGE_HEADER_V2_SIZE, mmap_flags,
157 | MAP_SHARED, fd, 0);
158 | stop(addr == MAP_FAILED, "mmap %s failed", file);
159 | close(fd);
160 |
161 | stopx(strncmp((const char *)addr, "ANDROID!", 8),
162 | "%s has incorrect magic number, not an android boot image",
163 | file
164 | );
165 |
166 | header_version = get_header_version(addr);
167 | stopx(header_version > 3,
168 | "%s unsupported header version (%u)",
169 | file, header_version
170 | );
171 |
172 | return addr;
173 | }
174 |
175 | int main(int argc, char *argv[])
176 | {
177 | uint8_t *addr;
178 | const char *file, *os_version, *os_patch_level;
179 | char *delim = NULL;
180 | int year, month;
181 | int a, b, c;
182 | os_version_t curv, newv;
183 | bool preserve_os_version = false;
184 | bool preserve_os_patch_level = false;
185 |
186 | stopx(argc != 4,
187 | "Usage: %s ",
188 | argv[0]);
189 |
190 | file = argv[1];
191 | os_version = argv[2];
192 | os_patch_level = argv[3];
193 |
194 | if (!strcmp(os_version, "same")) {
195 | preserve_os_version = true;
196 | } else {
197 | // Format: a.b.c
198 | for (const char *p = os_version; *p != '\0'; ++p) {
199 | stopx(!(isdigit(*p) || *p == '.'),
200 | "Incorrect os_version '%s'. Format: a.b.c",
201 | os_version);
202 | }
203 | a = strtol(os_version, &delim, 10);
204 | stopx(*delim != '.',
205 | "Incorrect os_version '%s'. Format: a.b.c", os_version);
206 | b = strtol(delim + 1, &delim, 10);
207 | stopx(*delim != '.',
208 | "Incorrect os_version '%s'. Format: a.b.c", os_version);
209 | c = strtol(delim + 1, NULL, 10);
210 | stopx(!(0 <= a && a <= 127 &&
211 | 0 <= b && b <= 127 &&
212 | 0 <= c && c <= 127),
213 | "Incorrect os_version '%s'. Format: a.b.c", os_version);
214 | }
215 |
216 | if (!strcmp(os_patch_level, "same")) {
217 | preserve_os_patch_level = true;
218 | } else {
219 | // Format: YYYY-MM
220 | stopx(strlen(os_patch_level) != 7 ||
221 | os_patch_level[4] != '-' ||
222 | !isdigit(os_patch_level[0]) ||
223 | !isdigit(os_patch_level[1]) ||
224 | !isdigit(os_patch_level[2]) ||
225 | !isdigit(os_patch_level[3]) ||
226 | !isdigit(os_patch_level[5]) ||
227 | !isdigit(os_patch_level[6]),
228 | "Incorrent os_patch_level '%s'. Format: YYYY-MM",
229 | os_patch_level);
230 |
231 | year = atoi(os_patch_level);
232 | month = atoi(os_patch_level + 5);
233 |
234 | stopx(!(2000 <= year && year <= 2127),
235 | "Incorrect year: %ld (2000 <= year <= 2127)", year);
236 | stopx(!(1 <= month && month <= 12),
237 | "Incorrect month: %ld (01 <= month <= 12)", month);
238 | }
239 |
240 | addr = mmap_boot_image(file, O_RDWR);
241 |
242 | curv = get_os_version(addr);
243 | printf("Current OS version:\t%u.%u.%u %u-%02u\n",
244 | curv.a, curv.b, curv.c,
245 | curv.year + 2000, curv.month);
246 |
247 | if (preserve_os_version) {
248 | newv.os_version = curv.os_version;
249 | } else {
250 | newv.a = a;
251 | newv.b = b;
252 | newv.c = c;
253 | }
254 |
255 | if (preserve_os_patch_level) {
256 | newv.os_patch_level = curv.os_patch_level;
257 | } else {
258 | newv.year = (year - 2000);
259 | newv.month = month;
260 | }
261 |
262 | if (curv.version != newv.version) {
263 | printf("New OS version:\t\t%u.%u.%u %u-%02u\n",
264 | newv.a, newv.b, newv.c,
265 | newv.year + 2000, newv.month);
266 |
267 | checkx(curv.os_version > newv.os_version,
268 | "warn: new os_version is lower than current"
269 | );
270 |
271 | checkx(curv.os_patch_level > newv.os_patch_level,
272 | "warn: new os_patch_level version is lower than current"
273 | );
274 |
275 | set_os_version(addr, newv);
276 |
277 | check(msync(addr, BOOT_IMAGE_HEADER_V2_SIZE, MS_SYNC) < 0,
278 | "msync failed");
279 | } else {
280 | printf("The dates are the same. Nothing to be done.\n");
281 | }
282 |
283 | munmap(addr, BOOT_IMAGE_HEADER_V2_SIZE);
284 |
285 | return 0;
286 | }
287 |
--------------------------------------------------------------------------------