1
0
mirror of git://projects.qi-hardware.com/wernermisc.git synced 2024-11-15 10:10:39 +02:00

neocon.c: copyright update and whitespace cleanup

Now conforms to Linux kernel style.
This commit is contained in:
Werner Almesberger 2011-11-21 17:12:51 -03:00
parent 7d0683b335
commit f3e1f925c4

View File

@ -2,7 +2,8 @@
* neocon.c - An interface for changing tty devices * neocon.c - An interface for changing tty devices
* *
* Copyright (C) 2007, 2008 by OpenMoko, Inc. * Copyright (C) 2007, 2008 by OpenMoko, Inc.
* Written by Werner Almesberger <werner@openmoko.org> * Copyright 2011 by Werner Almesberger
* Written by Werner Almesberger <werner@almesberger.net>
* All Rights Reserved * All Rights Reserved
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -46,86 +47,86 @@ static char escape = '~';
static struct bps { static struct bps {
speed_t speed; speed_t speed;
int bps; int bps;
} bps_tab[] = { } bps_tab[] = {
{ B300, 300 }, { B300, 300 },
{ B1200, 1200 }, { B1200, 1200 },
{ B2400, 2400 }, { B2400, 2400 },
{ B9600, 9600 }, { B9600, 9600 },
{ B19200, 19200 }, { B19200, 19200 },
{ B38400, 38400 }, { B38400, 38400 },
{ B115200, 115200 }, { B115200, 115200 },
{ 0, 0 } { 0, 0 }
}; };
static speed_t bps_to_speed(int bps) static speed_t bps_to_speed(int bps)
{ {
const struct bps *p; const struct bps *p;
for (p = bps_tab; p->bps; p++) for (p = bps_tab; p->bps; p++)
if (p->bps == bps) if (p->bps == bps)
return p->speed; return p->speed;
fprintf(stderr, "no such speed: %d bps\n", bps); fprintf(stderr, "no such speed: %d bps\n", bps);
exit(1); exit(1);
} }
static void make_raw(int fd, struct termios *old) static void make_raw(int fd, struct termios *old)
{ {
struct termios t; struct termios t;
long flags; long flags;
if (tcgetattr(fd, &t) < 0) { if (tcgetattr(fd, &t) < 0) {
perror("tcgetattr"); perror("tcgetattr");
exit(1); exit(1);
}
if (old)
*old = t;
cfmakeraw(&t);
if (fd) {
t.c_iflag &= ~(IXON | IXOFF);
t.c_cflag |= CLOCAL;
t.c_cflag &= ~CRTSCTS;
if (cfsetispeed(&t, speed) < 0) {
perror("cfsetispeed");
exit(1);
} }
if (cfsetospeed(&t, speed) < 0) { if (old)
perror("cfsetospeed"); *old = t;
exit(1); cfmakeraw(&t);
if (fd) {
t.c_iflag &= ~(IXON | IXOFF);
t.c_cflag |= CLOCAL;
t.c_cflag &= ~CRTSCTS;
if (cfsetispeed(&t, speed) < 0) {
perror("cfsetispeed");
exit(1);
}
if (cfsetospeed(&t, speed) < 0) {
perror("cfsetospeed");
exit(1);
}
}
if (tcsetattr(fd, TCSANOW, &t) < 0) {
perror("tcsetattr");
exit(1);
}
flags = fcntl(fd, F_GETFL);
if (flags < 0) {
perror("fcntl F_GETFL");
exit(1);
}
if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) < 0) {
perror("fcntl F_GETFL");
exit(1);
} }
}
if (tcsetattr(fd, TCSANOW, &t) < 0) {
perror("tcsetattr");
exit(1);
}
flags = fcntl(fd,F_GETFL);
if (flags < 0) {
perror("fcntl F_GETFL");
exit(1);
}
if (fcntl(fd,F_SETFL,flags & ~O_NONBLOCK) < 0) {
perror("fcntl F_GETFL");
exit(1);
}
} }
static int open_next_tty(void) static int open_next_tty(void)
{ {
int i, fd = -1; int i, fd = -1;
for (i = 0; i != num_ttys; i++) { for (i = 0; i != num_ttys; i++) {
curr_tty = (curr_tty+1) % num_ttys; curr_tty = (curr_tty+1) % num_ttys;
fd = open(ttys[curr_tty], O_RDWR | O_NDELAY); fd = open(ttys[curr_tty], O_RDWR | O_NDELAY);
if (fd >= 0)
break;
}
if (fd >= 0) if (fd >= 0)
break; make_raw(fd, &tty);
} return fd;
if (fd >= 0)
make_raw(fd, &tty);
return fd;
} }
@ -136,148 +137,147 @@ static int open_next_tty(void)
static int scan(const char *s, size_t len) static int scan(const char *s, size_t len)
{ {
static int state = 0; static int state = 0;
const char *p; const char *p;
int res = 0; int res = 0;
for (p = s; p != s+len; p++) for (p = s; p != s+len; p++)
switch (state) { switch (state) {
case 0: case 0:
if (*p == escape) if (*p == escape)
state++; state++;
else else
state = 0; state = 0;
break; break;
case 1: case 1:
if (*p == '.') if (*p == '.')
exit(0); exit(0);
if (*p == 'n') if (*p == 'n')
res = 1; res = 1;
state = 0; state = 0;
break; break;
} }
return res; return res;
} }
static int write_log(const char *buf, ssize_t len) static int write_log(const char *buf, ssize_t len)
{ {
size_t wrote; size_t wrote;
wrote = fwrite(buf, 1, len, log); wrote = fwrite(buf, 1, len, log);
if (wrote == len) if (wrote == len)
return 1; return 1;
fprintf(stderr, "write failed. closing log file.\n"); fprintf(stderr, "write failed. closing log file.\n");
fclose(log); fclose(log);
log = NULL; log = NULL;
return 0; return 0;
} }
static int add_timestamp(void) static int add_timestamp(void)
{ {
struct timeval tv; struct timeval tv;
char buf[40]; /* be generous */ char buf[40]; /* be generous */
int len; int len;
if (gettimeofday(&tv, NULL) < 0) { if (gettimeofday(&tv, NULL) < 0) {
perror("gettimeofday"); perror("gettimeofday");
exit(1); exit(1);
} }
len = sprintf(buf, "%lu.%06lu ", len = sprintf(buf, "%lu.%06lu ",
(unsigned long) tv.tv_sec, (unsigned long) tv.tv_usec); (unsigned long) tv.tv_sec, (unsigned long) tv.tv_usec);
return write_log(buf, len); return write_log(buf, len);
} }
static void do_log(const char *buf, ssize_t len) static void do_log(const char *buf, ssize_t len)
{ {
static int nl = 1; /* we're at the beginning of a new line */ static int nl = 1; /* we're at the beginning of a new line */
char tmp[MAX_BUF]; char tmp[MAX_BUF];
const char *from; const char *from;
char *to; char *to;
assert(len <= MAX_BUF); assert(len <= MAX_BUF);
from = buf; from = buf;
to = tmp; to = tmp;
while (from != buf+len) { while (from != buf+len) {
if (*from == '\r') { if (*from == '\r') {
from++; from++;
continue; continue;
}
if (nl && timestamp)
if (!add_timestamp())
return;
nl = 0;
if (*from == '\n') {
*to++ = *from++;
if (!write_log(tmp, to-tmp))
return;
to = tmp;
nl = 1;
continue;
}
*to++ = *from < ' ' || *from > '~' ? '#' : *from;
from++;
} }
if (nl && timestamp) write_log(tmp, to-tmp);
if (!add_timestamp())
return;
nl = 0;
if (*from == '\n') {
*to++ = *from++;
if (!write_log(tmp, to-tmp))
return;
to = tmp;
nl = 1;
continue;
}
*to++ = *from < ' ' || *from > '~' ? '#' : *from;
from++;
}
write_log(tmp, to-tmp);
} }
static int copy(int in, int out, int from_user, int single) static int copy(int in, int out, int from_user, int single)
{ {
char buffer[MAX_BUF]; char buffer[MAX_BUF];
ssize_t got, wrote, pos; ssize_t got, wrote, pos;
got = read(in, buffer, single ? 1 : sizeof(buffer)); got = read(in, buffer, single ? 1 : sizeof(buffer));
if (got <= 0) if (got <= 0)
return 0; return 0;
if (from_user) { if (from_user) {
if (scan(buffer, got)) if (scan(buffer, got))
return 0; return 0;
} } else {
else { if (log)
if (log) do_log(buffer, got);
do_log(buffer, got); }
} for (pos = 0; pos != got; pos += wrote) {
for (pos = 0; pos != got; pos += wrote) { wrote = write(out, buffer+pos, got-pos);
wrote = write(out, buffer+pos, got-pos); if (wrote < 0)
if (wrote < 0) return 0;
return 0; }
} return 1;
return 1;
} }
static void write_string(const char *s) static void write_string(const char *s)
{ {
int len = strlen(s); int len = strlen(s);
while (len) { while (len) {
ssize_t wrote; ssize_t wrote;
wrote = write(1, s, len); wrote = write(1, s, len);
if (wrote < 0) { if (wrote < 0) {
perror("write"); perror("write");
exit(1); exit(1);
}
s += wrote;
len -= wrote;
} }
s += wrote;
len -= wrote;
}
} }
static void cleanup(void) static void cleanup(void)
{ {
if (tcsetattr(0, TCSANOW, &console) < 0) if (tcsetattr(0, TCSANOW, &console) < 0)
perror("tcsetattr"); perror("tcsetattr");
write(1, "\n", 1); write(1, "\n", 1);
} }
static void usage(const char *name) static void usage(const char *name)
{ {
fprintf(stderr, fprintf(stderr,
"usage: %s [-b bps] [-e escape] [-l logfile [-a] [-T]] [-t delay_ms] tty ...\n\n" "usage: %s [-b bps] [-e escape] [-l logfile [-a] [-T]] [-t delay_ms] tty ...\n\n"
" -a append to the log file if it already exists\n" " -a append to the log file if it already exists\n"
" -b bps set the TTY to the specified bit rate\n" " -b bps set the TTY to the specified bit rate\n"
@ -285,108 +285,109 @@ static void usage(const char *name)
" -l logfile log all output to the specified file\n" " -l logfile log all output to the specified file\n"
" -t delay_ms wait the specified amount of time between input characters\n" " -t delay_ms wait the specified amount of time between input characters\n"
" -T add timestamps to the log file\n" " -T add timestamps to the log file\n"
, name); , name);
exit(1); exit(1);
} }
int main(int argc, char *const *argv) int main(int argc, char *const *argv)
{ {
char *end; char *end;
int c, bps; int c, bps;
int fd = -1; int fd = -1;
int append = 0; int append = 0;
const char *logfile = NULL; const char *logfile = NULL;
int throttle_us = 0; int throttle_us = 0;
int throttle = 0; int throttle = 0;
while ((c = getopt(argc, argv, "ab:e:l:t:T")) != EOF) while ((c = getopt(argc, argv, "ab:e:l:t:T")) != EOF)
switch (c) { switch (c) {
case 'a': case 'a':
append = 1; append = 1;
break; break;
case 'b': case 'b':
bps = strtoul(optarg, &end, 0); bps = strtoul(optarg, &end, 0);
if (*end) if (*end)
usage(*argv); usage(*argv);
speed = bps_to_speed(bps); speed = bps_to_speed(bps);
break; break;
case 'e': case 'e':
if (strlen(optarg) != 1) if (strlen(optarg) != 1)
usage(*argv); usage(*argv);
escape = *optarg; escape = *optarg;
break; break;
case 'l': case 'l':
logfile = optarg; logfile = optarg;
break; break;
case 't': case 't':
throttle_us = strtoul(optarg, &end, 0)*1000; throttle_us = strtoul(optarg, &end, 0)*1000;
if (*end) if (*end)
usage(*argv); usage(*argv);
break; break;
case 'T': case 'T':
timestamp = 1; timestamp = 1;
break; break;
default: default:
usage(*argv); usage(*argv);
} }
num_ttys = argc-optind; num_ttys = argc-optind;
ttys = argv+optind; ttys = argv+optind;
if (logfile) { if (logfile) {
log = fopen(logfile, append ? "a" : "w"); log = fopen(logfile, append ? "a" : "w");
if (!log) { if (!log) {
perror(logfile); perror(logfile);
exit(1); exit(1);
}
setlinebuf(log);
} }
setlinebuf(log);
}
make_raw(0, &console); make_raw(0, &console);
atexit(cleanup); atexit(cleanup);
while (1) { while (1) {
struct timeval tv; struct timeval tv;
fd_set set; fd_set set;
int res; int res;
if (fd < 0) { if (fd < 0) {
fd = open_next_tty(); fd = open_next_tty();
if (fd > 0) { if (fd > 0) {
char buf[1024]; /* enough :-) */ char buf[1024]; /* enough :-) */
sprintf(buf, "\r\r[Open %s]\r\n", ttys[curr_tty]); sprintf(buf, "\r\r[Open %s]\r\n",
write_string(buf); ttys[curr_tty]);
} write_string(buf);
} }
FD_ZERO(&set); }
if (!throttle) FD_ZERO(&set);
FD_SET(0, &set); if (!throttle)
if (fd >= 0) FD_SET(0, &set);
FD_SET(fd, &set); if (fd >= 0)
tv.tv_sec = 0; FD_SET(fd, &set);
tv.tv_usec = throttle ? throttle_us : 100000; tv.tv_sec = 0;
res = select(fd < 0 ? 1 : fd+1, &set, NULL, NULL, &tv); tv.tv_usec = throttle ? throttle_us : 100000;
if (res < 0) { res = select(fd < 0 ? 1 : fd+1, &set, NULL, NULL, &tv);
perror("select"); if (res < 0) {
return 1; perror("select");
} return 1;
if (!res) }
throttle = 0; if (!res)
if (FD_ISSET(0, &set)) { throttle = 0;
if (throttle_us) if (FD_ISSET(0, &set)) {
throttle = 1; if (throttle_us)
if (!copy(0, fd, 1, throttle_us != 0)) throttle = 1;
goto failed; if (!copy(0, fd, 1, throttle_us != 0))
} goto failed;
if (fd >= 0 && FD_ISSET(fd, &set)) }
if (!copy(fd, 1, 0, 0)) if (fd >= 0 && FD_ISSET(fd, &set))
goto failed; if (!copy(fd, 1, 0, 0))
continue; goto failed;
continue;
failed: failed:
write_string("\r\n[Closed]\r\n"); write_string("\r\n[Closed]\r\n");
(void) close(fd); (void) close(fd);
fd = -1; fd = -1;
} }
return 0; return 0;
} }