blob: 8c015d84ef6d9246addd37f5e392698dba68274b [file] [log] [blame]
adlr@google.com3defe6a2009-12-04 20:57:17 +00001// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "update_engine/omaha_request_prep_action.h"
6#include <sys/utsname.h>
Andrew de los Reyes970bb282009-12-09 16:34:04 -08007#include <errno.h>
adlr@google.com3defe6a2009-12-04 20:57:17 +00008#include <string>
Andrew de los Reyes970bb282009-12-09 16:34:04 -08009#include "base/string_util.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000010#include "update_engine/utils.h"
11
12using std::string;
13
14// This gathers local system information and prepares info used by the
15// update check action.
16
Andrew de los Reyes970bb282009-12-09 16:34:04 -080017namespace {
18const string OmahaIdPath() {
19 return chromeos_update_engine::utils::kStatefulPartition + "/etc/omaha_id";
20}
21} // namespace {}
22
adlr@google.com3defe6a2009-12-04 20:57:17 +000023namespace chromeos_update_engine {
24
25void OmahaRequestPrepAction::PerformAction() {
26 // TODO(adlr): honor force_full_update_
Andrew de los Reyes970bb282009-12-09 16:34:04 -080027 ScopedActionCompleter completer(processor_, this);
28 string machine_id;
29 TEST_AND_RETURN(GetMachineId(&machine_id));
adlr@google.com3defe6a2009-12-04 20:57:17 +000030 const string version(GetLsbValue("GOOGLE_RELEASE"));
31 const string sp(version + "_" + GetMachineType());
32 const string track(GetLsbValue("GOOGLE_TRACK"));
33
34 UpdateCheckParams out(machine_id, // machine_id
35 machine_id, // user_id (use machine_id)
36 UpdateCheckParams::kOsPlatform,
37 UpdateCheckParams::kOsVersion,
38 sp, // e.g. 0.2.3.3_i686
39 UpdateCheckParams::kAppId,
40 version, // app version (from lsb-release)
41 "en-US", //lang
42 track); // track
43
44 CHECK(HasOutputPipe());
45 SetOutputObject(out);
Andrew de los Reyes970bb282009-12-09 16:34:04 -080046 completer.set_success(true);
adlr@google.com3defe6a2009-12-04 20:57:17 +000047}
48
Andrew de los Reyes970bb282009-12-09 16:34:04 -080049namespace {
50const size_t kGuidDataByteLength = 128 / 8;
51const string::size_type kGuidStringLength = 38;
52// Formats 16 bytes (128 bits) of data as a GUID:
53// "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" where X is a hex digit
54string GuidFromData(const unsigned char data[kGuidDataByteLength]) {
55 return StringPrintf(
56 "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
57 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
58 data[8], data[9], data[10], data[11], data[12], data[13], data[14],
59 data[15]);
60}
61}
62
63// Returns true on success.
64bool OmahaRequestPrepAction::GetMachineId(std::string* out_id) const {
65 // See if we have an existing Machine ID
66 const string omaha_id_path = root_ + OmahaIdPath();
67
68 if (utils::ReadFileToString(omaha_id_path, out_id) &&
69 out_id->size() == kGuidStringLength) {
70 return true;
adlr@google.com3defe6a2009-12-04 20:57:17 +000071 }
Andrew de los Reyes970bb282009-12-09 16:34:04 -080072
73 // Create a new ID
74 int rand_fd = open("/dev/urandom", O_RDONLY, 0);
75 TEST_AND_RETURN_FALSE_ERRNO(rand_fd >= 0);
76 ScopedFdCloser rand_fd_closer(&rand_fd);
77 unsigned char buf[kGuidDataByteLength];
78 size_t bytes_read = 0;
79 while (bytes_read < sizeof(buf)) {
80 ssize_t rc = read(rand_fd, buf + bytes_read, sizeof(buf) - bytes_read);
81 TEST_AND_RETURN_FALSE_ERRNO(rc > 0);
82 bytes_read += rc;
83 }
84 string guid = GuidFromData(buf);
85 TEST_AND_RETURN_FALSE(
86 utils::WriteFile(omaha_id_path.c_str(), guid.data(), guid.size()));
87 *out_id = guid;
88 return true;
adlr@google.com3defe6a2009-12-04 20:57:17 +000089}
90
91std::string OmahaRequestPrepAction::GetLsbValue(const std::string& key) const {
92 string files[] = {utils::kStatefulPartition + "/etc/lsb-release",
93 "/etc/lsb-release"};
94 for (unsigned int i = 0; i < arraysize(files); i++) {
95 string file_data;
96 if (!utils::ReadFileToString(root_ + files[i], &file_data))
97 continue;
98 string::size_type pos = 0;
99 if (!utils::StringHasPrefix(file_data, key + "=")) {
100 pos = file_data.find(string("\n") + key + "=");
101 if (pos != string::npos)
102 pos++; // advance past \n
103 }
104 if (pos == string::npos)
105 continue;
106 pos += key.size() + 1; // advance past the key and the '='
107 string::size_type endpos = file_data.find('\n', pos);
108 string::size_type length =
109 (endpos == string::npos ? string::npos : endpos - pos);
110 return file_data.substr(pos, length);
111 }
112 // not found
113 return "";
114}
115
116std::string OmahaRequestPrepAction::GetMachineType() const {
117 struct utsname buf;
118 string ret;
119 if (uname(&buf) == 0)
120 ret = buf.machine;
121 return ret;
122}
123
124} // namespace chromeos_update_engine