orscmd: add minimal getcap and setcap tools
These are mostly intended for debugging and for emergency repairs. Optimized for minimal code size and dependencies, not for usability. Change-Id: I671850a03151dd716c715f953f0b2bc8dbacffe7
This commit is contained in:
@@ -13,12 +13,20 @@
|
||||
along with TWRP. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define __STDC_FORMAT_MACROS 1
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
// for setcap and getcap
|
||||
#include <sys/capability.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <linux/xattr.h>
|
||||
|
||||
#include "orscmd.h"
|
||||
#include "../variables.h"
|
||||
@@ -44,6 +52,45 @@ void print_usage(void) {
|
||||
printf("\nSee more documentation at http://teamw.in/openrecoveryscript\n");
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int read_fd, write_fd, index;
|
||||
char command[1024], result[512];
|
||||
@@ -57,6 +104,25 @@ int main(int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
sprintf(command, "%s", argv[1]);
|
||||
for (index = 2; index < argc; index++) {
|
||||
sprintf(command, "%s %s", command, argv[index]);
|
||||
|
||||
Reference in New Issue
Block a user