Return to BSD News archive
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!news.gan.net.au!act.news.telstra.net!psgrain!usenet.eel.ufl.edu!spool.mu.edu!news.sol.net!news.inc.net!trellis.wwnet.com!nntp.coast.net!howland.reston.ans.net!EU.net!Germany.EU.net!Dortmund.Germany.EU.net!interface-business.de!usenet From: j@ida.interface-business.de (J Wunsch) Newsgroups: comp.unix.bsd.bsdi.misc,comp.unix.bsd.misc,comp.unix.misc Subject: Re: Maintaining tty - [HELP!] Date: 19 Mar 1996 18:50:42 GMT Organization: interface business GmbH, Dresden Lines: 261 Message-ID: <4imvm2$bh8@innocence.interface-business.de> References: <4i4070$aei@fagot.techno.ru> Reply-To: joerg_wunsch@interface-business.de (Joerg Wunsch) NNTP-Posting-Host: ida.interface-business.de X-Newsreader: knews 0.9.3 Xref: euryale.cc.adfa.oz.au comp.unix.bsd.bsdi.misc:2707 comp.unix.bsd.misc:565 comp.unix.misc:21408 oleg@magnum.techno.ru (Oleg Gamayunoff) writes: > I'm not a professional C programmer, but.. please, help! > > I was told to wrote a short program to maintain a modem-like device (some > sort of terminal) but I havent program anything that works with > COM-ports/ttyXX/etc and I dunno where to read about it... > Could anyone explain shortly these functions to me, how to hande/maintain > DTR/DSR/etc and so on? Or maybe anyone could send me a short _commented_ > communication/terminal program? You'll probably have a hard time. I wrote this little program a few days ago. It serves as a modem-to- telnet forwarder here, perhaps it might be of some use for you. It provides the basic framework that is required to handle a tty-style device. It also demonstrates UUCP-style tty lock file locking (ick!). It has been written on a FreeBSD system, so i assume you can recompile it without modification on BSD/OS. # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # comt.c # Makefile # echo x - comt.c sed 's/^X//' >comt.c << 'END-of-comt.c' X/* X * comt -- simple modem forwarder daemon X * X * Designed for being started by telnet, specifically for use by the X * `comt' client program under winglows. Forwards the raw modem to X * a telnet port on fd's 0 and 1. X * X * Obeys the UUCP lock file protocol. X * X * TODO: handle a stat file, to avoid spin loops in inetd. X * X * Author: Jörg Wunsch, interface business GmbH, Dresden X * <joerg_wunsch@interface-business.de> X * X * Copyright © 1996, interface business GmbH. All Rights Reserved. X * X * $Id: comt.c,v 1.3 1996/03/19 18:48:01 j Exp $ X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR X * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF X * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE X * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH X * DAMAGE. X * X */ X X#include <sys/types.h> X#include <sys/time.h> X#include <termios.h> X#include <stdio.h> X#include <stdlib.h> X#include <unistd.h> X#include <fcntl.h> X#include <sysexits.h> X#include <err.h> X#include <signal.h> X#include <syslog.h> X#include <stdarg.h> X#include <paths.h> X#include <string.h> X#include <errno.h> X Xstruct termios oldm, oldt; Xint fd, lockfd; Xchar lockfname[128]; X X/* XXX kludge alert. Ya'know, fixed buffers are ugly. :-) */ X#define BUFFSIZE 10000 X X/* # of tries to establish the tty lock */ X#define MAXTRIES 5 X Xvoid Xsighandler(int signo) X{ X (void)tcsetattr(fd, TCSANOW, &oldm); X if (isatty(0)) X (void)tcsetattr(0, TCSANOW, &oldt); X (void)unlink(lockfname); X exit(EX_OK); X} X Xvoid Xlog(int status, const char *fmt, ...) X{ X va_list ap; X va_start(ap, fmt); X vsyslog(LOG_NOTICE, fmt, ap); X va_end(ap); X exit(status); X} X X Xint Xmain(int argc, char **argv) X{ X int eof = 0; X char *cp; X char locktempname[128], b[12]; X struct termios newm, newt; X int tries, lockfd, locktmpfd; X pid_t lockpid; X X openlog("comt", LOG_PID, LOG_USER); X X if (argc != 2) X log(EX_USAGE, "usage: comt ttyname"); X X if ((cp = strrchr(argv[1], '/'))) X cp++; X else X /* shouldn't happen */ X cp = argv[1]; X snprintf(locktempname, 128, "%s/LCKTMP..%d", _PATH_UUCPLOCK, getpid()); X snprintf(lockfname, 128, "%s/LCK..%s", _PATH_UUCPLOCK, cp); X X if ((locktmpfd = open(locktempname, O_WRONLY|O_CREAT, 0666)) == -1) X log(EX_OSERR, "open(%s): %m", locktempname); X X /* Ain't the UUCP lock protocol fun? I love it, ya'know... */ X for (tries = 0; tries < MAXTRIES; tries++) X { X if (link(locktempname, lockfname) == -1) X { X if (errno != EEXIST) X log(EX_OSERR, "link(%s, %s): %m", locktempname, lockfname); X if ((lockfd = open(lockfname, O_RDONLY, 0666)) == -1) X log(EX_OSERR, "open(%s): %m", lockfname); X if (read(lockfd, b, 12) <= 0) X log(EX_OSERR, "read(%s): %m", lockfname); X close(lockfd); X lockpid = atoi(b); X if (kill(lockpid, 0) == 0 || errno != ESRCH) X log(EX_UNAVAILABLE, "lock held for %s by PID %d", cp, lockpid); X (void)unlink(lockfname); X } X else X { X (void)unlink(locktempname); X lockfd = locktmpfd; X snprintf(b, 12, "%10d\n", getpid()); X (void)write(lockfd, b, strlen(b)); X close(lockfd); X break; X } X } X if (tries >= MAXTRIES) X log(EX_UNAVAILABLE, "failed to establish lock for %s", cp); X X if ((fd = open(argv[1], O_RDWR|O_NONBLOCK, 0)) == -1) X log(EX_OSERR, "open(%s): %m", argv[1]); X X if (tcgetattr(fd, &oldm) == -1) X log(EX_OSERR, "tcgetattr() %m"); X X newm = oldm; X cfmakeraw(&newm); X cfsetispeed(&newm, B38400); X cfsetospeed(&newm, B38400); X newm.c_cflag |= (CLOCAL|CRTSCTS); X if (tcsetattr(fd, TCSANOW, &newm) == -1) X log(EX_OSERR, "tcsetattr() %m"); X X if (isatty(0)) X { X if (tcgetattr(0, &oldt) == -1) X log(EX_OSERR, "tcgetattr() %m"); X X newt = oldt; X cfmakeraw(&newt); X if (tcsetattr(0, TCSANOW, &newt) == -1) X log(EX_OSERR, "tcsetattr() %m"); X } X X (void)signal(SIGINT, sighandler); X (void)signal(SIGTERM, sighandler); X (void)signal(SIGHUP, sighandler); X X while (!eof) X { X fd_set rfd, xfd; X char b[BUFFSIZE]; X int i; X X FD_ZERO(&rfd); X FD_ZERO(&xfd); X FD_SET(0, &rfd); X FD_SET(fd, &rfd); X FD_SET(0, &xfd); X FD_SET(fd, &xfd); X if (select(32, &rfd, 0, &xfd, 0) == -1) X log(EX_OSERR, "select() %m"); X X if (FD_ISSET(0, &xfd) || FD_ISSET(fd, &xfd)) X eof++; X X if (!eof && FD_ISSET(0, &rfd)) X { X if ((i = read(0, b, BUFFSIZE)) <= 0) X eof++; /* EOF on stdin */ X else X (void)write(fd, b, i); X } X X if (!eof && FD_ISSET(fd, &rfd)) X { X if ((i = read(fd, b, BUFFSIZE)) <= 0) X eof++; /* EOF on modem */ X else X (void)write(1, b, i); X } X } X X (void)tcsetattr(fd, TCSANOW, &oldm); X if (isatty(0)) X (void)tcsetattr(0, TCSANOW, &oldt); X (void)unlink(lockfname); X return EX_OK; X} END-of-comt.c echo x - Makefile sed 's/^X//' >Makefile << 'END-of-Makefile' XPROG= comt XNOMAN= ohno X X.include <bsd.prog.mk> END-of-Makefile exit -- J"org Wunsch Unix support engineer joerg_wunsch@interface-business.de http://www.interface-business.de/~j