1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdarg.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 24504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross#include <time.h> 25ae76f6dbcf3dfd6eda223911f91f4a1316433771Nick Kralevich#include <ftw.h> 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 27e46f9d510db9351682cf17c49115110870147335Stephen Smalley#include <selinux/label.h> 28dbd37f2e1da5b27ef1ad6d0cc9580e6893560f5fStephen Smalley#include <selinux/android.h> 29e46f9d510db9351682cf17c49115110870147335Stephen Smalley 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/socket.h> 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/un.h> 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* for ANDROID_SOCKET_* */ 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/sockets.h> 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <private/android_filesystem_config.h> 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 40e46f9d510db9351682cf17c49115110870147335Stephen Smalley#include "init.h" 41ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross#include "log.h" 42f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross#include "util.h" 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * android_name_to_id - returns the integer uid/gid associated with the given 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * name, or -1U on error. 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic unsigned int android_name_to_id(const char *name) 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 50de7f1ad86f532e79ea2a9f77b0147406a9ad971bEdwin Vane const struct android_id_info *info = android_ids; 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int n; 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (n = 0; n < android_id_count; n++) { 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(info[n].name, name)) 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return info[n].aid; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1U; 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * decode_uid - decodes and returns the given string, which can be either the 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * numeric or name representation, into the integer uid or gid. Returns -1U on 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * error. 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunsigned int decode_uid(const char *s) 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int v; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!s || *s == '\0') 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1U; 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (isalpha(s[0])) 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return android_name_to_id(s); 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = 0; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project v = (unsigned int) strtoul(s, 0, 0); 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (errno) 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1U; 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return v; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * create_socket - creates a Unix domain socket in ANDROID_SOCKET_DIR 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ("/dev/socket") as dictated in init.rc. This socket is inherited by the 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * daemon. We communicate the file descriptor's value via the environment 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * variable ANDROID_SOCKET_ENV_PREFIX<name> ("ANDROID_SOCKET_foo"). 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 888348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalleyint create_socket(const char *name, int type, mode_t perm, uid_t uid, 898348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalley gid_t gid, const char *socketcon) 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct sockaddr_un addr; 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd, ret; 938348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalley char *filecon; 948348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalley 958348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalley if (socketcon) 968348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalley setsockcreatecon(socketcon); 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = socket(PF_UNIX, type, 0); 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd < 0) { 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("Failed to open socket '%s': %s\n", name, strerror(errno)); 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1048348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalley if (socketcon) 1058348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalley setsockcreatecon(NULL); 1068348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalley 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(&addr, 0 , sizeof(addr)); 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project addr.sun_family = AF_UNIX; 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s", 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name); 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = unlink(addr.sun_path); 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret != 0 && errno != ENOENT) { 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("Failed to unlink old socket '%s': %s\n", name, strerror(errno)); 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto out_close; 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1188348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalley filecon = NULL; 119e46f9d510db9351682cf17c49115110870147335Stephen Smalley if (sehandle) { 1208348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalley ret = selabel_lookup(sehandle, &filecon, addr.sun_path, S_IFSOCK); 121e46f9d510db9351682cf17c49115110870147335Stephen Smalley if (ret == 0) 1228348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalley setfscreatecon(filecon); 123e46f9d510db9351682cf17c49115110870147335Stephen Smalley } 124e46f9d510db9351682cf17c49115110870147335Stephen Smalley 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = bind(fd, (struct sockaddr *) &addr, sizeof (addr)); 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret) { 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("Failed to bind socket '%s': %s\n", name, strerror(errno)); 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto out_unlink; 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 131e46f9d510db9351682cf17c49115110870147335Stephen Smalley setfscreatecon(NULL); 1328348d279c7ce1a2453965ba7f05a7b818d58886cStephen Smalley freecon(filecon); 133e46f9d510db9351682cf17c49115110870147335Stephen Smalley 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project chown(addr.sun_path, uid, gid); 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project chmod(addr.sun_path, perm); 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INFO("Created socket '%s' with mode '%o', user '%d', group '%d'\n", 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project addr.sun_path, perm, uid, gid); 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fd; 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectout_unlink: 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unlink(addr.sun_path); 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectout_close: 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* reads a file, making sure it is terminated with \n \0 */ 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid *read_file(const char *fn, unsigned *_sz) 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *data; 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int sz; 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 15538f368c1b3bac76d342189b6412691a217421178Nick Kralevich struct stat sb; 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = 0; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open(fn, O_RDONLY); 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) return 0; 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 16138f368c1b3bac76d342189b6412691a217421178Nick Kralevich // for security reasons, disallow world-writable 16238f368c1b3bac76d342189b6412691a217421178Nick Kralevich // or group-writable files 16338f368c1b3bac76d342189b6412691a217421178Nick Kralevich if (fstat(fd, &sb) < 0) { 16438f368c1b3bac76d342189b6412691a217421178Nick Kralevich ERROR("fstat failed for '%s'\n", fn); 16538f368c1b3bac76d342189b6412691a217421178Nick Kralevich goto oops; 16638f368c1b3bac76d342189b6412691a217421178Nick Kralevich } 16738f368c1b3bac76d342189b6412691a217421178Nick Kralevich if ((sb.st_mode & (S_IWGRP | S_IWOTH)) != 0) { 16838f368c1b3bac76d342189b6412691a217421178Nick Kralevich ERROR("skipping insecure file '%s'\n", fn); 16938f368c1b3bac76d342189b6412691a217421178Nick Kralevich goto oops; 17038f368c1b3bac76d342189b6412691a217421178Nick Kralevich } 17138f368c1b3bac76d342189b6412691a217421178Nick Kralevich 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sz = lseek(fd, 0, SEEK_END); 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(sz < 0) goto oops; 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(lseek(fd, 0, SEEK_SET) != 0) goto oops; 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data = (char*) malloc(sz + 2); 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(data == 0) goto oops; 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(read(fd, data, sz) != sz) goto oops; 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data[sz] = '\n'; 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data[sz+1] = 0; 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(_sz) *_sz = sz; 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return data; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectoops: 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(data != 0) free(data); 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 193f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross#define MAX_MTD_PARTITIONS 16 194f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross 195f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Crossstatic struct { 196f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross char name[16]; 197f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross int number; 198f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross} mtd_part_map[MAX_MTD_PARTITIONS]; 199f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross 200f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Crossstatic int mtd_part_count = -1; 201f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross 202f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Crossstatic void find_mtd_partitions(void) 203f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross{ 204f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross int fd; 205f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross char buf[1024]; 206f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross char *pmtdbufp; 207f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross ssize_t pmtdsize; 208f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross int r; 209f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross 210f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross fd = open("/proc/mtd", O_RDONLY); 211f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross if (fd < 0) 212f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross return; 213f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross 214f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross buf[sizeof(buf) - 1] = '\0'; 215f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross pmtdsize = read(fd, buf, sizeof(buf) - 1); 216f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross pmtdbufp = buf; 217f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross while (pmtdsize > 0) { 218f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross int mtdnum, mtdsize, mtderasesize; 219f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross char mtdname[16]; 220f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross mtdname[0] = '\0'; 221f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross mtdnum = -1; 222f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross r = sscanf(pmtdbufp, "mtd%d: %x %x %15s", 223f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross &mtdnum, &mtdsize, &mtderasesize, mtdname); 224f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross if ((r == 4) && (mtdname[0] == '"')) { 225f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross char *x = strchr(mtdname + 1, '"'); 226f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross if (x) { 227f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross *x = 0; 228f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross } 229f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross INFO("mtd partition %d, %s\n", mtdnum, mtdname + 1); 230f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross if (mtd_part_count < MAX_MTD_PARTITIONS) { 231f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross strcpy(mtd_part_map[mtd_part_count].name, mtdname + 1); 232f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross mtd_part_map[mtd_part_count].number = mtdnum; 233f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross mtd_part_count++; 234f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross } else { 235f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross ERROR("too many mtd partitions\n"); 236f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross } 237f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross } 238f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross while (pmtdsize > 0 && *pmtdbufp != '\n') { 239f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross pmtdbufp++; 240f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross pmtdsize--; 241f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross } 242f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross if (pmtdsize > 0) { 243f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross pmtdbufp++; 244f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross pmtdsize--; 245f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross } 246f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross } 247f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross close(fd); 248f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross} 249f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross 250f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Crossint mtd_name_to_number(const char *name) 251f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross{ 252f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross int n; 253f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross if (mtd_part_count < 0) { 254f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross mtd_part_count = 0; 255f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross find_mtd_partitions(); 256f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross } 257f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross for (n = 0; n < mtd_part_count; n++) { 258f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross if (!strcmp(name, mtd_part_map[n].name)) { 259f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross return mtd_part_map[n].number; 260f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross } 261f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross } 262f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross return -1; 263f24ed8ca0a13f1b97bd55d10f75a289bf9ccd98dColin Cross} 264504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross 265504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross/* 266504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross * gettime() - returns the time in seconds of the system's monotonic clock or 267504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross * zero on error. 268504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross */ 269504bc5175a8fe5a2f2552903afee761a86283cf4Colin Crosstime_t gettime(void) 270504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross{ 271504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross struct timespec ts; 272504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross int ret; 273504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross 274504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross ret = clock_gettime(CLOCK_MONOTONIC, &ts); 275504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross if (ret < 0) { 276504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno)); 277504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross return 0; 278504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross } 279504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross 280504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross return ts.tv_sec; 281504bc5175a8fe5a2f2552903afee761a86283cf4Colin Cross} 282b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross 283b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Crossint mkdir_recursive(const char *pathname, mode_t mode) 284b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross{ 285b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross char buf[128]; 286b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross const char *slash; 287b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross const char *p = pathname; 288b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross int width; 289b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross int ret; 290b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross struct stat info; 291b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross 292b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross while ((slash = strchr(p, '/')) != NULL) { 293b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross width = slash - pathname; 294b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross p = slash + 1; 295b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if (width < 0) 296b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross break; 297b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if (width == 0) 298b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross continue; 299b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if ((unsigned int)width > sizeof(buf) - 1) { 300b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross ERROR("path too long for mkdir_recursive\n"); 301b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross return -1; 302b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross } 303b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross memcpy(buf, pathname, width); 304b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross buf[width] = 0; 305b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if (stat(buf, &info) != 0) { 306e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley ret = make_dir(buf, mode); 307b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if (ret && errno != EEXIST) 308b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross return ret; 309b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross } 310b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross } 311e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley ret = make_dir(pathname, mode); 312b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if (ret && errno != EEXIST) 313b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross return ret; 314b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross return 0; 315b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross} 316b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross 31793ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig/* 31893ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig * replaces any unacceptable characters with '_', the 31993ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig * length of the resulting string is equal to the input string 32093ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig */ 321b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Crossvoid sanitize(char *s) 322b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross{ 32393ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig const char* accept = 32493ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig "abcdefghijklmnopqrstuvwxyz" 32593ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 32693ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig "0123456789" 32793ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig "_-."; 32893ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig 329b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if (!s) 330b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross return; 33193ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig 332ba95be58c596aa7b5034b1bce8f3fde97ae08780Christopher R. Palmer while (*s) { 33393ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig s += strspn(s, accept); 334ba95be58c596aa7b5034b1bce8f3fde97ae08780Christopher R. Palmer if (*s) *s++ = '_'; 33593ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig } 336b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross} 33793ca79b44535ee24ece08001e1948070db6ab6edJohan Redestig 3385b3aa21bc70d42b3fcb1764a1be04ab8db5ebfb9Chris Friesvoid make_link_init(const char *oldpath, const char *newpath) 339b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross{ 340b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross int ret; 341b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross char buf[256]; 342b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross char *slash; 343b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross int width; 344b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross 345b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross slash = strrchr(newpath, '/'); 346b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if (!slash) 347b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross return; 348b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross width = slash - newpath; 349b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if (width <= 0 || width > (int)sizeof(buf) - 1) 350b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross return; 351b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross memcpy(buf, newpath, width); 352b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross buf[width] = 0; 353b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross ret = mkdir_recursive(buf, 0755); 354b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if (ret) 355b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross ERROR("Failed to create directory %s: %s (%d)\n", buf, strerror(errno), errno); 356b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross 357b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross ret = symlink(oldpath, newpath); 358b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if (ret && errno != EEXIST) 359b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross ERROR("Failed to symlink %s to %s: %s (%d)\n", oldpath, newpath, strerror(errno), errno); 360b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross} 361b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross 362b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Crossvoid remove_link(const char *oldpath, const char *newpath) 363b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross{ 364b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross char path[256]; 365b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross ssize_t ret; 366b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross ret = readlink(newpath, path, sizeof(path) - 1); 367b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if (ret <= 0) 368b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross return; 369b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross path[ret] = 0; 370b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross if (!strcmp(path, oldpath)) 371b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross unlink(newpath); 372b0ab94b7d5a888f0b6920b156e5c6a075fa0741aColin Cross} 373cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross 374cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Crossint wait_for_file(const char *filename, int timeout) 375cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross{ 376cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross struct stat info; 377cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross time_t timeout_time = gettime() + timeout; 378cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross int ret = -1; 379cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross 380cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0)) 381cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross usleep(10000); 382cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross 383cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross return ret; 384cd0f173e2790ee068fd2a20bcfc6c20468e97e51Colin Cross} 385f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 386f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Crossvoid open_devnull_stdio(void) 387f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross{ 388f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross int fd; 389f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross static const char *name = "/dev/__null__"; 390f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) { 391f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross fd = open(name, O_RDWR); 392f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross unlink(name); 393f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross if (fd >= 0) { 394f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross dup2(fd, 0); 395f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross dup2(fd, 1); 396f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross dup2(fd, 2); 397f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross if (fd > 2) { 398f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross close(fd); 399f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross } 400f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross return; 401f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross } 402f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross } 403f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 404f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross exit(1); 405f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross} 406f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 407f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Crossvoid get_hardware_name(char *hardware, unsigned int *revision) 408f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross{ 409229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst const char *cpuinfo = "/proc/cpuinfo"; 410229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst char *data = NULL; 411229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst size_t len = 0, limit = 1024; 412f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross int fd, n; 413f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross char *x, *hw, *rev; 414f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 415f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross /* Hardware string was provided on kernel command line */ 416f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross if (hardware[0]) 417f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross return; 418f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 419229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst fd = open(cpuinfo, O_RDONLY); 420f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross if (fd < 0) return; 421f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 422229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst for (;;) { 423229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst x = realloc(data, limit); 424229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst if (!x) { 425229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst ERROR("Failed to allocate memory to read %s\n", cpuinfo); 426229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst goto done; 427229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst } 428229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst data = x; 429229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst 430229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst n = read(fd, data + len, limit - len); 431229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst if (n < 0) { 432229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst ERROR("Failed reading %s: %s (%d)\n", cpuinfo, strerror(errno), errno); 433229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst goto done; 434229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst } 435229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst len += n; 436229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst 437229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst if (len < limit) 438229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst break; 439229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst 440229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst /* We filled the buffer, so increase size and loop to read more */ 441229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst limit *= 2; 442229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst } 443f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 444229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst data[len] = 0; 445f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross hw = strstr(data, "\nHardware"); 446f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross rev = strstr(data, "\nRevision"); 447f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 448f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross if (hw) { 449f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross x = strstr(hw, ": "); 450f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross if (x) { 451f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross x += 2; 452f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross n = 0; 453742150c031756da1393bf4223b2468b17cb79326The Android Open Source Project while (*x && *x != '\n') { 454742150c031756da1393bf4223b2468b17cb79326The Android Open Source Project if (!isspace(*x)) 455742150c031756da1393bf4223b2468b17cb79326The Android Open Source Project hardware[n++] = tolower(*x); 456f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross x++; 457f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross if (n == 31) break; 458f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross } 459f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross hardware[n] = 0; 460f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross } 461f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross } 462f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 463f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross if (rev) { 464f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross x = strstr(rev, ": "); 465f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross if (x) { 466f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross *revision = strtoul(x + 2, 0, 16); 467f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross } 468f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross } 469229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst 470229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurstdone: 471229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst close(fd); 472229dc35f699f144e5e3ccd8062bba8f6e650cfdcJon Medhurst free(data); 473f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross} 4742b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine 4752b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkinevoid import_kernel_cmdline(int in_qemu, 4762b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine void (*import_kernel_nv)(char *name, int in_qemu)) 4772b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine{ 4782e63e71f3116f0330b3bf61dde7deca235dd40acAndrew Boie char cmdline[2048]; 4792b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine char *ptr; 4802b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine int fd; 4812b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine 4822b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine fd = open("/proc/cmdline", O_RDONLY); 4832b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine if (fd >= 0) { 4842e63e71f3116f0330b3bf61dde7deca235dd40acAndrew Boie int n = read(fd, cmdline, sizeof(cmdline) - 1); 4852b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine if (n < 0) n = 0; 4862b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine 4872b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine /* get rid of trailing newline, it happens */ 4882b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine if (n > 0 && cmdline[n-1] == '\n') n--; 4892b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine 4902b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine cmdline[n] = 0; 4912b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine close(fd); 4922b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine } else { 4932b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine cmdline[0] = 0; 4942b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine } 4952b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine 4962b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine ptr = cmdline; 4972b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine while (ptr && *ptr) { 4982b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine char *x = strchr(ptr, ' '); 4992b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine if (x != 0) *x++ = 0; 5002b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine import_kernel_nv(ptr, in_qemu); 5012b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine ptr = x; 5022b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine } 5032b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine} 504e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley 505e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalleyint make_dir(const char *path, mode_t mode) 506e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley{ 507e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley int rc; 508e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley 509e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley char *secontext = NULL; 510e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley 511e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley if (sehandle) { 512e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley selabel_lookup(sehandle, &secontext, path, mode); 513e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley setfscreatecon(secontext); 514e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley } 515e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley 516e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley rc = mkdir(path, mode); 517e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley 518e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley if (secontext) { 519e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley int save_errno = errno; 520e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley freecon(secontext); 521e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley setfscreatecon(NULL); 522e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley errno = save_errno; 523e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley } 524b5982bf7c65b30be981ecfe1847437b05e32b2bbKenny Root 525e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley return rc; 526e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley} 527e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley 528dbd37f2e1da5b27ef1ad6d0cc9580e6893560f5fStephen Smalleyint restorecon(const char* pathname) 529e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley{ 53027a93650c0df02e4cd3c48bbec8acee8b817a012Stephen Smalley return selinux_android_restorecon(pathname, 0); 531ae76f6dbcf3dfd6eda223911f91f4a1316433771Nick Kralevich} 532ae76f6dbcf3dfd6eda223911f91f4a1316433771Nick Kralevich 533ae76f6dbcf3dfd6eda223911f91f4a1316433771Nick Kralevichint restorecon_recursive(const char* pathname) 534ae76f6dbcf3dfd6eda223911f91f4a1316433771Nick Kralevich{ 53527a93650c0df02e4cd3c48bbec8acee8b817a012Stephen Smalley return selinux_android_restorecon(pathname, SELINUX_ANDROID_RESTORECON_RECURSE); 536ae76f6dbcf3dfd6eda223911f91f4a1316433771Nick Kralevich} 537