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
1349629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymo// Setup the directory |new_root_temp_dir| to be used as the root directory for
1359629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymo// temporary files instead of the system's default. If the directory doesn't
1369629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymo// exists, it will be created when first used.
1379629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymo// NOTE: The memory pointed by |new_root_temp_dir| must be available until this
1389629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymo// function is called again with a different value.
1399629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymovoid SetRootTempDir(const char* new_root_temp_dir);
1409629bbc4ba447d3c2806a3ee1ed9c07a4ced75e2Alex Deymo
141d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold// If |base_filename_template| is neither absolute (starts with "/") nor
142d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold// explicitly relative to the current working directory (starts with "./" or
1435aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// "../"), then it is prepended the system's temporary directory. On success,
1445aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// stores the name of the new temporary file in |filename|. If |fd| is
14588b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// non-null, the file descriptor returned by mkstemp is written to it and
14688b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// kept open; otherwise, it is closed. The template must end with "XXXXXX".
14788b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// Returns true on success.
148d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnoldbool MakeTempFile(const std::string& base_filename_template,
149b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes                  std::string* filename,
150b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes                  int* fd);
151b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes
1525aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// If |base_dirname_template| is neither absolute (starts with "/") nor
153d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold// explicitly relative to the current working directory (starts with "./" or
1545aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// "../"), then it is prepended the system's temporary directory. On success,
1555aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// stores the name of the new temporary directory in |dirname|. The template
1565aa1c54312fdaf541c70932900fb3c80145592e1Alex Deymo// must end with "XXXXXX". Returns true on success.
157d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnoldbool MakeTempDirectory(const std::string& base_dirname_template,
15809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes                       std::string* dirname);
15909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
1604f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Splits the partition device name into the block device name and partition
1614f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// number. For example, "/dev/sda3" will be split into {"/dev/sda", 3} and
1624f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// "/dev/mmcblk0p2" into {"/dev/mmcblk0", 2}
1634f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Returns false when malformed device name is passed in.
16488b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko// If both output parameters are omitted (null), can be used
1654f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// just to test the validity of the device name. Note that the function
1664f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// simply checks if the device name looks like a valid device, no other
1674f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// checks are performed (i.e. it doesn't check if the device actually exists).
1684f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenkobool SplitPartitionName(const std::string& partition_name,
1694f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko                        std::string* out_disk_name,
1704f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko                        int* out_partition_num);
1714f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko
1724f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Builds a partition device name from the block device name and partition
1734f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// number. For example:
1744f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// {"/dev/sda", 1} => "/dev/sda1"
1754f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// {"/dev/mmcblk2", 12} => "/dev/mmcblk2p12"
1764f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko// Returns empty string when invalid parameters are passed in
1774f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenkostd::string MakePartitionName(const std::string& disk_name,
1784f5b144e3e003663fbc9a89c3a43d214ecc61238Alex Vakulenko                              int partition_num);
179f97144334e945a5ec88970b4b28f4e98ce0bbb80Andrew de los Reyes
180a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// Similar to "MakePartitionName" but returns a name that is suitable for
181a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// mounting. On NAND system we can write to "/dev/ubiX_0", which is what
182a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// MakePartitionName returns, but we cannot mount that device. To mount, we
183a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// have to use "/dev/ubiblockX_0" for rootfs. Stateful and OEM partitions are
184a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// mountable with "/dev/ubiX_0". The input is a partition device such as
185a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen// /dev/sda3. Return empty string on error.
186a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyenstd::string MakePartitionNameForMount(const std::string& part_name);
187a78b28c6f202b801fe7cb85246b33afe01aeaa7aNam T. Nguyen
1882e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymo// Set the read-only attribute on the block device |device| to the value passed
1892e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymo// in |read_only|. Return whether the operation succeeded.
1902e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymobool SetBlockDeviceReadOnly(const std::string& device, bool read_only);
1912e1de4f9f0457cd6117ddb22ffef72c8e2fbd4f3Alex Deymo
1923defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Synchronously mount or unmount a filesystem. Return true on success.
193390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo// When mounting, it will attempt to mount the device as the passed filesystem
194390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo// type |type|, with the passed |flags| options. If |type| is empty, "ext2",
195390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo// "ext3", "ext4" and "squashfs" will be tried.
196390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymobool MountFilesystem(const std::string& device,
197390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo                     const std::string& mountpoint,
198390efedcb7e17587da765b6d682077cb7fa46ee1Alex Deymo                     unsigned long flags,  // NOLINT(runtime/int)
19914dbd333439f34c648b9f783ffa656ef565de0ccAlex Deymo                     const std::string& type,
20014dbd333439f34c648b9f783ffa656ef565de0ccAlex Deymo                     const std::string& fs_mount_options);
2014fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesbool UnmountFilesystem(const std::string& mountpoint);
2023defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
203192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Returns the block count and the block byte size of the file system on
204d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov// |device| (which may be a real device or a path to a filesystem image) or on
205d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov// an opened file descriptor |fd|. The actual file-system size is |block_count|
206d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov// * |block_size| bytes. Returns true on success, false otherwise.
207d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkovbool GetFilesystemSize(const std::string& device,
208d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov                       int* out_block_count,
209d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov                       int* out_block_size);
210d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkovbool GetFilesystemSizeFromFD(int fd,
211d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov                             int* out_block_count,
212d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov                             int* out_block_size);
213d3f8c89b7ed8f7ea58fe08ad98949101569e9869Darin Petkov
214192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Determines the block count and block size of the ext3 fs. At least 2048 bytes
215192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// are required to parse the first superblock. Returns whether the buffer
216192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// contains a valid ext3 filesystem and the values were parsed.
217192393ba515e917d06248b6459b20b6547ef496dAlex Deymobool GetExt3Size(const uint8_t* buffer, size_t buffer_size,
218192393ba515e917d06248b6459b20b6547ef496dAlex Deymo                 int* out_block_count,
219192393ba515e917d06248b6459b20b6547ef496dAlex Deymo                 int* out_block_size);
220192393ba515e917d06248b6459b20b6547ef496dAlex Deymo
221192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Determines the block count and block size of the squashfs v4 fs. At least 96
222192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// bytes are required to parse the header of the filesystem. Since squashfs
223192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// doesn't define a physical block size, a value of 4096 is used for the block
224192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// size, which is the default padding when creating the filesystem.
225192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// Returns whether the buffer contains a valid squashfs v4 header and the size
226192393ba515e917d06248b6459b20b6547ef496dAlex Deymo// was parsed. Only little endian squashfs is supported.
227192393ba515e917d06248b6459b20b6547ef496dAlex Deymobool GetSquashfs4Size(const uint8_t* buffer, size_t buffer_size,
228192393ba515e917d06248b6459b20b6547ef496dAlex Deymo                      int* out_block_count,
229192393ba515e917d06248b6459b20b6547ef496dAlex Deymo                      int* out_block_size);
230192393ba515e917d06248b6459b20b6547ef496dAlex Deymo
231de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// Returns whether the filesystem is an ext[234] filesystem. In case of failure,
232de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// such as if the file |device| doesn't exists or can't be read, it returns
233de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// false.
234de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymobool IsExtFilesystem(const std::string& device);
235de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo
236de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// Returns whether the filesystem is a squashfs filesystem. In case of failure,
237de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// such as if the file |device| doesn't exists or can't be read, it returns
238de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo// false.
239de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymobool IsSquashfsFilesystem(const std::string& device);
240de942f30cf986cf6bfc55fb5f9af6d7fea4ae51bAlex Deymo
241032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymo// Returns a human-readable string with the file format based on magic constants
242032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymo// on the header of the file.
243032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymostd::string GetFileFormat(const std::string& path);
244032e772f76a6cd0b4caf1af7bd02dd81af2dc7ddAlex Deymo
245480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan// Returns the string representation of the given UTC time.
246480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan// such as "11/14/2011 14:05:30 GMT".
247480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasanstd::string ToString(const base::Time utc_time);
248480ddfa079ebd01ed87e495332dec121d9ae781fJay Srinivasan
249ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan// Returns true or false depending on the value of b.
250ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanstd::string ToString(bool b);
251ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
25219409b74019d787100b768306e75ab3e5882898dJay Srinivasan// Returns a string representation of the given enum.
25319409b74019d787100b768306e75ab3e5882898dJay Srinivasanstd::string ToString(DownloadSource source);
25419409b74019d787100b768306e75ab3e5882898dJay Srinivasan
2551c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo// Returns a string representation of the given enum.
2561c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymostd::string ToString(PayloadType payload_type);
2571c656c48886cf5054b526ed7e95b05903d7644dbAlex Deymo
258712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyes// Schedules a Main Loop callback to trigger the crash reporter to perform an
259712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyes// upload as if this process had crashed.
260712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyesvoid ScheduleCrashReporterUpload();
261712b3ace08181a22659e7dd87ca225e307d453f2Andrew de los Reyes
2625c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov// Fuzzes an integer |value| randomly in the range:
2635c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov// [value - range / 2, value + range - range / 2]
2645c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkovint FuzzInt(int value, unsigned int range);
2655c0a8afa879886800d82b195e3164e5a580a2cc7Darin Petkov
2663defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Log a string in hex to LOG(INFO). Useful for debugging.
267f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkovoid HexDumpArray(const uint8_t* const arr, const size_t length);
2683defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.cominline void HexDumpString(const std::string& str) {
269f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko  HexDumpArray(reinterpret_cast<const uint8_t*>(str.data()), str.size());
2703defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}
2713f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkoinline void HexDumpVector(const brillo::Blob& vect) {
272f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko  HexDumpArray(vect.data(), vect.size());
2733defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}
2743defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
2753defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comtemplate<typename KeyType, typename ValueType>
2763defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.combool MapContainsKey(const std::map<KeyType, ValueType>& m, const KeyType& k) {
2773defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  return m.find(k) != m.end();
2783defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}
2794fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyestemplate<typename KeyType>
2804fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyesbool SetContainsKey(const std::set<KeyType>& s, const KeyType& k) {
2814fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes  return s.find(k) != s.end();
2824fe15d017c145aca449c2248420c1b4ec8c23758Andrew de los Reyes}
2833defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
2840ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyestemplate<typename T>
2850ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyesbool VectorContainsValue(const std::vector<T>& vect, const T& value) {
286c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov  return std::find(vect.begin(), vect.end(), value) != vect.end();
2870ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyes}
2880ce161b06c0430de62658e1f6bcea7a4a97eddf7Andrew de los Reyes
289b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyestemplate<typename T>
290b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyesbool VectorIndexOf(const std::vector<T>& vect, const T& value,
291b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes                   typename std::vector<T>::size_type* out_index) {
292b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes  typename std::vector<T>::const_iterator it = std::find(vect.begin(),
293b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes                                                         vect.end(),
294b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes                                                         value);
295b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes  if (it == vect.end()) {
296b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes    return false;
297b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes  } else {
298b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes    *out_index = it - vect.begin();
299b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes    return true;
300b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes  }
301b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes}
302b10320d4f76a2d263566f6eed471921382fae800Andrew de los Reyes
303d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// Converts seconds into human readable notation including days, hours, minutes
304d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// and seconds. For example, 185 will yield 3m5s, 4300 will yield 1h11m40s, and
305d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// 360000 will yield 4d4h0m0s.  Zero padding not applied. Seconds are always
306d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// shown in the result.
307d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnoldstd::string FormatSecs(unsigned secs);
308d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold
309d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// Converts a TimeDelta into human readable notation including days, hours,
310d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// minutes, seconds and fractions of a second down to microsecond granularity,
311d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// as necessary; for example, an output of 5d2h0m15.053s means that the input
312d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// time was precise to the milliseconds only. Zero padding not applied, except
313d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnold// for fractions. Seconds are always shown, but fractions thereof are only shown
314973449e82eaf611adb911ac1b977baad2e2071e9David Zeuthen// when applicable. If |delta| is negative, the output will have a leading '-'
315973449e82eaf611adb911ac1b977baad2e2071e9David Zeuthen// followed by the absolute duration.
316d7b513d83954a28f3f71652b807aae4cc0c52f95Gilad Arnoldstd::string FormatTimeDelta(base::TimeDelta delta);
3171ebd813ad19214d0b59ade04005c3b84ae765e42Gilad Arnold
3182b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// This method transforms the given error code to be suitable for UMA and
3192b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// for error classification purposes by removing the higher order bits and
3202b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// aggregating error codes beyond the enum range, etc. This method is
3212b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// idempotent, i.e. if called with a value previously returned by this method,
3222b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan// it'll return the same value again.
323a99981fda75fe0b17e96c700e3ddc93eca1cebe5David ZeuthenErrorCode GetBaseErrorCode(ErrorCode code);
3242b5a0f065187fd19179e3809148dbfc376ada7a0Jay Srinivasan
325e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// Decodes the data in |base64_encoded| and stores it in a temporary
326e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// file. Returns false if the given data is empty, not well-formed
327e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// base64 or if an error occurred. If true is returned, the decoded
328e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// data is stored in the file returned in |out_path|. The file should
329e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen// be deleted when no longer needed.
330e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthenbool DecodeAndStoreBase64String(const std::string& base64_encoded,
331e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen                                base::FilePath *out_path);
332e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen
333639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// Converts |time| to an Omaha InstallDate which is defined as "the
334639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// number of PST8PDT calendar weeks since Jan 1st 2007 0:00 PST, times
335639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// seven" with PST8PDT defined as "Pacific Time" (e.g. UTC-07:00 if
336639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// daylight savings is observed and UTC-08:00 otherwise.)
337639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen//
338639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// If the passed in |time| variable is before Monday January 1st 2007
339639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// 0:00 PST, False is returned and the value returned in
340639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// |out_num_days| is undefined. Otherwise the number of PST8PDT
341639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// calendar weeks since that date times seven is returned in
342639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// |out_num_days| and the function returns True.
343639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen//
344639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// (NOTE: This function does not currently take daylight savings time
345639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// into account so the result may up to one hour off. This is because
346639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen// the glibc date and timezone routines depend on the TZ environment
3470b3db6b6040f53eb9859e614f7fe4c681213d33aAlex Deymo// variable and changing environment variables is not thread-safe.
348639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthenbool ConvertToOmahaInstallDate(base::Time time, int *out_num_days);
349639aa36fc7e27ba400402cd7a32b091f555783a6David Zeuthen
350b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo// Look for the minor version value in the passed |store| and set
351b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo// |minor_version| to that value. Return whether the value was found and valid.
3523f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool GetMinorVersion(const brillo::KeyValueStore& store,
353b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo                     uint32_t* minor_version);
35478750a450ce84b2d335134402d041aa8773ab8efAllie Wood
3553a92aa2fe6aafd1007b6427795dfe8711b6cb094Sen Jiang// Returns whether zlib |fingerprint| is compatible with zlib we are using.
3563a92aa2fe6aafd1007b6427795dfe8711b6cb094Sen Jiangbool IsZlibCompatible(const std::string& fingerprint);
3573a92aa2fe6aafd1007b6427795dfe8711b6cb094Sen Jiang
358568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// This function reads the specified data in |extents| into |out_data|. The
359568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// extents are read from the file at |path|. |out_data_size| is the size of
360568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// |out_data|. Returns false if the number of bytes to read given in
361568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood// |extents| does not equal |out_data_size|.
36241e3474eebe3748a45aba4b297a7a313a1006c6cGilad Arnoldbool ReadExtents(const std::string& path, const std::vector<Extent>& extents,
3633f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko                 brillo::Blob* out_data, ssize_t out_data_size,
364568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood                 size_t block_size);
365568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood
366dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo// Read the current boot identifier and store it in |boot_id|. This identifier
367dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo// is constants during the same boot of the kernel and is regenerated after
368dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo// reboot. Returns whether it succeeded getting the boot_id.
369dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymobool GetBootId(std::string* boot_id);
370dd132f39cced9028c01e98895a4f6c5fb9553de1Alex Deymo
3713defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}  // namespace utils
3723defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
37308fce04e5341c99f308ee7462b1f351f5232eacdJay Srinivasan
3743defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// Utility class to close a file descriptor
3753defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comclass ScopedFdCloser {
3763defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com public:
3774600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo  explicit ScopedFdCloser(int* fd) : fd_(fd) {}
3783defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  ~ScopedFdCloser() {
3794600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo    if (should_close_ && fd_ && (*fd_ >= 0) && !IGNORE_EINTR(close(*fd_)))
3804600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo      *fd_ = -1;
3813defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  }
3826f03a3b868d4b632931400628763036f79c449f7Darin Petkov  void set_should_close(bool should_close) { should_close_ = should_close; }
3833defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com private:
3843defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  int* fd_;
3854600b8b73e0a9cee5f17eef9e4b4a56166bf1910Alex Deymo  bool should_close_ = true;
38609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  DISALLOW_COPY_AND_ASSIGN(ScopedFdCloser);
38709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes};
38809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
38909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Utility class to delete a file when it goes out of scope.
39009e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesclass ScopedPathUnlinker {
39109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes public:
39252dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov  explicit ScopedPathUnlinker(const std::string& path)
39352dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov      : path_(path),
39452dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov        should_remove_(true) {}
39509e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  ~ScopedPathUnlinker() {
39652dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov    if (should_remove_ && unlink(path_.c_str()) < 0) {
39718f48aa4e962997a9ff12fac8933c94aac247fd9Alex Deymo      PLOG(ERROR) << "Unable to unlink path " << path_;
39809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes    }
39909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  }
40052dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov  void set_should_remove(bool should_remove) { should_remove_ = should_remove; }
40152dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov
40209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes private:
40309e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  const std::string path_;
40452dcaeb2d6c9239206e8fac3ae4c325b40ffbe25Darin Petkov  bool should_remove_;
40509e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  DISALLOW_COPY_AND_ASSIGN(ScopedPathUnlinker);
40609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes};
40709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
40809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes// Utility class to delete an empty directory when it goes out of scope.
40909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesclass ScopedDirRemover {
41009e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes public:
4116f03a3b868d4b632931400628763036f79c449f7Darin Petkov  explicit ScopedDirRemover(const std::string& path)
4126f03a3b868d4b632931400628763036f79c449f7Darin Petkov      : path_(path),
4136f03a3b868d4b632931400628763036f79c449f7Darin Petkov        should_remove_(true) {}
41409e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  ~ScopedDirRemover() {
4156f03a3b868d4b632931400628763036f79c449f7Darin Petkov    if (should_remove_ && (rmdir(path_.c_str()) < 0)) {
41609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes      PLOG(ERROR) << "Unable to remove dir " << path_;
4176f03a3b868d4b632931400628763036f79c449f7Darin Petkov    }
41809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  }
4196f03a3b868d4b632931400628763036f79c449f7Darin Petkov  void set_should_remove(bool should_remove) { should_remove_ = should_remove; }
4206f03a3b868d4b632931400628763036f79c449f7Darin Petkov
4216f03a3b868d4b632931400628763036f79c449f7Darin Petkov protected:
42209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  const std::string path_;
4236f03a3b868d4b632931400628763036f79c449f7Darin Petkov
4246f03a3b868d4b632931400628763036f79c449f7Darin Petkov private:
4256f03a3b868d4b632931400628763036f79c449f7Darin Petkov  bool should_remove_;
42609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  DISALLOW_COPY_AND_ASSIGN(ScopedDirRemover);
4273defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com};
4283defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4293defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// A little object to call ActionComplete on the ActionProcessor when
4303defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com// it's destructed.
4313defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comclass ScopedActionCompleter {
4323defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com public:
4333defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  explicit ScopedActionCompleter(ActionProcessor* processor,
4343defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com                                 AbstractAction* action)
4353defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      : processor_(processor),
4363defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com        action_(action),
437d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold        code_(ErrorCode::kError),
4383defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com        should_complete_(true) {}
4393defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  ~ScopedActionCompleter() {
4403defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    if (should_complete_)
441c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov      processor_->ActionComplete(action_, code_);
4423defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  }
443a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  void set_code(ErrorCode code) { code_ = code; }
4443defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  void set_should_complete(bool should_complete) {
4453defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    should_complete_ = should_complete;
4463defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  }
44733bae491eded4ef4f1eb4f4ef0f01ef0e5463f3aDavid Zeuthen  ErrorCode get_code() const { return code_; }
448c1a8b426be9542bc880923711ca508ea3f84000eDarin Petkov
4493defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com private:
4503defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  ActionProcessor* processor_;
4513defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  AbstractAction* action_;
452a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  ErrorCode code_;
4533defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  bool should_complete_;
4543defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  DISALLOW_COPY_AND_ASSIGN(ScopedActionCompleter);
4553defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com};
4563defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4573defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}  // namespace chromeos_update_engine
4583defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4593defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN_FALSE_ERRNO(_x)                                        \
4603defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  do {                                                                         \
4612b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen    bool _success = static_cast<bool>(_x);                                     \
4623defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    if (!_success) {                                                           \
4633defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      std::string _msg =                                                       \
4643defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com          chromeos_update_engine::utils::ErrnoNumberAsString(errno);           \
4653defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      LOG(ERROR) << #_x " failed: " << _msg;                                   \
4663defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      return false;                                                            \
4673defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    }                                                                          \
4683defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  } while (0)
4693defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4703defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN_FALSE(_x)                                              \
4713defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  do {                                                                         \
4722b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen    bool _success = static_cast<bool>(_x);                                     \
4733defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    if (!_success) {                                                           \
4743defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      LOG(ERROR) << #_x " failed.";                                            \
4753defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      return false;                                                            \
4763defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    }                                                                          \
4773defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  } while (0)
4783defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4793defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN_ERRNO(_x)                                              \
4803defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  do {                                                                         \
4812b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen    bool _success = static_cast<bool>(_x);                                     \
4823defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    if (!_success) {                                                           \
4833defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      std::string _msg =                                                       \
4843defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com          chromeos_update_engine::utils::ErrnoNumberAsString(errno);           \
4853defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      LOG(ERROR) << #_x " failed: " << _msg;                                   \
4863defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      return;                                                                  \
4873defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    }                                                                          \
4883defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  } while (0)
4893defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4903defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#define TEST_AND_RETURN(_x)                                                    \
4913defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  do {                                                                         \
4922b67a59a6975d4b5777ae40b638ee00acf7e54c8Nam T. Nguyen    bool _success = static_cast<bool>(_x);                                     \
4933defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    if (!_success) {                                                           \
4943defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      LOG(ERROR) << #_x " failed.";                                            \
4953defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com      return;                                                                  \
4963defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    }                                                                          \
4973defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  } while (0)
4983defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
4995c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le#define TEST_AND_RETURN_FALSE_ERRCODE(_x)                                      \
5005c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le  do {                                                                         \
5015c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le    errcode_t _error = (_x);                                                   \
5025c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le    if (_error) {                                                              \
5035c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le      errno = _error;                                                          \
5045c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le      LOG(ERROR) << #_x " failed: " << _error;                                 \
5055c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le      return false;                                                            \
5065c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le    }                                                                          \
5075c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le  } while (0)
5085c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le
50939910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif  // UPDATE_ENGINE_COMMON_UTILS_H_
510