• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2013, Google Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *  * Neither the name of Google, Inc. nor the names of its contributors
15  *    may be used to endorse or promote products derived from this
16  *    software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <stdio.h>
35 #include <sys/ioctl.h>
36 #include <linux/fs.h>
37 #include <stdlib.h>
38 #include <cutils/properties.h>
39 
40 #include "utils.h"
41 #include "debug.h"
42 
43 #ifndef BLKDISCARD
44 #define BLKDISCARD _IO(0x12,119)
45 #endif
46 
47 #ifndef BLKSECDISCARD
48 #define BLKSECDISCARD _IO(0x12,125)
49 #endif
50 
51 #define READ_BUF_SIZE (16*1024)
52 
get_stream_size(FILE * stream)53 int get_stream_size(FILE *stream) {
54     int size;
55     fseek(stream, 0, SEEK_END);
56     size = ftell(stream);
57     fseek(stream, 0, SEEK_SET);
58     return size;
59 }
60 
get_block_device_size(int fd)61 uint64_t get_block_device_size(int fd)
62 {
63     uint64_t size = 0;
64     int ret;
65 
66     ret = ioctl(fd, BLKGETSIZE64, &size);
67 
68     if (ret)
69         return 0;
70 
71     return size;
72 }
73 
get_file_size(int fd)74 uint64_t get_file_size(int fd)
75 {
76     struct stat buf;
77     int ret;
78     int64_t computed_size;
79 
80     ret = fstat(fd, &buf);
81     if (ret)
82         return 0;
83 
84     if (S_ISREG(buf.st_mode))
85         computed_size = buf.st_size;
86     else if (S_ISBLK(buf.st_mode))
87         computed_size = get_block_device_size(fd);
88     else
89         computed_size = 0;
90 
91     return computed_size;
92 }
93 
get_file_size64(int fd)94 uint64_t get_file_size64(int fd)
95 {
96     struct stat64 buf;
97     int ret;
98     uint64_t computed_size;
99 
100     ret = fstat64(fd, &buf);
101     if (ret)
102         return 0;
103 
104     if (S_ISREG(buf.st_mode))
105         computed_size = buf.st_size;
106     else if (S_ISBLK(buf.st_mode))
107         computed_size = get_block_device_size(fd);
108     else
109         computed_size = 0;
110 
111     return computed_size;
112 }
113 
114 
strip(char * str)115 char *strip(char *str)
116 {
117     int n;
118 
119     n = strspn(str, " \t");
120     str += n;
121     n = strcspn(str, " \t");
122     str[n] = '\0';
123 
124     return str;
125 }
126 
wipe_block_device(int fd,int64_t len)127 int wipe_block_device(int fd, int64_t len)
128 {
129     uint64_t range[2];
130     int ret;
131 
132     range[0] = 0;
133     range[1] = len;
134     ret = ioctl(fd, BLKSECDISCARD, &range);
135     if (ret < 0) {
136         range[0] = 0;
137         range[1] = len;
138         ret = ioctl(fd, BLKDISCARD, &range);
139         if (ret < 0) {
140             D(WARN, "Discard failed\n");
141             return 1;
142         } else {
143             D(WARN, "Wipe via secure discard failed, used discard instead\n");
144             return 0;
145         }
146     }
147 
148     return 0;
149 }
150 
create_temp_file()151 int create_temp_file() {
152     char tempname[] = "/dev/fastboot_data_XXXXXX";
153     int fd;
154 
155     fd = mkstemp(tempname);
156     if (fd < 0)
157         return -1;
158 
159     unlink(tempname);
160 
161     return fd;
162 }
163 
bulk_write(int bulk_in,const char * buf,size_t length)164 ssize_t bulk_write(int bulk_in, const char *buf, size_t length)
165 {
166     size_t count = 0;
167     ssize_t ret;
168 
169     do {
170         ret = TEMP_FAILURE_RETRY(write(bulk_in, buf + count, length - count));
171         if (ret < 0) {
172             D(WARN, "[ bulk_write failed fd=%d length=%zu errno=%d %s ]",
173                     bulk_in, length, errno, strerror(errno));
174             return -1;
175         } else {
176             count += ret;
177         }
178     } while (count < length);
179 
180     D(VERBOSE, "[ bulk_write done fd=%d ]", bulk_in);
181     return count;
182 }
183 
bulk_read(int bulk_out,char * buf,size_t length)184 ssize_t bulk_read(int bulk_out, char *buf, size_t length)
185 {
186     ssize_t ret;
187     size_t n = 0;
188 
189     while (n < length) {
190         size_t to_read = (length - n > READ_BUF_SIZE) ? READ_BUF_SIZE : length - n;
191         ret = TEMP_FAILURE_RETRY(read(bulk_out, buf + n, to_read));
192         if (ret < 0) {
193             D(WARN, "[ bulk_read failed fd=%d length=%zu errno=%d %s ]",
194                     bulk_out, length, errno, strerror(errno));
195             return ret;
196         }
197         n += ret;
198         if (ret < (ssize_t)to_read) {
199             D(VERBOSE, "bulk_read short read, ret=%zd to_read=%zu n=%zu length=%zu",
200                     ret, to_read, n, length);
201             break;
202         }
203     }
204 
205     return n;
206 }
207 
208 #define NAP_TIME 200  // 200 ms between polls
wait_for_property(const char * name,const char * desired_value,int maxwait)209 static int wait_for_property(const char *name, const char *desired_value, int maxwait)
210 {
211     char value[PROPERTY_VALUE_MAX] = {'\0'};
212     int maxnaps = (maxwait * 1000) / NAP_TIME;
213 
214     if (maxnaps < 1) {
215         maxnaps = 1;
216     }
217 
218     while (maxnaps-- > 0) {
219         usleep(NAP_TIME * 1000);
220         if (property_get(name, value, NULL)) {
221             if (desired_value == NULL || strcmp(value, desired_value) == 0) {
222                 return 0;
223             }
224         }
225     }
226     return -1; /* failure */
227 }
228 
service_start(const char * service_name)229 int service_start(const char *service_name)
230 {
231     int result = 0;
232     char property_value[PROPERTY_VALUE_MAX];
233 
234     property_get(service_name, property_value, "");
235     if (strcmp("running", property_value) != 0) {
236         D(INFO, "Starting %s", service_name);
237         property_set("ctl.start", service_name);
238         if (wait_for_property(service_name, "running", 5))
239             result = -1;
240     }
241 
242     return result;
243 }
244 
service_stop(const char * service_name)245 int service_stop(const char *service_name)
246 {
247     int result = 0;
248 
249     D(INFO, "Stopping MDNSD");
250     property_set("ctl.stop", service_name);
251     if (wait_for_property(service_name, "stopped", 5))
252         result = -1;
253 
254     return result;
255 }
256 
ssh_server_start()257 int ssh_server_start()
258 {
259     return service_start("sshd");
260 }
261