1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2012 The Android Open Source Project
3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License.
6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at
7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software
11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and
14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License.
15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
163defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
1739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#ifndef UPDATE_ENGINE_COMMON_UTILS_H_
1839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#define UPDATE_ENGINE_COMMON_UTILS_H_
193defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
202643cb7494baa29bbd6b956b93967c6e33ae0350Han Shen#include <errno.h>
21d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko#include <unistd.h>
22d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko
23d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko#include <algorithm>
24d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko#include <map>
2502f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan#include <memory>
263defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include <set>
273defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include <string>
283defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include <vector>
29c6c135c3e555a856b762e4f383d1d2768363589dDarin Petkov
3075039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/files/file_path.h>
31fc661a18c07822f1700b870d8435189d5d809f3bChris Sosa#include <base/posix/eintr_wrapper.h>
3275039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/time/time.h>
333f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/key_value_store.h>
343f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/secure_blob.h>
35c6c135c3e555a856b762e4f383d1d2768363589dDarin Petkov
3639910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/action.h"
3739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/action_processor.h"
3839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/constants.h"
3939910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/payload_consumer/file_descriptor.h"
40568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood#include "update_engine/update_metadata.pb.h"
413defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
423defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comnamespace chromeos_update_engine {
433defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
443defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comnamespace utils {
453defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4627a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthen// Converts a struct timespec representing a number of seconds since
4727a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthen// the Unix epoch to a base::Time. Sub-microsecond time is rounded
4827a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthen// down.
4927a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthenbase::Time TimeFromStructTimespec(struct timespec *ts);
5027a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthen
51f329b933db41d26644a97afef928eb1b319d6d99Alex Deymo// Formats |vec_str| as a string of the form ["<elem1>", "<elem2>"].
5227a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthen// Does no escaping, only use this for presentation in error messages.
53f329b933db41d26644a97afef928eb1b319d6d99Alex Deymostd::string StringVectorToString(const std::vector<std::string> &vec_str);
5427a48bc3f2531166370c214f7a21e17fb1fc7af1David Zeuthen
558f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen// Calculates the p2p file id from payload hash and size
568f191b22a1a1ab2b803d65ee488729206e648695David Zeuthenstd::string CalculateP2PFileId(const std::string& payload_hash,
578f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen                               size_t payload_size);
588f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen
5963137e5ded659c02eb70d59ef38f99aecac4d076J. Richard Barnette// Parse the firmware version from one line of output from the
6063137e5ded659c02eb70d59ef38f99aecac4d076J. Richard Barnette// "mosys" command.
6163137e5ded659c02eb70d59ef38f99aecac4d076J. Richard Barnettestd::string ParseECVersion(std::string input_line);
6263137e5ded659c02eb70d59ef38f99aecac4d076J. Richard Barnette
63970bb28905b44bf9f2cb986bb412ecda1095b0b1Andrew de los Reyes// Writes the data passed to path. The file at path will be overwritten if it
64970bb28905b44bf9f2cb986bb412ecda1095b0b1Andrew de los Reyes// exists. Returns true on success, false otherwise.
65f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkobool WriteFile(const char* path, const void* data, int data_len);
66970bb28905b44bf9f2cb986bb412ecda1095b0b1Andrew de los Reyes
6709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Calls write() or pwrite() repeatedly until all count bytes at buf are
6809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// written to fd or an error occurs. Returns true on success.
6909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesbool WriteAll(int fd, const void* buf, size_t count);
7009e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesbool PWriteAll(int fd, const void* buf, size_t count, off_t offset);
7109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
72f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyenbool WriteAll(FileDescriptorPtr fd, const void* buf, size_t count);
73f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyenbool PWriteAll(FileDescriptorPtr fd,
74f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyen               const void* buf,
75f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyen               size_t count,
76f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyen               off_t offset);
77f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyen
7872ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo// Calls read() repeatedly until |count| bytes are read or EOF or EWOULDBLOCK
7972ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo// is reached. Returns whether all read() calls succeeded (including EWOULDBLOCK
8072ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo// as a success case), sets |eof| to whether the eof was reached and sets
8172ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo// |out_bytes_read| to the actual number of bytes read regardless of the return
8272ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo// value.
8372ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymobool ReadAll(
8472ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo    int fd, void* buf, size_t count, size_t* out_bytes_read, bool* eof);
8572ea95ab7705448b044cafc6b8cf2a2f4d929bd9Alex Deymo
8609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Calls pread() repeatedly until count bytes are read, or EOF is reached.
8709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Returns number of bytes read in *bytes_read. Returns true on success.
8809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesbool PReadAll(int fd, void* buf, size_t count, off_t offset,
8909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes              ssize_t* out_bytes_read);
90b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes
91f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyenbool PReadAll(FileDescriptorPtr fd, void* buf, size_t count, off_t offset,
92f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyen              ssize_t* out_bytes_read);
93f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyen
9419a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// Opens |path| for reading and appends its entire content to the container
9519a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// pointed to by |out_p|. Returns true upon successfully reading all of the
9619a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// file's content, false otherwise, in which case the state of the output
978e447e02eb60955bc1f982f0d20b7f0d2689e0dbDarin Petkov// container is unknown. ReadFileChunk starts reading the file from |offset|; if
988e447e02eb60955bc1f982f0d20b7f0d2689e0dbDarin Petkov// |size| is not -1, only up to |size| bytes are read in.
993f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool ReadFile(const std::string& path, brillo::Blob* out_p);
10019a45f0eda0917b7788b925b501e774208474fdeGilad Arnoldbool ReadFile(const std::string& path, std::string* out_p);
1018e447e02eb60955bc1f982f0d20b7f0d2689e0dbDarin Petkovbool ReadFileChunk(const std::string& path, off_t offset, off_t size,
1023f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko                   brillo::Blob* out_p);
10319a45f0eda0917b7788b925b501e774208474fdeGilad Arnold
10419a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// Invokes |cmd| in a pipe and appends its stdout to the container pointed to by
10519a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// |out_p|. Returns true upon successfully reading all of the output, false
10619a45f0eda0917b7788b925b501e774208474fdeGilad Arnold// otherwise, in which case the state of the output container is unknown.
10719a45f0eda0917b7788b925b501e774208474fdeGilad Arnoldbool ReadPipe(const std::string& cmd, std::string* out_p);
1083defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
1091016ae1251f9e9f82389194c2175b3dd024b7ddbAlex Deymo// Returns the size of the block device at the file descriptor fd. If an error
1101016ae1251f9e9f82389194c2175b3dd024b7ddbAlex Deymo// occurs, -1 is returned.
111b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Blackoff_t BlockDevSize(int fd);
112b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Black
113b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Black// Returns the size of the file at path, or the file desciptor fd. If the file
114b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Black// is actually a block device, this function will automatically call
115b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Black// BlockDevSize. If the file doesn't exist or some error occurrs, -1 is
116b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Black// returned.
117f4c7ef1bc239890d8bee30e6823f88814fef8ce5Andrew de los Reyesoff_t FileSize(const std::string& path);
118b92cd2e0c4eb241eecffa6ad63efdd021a387f8bGabe Blackoff_t FileSize(int fd);
119f4c7ef1bc239890d8bee30e6823f88814fef8ce5Andrew de los Reyes
1203defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comstd::string ErrnoNumberAsString(int err);
1213defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
1223defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Returns true if the file exists for sure. Returns false if it doesn't exist,
1233defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// or an error occurs.
1243defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.combool FileExists(const char* path);
1253defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
12630291edee8e2f7646b540b00672c81b442386ed6Darin Petkov// Returns true if |path| exists and is a symbolic link.
12730291edee8e2f7646b540b00672c81b442386ed6Darin Petkovbool IsSymlink(const char* path);
12830291edee8e2f7646b540b00672c81b442386ed6Darin Petkov
129a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// Try attaching UBI |volume_num|. If there is any error executing required
130a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// commands to attach the volume, this function returns false. This function
131a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// only returns true if "/dev/ubi%d_0" becomes available in |timeout| seconds.
132a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyenbool TryAttachingUbiVolume(int volume_num, int timeout);
133a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen
134d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold// If |base_filename_template| is neither absolute (starts with "/") nor
135d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold// explicitly relative to the current working directory (starts with "./" or
1365aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// "../"), then it is prepended the system's temporary directory. On success,
1375aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// stores the name of the new temporary file in |filename|. If |fd| is
13888b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// non-null, the file descriptor returned by mkstemp is written to it and
13988b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// kept open; otherwise, it is closed. The template must end with "XXXXXX".
14088b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// Returns true on success.
141d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnoldbool MakeTempFile(const std::string& base_filename_template,
142b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes                  std::string* filename,
143b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes                  int* fd);
144b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes
1455aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// If |base_dirname_template| is neither absolute (starts with "/") nor
146d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold// explicitly relative to the current working directory (starts with "./" or
1475aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// "../"), then it is prepended the system's temporary directory. On success,
1485aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// stores the name of the new temporary directory in |dirname|. The template
1495aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// must end with "XXXXXX". Returns true on success.
150d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnoldbool MakeTempDirectory(const std::string& base_dirname_template,
15109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes                       std::string* dirname);
15209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
1534f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Splits the partition device name into the block device name and partition
1544f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// number. For example, "/dev/sda3" will be split into {"/dev/sda", 3} and
1554f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// "/dev/mmcblk0p2" into {"/dev/mmcblk0", 2}
1564f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Returns false when malformed device name is passed in.
15788b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// If both output parameters are omitted (null), can be used
1584f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// just to test the validity of the device name. Note that the function
1594f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// simply checks if the device name looks like a valid device, no other
1604f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// checks are performed (i.e. it doesn't check if the device actually exists).
1614f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenkobool SplitPartitionName(const std::string& partition_name,
1624f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko                        std::string* out_disk_name,
1634f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko                        int* out_partition_num);
1644f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko
1654f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Builds a partition device name from the block device name and partition
1664f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// number. For example:
1674f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// {"/dev/sda", 1} => "/dev/sda1"
1684f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// {"/dev/mmcblk2", 12} => "/dev/mmcblk2p12"
1694f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Returns empty string when invalid parameters are passed in
1704f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenkostd::string MakePartitionName(const std::string& disk_name,
1714f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko                              int partition_num);
172f97144334e945a5ec88970b4b28f4e98ce0bbb80Andrew de los Reyes
173a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// Similar to "MakePartitionName" but returns a name that is suitable for
174a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// mounting. On NAND system we can write to "/dev/ubiX_0", which is what
175a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// MakePartitionName returns, but we cannot mount that device. To mount, we
176a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// have to use "/dev/ubiblockX_0" for rootfs. Stateful and OEM partitions are
177a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// mountable with "/dev/ubiX_0". The input is a partition device such as
178a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// /dev/sda3. Return empty string on error.
179a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyenstd::string MakePartitionNameForMount(const std::string& part_name);
180a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen
1812e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymo// Set the read-only attribute on the block device |device| to the value passed
1822e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymo// in |read_only|. Return whether the operation succeeded.
1832e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymobool SetBlockDeviceReadOnly(const std::string& device, bool read_only);
1842e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymo
1853defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Synchronously mount or unmount a filesystem. Return true on success.
186390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo// When mounting, it will attempt to mount the device as the passed filesystem
187390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo// type |type|, with the passed |flags| options. If |type| is empty, "ext2",
188390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo// "ext3", "ext4" and "squashfs" will be tried.
189390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymobool MountFilesystem(const std::string& device,
190390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo                     const std::string& mountpoint,
191390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo                     unsigned long flags,  // NOLINT(runtime/int)
19214dbd333439f34c648b9f783ffa656ef565de0ccAlex Deymo                     const std::string& type,
19314dbd333439f34c648b9f783ffa656ef565de0ccAlex Deymo                     const std::string& fs_mount_options);
1944fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesbool UnmountFilesystem(const std::string& mountpoint);
1953defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
196192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Returns the block count and the block byte size of the file system on
197d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov// |device| (which may be a real device or a path to a filesystem image) or on
198d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov// an opened file descriptor |fd|. The actual file-system size is |block_count|
199d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov// * |block_size| bytes. Returns true on success, false otherwise.
200d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkovbool GetFilesystemSize(const std::string& device,
201d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov                       int* out_block_count,
202d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov                       int* out_block_size);
203d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkovbool GetFilesystemSizeFromFD(int fd,
204d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov                             int* out_block_count,
205d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov                             int* out_block_size);
206d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov
207192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Determines the block count and block size of the ext3 fs. At least 2048 bytes
208192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// are required to parse the first superblock. Returns whether the buffer
209192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// contains a valid ext3 filesystem and the values were parsed.
210192393ba515e917d06248b6459b20b6547ef496dAlex Deymobool GetExt3Size(const uint8_t* buffer, size_t buffer_size,
211192393ba515e917d06248b6459b20b6547ef496dAlex Deymo                 int* out_block_count,
212192393ba515e917d06248b6459b20b6547ef496dAlex Deymo                 int* out_block_size);
213192393ba515e917d06248b6459b20b6547ef496dAlex Deymo
214192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Determines the block count and block size of the squashfs v4 fs. At least 96
215192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// bytes are required to parse the header of the filesystem. Since squashfs
216192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// doesn't define a physical block size, a value of 4096 is used for the block
217192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// size, which is the default padding when creating the filesystem.
218192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Returns whether the buffer contains a valid squashfs v4 header and the size
219192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// was parsed. Only little endian squashfs is supported.
220192393ba515e917d06248b6459b20b6547ef496dAlex Deymobool GetSquashfs4Size(const uint8_t* buffer, size_t buffer_size,
221192393ba515e917d06248b6459b20b6547ef496dAlex Deymo                      int* out_block_count,
222192393ba515e917d06248b6459b20b6547ef496dAlex Deymo                      int* out_block_size);
223192393ba515e917d06248b6459b20b6547ef496dAlex Deymo
224de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// Returns whether the filesystem is an ext[234] filesystem. In case of failure,
225de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// such as if the file |device| doesn't exists or can't be read, it returns
226de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// false.
227de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymobool IsExtFilesystem(const std::string& device);
228de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo
229de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// Returns whether the filesystem is a squashfs filesystem. In case of failure,
230de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// such as if the file |device| doesn't exists or can't be read, it returns
231de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// false.
232de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymobool IsSquashfsFilesystem(const std::string& device);
233de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo
234032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymo// Returns a human-readable string with the file format based on magic constants
235032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymo// on the header of the file.
236032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymostd::string GetFileFormat(const std::string& path);
237032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymo
238480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan// Returns the string representation of the given UTC time.
239480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan// such as "11/14/2011 14:05:30 GMT".
240480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasanstd::string ToString(const base::Time utc_time);
241480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan
242ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan// Returns true or false depending on the value of b.
243ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanstd::string ToString(bool b);
244ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
24519409b74019d787100b768306e75ab3e5882898dJay Srinivasan// Returns a string representation of the given enum.
24619409b74019d787100b768306e75ab3e5882898dJay Srinivasanstd::string ToString(DownloadSource source);
24719409b74019d787100b768306e75ab3e5882898dJay Srinivasan
2481c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo// Returns a string representation of the given enum.
2491c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymostd::string ToString(PayloadType payload_type);
2501c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
251712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyes// Schedules a Main Loop callback to trigger the crash reporter to perform an
252712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyes// upload as if this process had crashed.
253712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyesvoid ScheduleCrashReporterUpload();
254712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyes
2555c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov// Fuzzes an integer |value| randomly in the range:
2565c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov// [value - range / 2, value + range - range / 2]
2575c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkovint FuzzInt(int value, unsigned int range);
2585c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov
2593defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Log a string in hex to LOG(INFO). Useful for debugging.
260f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkovoid HexDumpArray(const uint8_t* const arr, const size_t length);
2613defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.cominline void HexDumpString(const std::string& str) {
262f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko  HexDumpArray(reinterpret_cast<const uint8_t*>(str.data()), str.size());
2633defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}
2643f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkoinline void HexDumpVector(const brillo::Blob& vect) {
265f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko  HexDumpArray(vect.data(), vect.size());
2663defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}
2673defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
2683defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comtemplate<typename KeyType, typename ValueType>
2693defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.combool MapContainsKey(const std::map<KeyType, ValueType>& m, const KeyType& k) {
2703defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  return m.find(k) != m.end();
2713defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}
2724fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyestemplate<typename KeyType>
2734fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesbool SetContainsKey(const std::set<KeyType>& s, const KeyType& k) {
2744fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes  return s.find(k) != s.end();
2754fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes}
2763defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
2770ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyestemplate<typename T>
2780ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyesbool VectorContainsValue(const std::vector<T>& vect, const T& value) {
279c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov  return std::find(vect.begin(), vect.end(), value) != vect.end();
2800ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyes}
2810ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyes
282b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyestemplate<typename T>
283b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyesbool VectorIndexOf(const std::vector<T>& vect, const T& value,
284b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes                   typename std::vector<T>::size_type* out_index) {
285b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes  typename std::vector<T>::const_iterator it = std::find(vect.begin(),
286b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes                                                         vect.end(),
287b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes                                                         value);
288b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes  if (it == vect.end()) {
289b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes    return false;
290b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes  } else {
291b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes    *out_index = it - vect.begin();
292b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes    return true;
293b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes  }
294b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes}
295b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes
296d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// Converts seconds into human readable notation including days, hours, minutes
297d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// and seconds. For example, 185 will yield 3m5s, 4300 will yield 1h11m40s, and
298d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// 360000 will yield 4d4h0m0s.  Zero padding not applied. Seconds are always
299d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// shown in the result.
300d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnoldstd::string FormatSecs(unsigned secs);
301d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold
302d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// Converts a TimeDelta into human readable notation including days, hours,
303d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// minutes, seconds and fractions of a second down to microsecond granularity,
304d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// as necessary; for example, an output of 5d2h0m15.053s means that the input
305d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// time was precise to the milliseconds only. Zero padding not applied, except
306d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// for fractions. Seconds are always shown, but fractions thereof are only shown
307973449e82eaf611adb911ac1b977baad2e2071e9David Zeuthen// when applicable. If |delta| is negative, the output will have a leading '-'
308973449e82eaf611adb911ac1b977baad2e2071e9David Zeuthen// followed by the absolute duration.
309d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnoldstd::string FormatTimeDelta(base::TimeDelta delta);
3101ebd813ad19214d0b59ade04005c3b84ae765e42Gilad Arnold
3112b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// This method transforms the given error code to be suitable for UMA and
3122b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// for error classification purposes by removing the higher order bits and
3132b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// aggregating error codes beyond the enum range, etc. This method is
3142b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// idempotent, i.e. if called with a value previously returned by this method,
3152b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// it'll return the same value again.
316a99981fda75fe0b17e96c700e3ddc93eca1cebe5David ZeuthenErrorCode GetBaseErrorCode(ErrorCode code);
3172b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
31830dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold// Creates the powerwash marker file with the appropriate commands in it.  Uses
31988b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// |file_path| as the path to the marker file if non-null, otherwise uses the
32030dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold// global default. Returns true if successfully created.  False otherwise.
32130dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnoldbool CreatePowerwashMarkerFile(const char* file_path);
32230dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold
32330dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold// Deletes the marker file used to trigger Powerwash using clobber-state.  Uses
32488b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// |file_path| as the path to the marker file if non-null, otherwise uses the
32530dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold// global default. Returns true if successfully deleted. False otherwise.
32630dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnoldbool DeletePowerwashMarkerFile(const char* file_path);
3271c0fe79c7ef2b43946d756b54c8505d2bf48b93bJay Srinivasan
328e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// Decodes the data in |base64_encoded| and stores it in a temporary
329e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// file. Returns false if the given data is empty, not well-formed
330e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// base64 or if an error occurred. If true is returned, the decoded
331e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// data is stored in the file returned in |out_path|. The file should
332e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// be deleted when no longer needed.
333e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthenbool DecodeAndStoreBase64String(const std::string& base64_encoded,
334e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen                                base::FilePath *out_path);
335e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen
336639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// Converts |time| to an Omaha InstallDate which is defined as "the
337639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// number of PST8PDT calendar weeks since Jan 1st 2007 0:00 PST, times
338639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// seven" with PST8PDT defined as "Pacific Time" (e.g. UTC-07:00 if
339639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// daylight savings is observed and UTC-08:00 otherwise.)
340639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen//
341639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// If the passed in |time| variable is before Monday January 1st 2007
342639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// 0:00 PST, False is returned and the value returned in
343639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// |out_num_days| is undefined. Otherwise the number of PST8PDT
344639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// calendar weeks since that date times seven is returned in
345639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// |out_num_days| and the function returns True.
346639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen//
347639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// (NOTE: This function does not currently take daylight savings time
348639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// into account so the result may up to one hour off. This is because
349639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// the glibc date and timezone routines depend on the TZ environment
3500b3db6b6040f53eb9859e614f7fe4c681213d33aAlex Deymo// variable and changing environment variables is not thread-safe.
351639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthenbool ConvertToOmahaInstallDate(base::Time time, int *out_num_days);
352639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen
353b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo// Look for the minor version value in the passed |store| and set
354b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo// |minor_version| to that value. Return whether the value was found and valid.
3553f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool GetMinorVersion(const brillo::KeyValueStore& store,
356b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo                     uint32_t* minor_version);
35778750a450ce84b2d335134402d041aa8773ab8efAllie Wood
3583a92aa2fe6aafd1007b6427795dfe8711b6cb094Sen Jiang// Returns whether zlib |fingerprint| is compatible with zlib we are using.
3593a92aa2fe6aafd1007b6427795dfe8711b6cb094Sen Jiangbool IsZlibCompatible(const std::string& fingerprint);
3603a92aa2fe6aafd1007b6427795dfe8711b6cb094Sen Jiang
361568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// This function reads the specified data in |extents| into |out_data|. The
362568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// extents are read from the file at |path|. |out_data_size| is the size of
363568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// |out_data|. Returns false if the number of bytes to read given in
364568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// |extents| does not equal |out_data_size|.
36541e3474eebe3748a45aba4b297a7a313a1006c6cGilad Arnoldbool ReadExtents(const std::string& path, const std::vector<Extent>& extents,
3663f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko                 brillo::Blob* out_data, ssize_t out_data_size,
367568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood                 size_t block_size);
368568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood
369dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo// Read the current boot identifier and store it in |boot_id|. This identifier
370dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo// is constants during the same boot of the kernel and is regenerated after
371dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo// reboot. Returns whether it succeeded getting the boot_id.
372dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymobool GetBootId(std::string* boot_id);
373dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo
3743defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}  // namespace utils
3753defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
37608fce04e5341c99f308ee7462b1f351f5232eacdJay Srinivasan
3773defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Utility class to close a file descriptor
3783defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comclass ScopedFdCloser {
3793defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com public:
3804600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo  explicit ScopedFdCloser(int* fd) : fd_(fd) {}
3813defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  ~ScopedFdCloser() {
3824600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo    if (should_close_ && fd_ && (*fd_ >= 0) && !IGNORE_EINTR(close(*fd_)))
3834600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo      *fd_ = -1;
3843defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  }
3856f03a3b868d4b632931400628763036f79c449f7Darin Petkov  void set_should_close(bool should_close) { should_close_ = should_close; }
3863defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com private:
3873defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  int* fd_;
3884600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo  bool should_close_ = true;
38909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  DISALLOW_COPY_AND_ASSIGN(ScopedFdCloser);
39009e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes};
39109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
39209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Utility class to delete a file when it goes out of scope.
39309e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesclass ScopedPathUnlinker {
39409e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes public:
39552dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov  explicit ScopedPathUnlinker(const std::string& path)
39652dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov      : path_(path),
39752dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov        should_remove_(true) {}
39809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  ~ScopedPathUnlinker() {
39952dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov    if (should_remove_ && unlink(path_.c_str()) < 0) {
40018f48aa4e962997a9ff12fac8933c94aac247fd9Alex Deymo      PLOG(ERROR) << "Unable to unlink path " << path_;
40109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes    }
40209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  }
40352dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov  void set_should_remove(bool should_remove) { should_remove_ = should_remove; }
40452dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov
40509e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes private:
40609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  const std::string path_;
40752dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov  bool should_remove_;
40809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  DISALLOW_COPY_AND_ASSIGN(ScopedPathUnlinker);
40909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes};
41009e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
41109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Utility class to delete an empty directory when it goes out of scope.
41209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesclass ScopedDirRemover {
41309e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes public:
4146f03a3b868d4b632931400628763036f79c449f7Darin Petkov  explicit ScopedDirRemover(const std::string& path)
4156f03a3b868d4b632931400628763036f79c449f7Darin Petkov      : path_(path),
4166f03a3b868d4b632931400628763036f79c449f7Darin Petkov        should_remove_(true) {}
41709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  ~ScopedDirRemover() {
4186f03a3b868d4b632931400628763036f79c449f7Darin Petkov    if (should_remove_ && (rmdir(path_.c_str()) < 0)) {
41909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes      PLOG(ERROR) << "Unable to remove dir " << path_;
4206f03a3b868d4b632931400628763036f79c449f7Darin Petkov    }
42109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  }
4226f03a3b868d4b632931400628763036f79c449f7Darin Petkov  void set_should_remove(bool should_remove) { should_remove_ = should_remove; }
4236f03a3b868d4b632931400628763036f79c449f7Darin Petkov
4246f03a3b868d4b632931400628763036f79c449f7Darin Petkov protected:
42509e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  const std::string path_;
4266f03a3b868d4b632931400628763036f79c449f7Darin Petkov
4276f03a3b868d4b632931400628763036f79c449f7Darin Petkov private:
4286f03a3b868d4b632931400628763036f79c449f7Darin Petkov  bool should_remove_;
42909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  DISALLOW_COPY_AND_ASSIGN(ScopedDirRemover);
4303defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com};
4313defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4323defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// A little object to call ActionComplete on the ActionProcessor when
4333defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// it's destructed.
4343defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comclass ScopedActionCompleter {
4353defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com public:
4363defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  explicit ScopedActionCompleter(ActionProcessor* processor,
4373defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com                                 AbstractAction* action)
4383defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      : processor_(processor),
4393defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com        action_(action),
440d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold        code_(ErrorCode::kError),
4413defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com        should_complete_(true) {}
4423defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  ~ScopedActionCompleter() {
4433defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    if (should_complete_)
444c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov      processor_->ActionComplete(action_, code_);
4453defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  }
446a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  void set_code(ErrorCode code) { code_ = code; }
4473defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  void set_should_complete(bool should_complete) {
4483defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    should_complete_ = should_complete;
4493defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  }
45033bae491eded4ef4f1eb4f4ef0f01ef0e5463f3aDavid Zeuthen  ErrorCode get_code() const { return code_; }
451c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov
4523defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com private:
4533defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  ActionProcessor* processor_;
4543defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  AbstractAction* action_;
455a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  ErrorCode code_;
4563defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  bool should_complete_;
4573defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  DISALLOW_COPY_AND_ASSIGN(ScopedActionCompleter);
4583defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com};
4593defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4603defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}  // namespace chromeos_update_engine
4613defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4623defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN_FALSE_ERRNO(_x)                                        \
4633defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  do {                                                                         \
4642b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen    bool _success = static_cast<bool>(_x);                                     \
4653defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    if (!_success) {                                                           \
4663defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      std::string _msg =                                                       \
4673defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com          chromeos_update_engine::utils::ErrnoNumberAsString(errno);           \
4683defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      LOG(ERROR) << #_x " failed: " << _msg;                                   \
4693defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      return false;                                                            \
4703defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    }                                                                          \
4713defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  } while (0)
4723defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4733defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN_FALSE(_x)                                              \
4743defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  do {                                                                         \
4752b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen    bool _success = static_cast<bool>(_x);                                     \
4763defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    if (!_success) {                                                           \
4773defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      LOG(ERROR) << #_x " failed.";                                            \
4783defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      return false;                                                            \
4793defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    }                                                                          \
4803defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  } while (0)
4813defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4823defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN_ERRNO(_x)                                              \
4833defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  do {                                                                         \
4842b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen    bool _success = static_cast<bool>(_x);                                     \
4853defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    if (!_success) {                                                           \
4863defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      std::string _msg =                                                       \
4873defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com          chromeos_update_engine::utils::ErrnoNumberAsString(errno);           \
4883defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      LOG(ERROR) << #_x " failed: " << _msg;                                   \
4893defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      return;                                                                  \
4903defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    }                                                                          \
4913defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  } while (0)
4923defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4933defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN(_x)                                                    \
4943defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  do {                                                                         \
4952b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen    bool _success = static_cast<bool>(_x);                                     \
4963defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    if (!_success) {                                                           \
4973defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      LOG(ERROR) << #_x " failed.";                                            \
4983defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      return;                                                                  \
4993defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    }                                                                          \
5003defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  } while (0)
5013defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
5025c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le#define TEST_AND_RETURN_FALSE_ERRCODE(_x)                                      \
5035c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le  do {                                                                         \
5045c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le    errcode_t _error = (_x);                                                   \
5055c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le    if (_error) {                                                              \
5065c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le      errno = _error;                                                          \
5075c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le      LOG(ERROR) << #_x " failed: " << _error;                                 \
5085c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le      return false;                                                            \
5095c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le    }                                                                          \
5105c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le  } while (0)
5115c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le
51239910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif  // UPDATE_ENGINE_COMMON_UTILS_H_
513