daea84cd54682ad10ec37da119d0786cb39ffefe
[cascardo/b2hw.git] / main.c
1 /*
2  * Copyright (C) 2016  Thadeu Lima de Souza Cascardo <cascardo@cascardo.eti.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, visit the http://fsf.org website.
16  */
17
18 #include "init.h"
19 #include <stdio.h>
20
21 #include <stdlib.h>
22 #include <fcntl.h>
23 #include <sys/ioctl.h>
24 #include <sys/mount.h>
25 #include <sys/stat.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30
31 #define PREFIX "/sys/class/android_usb/android0/"
32
33 int do_write(char *fname, char *text)
34 {
35         int fd;
36         fd = open(fname, O_WRONLY);
37         write(fd, text, strlen(text));
38         close(fd);
39         return 0;
40 }
41
42 int do_read(char *fname, char *buffer, size_t len)
43 {
44         int fd;
45         int r;
46         fd = open(fname, O_RDONLY);
47         if (fd < 0) {
48                 fprintf(stderr, "failed to open %s: %s\n", fname,
49                         strerror(errno));
50                 return -1;
51         }
52         r = read(fd, buffer, len);
53         close(fd);
54         return r;
55 }
56
57 int
58 do_mknod(char *path, char *name, int block, int wait)
59 {
60         char *fullpath;
61         size_t len;
62         int r;
63         char dev[33];
64         int maj, min;
65         len = strlen(path) + strlen(name) + 6;
66         fullpath = malloc(len);
67         if (!fullpath) {
68                 fprintf(stderr, "failed to allocate buffer\n");
69                 return -1;
70         }
71         snprintf(fullpath, len, "%s/%s/dev", path, name);
72         do {
73                 r = do_read(fullpath, dev, sizeof(dev));
74                 if (r < 0 && !wait) {
75                         fprintf(stderr, "failed to read %s: %s\n", fullpath,
76                                         strerror(errno));
77                         goto out;
78                 }
79         } while (r < 0 && wait);
80         r = sscanf(dev, "%d:%d", &maj, &min);
81         if (r < 0) {
82                 fprintf(stderr, "failed to read devno from %s\n", dev);
83                 goto out;
84         }
85         snprintf(fullpath, len, "/dev/%s", name);
86         r = mknod(fullpath, 0666 | (block ? S_IFBLK : S_IFCHR), makedev(maj, min));
87         if (r < 0) {
88                 fprintf(stderr, "failed to mknod %s: %s\n", fullpath,
89                                 strerror(errno));
90         }
91 out:
92         free(fullpath);
93         return r;
94 }
95
96 int main(int argc, char **argv)
97 {
98         int r;
99         int fd = -1;
100         int i;
101         char *args[] = { "bash", "-l", NULL };
102         char demo[2];
103         r = devmount_setup();
104         if (r < 0) {
105                 fprintf(stderr, "failed to mount devtmpfs, proceeding anyway\n");
106         }
107         r = sysfsmount_setup();
108         if (r < 0) {
109                 fprintf(stderr, "failed to mount sysfs, proceeding anyway\n");
110         }
111         do_write(PREFIX "/enable", "0");
112         do_write(PREFIX "/idVendor", "04E8");
113         do_write(PREFIX "/idProduct", "6860");
114         do_write(PREFIX "/f_acm/acm_transports", "tty");
115         do_write(PREFIX "/functions", "acm");
116         do_write(PREFIX "/enable", "1");
117         do_mknod("/sys/class/tty", "ttyGS0", 0, 1);
118         fd = open("/dev/ttyGS0", O_RDWR);
119         for (i = 0; i < 10; i++) {
120                 write(fd, "Hello World!\n", 13);
121                 sleep(1);
122         }
123         read(fd, demo, 2);
124         write(fd, "G\n", 2);
125         dup2(fd, 0);
126         dup2(fd, 1);
127         dup2(fd, 2);
128         read(fd, demo, 2);
129         printf("N\n");
130         r = do_mknod("/sys/block/mmcblk1", "mmcblk1p3", 1, 1);
131         if (r < 0) {
132                 fprintf(stderr, "Failed to create mmcblk1p3\n");
133         }
134         read(fd, demo, 2);
135         printf("U\n");
136         printf("Mounting root\n");
137         r = mkdir("/root", 0755);
138         if (r) printf("failed mkdir\n");
139         r = mount("/dev/mmcblk1p3", "/root", "ext4", MS_NOATIME, NULL);
140         if (r) printf("failed mount: %d\n", errno);
141         printf("Chroot and chdir\n");
142         r = chdir("/root");
143         if (r) printf("failed first chdir\n");
144         r = chroot("/root");
145         if (r) printf("failed chroot\n");
146         r = chdir("/");
147         if (r) printf("failed second chdir\n");
148         execve("/bin/bash", args, NULL);
149         return 0;
150 }