source: trunk/software/tty/readtty_command.c @ 19

Last change on this file since 19 was 19, checked in by bouyer, 7 weeks ago

Also restricyt "E" command

File size: 2.8 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <string.h>
5#include <errno.h>
6#include <err.h>
7#include <fcntl.h>
8#include <signal.h>
9#include <termios.h>
10#include <sys/ioctl.h>
11#include <sys/select.h>
12#include <pwd.h>
13#include <grp.h>
14
15volatile int quit;
16const char *prog;
17
18static void
19set_quit(int s)
20{
21        quit = 1;
22}
23
24static void
25usage()
26{
27        errx(1, "usage: %s <device> <cmd>", prog);
28}
29
30static void
31readline(int d, char *buf, int l)
32{
33        int i;
34        int bytes;
35        do {
36                for (i = 0; i < l; i++) {
37                        do {
38                                bytes = read(d, &buf[i], 1);
39                                if (quit)
40                                        return;
41                        } while ((bytes < 0 && errno == EAGAIN) || buf[i] == '\r');
42                        if (bytes != 1) {
43                                fprintf(stderr, "readline: read %d\n", bytes);
44                                err(1, "read line");
45                        }
46                        if (buf[i] == '\n')
47                                break;
48                }
49        } while (i == 0);
50        if (buf[i] != '\n') {
51                warnx("realine: end of line not found");
52        }
53        buf[i] = '\0';
54}
55
56int
57main(int argc, char * const argv[])
58{
59        int d;
60        char buf[256];
61        int i;
62
63        struct termios t, ot;
64
65        prog = argv[0];
66        argc -= 1;
67        argv += 1;
68
69        if (argc != 2)
70                usage();
71        if (*argv[1] == 'P' || *argv[1] == 'E') {
72                /* check if user is in group wheel or sudo */
73                gid_t mygroups[64];
74                int ngroups = 64;
75                struct passwd *pwp = getpwuid(getuid());
76                if (pwp == NULL) {
77                        err(1, "getpwuid(%d)", getuid());
78                }
79                if ((i = getgrouplist(pwp->pw_name, pwp->pw_gid, mygroups, &ngroups)) < 0) {
80                        fprintf(stderr, "getgrouplist(%s,%d) fail: %d %d\n",
81                            pwp->pw_name, pwp->pw_gid, i, ngroups);
82                        exit(1);
83                }
84                for (i = 0; i < ngroups; i++) {
85                        struct group *grpp = getgrgid(mygroups[i]);
86                        if (grpp == NULL) {
87                                err(1, "getgrgid(%d)", mygroups[i]);
88                        }
89                        if (strcmp(grpp->gr_name, "wheel") == 0 ||
90                            strcmp(grpp->gr_name, "sudo") == 0) {
91                                break;
92                        }
93                }
94                if (i == ngroups) {
95                        errx(1, "command %s: permission denied", argv[1]);
96                }
97        }
98
99        d = open(argv[0], O_RDWR | O_NOCTTY | O_NONBLOCK, 0);
100        if (d < 0) {
101                err(1, "open %s", argv[0]);
102        }
103
104        if (tcgetattr(d, &ot) < 0) {
105                err(1, "tcgetattr");
106        }
107
108        quit = 0;
109
110        if (signal(SIGINT, set_quit) == SIG_ERR) {
111                err(1, "signal(SIGINT)");
112        }
113        if (signal(SIGQUIT, set_quit) == SIG_ERR) {
114                err(1, "signal(SIGQUIT)");
115        }
116        if (signal(SIGPIPE, set_quit) == SIG_ERR) {
117                err(1, "signal(SIGPIPE)");
118        }
119        if (signal(SIGTERM, set_quit) == SIG_ERR) {
120                err(1, "signal(SIGTERM)");
121        }
122
123        t = ot;
124        cfmakeraw(&t);
125        t.c_cflag |= CLOCAL;
126        t.c_cflag &= ~CRTSCTS;
127        cfsetspeed(&t, B921600);
128
129        if (tcsetattr(d, TCSANOW | TCSAFLUSH, &t) < 0) {
130                err(1, "tcsetattr");
131        }
132        do {
133                write(d, "M0\n", 3);
134                readline(d, buf, sizeof(buf));
135                if (quit)
136                        goto quit;
137        } while (memcmp(buf, "OK", 2) != 0);
138
139        snprintf(buf, sizeof(buf) - 1, "%s\n", argv[1]);
140        write(d, buf, strlen(buf));
141        readline(d, buf, sizeof(buf));
142        if (quit)
143                goto quit;
144        printf("%s\n", buf);
145quit:
146        if (fflush(stdout) == EOF) {
147                warn("fflush");
148        }
149        if (tcsetattr(d, TCSANOW, &ot) < 0) {
150                err(1, "restore tcsetattr");
151        }
152        exit(0);
153}
Note: See TracBrowser for help on using the repository browser.