orscmd.cpp 4.43 KB
Newer Older
Ethan Yonker's avatar
Ethan Yonker committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
		TWRP is free software: you can redistribute it and/or modify
		it under the terms of the GNU General Public License as published by
		the Free Software Foundation, either version 3 of the License, or
		(at your option) any later version.

		TWRP is distributed in the hope that it will be useful,
		but WITHOUT ANY WARRANTY; without even the implied warranty of
		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
		GNU General Public License for more details.

		You should have received a copy of the GNU General Public License
		along with TWRP.  If not, see <http://www.gnu.org/licenses/>.
*/

16
#define __STDC_FORMAT_MACROS 1
Ethan Yonker's avatar
Ethan Yonker committed
17 18 19 20 21 22
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
23 24 25 26 27 28 29
#include <errno.h>
#include <inttypes.h>

// for setcap and getcap
#include <sys/capability.h>
#include <sys/xattr.h>
#include <linux/xattr.h>
Ethan Yonker's avatar
Ethan Yonker committed
30 31 32 33 34 35 36 37 38 39 40 41 42

#include "orscmd.h"
#include "../variables.h"

void print_version(void) {
	printf("TWRP openrecoveryscript command line tool, TWRP version %s\n\n", TW_VERSION_STR);
}

void print_usage(void) {
	print_version();
	printf("Allows command line usage of TWRP via openrecoveryscript commands.\n");
	printf("Some common commands include:\n");
	printf("  install /path/to/update.zip\n");
nailyk-fr's avatar
nailyk-fr committed
43 44 45
	printf("  backup <SDCRBAEM> [backupname]\n");
	printf("  restore <SDCRBAEM> [backupname]\n");
	printf("  wipe <partition name>\n");
Ethan Yonker's avatar
Ethan Yonker committed
46
	printf("  sideload\n");
nailyk-fr's avatar
nailyk-fr committed
47 48
	printf("  set <variable> [value]\n");
	printf("  decrypt <password>\n");
bigbiff's avatar
bigbiff committed
49
	printf("  remountrw\n");
nailyk-fr's avatar
nailyk-fr committed
50
	printf("\nSee more documentation at https://twrp.me/faq/openrecoveryscript.html\n");
Ethan Yonker's avatar
Ethan Yonker committed
51 52
}

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
int do_setcap(const char* filename, const char* capabilities)
{
	uint64_t caps;
	if (sscanf(capabilities, "%" SCNi64, &caps) != 1)
	{
		printf("setcap: invalid capabilities \"%s\"\n", filename);
		return 1;
	}
	struct vfs_cap_data cap_data;
	memset(&cap_data, 0, sizeof(cap_data));
	cap_data.magic_etc = VFS_CAP_REVISION | VFS_CAP_FLAGS_EFFECTIVE;
	cap_data.data[0].permitted = (uint32_t) (caps & 0xffffffff);
	cap_data.data[0].inheritable = 0;
	cap_data.data[1].permitted = (uint32_t) (caps >> 32);
	cap_data.data[1].inheritable = 0;
	if (setxattr(filename, XATTR_NAME_CAPS, &cap_data, sizeof(cap_data), 0) < 0) {
		printf("setcap of %s to %" PRIx64 " failed: %s\n",
				filename, caps, strerror(errno));
		return 1;
	}
	return 0;
}

int do_getcap(const char* filename)
{
	struct vfs_cap_data cap_data;
	memset(&cap_data, 0, sizeof(cap_data));
	int rc = getxattr(filename, XATTR_NAME_CAPS, &cap_data, sizeof(vfs_cap_data));
	if (rc > 0)
	{
		uint64_t caps = (uint64_t) cap_data.data[1].permitted << 32 | cap_data.data[0].permitted;
		printf("0x%" PRIx64 "\n", caps);
	}
	else
		printf("getcap of %s failed: %s\n", filename, strerror(errno));

	return rc > 0;
}

Ethan Yonker's avatar
Ethan Yonker committed
92 93 94 95 96 97 98 99 100 101 102 103 104
int main(int argc, char **argv) {
	int read_fd, write_fd, index;
	char command[1024], result[512];

	if (argc < 2 || strcmp(argv[1], "help") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "?") == 0 || strcmp(argv[1], "-h") == 0) {
		print_usage();
		return 0;
	}
	if (strcmp(argv[1], "version") == 0 || strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) {
		print_version();
		return 0;
	}

105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
	if (strcmp(argv[1], "setcap") == 0) {
		if (argc != 4)
		{
			printf("Usage: setcap filename capabilities\n\n"
				"capabilities must be specified as a number. Prefix with 0x for hexadecimal.\n");
			return 1;
		}
		return do_setcap(argv[2], argv[3]);
	}

	if (strcmp(argv[1], "getcap") == 0) {
		if (argc != 3)
		{
			printf("Usage: getcap filename\n");
			return 1;
		}
		return do_getcap(argv[2]);
	}

Ethan Yonker's avatar
Ethan Yonker committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
	sprintf(command, "%s", argv[1]);
	for (index = 2; index < argc; index++) {
		sprintf(command, "%s %s", command, argv[index]);
	}

	write_fd = open(ORS_INPUT_FILE, O_WRONLY);
	if (write_fd < 0) {
		printf("TWRP does not appear to be running. Waiting for TWRP to start . . .\n");
		printf("Press CTRL + C to quit.\n");
		while (write_fd < 0)
			write_fd = open(ORS_INPUT_FILE, O_WRONLY);
	}
	if (write(write_fd, command, sizeof(command)) != sizeof(command)) {
		printf("Error sending command.\n");
		close(write_fd);
		return -1;
	}
	read_fd = open(ORS_OUTPUT_FILE, O_RDONLY);
	if (read_fd < 0) {
		printf("Unable to open %s for read.\n", ORS_OUTPUT_FILE);
		return -1;
	}
	memset(&result, 0, sizeof(result));
	while (read(read_fd, &result, sizeof(result)) > 0) {
		result[510] = '\n';
		result[511] = '\0';
		printf("%s", result);
		memset(&result, 0, sizeof(result));
	}
	close(write_fd);
	close(read_fd);
	return 0;
}