Skip to content

Commit

Permalink
Merge pull request #84 from bndeff/usbapi
Browse files Browse the repository at this point in the history
Add a USB API compatible with libusb
  • Loading branch information
xalexalex authored Oct 6, 2019
2 parents 82ec2e3 + e19c3ca commit 97d7297
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 4 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ termux-api: termux-api.c
install: termux-api
mkdir -p $(PREFIX)/bin/ $(PREFIX)/libexec/
install termux-api $(PREFIX)/libexec/
install termux-callback $(PREFIX)/libexec/
install scripts/* $(PREFIX)/bin/

.PHONY: install
57 changes: 57 additions & 0 deletions scripts/termux-usb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/data/data/com.termux/files/usr/bin/bash
set -e -u

SCRIPTNAME=termux-usb
show_usage () {
echo "Usage: $SCRIPTNAME [-l | [-r] [-e command] device]"
echo "List or access USB devices. Devices cannot be accessed directly,"
echo " only using $SCRIPTNAME."
echo " -l list available devices"
echo " -r show permission request dialog if necessary"
echo " -e command execute the specified command with a file descriptor"
echo " referring to the device as its argument"
exit 0
}

ACTION="permission"
PARAMS=""
MASK=0
while getopts :hlre: option
do
case "$option" in
h) show_usage;;
l) ACTION="list"; ((MASK |= 1));;
r) PARAMS="$PARAMS --ez request true"; ((MASK |= 2));;
e) ACTION="open"; export TERMUX_CALLBACK="$OPTARG"; ((MASK |= 2));;
?) echo "$SCRIPTNAME: illegal option -$OPTARG"; exit 1;
esac
done
shift $(($OPTIND-1))

if [ $MASK -eq 3 ]; then echo "$SCRIPTNAME: -l cannot be combined with other options"; exit 1; fi

if [ "$ACTION" == "list" ]
then
if [ $# -gt 0 ]; then echo "$SCRIPTNAME: too many arguments"; exit 1; fi
else
if [ $# -gt 1 ]; then echo "$SCRIPTNAME: too many arguments"; exit 1; fi
if [ $# -lt 1 ]; then echo "$SCRIPTNAME: missing -l or device path"; exit 1; fi
PARAMS="$PARAMS --es device $1"
fi

CMD="/data/data/com.termux/files/usr/libexec/termux-api Usb -a $ACTION $PARAMS"

if [ "$ACTION" == "permission" ]
then
if [ "$($CMD)" == "yes" ]
then
echo "Access granted."
exit 0
else
echo "Access denied."
exit 1
fi
else
$CMD
fi

38 changes: 34 additions & 4 deletions termux-api.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ _Noreturn void exec_am_broadcast(int argc, char** argv, char* input_address_stri
exit(1);
}

_Noreturn void exec_callback(int fd)
{
char *fds;
if(asprintf(&fds, "%d", fd) == -1) { perror("asprintf"); }
execl("/data/data/com.termux/files/usr/libexec/termux-callback", "termux-callback", fds, NULL);
perror("execl(\"/data/data/com.termux/files/usr/libexec/termux-callback\")");
exit(1);
}

void generate_uuid(char* str) {
sprintf(str, "%x%x-%x-%x-%x-%x%x%x",
arc4random(), arc4random(), // Generates a 64-bit Hex number
Expand Down Expand Up @@ -93,13 +102,32 @@ void* transmit_stdin_to_socket(void* arg) {
}

// Main thread function which reads from input socket and writes to stdout.
void transmit_socket_to_stdout(int input_socket_fd) {
int transmit_socket_to_stdout(int input_socket_fd) {
ssize_t len;
char buffer[1024];
while ((len = read(input_socket_fd, &buffer, sizeof(buffer))) > 0) {
char cbuf[256];
struct iovec io = { .iov_base = buffer, .iov_len = sizeof(buffer) };
struct msghdr msg = { 0 };
int fd = -1; // An optional file descriptor received through the socket
msg.msg_iov = &io;
msg.msg_iovlen = 1;
msg.msg_control = cbuf;
msg.msg_controllen = sizeof(cbuf);
while ((len = recvmsg(input_socket_fd, &msg, 0)) > 0) {
struct cmsghdr * cmsg = CMSG_FIRSTHDR(&msg);
if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmsg->cmsg_type == SCM_RIGHTS) {
fd = *((int *) CMSG_DATA(cmsg));
}
}
// A file descriptor must be accompanied by a non-empty message,
// so we use "@" when we don't want any output.
if (fd != -1 && len == 1 && buffer[0] == '@') { len = 0; }
write(STDOUT_FILENO, buffer, len);
msg.msg_controllen = sizeof(cbuf);
}
if (len < 0) perror("read()");
if (len < 0) perror("recvmsg()");
return fd;
}

int main(int argc, char** argv) {
Expand Down Expand Up @@ -149,7 +177,9 @@ int main(int argc, char** argv) {
pthread_t transmit_thread;
pthread_create(&transmit_thread, NULL, transmit_stdin_to_socket, &output_server_socket);

transmit_socket_to_stdout(input_client_socket);
int fd = transmit_socket_to_stdout(input_client_socket);
close(input_client_socket);
if (fd != -1) { exec_callback(fd); }

return 0;
}
Expand Down
4 changes: 4 additions & 0 deletions termux-callback
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/data/data/com.termux/files/usr/bin/bash
set -e -u
$TERMUX_CALLBACK "$@"

0 comments on commit 97d7297

Please sign in to comment.