mirror of
				https://github.com/meizu-m86/twrp_multirom_m86
				synced 2025-11-04 06:15:41 +08:00 
			
		
		
		
	Pull in most TWRP sources Stub out partition management code Make it compile -- probably will not boot Kind of a mess but have to start somewhere
		
			
				
	
	
		
			216 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			216 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (C) 2007 The Android Open Source Project
 | 
						|
 *
 | 
						|
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
 * you may not use this file except in compliance with the License.
 | 
						|
 * You may obtain a copy of the License at
 | 
						|
 *
 | 
						|
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 *
 | 
						|
 * Unless required by applicable law or agreed to in writing, software
 | 
						|
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
 * See the License for the specific language governing permissions and
 | 
						|
 * limitations under the License.
 | 
						|
 */
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <fcntl.h>
 | 
						|
#include <errno.h>
 | 
						|
#include <sys/mount.h>
 | 
						|
 | 
						|
#include "mounts.h"
 | 
						|
 | 
						|
typedef struct {
 | 
						|
    MountedVolume *volumes;
 | 
						|
    int volumes_allocd;
 | 
						|
    int volume_count;
 | 
						|
} MountsState;
 | 
						|
 | 
						|
static MountsState g_mounts_state = {
 | 
						|
    NULL,   // volumes
 | 
						|
    0,      // volumes_allocd
 | 
						|
    0       // volume_count
 | 
						|
};
 | 
						|
 | 
						|
static inline void
 | 
						|
