📄 seport.c
字号:
intMdmSetGetStopBits(bits) int bits;{#if HAVE_TERMIOS || HAVE_TERMIO if (bits != -1) { switch (bits) { case 1: pmode.c_cflag &= ~CSTOPB; break; case 2: pmode.c_cflag |= CSTOPB; break; default: SeErrorF("invalid number of stop bits: %d", bits, "", ""); return -1; } if (mfd != -1) io_set_attr(mfd, &pmode); } if (mfd != -1) io_get_attr(mfd, &pmode); if (pmode.c_cflag & CSTOPB) return 2; else return 1;#else#if !HAVE_SGTTYB if (mfd != -1) io_set_attr(mfd, &pmode); return 1;#endif#endif}/* * Get/set the baud rate of the modem port. If the port hasn't been opened * yet, just store in pmode for mopen() to use when it opens the port. */longmbaud(s) char *s;{#if USE_NONSTD_BAUD#ifdef linux static struct serial_struct ser_io; if (ioctl(mfd, TIOCGSERIAL, &ser_io) < 0) { SePError("Could not get linux serial info"); return -1; }#endif#endif if (s != NULL) { /* this gives a more limited, realistic */ switch (atol(s)) { /* range than in sgtty.h */ case 300: baudrate = B300; break; case 1200: baudrate = B1200; break; case 2400: baudrate = B2400; break; case 4800: baudrate = B4800; break; case 9600: baudrate = B9600; break; case 19200: baudrate = B19200; break; case 38400: baudrate = B38400;#if USE_NONSTD_BAUD#ifdef linux ser_io.flags &= ~ASYNC_SPD_MASK;#endif#endif break;#if USE_NONSTD_BAUD#ifdef linux case 57600: baudrate = B38400; ser_io.flags &= ~ASYNC_SPD_MASK; ser_io.flags |= ASYNC_SPD_HI; break; case 115200: baudrate = B38400; ser_io.flags &= ~ASYNC_SPD_MASK; ser_io.flags |= ASYNC_SPD_VHI; break;#endif#endif default: return (-1); } io_set_speed(&pmode, baudrate); if (mfd != -1) { io_set_attr(mfd, &pmode);#if USE_NONSTD_BAUD#ifdef linux if (baudrate == B38400) if (ioctl(mfd, TIOCSSERIAL, &ser_io) < 0) { SePError("Could not set linux serial info"); return -1; }#endif#endif } } if (mfd != -1) io_get_attr(mfd, &pmode); switch (io_get_speed(&pmode)) { case B300: return (300); case B1200: return (1200); case B2400: return (2400); case B4800: return (4800); case B9600: return (9600); case B19200: return (19200); case B38400:#if USE_NONSTD_BAUD#ifdef linux if (mfd != -1) if (ioctl(mfd, TIOCGSERIAL, &ser_io) < 0) { SePError("Could not get linux serial info"); return -1; } if ((ser_io.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) return 115200; else if ((ser_io.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) return 57600; else#endif#endif return 38400; } SeError("Consistency error in baud rate"); return -1;}/* * The following routine is used to hang up the modem. This is accomplished * by setting the baud rate to 0. According to my documentation on termio, * setting the baud rate to zero will result in DTR not being asserted. This * hangs up some (most?) modems. If not, the second part of the routine * sends the Hayes modem "escape" and then a hangup command. */voidMdmHangup(){ int terminalWasActive; if (mfd == -1) return; terminalWasActive = SuspContTerminal(TERM_SUSPEND); if (qres.hangupViaDTR) { io_set_speed(&pmode, B0); /* set baud 0 (drop DTR) */ io_set_attr(mfd, &pmode); sleep(1); /* wait a second */ io_set_speed(&pmode, baudrate); /* reset baud rate */ io_set_attr(mfd, &pmode); } else { /* use Hayes command */ sleep(2); /* allow for "escape guard time" */ MdmPutString(qres.modemAttentionString); /* send modem escape command */ sleep(3); /* more "escape guard time" */ MdmPutString(qres.modemHangupString); /* send hangup command */ } MdmPurge(); if (terminalWasActive) SuspContTerminal(TERM_CONTINUE); UpdateStatusBox(NULL);} /* * Opens the modem port and configures it. Returns 0 for success or -1 on * error. */intOpenModem(modem) String modem;{ int LockModem(), UnlockModem(); void MdmIOFlush(); int oldFlags; if (modem == NULL || modem[0] == '\0') return ERR_MDM_NOMODEM; if (LockModem(modem)) return ERR_MDM_LOCKED; /* Need O_NDELAY to get the file open before we have carrier */ if ((mfd = open(modem, O_RDWR | O_NDELAY)) < 0) {UnlockModem(modem); return ERR_MDM_OPENFAILED;} /* Now, we must reset the O_NDELAY mode so that read() works correctly */ if (((oldFlags = fcntl(mfd, F_GETFL, 0)) == -1) || (fcntl(mfd, F_SETFL, oldFlags & ~O_NDELAY) == -1)) {UnlockModem(modem); return ERR_MDM_RESETFLAGSFAILED;}#if HAVE_SGTTYB if (ioctl(mfd, TIOCEXCL) < 0) SePError("exclusive-use");#endif mport(modem); MdmIOFlush(); MdmSaveRestoreAttr(ATTR_SAVE); SetInitialModemAttr(); io_set_attr(mfd, &pmode); GetModemStat(1); if (mbaud(qres.defaultBPS) == -1) se_warningf("invalid default BPS value: %s", qres.defaultBPS, "", ""); if (MdmSetGetCSize(qres.defaultBits) < 0) se_warningf("invalid default number of bits: %s", qres.defaultBits, "", ""); if (MdmSetGetParity(qres.defaultParity) < 0) se_warningf("invalid default parity value: %s", qres.defaultParity, "", ""); if (MdmSetGetStopBits(qres.defaultStopBits) < 0) se_warningf("invalid default number of stop bits: %s", qres.defaultStopBits, "", ""); return 0;}voidShowOpenModemErrMsg(modemName, retStatus) String modemName; int retStatus;{ switch(retStatus) { case ERR_MDM_NOMODEM: SeError("No Modem Specified"); break; case ERR_MDM_LOCKED: SeError(FmtString("Modem ``%s'' is Locked", modemName, "", "")); break; case ERR_MDM_OPENFAILED: SePError(FmtString("Unable to Open Modem ``%s''", modemName, "", "")); break; case ERR_MDM_RESETFLAGSFAILED: SePError(FmtString("Unable to Reset Flags for Modem ``%s''", modemName, "", "")); break; default: SeError(FmtString("Unknown Error While Openeong Modem ``%s''", modemName, "", "")); break; }}intCloseModem(){ if (mfd == -1) return -1; MdmSaveRestoreAttr(ATTR_RESTORE); close(mfd); return 0;}/* * Attach standard input and output to the modem port. This only gets called * after a fork by the child process; which then exec's a program that uses * standard i/o for some data transfer protocol. (To put this here is * actually a kludge, but I wanted to keep the modem-specific stuff in a * black box.) */voidmattach(){ extern int dup2(); /* * attach standard i/o to port */ dup2(mfd, 0); /* close local stdin and connect to port */ dup2(mfd, 1); /* close local stdout and connect to port */ close(mfd); /* close the old port descriptor */}/* ------------------------------------------------------------ * Routines to read from the modem. *//* * MdmReadStr: reads a bunch of characters from the modem. */intMdmReadStr(buf) char *buf;{ return TtyReadStr(mfd, buf);}/* * MdmReadChar: reads one character from the modem. */charMdmReadChar(readChar) char *readChar;{ return TtyReadChar(mfd, readChar);}intMdmTimedReadChar(readChar, expireTime) char *readChar; int expireTime;{ return TtyTimedReadChar(mfd, readChar, expireTime);}/* * MdmReadLine: reads one line from the modem. */intMdmReadLine(buf) char *buf;{ return TtyReadLine(mfd, buf);}intMdmTimedWaitFor(expectedString, waitTime) char *expectedString; int waitTime;{ return TtyTimedWaitFor(mfd, expectedString, waitTime);}/* * MdmPurge: throws away all incoming characters until no more are sent. */voidMdmPurge(){ char c; while (MdmTimedReadChar(&c, 1) >= 0);}#ifdef retiredintreadbyte(seconds) int seconds;{ return trminp(mfd, seconds);}#endif/* * Output a byte to the modem port. All data sent to the modem * is output through this routine. */voidsendbyte(ch) int ch;{ char c = ch & 0xff; if (write(mfd, &c, 1) < 0) SePError("character write");}voidsendf_slowly(format, a, b, c) char *format, *a, *b, *c;{ char buffer[SM_BUF]; sprintf(buffer, format, a, b, c); send_slowly(buffer);}voidsend_slowly(s) char *s;{ while (*s) { sendbyte(*s++); /* * avoid busy waiting by using usleep if available. adjust MDELAY if * you're having trouble */ usleep(MDELAY); }}/* * lock_tty() returns non-zero if the lock file exists (prevents Seyon from * running). * * unlock_tty() deletes the lock file. * * Simple, eh? */char lckf[SM_BUF];char ltmp[SM_BUF];pid_t lockPid;intLockModem(modem) String modem;{ strcpy(modem_port, modem); return lock_tty();}intUnlockModem(modem) String modem;{ unlock_tty(); return 0;}intlock_tty(){ int lfd; pid_t pid, lckpid; char *modemname;#if LF_USE_ASCII_PID char pidstr[20], lckpidstr[20]; int nb;#endif#if LF_USE_DEV_NUMBERS struct stat mbuf;#endif /* Get our PID, and initialize the filename strings */ pid = getpid();#if !LF_USE_DEV_NUMBERS modemname = strrchr(modem_port, '/'); sprintf(lckf, "%s/%s%s", LF_PATH, LF_PREFIX, (modemname ? (modemname + 1) : modem_port));#else if(stat(modem_port, &mbuf) < 0) { SePErrorF("could not stat modem port %s", modem_port, "", ""); return -1; } sprintf(lckf,"%s/%s%03u.%03u.%03u", LF_PATH, LF_PREFIX, major(mbuf.st_dev), major(mbuf.st_rdev), minor(mbuf.st_rdev));#endif /* LF_USE_DEV_NUMBERS */ sprintf(ltmp, "%s/%s%d", LF_PATH, "LTMP.", pid); /* Create the LTMP.<pid> file and scribble our PID in it */ unlink(ltmp); if ((lfd = creat(ltmp, 0644)) == -1) { SePErrorF("Could not create temporary lock file %s", ltmp, "", ""); return -1; }#if LF_USE_ASCII_PID sprintf(pidstr, "%10d\n", pid); write(lfd, pidstr, 11);#else write(lfd, (char*)&pid, sizeof(pid));#endif close(lfd); /* * Attempt to link directly - if it works, we're done. */relink: if (link(ltmp, lckf) == 0) { unlink(ltmp); lockPid = pid; return 0; } /* * Oh brother, there's a LCK..* file already; we must now expend effort to * learn if it's stale or not. */ if ((lfd = open(lckf, O_RDONLY)) != -1) {#if LF_USE_ASCII_PID for (nb = 0; nb < 20 && read(lfd, lckpidstr + nb, sizeof(char)); nb++); if (nb) { lckpid = atol(lckpidstr);#else if (read(lfd, (char *)&lckpid, sizeof(lckpid)) == sizeof(lckpid)) {#endif lockPid = (pid_t) lckpid; if (kill(lckpid, 0) == 0 || errno != ESRCH) { SeErrorF("Device %s is locked by process %d", modem_port, lckpid, ""); unlink(ltmp); return -1; } } } /* * The LCK..* file was stale. Remove and retry. */ if (unlink(lckf)) { SePErrorF("Unable to unlink stale lock file \"%s\"", lckf, "", ""); unlink(ltmp); return -1; } goto relink; /* NOTREACHED */}voidunlock_tty(){ /* Don't remove the lock file unless it's the one we created */ if (getpid() == lockPid) unlink(lckf);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -