Date:2011-11-21 21:12:51 (7 years 6 months ago)
Author:Werner Almesberger
Commit:f3e1f925c4333ac20d375f4aa5f629ad40c87306
Message:neocon.c: copyright update and whitespace cleanup

Now conforms to Linux kernel style.
Files: neocon/neocon.c (4 diffs)

Change Details

neocon/neocon.c
22 * neocon.c - An interface for changing tty devices
33 *
44 * Copyright (C) 2007, 2008 by OpenMoko, Inc.
5 * Written by Werner Almesberger <werner@openmoko.org>
5 * Copyright 2011 by Werner Almesberger
6 * Written by Werner Almesberger <werner@almesberger.net>
67 * All Rights Reserved
78 *
89 * This program is free software; you can redistribute it and/or modify
...... 
4647
4748
4849static struct bps {
49    speed_t speed;
50    int bps;
50    speed_t speed;
51    int bps;
5152} bps_tab[] = {
52    { B300, 300 },
53    { B1200, 1200 },
54    { B2400, 2400 },
55    { B9600, 9600 },
56    { B19200, 19200 },
57    { B38400, 38400 },
58    { B115200, 115200 },
59    { 0, 0 }
53    { B300, 300 },
54    { B1200, 1200 },
55    { B2400, 2400 },
56    { B9600, 9600 },
57    { B19200, 19200 },
58    { B38400, 38400 },
59    { B115200, 115200 },
60    { 0, 0 }
6061};
6162
6263
6364static speed_t bps_to_speed(int bps)
6465{
65    const struct bps *p;
66    const struct bps *p;
6667
67    for (p = bps_tab; p->bps; p++)
68    if (p->bps == bps)
69        return p->speed;
70    fprintf(stderr, "no such speed: %d bps\n", bps);
71    exit(1);
68    for (p = bps_tab; p->bps; p++)
69        if (p->bps == bps)
70            return p->speed;
71    fprintf(stderr, "no such speed: %d bps\n", bps);
72    exit(1);
7273}
7374
7475
7576static void make_raw(int fd, struct termios *old)
7677{
77    struct termios t;
78    long flags;
78    struct termios t;
79    long flags;
7980
80    if (tcgetattr(fd, &t) < 0) {
81    perror("tcgetattr");
82    exit(1);
83    }
84    if (old)
85    *old = t;
86    cfmakeraw(&t);
87    if (fd) {
88    t.c_iflag &= ~(IXON | IXOFF);
89    t.c_cflag |= CLOCAL;
90    t.c_cflag &= ~CRTSCTS;
91    if (cfsetispeed(&t, speed) < 0) {
92        perror("cfsetispeed");
93        exit(1);
81    if (tcgetattr(fd, &t) < 0) {
82        perror("tcgetattr");
83        exit(1);
9484    }
95    if (cfsetospeed(&t, speed) < 0) {
96        perror("cfsetospeed");
97        exit(1);
85    if (old)
86        *old = t;
87    cfmakeraw(&t);
88    if (fd) {
89        t.c_iflag &= ~(IXON | IXOFF);
90        t.c_cflag |= CLOCAL;
91        t.c_cflag &= ~CRTSCTS;
92        if (cfsetispeed(&t, speed) < 0) {
93            perror("cfsetispeed");
94            exit(1);
95        }
96        if (cfsetospeed(&t, speed) < 0) {
97            perror("cfsetospeed");
98            exit(1);
99        }
100    }
101    if (tcsetattr(fd, TCSANOW, &t) < 0) {
102        perror("tcsetattr");
103        exit(1);
104    }
105    flags = fcntl(fd, F_GETFL);
106    if (flags < 0) {
107        perror("fcntl F_GETFL");
108        exit(1);
109    }
110    if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) < 0) {
111        perror("fcntl F_GETFL");
112        exit(1);
98113    }
99    }
100    if (tcsetattr(fd, TCSANOW, &t) < 0) {
101    perror("tcsetattr");
102    exit(1);
103    }
104    flags = fcntl(fd,F_GETFL);
105    if (flags < 0) {
106    perror("fcntl F_GETFL");
107    exit(1);
108    }
109    if (fcntl(fd,F_SETFL,flags & ~O_NONBLOCK) < 0) {
110    perror("fcntl F_GETFL");
111    exit(1);
112    }
113114}
114115
115116
116117static int open_next_tty(void)
117118{
118    int i, fd = -1;
119    int i, fd = -1;
119120
120    for (i = 0; i != num_ttys; i++) {
121    curr_tty = (curr_tty+1) % num_ttys;
122    fd = open(ttys[curr_tty], O_RDWR | O_NDELAY);
121    for (i = 0; i != num_ttys; i++) {
122        curr_tty = (curr_tty+1) % num_ttys;
123        fd = open(ttys[curr_tty], O_RDWR | O_NDELAY);
124        if (fd >= 0)
125            break;
126    }
123127    if (fd >= 0)
124        break;
125    }
126    if (fd >= 0)
127    make_raw(fd, &tty);
128    return fd;
128        make_raw(fd, &tty);
129        return fd;
129130}
130131
131132
...... 
136137
137138static int scan(const char *s, size_t len)
138139{
139    static int state = 0;
140    const char *p;
141    int res = 0;
142
143    for (p = s; p != s+len; p++)
144    switch (state) {
145        case 0:
146        if (*p == escape)
147            state++;
148        else
149            state = 0;
150        break;
151        case 1:
152        if (*p == '.')
153            exit(0);
154        if (*p == 'n')
155            res = 1;
156        state = 0;
157        break;
158    }
159    return res;
140    static int state = 0;
141    const char *p;
142    int res = 0;
143
144    for (p = s; p != s+len; p++)
145        switch (state) {
146        case 0:
147            if (*p == escape)
148                state++;
149            else
150                state = 0;
151            break;
152        case 1:
153            if (*p == '.')
154                exit(0);
155            if (*p == 'n')
156                res = 1;
157            state = 0;
158            break;
159        }
160    return res;
160161}
161162
162163
163164static int write_log(const char *buf, ssize_t len)
164165{
165    size_t wrote;
166
167    wrote = fwrite(buf, 1, len, log);
168    if (wrote == len)
169    return 1;
170    fprintf(stderr, "write failed. closing log file.\n");
171    fclose(log);
172    log = NULL;
173    return 0;
166    size_t wrote;
167
168    wrote = fwrite(buf, 1, len, log);
169    if (wrote == len)
170        return 1;
171    fprintf(stderr, "write failed. closing log file.\n");
172    fclose(log);
173    log = NULL;
174    return 0;
174175}
175176
176177
177178static int add_timestamp(void)
178179{
179    struct timeval tv;
180    char buf[40]; /* be generous */
181    int len;
180    struct timeval tv;
181    char buf[40]; /* be generous */
182    int len;
182183
183    if (gettimeofday(&tv, NULL) < 0) {
184    perror("gettimeofday");
185    exit(1);
186    }
187    len = sprintf(buf, "%lu.%06lu ",
188      (unsigned long) tv.tv_sec, (unsigned long) tv.tv_usec);
189    return write_log(buf, len);
184    if (gettimeofday(&tv, NULL) < 0) {
185        perror("gettimeofday");
186        exit(1);
187    }
188    len = sprintf(buf, "%lu.%06lu ",
189        (unsigned long) tv.tv_sec, (unsigned long) tv.tv_usec);
190    return write_log(buf, len);
190191}
191192
192193
193194static void do_log(const char *buf, ssize_t len)
194195{
195    static int nl = 1; /* we're at the beginning of a new line */
196    char tmp[MAX_BUF];
197    const char *from;
198    char *to;
199
200    assert(len <= MAX_BUF);
201    from = buf;
202    to = tmp;
203    while (from != buf+len) {
204    if (*from == '\r') {
205        from++;
206        continue;
207    }
208    if (nl && timestamp)
209        if (!add_timestamp())
210        return;
211    nl = 0;
212    if (*from == '\n') {
213        *to++ = *from++;
214        if (!write_log(tmp, to-tmp))
215        return;
216        to = tmp;
217        nl = 1;
218        continue;
196    static int nl = 1; /* we're at the beginning of a new line */
197    char tmp[MAX_BUF];
198    const char *from;
199    char *to;
200
201    assert(len <= MAX_BUF);
202    from = buf;
203    to = tmp;
204    while (from != buf+len) {
205        if (*from == '\r') {
206            from++;
207            continue;
208        }
209        if (nl && timestamp)
210            if (!add_timestamp())
211                return;
212        nl = 0;
213        if (*from == '\n') {
214            *to++ = *from++;
215            if (!write_log(tmp, to-tmp))
216                return;
217            to = tmp;
218            nl = 1;
219            continue;
220        }
221        *to++ = *from < ' ' || *from > '~' ? '#' : *from;
222        from++;
219223    }
220    *to++ = *from < ' ' || *from > '~' ? '#' : *from;
221    from++;
222    }
223    write_log(tmp, to-tmp);
224    write_log(tmp, to-tmp);
224225}
225226
226227
227228static int copy(int in, int out, int from_user, int single)
228229{
229    char buffer[MAX_BUF];
230    ssize_t got, wrote, pos;
231
232    got = read(in, buffer, single ? 1 : sizeof(buffer));
233    if (got <= 0)
234    return 0;
235    if (from_user) {
236    if (scan(buffer, got))
237        return 0;
238    }
239    else {
240    if (log)
241        do_log(buffer, got);
242    }
243    for (pos = 0; pos != got; pos += wrote) {
244    wrote = write(out, buffer+pos, got-pos);
245    if (wrote < 0)
246        return 0;
247    }
248    return 1;
230    char buffer[MAX_BUF];
231    ssize_t got, wrote, pos;
232
233    got = read(in, buffer, single ? 1 : sizeof(buffer));
234    if (got <= 0)
235        return 0;
236    if (from_user) {
237        if (scan(buffer, got))
238            return 0;
239    } else {
240        if (log)
241            do_log(buffer, got);
242    }
243    for (pos = 0; pos != got; pos += wrote) {
244        wrote = write(out, buffer+pos, got-pos);
245        if (wrote < 0)
246            return 0;
247    }
248    return 1;
249249}
250250
251251
252252static void write_string(const char *s)
253253{
254    int len = strlen(s);
255
256    while (len) {
257    ssize_t wrote;
258
259    wrote = write(1, s, len);
260    if (wrote < 0) {
261        perror("write");
262        exit(1);
254    int len = strlen(s);
255
256    while (len) {
257        ssize_t wrote;
258
259        wrote = write(1, s, len);
260        if (wrote < 0) {
261            perror("write");
262            exit(1);
263        }
264        s += wrote;
265        len -= wrote;
263266    }
264    s += wrote;
265    len -= wrote;
266    }
267267}
268268
269269
270270static void cleanup(void)
271271{
272    if (tcsetattr(0, TCSANOW, &console) < 0)
273    perror("tcsetattr");
274    write(1, "\n", 1);
272    if (tcsetattr(0, TCSANOW, &console) < 0)
273        perror("tcsetattr");
274    write(1, "\n", 1);
275275}
276276
277277
278278static void usage(const char *name)
279279{
280    fprintf(stderr,
280    fprintf(stderr,
281281"usage: %s [-b bps] [-e escape] [-l logfile [-a] [-T]] [-t delay_ms] tty ...\n\n"
282282" -a append to the log file if it already exists\n"
283283" -b bps set the TTY to the specified bit rate\n"
...... 
285285" -l logfile log all output to the specified file\n"
286286" -t delay_ms wait the specified amount of time between input characters\n"
287287" -T add timestamps to the log file\n"
288      , name);
289    exit(1);
288        , name);
289    exit(1);
290290}
291291
292292
293293int main(int argc, char *const *argv)
294294{
295    char *end;
296    int c, bps;
297    int fd = -1;
298    int append = 0;
299    const char *logfile = NULL;
300    int throttle_us = 0;
301    int throttle = 0;
302
303    while ((c = getopt(argc, argv, "ab:e:l:t:T")) != EOF)
304    switch (c) {
305        case 'a':
306        append = 1;
307        break;
308        case 'b':
309        bps = strtoul(optarg, &end, 0);
310        if (*end)
311            usage(*argv);
312        speed = bps_to_speed(bps);
313        break;
314        case 'e':
315        if (strlen(optarg) != 1)
316            usage(*argv);
317        escape = *optarg;
318        break;
319        case 'l':
320        logfile = optarg;
321        break;
322        case 't':
323        throttle_us = strtoul(optarg, &end, 0)*1000;
324        if (*end)
325            usage(*argv);
326        break;
327        case 'T':
328        timestamp = 1;
329        break;
330        default:
331        usage(*argv);
295    char *end;
296    int c, bps;
297    int fd = -1;
298    int append = 0;
299    const char *logfile = NULL;
300    int throttle_us = 0;
301    int throttle = 0;
302
303    while ((c = getopt(argc, argv, "ab:e:l:t:T")) != EOF)
304        switch (c) {
305        case 'a':
306            append = 1;
307            break;
308        case 'b':
309            bps = strtoul(optarg, &end, 0);
310            if (*end)
311                    usage(*argv);
312            speed = bps_to_speed(bps);
313            break;
314        case 'e':
315            if (strlen(optarg) != 1)
316                usage(*argv);
317            escape = *optarg;
318            break;
319        case 'l':
320            logfile = optarg;
321            break;
322        case 't':
323            throttle_us = strtoul(optarg, &end, 0)*1000;
324            if (*end)
325                usage(*argv);
326            break;
327        case 'T':
328            timestamp = 1;
329            break;
330        default:
331            usage(*argv);
332332    }
333    num_ttys = argc-optind;
334    ttys = argv+optind;
335
336    if (logfile) {
337    log = fopen(logfile, append ? "a" : "w");
338    if (!log) {
339        perror(logfile);
340        exit(1);
333    num_ttys = argc-optind;
334    ttys = argv+optind;
335
336    if (logfile) {
337        log = fopen(logfile, append ? "a" : "w");
338        if (!log) {
339            perror(logfile);
340            exit(1);
341        }
342        setlinebuf(log);
341343    }
342    setlinebuf(log);
343    }
344344
345    make_raw(0, &console);
346    atexit(cleanup);
347    while (1) {
348    struct timeval tv;
349    fd_set set;
350    int res;
351
352    if (fd < 0) {
353        fd = open_next_tty();
354        if (fd > 0) {
355        char buf[1024]; /* enough :-) */
356
357        sprintf(buf, "\r\r[Open %s]\r\n", ttys[curr_tty]);
358        write_string(buf);
359        }
360    }
361    FD_ZERO(&set);
362    if (!throttle)
363        FD_SET(0, &set);
364    if (fd >= 0)
365        FD_SET(fd, &set);
366    tv.tv_sec = 0;
367    tv.tv_usec = throttle ? throttle_us : 100000;
368    res = select(fd < 0 ? 1 : fd+1, &set, NULL, NULL, &tv);
369    if (res < 0) {
370        perror("select");
371        return 1;
372    }
373    if (!res)
374        throttle = 0;
375    if (FD_ISSET(0, &set)) {
376        if (throttle_us)
377        throttle = 1;
378        if (!copy(0, fd, 1, throttle_us != 0))
379        goto failed;
380    }
381    if (fd >= 0 && FD_ISSET(fd, &set))
382        if (!copy(fd, 1, 0, 0))
383        goto failed;
384    continue;
345    make_raw(0, &console);
346    atexit(cleanup);
347    while (1) {
348        struct timeval tv;
349        fd_set set;
350        int res;
351
352        if (fd < 0) {
353            fd = open_next_tty();
354            if (fd > 0) {
355                char buf[1024]; /* enough :-) */
356
357                sprintf(buf, "\r\r[Open %s]\r\n",
358                    ttys[curr_tty]);
359                write_string(buf);
360            }
361        }
362        FD_ZERO(&set);
363        if (!throttle)
364            FD_SET(0, &set);
365        if (fd >= 0)
366            FD_SET(fd, &set);
367        tv.tv_sec = 0;
368        tv.tv_usec = throttle ? throttle_us : 100000;
369        res = select(fd < 0 ? 1 : fd+1, &set, NULL, NULL, &tv);
370        if (res < 0) {
371            perror("select");
372            return 1;
373        }
374        if (!res)
375            throttle = 0;
376        if (FD_ISSET(0, &set)) {
377            if (throttle_us)
378                throttle = 1;
379            if (!copy(0, fd, 1, throttle_us != 0))
380                goto failed;
381        }
382        if (fd >= 0 && FD_ISSET(fd, &set))
383            if (!copy(fd, 1, 0, 0))
384                goto failed;
385        continue;
385386
386387failed:
387    write_string("\r\n[Closed]\r\n");
388    (void) close(fd);
389    fd = -1;
390    }
391    return 0;
388        write_string("\r\n[Closed]\r\n");
389        (void) close(fd);
390        fd = -1;
391    }
392    return 0;
392393}

Archive Download the corresponding diff file

Branches:
master



interactive