free_volume_internals(const MountedVolume *volume, int zero)
 | 
						|
{
 | 
						|
    free((char *)volume->device);
 | 
						|
    free((char *)volume->mount_point);
 | 
						|
    free((char *)volume->filesystem);
 | 
						|
    free((char *)volume->flags);
 | 
						|
    if (zero) {
 | 
						|
        memset((void *)volume, 0, sizeof(*volume));
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#define PROC_MOUNTS_FILENAME   "/proc/mounts"
 | 
						|
 | 
						|
int
 | 
						|
scan_mounted_volumes()
 | 
						|
{
 | 
						|
    char buf[2048];
 | 
						|
    const char *bufp;
 | 
						|
    int fd;
 | 
						|
    ssize_t nbytes;
 | 
						|
 | 
						|
    if (g_mounts_state.volumes == NULL) {
 | 
						|
        const int numv = 32;
 | 
						|
        MountedVolume *volumes = malloc(numv * sizeof(*volumes));
 | 
						|
        if (volumes == NULL) {
 | 
						|
            errno = ENOMEM;
 | 
						|
            return -1;
 | 
						|
        }
 | 
						|
        g_mounts_state.volumes = volumes;
 | 
						|
        g_mounts_state.volumes_allocd = numv;
 | 
						|
        memset(volumes, 0, numv * sizeof(*volumes));
 | 
						|
    } else {
 | 
						|
        /* Free the old volume strings.
 | 
						|
         */
 | 
						|
        int i;
 | 
						|
        for (i = 0; i < g_mounts_state.volume_count; i++) {
 | 
						|
            free_volume_internals(&g_mounts_state.volumes[i], 1);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    g_mounts_state.volume_count = 0;
 | 
						|
 | 
						|
    /* Open and read the file contents.
 | 
						|
     */
 | 
						|
    fd = open(PROC_MOUNTS_FILENAME, O_RDONLY);
 | 
						|
    if (fd < 0) {
 | 
						|
        goto bail;
 | 
						|
    }
 | 
						|
    nbytes = read(fd, buf, sizeof(buf) - 1);
 | 
						|
    close(fd);
 | 
						|
    if (nbytes < 0) {
 | 
						|
        goto bail;
 | 
						|
    }
 | 
						|
    buf[nbytes] = '\0';
 | 
						|
 | 
						|
    /* Parse the contents of the file, which looks like:
 | 
						|
     *
 | 
						|
     *     # cat /proc/mounts
 | 
						|
     *     rootfs / rootfs rw 0 0
 | 
						|
     *     /dev/pts /dev/pts devpts rw 0 0
 | 
						|
     *     /proc /proc proc rw 0 0
 | 
						|
     *     /sys /sys sysfs rw 0 0
 | 
						|
     *     /dev/block/mtdblock4 /system yaffs2 rw,nodev,noatime,nodiratime 0 0
 | 
						|
     *     /dev/block/mtdblock5 /data yaffs2 rw,nodev,noatime,nodiratime 0 0
 | 
						|
     *     /dev/block/mmcblk0p1 /sdcard vfat rw,sync,dirsync,fmask=0000,dmask=0000,codepage=cp437,iocharset=iso8859-1,utf8 0 0
 | 
						|
     *
 | 
						|
     * The zeroes at the end are dummy placeholder fields to make the
 | 
						|
     * output match Linux's /etc/mtab, but don't represent anything here.
 | 
						|
     */
 | 
						|
    bufp = buf;
 | 
						|
    while (nbytes > 0) {
 | 
						|
        char device[64];
 | 
						|
        char mount_point[64];
 | 
						|
        char filesystem[64];
 | 
						|
        char flags[128];
 | 
						|
        int matches;
 | 
						|
 | 
						|
        /* %as is a gnu extension that malloc()s a string for each field.
 | 
						|
         */
 | 
						|
        matches = sscanf(bufp, "%63s %63s %63s %127s",
 | 
						|
                device, mount_point, filesystem, flags);
 | 
						|
 | 
						|
        if (matches == 4) {
 | 
						|
            device[sizeof(device)-1] = '\0';
 | 
						|
            mount_point[sizeof(mount_point)-1] = '\0';
 | 
						|
            filesystem[sizeof(filesystem)-1] = '\0';
 | 
						|
            flags[sizeof(flags)-1] = '\0';
 | 
						|
 | 
						|
            MountedVolume *v =
 | 
						|
                    &g_mounts_state.volumes[g_mounts_state.volume_count++];
 | 
						|
            v->device = strdup(device);
 | 
						|
            v->mount_point = strdup(mount_point);
 | 
						|
            v->filesystem = strdup(filesystem);
 | 
						|
            v->flags = strdup(flags);
 | 
						|
        } else {
 | 
						|
printf("matches was %d on <<%.40s>>\n", matches, bufp);
 | 
						|
        }
 | 
						|
 | 
						|
        /* Eat the line.
 | 
						|
         */
 | 
						|
        while (nbytes > 0 && *bufp != '\n') {
 | 
						|
            bufp++;
 | 
						|
            nbytes--;
 | 
						|
        }
 | 
						|
        if (nbytes > 0) {
 | 
						|
            bufp++;
 | 
						|
            nbytes--;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
 | 
						|
bail:
 | 
						|
//TODO: free the strings we've allocated.
 | 
						|
    g_mounts_state.volume_count = 0;
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
const MountedVolume *
 | 
						|
find_mounted_volume_by_device(const char *device)
 | 
						|
{
 | 
						|
    if (g_mounts_state.volumes != NULL) {
 | 
						|
        int i;
 | 
						|
        for (i = 0; i < g_mounts_state.volume_count; i++) {
 | 
						|
            MountedVolume *v = &g_mounts_state.volumes[i];
 | 
						|
            /* May be null if it was unmounted and we haven't rescanned.
 | 
						|
             */
 | 
						|
            if (v->device != NULL) {
 | 
						|
                if (strcmp(v->device, device) == 0) {
 | 
						|
                    return v;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
const MountedVolume *
 | 
						|
find_mounted_volume_by_mount_point(const char *mount_point)
 | 
						|
{
 | 
						|
    if (g_mounts_state.volumes != NULL) {
 | 
						|
        int i;
 | 
						|
        for (i = 0; i < g_mounts_state.volume_count; i++) {
 | 
						|
            MountedVolume *v = &g_mounts_state.volumes[i];
 | 
						|
            /* May be null if it was unmounted and we haven't rescanned.
 | 
						|
             */
 | 
						|
            if (v->mount_point != NULL) {
 | 
						|
                if (strcmp(v->mount_point, mount_point) == 0) {
 | 
						|
                    return v;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
unmount_mounted_volume(const MountedVolume *volume)
 | 
						|
{
 | 
						|
    /* Intentionally pass NULL to umount if the caller tries
 | 
						|
     * to unmount a volume they already unmounted using this
 | 
						|
     * function.
 | 
						|
     */
 | 
						|
    int ret = umount(volume->mount_point);
 | 
						|
    if (ret == 0) {
 | 
						|
        free_volume_internals(volume, 1);
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
remount_read_only(const MountedVolume* volume)
 | 
						|
{
 | 
						|
    return mount(volume->device, volume->mount_point, volume->filesystem,
 | 
						|
                 MS_NOATIME | MS_NODEV | MS_NODIRATIME |
 | 
						|
                 MS_RDONLY | MS_REMOUNT, 0);
 | 
						|
}
 |